]>
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 bool wxGLContext::SetCurrent(const wxGLCanvas
& win
) const
83 AGLDrawable drawable
= (AGLDrawable
)GetWindowPort(
84 MAC_WXHWND(win
.MacGetTopLevelWindowRef()));
85 if ( !aglSetDrawable(m_aglContext
, drawable
) )
87 wxLogAGLError("aglSetDrawable");
91 if ( !aglSetCurrentContext(m_aglContext
) )
93 wxLogAGLError("aglSetCurrentContext");
97 wx_const_cast(wxGLCanvas
&, win
).SetViewport();
101 // ----------------------------------------------------------------------------
103 // ----------------------------------------------------------------------------
105 IMPLEMENT_CLASS(wxGLCanvas
, wxWindow
)
107 BEGIN_EVENT_TABLE(wxGLCanvas
, wxWindow
)
108 EVT_SIZE(wxGLCanvas::OnSize
)
111 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
113 const int *attribList
,
117 const wxString
& name
,
118 const wxPalette
& palette
)
120 Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
);
123 #if WXWIN_COMPATIBILITY_2_8
125 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
130 const wxString
& name
,
131 const int *attribList
,
132 const wxPalette
& palette
)
134 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
135 m_glContext
= new wxGLContext(this);
138 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
139 const wxGLContext
*shared
,
144 const wxString
& name
,
145 const int *attribList
,
146 const wxPalette
& palette
)
148 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
149 m_glContext
= new wxGLContext(this, shared
);
152 wxGLCanvas::wxGLCanvas(wxWindow
*parent
,
153 const wxGLCanvas
*shared
,
158 const wxString
& name
,
159 const int *attribList
,
160 const wxPalette
& palette
)
162 if ( Create(parent
, id
, pos
, size
, style
, name
, attribList
, palette
) )
163 m_glContext
= new wxGLContext(this, shared
? shared
->m_glContext
: NULL
);
166 #endif // WXWIN_COMPATIBILITY_2_8
168 static AGLPixelFormat
ChoosePixelFormat(const int *attribList
)
171 const GLint defaultAttribs
[] =
175 AGL_MINIMUM_POLICY
, // never choose less than requested
176 AGL_DEPTH_SIZE
, 1, // use largest available depth buffer
184 const GLint
*attribs
;
187 attribs
= defaultAttribs
;
192 data
[p
++] = AGL_MINIMUM_POLICY
; // make _SIZE tags behave more like GLX
194 for ( unsigned arg
= 0; attribList
[arg
] !=0 && p
< WXSIZEOF(data
); )
196 switch ( attribList
[arg
++] )
199 data
[p
++] = AGL_RGBA
;
202 case WX_GL_BUFFER_SIZE
:
203 data
[p
++] = AGL_BUFFER_SIZE
;
204 data
[p
++] = attribList
[arg
++];
209 data
[p
++]=attribList
[arg
++];
212 case WX_GL_DOUBLEBUFFER
:
213 data
[p
++] = AGL_DOUBLEBUFFER
;
217 data
[p
++] = AGL_STEREO
;
220 case WX_GL_AUX_BUFFERS
:
221 data
[p
++] = AGL_AUX_BUFFERS
;
222 data
[p
++] = attribList
[arg
++];
226 data
[p
++] = AGL_RED_SIZE
;
227 data
[p
++] = attribList
[arg
++];
230 case WX_GL_MIN_GREEN
:
231 data
[p
++] = AGL_GREEN_SIZE
;
232 data
[p
++] = attribList
[arg
++];
236 data
[p
++] = AGL_BLUE_SIZE
;
237 data
[p
++] = attribList
[arg
++];
240 case WX_GL_MIN_ALPHA
:
241 data
[p
++] = AGL_ALPHA_SIZE
;
242 data
[p
++] = attribList
[arg
++];
245 case WX_GL_DEPTH_SIZE
:
246 data
[p
++] = AGL_DEPTH_SIZE
;
247 data
[p
++] = attribList
[arg
++];
250 case WX_GL_STENCIL_SIZE
:
251 data
[p
++] = AGL_STENCIL_SIZE
;
252 data
[p
++] = attribList
[arg
++];
255 case WX_GL_MIN_ACCUM_RED
:
256 data
[p
++] = AGL_ACCUM_RED_SIZE
;
257 data
[p
++] = attribList
[arg
++];
260 case WX_GL_MIN_ACCUM_GREEN
:
261 data
[p
++] = AGL_ACCUM_GREEN_SIZE
;
262 data
[p
++] = attribList
[arg
++];
265 case WX_GL_MIN_ACCUM_BLUE
:
266 data
[p
++] = AGL_ACCUM_BLUE_SIZE
;
267 data
[p
++] = attribList
[arg
++];
270 case WX_GL_MIN_ACCUM_ALPHA
:
271 data
[p
++] = AGL_ACCUM_ALPHA_SIZE
;
272 data
[p
++] = attribList
[arg
++];
282 return aglChoosePixelFormat(NULL
, 0, attribs
);
285 bool wxGLCanvas::Create(wxWindow
*parent
,
290 const wxString
& name
,
291 const int *attribList
,
292 const wxPalette
& WXUNUSED(palette
))
294 m_needsUpdate
= false;
295 m_macCanvasIsShown
= false;
297 m_aglFormat
= ChoosePixelFormat(attribList
);
301 if ( !wxWindow::Create(parent
, id
, pos
, size
, style
, name
) )
304 m_macCanvasIsShown
= true;
309 wxGLCanvas::~wxGLCanvas()
312 aglDestroyPixelFormat(m_aglFormat
);
316 bool wxGLCanvasBase::IsDisplaySupported(const int *attribList
)
318 AGLPixelFormat aglFormat
= ChoosePixelFormat(attribList
);
323 aglDestroyPixelFormat(aglFormat
);
328 bool wxGLCanvas::SwapBuffers()
330 AGLContext context
= aglGetCurrentContext();
331 wxCHECK_MSG(context
, false, _T("should have current context"));
333 aglSwapBuffers(context
);
337 void wxGLCanvas::SetViewport()
339 if ( !m_needsUpdate
)
342 m_needsUpdate
= false;
344 AGLContext context
= aglGetCurrentContext();
348 // viewport is initially set to entire port, adjust it to just this window
351 MacClientToRootWindow(&x
, &y
);
354 GetClientSize(&width
, &height
);
357 GetWindowPortBounds(MAC_WXHWND(MacGetTopLevelWindowRef()) , &bounds
);
360 // TODO in case we adopt point vs pixel coordinates, this will make the conversion
361 HIRect hiRect
= CGRectMake( x
, y
, width
, height
);
362 HIRectConvert( &hiRect
, kHICoordSpace72DPIGlobal
, NULL
, kHICoordSpaceScreenPixel
, NULL
);
363 HIRect hiBounds
= CGRectMake( 0, 0, bounds
.right
- bounds
.left
, bounds
.bottom
- bounds
.top
);
364 HIRectConvert( &hiBounds
, kHICoordSpace72DPIGlobal
, NULL
, kHICoordSpaceScreenPixel
, NULL
);
366 parms
[0] = hiRect
.origin
.x
;
367 parms
[1] = hiBounds
.size
.height
- (hiRect
.origin
.y
+ hiRect
.size
.height
);
368 parms
[2] = hiRect
.size
.width
;
369 parms
[3] = hiRect
.size
.height
;
373 parms
[1] = bounds
.bottom
- bounds
.top
- ( y
+ height
);
378 // move the buffer rect out of sight if we're hidden
379 if ( !m_macCanvasIsShown
)
382 if ( !aglSetInteger(context
, AGL_BUFFER_RECT
, parms
) )
383 wxLogAGLError("aglSetInteger(AGL_BUFFER_RECT)");
385 if ( !aglEnable(context
, AGL_BUFFER_RECT
) )
386 wxLogAGLError("aglEnable(AGL_BUFFER_RECT)");
388 if ( !aglUpdateContext(context
) )
389 wxLogAGLError("aglUpdateContext");
392 void wxGLCanvas::OnSize(wxSizeEvent
& event
)
398 void wxGLCanvas::MacUpdateView()
400 m_needsUpdate
= true;
404 void wxGLCanvas::MacSuperChangedPosition()
407 wxWindow::MacSuperChangedPosition();
410 void wxGLCanvas::MacTopLevelWindowChangedPosition()
413 wxWindow::MacTopLevelWindowChangedPosition();
416 void wxGLCanvas::MacVisibilityChanged()
418 if ( IsShownOnScreen() != m_macCanvasIsShown
)
420 m_macCanvasIsShown
= !m_macCanvasIsShown
;
424 wxWindowMac::MacVisibilityChanged();
427 // ----------------------------------------------------------------------------
429 // ----------------------------------------------------------------------------
431 bool wxGLApp::InitGLVisual(const int *attribList
)
433 AGLPixelFormat fmt
= ChoosePixelFormat(attribList
);
437 aglDestroyPixelFormat(fmt
);
441 #endif // wxUSE_GLCANVAS