[API] Make GLFW to check availability of features
This commit is contained in:
1 parent
d1e264a663
commit
e8678ef62c
2 files changed
+70
-15
No files matched your search
@@ -21,7 +21,7 @@ import static org.lwjgl.opengl.GL32.*;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a straightforward port of the
|
* This class is a straightforward port of the
|
||||||
* <a href="https://raw.githubusercontent.com/ocornut/imgui/05bc204dbd80dfebb3dab1511caf1cb980620c76/examples/imgui_impl_opengl3.cpp">imgui_impl_opengl3.cpp</a>.
|
* <a href="https://raw.githubusercontent.com/ocornut/imgui/256594575d95d56dda616c544c509740e74906b4/backends/imgui_impl_opengl3.cpp">imgui_impl_opengl3.cpp</a>.
|
||||||
* <p>
|
* <p>
|
||||||
* It do support a backup and restoring of the GL state in the same way the original Dear ImGui code does.
|
* It do support a backup and restoring of the GL state in the same way the original Dear ImGui code does.
|
||||||
* Some of the very specific OpenGL variables may be ignored here,
|
* Some of the very specific OpenGL variables may be ignored here,
|
||||||
|
|||||||
@@ -38,17 +38,28 @@ import static org.lwjgl.system.MemoryUtil.NULL;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a straightforward port of the
|
* This class is a straightforward port of the
|
||||||
* <a href="https://raw.githubusercontent.com/ocornut/imgui/05bc204dbd80dfebb3dab1511caf1cb980620c76/examples/imgui_impl_glfw.cpp">imgui_impl_glfw.cpp</a>.
|
* <a href="https://raw.githubusercontent.com/ocornut/imgui/256594575d95d56dda616c544c509740e74906b4/backends/imgui_impl_glfw.cpp">imgui_impl_glfw.cpp</a>.
|
||||||
* <p>
|
* <p>
|
||||||
* It supports clipboard, gamepad, mouse and keyboard in the same way the original Dear ImGui code does. You can copy-paste this class in your codebase and
|
* It supports clipboard, gamepad, mouse and keyboard in the same way the original Dear ImGui code does. You can copy-paste this class in your codebase and
|
||||||
* modify the rendering routine in the way you'd like.
|
* modify the rendering routine in the way you'd like.
|
||||||
*/
|
*/
|
||||||
public class ImGuiImplGlfw {
|
public class ImGuiImplGlfw {
|
||||||
protected static final boolean IS_WINDOWS = System.getProperty("os.name", "generic").toLowerCase().contains("win");
|
private static final String OS = System.getProperty("os.name", "generic").toLowerCase();
|
||||||
|
protected static final boolean IS_WINDOWS = OS.contains("win");
|
||||||
|
protected static final boolean IS_APPLE = OS.contains("mac") || OS.contains("darwin");
|
||||||
|
|
||||||
// Pointer of the current GLFW window
|
// Pointer of the current GLFW window
|
||||||
private long windowPtr;
|
private long windowPtr;
|
||||||
|
|
||||||
|
// Some features may be available only from a specific version
|
||||||
|
private boolean glfwHawWindowTopmost;
|
||||||
|
private boolean glfwHasWindowAlpha;
|
||||||
|
private boolean glfwHasPerMonitorDpi;
|
||||||
|
private boolean glfwHasFocusWindow;
|
||||||
|
private boolean glfwHasFocusOnShow;
|
||||||
|
private boolean glfwHasMonitorWorkArea;
|
||||||
|
private boolean glfwHasOsxWindowPosFix;
|
||||||
|
|
||||||
// For application window properties
|
// For application window properties
|
||||||
private final int[] winWidth = new int[1];
|
private final int[] winWidth = new int[1];
|
||||||
private final int[] winHeight = new int[1];
|
private final int[] winHeight = new int[1];
|
||||||
@@ -167,6 +178,8 @@ public class ImGuiImplGlfw {
|
|||||||
public boolean init(final long windowId, final boolean installCallbacks) {
|
public boolean init(final long windowId, final boolean installCallbacks) {
|
||||||
this.windowPtr = windowId;
|
this.windowPtr = windowId;
|
||||||
|
|
||||||
|
detectGlfwVersionAndEnabledFeatures();
|
||||||
|
|
||||||
final ImGuiIO io = ImGui.getIO();
|
final ImGuiIO io = ImGui.getIO();
|
||||||
|
|
||||||
io.addBackendFlags(ImGuiBackendFlags.HasMouseCursors | ImGuiBackendFlags.HasSetMousePos | ImGuiBackendFlags.PlatformHasViewports);
|
io.addBackendFlags(ImGuiBackendFlags.HasMouseCursors | ImGuiBackendFlags.HasSetMousePos | ImGuiBackendFlags.PlatformHasViewports);
|
||||||
@@ -307,6 +320,22 @@ public class ImGuiImplGlfw {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void detectGlfwVersionAndEnabledFeatures() {
|
||||||
|
final int[] major = new int[1];
|
||||||
|
final int[] minor = new int[1];
|
||||||
|
final int[] rev = new int[1];
|
||||||
|
glfwGetVersion(major, minor, rev);
|
||||||
|
|
||||||
|
final int version = major[0] * 1000 + minor[0] * 100 + rev[0] * 10;
|
||||||
|
|
||||||
|
glfwHawWindowTopmost = version >= 3200;
|
||||||
|
glfwHasWindowAlpha = version >= 3300;
|
||||||
|
glfwHasPerMonitorDpi = version >= 3300;
|
||||||
|
glfwHasFocusWindow = version >= 3200;
|
||||||
|
glfwHasFocusOnShow = version >= 3300;
|
||||||
|
glfwHasMonitorWorkArea = version >= 3300;
|
||||||
|
}
|
||||||
|
|
||||||
private void updateMousePosAndButtons() {
|
private void updateMousePosAndButtons() {
|
||||||
final ImGuiIO io = ImGui.getIO();
|
final ImGuiIO io = ImGui.getIO();
|
||||||
|
|
||||||
@@ -459,7 +488,9 @@ public class ImGuiImplGlfw {
|
|||||||
final float mainSizeX = vidMode.width();
|
final float mainSizeX = vidMode.width();
|
||||||
final float mainSizeY = vidMode.height();
|
final float mainSizeY = vidMode.height();
|
||||||
|
|
||||||
glfwGetMonitorWorkarea(monitor, monitorWorkAreaX, monitorWorkAreaY, monitorWorkAreaWidth, monitorWorkAreaHeight);
|
if (glfwHasMonitorWorkArea) {
|
||||||
|
glfwGetMonitorWorkarea(monitor, monitorWorkAreaX, monitorWorkAreaY, monitorWorkAreaWidth, monitorWorkAreaHeight);
|
||||||
|
}
|
||||||
|
|
||||||
float workPosX = 0;
|
float workPosX = 0;
|
||||||
float workPosY = 0;
|
float workPosY = 0;
|
||||||
@@ -467,7 +498,7 @@ public class ImGuiImplGlfw {
|
|||||||
float workSizeY = 0;
|
float workSizeY = 0;
|
||||||
|
|
||||||
// Workaround a small GLFW issue reporting zero on monitor changes: https://github.com/glfw/glfw/pull/1761
|
// Workaround a small GLFW issue reporting zero on monitor changes: https://github.com/glfw/glfw/pull/1761
|
||||||
if (monitorWorkAreaWidth[0] > 0 && monitorWorkAreaHeight[0] > 0) {
|
if (glfwHasMonitorWorkArea && monitorWorkAreaWidth[0] > 0 && monitorWorkAreaHeight[0] > 0) {
|
||||||
workPosX = monitorWorkAreaX[0];
|
workPosX = monitorWorkAreaX[0];
|
||||||
workPosY = monitorWorkAreaY[0];
|
workPosY = monitorWorkAreaY[0];
|
||||||
workSizeX = monitorWorkAreaWidth[0];
|
workSizeX = monitorWorkAreaWidth[0];
|
||||||
@@ -476,7 +507,9 @@ public class ImGuiImplGlfw {
|
|||||||
|
|
||||||
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings,
|
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings,
|
||||||
// which generally needs to be set in the manifest or at runtime.
|
// which generally needs to be set in the manifest or at runtime.
|
||||||
glfwGetMonitorContentScale(monitor, monitorContentScaleX, monitorContentScaleY);
|
if (glfwHasPerMonitorDpi) {
|
||||||
|
glfwGetMonitorContentScale(monitor, monitorContentScaleX, monitorContentScaleY);
|
||||||
|
}
|
||||||
final float dpiScale = monitorContentScaleX[0];
|
final float dpiScale = monitorContentScaleX[0];
|
||||||
|
|
||||||
platformIO.pushMonitors(mainPosX, mainPosY, mainSizeX, mainSizeY, workPosX, workPosY, workSizeX, workSizeY, dpiScale);
|
platformIO.pushMonitors(mainPosX, mainPosY, mainSizeX, mainSizeY, workPosX, workPosY, workSizeX, workSizeY, dpiScale);
|
||||||
@@ -537,9 +570,13 @@ public class ImGuiImplGlfw {
|
|||||||
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
|
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
|
||||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||||
glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE);
|
glfwWindowHint(GLFW_FOCUSED, GLFW_FALSE);
|
||||||
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
|
if (glfwHasFocusOnShow) {
|
||||||
|
glfwWindowHint(GLFW_FOCUS_ON_SHOW, GLFW_FALSE);
|
||||||
|
}
|
||||||
glfwWindowHint(GLFW_DECORATED, vp.hasFlags(ImGuiViewportFlags.NoDecoration) ? GLFW_FALSE : GLFW_TRUE);
|
glfwWindowHint(GLFW_DECORATED, vp.hasFlags(ImGuiViewportFlags.NoDecoration) ? GLFW_FALSE : GLFW_TRUE);
|
||||||
glfwWindowHint(GLFW_FLOATING, vp.hasFlags(ImGuiViewportFlags.TopMost) ? GLFW_TRUE : GLFW_FALSE);
|
if (glfwHawWindowTopmost) {
|
||||||
|
glfwWindowHint(GLFW_FLOATING, vp.hasFlags(ImGuiViewportFlags.TopMost) ? GLFW_TRUE : GLFW_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
data.window = glfwCreateWindow((int) vp.getSizeX(), (int) vp.getSizeY(), "No Title Yet", NULL, windowPtr);
|
data.window = glfwCreateWindow((int) vp.getSizeX(), (int) vp.getSizeY(), "No Title Yet", NULL, windowPtr);
|
||||||
data.windowOwned = true;
|
data.windowOwned = true;
|
||||||
@@ -628,10 +665,24 @@ public class ImGuiImplGlfw {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class SetWindowSizeFunction extends ImPlatformFuncViewportImVec2 {
|
private final class SetWindowSizeFunction extends ImPlatformFuncViewportImVec2 {
|
||||||
|
private final int[] x = new int[1];
|
||||||
|
private final int[] y = new int[1];
|
||||||
|
private final int[] width = new int[1];
|
||||||
|
private final int[] height = new int[1];
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(final ImGuiViewport vp, final ImVec2 imVec2) {
|
public void accept(final ImGuiViewport vp, final ImVec2 imVec2) {
|
||||||
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
|
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
|
||||||
|
// Native OS windows are positioned from the bottom-left corner on macOS, whereas on other platforms they are
|
||||||
|
// positioned from the upper-left corner. GLFW makes an effort to convert macOS style coordinates, however it
|
||||||
|
// doesn't handle it when changing size. We are manually moving the window in order for changes of size to be based
|
||||||
|
// on the upper-left corner.
|
||||||
|
if (IS_APPLE && !glfwHasOsxWindowPosFix) {
|
||||||
|
glfwGetWindowPos(data.window, x, y);
|
||||||
|
glfwGetWindowSize(data.window, width, height);
|
||||||
|
glfwSetWindowPos(data.window, x[0], y[0] - height[0] + (int) imVec2.y);
|
||||||
|
}
|
||||||
data.ignoreWindowSizeEventFrame = ImGui.getFrameCount();
|
data.ignoreWindowSizeEventFrame = ImGui.getFrameCount();
|
||||||
glfwSetWindowSize(data.window, (int) imVec2.x, (int) imVec2.y);
|
glfwSetWindowSize(data.window, (int) imVec2.x, (int) imVec2.y);
|
||||||
}
|
}
|
||||||
@@ -645,11 +696,13 @@ public class ImGuiImplGlfw {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class SetWindowFocusFunction extends ImPlatformFuncViewport {
|
private final class SetWindowFocusFunction extends ImPlatformFuncViewport {
|
||||||
@Override
|
@Override
|
||||||
public void accept(final ImGuiViewport vp) {
|
public void accept(final ImGuiViewport vp) {
|
||||||
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
|
if (glfwHasFocusWindow) {
|
||||||
glfwFocusWindow(data.window);
|
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
|
||||||
|
glfwFocusWindow(data.window);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -669,11 +722,13 @@ public class ImGuiImplGlfw {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class SetWindowAlphaFunction extends ImPlatformFuncViewportFloat {
|
private final class SetWindowAlphaFunction extends ImPlatformFuncViewportFloat {
|
||||||
@Override
|
@Override
|
||||||
public void accept(final ImGuiViewport vp, final float f) {
|
public void accept(final ImGuiViewport vp, final float f) {
|
||||||
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
|
if (glfwHasWindowAlpha) {
|
||||||
glfwSetWindowOpacity(data.window, f);
|
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
|
||||||
|
glfwSetWindowOpacity(data.window, f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user