]> git.saurik.com Git - wxWidgets.git/blob - utils/glcanvas/win/glcanvas.cpp
Added wxGenericValidator & doc
[wxWidgets.git] / utils / glcanvas / win / glcanvas.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: glcanvas.cpp
3 // Purpose: wxGLCanvas, for using OpenGL with wxWindows under MS Windows
4 // Author: Julian Smart
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "glcanvas.h"
14 #endif
15
16 #include "wx/wxprec.h"
17
18 #if defined(__BORLANDC__)
19 #pragma hdrstop
20 #endif
21
22 #ifndef WX_PRECOMP
23 #include <wx/frame.h>
24 #endif
25
26 #include "glcanvas.h"
27
28 /*
29 * GLContext implementation
30 */
31
32 wxGLContext::wxGLContext(bool isRGB, wxWindow *win, const wxPalette& palette)
33 {
34 m_window = win;
35
36 m_hDC = (WXHDC) ::GetDC((HWND) win->GetHWND());
37
38 SetupPixelFormat();
39 SetupPalette(palette);
40
41 m_glContext = wglCreateContext((HDC) m_hDC);
42 wglMakeCurrent((HDC) m_hDC, m_glContext);
43 }
44
45 wxGLContext::~wxGLContext()
46 {
47 if (m_glContext)
48 {
49 wglMakeCurrent(NULL, NULL);
50 wglDeleteContext(m_glContext);
51 }
52
53 ::ReleaseDC((HWND) m_window->GetHWND(), (HDC) m_hDC);
54 }
55
56 void wxGLContext::SwapBuffers()
57 {
58 if (m_glContext)
59 {
60 wglMakeCurrent((HDC) m_hDC, m_glContext);
61 ::SwapBuffers((HDC) m_hDC); //blits the backbuffer into DC
62 }
63 }
64
65 void wxGLContext::SetCurrent()
66 {
67 if (m_glContext)
68 {
69 wglMakeCurrent((HDC) m_hDC, m_glContext);
70 }
71
72 /*
73 setupPixelFormat(hDC);
74 setupPalette(hDC);
75 */
76 }
77
78 void wxGLContext::SetColour(const char *colour)
79 {
80 float r = 0.0;
81 float g = 0.0;
82 float b = 0.0;
83 wxColour *col = wxTheColourDatabase->FindColour(colour);
84 if (col)
85 {
86 r = (float)(col->Red()/256.0);
87 g = (float)(col->Green()/256.0);
88 b = (float)(col->Blue()/256.0);
89 glColor3f( r, g, b);
90 }
91 }
92
93 void wxGLContext::SetupPixelFormat() // (HDC hDC)
94 {
95 PIXELFORMATDESCRIPTOR pfd = {
96 sizeof(PIXELFORMATDESCRIPTOR), /* size */
97 1, /* version */
98 PFD_SUPPORT_OPENGL |
99 PFD_DRAW_TO_WINDOW |
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 */
112 0, /* reserved */
113 0, 0, 0, /* no layer, visible, damage masks */
114 };
115 int pixelFormat;
116
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);
121 exit(1);
122 }
123
124 if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) {
125 MessageBox(WindowFromDC((HDC) m_hDC), "SetPixelFormat failed.", "Error",
126 MB_ICONERROR | MB_OK);
127 exit(1);
128 }
129 }
130
131 void wxGLContext::SetupPalette(const wxPalette& palette)
132 {
133 int pixelFormat = GetPixelFormat((HDC) m_hDC);
134 PIXELFORMATDESCRIPTOR pfd;
135
136 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
137
138 if (pfd.dwFlags & PFD_NEED_PALETTE)
139 {
140 }
141 else
142 {
143 return;
144 }
145
146 m_palette = palette;
147
148 if ( !m_palette.Ok() )
149 {
150 m_palette = CreateDefaultPalette();
151 }
152
153 if (m_palette.Ok())
154 {
155 SelectPalette((HDC) m_hDC, (HPALETTE) m_palette.GetHPALETTE(), FALSE);
156 RealizePalette((HDC) m_hDC);
157 }
158 }
159
160 wxPalette wxGLContext::CreateDefaultPalette()
161 {
162 PIXELFORMATDESCRIPTOR pfd;
163 int paletteSize;
164 int pixelFormat = GetPixelFormat((HDC) m_hDC);
165
166 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
167
168 paletteSize = 1 << pfd.cColorBits;
169
170 LOGPALETTE* pPal =
171 (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
172 pPal->palVersion = 0x300;
173 pPal->palNumEntries = paletteSize;
174
175 /* build a simple RGB color palette */
176 {
177 int redMask = (1 << pfd.cRedBits) - 1;
178 int greenMask = (1 << pfd.cGreenBits) - 1;
179 int blueMask = (1 << pfd.cBlueBits) - 1;
180 int i;
181
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;
190 }
191 }
192
193 HPALETTE hPalette = CreatePalette(pPal);
194 free(pPal);
195
196 wxPalette palette;
197 palette.SetHPALETTE((WXHPALETTE) hPalette);
198
199 return palette;
200 }
201
202 /*
203 * wxGLCanvas implementation
204 */
205
206 IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow)
207
208 BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow)
209 EVT_SIZE(wxGLCanvas::OnSize)
210 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged)
211 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette)
212 END_EVENT_TABLE()
213
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)
218 {
219 m_glContext = new wxGLContext(TRUE, this, palette);
220 }
221
222 wxGLCanvas::~wxGLCanvas()
223 {
224 if (m_glContext)
225 delete m_glContext;
226 }
227
228 void wxGLCanvas::SwapBuffers()
229 {
230 if (m_glContext)
231 m_glContext->SwapBuffers();
232 }
233
234 void wxGLCanvas::OnSize(wxSizeEvent& event)
235 {
236 int width, height;
237 GetClientSize(& width, & height);
238
239 if (m_glContext)
240 {
241 m_glContext->SetCurrent();
242
243 glViewport(0, 0, (GLint)width, (GLint)height);
244 glMatrixMode(GL_PROJECTION);
245 glLoadIdentity();
246 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
247 glMatrixMode(GL_MODELVIEW);
248 }
249 }
250
251 void wxGLCanvas::SetCurrent()
252 {
253 if (m_glContext)
254 {
255 m_glContext->SetCurrent();
256 }
257 }
258
259 void wxGLCanvas::SetColour(const char *colour)
260 {
261 if (m_glContext)
262 m_glContext->SetColour(colour);
263 }
264
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)
268 {
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());
274 Refresh();
275 event.SetPaletteRealized(TRUE);
276 }
277 else
278 event.SetPaletteRealized(FALSE);
279 }
280
281 // I think this doesn't have to be propagated to child windows.
282 void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
283 {
284 /* realize palette if this is *not* the current window */
285 if ( m_glContext &&
286 m_glContext->GetPalette() &&
287 m_glContext->GetPalette()->Ok() &&
288 (this != event.GetChangedWindow()) )
289 {
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());
293 Refresh();
294 }
295 }
296
297 /* Give extensions proper function names. */
298
299 /* EXT_vertex_array */
300 void glArrayElementEXT(GLint i)
301 {
302 }
303
304 void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
305 {
306 }
307
308 void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count)
309 {
310 #ifdef GL_EXT_vertex_array
311 static PFNGLDRAWARRAYSEXTPROC proc = 0;
312
313 if ( !proc )
314 {
315 proc = (PFNGLDRAWARRAYSEXTPROC) wglGetProcAddress("glDrawArraysEXT");
316 }
317
318 if ( proc )
319 (* proc) (mode, first, count);
320 #endif
321 }
322
323 void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer)
324 {
325 }
326
327 void glGetPointervEXT(GLenum pname, GLvoid* *params)
328 {
329 }
330
331 void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
332 {
333 }
334
335 void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
336 {
337 #ifdef GL_EXT_vertex_array
338 static PFNGLNORMALPOINTEREXTPROC proc = 0;
339
340 if ( !proc )
341 {
342 proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT");
343 }
344
345 if ( proc )
346 (* proc) (type, stride, count, pointer);
347 #endif
348 }
349
350 void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
351 {
352 }
353
354 void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
355 {
356 #ifdef GL_EXT_vertex_array
357 static PFNGLVERTEXPOINTEREXTPROC proc = 0;
358
359 if ( !proc )
360 {
361 proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT");
362 }
363
364 if ( proc )
365 (* proc) (size, type, stride, count, pointer);
366 #endif
367 }
368
369 /* EXT_color_subtable */
370 void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table)
371 {
372 }
373
374 /* EXT_color_table */
375 void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
376 {
377 }
378
379 void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)
380 {
381 }
382
383 void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table)
384 {
385 }
386
387 void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params)
388 {
389 }
390
391 void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params)
392 {
393 }
394
395 /* SGI_compiled_vertex_array */
396 void glLockArraysSGI(GLint first, GLsizei count)
397 {
398 }
399
400 void glUnlockArraysSGI()
401 {
402 }
403
404
405 /* SGI_cull_vertex */
406 void glCullParameterdvSGI(GLenum pname, GLdouble* params)
407 {
408 }
409
410 void glCullParameterfvSGI(GLenum pname, GLfloat* params)
411 {
412 }
413
414 /* SGI_index_func */
415 void glIndexFuncSGI(GLenum func, GLclampf ref)
416 {
417 }
418
419 /* SGI_index_material */
420 void glIndexMaterialSGI(GLenum face, GLenum mode)
421 {
422 }
423
424 /* WIN_swap_hint */
425 void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height)
426 {
427 }
428