]>
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 wxGLContext::~wxGLContext() 
  72         // it's ok to pass the current context to this function 
  73         if ( !aglDestroyContext(m_aglContext
) ) 
  74             wxLogAGLError("aglDestroyContext"); 
  78 void wxGLContext::SetCurrent(const wxGLCanvas
& win
) const 
  83     AGLDrawable drawable 
= (AGLDrawable
)UMAGetWindowPort( 
  84                                 MAC_WXHWND(win
.MacGetTopLevelWindowRef())); 
  85     if ( !aglSetDrawable(m_aglContext
, drawable
) ) 
  86         wxLogAGLError("aglSetDrawable"); 
  88     if ( !aglSetCurrentContext(m_aglContext
) ) 
  89         wxLogAGLError("aglSetCurrentContext"); 
  91     wx_const_cast(wxGLCanvas
&, win
).SetViewport(); 
  94 // ---------------------------------------------------------------------------- 
  96 // ---------------------------------------------------------------------------- 
  98 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
) 
 100 BEGIN_EVENT_TABLE(wxGLCanvas
, wxWindow
) 
 101     EVT_SIZE(wxGLCanvas::OnSize
) 
 104 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 106                        const int *attribList
, 
 110                        const wxString
& name
, 
 111                        const wxPalette
& palette
) 
 113     Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
); 
 116 #if WXWIN_COMPATIBILITY_2_8 
 118 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 123                        const wxString
& name
, 
 124                        const int *attribList
, 
 125                        const wxPalette
& palette
) 
 127     if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) ) 
 128         m_glContext 
= new wxGLContext(this); 
 131 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 132                        const wxGLContext 
*shared
, 
 137                        const wxString
& name
, 
 138                        const int *attribList
, 
 139                        const wxPalette
& palette
) 
 141     if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) ) 
 142         m_glContext 
= new wxGLContext(this, shared
); 
 145 wxGLCanvas::wxGLCanvas(wxWindow 
*parent
, 
 146                        const wxGLCanvas 
*shared
, 
 151                        const wxString
& name
, 
 152                        const int *attribList
, 
 153                        const wxPalette
& palette
) 
 155     if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) ) 
 156         m_glContext 
= new wxGLContext(this, shared 
? shared
->m_glContext 
: NULL
); 
 159 #endif // WXWIN_COMPATIBILITY_2_8 
 161 static AGLPixelFormat 
ChoosePixelFormat(const int *attribList
) 
 164     const GLint defaultAttribs
[] = 
 168         AGL_MINIMUM_POLICY
, // never choose less than requested 
 169         AGL_DEPTH_SIZE
, 1,  // use largest available depth buffer 
 177     const GLint 
*attribs
; 
 180         attribs 
= defaultAttribs
; 
 185         data
[p
++] = AGL_MINIMUM_POLICY
; // make _SIZE tags behave more like GLX 
 187         for ( unsigned arg 
= 0; attribList
[arg
] !=0 && p 
< WXSIZEOF(data
); ) 
 189             switch ( attribList
[arg
++] ) 
 192                     data
[p
++] = AGL_RGBA
; 
 195                 case WX_GL_BUFFER_SIZE
: 
 196                     data
[p
++] = AGL_BUFFER_SIZE
; 
 197                     data
[p
++] = attribList
[arg
++]; 
 202                     data
[p
++]=attribList
[arg
++]; 
 205                 case WX_GL_DOUBLEBUFFER
: 
 206                     data
[p
++] = AGL_DOUBLEBUFFER
; 
 210                     data
[p
++] = AGL_STEREO
; 
 213                 case WX_GL_AUX_BUFFERS
: 
 214                     data
[p
++] = AGL_AUX_BUFFERS
; 
 215                     data
[p
++] = attribList
[arg
++]; 
 219                     data
[p
++] = AGL_RED_SIZE
; 
 220                     data
[p
++] = attribList
[arg
++]; 
 223                 case WX_GL_MIN_GREEN
: 
 224                     data
[p
++] = AGL_GREEN_SIZE
; 
 225                     data
[p
++] = attribList
[arg
++]; 
 229                     data
[p
++] = AGL_BLUE_SIZE
; 
 230                     data
[p
++] = attribList
[arg
++]; 
 233                 case WX_GL_MIN_ALPHA
: 
 234                     data
[p
++] = AGL_ALPHA_SIZE
; 
 235                     data
[p
++] = attribList
[arg
++]; 
 238                 case WX_GL_DEPTH_SIZE
: 
 239                     data
[p
++] = AGL_DEPTH_SIZE
; 
 240                     data
[p
++] = attribList
[arg
++]; 
 243                 case WX_GL_STENCIL_SIZE
: 
 244                     data
[p
++] = AGL_STENCIL_SIZE
; 
 245                     data
[p
++] = attribList
[arg
++]; 
 248                 case WX_GL_MIN_ACCUM_RED
: 
 249                     data
[p
++] = AGL_ACCUM_RED_SIZE
; 
 250                     data
