]>
git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/glcanvas.cpp
   1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/mac/carbon/glcanvas.cpp 
   3 // Purpose:     wxGLCanvas, for using OpenGL with wxWidgets under Macintosh 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     wxWindows licence 
  10 /////////////////////////////////////////////////////////////////////////////// 
  12 // ============================================================================ 
  14 // ============================================================================ 
  16 // ---------------------------------------------------------------------------- 
  18 // ---------------------------------------------------------------------------- 
  20 #include "wx/wxprec.h" 
  22 #if defined(__BORLANDC__) 
  28 #include "wx/glcanvas.h" 
  33     #include "wx/settings.h" 
  36 #include "wx/mac/uma.h" 
  38 #include "wx/mac/private.h" 
  40 // ---------------------------------------------------------------------------- 
  42 // ---------------------------------------------------------------------------- 
  44 static void wxLogAGLError(const char *func
) 
  46     const int err 
= aglGetError(); 
  48     wxLogError(_("OpenGL function \"%s\" failed: %s (error %d)"), 
  49                func
, aglErrorString(err
), err
); 
  52 // ============================================================================ 
  54 // ============================================================================ 
  56 // ---------------------------------------------------------------------------- 
  58 // ---------------------------------------------------------------------------- 
  60 wxGLContext::wxGLContext(wxGLCanvas 
*win
, const wxGLContext 
*other
) 
  62     m_aglContext 
= aglCreateContext(win
->GetAGLPixelFormat(), 
  63                                     other 
? other
->m_aglContext 
: NULL
); 
  65         wxLogAGLError("aglCreateContext"); 
  68     if ( !aglEnable(m_aglContext
, AGL_BUFFER_RECT
) ) 
  69         wxLogAGLError("aglEnable(AGL_BUFFER_RECT)"); 
  72 wxGLContext::~wxGLContext() 
  76         // it's ok to pass the current context to this function 
  77         if ( !aglDestroyContext(m_aglContext
) ) 
  78             wxLogAGLError("aglDestroyContext"); 
  82 void wxGLContext::SetCurrent(const wxGLCanvas
& win
) const 
  87     AGLDrawable drawable 
= (AGLDrawable
)UMAGetWindowPort( 
  88                                 MAC_WXHWND(win
.MacGetTopLevelWindowRef())); 
  89     if ( !aglSetDrawable(m_aglContext
, drawable
) ) 
  90         wxLogAGLError("aglSetDrawable"); 
  92     if ( !aglSetCurrentContext(m_aglContext
) ) 
  93         wxLogAGLError("aglSetCurrentContext"); 
  95     wx_const_cast(wxGLCanvas
&, win
).SetViewport(); 
  98 // ---------------------------------------------------------------------------- 
 100 // ---------------------------------------------------------------------------- 
 102 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
) 
 104 BEGIN_EVENT_TABLE(wxGLCanvas
, wxWindow
) 
 105     EVT_SIZE(wxGLCanvas::OnSize
) 
 108 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 110                        const int *attribList
, 
 114                        const wxString
& name
, 
 115                        const wxPalette
& palette
) 
 117     Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
); 
 120 #if WXWIN_COMPATIBILITY_2_8 
 122 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 127                        const wxString
& name
, 
 128                        const int *attribList
, 
 129                        const wxPalette
& palette
) 
 131     if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) ) 
 132         m_glContext 
= new wxGLContext(this); 
 135 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 136                        const wxGLContext 
*shared
, 
 141                        const wxString
& name
, 
 142                        const int *attribList
, 
 143                        const wxPalette
& palette
) 
 145     if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) ) 
 146         m_glContext 
= new wxGLContext(this, shared
); 
 149 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 150                        const wxGLCanvas 
*shared
, 
 155                        const wxString
& name
, 
 156                        const int *attribList
, 
 157                        const wxPalette
& palette
) 
 159     if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) ) 
 160         m_glContext 
