]> git.saurik.com Git - wxWidgets.git/blame - src/msw/glcanvas.cpp
fixed bug with wxTR_EDIT_LABELS not working with xwTR_MULTIPLE (bug 622089)
[wxWidgets.git] / src / msw / glcanvas.cpp
CommitLineData
8b089c5e 1/////////////////////////////////////////////////////////////////////////////
2b8646e0 2// Name: src/msw/glcanvas.cpp
8b089c5e
JS
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
2b8646e0 9// Licence: wxWindows licence
8b089c5e
JS
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
8b089c5e
JS
22#if wxUSE_GLCANVAS
23
24#ifndef WX_PRECOMP
af0b1533
VZ
25 #include "wx/frame.h"
26 #include "wx/settings.h"
27 #include "wx/intl.h"
28 #include "wx/log.h"
8b089c5e
JS
29#endif
30
af0b1533 31#include "wx/msw/private.h"
8b089c5e 32
af0b1533 33#include "wx/glcanvas.h"
8b089c5e 34
b225f659
VZ
35static const wxChar *wxGLCanvasClassName = wxT("wxGLCanvasClass");
36static const wxChar *wxGLCanvasClassNameNoRedraw = wxT("wxGLCanvasClassNR");
8b089c5e
JS
37
38LRESULT WXDLLEXPORT APIENTRY _EXPORT wxWndProc(HWND hWnd, UINT message,
39 WPARAM wParam, LPARAM lParam);
40
41/*
42 * GLContext implementation
43 */
44
45wxGLContext::wxGLContext(bool isRGB, wxGLCanvas *win, const wxPalette& palette)
46{
47 m_window = win;
48
49 m_hDC = win->GetHDC();
50
51 m_glContext = wglCreateContext((HDC) m_hDC);
f6bcfd97 52 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
8b089c5e
JS
53
54 wglMakeCurrent((HDC) m_hDC, m_glContext);
55}
56
57wxGLContext::wxGLContext(
58 bool isRGB, wxGLCanvas *win,
59 const wxPalette& palette,
f48d169c
UN
60 const wxGLContext *other /* for sharing display lists */
61 )
8b089c5e 62{
f48d169c 63 m_window = win;
8b089c5e 64
f48d169c 65 m_hDC = win->GetHDC();
8b089c5e 66
f48d169c
UN
67 m_glContext = wglCreateContext((HDC) m_hDC);
68 wxCHECK_RET( m_glContext, wxT("Couldn't create OpenGl context") );
8b089c5e 69
f48d169c
UN
70 if( other != 0 )
71 wglShareLists( other->m_glContext, m_glContext );
8b089c5e 72
f48d169c 73 wglMakeCurrent((HDC) m_hDC, m_glContext);
8b089c5e
JS
74}
75
76wxGLContext::~wxGLContext()
77{
78 if (m_glContext)
79 {
80 wglMakeCurrent(NULL, NULL);
f48d169c 81 wglDeleteContext(m_glContext);
8b089c5e
JS
82 }
83}
84
85void wxGLContext::SwapBuffers()
86{
87 if (m_glContext)
88 {
89 wglMakeCurrent((HDC) m_hDC, m_glContext);
90 ::SwapBuffers((HDC) m_hDC); //blits the backbuffer into DC
91 }
92}
93
94void wxGLContext::SetCurrent()
95{
96 if (m_glContext)
97 {
98 wglMakeCurrent((HDC) m_hDC, m_glContext);
99 }
100
f48d169c
UN
101 /*
102 setupPixelFormat(hDC);
103 setupPalette(hDC);
104 */
8b089c5e
JS
105}
106
2b5f62a0 107void wxGLContext::SetColour(const wxChar *colour)
8b089c5e
JS
108{
109 float r = 0.0;
110 float g = 0.0;
111 float b = 0.0;
112 wxColour *col = wxTheColourDatabase->FindColour(colour);
113 if (col)
114 {
115 r = (float)(col->Red()/256.0);
116 g = (float)(col->Green()/256.0);
117 b = (float)(col->Blue()/256.0);
118 glColor3f( r, g, b);
119 }
120}
121
122
123/*
124 * wxGLCanvas implementation
125 */
126
4660d7e5 127IMPLEMENT_CLASS(wxGLCanvas, wxWindow)
8b089c5e 128
4660d7e5 129BEGIN_EVENT_TABLE(wxGLCanvas, wxWindow)
8b089c5e
JS
130 EVT_SIZE(wxGLCanvas::OnSize)
131 EVT_PALETTE_CHANGED(wxGLCanvas::OnPaletteChanged)
132 EVT_QUERY_NEW_PALETTE(wxGLCanvas::OnQueryNewPalette)
133END_EVENT_TABLE()
134
135wxGLCanvas::wxGLCanvas(wxWindow *parent, wxWindowID id,
136 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
4660d7e5 137 int *attribList, const wxPalette& palette) : wxWindow()
8b089c5e 138{
f48d169c 139 m_glContext = (wxGLContext*) NULL;
8b089c5e 140
f48d169c 141 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 142
f48d169c
UN
143 if ( ret )
144 {
a756f210
VS
145 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
146 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
f48d169c 147 }
8b089c5e 148
f48d169c 149 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 150
f48d169c
UN
151 SetupPixelFormat(attribList);
152 SetupPalette(palette);
8b089c5e 153
f48d169c 154 m_glContext = new wxGLContext(TRUE, this, palette);
8b089c5e
JS
155}
156
157wxGLCanvas::wxGLCanvas( wxWindow *parent,
158 const wxGLContext *shared, wxWindowID id,
159 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
160 int *attribList, const wxPalette& palette )
4660d7e5 161 : wxWindow()
8b089c5e 162{
f48d169c 163 m_glContext = (wxGLContext*) NULL;
8b089c5e 164
f48d169c 165 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 166
f48d169c
UN
167 if ( ret )
168 {
a756f210
VS
169 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
170 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
f48d169c 171 }
8b089c5e 172
f48d169c 173 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 174
f48d169c
UN
175 SetupPixelFormat(attribList);
176 SetupPalette(palette);
8b089c5e 177
f48d169c 178 m_glContext = new wxGLContext(TRUE, this, palette, shared );
8b089c5e
JS
179}
180
f6bcfd97 181// Not very useful for wxMSW, but this is to be wxGTK compliant
8b089c5e
JS
182
183wxGLCanvas::wxGLCanvas( wxWindow *parent, const wxGLCanvas *shared, wxWindowID id,
184 const wxPoint& pos, const wxSize& size, long style, const wxString& name,
185 int *attribList, const wxPalette& palette ):
4660d7e5 186 wxWindow()
8b089c5e 187{
f48d169c 188 m_glContext = (wxGLContext*) NULL;
8b089c5e 189
f48d169c 190 bool ret = Create(parent, id, pos, size, style, name);
8b089c5e 191
f48d169c
UN
192 if ( ret )
193 {
a756f210
VS
194 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
195 SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT));
f48d169c 196 }
8b089c5e 197
f48d169c 198 m_hDC = (WXHDC) ::GetDC((HWND) GetHWND());
8b089c5e 199
f48d169c
UN
200 SetupPixelFormat(attribList);
201 SetupPalette(palette);
8b089c5e 202
f48d169c
UN
203 wxGLContext *sharedContext=0;
204 if (shared) sharedContext=shared->GetContext();
205 m_glContext = new wxGLContext(TRUE, this, palette, sharedContext );
8b089c5e
JS
206}
207
208wxGLCanvas::~wxGLCanvas()
209{
210 if (m_glContext)
211 delete m_glContext;
212
213 ::ReleaseDC((HWND) GetHWND(), (HDC) m_hDC);
214}
215
b225f659
VZ
216// Replaces wxWindow::Create functionality, since we need to use a different
217// window class
218bool wxGLCanvas::Create(wxWindow *parent,
219 wxWindowID id,
220 const wxPoint& pos,
221 const wxSize& size,
222 long style,
223 const wxString& name)
8b089c5e 224{
b225f659 225 static bool s_registeredGLCanvasClass = FALSE;
8b089c5e 226
f48d169c
UN
227 // We have to register a special window class because we need
228 // the CS_OWNDC style for GLCanvas.
8b089c5e 229
f48d169c
UN
230 /*
231 From Angel Popov <jumpo@bitex.com>
8b089c5e 232
f48d169c
UN
233 Here are two snips from a dicussion in the OpenGL Gamedev list that explains
234 how this problem can be fixed:
8b089c5e 235
f48d169c
UN
236 "There are 5 common DCs available in Win95. These are aquired when you call
237 GetDC or GetDCEx from a window that does _not_ have the OWNDC flag.
238 OWNDC flagged windows do not get their DC from the common DC pool, the issue
239 is they require 800 bytes each from the limited 64Kb local heap for GDI."
8b089c5e 240
f48d169c
UN
241 "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps
242 do), Win95 will actually "steal" it from you. MakeCurrent fails,
243 apparently, because Windows re-assigns the HDC to a different window. The
244 only way to prevent this, the only reliable means, is to set CS_OWNDC."
245 */
8b089c5e 246
b225f659 247 if (!s_registeredGLCanvasClass)
f48d169c
UN
248 {
249 WNDCLASS wndclass;
8b089c5e 250
f48d169c
UN
251 // the fields which are common to all classes
252 wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
253 wndclass.cbClsExtra = 0;
254 wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for?
255 wndclass.hInstance = wxhInstance;
256 wndclass.hIcon = (HICON) NULL;
257 wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
258 wndclass.lpszMenuName = NULL;
8b089c5e 259
f48d169c
UN
260 // Register the GLCanvas class name
261 wndclass.hbrBackground = (HBRUSH)NULL;
262 wndclass.lpszClassName = wxGLCanvasClassName;
b225f659 263 wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
8b089c5e 264
b225f659 265 if ( !::RegisterClass(&wndclass) )
8b089c5e 266 {
f48d169c
UN
267 wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)"));
268 return FALSE;
8b089c5e
JS
269 }
270
b225f659
VZ
271 // Register the GLCanvas class name for windows which don't do full repaint
272 // on resize
273 wndclass.lpszClassName = wxGLCanvasClassNameNoRedraw;
274 wndclass.style &= ~(CS_HREDRAW | CS_VREDRAW);
275
276 if ( !::RegisterClass(&wndclass) )
277 {
278 wxLogLastError(wxT("RegisterClass(wxGLCanvasClassNameNoRedraw)"));
279
a8d20c57 280 ::UnregisterClass(wxGLCanvasClassName, wxhInstance);
b225f659
VZ
281
282 return FALSE;
283 }
284
285 s_registeredGLCanvasClass = TRUE;
f48d169c
UN
286 }
287
288 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
289
290 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
291 return FALSE;
292
293 parent->AddChild(this);
294
295 DWORD msflags = 0;
296 if ( style & wxBORDER )
297 msflags |= WS_BORDER;
298 if ( style & wxTHICK_FRAME )
299 msflags |= WS_THICKFRAME;
300
301 /*
302 A general rule with OpenGL and Win32 is that any window that will have a
303 HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS.
304 You can find references about this within the knowledge base and most OpenGL
305 books that contain the wgl function descriptions.
306 */
8b089c5e 307
b225f659 308 msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
8b089c5e 309
f48d169c
UN
310 bool want3D;
311 WXDWORD exStyle = Determine3DEffects(WS_EX_CLIENTEDGE, &want3D);
8b089c5e 312
f48d169c
UN
313 // Even with extended styles, need to combine with WS_BORDER
314 // for them to look right.
315 if ( want3D || (m_windowStyle & wxSIMPLE_BORDER) || (m_windowStyle & wxRAISED_BORDER ) ||
316 (m_windowStyle & wxSUNKEN_BORDER) || (m_windowStyle & wxDOUBLE_BORDER))
317 {
318 msflags |= WS_BORDER;
319 }
320
b225f659 321 return MSWCreate(wxGLCanvasClassName, NULL, pos, size, msflags, exStyle);
8b089c5e
JS
322}
323
a3081354 324static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList)
8b089c5e 325{
f48d169c
UN
326 if (attribList) {
327 pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
328 pfd.iPixelType = PFD_TYPE_COLORINDEX;
329 pfd.cColorBits = 0;
330 int arg=0;
b225f659 331
f48d169c
UN
332 while( (attribList[arg]!=0) )
333 {
334 switch( attribList[arg++] )
335 {
336 case WX_GL_RGBA:
337 pfd.iPixelType = PFD_TYPE_RGBA;
338 break;
339 case WX_GL_BUFFER_SIZE:
340 pfd.cColorBits = attribList[arg++];
341 break;
342 case WX_GL_LEVEL:
343 // this member looks like it may be obsolete
344 if (attribList[arg] > 0) {
d728116a 345 pfd.iLayerType = (BYTE)PFD_OVERLAY_PLANE;
f48d169c 346 } else if (attribList[arg] < 0) {
d728116a 347 pfd.iLayerType = (BYTE)PFD_UNDERLAY_PLANE;
f48d169c 348 } else {
d728116a 349 pfd.iLayerType = (BYTE)PFD_MAIN_PLANE;
f48d169c
UN
350 }
351 arg++;
352 break;
353 case WX_GL_DOUBLEBUFFER:
354 pfd.dwFlags |= PFD_DOUBLEBUFFER;
355 break;
356 case WX_GL_STEREO:
357 pfd.dwFlags |= PFD_STEREO;
358 break;
359 case WX_GL_AUX_BUFFERS:
360 pfd.cAuxBuffers = attribList[arg++];
361 break;
362 case WX_GL_MIN_RED:
363 pfd.cColorBits += (pfd.cRedBits = attribList[arg++]);
364 break;
365 case WX_GL_MIN_GREEN:
366 pfd.cColorBits += (pfd.cGreenBits = attribList[arg++]);
367 break;
368 case WX_GL_MIN_BLUE:
369 pfd.cColorBits += (pfd.cBlueBits = attribList[arg++]);
370 break;
371 case WX_GL_MIN_ALPHA:
372 // doesn't count in cColorBits
373 pfd.cAlphaBits = attribList[arg++];
374 break;
b225f659 375 case WX_GL_DEPTH_SIZE:
f48d169c
UN
376 pfd.cDepthBits = attribList[arg++];
377 break;
b225f659 378 case WX_GL_STENCIL_SIZE:
f48d169c
UN
379 pfd.cStencilBits = attribList[arg++];
380 break;
381 case WX_GL_MIN_ACCUM_RED:
382 pfd.cAccumBits += (pfd.cAccumRedBits = attribList[arg++]);
383 break;
384 case WX_GL_MIN_ACCUM_GREEN:
385 pfd.cAccumBits += (pfd.cAccumGreenBits = attribList[arg++]);
386 break;
387 case WX_GL_MIN_ACCUM_BLUE:
388 pfd.cAccumBits += (pfd.cAccumBlueBits = attribList[arg++]);
389 break;
390 case WX_GL_MIN_ACCUM_ALPHA:
391 pfd.cAccumBits += (pfd.cAccumAlphaBits = attribList[arg++]);
392 break;
393 default:
394 break;
395 }
8b089c5e 396 }
f48d169c 397 }
a3081354
VZ
398}
399
400void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC)
401{
a3081354 402 PIXELFORMATDESCRIPTOR pfd = {
b225f659
VZ
403 sizeof(PIXELFORMATDESCRIPTOR), /* size */
404 1, /* version */
405 PFD_SUPPORT_OPENGL |
406 PFD_DRAW_TO_WINDOW |
407 PFD_DOUBLEBUFFER, /* support double-buffering */
408 PFD_TYPE_RGBA, /* color type */
409 16, /* prefered color depth */
410 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
411 0, /* no alpha buffer */
412 0, /* alpha bits (ignored) */
413 0, /* no accumulation buffer */
414 0, 0, 0, 0, /* accum bits (ignored) */
415 16, /* depth buffer */
416 0, /* no stencil buffer */
417 0, /* no auxiliary buffers */
418 PFD_MAIN_PLANE, /* main layer */
419 0, /* reserved */
420 0, 0, 0, /* no layer, visible, damage masks */
421 };
a3081354
VZ
422
423 AdjustPFDForAttributes(pfd, attribList);
424
72adfc4b 425 int pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd);
f48d169c 426 if (pixelFormat == 0) {
72adfc4b 427 wxLogLastError(_T("ChoosePixelFormat"));
f48d169c 428 }
a3081354 429 else {
72adfc4b
VZ
430 if ( !::SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) ) {
431 wxLogLastError(_T("SetPixelFormat"));
a3081354 432 }
f48d169c 433 }
8b089c5e
JS
434}
435
436void wxGLCanvas::SetupPalette(const wxPalette& palette)
437{
438 int pixelFormat = GetPixelFormat((HDC) m_hDC);
439 PIXELFORMATDESCRIPTOR pfd;
440
441 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
442
443 if (pfd.dwFlags & PFD_NEED_PALETTE)
444 {
445 }
446 else
447 {
b225f659 448 return;
8b089c5e
JS
449 }
450
451 m_palette = palette;
452
453 if ( !m_palette.Ok() )
454 {
455 m_palette = CreateDefaultPalette();
456 }
457
458 if (m_palette.Ok())
459 {
460 SelectPalette((HDC) m_hDC, (HPALETTE) m_palette.GetHPALETTE(), FALSE);
461 RealizePalette((HDC) m_hDC);
462 }
463}
464
465wxPalette wxGLCanvas::CreateDefaultPalette()
466{
467 PIXELFORMATDESCRIPTOR pfd;
468 int paletteSize;
469 int pixelFormat = GetPixelFormat((HDC) m_hDC);
470
471 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
472
f48d169c 473 paletteSize = 1 << pfd.cColorBits;
8b089c5e
JS
474
475 LOGPALETTE* pPal =
476 (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
477 pPal->palVersion = 0x300;
478 pPal->palNumEntries = paletteSize;
479
480 /* build a simple RGB color palette */
481 {
b225f659
VZ
482 int redMask = (1 << pfd.cRedBits) - 1;
483 int greenMask = (1 << pfd.cGreenBits) - 1;
484 int blueMask = (1 << pfd.cBlueBits) - 1;
485 int i;
486
487 for (i=0; i<paletteSize; ++i) {
488 pPal->palPalEntry[i].peRed =
489 (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
490 pPal->palPalEntry[i].peGreen =
491 (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
492 pPal->palPalEntry[i].peBlue =
493 (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
494 pPal->palPalEntry[i].peFlags = 0;
495 }
8b089c5e
JS
496 }
497
498 HPALETTE hPalette = CreatePalette(pPal);
499 free(pPal);
500
501 wxPalette palette;
502 palette.SetHPALETTE((WXHPALETTE) hPalette);
503
504 return palette;
505}
506
507void wxGLCanvas::SwapBuffers()
508{
509 if (m_glContext)
510 m_glContext->SwapBuffers();
511}
512
513void wxGLCanvas::OnSize(wxSizeEvent& event)
514{
8b089c5e
JS
515}
516
517void wxGLCanvas::SetCurrent()
518{
519 if (m_glContext)
520 {
521 m_glContext->SetCurrent();
522 }
523}
524
2b5f62a0 525void wxGLCanvas::SetColour(const wxChar *colour)
8b089c5e
JS
526{
527 if (m_glContext)
528 m_glContext->SetColour(colour);
529}
530
531// TODO: Have to have this called by parent frame (?)
532// So we need wxFrame to call OnQueryNewPalette for all children...
533void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
534{
f48d169c
UN
535 /* realize palette if this is the current window */
536 if ( GetPalette()->Ok() ) {
537 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
538 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
539 ::RealizePalette((HDC) GetHDC());
540 Refresh();
541 event.SetPaletteRealized(TRUE);
542 }
543 else
544 event.SetPaletteRealized(FALSE);
8b089c5e
JS
545}
546
547// I think this doesn't have to be propagated to child windows.
548void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
549{
f48d169c
UN
550 /* realize palette if this is *not* the current window */
551 if ( GetPalette() &&
8b089c5e 552 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
f48d169c
UN
553 {
554 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
555 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
556 ::RealizePalette((HDC) GetHDC());
557 Refresh();
558 }
8b089c5e
JS
559}
560
561/* Give extensions proper function names. */
562
563/* EXT_vertex_array */
564void glArrayElementEXT(GLint i)
565{
566}
567
568void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
569{
570}
571
572void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count)
573{
574#ifdef GL_EXT_vertex_array
575 static PFNGLDRAWARRAYSEXTPROC proc = 0;
576
577 if ( !proc )
578 {
579 proc = (PFNGLDRAWARRAYSEXTPROC) wglGetProcAddress("glDrawArraysEXT");
580 }
581
582 if ( proc )
583 (* proc) (mode, first, count);
584#endif
585}
586
587void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer)
588{
589}
590
591void glGetPointervEXT(GLenum pname, GLvoid* *params)
592{
593}
594
595void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
596{
597}
598
599void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
600{
601#ifdef GL_EXT_vertex_array
f48d169c 602 static PFNGLNORMALPOINTEREXTPROC proc = 0;
8b089c5e 603
f48d169c
UN
604 if ( !proc )
605 {
606 proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT");
607 }
8b089c5e 608
f48d169c
UN
609 if ( proc )
610 (* proc) (type, stride, count, pointer);
8b089c5e
JS
611#endif
612}
613
614void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
615{
616}
617
618void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
619{
620#ifdef GL_EXT_vertex_array
f48d169c 621 static PFNGLVERTEXPOINTEREXTPROC proc = 0;
8b089c5e 622
f48d169c
UN
623 if ( !proc )
624 {
625 proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT");
626 }
627 if ( proc )
628 (* proc) (size, type, stride, count, pointer);
8b089c5e
JS
629#endif
630}
631
632/* EXT_color_subtable */
633void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table)
634{
635}
636
637/* EXT_color_table */
638void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
639{
640}
641
642void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)
643{
644}
645
646void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table)
647{
648}
649
650void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params)
651{
652}
653
654void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params)
655{
656}
657
658/* SGI_compiled_vertex_array */
659void glLockArraysSGI(GLint first, GLsizei count)
660{
661}
662
663void glUnlockArraysSGI()
664{
665}
666
667
668/* SGI_cull_vertex */
669void glCullParameterdvSGI(GLenum pname, GLdouble* params)
670{
671}
672
673void glCullParameterfvSGI(GLenum pname, GLfloat* params)
674{
675}
676
677/* SGI_index_func */
678void glIndexFuncSGI(GLenum func, GLclampf ref)
679{
680}
681
682/* SGI_index_material */
683void glIndexMaterialSGI(GLenum face, GLenum mode)
684{
685}
686
687/* WIN_swap_hint */
688void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height)
689{
690}
691
a3081354
VZ
692
693//---------------------------------------------------------------------------
694// wxGLApp
695//---------------------------------------------------------------------------
696
697IMPLEMENT_CLASS(wxGLApp, wxApp)
698
699bool wxGLApp::InitGLVisual(int *attribList)
700{
701 int pixelFormat;
702 PIXELFORMATDESCRIPTOR pfd = {
b225f659
VZ
703 sizeof(PIXELFORMATDESCRIPTOR), /* size */
704 1, /* version */
705 PFD_SUPPORT_OPENGL |
706 PFD_DRAW_TO_WINDOW |
707 PFD_DOUBLEBUFFER, /* support double-buffering */
708 PFD_TYPE_RGBA, /* color type */
709 16, /* prefered color depth */
710 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
711 0, /* no alpha buffer */
712 0, /* alpha bits (ignored) */
713 0, /* no accumulation buffer */
714 0, 0, 0, 0, /* accum bits (ignored) */
715 16, /* depth buffer */
716 0, /* no stencil buffer */
717 0, /* no auxiliary buffers */
718 PFD_MAIN_PLANE, /* main layer */
719 0, /* reserved */
720 0, 0, 0, /* no layer, visible, damage masks */
721 };
a3081354
VZ
722
723 AdjustPFDForAttributes(pfd, attribList);
724
725 // use DC for whole (root) screen, since no windows have yet been created
2b8646e0 726 pixelFormat = ChoosePixelFormat(ScreenHDC(), &pfd);
a3081354
VZ
727
728 if (pixelFormat == 0) {
729 wxLogError(_("Failed to initialize OpenGL"));
730 return FALSE;
731 }
732
733 return TRUE;
734}
735
736wxGLApp::~wxGLApp()
737{
738}
739
8b089c5e
JS
740#endif
741 // wxUSE_GLCANVAS