libui
libui copied to clipboard
uiOpenGLArea
I updated @pcwalton's work onto master. Closes #265. Closes #34
On Linux, mesa-common-dev is needed for building (or libgl1-mesa-dev?)

TODO:
- Windows: SetPixelFormat can only be called once per window
This is the modern way of creating an OpenGL context (needed for multisampling and sRGB frambuffers):
- Create a "fake context" only to get function pointers for a newer context creation method (involves
SetPixelFormat) - Create the actual context with the requested attributes and
SetPixelFormatthe actual format. - But
SetPixelFormatcan only be called once per Window, so a "fake window" needs to be created for the fake context. - How should that dummy window be created & destroyed?
- Create a "fake context" only to get function pointers for a newer context creation method (involves
- Windows: key events not working
- areaevents.cpp
areaDoEvents:- some
uMsg == msgAreaKeyDownfor uiArea - no
uMsg == WM_KEYDOWfor uiOpenGLArea
- some
- is
areaFilterworking for uiOpenGLArea as well?
- areaevents.cpp
- Windows:
onMouseCrossedstops working after clicking once onto the area (does this happen withuiAreaas well?)
To discuss:
General:
- How to do error handling (e.g. if requested attributes like OpenGL version area not available):
- Possible situations:
- missing required extensions/functions (needed by libui code)
- missing requested extensions/functions/versions (requested by user)
- Solutions:
- return an error code in uiNewOpenGLArea and add an enum for these OR return NULL and pass an error string in some other way
- a
uiprivUserbugcan't be caught so a program can't even display "Your graphics card is not supported".
- Possible situations:
- What about scrolling OpenGL areas?
Linux:
- Does including X11 libraries always use XWayland, is there a difference to before?
- Instead of GLX, EGL could be used on Wayland (the native interface there). But I don't know how to detect this at runtime and whether these libraries would need to be loaded dynamically regarding these:
- What if the Linux GL library is missing at runtime?
- Linux: use GtkGLArea / GdkGLContext ?
- Ubuntu 18.10 with libgl1-mesa-dev:
-- Found X11: /usr/lib/x86_64-linux-gnu/libX11.so
CMake Warning (dev) at /usr/share/cmake-3.12/Modules/FindOpenGL.cmake:270 (message):
Policy CMP0072 is not set: FindOpenGL prefers GLVND by default when
available. Run "cmake --help-policy CMP0072" for policy details. Use the
cmake_policy command to set the policy and suppress this warning.
FindOpenGL found both a legacy GL library:
OPENGL_gl_LIBRARY: /usr/lib/x86_64-linux-gnu/libGL.so
and GLVND libraries for OpenGL and GLX:
OPENGL_opengl_LIBRARY: /usr/lib/x86_64-linux-gnu/libOpenGL.so
OPENGL_glx_LIBRARY: /usr/lib/x86_64-linux-gnu/libGLX.so
OpenGL_GL_PREFERENCE has not been set to "GLVND" or "LEGACY", so for
compatibility with CMake 3.10 and below the legacy GL library will be used.
macOS:
- Does this apply:

https://twitter.com/pcwalton/status/1055528025247240192
Try putting the area in a box and marking it stretchy, then adding a button. There's glitches involving the sizing of areas that are by themselves in windows on GTK+.
Did that work?
Did that work?
Yes!
~The OpenGL error is 0x502 (GL_INVALID_OPERATION?) in these two lines, but not on macOS:~
glUniformMatrix4fv(openGLState.ProjectionUniform, 1, GL_FALSE, &projection.m11);
glUniformMatrix4fv(openGLState.ModelViewUniform, 1, GL_FALSE, &modelview.m11);
Well, InitGL was never called on Linux
@andlabs Is the macOS area refactoring acceptable? areaCommonView now handles all events and is the superclass of openGLAreaView and areaView .
Also, why are the macOS classes in lowerCameCase (Cocoa's arent: NSOpenGLArea, NSView).
Do we want a scrolling opengl view?
I'll look at all of that after releasing Alpha 4.
lowerCaseCamelCase is a habit I acquired from various places, including Go. The new convention is uiprivClassNameCamelCase, with uipriv still being lowercase to maximize collision avoidance.
Solved
~@andlabs For linux and macOS, this code works because the constructor runs synchronously and the context is actually created (see the opengl example):~
uiOpenGLArea *glarea = uiNewOpenGLArea(&AREA_HANDLER, attribs);
uiOpenGLAreaMakeCurrent(glarea);
GLenum glewStatus = glewInit();
if (glewStatus != GLEW_OK) {
fprintf(stderr, "GLEW init error: %s\n", glewGetErrorString(glewStatus));
exit(EXIT_FAILURE);
}
// ...
uiMain();
~On Windows however, the context creating happens in areaWndProc (see openglarea.c) so uiOpenGLAreaMakeCurrent tries to make NULL current (this needs to be done before glewInit can run). How can this be done?~
@andlabs The OpenGL area is now working on every platform, even with OpenGL 3.3. Only some cleanup and better openglattributes handling needs to be done.
@mischnic Instead of using GLX / X11 APIs directly in a custom widget, we should probably be using the included GtkGLArea widget. (GTK 3.16 added this, over three years ago now..)
I would need to bump the minimum version for that. Not sure if I should or not. Again, will look at all this soon and see if there's a better approach if bumping the version isn't suitable.
Instead of GLX, EGL could be used on Wayland (the native interface there). But I dont know how to detect this at runtime and if these libraries would need to be loaded dynamically regarding these:
That should then be the same behaviour as the Gtk GLArea. When was GdkGLContext added? Can it be used seperately?
Hi, I was wondering what the current state of this feature is?
The 3.0 changelog seems to indicate this was planned for the 4.0 release, but I don't believe this feature has made it in yet, has it?
CI seems to be failing for 32-bit Linux, because it can't find "-lGL", (the GL library), but when looking at the CMakeLists.txt I was wondering why you are manually specifying the library names instead of using FindOpenGL?
Hi, I was wondering what the current state of this feature is?
Waiting for @andlabs' feedback/review.
I was wondering why you are manually specifying the library names instead of using FindOpenGL?
Fixed. 😄 Let's see what happens.
@andlabs Why isn't Travis running? For #424 neither.
@andlabs ?
I don't know; that's weird. Travis still lets me see the status of libui, but it's behind...
Okay I guess I needed to just log in again and it seems to be back.
I should probably get to updating both the issues and pull requests for this now (I was taking a break after releasing Alpha 4 and package ui, but IDK how long that will continue for)
The Mac example doesn't start rendering until the window is resized, and then, it flickers a lot.
Any idea what's going on?
The Mac example doesn't start rendering until the window is resized
Could you please check if onDrawGL is called before resizing and if it is, whether the correct width & height (= non-zero) values are passed?
diff --git a/examples/opengl/main.c b/examples/opengl/main.c
index 1fff59c9..ab19e5a7 100644
--- a/examples/opengl/main.c
+++ b/examples/opengl/main.c
@@ -277,6 +277,7 @@ static void onInitGL(uiOpenGLAreaHandler *h, uiOpenGLArea *a)
static void onDrawGL(uiOpenGLAreaHandler *h, uiOpenGLArea *a, double width, double height)
{
GLCall(glViewport(0, 0, width, height));
+ printf("%f %f\n", width, height);
GLCall(glClear(GL_COLOR_BUFFER_BIT));
Should print: 600.000000 415.000000
and then, it flickers a lot.
Maybe disabling VSync (uiOpenGLAreaSetVSync(a, 0); in setup) helps?
Is there a difference with this change? (Still flickering when moving the mouse over the area?)
diff --git a/examples/opengl/main.c b/examples/opengl/main.c
index 1fff59c9..5e1c9914 100644
--- a/examples/opengl/main.c
+++ b/examples/opengl/main.c
@@ -362,8 +363,6 @@ int main(void)
uiOpenGLArea *glarea = uiNewOpenGLArea(&AREA_HANDLER, attribs);
uiBoxAppend(b, uiControl(glarea), 1);
- uiTimer(1000/60, render, glarea);
-
uiControlShow(uiControl(mainwin));
uiMain();
Works fine for me (macOS 10.13.6, Intel Graphics).
onDrawGL is called before resizing.
It's printing the right size I believe (600x416).
Disabling vsync doesn't change anything.
Still flickers without the timer.
I think every odd frame is transparent:
Screencast: https://streamable.com/12xcn
@paulrouget I guess you're running Mojave?
This should definitely fix the blank-before-resize-issue:
diff --git a/darwin/openglarea.m b/darwin/openglarea.m
index d98dbb9e..8d289c05 100644
--- a/darwin/openglarea.m
+++ b/darwin/openglarea.m
@@ -82,6 +83,8 @@ static void assignNextPixelFormatAttribute(NSOpenGLPixelFormatAttribute *as, uns
self->libui_a->ctx = [[NSOpenGLContext alloc] initWithFormat:self->libui_a->pixFmt shareContext:nil];
if(self->libui_a->ctx == nil)
uiprivUserBug("Couldn't create OpenGL context!");
+ [self->libui_a->ctx setView:self];
+ [self->libui_a->ctx update];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewBoundsDidChange:) name:NSViewFrameDidChangeNotification object:self];
}
When setting wantsLayer to true, the flickering happens for me as well, please try this change: (coincidentally, the tweet I mentioned in the PR description a while ago describes exactly this)
diff --git a/darwin/openglarea.m b/darwin/openglarea.m
index d98dbb9e..8d289c05 100644
--- a/darwin/openglarea.m
+++ b/darwin/openglarea.m
@@ -42,6 +42,8 @@ static void assignNextPixelFormatAttribute(NSOpenGLPixelFormatAttribute *as, uns
[self setupNewTrackingArea];
self->libui_enabled = YES;
+ [self setWantsLayer:NO];
+
NSOpenGLPixelFormatAttribute attrs[ATTRIBUTE_LIST_SIZE];
unsigned int attrIndex = 0;
assignNextPixelFormatAttribute(attrs, &attrIndex, NSOpenGLPFAColorSize);
I guess you're running Mojave?
Yes. 10.14.1.
This should definitely fix the blank-before-resize-issue: [self->libui_a->ctx setView:self]; [self->libui_a->ctx update];
This change changes nothing.
When setting
wantsLayerto true, the flickering happens for me as well, please try this change
Setting setWantsLayer to NO changes nothing.
Setting setWantsLayer to YES fixes the blank-before-resize-issue.
No matter the configuration/changes, it's flickering.
setWantsLayer:NO on Mojave: Blank before resize and flickering on every other frame
setWantsLayer:NO on High Sierra: Works fine
setWantsLayer:YES on Mojave: Flickering
setWantsLayer:YES on High Sierra: Flickering
The flickering could be related to double buffering?
@pcwalton You have investigated this some time ago, any suggestion?
Will this work on mac os? I know opengl is deprecated on mac os.