From 7851ae32521c3138d6c2749c1bd591311813eb6f Mon Sep 17 00:00:00 2001 From: Bill Spitzak Date: Sat, 18 Mar 2000 10:04:18 +0000 Subject: [PATCH] OpenGL overlays now work on NT! git-svn-id: file:///fltk/svn/fltk/branches/branch-1.0@1044 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/Fl_Gl_Choice.H | 9 ++++--- src/Fl_Gl_Choice.cxx | 59 ++++++++++++++++++++++++------------------- src/Fl_Gl_Overlay.cxx | 48 +++++++++++++++-------------------- src/Fl_Gl_Window.cxx | 40 +++++++++++++---------------- 4 files changed, 76 insertions(+), 80 deletions(-) diff --git a/src/Fl_Gl_Choice.H b/src/Fl_Gl_Choice.H index e49eff019..2aaeface5 100644 --- a/src/Fl_Gl_Choice.H +++ b/src/Fl_Gl_Choice.H @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Choice.H,v 1.4.2.1 1999/09/16 05:34:24 bill Exp $" +// "$Id: Fl_Gl_Choice.H,v 1.4.2.2 2000/03/18 10:04:17 bill Exp $" // // OpenGL definitions for the Fast Light Tool Kit (FLTK). // @@ -62,10 +62,11 @@ class Fl_Gl_Choice { Fl_Gl_Choice *next; public: #ifdef WIN32 - PIXELFORMATDESCRIPTOR pfd; + int pixelformat; // the visual to use + PIXELFORMATDESCRIPTOR pfd; // some wgl calls need this thing #else XVisualInfo *vis; // the visual to use - Colormap colormap; // a colormap to use + Colormap colormap; // a colormap for that visual #endif uchar r,d,o; // rgb mode, double buffered, overlay flags // Return one of these structures for a given gl mode. @@ -90,5 +91,5 @@ void fl_no_gl_context(); #endif // -// End of "$Id: Fl_Gl_Choice.H,v 1.4.2.1 1999/09/16 05:34:24 bill Exp $". +// End of "$Id: Fl_Gl_Choice.H,v 1.4.2.2 2000/03/18 10:04:17 bill Exp $". // diff --git a/src/Fl_Gl_Choice.cxx b/src/Fl_Gl_Choice.cxx index ed6f93ffc..b075412f7 100644 --- a/src/Fl_Gl_Choice.cxx +++ b/src/Fl_Gl_Choice.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Choice.cxx,v 1.5.2.1 1999/09/16 05:34:25 bill Exp $" +// "$Id: Fl_Gl_Choice.cxx,v 1.5.2.2 2000/03/18 10:04:17 bill Exp $" // // OpenGL visual selection code for the Fast Light Tool Kit (FLTK). // @@ -29,7 +29,6 @@ #include #include #include - #include "Fl_Gl_Choice.H" static Fl_Gl_Choice *first; @@ -103,26 +102,35 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) { #else - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL, - PFD_TYPE_RGBA, 8 }; - - if (mode & FL_INDEX) { - pfd.iPixelType = PFD_TYPE_COLORINDEX; - pfd.cColorBits = 8; - } else { - if (mode & FL_ALPHA) pfd.cAlphaBits = 8; - if (mode & FL_ACCUM) { - pfd.cAccumBits = 6; // Wonko: I didn't find any documentation on those bits - pfd.cAccumGreenBits = 1; // Wonko: They don't seem to get any support yet (4/98) - if (mode & FL_ALPHA) pfd.cAccumAlphaBits = 1; + // Replacement for ChoosePixelFormat() that finds one with an overlay + // if possible: + if (!fl_gc) fl_GetDC(0); + int pixelformat = 0; + PIXELFORMATDESCRIPTOR chosen_pfd; + for (int i = 1; ; i++) { + PIXELFORMATDESCRIPTOR pfd; + if (!DescribePixelFormat(fl_gc, i, sizeof(pfd), &pfd)) break; + // continue if it does not satisfy our requirements: + if (~pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL)) continue; + if (pfd.iPixelType != ((mode&FL_INDEX)?1:0)) continue; + if ((mode & FL_ALPHA) && !pfd.cAlphaBits) continue; + if ((mode & FL_ACCUM) && !pfd.cAccumBits) continue; + if ((!(mode & FL_DOUBLE)) != (!(pfd.dwFlags & PFD_DOUBLEBUFFER))) continue; + if ((mode & FL_DEPTH) && !pfd.cDepthBits) continue; + if ((mode & FL_STENCIL) && !pfd.cStencilBits) continue; + // see if better than the one we have already: + if (pixelformat) { + // offering overlay is better: + if (!(chosen_pfd.bReserved & 15) && (pfd.bReserved & 15)) {} + // otherwise more bit planes is better: + else if (chosen_pfd.cColorBits < pfd.cColorBits) {} + else continue; } + pixelformat = i; + chosen_pfd = pfd; } - if (mode & FL_DOUBLE) pfd.dwFlags |= PFD_DOUBLEBUFFER; - if (mode & FL_DEPTH) pfd.cDepthBits = 16; - if (mode & FL_STENCIL) pfd.cStencilBits = 1; - pfd.bReserved = 1; // always ask for overlay + //printf("Chosen pixel format is %d\n", pixelformat); + if (!pixelformat) return 0; #endif @@ -133,7 +141,8 @@ Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) { first = g; #ifdef WIN32 - memcpy(&g->pfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR)); + g->pixelformat = pixelformat; + g->pfd = chosen_pfd; g->d = ((mode&FL_DOUBLE) != 0); g->r = (mode & FL_INDEX); g->o = 0; // not an overlay @@ -164,10 +173,8 @@ HDC fl_private_dc(Fl_Window* w, int mode, Fl_Gl_Choice **gp) { if (!i->private_dc) { i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE); Fl_Gl_Choice *g = Fl_Gl_Choice::find(mode, 0); - if (gp) *gp = g; - int pixelFormat = ChoosePixelFormat(i->private_dc, &g->pfd); - if (!pixelFormat) {Fl::error("Insufficient GL support"); return NULL;} - SetPixelFormat(i->private_dc, pixelFormat, &g->pfd); + if (gp) *gp = g; + SetPixelFormat(i->private_dc, g->pixelformat, &g->pfd); #if USE_COLORMAP if (fl_palette) SelectPalette(i->private_dc, fl_palette, FALSE); #endif @@ -206,5 +213,5 @@ void fl_no_gl_context() { #endif // -// End of "$Id: Fl_Gl_Choice.cxx,v 1.5.2.1 1999/09/16 05:34:25 bill Exp $". +// End of "$Id: Fl_Gl_Choice.cxx,v 1.5.2.2 2000/03/18 10:04:17 bill Exp $". // diff --git a/src/Fl_Gl_Overlay.cxx b/src/Fl_Gl_Overlay.cxx index fe67cfb7f..d9416e9e4 100644 --- a/src/Fl_Gl_Overlay.cxx +++ b/src/Fl_Gl_Overlay.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.2 1999/10/23 05:59:26 bill Exp $" +// "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.3 2000/03/18 10:04:17 bill Exp $" // // OpenGL overlay code for the Fast Light Tool Kit (FLTK). // @@ -64,13 +64,13 @@ public: void show(); _Fl_Gl_Overlay(int x, int y, int w, int h) : Fl_Gl_Window(x,y,w,h) { + set_flag(INACTIVE); overlay_choice.vis = fl_overlay_visual; overlay_choice.colormap = fl_overlay_colormap; overlay_choice.r = 0; overlay_choice.d = 0; overlay_choice.o = 1; g = &overlay_choice; - set_flag(INACTIVE); } }; @@ -103,11 +103,9 @@ int Fl_Gl_Window::can_do_overlay() { #else // WIN32: -static int no_overlay_hardware; int Fl_Gl_Window::can_do_overlay() { - if (no_overlay_hardware) return 0; - // need to write a test here... - return 1; + Fl_Gl_Choice* choice = Fl_Gl_Choice::find(0,0); + return (choice && (choice->pfd.bReserved & 15)); } #endif @@ -122,28 +120,24 @@ void Fl_Gl_Window::make_overlay() { if (!overlay) { #if HAVE_GL_OVERLAY #ifdef WIN32 - if (!no_overlay_hardware) { - HDC hdc = fl_private_dc(this, mode_,&g); - GLXContext context = wglCreateLayerContext(hdc, 1); - if (!context) { // no overlay hardware - no_overlay_hardware = 1; - } else { - // copy all colors except #0 into the overlay palette: - COLORREF pcr[256]; - for (int i = 0; i < 256; i++) { - uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b); - pcr[i] = RGB(r,g,b); - } - wglSetLayerPaletteEntries(hdc, 1, 1, 255, pcr+1); - wglRealizeLayerPalette(hdc, 1, TRUE); - if (fl_first_context) wglShareLists(fl_first_context, context); - else fl_first_context = context; - overlay = context; - valid(0); - return; + HDC hdc = fl_private_dc(this, mode_,&g); + GLXContext context = wglCreateLayerContext(hdc, 1); + if (context) { + if (fl_first_context) wglShareLists(fl_first_context, context); + else fl_first_context = context; + overlay = context; + // copy all colors except #0 into the overlay palette: + COLORREF pcr[256]; + for (int i = 0; i < 256; i++) { + uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b); + pcr[i] = RGB(r,g,b); } + wglSetLayerPaletteEntries(hdc, 1, 1, 255, pcr+1); + wglRealizeLayerPalette(hdc, 1, TRUE); + valid(0); + return; } -#else +#else // glX version: if (can_do_overlay()) { _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h()); overlay = o; @@ -195,5 +189,5 @@ void Fl_Gl_Window::hide_overlay() { #endif // -// End of "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.2 1999/10/23 05:59:26 bill Exp $". +// End of "$Id: Fl_Gl_Overlay.cxx,v 1.5.2.3 2000/03/18 10:04:17 bill Exp $". // diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx index efce8348d..83242e957 100644 --- a/src/Fl_Gl_Window.cxx +++ b/src/Fl_Gl_Window.cxx @@ -1,5 +1,5 @@ // -// "$Id: Fl_Gl_Window.cxx,v 1.12.2.7 2000/03/05 06:51:05 bill Exp $" +// "$Id: Fl_Gl_Window.cxx,v 1.12.2.8 2000/03/18 10:04:18 bill Exp $" // // OpenGL window code for the Fast Light Tool Kit (FLTK). // @@ -70,20 +70,7 @@ extern HPALETTE fl_gl_palette; //////////////////////////////////////////////////////////////// int Fl_Gl_Window::can_do(int a, const int *b) { -#ifdef WIN32 - Fl_Gl_Choice *g = Fl_Gl_Choice::find(a,b); -/* - Is this necessary? Don't all windows have the same - support for pixel formats? - HWND w = GetDesktopWindow(); - HDC dc = GetDC(w); -*/ - if (!fl_gc) fl_GetDC(0); - int r = ChoosePixelFormat(fl_gc, &g->pfd); - return r != 0; -#else return Fl_Gl_Choice::find(a,b) != 0; -#endif } void Fl_Gl_Window::show() { @@ -150,11 +137,18 @@ void Fl_Gl_Window::make_current() { } void Fl_Gl_Window::ortho() { - GLint p[2]; - glGetIntegerv(GL_MAX_VIEWPORT_DIMS, p); +// Alpha NT seems to have a broken OpenGL that does not like negative coords: +#ifdef _M_ALPHA glLoadIdentity(); - glViewport(w()-p[0], h()-p[1], p[0], p[1]); - glOrtho(w()-p[0], w(), h()-p[1], h(), -1, 1); + glViewport(0, 0, w(), h()); + glOrtho(0, w(), 0, h(), -1, 1); +#else + GLint v[2]; + glGetIntegerv(GL_MAX_VIEWPORT_DIMS, v); + glLoadIdentity(); + glViewport(w()-v[0], h()-v[1], v[0], v[1]); + glOrtho(w()-v[0], w(), h()-v[1], h(), -1, 1); +#endif } void Fl_Gl_Window::swap_buffers() { @@ -174,11 +168,9 @@ uchar fl_overlay; // changes how fl_color() works void Fl_Gl_Window::flush() { make_current(); -#if HAVE_GL_OVERLAY -#ifdef WIN32 +#if defined(_WIN32) && HAVE_GL_OVERLAY uchar save_valid = valid_; if (overlay && overlay!= this && damage() == FL_DAMAGE_OVERLAY) goto DRAW_OVERLAY_ONLY; -#endif #endif if (g->d) { @@ -202,7 +194,6 @@ void Fl_Gl_Window::flush() { uchar save_valid = valid_; // don't draw if only the overlay is damaged: if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !valid()) draw(); - // we use a seperate context for the copy because rasterpos must be 0 // and depth test needs to be off: static GLXContext ortho_context = 0; @@ -264,6 +255,8 @@ void Fl_Gl_Window::flush() { #ifdef WIN32 if (overlay && overlay != this) { DRAW_OVERLAY_ONLY: + // Draw into hardware overlay planes + if (!g->d) SetCursor(0); // SGI system messes up overlay over singlebuffer valid_ = save_valid; fl_set_gl_context(this, (GLXContext)overlay); glDisable(GL_SCISSOR_TEST); @@ -272,6 +265,7 @@ void Fl_Gl_Window::flush() { draw_overlay(); wglSwapLayerBuffers(Fl_X::i(this)->private_dc,WGL_SWAP_OVERLAY1); fl_overlay = 0; + if (!g->d) SetCursor(Fl_X::i(this)->cursor); } #endif #endif @@ -324,5 +318,5 @@ void Fl_Gl_Window::draw_overlay() {} #endif // -// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.7 2000/03/05 06:51:05 bill Exp $". +// End of "$Id: Fl_Gl_Window.cxx,v 1.12.2.8 2000/03/18 10:04:18 bill Exp $". //