/////////////////////////////////////////////////////////////////////////////
// Name: glcanvas.cpp
// Purpose: wxGLCanvas, for using OpenGL with wxWindows under Macintosh
-// Author: AUTHOR
+// Author: Stefan Csomor
// Modified by:
-// Created: ??/??/98
+// Created: 1998-01-01
// RCS-ID: $Id$
-// Copyright: (c) AUTHOR
-// Licence: wxWindows licence
+// Copyright: (c) Stefan Csomor
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
#include "wx/glcanvas.h"
#include "wx/mac/uma.h"
-#include <agl.h>
+// DLL options compatibility check:
+#include "wx/build.h"
+WX_CHECK_BUILD_OPTIONS("wxGL")
/*
- * GLContext implementation
- */
+* GLContext implementation
+*/
wxGLContext::wxGLContext(
- AGLPixelFormat fmt, wxGLCanvas *win,
- const wxPalette& palette,
- const wxGLContext *other /* for sharing display lists */
-)
+ AGLPixelFormat fmt, wxGLCanvas *win,
+ const wxPalette& palette,
+ const wxGLContext *other /* for sharing display lists */
+ )
{
m_window = win;
-
- m_drawable = (AGLDrawable) UMAGetWindowPort(win->GetMacRootWindow());
-
+
+ m_drawable = (AGLDrawable) UMAGetWindowPort(MAC_WXHWND(win->MacGetTopLevelWindowRef()));
+
m_glContext = aglCreateContext(fmt, other ? other->m_glContext : NULL);
wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
-
- GLboolean b;
+
+ GLboolean b;
b = aglSetDrawable(m_glContext, m_drawable);
wxCHECK_RET( b, wxT("Couldn't bind OpenGl context") );
- aglEnable(m_glContext , AGL_BUFFER_RECT ) ;
+ aglEnable(m_glContext , AGL_BUFFER_RECT ) ;
b = aglSetCurrentContext(m_glContext);
wxCHECK_RET( b, wxT("Couldn't activate OpenGl context") );
}
wxGLContext::~wxGLContext()
{
- if (m_glContext)
- {
- aglSetCurrentContext(NULL);
- aglDestroyContext(m_glContext);
- }
+ if (m_glContext)
+ {
+ aglSetCurrentContext(NULL);
+ aglDestroyContext(m_glContext);
+ }
}
void wxGLContext::SwapBuffers()
{
- if (m_glContext)
- {
- aglSwapBuffers(m_glContext);
- }
+ if (m_glContext)
+ {
+ aglSwapBuffers(m_glContext);
+ }
}
void wxGLContext::SetCurrent()
{
- if (m_glContext)
- {
- aglSetCurrentContext(m_glContext);
- }
+ if (m_glContext)
+ {
+ aglSetCurrentContext(m_glContext);
+ }
}
void wxGLContext::Update()
{
- if (m_glContext)
- {
- aglUpdateContext(m_glContext);
- }
+ if (m_glContext)
+ {
+ aglUpdateContext(m_glContext);
+ }
}
-void wxGLContext::SetColour(const char *colour)
+void wxGLContext::SetColour(const wxChar *colour)
{
- float r = 0.0;
- float g = 0.0;
- float b = 0.0;
- wxColour *col = wxTheColourDatabase->FindColour(colour);
- if (col)
- {
- r = (float)(col->Red()/256.0);
- g = (float)(col->Green()/256.0);
- b = (float)(col->Blue()/256.0);
- glColor3f( r, g, b);
- }
+ wxColour col = wxTheColourDatabase->Find(colour);
+ if (col.Ok())
+ {
+ float r = (float)(col.Red()/256.0);
+ float g = (float)(col.Green()/256.0);
+ float b = (float)(col.Blue()/256.0);
+ glColor3f( r, g, b);
+ }
}
/*
- * wxGLCanvas implementation
- */
+* wxGLCanvas implementation
+*/
-IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow)
+IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
-BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow)
+BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
EVT_SIZE(wxGLCanvas::OnSize)
END_EVENT_TABLE()
wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
- const wxPoint& pos, const wxSize& size, long style, const wxString& name,
- int *attribList, const wxPalette& palette)
+ const wxPoint& pos, const wxSize& size, long style, const wxString& name,
+ int *attribList, const wxPalette& palette)
{
Create(parent, NULL, id, pos, size, style, name, attribList, palette);
}
wxGLCanvas::wxGLCanvas( wxWindow *parent,
- const wxGLContext *shared, wxWindowID id,
- const wxPoint& pos, const wxSize& size, long style, const wxString& name,
- int *attribList, const wxPalette& palette )
+ const wxGLContext *shared, wxWindowID id,
+ const wxPoint& pos, const wxSize& size, long style, const wxString& name,
+ int *attribList, const wxPalette& palette )
{
Create(parent, shared, id, pos, size, style, name, attribList, palette);
}
wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID id,
- const wxPoint& pos, const wxSize& size, long style, const wxString& name,
- int *attribList, const wxPalette& palette )
+ const wxPoint& pos, const wxSize& size, long style, const wxString& name,
+ int *attribList, const wxPalette& palette )
{
Create(parent, shared ? shared->GetContext() : NULL, id, pos, size, style, name, attribList, palette);
}
wxGLCanvas::~wxGLCanvas()
{
- if (m_glContext)
- delete m_glContext;
+ if (m_glContext != NULL) {
+ delete m_glContext;
+ m_glContext = NULL;
+ }
}
-bool wxGLCanvas::Create(wxWindow *parent, const wxGLContext *shared, wxWindowID id,
- const wxPoint& pos, const wxSize& size, long style, const wxString& name,
- int *attribList, const wxPalette& palette)
+static AGLPixelFormat ChoosePixelFormat(const int *attribList)
{
- m_macEraseOnRedraw = false ;
GLint data[512];
- GLint defs[] = { AGL_RGBA,
- AGL_DOUBLEBUFFER,
- AGL_MINIMUM_POLICY,
- AGL_DEPTH_SIZE, 1, // use largest available depth buffer
- AGL_RED_SIZE, 1,
- AGL_GREEN_SIZE, 1,
- AGL_BLUE_SIZE, 1,
- AGL_ALPHA_SIZE, 0,
- AGL_NONE };
+ GLint defaultAttribs[] = { AGL_RGBA,
+ AGL_DOUBLEBUFFER,
+ AGL_MINIMUM_POLICY,
+ AGL_DEPTH_SIZE, 1, // use largest available depth buffer
+ AGL_RED_SIZE, 1,
+ AGL_GREEN_SIZE, 1,
+ AGL_BLUE_SIZE, 1,
+ AGL_ALPHA_SIZE, 0,
+ AGL_NONE };
GLint *attribs;
if (!attribList)
{
- attribs = defs;
+ attribs = defaultAttribs;
}
else
{
- int data[512], arg=0, p=0;
-
- data[p++] = AGL_MINIMUM_POLICY; // make _SIZE tags behave more like GLX
- while( (attribList[arg]!=0) && (p<512) )
- {
- switch( attribList[arg++] )
+ int arg=0, p=0;
+
+ data[p++] = AGL_MINIMUM_POLICY; // make _SIZE tags behave more like GLX
+ while( (attribList[arg]!=0) && (p<512) )
{
- case WX_GL_RGBA: data[p++] = AGL_RGBA; break;
- case WX_GL_BUFFER_SIZE:
- data[p++]=AGL_BUFFER_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_LEVEL:
- data[p++]=AGL_LEVEL; data[p++]=attribList[arg++]; break;
- case WX_GL_DOUBLEBUFFER: data[p++] = AGL_DOUBLEBUFFER; break;
- case WX_GL_STEREO: data[p++] = AGL_STEREO; break;
- case WX_GL_AUX_BUFFERS:
- data[p++]=AGL_AUX_BUFFERS; data[p++]=attribList[arg++]; break;
- case WX_GL_MIN_RED:
- data[p++]=AGL_RED_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_MIN_GREEN:
- data[p++]=AGL_GREEN_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_MIN_BLUE:
- data[p++]=AGL_BLUE_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_MIN_ALPHA:
- data[p++]=AGL_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_DEPTH_SIZE:
- data[p++]=AGL_DEPTH_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_STENCIL_SIZE:
- data[p++]=AGL_STENCIL_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_MIN_ACCUM_RED:
- data[p++]=AGL_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_MIN_ACCUM_GREEN:
- data[p++]=AGL_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_MIN_ACCUM_BLUE:
- data[p++]=AGL_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break;
- case WX_GL_MIN_ACCUM_ALPHA:
- data[p++]=AGL_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
- default:
- break;
- }
- }
- data[p] = 0;
-
- attribs = defs;
+ switch( attribList[arg++] )
+ {
+ case WX_GL_RGBA: data[p++] = AGL_RGBA; break;
+ case WX_GL_BUFFER_SIZE:
+ data[p++]=AGL_BUFFER_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_LEVEL:
+ data[p++]=AGL_LEVEL; data[p++]=attribList[arg++]; break;
+ case WX_GL_DOUBLEBUFFER: data[p++] = AGL_DOUBLEBUFFER; break;
+ case WX_GL_STEREO: data[p++] = AGL_STEREO; break;
+ case WX_GL_AUX_BUFFERS:
+ data[p++]=AGL_AUX_BUFFERS; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_RED:
+ data[p++]=AGL_RED_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_GREEN:
+ data[p++]=AGL_GREEN_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_BLUE:
+ data[p++]=AGL_BLUE_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ALPHA:
+ data[p++]=AGL_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_DEPTH_SIZE:
+ data[p++]=AGL_DEPTH_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_STENCIL_SIZE:
+ data[p++]=AGL_STENCIL_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ACCUM_RED:
+ data[p++]=AGL_ACCUM_RED_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ACCUM_GREEN:
+ data[p++]=AGL_ACCUM_GREEN_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ACCUM_BLUE:
+ data[p++]=AGL_ACCUM_BLUE_SIZE; data[p++]=attribList[arg++]; break;
+ case WX_GL_MIN_ACCUM_ALPHA:
+ data[p++]=AGL_ACCUM_ALPHA_SIZE; data[p++]=attribList[arg++]; break;
+ default:
+ break;
+ }
+ }
+ data[p] = 0;
+
+ attribs = data;
}
- wxScrolledWindow::Create( parent, id, pos, size, style, name );
+
+ return aglChoosePixelFormat(NULL, 0, attribs);
+}
- AGLPixelFormat fmt = aglChoosePixelFormat(NULL, 0, attribs);
+bool wxGLCanvas::Create(wxWindow *parent, const wxGLContext *shared, wxWindowID id,
+ const wxPoint& pos, const wxSize& size, long style, const wxString& name,
+ int *attribList, const wxPalette& palette)
+{
+ wxWindow::Create( parent, id, pos, size, style, name );
+
+ AGLPixelFormat fmt = ChoosePixelFormat(attribList);
wxCHECK_MSG( fmt, false, wxT("Couldn't create OpenGl pixel format") );
-
+
m_glContext = new wxGLContext(fmt, this, palette, shared);
-
+ m_macCanvasIsShown = true ;
aglDestroyPixelFormat(fmt);
return true;
void wxGLCanvas::SwapBuffers()
{
- if (m_glContext)
- m_glContext->SwapBuffers();
+ if (m_glContext)
+ m_glContext->SwapBuffers();
}
void wxGLCanvas::UpdateContext()
{
- if (m_glContext)
- m_glContext->Update();
+ if (m_glContext)
+ m_glContext->Update();
}
void wxGLCanvas::SetViewport()
{
- // viewport is initially set to entire port
- // adjust glViewport to just this window
+ // viewport is initially set to entire port
+ // adjust glViewport to just this window
int x = 0 ;
int y = 0 ;
- MacClientToRootWindow( &x , &y ) ;
- int width, height;
- GetClientSize(& width, & height);
- Rect bounds ;
- GetWindowPortBounds( GetMacRootWindow() , &bounds ) ;
- GLint parms[4] ;
- parms[0] = x ;
- parms[1] = bounds.bottom - bounds.top - ( y + height ) ;
- parms[2] = width ;
- parms[3] = height ;
-
- aglSetInteger( m_glContext->m_glContext , AGL_BUFFER_RECT , parms ) ;
+ wxWindow* iter = this ;
+ while( iter->GetParent() )
+ {
+ iter = iter->GetParent() ;
+ }
+
+ if ( iter && iter->IsTopLevel() )
+ {
+ MacClientToRootWindow( &x , &y ) ;
+ int width, height;
+ GetClientSize(& width, & height);
+ Rect bounds ;
+ GetWindowPortBounds( MAC_WXHWND(MacGetTopLevelWindowRef()) , &bounds ) ;
+ GLint parms[4] ;
+ parms[0] = x ;
+ parms[1] = bounds.bottom - bounds.top - ( y + height ) ;
+ parms[2] = width ;
+ parms[3] = height ;
+
+ if ( !m_macCanvasIsShown )
+ parms[0] += 20000 ;
+ aglSetInteger( m_glContext->m_glContext , AGL_BUFFER_RECT , parms ) ;
+ }
}
void wxGLCanvas::OnSize(wxSizeEvent& event)
{
- if (m_glContext)
- {
- UpdateContext();
- m_glContext->SetCurrent();
-
- SetViewport();
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
- glMatrixMode(GL_MODELVIEW);
- }
+ MacUpdateView() ;
+}
+
+void wxGLCanvas::MacUpdateView()
+{
+ if (m_glContext)
+ {
+ UpdateContext();
+ m_glContext->SetCurrent();
+ SetViewport();
+ }
+}
+
+void wxGLCanvas::MacSuperChangedPosition()
+{
+ MacUpdateView() ;
+ wxWindow::MacSuperChangedPosition() ;
+}
+
+void wxGLCanvas::MacTopLevelWindowChangedPosition()
+{
+ MacUpdateView() ;
+ wxWindow::MacTopLevelWindowChangedPosition() ;
}
void wxGLCanvas::SetCurrent()
{
- if (m_glContext)
- {
- m_glContext->SetCurrent();
- }
+ if (m_glContext)
+ {
+ m_glContext->SetCurrent();
+ }
+}
+
+void wxGLCanvas::SetColour(const wxChar *colour)
+{
+ if (m_glContext)
+ m_glContext->SetColour(colour);
+}
+
+bool wxGLCanvas::Show(bool show)
+{
+ if ( !wxWindow::Show( show ) )
+ return FALSE ;
+/*
+ if ( !show )
+ {
+ if ( m_macCanvasIsShown )
+ {
+ m_macCanvasIsShown = false ;
+ SetViewport() ;
+ }
+ }
+ else
+ {
+ if ( IsControlVisible( (ControlRef) m_macControl ) && !m_macCanvasIsShown )
+ {
+ m_macCanvasIsShown = true ;
+ SetViewport() ;
+ }
+ }
+*/
+ return TRUE ;
+}
+
+void wxGLCanvas::MacVisibilityChanged()
+{
+ if ( !IsControlVisible( (ControlRef) m_macControl ) )
+ {
+ if ( m_macCanvasIsShown )
+ {
+ m_macCanvasIsShown = false ;
+ SetViewport() ;
+ }
+ }
+ else
+ {
+ if ( !m_macCanvasIsShown )
+ {
+ m_macCanvasIsShown = true ;
+ SetViewport() ;
+ }
+ }
+ wxWindowMac::MacVisibilityChanged() ;
+}
+
+//---------------------------------------------------------------------------
+// wxGLApp
+//---------------------------------------------------------------------------
+
+IMPLEMENT_CLASS(wxGLApp, wxApp)
+
+bool wxGLApp::InitGLVisual(int *attribList)
+{
+ AGLPixelFormat fmt = ChoosePixelFormat(attribList);
+ if (fmt != NULL) {
+ aglDestroyPixelFormat(fmt);
+ return true;
+ } else
+ return false;
}
-void wxGLCanvas::SetColour(const char *colour)
+wxGLApp::~wxGLApp(void)
{
- if (m_glContext)
- m_glContext->SetColour(colour);
}
#endif // wxUSE_GLCANVAS