= new wxGLContext(this, shared 
? shared
->m_glContext 
: NULL
); 
 163 #endif // WXWIN_COMPATIBILITY_2_8 
 165 static AGLPixelFormat 
ChoosePixelFormat(const int *attribList
) 
 168     const GLint defaultAttribs
[] = 
 172         AGL_MINIMUM_POLICY
, // never choose less than requested 
 173         AGL_DEPTH_SIZE
, 1,  // use largest available depth buffer 
 181     const GLint 
*attribs
; 
 184         attribs 
= defaultAttribs
; 
 189         data
[p
++] = AGL_MINIMUM_POLICY
; // make _SIZE tags behave more like GLX 
 191         for ( unsigned arg 
= 0; attribList
[arg
] !=0 && p 
< WXSIZEOF(data
); ) 
 193             switch ( attribList
[arg
++] ) 
 196                     data
[p
++] = AGL_RGBA
; 
 199                 case WX_GL_BUFFER_SIZE
: 
 200                     data
[p
++] = AGL_BUFFER_SIZE
; 
 201                     data
[p
++] = attribList
[arg
++]; 
 206                     data
[p
++]=attribList
[arg
++]; 
 209                 case WX_GL_DOUBLEBUFFER
: 
 210                     data
[p
++] = AGL_DOUBLEBUFFER
; 
 214                     data
[p
++] = AGL_STEREO
; 
 217                 case WX_GL_AUX_BUFFERS
: 
 218                     data
[p
++] = AGL_AUX_BUFFERS
; 
 219                     data
[p
++] = attribList
[arg
++]; 
 223                     data
[p
++] = AGL_RED_SIZE
; 
 224                     data
[p
++] = attribList
[arg
++]; 
 227                 case WX_GL_MIN_GREEN
: 
 228                     data
[p
++] = AGL_GREEN_SIZE
; 
 229                     data
[p
++] = attribList
[arg
++]; 
 233                     data
[p
++] = AGL_BLUE_SIZE
; 
 234                     data
[p
++] = attribList
[arg
++]; 
 237                 case WX_GL_MIN_ALPHA
: 
 238                     data
[p
++] = AGL_ALPHA_SIZE
; 
 239                     data
[p
++] = attribList
[arg
++]; 
 242                 case WX_GL_DEPTH_SIZE
: 
 243                     data
[p
++] = AGL_DEPTH_SIZE
; 
 244                     data
[p
++] = attribList
[arg
++]; 
 247                 case WX_GL_STENCIL_SIZE
: 
 248                     data
[p
++] = AGL_STENCIL_SIZE
; 
 249                     data
[p
++] = attribList
[arg
++]; 
 252                 case WX_GL_MIN_ACCUM_RED
: 
 253                     data
[p
++] = AGL_ACCUM_RED_SIZE
; 
 254                     data
[p
++] = attribList
[arg
++]; 
 257                 case WX_GL_MIN_ACCUM_GREEN
: 
 258                     data
[p
++] = AGL_ACCUM_GREEN_SIZE
; 
 259                     data
[p
++] = attribList
[arg
++]; 
 262                 case WX_GL_MIN_ACCUM_BLUE
: 
 263                     data
[p
++] = AGL_ACCUM_BLUE_SIZE
; 
 264                     data
[p
++] = attribList
[arg
++]; 
 267                 case WX_GL_MIN_ACCUM_ALPHA
: 
 268                     data
[p
++] = AGL_ACCUM_ALPHA_SIZE
; 
 269                     data
[p
++] = attribList
[arg
++]; 
 279     return aglChoosePixelFormat(NULL
, 0, attribs
); 
 282 bool wxGLCanvas::Create(wxWindow 
*parent
, 
 287                         const wxString
& name
, 
 288                         const int *attribList
, 
 289                         const wxPalette
& WXUNUSED(palette
)) 
 291     m_needsUpdate 
