Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenGL control #34

Open
mkeeter opened this issue May 20, 2016 · 37 comments · May be fixed by #405
Open

OpenGL control #34

mkeeter opened this issue May 20, 2016 · 37 comments · May be fixed by #405

Comments

@mkeeter
Copy link

mkeeter commented May 20, 2016

Are there any plans to add an OpenGL control?

GLFW is great for making a bare window and OpenGL context across platforms, but doesn't have the sweet cross-platform UI support that libui seems to offer.

@andlabs
Copy link
Owner

andlabs commented May 20, 2016

Yes. Unfortunately, GTK+ only added OpenGL support in 3.16, so if I want to use that I'll need to make it a separate library until I can bump my version numbers up (2018) or use the X11-only tegtkgl until then (possibly with Wayland once I formally drop 3.4-3.8 sometime this weekend or next week).

@pcwalton
Copy link
Contributor

This would potentially be really interesting for https://github.com/servo/servo/. +1 here :)

@pcwalton
Copy link
Contributor

@andlabs If you're willing to provide a sketch of the API you're looking for, I could start on implementing this in my spare time.

@andlabs
Copy link
Owner

andlabs commented May 21, 2016

I'd have to evaluate what APIs I can provide; that would mean going through wgl, GtkGLArea, and NSOpenGLView to see how they work and how to do OpenGL with them.

@pcwalton
Copy link
Contributor

pcwalton commented May 21, 2016

If you haven't seen it yet, a good place to start is looking at GLFW's window attributes (as windows are 1:1 with GL contexts). This set of attributes is supported across WGL, GtkGLArea, and NSOpenGLView. Another place to look is the GL attributes for the Rust glutin library (which I've done a good bit of work on): these are supported across all three backends as well.

Those, along with a MakeCurrent() (wglMakeCurrent()/CGLSetCurrentContext()/gtk_gl_area_make_current()) API and a rendering callback (that calls wglSwapBuffers() on Windows and CGLFlushDrawable() on Mac), would be enough to get started for our purposes :)

@andlabs
Copy link
Owner

andlabs commented May 22, 2016

Besides all of the above, which helps a lot (thanks!), there's also realization/unrealization and context creation, which I'm also not fully sure about. There's also minimum OpenGL versions and required extensions, which have hit some programmers using GtkGLArea before.

Should OpenGL areas be scrollable? I want the uiOpenGLArea to be as orthogonal to uiArea as possible, even using much of the same code.

@pcwalton
Copy link
Contributor

pcwalton commented May 22, 2016

As far as realization/unrealization, if I'm understanding you correctly, I believe all you need to do is call the platform specific version of MakeCurrent() before the rendering callback. Note that lots of games (and us) will want to be able to call MakeCurrent() outside of the rendering callback and do our rendering outside of the main loop—obviously this requires a "step" kind of function like the one in #21.

For context creation, WGL and NSOpenGLView both support the full set of attributes; you use wglCreateContext() for WGL, and for NSOpenGLView you use -[NSOpenGLView initWithFrame:pixelFormat:]. Note that for me it was actually easier to not use NSOpenGLView and to just use a plain old NSView with a CGL context; NSOpenGLView really doesn't provide much if you're not using Interface Builder.

From a glance, it doesn't look like the GTK stuff provides all of the pixel format attributes that GLX does, which is a nuisance. I guess we'll have to either just omit unsupported pixel formats or drop down to GLX directly.

I personally don't care whether the OpenGL area is scrollable (Servo implements scrolling itself), but if it makes it easier for you I think all UI systems support it.

@andlabs
Copy link
Owner

andlabs commented May 22, 2016

I suppose having backend-specific OpenGL code for Unix is fine; we'd really only need to support the backends that GTK+ itself supports that aren't Windows and OS X (and possibly also Broadway). Waiting a week for me to switch to 3.10 will help here, but it's not necessary. We can build on tegtkgl or one of its forks (but some are GPL, so we can't use those), or build it from scratch? Whatever you think is best, I suppose :) I'm not fully familiar with OpenGL in desktop applications yet myself.

By realization/unrealization I meant for allocating and deallocating context-specific resources like shaders. I assume on OS X and Windows the context will never change, right?

@pcwalton
Copy link
Contributor

pcwalton commented May 22, 2016

I'm not actually sure how the GTK GL view deals with realization and unrealization. In general, if you use the GLX API (or something that wraps it) then you can assume your context will stay put, just as on Windows and Mac it will.

@andlabs
Copy link
Owner

andlabs commented May 22, 2016

The GTK+ GL API ties a GL context to a GdkWindow; if something causes a widget's GdkWindow to change (for instance, moving a widget from one GtkWindow to another) then the context will need to be re-realized. If using GLX directly makes this unnecessary then I suppose we can just go ahead and implement it ourselves. Still curious about how Wayland will work...

I guess you can get started now if you'd like :) I'll probably merge in uiMainStep() or similar later today.

@andlabs
Copy link
Owner

andlabs commented May 25, 2016

Does what I said sound fine? I added uiMainStep() in the meantime.

@pcwalton
Copy link
Contributor

Yup, sounds good :) I'm not sure how much time I'll have to work on this in the near term, so feel free to take it if you'd like.

@pcwalton
Copy link
Contributor

pcwalton commented May 30, 2016

I've started on this: http://github.com/pcwalton/libui/tree/gl

Tasks:

  • Declare the basic interface.
  • Write an example.
  • Implement basic functionality on Mac.
  • Implement basic functionality on Linux.
  • Implement basic functionality on Windows.
  • Unify the interface with uiArea to allow for event handling, etc.
  • Unify the interface per above on Mac.
  • Unify the interface per above on Linux.
  • Unify the interface per above on Windows.
  • Add support for an InitGL callback per request on Mac.
  • Add support for an InitGL callback per request on Linux.
  • Improve the example to show animation, etc.

