Skip to content

Commit

Permalink
[API] Make GLFW to check availability of features
Browse files Browse the repository at this point in the history
  • Loading branch information
SpaiR committed Mar 30, 2021
1 parent d1e264a commit e8678ef
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 15 deletions.
2 changes: 1 addition & 1 deletion imgui-lwjgl3/src/main/java/imgui/gl3/ImGuiImplGl3.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

/**
* This class is a straightforward port of the
* <a href="https://github.com/raw/ocornut/imgui/05bc204dbd80dfebb3dab1511caf1cb980620c76/examples/imgui_impl_opengl3.cpp">imgui_impl_opengl3.cpp</a>.
* <a href="https://github.com/raw/ocornut/imgui/256594575d95d56dda616c544c509740e74906b4/backends/imgui_impl_opengl3.cpp">imgui_impl_opengl3.cpp</a>.
* <p>
* 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,
Expand Down
83 changes: 69 additions & 14 deletions imgui-lwjgl3/src/main/java/imgui/glfw/ImGuiImplGlfw.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,28 @@

/**
* This class is a straightforward port of the
* <a href="https://github.com/raw/ocornut/imgui/05bc204dbd80dfebb3dab1511caf1cb980620c76/examples/imgui_impl_glfw.cpp">imgui_impl_glfw.cpp</a>.
* <a href="https://github.com/raw/ocornut/imgui/256594575d95d56dda616c544c509740e74906b4/backends/imgui_impl_glfw.cpp">imgui_impl_glfw.cpp</a>.
* <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
* modify the rendering routine in the way you'd like.
*/
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
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
private final int[] winWidth = new int[1];
private final int[] winHeight = new int[1];
Expand Down Expand Up @@ -167,6 +178,8 @@ public void monitorCallback(final long windowId, final int event) {
public boolean init(final long windowId, final boolean installCallbacks) {
this.windowPtr = windowId;

detectGlfwVersionAndEnabledFeatures();

final ImGuiIO io = ImGui.getIO();

io.addBackendFlags(ImGuiBackendFlags.HasMouseCursors | ImGuiBackendFlags.HasSetMousePos | ImGuiBackendFlags.PlatformHasViewports);
Expand Down Expand Up @@ -307,6 +320,22 @@ public void dispose() {
}
}

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() {
final ImGuiIO io = ImGui.getIO();

Expand Down Expand Up @@ -459,15 +488,17 @@ private void updateMonitors() {
final float mainSizeX = vidMode.width();
final float mainSizeY = vidMode.height();

glfwGetMonitorWorkarea(monitor, monitorWorkAreaX, monitorWorkAreaY, monitorWorkAreaWidth, monitorWorkAreaHeight);
if (glfwHasMonitorWorkArea) {
glfwGetMonitorWorkarea(monitor, monitorWorkAreaX, monitorWorkAreaY, monitorWorkAreaWidth, monitorWorkAreaHeight);
}

float workPosX = 0;
float workPosY = 0;
float workSizeX = 0;
float workSizeY = 0;

// 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];
workPosY = monitorWorkAreaY[0];
workSizeX = monitorWorkAreaWidth[0];
Expand All @@ -476,7 +507,9 @@ private void updateMonitors() {

// 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.
glfwGetMonitorContentScale(monitor, monitorContentScaleX, monitorContentScaleY);
if (glfwHasPerMonitorDpi) {
glfwGetMonitorContentScale(monitor, monitorContentScaleX, monitorContentScaleY);
}
final float dpiScale = monitorContentScaleX[0];

platformIO.pushMonitors(mainPosX, mainPosY, mainSizeX, mainSizeY, workPosX, workPosY, workSizeX, workSizeY, dpiScale);
Expand Down Expand Up @@ -537,9 +570,13 @@ public void accept(final ImGuiViewport vp) {
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
glfwWindowHint(GLFW_VISIBLE, 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_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.windowOwned = true;
Expand Down Expand Up @@ -628,10 +665,24 @@ public void get(final ImGuiViewport vp, final ImVec2 dstImVec2) {
}
}

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
public void accept(final ImGuiViewport vp, final ImVec2 imVec2) {
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();
glfwSetWindowSize(data.window, (int) imVec2.x, (int) imVec2.y);
}
Expand All @@ -645,11 +696,13 @@ public void accept(final ImGuiViewport vp, final String str) {
}
}

private static final class SetWindowFocusFunction extends ImPlatformFuncViewport {
private final class SetWindowFocusFunction extends ImPlatformFuncViewport {
@Override
public void accept(final ImGuiViewport vp) {
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
glfwFocusWindow(data.window);
if (glfwHasFocusWindow) {
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
glfwFocusWindow(data.window);
}
}
}

Expand All @@ -669,11 +722,13 @@ public boolean get(final ImGuiViewport vp) {
}
}

private static final class SetWindowAlphaFunction extends ImPlatformFuncViewportFloat {
private final class SetWindowAlphaFunction extends ImPlatformFuncViewportFloat {
@Override
public void accept(final ImGuiViewport vp, final float f) {
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
glfwSetWindowOpacity(data.window, f);
if (glfwHasWindowAlpha) {
final ImGuiViewportDataGlfw data = (ImGuiViewportDataGlfw) vp.getPlatformUserData();
glfwSetWindowOpacity(data.window, f);
}
}
}

Expand Down

0 comments on commit e8678ef

Please sign in to comment.