libui icon indicating copy to clipboard operation
libui copied to clipboard

uiOpenGLArea

Open mischnic opened this issue 7 years ago • 25 comments

I updated @pcwalton's work onto master. Closes #265. Closes #34

On Linux, mesa-common-dev is needed for building (or libgl1-mesa-dev?) bildschirmfoto 2018-09-02 um 23 34 43

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 SetPixelFormat the actual format.
    • But SetPixelFormat can 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?
  • Windows: key events not working
    • areaevents.cpp areaDoEvents:
      • some uMsg == msgAreaKeyDown for uiArea
      • no uMsg == WM_KEYDOW for uiOpenGLArea
    • is areaFilter working for uiOpenGLArea as well?
  • Windows: onMouseCrossed stops working after clicking once onto the area (does this happen with uiArea as 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 uiprivUserbug can't be caught so a program can't even display "Your graphics card is not supported".
  • 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:

bildschirmfoto 2018-10-25 um 20 47 12

https://twitter.com/pcwalton/status/1055528025247240192

mischnic avatar Aug 06 '18 21:08 mischnic

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+.

andlabs avatar Aug 06 '18 21:08 andlabs

Did that work?

andlabs avatar Aug 07 '18 13:08 andlabs

Did that work?

Yes!

mischnic avatar Aug 07 '18 13:08 mischnic

~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

mischnic avatar Aug 07 '18 15:08 mischnic

@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).

mischnic avatar Aug 07 '18 17:08 mischnic

Do we want a scrolling opengl view?

mischnic avatar Aug 09 '18 16:08 mischnic

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.

andlabs avatar Aug 09 '18 17:08 andlabs

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?~

mischnic avatar Aug 31 '18 18:08 mischnic

@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 avatar Sep 02 '18 08:09 mischnic

@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..)

cody271 avatar Sep 03 '18 03:09 cody271

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.

andlabs avatar Sep 03 '18 04:09 andlabs

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?

mischnic avatar Sep 03 '18 09:09 mischnic

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?

ThomasCassimon avatar Sep 26 '18 20:09 ThomasCassimon

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.

mischnic avatar Sep 26 '18 21:09 mischnic

@andlabs Why isn't Travis running? For #424 neither.

mischnic avatar Sep 26 '18 21:09 mischnic

@andlabs ?

mischnic avatar Oct 06 '18 12:10 mischnic

I don't know; that's weird. Travis still lets me see the status of libui, but it's behind...

andlabs avatar Oct 06 '18 13:10 andlabs

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)

andlabs avatar Oct 06 '18 20:10 andlabs

The Mac example doesn't start rendering until the window is resized, and then, it flickers a lot.

Any idea what's going on?

paulrouget avatar Feb 06 '19 02:02 paulrouget

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).

mischnic avatar Feb 06 '19 19:02 mischnic

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 avatar Feb 07 '19 04:02 paulrouget

@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);

mischnic avatar Feb 07 '19 22:02 mischnic

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 wantsLayer to 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.

paulrouget avatar Feb 08 '19 07:02 paulrouget

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?

mischnic avatar Feb 08 '19 18:02 mischnic

Will this work on mac os? I know opengl is deprecated on mac os.

Shadowblitz16 avatar Nov 18 '21 04:11 Shadowblitz16