From f48d169c4a57bd4ac2f44e42b9fd26a930bbdca0 Mon Sep 17 00:00:00 2001 From: "Unknown (NI)" Date: Thu, 20 Jul 2000 17:31:40 +0000 Subject: [PATCH] applied the patch by Garrick Meeker git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@7793 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/glcanvas.h | 15 +- include/wx/gtk1/glcanvas.h | 15 +- include/wx/motif/glcanvas.h | 24 ++ include/wx/msw/glcanvas.h | 77 ++---- src/motif/glcanvas.cpp | 191 ++++++++------ src/msw/glcanvas.cpp | 506 ++++++++++++++++++++---------------- 6 files changed, 472 insertions(+), 356 deletions(-) diff --git a/include/wx/gtk/glcanvas.h b/include/wx/gtk/glcanvas.h index 14c439691d..813e314738 100644 --- a/include/wx/gtk/glcanvas.h +++ b/include/wx/gtk/glcanvas.h @@ -35,12 +35,21 @@ extern "C" { enum { WX_GL_RGBA=1, /* use true color palette */ - WX_GL_DEPTH_SIZE, /* bits for Z-buffer (0,16,32) */ + WX_GL_BUFFER_SIZE, /* bits for buffer if not WX_GL_RGBA */ + WX_GL_LEVEL, /* 0 for main buffer, >0 for overlay, <0 for underlay */ WX_GL_DOUBLEBUFFER, /* use doublebuffer */ + WX_GL_STEREO, /* use stereoscopic display */ + WX_GL_AUX_BUFFERS, /* number of auxiliary buffers */ WX_GL_MIN_RED, /* use red buffer with most bits (> MIN_RED bits) */ WX_GL_MIN_GREEN, /* use green buffer with most bits (> MIN_GREEN bits) */ - WX_GL_MIN_BLUE /* use blue buffer with most bits (> MIN_BLUE bits) */ -/* these are enough constants for now, the remaining will be added later */ + WX_GL_MIN_BLUE, /* use blue buffer with most bits (> MIN_BLUE bits) */ + WX_GL_MIN_ALPHA, /* use blue buffer with most bits (> MIN_ALPHA bits) */ + WX_GL_DEPTH_SIZE, /* bits for Z-buffer (0,16,32) */ + WX_GL_STENCIL_SIZE, /* bits for stencil buffer */ + WX_GL_MIN_ACCUM_RED, /* use red accum buffer with most bits (> MIN_ACCUM_RED bits) */ + WX_GL_MIN_ACCUM_GREEN, /* use green buffer with most bits (> MIN_ACCUM_GREEN bits) */ + WX_GL_MIN_ACCUM_BLUE, /* use blue buffer with most bits (> MIN_ACCUM_BLUE bits) */ + WX_GL_MIN_ACCUM_ALPHA /* use blue buffer with most bits (> MIN_ACCUM_ALPHA bits) */ }; //--------------------------------------------------------------------------- diff --git a/include/wx/gtk1/glcanvas.h b/include/wx/gtk1/glcanvas.h index 14c439691d..813e314738 100644 --- a/include/wx/gtk1/glcanvas.h +++ b/include/wx/gtk1/glcanvas.h @@ -35,12 +35,21 @@ extern "C" { enum { WX_GL_RGBA=1, /* use true color palette */ - WX_GL_DEPTH_SIZE, /* bits for Z-buffer (0,16,32) */ + WX_GL_BUFFER_SIZE, /* bits for buffer if not WX_GL_RGBA */ + WX_GL_LEVEL, /* 0 for main buffer, >0 for overlay, <0 for underlay */ WX_GL_DOUBLEBUFFER, /* use doublebuffer */ + WX_GL_STEREO, /* use stereoscopic display */ + WX_GL_AUX_BUFFERS, /* number of auxiliary buffers */ WX_GL_MIN_RED, /* use red buffer with most bits (> MIN_RED bits) */ WX_GL_MIN_GREEN, /* use green buffer with most bits (> MIN_GREEN bits) */ - WX_GL_MIN_BLUE /* use blue buffer with most bits (> MIN_BLUE bits) */ -/* these are enough constants for now, the remaining will be added later */ + WX_GL_MIN_BLUE, /* use blue buffer with most bits (> MIN_BLUE bits) */ + WX_GL_MIN_ALPHA, /* use blue buffer with most bits (> MIN_ALPHA bits) */ + WX_GL_DEPTH_SIZE, /* bits for Z-buffer (0,16,32) */ + WX_GL_STENCIL_SIZE, /* bits for stencil buffer */ + WX_GL_MIN_ACCUM_RED, /* use red accum buffer with most bits (> MIN_ACCUM_RED bits) */ + WX_GL_MIN_ACCUM_GREEN, /* use green buffer with most bits (> MIN_ACCUM_GREEN bits) */ + WX_GL_MIN_ACCUM_BLUE, /* use blue buffer with most bits (> MIN_ACCUM_BLUE bits) */ + WX_GL_MIN_ACCUM_ALPHA /* use blue buffer with most bits (> MIN_ACCUM_ALPHA bits) */ }; //--------------------------------------------------------------------------- diff --git a/include/wx/motif/glcanvas.h b/include/wx/motif/glcanvas.h index b3a9ab8016..a869f8e0be 100644 --- a/include/wx/motif/glcanvas.h +++ b/include/wx/motif/glcanvas.h @@ -27,6 +27,30 @@ #include +enum +{ + WX_GL_RGBA=1, /* use true color palette */ + WX_GL_BUFFER_SIZE, /* bits for buffer if not WX_GL_RGBA */ + WX_GL_LEVEL, /* 0 for main buffer, >0 for overlay, <0 for underlay */ + WX_GL_DOUBLEBUFFER, /* use doublebuffer */ + WX_GL_STEREO, /* use stereoscopic display */ + WX_GL_AUX_BUFFERS, /* number of auxiliary buffers */ + WX_GL_MIN_RED, /* use red buffer with most bits (> MIN_RED bits) */ + WX_GL_MIN_GREEN, /* use green buffer with most bits (> MIN_GREEN bits) */ + WX_GL_MIN_BLUE, /* use blue buffer with most bits (> MIN_BLUE bits) */ + WX_GL_MIN_ALPHA, /* use blue buffer with most bits (> MIN_ALPHA bits) */ + WX_GL_DEPTH_SIZE, /* bits for Z-buffer (0,16,32) */ + WX_GL_STENCIL_SIZE, /* bits for stencil buffer */ + WX_GL_MIN_ACCUM_RED, /* use red accum buffer with most bits (> MIN_ACCUM_RED bits) */ + WX_GL_MIN_ACCUM_GREEN, /* use green buffer with most bits (> MIN_ACCUM_GREEN bits) */ + WX_GL_MIN_ACCUM_BLUE, /* use blue buffer with most bits (> MIN_ACCUM_BLUE bits) */ + WX_GL_MIN_ACCUM_ALPHA /* use blue buffer with most bits (> MIN_ACCUM_ALPHA bits) */ +}; + +//--------------------------------------------------------------------------- +// classes +//--------------------------------------------------------------------------- + class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow { DECLARE_CLASS(wxGLCanvas) diff --git a/include/wx/msw/glcanvas.h b/include/wx/msw/glcanvas.h index 73ad346178..534528d559 100644 --- a/include/wx/msw/glcanvas.h +++ b/include/wx/msw/glcanvas.h @@ -31,15 +31,28 @@ // Constants for attriblist //--------------------------------------------------------------------------- +// The generic GL implementation doesn't support most of these options, +// such as stereo, auxiliary buffers, alpha channel, and accum buffer. +// Other implementations may actually support them. + enum { WX_GL_RGBA=1, /* use true color palette */ - WX_GL_DEPTH_SIZE, /* bits for Z-buffer (0,16,32) */ + WX_GL_BUFFER_SIZE, /* bits for buffer if not WX_GL_RGBA */ + WX_GL_LEVEL, /* 0 for main buffer, >0 for overlay, <0 for underlay */ WX_GL_DOUBLEBUFFER, /* use doublebuffer */ + WX_GL_STEREO, /* use stereoscopic display */ + WX_GL_AUX_BUFFERS, /* number of auxiliary buffers */ WX_GL_MIN_RED, /* use red buffer with most bits (> MIN_RED bits) */ WX_GL_MIN_GREEN, /* use green buffer with most bits (> MIN_GREEN bits) */ - WX_GL_MIN_BLUE /* use blue buffer with most bits (> MIN_BLUE bits) */ -/* these are enough constants for now, the remaining will be added later */ + WX_GL_MIN_BLUE, /* use blue buffer with most bits (> MIN_BLUE bits) */ + WX_GL_MIN_ALPHA, /* use blue buffer with most bits (> MIN_ALPHA bits) */ + WX_GL_DEPTH_SIZE, /* bits for Z-buffer (0,16,32) */ + WX_GL_STENCIL_SIZE, /* bits for stencil buffer */ + WX_GL_MIN_ACCUM_RED, /* use red accum buffer with most bits (> MIN_ACCUM_RED bits) */ + WX_GL_MIN_ACCUM_GREEN, /* use green buffer with most bits (> MIN_ACCUM_GREEN bits) */ + WX_GL_MIN_ACCUM_BLUE, /* use blue buffer with most bits (> MIN_ACCUM_BLUE bits) */ + WX_GL_MIN_ACCUM_ALPHA /* use blue buffer with most bits (> MIN_ACCUM_ALPHA bits) */ }; class WXDLLEXPORT wxGLCanvas; /* forward reference */ @@ -80,17 +93,17 @@ class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow wxGLCanvas( wxWindow *parent, const wxGLContext *shared = (wxGLContext *)NULL, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "GLCanvas", - int *attribList = (int*) NULL, const wxPalette& palette = wxNullPalette ); + int *attribList = (int*) NULL, const wxPalette& palette = wxNullPalette ); wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared = (wxGLCanvas *)NULL, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, - const wxString& name = "GLCanvas", int *attribList = 0, const wxPalette& palette = wxNullPalette ); + const wxString& name = "GLCanvas", int *attribList = 0, const wxPalette& palette = wxNullPalette ); ~wxGLCanvas(); // Replaces wxWindow::Create functionality, since we need to use a different window class bool Create(wxWindow *parent, wxWindowID id, - const wxPoint& pos, const wxSize& size, long style, const wxString& name); + const wxPoint& pos, const wxSize& size, long style, const wxString& name); void SetCurrent(); void SetColour(const char *colour); @@ -104,7 +117,7 @@ class WXDLLEXPORT wxGLCanvas: public wxScrolledWindow inline wxGLContext* GetContext() const { return m_glContext; } inline WXHDC GetHDC() const { return m_hDC; } - void SetupPixelFormat(); + void SetupPixelFormat(int *attribList = (int*) NULL); void SetupPalette(const wxPalette& palette); wxPalette CreateDefaultPalette(); @@ -118,56 +131,6 @@ protected: DECLARE_EVENT_TABLE() }; -#ifdef __cplusplus -extern "C" { -#endif - -/* Give extensions proper function names. */ - -/* N.B. - this is not completely implemented as yet */ - -/* EXT_vertex_array */ -void glArrayElementEXT(GLint i); -void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count); -void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer); -void glGetPointervEXT(GLenum pname, GLvoid* *params); -void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); - -/* EXT_color_subtable */ -void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table); - -/* EXT_color_table */ -void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table); -void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params); -void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params); - -/* SGI_compiled_vertex_array */ -void glLockArraysSGI(GLint first, GLsizei count); -void glUnlockArraysSGI(); - -/* SGI_cull_vertex */ -void glCullParameterdvSGI(GLenum pname, GLdouble* params); -void glCullParameterfvSGI(GLenum pname, GLfloat* params); - -/* SGI_index_func */ -void glIndexFuncSGI(GLenum func, GLclampf ref); - -/* SGI_index_material */ -void glIndexMaterialSGI(GLenum face, GLenum mode); - -/* WIN_swap_hint */ -void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height); - -#ifdef __cplusplus -} -#endif - #endif // wxUSE_GLCANVAS #endif diff --git a/src/motif/glcanvas.cpp b/src/motif/glcanvas.cpp index 0c1f9780d2..a7a8e3019a 100644 --- a/src/motif/glcanvas.cpp +++ b/src/motif/glcanvas.cpp @@ -7,7 +7,7 @@ // Created: 1995, 1999 // RCS-ID: $Id$ // Copyright: (c) Julian Smart, Wolfram Gloger -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ @@ -31,8 +31,8 @@ static int bitcount( unsigned long n ) { int bits; for (bits=0; n>0;) { - if(n & 1) bits++; - n = n >> 1; + if(n & 1) bits++; + n = n >> 1; } return bits; } @@ -44,14 +44,10 @@ static int bitcount( unsigned long n ) IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) -wxGLCanvas::wxGLCanvas(wxWindow *parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name, - int *attrib_list, const wxPalette& palette) - : wxScrolledWindow(parent, id, pos, size, style, name) +wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos, + const wxSize& size, long style, + const wxString& name, int *attribList, const wxPalette& palette): + wxScrolledWindow(parent, id, pos, size, style, name) { XVisualInfo *vi, vi_templ; XWindowAttributes xwa; @@ -62,53 +58,96 @@ wxGLCanvas::wxGLCanvas(wxWindow *parent, glx_cx = 0; // Check for the presence of the GLX extension if(!glXQueryExtension(display, NULL, NULL)) { - wxDebugMsg("wxGLCanvas: GLX extension is missing\n"); - return; + wxDebugMsg("wxGLCanvas: GLX extension is missing\n"); + return; } - if(attrib_list) { - // Get an appropriate visual - vi = glXChooseVisual(display, DefaultScreen(display), attrib_list); - if(!vi) return; - - // Here we should make sure that vi is the same visual as the - // one used by the xwindow drawable in wxCanvas. However, - // there is currently no mechanism for this in wx_canvs.cc. + if(attribList) { + int data[512], arg=0, p=0; + + while( (attribList[arg]!=0) && (p<512) ) + { + switch( attribList[arg++] ) + { + case WX_GL_RGBA: data[p++] = GLX_RGBA; break; + case WX_GL_BUFFER_SIZE: + data[p++]=GLX_BUFFER_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_LEVEL: + data[p++]=GLX_LEVEL; data[p++]=attribList[arg++]; break; + case WX_GL_DOUBLEBUFFER: data[p++] = GLX_DOUBLEBUFFER; break; + case WX_GL_STEREO: data[p++] = GLX_STEREO; break; + case WX_GL_AUX_BUFFERS: + data[p++]=GLX_AUX_BUFFERS; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_RED: + data[p++]=GLX_RED_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_GREEN: + data[p++]=GLX_GREEN_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_BLUE: + data[p++]=GLX_BLUE_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_ALPHA: + data[p++]=GLX_ALPHA_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_DEPTH_SIZE: + data[p++]=GLX_DEPTH_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_STENCIL_SIZE: + data[p++]=GLX_STENCIL_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_ACCUM_RED: + data[p++]=GLX_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_ACCUM_GREEN: + data[p++]=GLX_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_ACCUM_BLUE: + data[p++]=GLX_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break; + case WX_GL_MIN_ACCUM_ALPHA: + data[p++]=GLX_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break; + default: + break; + } + } + data[p] = 0; + + attribList = (int*) data; + // Get an appropriate visual + vi = glXChooseVisual(display, DefaultScreen(display), attribList); + if(!vi) return; + + // Here we should make sure that vi is the same visual as the + // one used by the xwindow drawable in wxCanvas. However, + // there is currently no mechanism for this in wx_canvs.cc. } else { - // By default, we use the visual of xwindow - XGetWindowAttributes(display, (Window) GetXWindow(), &xwa); - vi_templ.visualid = XVisualIDFromVisual(xwa.visual); - vi = XGetVisualInfo(display, VisualIDMask, &vi_templ, &n); - if(!vi) return; - glXGetConfig(display, vi, GLX_USE_GL, &val); - if(!val) return; - // Basically, this is it. It should be possible to use vi - // in glXCreateContext() below. But this fails with Mesa. - // I notified the Mesa author about it; there may be a fix. + // By default, we use the visual of xwindow + // NI: is this really senseful ? opengl in e.g. color index mode ? + XGetWindowAttributes(display, (Window) GetXWindow(), &xwa); + vi_templ.visualid = XVisualIDFromVisual(xwa.visual); + vi = XGetVisualInfo(display, VisualIDMask, &vi_templ, &n); + if(!vi) return; + glXGetConfig(display, vi, GLX_USE_GL, &val); + if(!val) return; + // Basically, this is it. It should be possible to use vi + // in glXCreateContext() below. But this fails with Mesa. + // I notified the Mesa author about it; there may be a fix. #ifdef OLD_MESA - // Construct an attribute list matching the visual - int a_list[32]; - n = 0; - if(vi->c_class==TrueColor || vi->c_class==DirectColor) { // RGBA visual - a_list[n++] = GLX_RGBA; - a_list[n++] = GLX_RED_SIZE; - a_list[n++] = bitcount(vi->red_mask); - a_list[n++] = GLX_GREEN_SIZE; - a_list[n++] = bitcount(vi->green_mask); - a_list[n++] = GLX_BLUE_SIZE; - a_list[n++] = bitcount(vi->blue_mask); - glXGetConfig(display, vi, GLX_ALPHA_SIZE, &val); - a_list[n++] = GLX_ALPHA_SIZE; - a_list[n++] = val; - } else { // Color index visual - glXGetConfig(display, vi, GLX_BUFFER_SIZE, &val); - a_list[n++] = GLX_BUFFER_SIZE; - a_list[n++] = val; - } - a_list[n] = None; - XFree(vi); - vi = glXChooseVisual(display, DefaultScreen(display), a_list); - if(!vi) return; + // Construct an attribute list matching the visual + int a_list[32]; + n = 0; + if(vi->c_class==TrueColor || vi->c_class==DirectColor) { // RGBA visual + a_list[n++] = GLX_RGBA; + a_list[n++] = GLX_RED_SIZE; + a_list[n++] = bitcount(vi->red_mask); + a_list[n++] = GLX_GREEN_SIZE; + a_list[n++] = bitcount(vi->green_mask); + a_list[n++] = GLX_BLUE_SIZE; + a_list[n++] = bitcount(vi->blue_mask); + glXGetConfig(display, vi, GLX_ALPHA_SIZE, &val); + a_list[n++] = GLX_ALPHA_SIZE; + a_list[n++] = val; + } else { // Color index visual + glXGetConfig(display, vi, GLX_BUFFER_SIZE, &val); + a_list[n++] = GLX_BUFFER_SIZE; + a_list[n++] = val; + } + a_list[n] = None; + XFree(vi); + vi = glXChooseVisual(display, DefaultScreen(display), a_list); + if(!vi) return; #endif /* OLD_MESA */ } @@ -142,28 +181,28 @@ void wxGLCanvas::SetColour(const char *col) { wxColour *the_colour = wxTheColourDatabase->FindColour(col); if(the_colour) { - GLboolean b; - glGetBooleanv(GL_RGBA_MODE, &b); - if(b) { - glColor3ub(the_colour->Red(), - the_colour->Green(), - the_colour->Blue()); - } else { - GLint pix = (GLint)the_colour->m_pixel; - if(pix == -1) { - XColor exact_def; - exact_def.red = (unsigned short)the_colour->Red() << 8; - exact_def.green = (unsigned short)the_colour->Green() << 8; - exact_def.blue = (unsigned short)the_colour->Blue() << 8; - exact_def.flags = DoRed | DoGreen | DoBlue; - if(!XAllocColor((Display*) GetXDisplay(), (Colormap) wxTheApp->GetMainColormap(GetXDisplay()), &exact_def)) { - wxDebugMsg("wxGLCanvas: cannot allocate color\n"); - return; - } - pix = the_colour->m_pixel = exact_def.pixel; - } - glIndexi(pix); - } + GLboolean b; + glGetBooleanv(GL_RGBA_MODE, &b); + if(b) { + glColor3ub(the_colour->Red(), + the_colour->Green(), + the_colour->Blue()); + } else { + GLint pix = (GLint)the_colour->m_pixel; + if(pix == -1) { + XColor exact_def; + exact_def.red = (unsigned short)the_colour->Red() << 8; + exact_def.green = (unsigned short)the_colour->Green() << 8; + exact_def.blue = (unsigned short)the_colour->Blue() << 8; + exact_def.flags = DoRed | DoGreen | DoBlue; + if(!XAllocColor((Display*) GetXDisplay(), (Colormap) wxTheApp->GetMainColormap(GetXDisplay()), &exact_def)) { + wxDebugMsg("wxGLCanvas: cannot allocate color\n"); + return; + } + pix = the_colour->m_pixel = exact_def.pixel; + } + glIndexi(pix); + } } } diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index 78c1a4bd2d..360e36c876 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -57,20 +57,20 @@ wxGLContext::wxGLContext(bool isRGB, wxGLCanvas *win, const wxPalette& palette) wxGLContext::wxGLContext( bool isRGB, wxGLCanvas *win, const wxPalette& palette, - const wxGLContext *other /* for sharing display lists */ -) + const wxGLContext *other /* for sharing display lists */ + ) { - m_window = win; + m_window = win; - m_hDC = win->GetHDC(); + m_hDC = win->GetHDC(); - m_glContext = wglCreateContext((HDC) m_hDC); - wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") ); + m_glContext = wglCreateContext((HDC) m_hDC); + wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") ); - if( other != 0 ) - wglShareLists( other->m_glContext, m_glContext ); + if( other != 0 ) + wglShareLists( other->m_glContext, m_glContext ); - wglMakeCurrent((HDC) m_hDC, m_glContext); + wglMakeCurrent((HDC) m_hDC, m_glContext); } wxGLContext::~wxGLContext() @@ -78,7 +78,7 @@ wxGLContext::~wxGLContext() if (m_glContext) { wglMakeCurrent(NULL, NULL); - wglDeleteContext(m_glContext); + wglDeleteContext(m_glContext); } } @@ -98,10 +98,10 @@ void wxGLContext::SetCurrent() wglMakeCurrent((HDC) m_hDC, m_glContext); } -/* - setupPixelFormat(hDC); - setupPalette(hDC); -*/ + /* + setupPixelFormat(hDC); + setupPalette(hDC); + */ } void wxGLContext::SetColour(const char *colour) @@ -134,25 +134,24 @@ END_EVENT_TABLE() wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name, - int *attribList /* not used yet! */, const wxPalette& palette): - wxScrolledWindow() + int *attribList, const wxPalette& palette) : wxScrolledWindow() { - m_glContext = (wxGLContext*) NULL; + m_glContext = (wxGLContext*) NULL; - bool ret = Create(parent, id, pos, size, style, name); + bool ret = Create(parent, id, pos, size, style, name); - if ( ret ) - { - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); - } + if ( ret ) + { + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + } - m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); - SetupPixelFormat(); - SetupPalette(palette); + SetupPixelFormat(attribList); + SetupPalette(palette); - m_glContext = new wxGLContext(TRUE, this, palette); + m_glContext = new wxGLContext(TRUE, this, palette); } wxGLCanvas::wxGLCanvas( wxWindow *parent, @@ -161,22 +160,22 @@ wxGLCanvas::wxGLCanvas( wxWindow *parent, int *attribList, const wxPalette& palette ) : wxScrolledWindow() { - m_glContext = (wxGLContext*) NULL; + m_glContext = (wxGLContext*) NULL; - bool ret = Create(parent, id, pos, size, style, name); + bool ret = Create(parent, id, pos, size, style, name); - if ( ret ) - { - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); - } + if ( ret ) + { + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + } - m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); - SetupPixelFormat(); - SetupPalette(palette); + SetupPixelFormat(attribList); + SetupPalette(palette); - m_glContext = new wxGLContext(TRUE, this, palette, shared ); + m_glContext = new wxGLContext(TRUE, this, palette, shared ); } // Not very useful for wxMSW, but this is to be wxGTK compliant @@ -186,24 +185,24 @@ wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID i int *attribList, const wxPalette& palette ): wxScrolledWindow() { - m_glContext = (wxGLContext*) NULL; + m_glContext = (wxGLContext*) NULL; - bool ret = Create(parent, id, pos, size, style, name); + bool ret = Create(parent, id, pos, size, style, name); - if ( ret ) - { - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); - SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); - } + if ( ret ) + { + SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE)); + SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT)); + } - m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); + m_hDC = (WXHDC) ::GetDC((HWND) GetHWND()); - SetupPixelFormat(); - SetupPalette(palette); + SetupPixelFormat(attribList); + SetupPalette(palette); - wxGLContext *sharedContext=0; - if (shared) sharedContext=shared->GetContext(); - m_glContext = new wxGLContext(TRUE, this, palette, sharedContext ); + wxGLContext *sharedContext=0; + if (shared) sharedContext=shared->GetContext(); + m_glContext = new wxGLContext(TRUE, this, palette, sharedContext ); } wxGLCanvas::~wxGLCanvas() @@ -218,157 +217,231 @@ wxGLCanvas::~wxGLCanvas() bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name) { -/* Suggestion from Kelly Brock (not yet implemented): + /* + Suggestion from Kelly Brock (not yet implemented): -OpenGL corruption fix is simple assuming it doesn't screw anything else -up. Add the following line to the top of the create function: - wxSize parentSize = GetClientSize(); - All locations within the function that use 'size' are changed to -'parentSize'. - The above corrects the initial display corruption with the GeForce and -TNT2, not sure about other NVidia cards yet. -*/ + OpenGL corruption fix is simple assuming it doesn't screw anything else + up. Add the following line to the top of the create function: + + wxSize parentSize = GetClientSize(); - static bool registeredGLCanvasClass = FALSE; + All locations within the function that use 'size' are changed to + 'parentSize'. + The above corrects the initial display corruption with the GeForce and + TNT2, not sure about other NVidia cards yet. + */ - // We have to register a special window class because we need - // the CS_OWNDC style for GLCanvas. + static bool registeredGLCanvasClass = FALSE; -/* - From Angel Popov + // We have to register a special window class because we need + // the CS_OWNDC style for GLCanvas. - Here are two snips from a dicussion in the OpenGL Gamedev list that explains - how this problem can be fixed: + /* + From Angel Popov - "There are 5 common DCs available in Win95. These are aquired when you call - GetDC or GetDCEx from a window that does _not_ have the OWNDC flag. - OWNDC flagged windows do not get their DC from the common DC pool, the issue - is they require 800 bytes each from the limited 64Kb local heap for GDI." + Here are two snips from a dicussion in the OpenGL Gamedev list that explains + how this problem can be fixed: - "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps - do), Win95 will actually "steal" it from you. MakeCurrent fails, - apparently, because Windows re-assigns the HDC to a different window. The - only way to prevent this, the only reliable means, is to set CS_OWNDC." -*/ + "There are 5 common DCs available in Win95. These are aquired when you call + GetDC or GetDCEx from a window that does _not_ have the OWNDC flag. + OWNDC flagged windows do not get their DC from the common DC pool, the issue + is they require 800 bytes each from the limited 64Kb local heap for GDI." - if (!registeredGLCanvasClass) - { - WNDCLASS wndclass; - - static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC; - - // the fields which are common to all classes - wndclass.lpfnWndProc = (WNDPROC)wxWndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for? - wndclass.hInstance = wxhInstance; - wndclass.hIcon = (HICON) NULL; - wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW); - wndclass.lpszMenuName = NULL; - - // Register the GLCanvas class name - wndclass.hbrBackground = (HBRUSH)NULL; - wndclass.lpszClassName = wxGLCanvasClassName; - wndclass.style = styleNormal; - - if ( !RegisterClass(&wndclass) ) - { - wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)")); - - return FALSE; - } - registeredGLCanvasClass = TRUE; - } + "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps + do), Win95 will actually "steal" it from you. MakeCurrent fails, + apparently, because Windows re-assigns the HDC to a different window. The + only way to prevent this, the only reliable means, is to set CS_OWNDC." + */ - wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); + if (!registeredGLCanvasClass) + { + WNDCLASS wndclass; - if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) - return FALSE; + static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC; - parent->AddChild(this); + // the fields which are common to all classes + wndclass.lpfnWndProc = (WNDPROC)wxWndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for? + wndclass.hInstance = wxhInstance; + wndclass.hIcon = (HICON) NULL; + wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW); + wndclass.lpszMenuName = NULL; - DWORD msflags = 0; - if ( style & wxBORDER ) - msflags |= WS_BORDER; - if ( style & wxTHICK_FRAME ) - msflags |= WS_THICKFRAME; + // Register the GLCanvas class name + wndclass.hbrBackground = (HBRUSH)NULL; + wndclass.lpszClassName = wxGLCanvasClassName; + wndclass.style = styleNormal; -/* - A general rule with OpenGL and Win32 is that any window that will have a - HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS. - You can find references about this within the knowledge base and most OpenGL - books that contain the wgl function descriptions. -*/ - - msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; -// if ( style & wxCLIP_CHILDREN ) -// msflags |= WS_CLIPCHILDREN; - msflags |= WS_CLIPCHILDREN; - - bool want3D; - WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); - - // Even with extended styles, need to combine with WS_BORDER - // for them to look right. - if ( want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) || - (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER)) + if ( !RegisterClass(&wndclass) ) { - msflags |= WS_BORDER; + wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)")); + return FALSE; } - // calculate the value to return from WM_GETDLGCODE handler - if ( GetWindowStyleFlag() & wxWANTS_CHARS ) - { - // want everything: i.e. all keys and WM_CHAR message - m_lDlgCode = DLGC_WANTARROWS | DLGC_WANTCHARS | - DLGC_WANTTAB | DLGC_WANTMESSAGE; - } + registeredGLCanvasClass = TRUE; + } - MSWCreate(m_windowId, parent, wxGLCanvasClassName, this, NULL, - pos.x, pos.y, - WidthDefault(size.x), HeightDefault(size.y), - msflags, NULL, exStyle); - - return TRUE; - -} - -void wxGLCanvas::SetupPixelFormat() // (HDC hDC) -{ - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), /* size */ - 1, /* version */ - PFD_SUPPORT_OPENGL | - PFD_DRAW_TO_WINDOW | - PFD_DOUBLEBUFFER, /* support double-buffering */ - PFD_TYPE_RGBA, /* color type */ - 16, /* prefered color depth */ - 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ - 0, /* no alpha buffer */ - 0, /* alpha bits (ignored) */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits (ignored) */ - 16, /* depth buffer */ - 0, /* no stencil buffer */ - 0, /* no auxiliary buffers */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0, /* no layer, visible, damage masks */ - }; - int pixelFormat; - - pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd); - if (pixelFormat == 0) { - MessageBox(WindowFromDC((HDC) m_hDC), wxT("ChoosePixelFormat failed."), wxT("Error"), - MB_ICONERROR | MB_OK); - exit(1); - } + wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") ); + + if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) ) + return FALSE; + + parent->AddChild(this); + + DWORD msflags = 0; + if ( style & wxBORDER ) + msflags |= WS_BORDER; + if ( style & wxTHICK_FRAME ) + msflags |= WS_THICKFRAME; + + /* + A general rule with OpenGL and Win32 is that any window that will have a + HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS. + You can find references about this within the knowledge base and most OpenGL + books that contain the wgl function descriptions. + */ - if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) { - MessageBox(WindowFromDC((HDC) m_hDC), wxT("SetPixelFormat failed."), wxT("Error"), - MB_ICONERROR | MB_OK); - exit(1); + msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS; + // if ( style & wxCLIP_CHILDREN ) + // msflags |= WS_CLIPCHILDREN; + msflags |= WS_CLIPCHILDREN; + + bool want3D; + WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D); + + // Even with extended styles, need to combine with WS_BORDER + // for them to look right. + if ( want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) || + (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER)) + { + msflags |= WS_BORDER; + } + + // calculate the value to return from WM_GETDLGCODE handler + if ( GetWindowStyleFlag() & wxWANTS_CHARS ) + { + // want everything: i.e. all keys and WM_CHAR message + m_lDlgCode = DLGC_WANTARROWS | DLGC_WANTCHARS | + DLGC_WANTTAB | DLGC_WANTMESSAGE; + } + + MSWCreate(m_windowId, parent, wxGLCanvasClassName, this, NULL, + pos.x, pos.y, + WidthDefault(size.x), HeightDefault(size.y), + msflags, NULL, exStyle); + + return TRUE; +} + +void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC) +{ + int pixelFormat; + PIXELFORMATDESCRIPTOR pfd = { + sizeof(PIXELFORMATDESCRIPTOR), /* size */ + 1, /* version */ + PFD_SUPPORT_OPENGL | + PFD_DRAW_TO_WINDOW | + PFD_DOUBLEBUFFER, /* support double-buffering */ + PFD_TYPE_RGBA, /* color type */ + 16, /* prefered color depth */ + 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ + 0, /* no alpha buffer */ + 0, /* alpha bits (ignored) */ + 0, /* no accumulation buffer */ + 0, 0, 0, 0, /* accum bits (ignored) */ + 16, /* depth buffer */ + 0, /* no stencil buffer */ + 0, /* no auxiliary buffers */ + PFD_MAIN_PLANE, /* main layer */ + 0, /* reserved */ + 0, 0, 0, /* no layer, visible, damage masks */ + }; + + if (attribList) { + pfd.dwFlags &= ~PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_COLORINDEX; + pfd.cColorBits = 0; + int arg=0; + + while( (attribList[arg]!=0) ) + { + switch( attribList[arg++] ) + { + case WX_GL_RGBA: + pfd.iPixelType = PFD_TYPE_RGBA; + break; + case WX_GL_BUFFER_SIZE: + pfd.cColorBits = attribList[arg++]; + break; + case WX_GL_LEVEL: + // this member looks like it may be obsolete + if (attribList[arg] > 0) { + pfd.iLayerType = PFD_OVERLAY_PLANE; + } else if (attribList[arg] < 0) { + pfd.iLayerType = PFD_UNDERLAY_PLANE; + } else { + pfd.iLayerType = PFD_MAIN_PLANE; + } + arg++; + break; + case WX_GL_DOUBLEBUFFER: + pfd.dwFlags |= PFD_DOUBLEBUFFER; + break; + case WX_GL_STEREO: + pfd.dwFlags |= PFD_STEREO; + break; + case WX_GL_AUX_BUFFERS: + pfd.cAuxBuffers = attribList[arg++]; + break; + case WX_GL_MIN_RED: + pfd.cColorBits += (pfd.cRedBits = attribList[arg++]); + break; + case WX_GL_MIN_GREEN: + pfd.cColorBits += (pfd.cGreenBits = attribList[arg++]); + break; + case WX_GL_MIN_BLUE: + pfd.cColorBits += (pfd.cBlueBits = attribList[arg++]); + break; + case WX_GL_MIN_ALPHA: + // doesn't count in cColorBits + pfd.cAlphaBits = attribList[arg++]; + break; + case WX_GL_DEPTH_SIZE: + pfd.cDepthBits = attribList[arg++]; + break; + case WX_GL_STENCIL_SIZE: + pfd.cStencilBits = attribList[arg++]; + break; + case WX_GL_MIN_ACCUM_RED: + pfd.cAccumBits += (pfd.cAccumRedBits = attribList[arg++]); + break; + case WX_GL_MIN_ACCUM_GREEN: + pfd.cAccumBits += (pfd.cAccumGreenBits = attribList[arg++]); + break; + case WX_GL_MIN_ACCUM_BLUE: + pfd.cAccumBits += (pfd.cAccumBlueBits = attribList[arg++]); + break; + case WX_GL_MIN_ACCUM_ALPHA: + pfd.cAccumBits += (pfd.cAccumAlphaBits = attribList[arg++]); + break; + default: + break; + } } + } + pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd); + if (pixelFormat == 0) { + MessageBox(WindowFromDC((HDC) m_hDC), wxT("ChoosePixelFormat failed."), wxT("Error"), + MB_ICONERROR | MB_OK); + exit(1); + } + + if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) { + MessageBox(WindowFromDC((HDC) m_hDC), wxT("SetPixelFormat failed."), wxT("Error"), + MB_ICONERROR | MB_OK); + exit(1); + } } void wxGLCanvas::SetupPalette(const wxPalette& palette) @@ -408,7 +481,7 @@ wxPalette wxGLCanvas::CreateDefaultPalette() DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - paletteSize = 1 << pfd.cColorBits; + paletteSize = 1 << pfd.cColorBits; LOGPALETTE* pPal = (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY)); @@ -483,30 +556,30 @@ void wxGLCanvas::SetColour(const char *colour) // So we need wxFrame to call OnQueryNewPalette for all children... void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event) { - /* realize palette if this is the current window */ - if ( GetPalette()->Ok() ) { - ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); - ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); - ::RealizePalette((HDC) GetHDC()); - Refresh(); - event.SetPaletteRealized(TRUE); - } - else - event.SetPaletteRealized(FALSE); + /* realize palette if this is the current window */ + if ( GetPalette()->Ok() ) { + ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); + ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette((HDC) GetHDC()); + Refresh(); + event.SetPaletteRealized(TRUE); + } + else + event.SetPaletteRealized(FALSE); } // I think this doesn't have to be propagated to child windows. void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event) { - /* realize palette if this is *not* the current window */ - if ( GetPalette() && + /* realize palette if this is *not* the current window */ + if ( GetPalette() && GetPalette()->Ok() && (this != event.GetChangedWindow()) ) - { - ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); - ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); - ::RealizePalette((HDC) GetHDC()); - Refresh(); - } + { + ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE()); + ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE); + ::RealizePalette((HDC) GetHDC()); + Refresh(); + } } /* Give extensions proper function names. */ @@ -550,15 +623,15 @@ void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) { #ifdef GL_EXT_vertex_array - static PFNGLNORMALPOINTEREXTPROC proc = 0; + static PFNGLNORMALPOINTEREXTPROC proc = 0; - if ( !proc ) - { - proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT"); - } + if ( !proc ) + { + proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT"); + } - if ( proc ) - (* proc) (type, stride, count, pointer); + if ( proc ) + (* proc) (type, stride, count, pointer); #endif } @@ -569,15 +642,14 @@ void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer) { #ifdef GL_EXT_vertex_array - static PFNGLVERTEXPOINTEREXTPROC proc = 0; - - if ( !proc ) - { - proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT"); - } + static PFNGLVERTEXPOINTEREXTPROC proc = 0; - if ( proc ) - (* proc) (size, type, stride, count, pointer); + if ( !proc ) + { + proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT"); + } + if ( proc ) + (* proc) (size, type, stride, count, pointer); #endif } -- 2.45.2