@andlabs
Copy link
Owner

andlabs commented May 31, 2016

For unification, I was thinking of having a uiAreaEventHandler with just the event handler interface, that both uiAreaHandler and uiOpenGLAreaHandler (if that one is needed) derive from in the same COM-like way uiDarwinControl derives from uiControl.

On the backend, the area event handling code would be split and a uiAreaEventState object would be used to handle events. These would be accessible via functions on GTK+, a BOOL handlmessage(HWND, UINT, WPARAM, LPARAM, LRESULT *) type thing on Windows, and an Objective-C class that implements the requisite methods on OS X. Each uiArea would have one of these and delegate their input handling work to that helper object.

@pcwalton
Copy link
Contributor

Excellent, that sounds totally doable.

@andlabs
Copy link
Owner

andlabs commented Jun 6, 2016

What branch is this on again? I forgot already.

@pcwalton
Copy link
Contributor

pcwalton commented Jun 6, 2016

The gl branch.

@andlabs
Copy link
Owner

andlabs commented Jun 6, 2016

Looks good to me so far :) If you want to merge it now, all that would need to be changed is the build system setup. Unless you want to wait for the Windows support?

@pcwalton
Copy link
Contributor

pcwalton commented Jun 6, 2016

I'm working on Windows right now.

@pcwalton
Copy link
Contributor

I have Windows support via WGL drafted and am debugging it now.

@andlabs
Copy link
Owner

andlabs commented Jun 12, 2016

Cool. I'm working on the uiGrid layout control; I can start merging other things once I finish that up.

@trevex
Copy link

trevex commented Jun 12, 2016

Great work so far, I have been following the progress closely, because OpenGL support would be mandatory, if I wanted to replace the current GUI system with libui to support other platforms.
One question that has arisen though is, whether rendering in a background thread is possible? I noticed MakeCurrent is exposed, so in theory everything is in place, but are there any known limitations in regards to threading?

@kainjow
Copy link
Contributor

kainjow commented Jun 12, 2016

On OS X CVDisplayLink I believe is the recommended way to use OpenGL, and that runs in a separate thread.

@pcwalton
Copy link
Contributor

I don't like CVDisplayLink much: it doesn't synchronize to the vertical retrace, only to the vertical retrace interval. It's the equivalent of setting a kernel timer for 60 Hz—in fact, that's what it does (assuming your monitor refresh rate is 60 Hz). The result is that CVDisplayLink doesn't relieve you of the need to set an appropriate swap interval and enable vsync. And if you do set an appropriate swap interval and block in CGLFlushDrawable, then there's usually no need to use CVDisplayLink.

@trevex
Copy link

trevex commented Jun 13, 2016

To reiterate somehow: Sorry, if I didn't made myself clear. I meant users being able to use rendering threads with libui rather than libui using a rendering thread. As I mentioned MakeCurrent is there and basically all you need, but I wanted to know whether there are any limitations regarding threading and safety of libui and/or specific GUI backends, e.g. is SwapBuffers thread-safe?

@pcwalton
Copy link
Contributor

uiOpenGLAreaMakeCurrent is guaranteed to be thread-safe in that it can be called from a thread other than the thread you created the area on, but a context can only belong to one thread at a time. I believe you can also call uiOpenGLAreaSwapBuffers from any thread that the context is current for, though I would need to double-check this.

@andlabs
Copy link
Owner

andlabs commented Jun 14, 2016

Quick updates:

  • uiArea scrolling sizes are now int
  • uiMouseEvent Down, Up, and Count are also now int

(as per #25)

@andlabs
Copy link
Owner

andlabs commented Jun 29, 2016

Any progress? :)

@pcwalton
Copy link
Contributor

Sorry, haven't had a lot of time for this lately…

@dgellow
Copy link

dgellow commented Jan 1, 2017

Any update?

@zatherz
Copy link

zatherz commented Mar 8, 2017

Bump.

@DCubix
Copy link

DCubix commented May 30, 2018

Any update on this?

@mischnic
Copy link
Contributor

mischnic commented Aug 9, 2018

I have Windows support via WGL drafted and am debugging it now.

@pcwalton How finished is the Windows support? Someone also did an implementation in #265.

@mischnic mischnic linked a pull request Aug 9, 2018 that will close this issue
@pcwalton
Copy link
Contributor

pcwalton commented Aug 9, 2018

My work is so old that it's not worth using anymore. Use the other implementation :)

@mischnic
Copy link
Contributor

mischnic commented Aug 10, 2018

@pcwalton Do you have a solution to the gl.h header on Windows only containing opengl 1.1 functions (maybe without other dependencies like GLFW)? The example doesn't compile. (And things like wglSwapIntervalEXT and wglCreateContextAttribsARB)

@andlabs andlabs added this to the Post-Alpha 5 milestone Dec 31, 2018
bors-servo pushed a commit to servo/servo that referenced this issue Feb 6, 2019
Some tweaks in libsimpleservo C API

- Adding logs.
- Adding OpenGL support for OSX.
- Fixing file reading issue.

With this, I can load Servo into a C app (with the C version of libui + andlabs/libui#34).

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/22832)
<!-- Reviewable:end -->
@naps62
Copy link

naps62 commented Jul 4, 2020

@andlabs have there been any progresses on this? Looking at #265, it seems stale as well. I was hoping to use this library on a project, but I need to draw from a buffer (OpenGL, SDL, anything would work really)

@mischnic
Copy link
Contributor

mischnic commented Jul 4, 2020

#405 is somewhat newer, but probably just as stale....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants