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__)
29 * GLContext implementation
32 wxGLContext::wxGLContext(bool isRGB
, wxWindow
*win
, const wxPalette
& palette
)
36 m_hDC
= (WXHDC
) ::GetDC((HWND
) win
->GetHWND());
39 SetupPalette(palette
);
41 m_glContext
= wglCreateContext((HDC
) m_hDC
);
42 wglMakeCurrent((HDC
) m_hDC
, m_glContext
);
45 wxGLContext::~wxGLContext()
49 wglMakeCurrent(NULL
, NULL
);
50 wglDeleteContext(m_glContext
);
53 ::ReleaseDC((HWND
) m_window
->GetHWND(), (HDC
) m_hDC
);
56 void wxGLContext::SwapBuffers()
60 wglMakeCurrent((HDC
) m_hDC
, m_glContext
);
61 ::SwapBuffers((HDC
) m_hDC
); //blits the backbuffer into DC
65 void wxGLContext::SetCurrent()
69 wglMakeCurrent((HDC
) m_hDC
, m_glContext
);
73 setupPixelFormat(hDC);
78 void wxGLContext::SetColour(const char *colour
)
83 wxColour
*col
= wxTheColourDatabase
->FindColour(colour
);
86 r
= (float)(col
->Red()/256.0);
87 g
= (float)(col
->Green()/256.0);
88 b
= (float)(col
->Blue()/256.0);
93 void wxGLContext::SetupPixelFormat() // (HDC hDC)
95 PIXELFORMATDESCRIPTOR pfd
= {
96 sizeof(PIXELFORMATDESCRIPTOR
), /* size */
100 PFD_DOUBLEBUFFER
, /* support double-buffering */
101 PFD_TYPE_RGBA
, /* color type */
102 16, /* prefered color depth */
103 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
104 0, /* no alpha buffer */
105 0, /* alpha bits (ignored) */
106 0, /* no accumulation buffer */
107 0, 0, 0, 0, /* accum bits (ignored) */
108 16, /* depth buffer */
109 0, /* no stencil buffer */
110 0, /* no auxiliary buffers */
111 PFD_MAIN_PLANE
, /* main layer */
113 0, 0, 0, /* no layer, visible, damage masks */
117 pixelFormat
= ChoosePixelFormat((HDC
) m_hDC
, &pfd
);
118 if (pixelFormat
== 0) {
119 MessageBox(WindowFromDC((HDC
) m_hDC
), "ChoosePixelFormat failed.", "Error",
120 MB_ICONERROR
| MB_OK
);
124 if (SetPixelFormat((HDC
) m_hDC
, pixelFormat
, &pfd
) != TRUE
) {
125 MessageBox(WindowFromDC((HDC
) m_hDC
), "SetPixelFormat failed.", "Error",
126 MB_ICONERROR
| MB_OK
);
131 void wxGLContext::SetupPalette(const wxPalette
& palette
)
133 int pixelFormat
= GetPixelFormat((HDC
) m_hDC
);
134 PIXELFORMATDESCRIPTOR pfd
;
136 DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
);
138 if (pfd
.dwFlags
& PFD_NEED_PALETTE
)
148 if ( !m_palette
.Ok() )
150 m_palette
= CreateDefaultPalette();
155 SelectPalette((HDC
) m_hDC
, (HPALETTE
) m_palette
.GetHPALETTE(), FALSE
);
156 RealizePalette((HDC
) m_hDC
);
160 wxPalette
wxGLContext::CreateDefaultPalette()
162 PIXELFORMATDESCRIPTOR pfd
;
164 int pixelFormat
= GetPixelFormat((HDC
) m_hDC
);
166 DescribePixelFormat((HDC
) m_hDC
, pixelFormat
, sizeof(PIXELFORMATDESCRIPTOR
), &pfd
);
168 paletteSize
= 1 << pfd
.cColorBits
;
171 (LOGPALETTE
*) malloc(sizeof(LOGPALETTE
) + paletteSize
* sizeof(PALETTEENTRY
));
172 pPal
->palVersion
= 0x300;
173 pPal
->palNumEntries
= paletteSize
;
175 /* build a simple RGB color palette */
177 int redMask
= (1 << pfd
.cRedBits
) - 1;
178 int greenMask
= (1 << pfd
.cGreenBits
) - 1;
179 int blueMask
= (1 << pfd
.cBlueBits
) - 1;
182 for (i
=0; i
<paletteSize
; ++i
) {
183 pPal
->palPalEntry
[i
].peRed
=
184 (((i
>> pfd
.cRedShift
) & redMask
) * 255) / redMask
;
185 pPal
->palPalEntry
[i
].peGreen
=
186 (((i
>> pfd
.cGreenShift
) & greenMask
) * 255) / greenMask
;
187 pPal
->palPalEntry
[i
].peBlue
=
188 (((i
>> pfd
.cBlueShift
) & blueMask
) * 255) / blueMask
;
189 pPal
->palPalEntry
[i
].peFlags
= 0;
193 HPALETTE hPalette
= CreatePalette(pPal
);
197 palette
.SetHPALETTE((WXHPALETTE
) hPalette
);
203 * wxGLCanvas implementation
206 IMPLEMENT_CLASS(wxGLCanvas
, wxScrolledWindow
)
208 BEGIN_EVENT_TABLE(wxGLCanvas
, wxScrolledWindow
)
209 EVT_SIZE(wxGLCanvas::OnSize
)
210 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged
)
211 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette
)
214 wxGLCanvas::wxGLCanvas(wxWindow
*parent
, wxWindowID id
,
215 const wxPoint
& pos
, const wxSize
& size
, long style
, const wxString
& name
,
216 int *attribList
/* not used yet! */, const wxPalette
& palette
):
217 wxScrolledWindow(parent
, id
, pos
, size
, style
, name
)
219 m_glContext
= new wxGLContext(TRUE
, this, palette
);
222 wxGLCanvas::~wxGLCanvas()
228 void wxGLCanvas::SwapBuffers()
231 m_glContext
->SwapBuffers();
234 void wxGLCanvas::OnSize(wxSizeEvent
& event
)
237 GetClientSize(& width
, & height
);
241 m_glContext
->SetCurrent();
243 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
244 glMatrixMode(GL_PROJECTION
);
246 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
247 glMatrixMode(GL_MODELVIEW
);
251 void wxGLCanvas::SetCurrent()
255 m_glContext
->SetCurrent();
259 void wxGLCanvas::SetColour(const char *colour
)
262 m_glContext
->SetColour(colour
);
265 // TODO: Have to have this called by parent frame (?)
266 // So we need wxFrame to call OnQueryNewPalette for all children...
267 void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent
& event
)
269 /* realize palette if this is the current window */
270 if (m_glContext
&& m_glContext
->GetPalette()->Ok()) {
271 ::UnrealizeObject((HPALETTE
) m_glContext
->GetPalette()->GetHPALETTE());
272 ::SelectPalette((HDC
) m_glContext
->GetHDC(), (HPALETTE
) m_glContext
->GetPalette()->GetHPALETTE(), FALSE
);
273 ::RealizePalette((HDC
) m_glContext
->GetHDC());
275 event
.SetPaletteRealized(TRUE
);
278 event
.SetPaletteRealized(FALSE
);
281 // I think this doesn't have to be propagated to child windows.
282 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent
& event
)
284 /* realize palette if this is *not* the current window */
286 m_glContext
->GetPalette() &&
287 m_glContext
->GetPalette()->Ok() &&
288 (this != event
.GetChangedWindow()) )
290 ::UnrealizeObject((HPALETTE
) m_glContext
->GetPalette()->GetHPALETTE());
291 ::SelectPalette((HDC
) m_glContext
->GetHDC(), (HPALETTE
) m_glContext
->GetPalette()->GetHPALETTE(), FALSE
);
292 ::RealizePalette((HDC
) m_glContext
->GetHDC());
297 /* Give extensions proper function names. */
299 /* EXT_vertex_array */
300 void glArrayElementEXT(GLint i
)
304 void glColorPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
308 void glDrawArraysEXT(GLenum mode
, GLint first
, GLsizei count
)
310 #ifdef GL_EXT_vertex_array
311 static PFNGLDRAWARRAYSEXTPROC proc
= 0;
315 proc
= (PFNGLDRAWARRAYSEXTPROC
) wglGetProcAddress("glDrawArraysEXT");
319 (* proc
) (mode
, first
, count
);
323 void glEdgeFlagPointerEXT(GLsizei stride
, GLsizei count
, const GLboolean
*pointer
)
327 void glGetPointervEXT(GLenum pname
, GLvoid
* *params
)
331 void glIndexPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
335 void glNormalPointerEXT(GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
337 #ifdef GL_EXT_vertex_array
338 static PFNGLNORMALPOINTEREXTPROC proc
= 0;
342 proc
= (PFNGLNORMALPOINTEREXTPROC
) wglGetProcAddress("glNormalPointerEXT");
346 (* proc
) (type
, stride
, count
, pointer
);
350 void glTexCoordPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
354 void glVertexPointerEXT(GLint size
, GLenum type
, GLsizei stride
, GLsizei count
, const GLvoid
*pointer
)
356 #ifdef GL_EXT_vertex_array
357 static PFNGLVERTEXPOINTEREXTPROC proc
= 0;
361 proc
= (PFNGLVERTEXPOINTEREXTPROC
) wglGetProcAddress("glVertexPointerEXT");
365 (* proc
) (size
, type
, stride
, count
, pointer
);
369 /* EXT_color_subtable */
370 void glColorSubtableEXT(GLenum target
, GLsizei start
, GLsizei count
, GLenum format
, GLenum type
, const GLvoid
*table
)
374 /* EXT_color_table */
375 void glColorTableEXT(GLenum target
, GLenum internalformat
, GLsizei width
, GLenum format
, GLenum type
, const GLvoid
*table
)
379 void glCopyColorTableEXT(GLenum target
, GLenum internalformat
, GLint x
, GLint y
, GLsizei width
)
383 void glGetColorTableEXT(GLenum target
, GLenum format
, GLenum type
, GLvoid
*table
)
387 void glGetColorTableParamaterfvEXT(GLenum target
, GLenum pname
, GLfloat
*params
)
391 void glGetColorTavleParameterivEXT(GLenum target
, GLenum pname
, GLint
*params
)
395 /* SGI_compiled_vertex_array */
396 void glLockArraysSGI(GLint first
, GLsizei count
)
400 void glUnlockArraysSGI()
405 /* SGI_cull_vertex */
406 void glCullParameterdvSGI(GLenum pname
, GLdouble
* params
)
410 void glCullParameterfvSGI(GLenum pname
, GLfloat
* params
)
415 void glIndexFuncSGI(GLenum func
, GLclampf ref
)
419 /* SGI_index_material */
420 void glIndexMaterialSGI(GLenum face
, GLenum mode
)
425 void glAddSwapHintRectWin(GLint x
, GLint y
, GLsizei width
, GLsizei height
)