[fltk.bugs] [HIGH] STR #2944: Mac OS X Fl_Gl_Window bugs - all FLTK versions
DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW. [STR New] Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2 Patches for several Mac OS X Fl_Gl_Window bugs. I believe that these patches apply to ALL FLTK versions, with possible minor modifications to account for API differences. 1. Fl_Gl_Window::swap_buffers bug when a Gl_Window (simulated) overlay is used: glRasterPos is not properly set before calling glCopyPixels. This occurs when gl_draw(const char* str, int n) has been called to draw a string into the Gl_Window, which changed glRasterPos. 2. Fl_Gl_Window::make_current bug when the Gl_Window is inside nested Fl_Windows. The computation for the x and y values of the xywh array passed to aglSetInteger(context_, AGL_BUFFER_RECT, xywh) does not take this nesting into account, causing the Gl_Window drawing area to be incorrectly placed inside the main window. 3. Fl_Gl_Window::redraw_overlay unnecessarily redrawing everything rather than just the overlay. Apparently this was stale code that assumes that complete redraws were always needed on Mac OS X. Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2Index: src/Fl_Gl_Window.cxx === --- src/Fl_Gl_Window.cxx(revision 9857) +++ src/Fl_Gl_Window.cxx(working copy) @@ -181,10 +181,22 @@ // Set the buffer rectangle here, since in resize() we won't have the // correct parent window size to work with... GLint xywh[4]; - if (window()) { -xywh[0] = x(); -xywh[1] = window()->h() - y() - h(); +int xp = 0, yp = 0; +Fl_Window *win = this; +// Code fragment from Fl_Window::make_current() in Fl_mac.cxx +// Compute xp, yp offset of upper left corner of Gl_Window relative to top-level window +// accounting possible nesting of windows. +while ( win ) + { + if ( !win->window() ) + break; + xp += win->x(); + yp += win->y(); + win = (Fl_Window*)win->window(); + } +xywh[0] = xp; +xywh[1] = win->h() - yp - h(); } else { xywh[0] = 0; xywh[1] = 0; @@ -195,7 +207,7 @@ aglSetInteger(context_, AGL_BUFFER_RECT, xywh); aglEnable(context_, AGL_BUFFER_RECT); -// printf("make_current: xywh=[%d %d %d %d]\n", xywh[0], xywh[1], xywh[2], xywh[3]); + // printf("make_current: xywh=[%d %d %d %d]\n", xywh[0], xywh[1], xywh[2], xywh[3]); #endif // __APPLE__ #if defined(WIN32) && USE_COLORMAP @@ -249,10 +261,28 @@ # endif #elif defined(__APPLE_QUARTZ__) if(overlay != NULL) { -//aglSwapBuffers does not work well with overlays under cocoa +int wo=w(); int ho=h(); +GLint matrixMode; +glGetIntegerv (GL_MATRIX_MODE, &matrixMode); +glMatrixMode (GL_PROJECTION); +glPushMatrix(); // save original GL matrices +glLoadIdentity (); +glMatrixMode (GL_MODELVIEW); +glPushMatrix(); +glLoadIdentity (); +glScalef (2.0f / wo, 2.0f / ho, 1.0f); +glTranslatef (-wo / 2.0f, -ho / 2.0f, 0.0f);// set transform so that 0,0 is the bottom left corner of Gl_Window +GLfloat pos[4]; +glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); // save original glRasterPos +glRasterPos2i(0,0); // set glRasterPos to bottom left corner glReadBuffer(GL_BACK); glDrawBuffer(GL_FRONT); -glCopyPixels(0,0,w(),h(),GL_COLOR); +glCopyPixels(0,0,wo,ho,GL_COLOR); // copy GL_BACK to GL_FRONT +glPopMatrix(); // GL_MODELVIEW // restore original matrices +glMatrixMode (GL_PROJECTION); +glPopMatrix(); +glMatrixMode (matrixMode); +glRasterPos3f(pos[0],pos[1],pos[2]);// restore original glRasterPos } else aglSwapBuffers((AGLContext)context_); @@ -261,6 +291,7 @@ #endif } + #if HAVE_GL_OVERLAY && defined(WIN32) uchar fl_overlay; // changes how fl_color() works int fl_overlay_depth = 0; Index: src/Fl_Gl_Overlay.cxx === --- src/Fl_Gl_Overlay.cxx (revision 9857) +++ src/Fl_Gl_Overlay.cxx (working copy) @@ -187,18 +187,18 @@ void Fl_Gl_Window::redraw_overlay() { if (!shown()) return; make_overlay(); -#ifdef __APPLE__ - redraw(); -#else + #ifndef WIN32 - if (overlay != this) + if (overlay && (overlay != this)) ((Fl_Gl_Window*)overlay)->redraw(); else #endif damage(FL_DAMAGE_OVERLAY); -#endif } + + + void Fl_Gl_Window::make_overlay_current() { make_overlay(); #ifdef __APPLE__ ___ fltk-bugs mailing list fltk-bugs@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-bugs
Re: [fltk.bugs] [HIGH] STR #2944: Mac OS X Fl_Gl_Window bugs - all FLTK versions
DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW. [STR New] Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2 Thanks for the patches! Can you supply a small compilable app that demonstrates the problem for (1) and (2)? Along the lines of e.g. http://seriss.com/people/erco/fltk/#OpenGlSimple Would like to verify the behavior described. Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2 ___ fltk-bugs mailing list fltk-bugs@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-bugs
Re: [fltk.bugs] [HIGH] STR #2944: Mac OS X Fl_Gl_Window bugs - all FLTK versions
DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW. [STR New] Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2 Attached file "GlWindow-rasterpos-bug.c++"... Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2// LHQuam modification to gl_overlay.cxx to demonstrate Mac OS X Gl_Window glRasterPos bug // when drawing text using gl_draw to Gl_Window AND using draw_overlay. // On Mac OS X // g++ -g -Wno-deprecated-declarations -Wall -Wunused -Wno-format-y2k -fPIC -fno-exceptions -fno-strict-aliasing -I/homedir/quam/Q/downloads/fltk/fltk-1.3.2-mac/ -o GlWindow-rasterpos-bug GlWindow-rasterpos-bug.c++ -L/opt/local/lib -lfltk_gl -lfltk -framework AGL -framework OpenGL -framework ApplicationServices -framework Cocoa // On Mac OS X: To redirect to alternate library location: // export DYLD_LIBRARY_PATH=/homedir/quam/Q/downloads/fltk/fltk-1.3.2-mac/src // On Linux //g++ -g -Wno-deprecated-declarations -Wall -Wunused -Wno-format-y2k -fPIC -fno-exceptions -fno-strict-aliasing -I/homedir/quam/Q/downloads/fltk/fltk-1.3.2/ -o GlWindow-rasterpos-bug GlWindow-rasterpos-bug.c++ -L/homedir/quam/downloads/fltk/fltk-1.3.2/src/ -lfltk.1.3 -lfltk_gl.1.3 -lGL // On Linux: To redirect to alternate library location: // set environment LD_LIBRARY_PATH=/homedir/quam/downloads/fltk/fltk-1.3-SVN-20130404/src // // "$Id: gl_overlay.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $" // // OpenGL overlay test program for the Fast Light Tool Kit (FLTK). // // Copyright 1998-2010 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this // file is missing or damaged, see the license at: // // http://www.fltk.org/COPYING.php // // Please report all bugs and problems on the following page: // // http://www.fltk.org/str.php // #include #include #include #include #include #include #if !HAVE_GL #include class shape_window : public Fl_Box { public: int sides; shape_window(int x,int y,int w,int h,const char *l=0) :Fl_Box(FL_DOWN_BOX,x,y,w,h,l){ label("This demo does\nnot work without GL"); } }; #else #include #include class shape_window : public Fl_Gl_Window { void draw(); void draw_overlay(); public: int sides; int overlay_sides; shape_window(int x,int y,int w,int h,const char *l=0); }; shape_window::shape_window(int x,int y,int w,int h,const char *l) : Fl_Gl_Window(x,y,w,h,l) { sides = overlay_sides = 3; } void shape_window::draw() { // the valid() property may be used to avoid reinitializing your // GL transformation for each redraw: if (!valid()) { valid(1); glLoadIdentity(); glViewport(0,0,w(),h()); } // draw an amazing but slow graphic: glClear(GL_COLOR_BUFFER_BIT); // for (int j=1; j<=1000; j++) { glBegin(GL_POLYGON); for (int j=0; jsides = int(((Fl_Slider *)o)->value()); sw->redraw(); } #if HAVE_GL void overlay_sides_cb(Fl_Widget *o, void *p) { shape_window *sw = (shape_window *)p; sw->overlay_sides = int(((Fl_Slider *)o)->value()); sw->redraw_overlay(); } #endif #include int main(int argc, char **argv) { Fl_Window window(300, 370); shape_window sw(10, 75, window.w()-20, window.h()-90); //sw.mode(FL_RGB); window.resizable(&sw); Fl_Hor_Slider slider(60, 5, window.w()-70, 30, "Sides:"); slider.align(FL_ALIGN_LEFT); slider.callback(sides_cb,&sw); slider.value(sw.sides); slider.step(1); slider.bounds(3,40); Fl_Hor_Slider oslider(60, 40, window.w()-70, 30, "Overlay:"); oslider.align(FL_ALIGN_LEFT); #if HAVE_GL oslider.callback(overlay_sides_cb,&sw); oslider.value(sw.overlay_sides); #endif oslider.step(1); oslider.bounds(3,40); window.end(); window.show(argc,argv); #if HAVE_GL printf("Can do overlay = %d\n", sw.can_do_overlay()); sw.show(); sw.redraw_overlay(); #else sw.show(); #endif return Fl::run(); } // // End of "$Id: gl_overlay.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $". // ___ fltk-bugs mailing list fltk-bugs@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-bugs
Re: [fltk.bugs] [HIGH] STR #2944: Mac OS X Fl_Gl_Window bugs - all FLTK versions
DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW. [STR New] Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2 Attached file "GlWindow-nested-window-bug.c++"... Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2// LHQuam modification to shape.cxx to demonstrate Mac OS X Gl_Window bug when the Gl_Window // is inside nested Fl_Windows. // // On Mac OS X // g++ -g -Wno-deprecated-declarations -Wall -Wunused -Wno-format-y2k -fPIC -fno-exceptions -fno-strict-aliasing -I/homedir/quam/Q/downloads/fltk/fltk-1.3.2-mac/ -o GlWindow-nested-window-bug GlWindow-nested-window-bug.c++ -L/opt/local/lib -lfltk_gl -lfltk -framework AGL -framework OpenGL -framework ApplicationServices -framework Cocoa // On Mac OS X: To redirect to alternate library location: // export DYLD_LIBRARY_PATH=/homedir/quam/Q/downloads/fltk/fltk-1.3.2-mac/src // On Linux //g++ -g -Wno-deprecated-declarations -Wall -Wunused -Wno-format-y2k -fPIC -fno-exceptions -fno-strict-aliasing -I/homedir/quam/Q/downloads/fltk/fltk-1.3.2/ -o GlWindow-nested-window-bug GlWindow-nested-window-bug.c++ -L/homedir/quam/downloads/fltk/fltk-1.3.2/src/ -lfltk.1.3 -lfltk_gl.1.3 -lGL // On Linux: To redirect to alternate library location: // set environment LD_LIBRARY_PATH=/homedir/quam/downloads/fltk/fltk-1.3-SVN-20130404/src // ## // "$Id: shape.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $" // // Tiny OpenGL demo program for the Fast Light Tool Kit (FLTK). // // Copyright 1998-2010 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this // file is missing or damaged, see the license at: // // http://www.fltk.org/COPYING.php // // Please report all bugs and problems on the following page: // // http://www.fltk.org/str.php // #include #include #include #include #include #if HAVE_GL #include #include class shape_window : public Fl_Gl_Window { void draw(); public: int sides; shape_window(int x,int y,int w,int h,const char *l=0); }; shape_window::shape_window(int x,int y,int w,int h,const char *l) : Fl_Gl_Window(x,y,w,h,l) { sides = 3; } void shape_window::draw() { // the valid() property may be used to avoid reinitializing your // GL transformation for each redraw: if (!valid()) { valid(1); glLoadIdentity(); glViewport(0, 0, w(), h()); } // draw an amazing graphic: glClear(GL_COLOR_BUFFER_BIT); glColor3f(.5,.6,.7); glBegin(GL_POLYGON); for (int j=0; j class shape_window : public Fl_Box { public: int sides; shape_window(int x,int y,int w,int h,const char *l=0) :Fl_Box(FL_DOWN_BOX,x,y,w,h,l){ label("This demo does\nnot work without GL"); } }; #endif // when you change the data, as in this callback, you must call redraw(): void sides_cb(Fl_Widget *o, void *p) { shape_window *sw = (shape_window *)p; sw->sides = int(((Fl_Slider *)o)->value()); sw->redraw(); } int main(int argc, char **argv) { Fl_Window window(300, 330); // top-level Fl_Window Fl_Window win2(0,0,300,290); // Fl_Window nested inside top-level Fl_Window shape_window sw(10, 10, 280, 280); // make it resize: win2.resizable(&sw); win2.end(); window.resizable(&win2); // window.size_range(300,330,0,0,1,1,1); // add a knob to control it: Fl_Hor_Slider slider(50, 295, window.w()-60, 30, "Sides:"); slider.align(FL_ALIGN_LEFT); slider.callback(sides_cb,&sw); slider.value(sw.sides); slider.step(1); slider.bounds(3,40); window.end(); window.show(argc,argv); return Fl::run(); } // // End of "$Id: shape.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $". // ___ fltk-bugs mailing list fltk-bugs@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-bugs
Re: [fltk.bugs] [HIGH] STR #2944: Mac OS X Fl_Gl_Window bugs - all FLTK versions
DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW. [STR New] Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2 I have added files for two test programs that demonstrate the reported Gl_Window bugs. Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2 ___ fltk-bugs mailing list fltk-bugs@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-bugs
Re: [fltk.bugs] [HIGH] STR #2944: Mac OS X Fl_Gl_Window bugs - all FLTK versions
DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW. [STR Active] Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2 Assigning this STR to myself. Confirmed #2: Attaching rasterpos-fix-before-and-after-screenshot.jpg showing the problem/solution, and agree with the suggested fix to Fl_Gl_Window::make_current(). Since finding the window offset is now needed in at least two places in the code, will probably add a method to the Fl_Window base class that returns x/y offsets, and use that to implement the fix. Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2<>___ fltk-bugs mailing list fltk-bugs@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-bugs
Re: [fltk.bugs] [HIGH] STR #2944: Mac OS X Fl_Gl_Window bugs - all FLTK versions
DO NOT REPLY TO THIS MESSAGE. INSTEAD, POST ANY RESPONSES TO THE LINK BELOW. [STR Active] Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2 To fix #2, I'm thinking the attached patch, rasterpos_bugfix.patch, might be a good way to implement the fix with code reuse in mind. This adds a find_offset() method to Fl_Widget.. essentially the same code you provided from Fl_mac.cxx, but made into a method so that both Fl_mac.cxx + Fl_Gl_Window.cxx can use it. Funny thing though, I *think* Fl_mac.cxx is completely unused code, a left over from the de-carbonization of FLTK. (verifying this with the other devs) In which case the code reuse issue might be moot. Still, it's probably useful to have this as a method; awaiting info from the other devs. Anyway, leaving this alternate patch suggestion to fix just #2 here, in case I get pulled off on other stuff and forget where I left off. Link: http://www.fltk.org/str.php?L2944 Version: 1.3.2Index: src/Fl_Gl_Window.cxx === --- src/Fl_Gl_Window.cxx(revision 9861) +++ src/Fl_Gl_Window.cxx(working copy) @@ -183,8 +183,10 @@ GLint xywh[4]; if (window()) { -xywh[0] = x(); -xywh[1] = window()->h() - y() - h(); +int xoff,yoff; +const Fl_Window *win = find_offset(xoff, yoff);// STR #2944 +xywh[0] = xoff; +xywh[1] = win->h() - yoff - h(); } else { xywh[0] = 0; xywh[1] = 0; Index: src/Fl_Window.cxx === --- src/Fl_Window.cxx (revision 9861) +++ src/Fl_Window.cxx (working copy) @@ -278,6 +278,21 @@ icon_ = ic; } +/** + Finds the x/y offset of the current window relative to the top-level window. + \param[out] xoff,yoff Returns the x/y offset + \returns the top-level window +*/ +Fl_Window* Fl_Window::find_offset(int& xoff, int& yoff) const { + xoff = yoff = 0; + const Fl_Window *win = (const Fl_Window*)this; + while (win && win->window()) { +xoff += win->x(); // accumulate offsets +yoff += win->y(); +win = win->window(); // walk up window hierarchy + } + return (Fl_Window*)win; +} // // End of "$Id$". Index: FL/Fl_Window.H === --- FL/Fl_Window.H (revision 9861) +++ FL/Fl_Window.H (working copy) @@ -120,6 +120,7 @@ \see force_position(int) */ int force_position() const { return ((flags() & FORCE_POSITION)?1:0); } + Fl_Window* find_offset(int& xoff, int& yoff) const; public: ___ fltk-bugs mailing list fltk-bugs@easysw.com http://lists.easysw.com/mailman/listinfo/fltk-bugs