///////////////////////////////////////////////////////////////////////////// // Name: glcanvas.cpp // Purpose: wxGLCanvas, for using OpenGL with wxWindows under Macintosh // Author: AUTHOR // Modified by: // Created: ??/??/98 // RCS-ID: $Id$ // Copyright: (c) AUTHOR // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifdef __GNUG__ #pragma implementation "glcanvas.h" #endif #include "wx/wxprec.h" #if defined(__BORLANDC__) #pragma hdrstop #endif #include "wx/setup.h" #if wxUSE_GLCANVAS #ifndef WX_PRECOMP #include "wx/frame.h" #endif #include "wx/settings.h" #include "wx/log.h" #include "wx/glcanvas.h" #include "wx/mac/uma.h" /* * GLContext implementation */ wxGLContext::wxGLContext( AGLPixelFormat fmt, wxGLCanvas *win, const wxPalette& palette, const wxGLContext *other /* for sharing display lists */ ) { m_window = win; m_drawable = (AGLDrawable) UMAGetWindowPort(win->GetMacRootWindow()); m_glContext = aglCreateContext(fmt, other ? other->m_glContext : NULL); wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") ); GLboolean b; b = aglSetDrawable(m_glContext, m_drawable); wxCHECK_RET( b, wxT("Couldn't bind OpenGl context") ); 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); } } void wxGLContext::SwapBuffers() { if (m_glContext) { aglSwapBuffers(m_glContext); } } void wxGLContext::SetCurrent() { if (m_glContext) { aglSetCurrentContext(m_glContext); } } void wxGLContext::Update() { if (m_glContext) { aglUpdateContext(m_glContext); } } void wxGLContext::SetColour(const char *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); } } /* * wxGLCanvas implementation */ IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow) BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow) 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) { 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 ) { 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 ) { Create(parent, shared ? shared->GetContext() : NULL, id, pos, size, style, name, attribList, palette); } wxGLCanvas::~wxGLCanvas() { if (m_glContext) delete m_glContext; } 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) { 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 *attribs; if (!attribList) { attribs = defs; } 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++] ) { 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; } wxScrolledWindow::Create( parent, id, pos, size, style, name ); AGLPixelFormat fmt = aglChoosePixelFormat(NULL, 0, attribs); wxCHECK_MSG( fmt, false, wxT("Couldn't create OpenGl pixel format") ); m_glContext = new wxGLContext(fmt, this, palette, shared); aglDestroyPixelFormat(fmt); return true; } void wxGLCanvas::SwapBuffers() { if (m_glContext) m_glContext->SwapBuffers(); } void wxGLCanvas::UpdateContext() { if (m_glContext) m_glContext->Update(); } void wxGLCanvas::SetViewport() { // 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 ) ; } 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); } } void wxGLCanvas::SetCurrent() { if (m_glContext) { m_glContext->SetCurrent(); } } void wxGLCanvas::SetColour(const char *colour) { if (m_glContext) m_glContext->SetColour(colour); } #endif // wxUSE_GLCANVAS