]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/glcanvas.cpp
Use "&Help" so wxMac doesn't make an extra help menu
[wxWidgets.git] / src / mac / carbon / glcanvas.cpp
index b3832d29fa1b822dcd007ccf397f738be2a6983e..e6a8b50a69cf9343225f4a229f967929aa294098 100644 (file)
@@ -1,12 +1,12 @@
 /////////////////////////////////////////////////////////////////////////////
 // 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;
@@ -227,64 +233,153 @@ bool wxGLCanvas::Create(wxWindow *parent, const wxGLContext *shared, wxWindowID
 
 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