]>
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