[p
++] = attribList
[arg
++]; 
 253                 case WX_GL_MIN_ACCUM_GREEN
: 
 254                     data
[p
++] = AGL_ACCUM_GREEN_SIZE
; 
 255                     data
[p
++] = attribList
[arg
++]; 
 258                 case WX_GL_MIN_ACCUM_BLUE
: 
 259                     data
[p
++] = AGL_ACCUM_BLUE_SIZE
; 
 260                     data
[p
++] = attribList
[arg
++]; 
 263                 case WX_GL_MIN_ACCUM_ALPHA
: 
 264                     data
[p
++] = AGL_ACCUM_ALPHA_SIZE
; 
 265                     data
[p
++] = attribList
[arg
++]; 
 275     return aglChoosePixelFormat(NULL
, 0, attribs
); 
 278 bool wxGLCanvas::Create(wxWindow 
*parent
, 
 283                         const wxString
& name
, 
 284                         const int *attribList
, 
 285                         const wxPalette
& WXUNUSED(palette
)) 
 287     m_needsUpdate 
= false; 
 288     m_macCanvasIsShown 
= false; 
 290     m_aglFormat 
= ChoosePixelFormat(attribList
); 
 294     if ( !wxWindow::Create(parent
, id
, pos
, size
, style
, name
) ) 
 297     m_macCanvasIsShown 
= true; 
 302 wxGLCanvas::~wxGLCanvas() 
 305         aglDestroyPixelFormat(m_aglFormat
); 
 308 void wxGLCanvas::SwapBuffers() 
 310     AGLContext context 
= aglGetCurrentContext(); 
 311     wxCHECK_RET( context
, _T("should have current context") ); 
 313     aglSwapBuffers(context
); 
 316 void wxGLCanvas::SetViewport() 
 318     if ( !m_needsUpdate 
) 
 321     m_needsUpdate 
= false; 
 323     AGLContext context 
= aglGetCurrentContext(); 
 327     // viewport is initially set to entire port, adjust it to just this window 
 330     MacClientToRootWindow(&x 
, &y
); 
 333     GetClientSize(&width
, &height
); 
 336     GetWindowPortBounds(MAC_WXHWND(MacGetTopLevelWindowRef()) , &bounds
); 
 339     // TODO in case we adopt point vs pixel coordinates, this will make the conversion 
 340     HIRect hiRect 
= CGRectMake( x
, y
, width
, height 
); 
 341     HIRectConvert( &hiRect
, kHICoordSpace72DPIGlobal
, NULL
, kHICoordSpaceScreenPixel
, NULL
); 
 342     HIRect hiBounds 
= CGRectMake( 0, 0, bounds
.right 
- bounds
.left 
, bounds
.bottom 
- bounds
.top 
); 
 343     HIRectConvert( &hiBounds
, kHICoordSpace72DPIGlobal
, NULL
, kHICoordSpaceScreenPixel
, NULL
); 
 345     parms
[0] = hiRect
.origin
.x
; 
 346     parms
[1] = hiBounds
.size
.height 
- (hiRect
.origin
.y 
+ hiRect
.size
.height
); 
 347     parms
[2] = hiRect
.size
.width
; 
 348     parms
[3] = hiRect
.size
.height
; 
 352     parms
[1] = bounds
.bottom 
- bounds
.top 
- ( y 
+ height 
); 
 357     // move the buffer rect out of sight if we're hidden 
 358     if ( !m_macCanvasIsShown 
) 
 361     if ( !aglSetInteger(context
, AGL_BUFFER_RECT
, parms
) ) 
 362         wxLogAGLError("aglSetInteger(AGL_BUFFER_RECT)"); 
 364     if ( !aglEnable(context
, AGL_BUFFER_RECT
) ) 
 365         wxLogAGLError("aglEnable(AGL_BUFFER_RECT)"); 
 367     if ( !aglUpdateContext(context
) ) 
 368         wxLogAGLError("aglUpdateContext"); 
 371 void wxGLCanvas::OnSize(wxSizeEvent
& event
) 
 377 void wxGLCanvas::MacUpdateView() 
 379     m_needsUpdate 
= true; 
 383 void wxGLCanvas::MacSuperChangedPosition() 
 386     wxWindow::MacSuperChangedPosition(); 
 389 void wxGLCanvas::MacTopLevelWindowChangedPosition() 
 392     wxWindow::MacTopLevelWindowChangedPosition(); 
 395 void wxGLCanvas::MacVisibilityChanged() 
 397     if ( MacIsReallyShown() != m_macCanvasIsShown 
) 
 399         m_macCanvasIsShown 
= !m_macCanvasIsShown
; 
 403     wxWindowMac::MacVisibilityChanged(); 
 406 // ---------------------------------------------------------------------------- 
 408 // ---------------------------------------------------------------------------- 
 410 bool wxGLApp::InitGLVisual(const int *attribList
) 
 412     AGLPixelFormat fmt 
= ChoosePixelFormat(attribList
); 
 416     aglDestroyPixelFormat(fmt
); 
 420 #endif // wxUSE_GLCANVAS