= false; 
 292     m_macCanvasIsShown 
= false; 
 294     m_aglFormat 
= ChoosePixelFormat(attribList
); 
 298     if ( !wxWindow::Create(parent
, id
, pos
, size
, style
, name
) ) 
 301     m_macCanvasIsShown 
= true; 
 306 wxGLCanvas::~wxGLCanvas() 
 309         aglDestroyPixelFormat(m_aglFormat
); 
 312 void wxGLCanvas::SwapBuffers() 
 314     AGLContext context 
= aglGetCurrentContext(); 
 315     wxCHECK_RET( context
, _T("should have current context") ); 
 317     aglSwapBuffers(context
); 
 320 void wxGLCanvas::SetViewport() 
 322     if ( !m_needsUpdate 
) 
 325     m_needsUpdate 
= false; 
 327     AGLContext context 
= aglGetCurrentContext(); 
 331     // viewport is initially set to entire port, adjust it to just this window 
 334     MacClientToRootWindow(&x 
, &y
); 
 337     GetClientSize(&width
, &height
); 
 340     GetWindowPortBounds(MAC_WXHWND(MacGetTopLevelWindowRef()) , &bounds
); 
 343     // TODO in case we adopt point vs pixel coordinates, this will make the conversion 
 344     HIRect hiRect 
= CGRectMake( x
, y
, width
, height 
); 
 345     HIRectConvert( &hiRect
, kHICoordSpace72DPIGlobal
, NULL
, kHICoordSpaceScreenPixel
, NULL
); 
 346     HIRect hiBounds 
= CGRectMake( 0, 0, bounds
.right 
- bounds
.left 
, bounds
.bottom 
- bounds
.top 
); 
 347     HIRectConvert( &hiBounds
, kHICoordSpace72DPIGlobal
, NULL
, kHICoordSpaceScreenPixel
, NULL
); 
 349     parms
[0] = hiRect
.origin
.x
; 
 350     parms
[1] = hiBounds
.size
.height 
- (hiRect
.origin
.y 
+ hiRect
.size
.height
); 
 351     parms
[2] = hiRect
.size
.width
; 
 352     parms
[3] = hiRect
.size
.height
; 
 356     parms
[1] = bounds
.bottom 
- bounds
.top 
- ( y 
+ height 
); 
 361     // move the buffer rect out of sight if we're hidden 
 362     if ( !m_macCanvasIsShown 
) 
 365     if ( !aglSetInteger(context
, AGL_BUFFER_RECT
, parms
) ) 
 366         wxLogAGLError("aglSetInteger(AGL_BUFFER_RECT)"); 
 368     if ( !aglUpdateContext(context
) ) 
 369         wxLogAGLError("aglUpdateContext"); 
 372 void wxGLCanvas::OnSize(wxSizeEvent
& event
) 
 378 void wxGLCanvas::MacUpdateView() 
 380     m_needsUpdate 
= true; 
 384 void wxGLCanvas::MacSuperChangedPosition() 
 387     wxWindow::MacSuperChangedPosition(); 
 390 void wxGLCanvas::MacTopLevelWindowChangedPosition() 
 393     wxWindow::MacTopLevelWindowChangedPosition(); 
 396 void wxGLCanvas::MacVisibilityChanged() 
 398     if ( MacIsReallyShown() != m_macCanvasIsShown 
) 
 400         m_macCanvasIsShown 
= !m_macCanvasIsShown
; 
 404     wxWindowMac::MacVisibilityChanged(); 
 407 // ---------------------------------------------------------------------------- 
 409 // ---------------------------------------------------------------------------- 
 411 bool wxGLApp::InitGLVisual(const int *attribList
) 
 413     AGLPixelFormat fmt 
= ChoosePixelFormat(attribList
); 
 417     aglDestroyPixelFormat(fmt
); 
 421 #endif // wxUSE_GLCANVAS