diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx | 41 | ||||
| -rw-r--r-- | src/glut_compatibility.cxx | 24 |
2 files changed, 65 insertions, 0 deletions
diff --git a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx index 4d47c3015..b14ac6a17 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx @@ -304,6 +304,47 @@ FL_EXPORT NSOpenGLContext *fl_mac_glcontext(GLContext rc) { } +/* macOS offers only core contexts when using GL3. This forbids to add + FLTK widgets to a GL3-using Fl_Gl_Window because these widgets are drawn + with the GL1-based Fl_OpenGL_Graphics_Driver. The solution implemented here + is to create, with public function fl_mac_prepare_add_widgets_to_GL3_win(), + an additional Fl_Gl_Window placed above and sized as the GL3-based window, + to give it a non opaque, GL1-based context, and to put the FLTK widgets + in that additional window. + */ + +class transparentGlWindow : public Fl_Gl_Window { // utility class + bool need_remove_opacity; +public: + transparentGlWindow(int x, int y, int w, int h) : Fl_Gl_Window(x, y, w, h) { + mode(FL_RGB8 | FL_ALPHA | FL_SINGLE); + need_remove_opacity = true; + } + void show() { + Fl_Gl_Window::show(); + if (need_remove_opacity) { + need_remove_opacity = false; + Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(this); + d->remove_gl_context_opacity((NSOpenGLContext*)context()); + } + } +}; + + +Fl_Gl_Window *fl_mac_prepare_add_widgets_to_GL3_win(Fl_Gl_Window *gl3win) { + gl3win->begin(); + transparentGlWindow *transp = new transparentGlWindow(0, 0, + gl3win->w(), gl3win->h()); + gl3win->end(); + if (!gl3win->resizable()) gl3win->resizable(gl3win); + if (gl3win->shown()) { + transp->show(); + gl3win->make_current(); + } + return transp; +} + + class Fl_Gl_Cocoa_Plugin : public Fl_Cocoa_Plugin { public: Fl_Gl_Cocoa_Plugin() : Fl_Cocoa_Plugin(name()) { } diff --git a/src/glut_compatibility.cxx b/src/glut_compatibility.cxx index 0a5a6b30e..011f9290b 100644 --- a/src/glut_compatibility.cxx +++ b/src/glut_compatibility.cxx @@ -30,6 +30,9 @@ # include "Fl_Screen_Driver.H" # include <FL/glut.H> # define MAXWINDOWS 32 +# ifndef GL_CURRENT_PROGRAM +# define GL_CURRENT_PROGRAM 0x8B8D // from glew.h +# endif static Fl_Glut_Window *windows[MAXWINDOWS+1]; @@ -54,6 +57,27 @@ void Fl_Glut_Window::draw() { indraw = 1; if (!valid()) {reshape(pixel_w(),pixel_h()); valid(1);} display(); + if (children()) { + if ((mode() & FL_OPENGL3)) { +#ifndef __APPLE__ + typedef void (*glUseProgram_type)(GLint); + static glUseProgram_type glUseProgram_f = NULL; + if (!glUseProgram_f) { + Fl_Gl_Window_Driver *dr = Fl_Gl_Window_Driver::driver(this); + glUseProgram_f = (glUseProgram_type)dr->GetProcAddress("glUseProgram"); + } + GLint current_prog = 0; + glGetIntegerv(GL_CURRENT_PROGRAM, ¤t_prog); + // Switch from GL3-style to GL1-style drawing; + // good under Windows, X11 and Wayland; impossible under macOS. + glUseProgram_f(0); + // Draw FLTK child widgets + Fl_Gl_Window::draw(); + // Switch back to GL3-style drawing + glUseProgram_f((GLuint)current_prog); +#endif // ! __APPLE__ + } else Fl_Gl_Window::draw(); // Draw FLTK child widgets + } indraw = 0; } |
