1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxGLCanvas, for using OpenGL with wxWindows under MS Windows
4 // Author: Julian Smart
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 #pragma implementation "glcanvas.h"
16 #include "wx/wxprec.h"
18 #if defined(__BORLANDC__)
31 * GLContext implementation
34 wxGLContext::wxGLContext(bool isRGB
, wxWindow
*win
, const wxPalette
& palette
)
38 m_hDC
= (WXHDC
) ::GetDC((HWND
) win
->GetHWND());
41 SetupPalette(palette
);
43 m_glContext
= wglCreateContext((HDC
) m_hDC
);
44 wglMakeCurrent((HDC
) m_hDC
, m_glContext
);
47 wxGLContext::~wxGLContext()
51 wglMakeCurrent(NULL
, NULL
);
52 wglDeleteContext(m_glContext
);
55 ::ReleaseDC((HWND
) m_window
->GetHWND(), (HDC
) m_hDC
);
58 void wxGLContext::SwapBuffers()
62 wglMakeCurrent((HDC
) m_hDC
, m_glContext
);
63 ::SwapBuffers((HDC
) m_hDC
); //blits the backbuffer into DC
67 void wxGLContext::SetCurrent()
71 wglMakeCurrent((HDC
) m_hDC
, m_glContext
);
75 setupPixelFormat(hDC);
80 void wxGLContext::SetColour(const char *colour
)
85 wxColour
*col
= wxTheColourDatabase
->FindColour(colour
);
88 r
= (float)(col
->Red()/256.0);
89 g
= (float)(col
->Green()/256.0);
90 b
= (float)(col
->Blue()/256.0);
95 void wxGLContext::SetupPixelFormat() // (HDC hDC)
97 PIXELFORMATDESCRIPTOR pfd
= {
98 sizeof(PIXELFORMATDESCRIPTOR
), /* size */
102 PFD_DOUBLEBUFFER
, /* support double-buffering */
103 PFD_TYPE_RGBA
, /* color type */
104 16, /* prefered color depth */
105 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
106 0, /* no alpha buffer */
107 0, /* alpha bits (ignored) */
108 0, /* no accumulation buffer */
109 0, 0, 0, 0, /* accum bits (ignored) */
110 16, /* depth buffer */
111 0, /* no stencil buffer */
112 0, /* no auxiliary buffers */
113 PFD_MAIN_PLANE
, /* main layer */
115 0, 0, 0, /* no layer, visible, damage masks */
119 pixelFormat
= ChoosePixelFormat((HDC
) m_hDC
, &pfd
);
120 if (pixelFormat
== 0) {
121 MessageBox(WindowFromDC((HDC
) m_hDC
), "ChoosePixelFormat failed.", "Error",
122 MB_ICONERROR
| MB_OK
);
126 if (SetPixelFormat((HDC
) m_hDC
, pixelFormat
, &pfd
) != TRUE
) {
127 MessageBox(WindowFromDC((HDC
) m_hDC
), "SetPixelFormat failed.", "Error",
128 MB_ICONERROR
| MB_OK
);
133 void wxGLContext::SetupPalette(const wxPalette
& palette
)
135 int pixelFormat
= GetPixelFormat((HDC
) m_hDC
);
136 PIXELFORMATDESCRIPTOR pfd
;
138 DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
);
140 if (pfd
.dwFlags
& PFD_NEED_PALETTE
)
150 if ( !m_palette
.Ok() )
152 m_palette
= CreateDefaultPalette();
157 SelectPalette((HDC
) m_hDC
, (HPALETTE
) m_palette
.GetHPALETTE(), FALSE
);
158 RealizePalette((HDC
) m_hDC
);
162 wxPalette
wxGLContext::CreateDefaultPalette()
164 PIXELFORMATDESCRIPTOR pfd
;
166 int pixelFormat
= GetPixelFormat((HDC
) m_hDC
);
168 DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
);
170 paletteSize
= 1 << pfd
.cColorBits
;
173 (LOGPALETTE
*) malloc(sizeof(LOGPALETTE
) + paletteSize
* sizeof(PALETTEENTRY
));
174 pPal
->palVersion
= 0x300;
175 pPal
->palNumEntries
= paletteSize
;
177 /* build a simple RGB color palette */
179 int redMask
= (1 << pfd
.cRedBits
) - 1;
180 int greenMask
= (1 << pfd
.cGreenBits
) - 1;
181 int blueMask
= (1 << pfd
.cBlueBits
) - 1;
184 for (i
=0; i
<paletteSize
; ++i
) {
185 pPal
->palPalEntry
[i
].peRed
=
186 (((i
>> pfd
.cRedShift
) & redMask
) * 255) / redMask
;
187 pPal
->palPalEntry
[i
].peGreen
=
188 (((i
>> pfd
.cGreenShift
) & greenMask
) * 255) / greenMask
;
189 pPal
->palPalEntry
[i
].peBlue
=
190 (((i
>> pfd
.cBlueShift
) & blueMask
) * 255) / blueMask
;
191 pPal
->palPalEntry
[i
].peFlags
= 0;
195 HPALETTE hPalette
= CreatePalette(pPal
);
199 palette
.SetHPALETTE((WXHPALETTE
) hPalette
);
205 * wxGLCanvas implementation
208 IMPLEMENT_CLASS(wxGLCanvas
, wxScrolledWindow
)
210 BEGIN_EVENT_TABLE(wxGLCanvas
, wxScrolledWindow
)
211 EVT_SIZE(wxGLCanvas::OnSize
)
212 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged
)
213 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette
)
216 wxGLCanvas::wxGLCanvas(wxWindow
*parent
, wxWindowID id
,
217 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
,
218 int *attribList
/* not used yet! */, const wxPalette
& palette
):
219 wxScrolledWindow(parent
, id
, pos
, size
, style
, name
)
221 m_glContext
= new wxGLContext(TRUE
, this, palette
);
224 wxGLCanvas::~wxGLCanvas()
230 void wxGLCanvas::SwapBuffers()
233 m_glContext
->SwapBuffers();
236 void wxGLCanvas::OnSize(wxSizeEvent
& event
)
239 GetClientSize(& width
, & height
);
243 m_glContext
->SetCurrent();
245 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
246 glMatrixMode(GL_PROJECTION
);
248 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
249 glMatrixMode(GL_MODELVIEW
);
253 void wxGLCanvas::SetCurrent()
257 m_glContext
->SetCurrent();
261 void wxGLCanvas::SetColour(const char *colour
)
264 m_glContext
->SetColour(colour
);
267 // TODO: Have to have this called by parent frame (?)
268 // So we need wxFrame to call OnQueryNewPalette for all children...
269 void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent
& event
)
271 /* realize palette if this is the current window */
272 if (m_glContext
&& m_glContext
->GetPalette()->Ok()) {
273 ::UnrealizeObject((HPALETTE
) m_glContext
->GetPalette()->GetHPALETTE());
274 ::SelectPalette((HDC
) m_glContext
->GetHDC(), (HPALETTE
) m_glContext
->GetPalette()->GetHPALETTE(), FALSE
);
275 ::RealizePalette((HDC
) m_glContext
->GetHDC());
277 event
.SetPaletteRealized(TRUE
);
280 event
.SetPaletteRealized(FALSE
);
283 // I think this doesn't have to be propagated to child windows.
284 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent
& event
)
286 /* realize palette if this is *not* the current window */
288 m_glContext
->GetPalette() &&
289 m_glContext
->GetPalette()->Ok() &&
290 (this != event
.GetChangedWindow()) )
292 ::UnrealizeObject((HPALETTE
) m_glContext
->GetPalette()->GetHPALETTE());
293 ::SelectPalette((HDC
) m_glContext
->GetHDC(), (HPALETTE
) m_glContext
->GetPalette()->GetHPALETTE(), FALSE
);
294 ::RealizePalette((HDC
) m_glContext
->GetHDC());
299 /* Give extensions proper function names. */
301 /* EXT_vertex_array */
302 void glArrayElementEXT(GLint i
)
306 void glColorPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
310 void glDrawArraysEXT(GLenum mode
, GLint first
, GLsizei count
)
312 #ifdef GL_EXT_vertex_array
313 static PFNGLDRAWARRAYSEXTPROC proc
= 0;
317 proc
= (PFNGLDRAWARRAYSEXTPROC
) wglGetProcAddress("glDrawArraysEXT");
321 (* proc
) (mode
, first
, count
);
325 void glEdgeFlagPointerEXT(GLsizei stride
, GLsizei count
, const GLboolean
*pointer
)
329 void glGetPointervEXT(GLenum pname
, GLvoid
* *params
)
333 void glIndexPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
337 void glNormalPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
339 #ifdef GL_EXT_vertex_array
340 static PFNGLNORMALPOINTEREXTPROC proc
= 0;
344 proc
= (PFNGLNORMALPOINTEREXTPROC
) wglGetProcAddress("glNormalPointerEXT");
348 (* proc
) (type
, stride
, count
, pointer
);
352 void glTexCoordPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
356 void glVertexPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
358 #ifdef GL_EXT_vertex_array
359 static PFNGLVERTEXPOINTEREXTPROC proc
= 0;
363 proc
= (PFNGLVERTEXPOINTEREXTPROC
) wglGetProcAddress("glVertexPointerEXT");
367 (* proc
) (size
, type
, stride
, count
, pointer
);
371 /* EXT_color_subtable */
372 void glColorSubtableEXT(GLenum target
, GLsizei start
, GLsizei count
, GLenum format
, GLenum type
, const GLvoid
*table
)
376 /* EXT_color_table */
377 void glColorTableEXT(GLenum target
, GLenum internalformat
, GLsizei width
, GLenum format
, GLenum type
, const GLvoid
*table
)
381 void glCopyColorTableEXT(GLenum target
, GLenum internalformat
, GLint x
, GLint y
, GLsizei width
)
385 void glGetColorTableEXT(GLenum target
, GLenum format
, GLenum type
, GLvoid
*table
)
389 void glGetColorTableParamaterfvEXT(GLenum target
, GLenum pname
, GLfloat
*params
)
393 void glGetColorTavleParameterivEXT(GLenum target
, GLenum pname
, GLint
*params
)
397 /* SGI_compiled_vertex_array */
398 void glLockArraysSGI(GLint first
, GLsizei count
)
402 void glUnlockArraysSGI()
407 /* SGI_cull_vertex */
408 void glCullParameterdvSGI(GLenum pname
, GLdouble
* params
)
412 void glCullParameterfvSGI(GLenum pname
, GLfloat
* params
)
417 void glIndexFuncSGI(GLenum func
, GLclampf ref
)
421 /* SGI_index_material */
422 void glIndexMaterialSGI(GLenum face
, GLenum mode
)
427 void glAddSwapHintRectWin(GLint x
, GLint y
, GLsizei width
, GLsizei height
)