]> git.saurik.com Git - wxWidgets.git/blame - src/msw/glcanvas.cpp
fixed spurious assert failure in wxMenuBar::Insert
[wxWidgets.git] / src / msw / glcanvas.cpp
CommitLineData
8b089c5e
JS
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#include <wx/setup.h>
23
24#if wxUSE_GLCANVAS
25
26#ifndef WX_PRECOMP
27#include <wx/frame.h>
28#endif
29
30#include <wx/msw/private.h>
7e42f2f8
UN
31#include <wx/settings.h>
32#include <wx/log.h>
8b089c5e
JS
33
34#include <wx/glcanvas.h>
35
36wxChar wxGLCanvasClassName[] = wxT("wxGLCanvasClass");
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
107void wxGLContext::SetColour(const char *colour)
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
127IMPLEMENT_CLASS(wxGLCanvas, wxScrolledWindow)
128
129BEGIN_EVENT_TABLE(wxGLCanvas, wxScrolledWindow)
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,
f48d169c 137 int *attribList, const wxPalette& palette) : wxScrolledWindow()
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 {
145 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
146 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
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 )
161 : wxScrolledWindow()
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 {
169 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
170 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
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 ):
186 wxScrolledWindow()
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 {
194 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));
195 SetFont(wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT));
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
216// Replaces wxWindow::Create functionality, since we need to use a different window class
217bool wxGLCanvas::Create(wxWindow *parent, wxWindowID id,
218 const wxPoint& pos, const wxSize& size, long style, const wxString& name)
219{
f48d169c
UN
220 /*
221 Suggestion from Kelly Brock <kbrock@8cs.com> (not yet implemented):
f6bcfd97 222
f48d169c
UN
223 OpenGL corruption fix is simple assuming it doesn't screw anything else
224 up. Add the following line to the top of the create function:
225
226 wxSize parentSize = GetClientSize();
f6bcfd97 227
f48d169c
UN
228 All locations within the function that use 'size' are changed to
229 'parentSize'.
230 The above corrects the initial display corruption with the GeForce and
231 TNT2, not sure about other NVidia cards yet.
232 */
8b089c5e 233
f48d169c 234 static bool registeredGLCanvasClass = FALSE;
8b089c5e 235
f48d169c
UN
236 // We have to register a special window class because we need
237 // the CS_OWNDC style for GLCanvas.
8b089c5e 238
f48d169c
UN
239 /*
240 From Angel Popov <jumpo@bitex.com>
8b089c5e 241
f48d169c
UN
242 Here are two snips from a dicussion in the OpenGL Gamedev list that explains
243 how this problem can be fixed:
8b089c5e 244
f48d169c
UN
245 "There are 5 common DCs available in Win95. These are aquired when you call
246 GetDC or GetDCEx from a window that does _not_ have the OWNDC flag.
247 OWNDC flagged windows do not get their DC from the common DC pool, the issue
248 is they require 800 bytes each from the limited 64Kb local heap for GDI."
8b089c5e 249
f48d169c
UN
250 "The deal is, if you hold onto one of the 5 shared DC's too long (as GL apps
251 do), Win95 will actually "steal" it from you. MakeCurrent fails,
252 apparently, because Windows re-assigns the HDC to a different window. The
253 only way to prevent this, the only reliable means, is to set CS_OWNDC."
254 */
8b089c5e 255
f48d169c
UN
256 if (!registeredGLCanvasClass)
257 {
258 WNDCLASS wndclass;
8b089c5e 259
f48d169c 260 static const long styleNormal = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
8b089c5e 261
f48d169c
UN
262 // the fields which are common to all classes
263 wndclass.lpfnWndProc = (WNDPROC)wxWndProc;
264 wndclass.cbClsExtra = 0;
265 wndclass.cbWndExtra = sizeof( DWORD ); // VZ: what is this DWORD used for?
266 wndclass.hInstance = wxhInstance;
267 wndclass.hIcon = (HICON) NULL;
268 wndclass.hCursor = ::LoadCursor((HINSTANCE)NULL, IDC_ARROW);
269 wndclass.lpszMenuName = NULL;
8b089c5e 270
f48d169c
UN
271 // Register the GLCanvas class name
272 wndclass.hbrBackground = (HBRUSH)NULL;
273 wndclass.lpszClassName = wxGLCanvasClassName;
274 wndclass.style = styleNormal;
8b089c5e 275
f48d169c 276 if ( !RegisterClass(&wndclass) )
8b089c5e 277 {
f48d169c
UN
278 wxLogLastError(wxT("RegisterClass(wxGLCanvasClass)"));
279 return FALSE;
8b089c5e
JS
280 }
281
f48d169c
UN
282 registeredGLCanvasClass = TRUE;
283 }
284
285 wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
286
287 if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
288 return FALSE;
289
290 parent->AddChild(this);
291
292 DWORD msflags = 0;
293 if ( style & wxBORDER )
294 msflags |= WS_BORDER;
295 if ( style & wxTHICK_FRAME )
296 msflags |= WS_THICKFRAME;
297
298 /*
299 A general rule with OpenGL and Win32 is that any window that will have a
300 HGLRC built for it must have two flags: WS_CLIPCHILDREN & WS_CLIPSIBLINGS.
301 You can find references about this within the knowledge base and most OpenGL
302 books that contain the wgl function descriptions.
303 */
8b089c5e 304
f48d169c
UN
305 msflags |= WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS;
306 // if ( style & wxCLIP_CHILDREN )
307 // msflags |= WS_CLIPCHILDREN;
308 msflags |= 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
321 // calculate the value to return from WM_GETDLGCODE handler
322 if ( GetWindowStyleFlag() & wxWANTS_CHARS )
323 {
324 // want everything: i.e. all keys and WM_CHAR message
325 m_lDlgCode = DLGC_WANTARROWS | DLGC_WANTCHARS |
326 DLGC_WANTTAB | DLGC_WANTMESSAGE;
327 }
328
329 MSWCreate(m_windowId, parent, wxGLCanvasClassName, this, NULL,
330 pos.x, pos.y,
331 WidthDefault(size.x), HeightDefault(size.y),
332 msflags, NULL, exStyle);
333
334 return TRUE;
8b089c5e
JS
335}
336
a3081354 337static void AdjustPFDForAttributes(PIXELFORMATDESCRIPTOR& pfd, int *attribList)
8b089c5e 338{
f48d169c
UN
339 if (attribList) {
340 pfd.dwFlags &= ~PFD_DOUBLEBUFFER;
341 pfd.iPixelType = PFD_TYPE_COLORINDEX;
342 pfd.cColorBits = 0;
343 int arg=0;
344
345 while( (attribList[arg]!=0) )
346 {
347 switch( attribList[arg++] )
348 {
349 case WX_GL_RGBA:
350 pfd.iPixelType = PFD_TYPE_RGBA;
351 break;
352 case WX_GL_BUFFER_SIZE:
353 pfd.cColorBits = attribList[arg++];
354 break;
355 case WX_GL_LEVEL:
356 // this member looks like it may be obsolete
357 if (attribList[arg] > 0) {
358 pfd.iLayerType = PFD_OVERLAY_PLANE;
359 } else if (attribList[arg] < 0) {
360 pfd.iLayerType = PFD_UNDERLAY_PLANE;
361 } else {
362 pfd.iLayerType = PFD_MAIN_PLANE;
363 }
364 arg++;
365 break;
366 case WX_GL_DOUBLEBUFFER:
367 pfd.dwFlags |= PFD_DOUBLEBUFFER;
368 break;
369 case WX_GL_STEREO:
370 pfd.dwFlags |= PFD_STEREO;
371 break;
372 case WX_GL_AUX_BUFFERS:
373 pfd.cAuxBuffers = attribList[arg++];
374 break;
375 case WX_GL_MIN_RED:
376 pfd.cColorBits += (pfd.cRedBits = attribList[arg++]);
377 break;
378 case WX_GL_MIN_GREEN:
379 pfd.cColorBits += (pfd.cGreenBits = attribList[arg++]);
380 break;
381 case WX_GL_MIN_BLUE:
382 pfd.cColorBits += (pfd.cBlueBits = attribList[arg++]);
383 break;
384 case WX_GL_MIN_ALPHA:
385 // doesn't count in cColorBits
386 pfd.cAlphaBits = attribList[arg++];
387 break;
388 case WX_GL_DEPTH_SIZE:
389 pfd.cDepthBits = attribList[arg++];
390 break;
391 case WX_GL_STENCIL_SIZE:
392 pfd.cStencilBits = attribList[arg++];
393 break;
394 case WX_GL_MIN_ACCUM_RED:
395 pfd.cAccumBits += (pfd.cAccumRedBits = attribList[arg++]);
396 break;
397 case WX_GL_MIN_ACCUM_GREEN:
398 pfd.cAccumBits += (pfd.cAccumGreenBits = attribList[arg++]);
399 break;
400 case WX_GL_MIN_ACCUM_BLUE:
401 pfd.cAccumBits += (pfd.cAccumBlueBits = attribList[arg++]);
402 break;
403 case WX_GL_MIN_ACCUM_ALPHA:
404 pfd.cAccumBits += (pfd.cAccumAlphaBits = attribList[arg++]);
405 break;
406 default:
407 break;
408 }
8b089c5e 409 }
f48d169c 410 }
a3081354
VZ
411}
412
413void wxGLCanvas::SetupPixelFormat(int *attribList) // (HDC hDC)
414{
415 int pixelFormat;
416 PIXELFORMATDESCRIPTOR pfd = {
417 sizeof(PIXELFORMATDESCRIPTOR), /* size */
418 1, /* version */
419 PFD_SUPPORT_OPENGL |
420 PFD_DRAW_TO_WINDOW |
421 PFD_DOUBLEBUFFER, /* support double-buffering */
422 PFD_TYPE_RGBA, /* color type */
423 16, /* prefered color depth */
424 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
425 0, /* no alpha buffer */
426 0, /* alpha bits (ignored) */
427 0, /* no accumulation buffer */
428 0, 0, 0, 0, /* accum bits (ignored) */
429 16, /* depth buffer */
430 0, /* no stencil buffer */
431 0, /* no auxiliary buffers */
432 PFD_MAIN_PLANE, /* main layer */
433 0, /* reserved */
434 0, 0, 0, /* no layer, visible, damage masks */
435 };
436
437 AdjustPFDForAttributes(pfd, attribList);
438
f48d169c
UN
439 pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd);
440 if (pixelFormat == 0) {
a3081354 441 wxLogWarning(_("ChoosePixelFormat failed."));
f48d169c 442 }
a3081354
VZ
443 else {
444 if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) {
445 wxLogWarning(_("SetPixelFormat failed."));
446 }
f48d169c 447 }
8b089c5e
JS
448}
449
450void wxGLCanvas::SetupPalette(const wxPalette& palette)
451{
452 int pixelFormat = GetPixelFormat((HDC) m_hDC);
453 PIXELFORMATDESCRIPTOR pfd;
454
455 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
456
457 if (pfd.dwFlags & PFD_NEED_PALETTE)
458 {
459 }
460 else
461 {
462 return;
463 }
464
465 m_palette = palette;
466
467 if ( !m_palette.Ok() )
468 {
469 m_palette = CreateDefaultPalette();
470 }
471
472 if (m_palette.Ok())
473 {
474 SelectPalette((HDC) m_hDC, (HPALETTE) m_palette.GetHPALETTE(), FALSE);
475 RealizePalette((HDC) m_hDC);
476 }
477}
478
479wxPalette wxGLCanvas::CreateDefaultPalette()
480{
481 PIXELFORMATDESCRIPTOR pfd;
482 int paletteSize;
483 int pixelFormat = GetPixelFormat((HDC) m_hDC);
484
485 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
486
f48d169c 487 paletteSize = 1 << pfd.cColorBits;
8b089c5e
JS
488
489 LOGPALETTE* pPal =
490 (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
491 pPal->palVersion = 0x300;
492 pPal->palNumEntries = paletteSize;
493
494 /* build a simple RGB color palette */
495 {
496 int redMask = (1 << pfd.cRedBits) - 1;
497 int greenMask = (1 << pfd.cGreenBits) - 1;
498 int blueMask = (1 << pfd.cBlueBits) - 1;
499 int i;
500
501 for (i=0; i<paletteSize; ++i) {
502 pPal->palPalEntry[i].peRed =
503 (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
504 pPal->palPalEntry[i].peGreen =
505 (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
506 pPal->palPalEntry[i].peBlue =
507 (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
508 pPal->palPalEntry[i].peFlags = 0;
509 }
510 }
511
512 HPALETTE hPalette = CreatePalette(pPal);
513 free(pPal);
514
515 wxPalette palette;
516 palette.SetHPALETTE((WXHPALETTE) hPalette);
517
518 return palette;
519}
520
521void wxGLCanvas::SwapBuffers()
522{
523 if (m_glContext)
524 m_glContext->SwapBuffers();
525}
526
527void wxGLCanvas::OnSize(wxSizeEvent& event)
528{
529 int width, height;
530 GetClientSize(& width, & height);
531
532 if (m_glContext)
533 {
534 m_glContext->SetCurrent();
535
536 glViewport(0, 0, (GLint)width, (GLint)height);
537 glMatrixMode(GL_PROJECTION);
538 glLoadIdentity();
539 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 15.0 );
540 glMatrixMode(GL_MODELVIEW);
541 }
542}
543
544void wxGLCanvas::SetCurrent()
545{
546 if (m_glContext)
547 {
548 m_glContext->SetCurrent();
549 }
550}
551
552void wxGLCanvas::SetColour(const char *colour)
553{
554 if (m_glContext)
555 m_glContext->SetColour(colour);
556}
557
558// TODO: Have to have this called by parent frame (?)
559// So we need wxFrame to call OnQueryNewPalette for all children...
560void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
561{
f48d169c
UN
562 /* realize palette if this is the current window */
563 if ( GetPalette()->Ok() ) {
564 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
565 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
566 ::RealizePalette((HDC) GetHDC());
567 Refresh();
568 event.SetPaletteRealized(TRUE);
569 }
570 else
571 event.SetPaletteRealized(FALSE);
8b089c5e
JS
572}
573
574// I think this doesn't have to be propagated to child windows.
575void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
576{
f48d169c
UN
577 /* realize palette if this is *not* the current window */
578 if ( GetPalette() &&
8b089c5e 579 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
f48d169c
UN
580 {
581 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
582 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
583 ::RealizePalette((HDC) GetHDC());
584 Refresh();
585 }
8b089c5e
JS
586}
587
588/* Give extensions proper function names. */
589
590/* EXT_vertex_array */
591void glArrayElementEXT(GLint i)
592{
593}
594
595void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
596{
597}
598
599void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count)
600{
601#ifdef GL_EXT_vertex_array
602 static PFNGLDRAWARRAYSEXTPROC proc = 0;
603
604 if ( !proc )
605 {
606 proc = (PFNGLDRAWARRAYSEXTPROC) wglGetProcAddress("glDrawArraysEXT");
607 }
608
609 if ( proc )
610 (* proc) (mode, first, count);
611#endif
612}
613
614void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer)
615{
616}
617
618void glGetPointervEXT(GLenum pname, GLvoid* *params)
619{
620}
621
622void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
623{
624}
625
626void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
627{
628#ifdef GL_EXT_vertex_array
f48d169c 629 static PFNGLNORMALPOINTEREXTPROC proc = 0;
8b089c5e 630
f48d169c
UN
631 if ( !proc )
632 {
633 proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT");
634 }
8b089c5e 635
f48d169c
UN
636 if ( proc )
637 (* proc) (type, stride, count, pointer);
8b089c5e
JS
638#endif
639}
640
641void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
642{
643}
644
645void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
646{
647#ifdef GL_EXT_vertex_array
f48d169c 648 static PFNGLVERTEXPOINTEREXTPROC proc = 0;
8b089c5e 649
f48d169c
UN
650 if ( !proc )
651 {
652 proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT");
653 }
654 if ( proc )
655 (* proc) (size, type, stride, count, pointer);
8b089c5e
JS
656#endif
657}
658
659/* EXT_color_subtable */
660void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table)
661{
662}
663
664/* EXT_color_table */
665void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
666{
667}
668
669void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)
670{
671}
672
673void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table)
674{
675}
676
677void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params)
678{
679}
680
681void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params)
682{
683}
684
685/* SGI_compiled_vertex_array */
686void glLockArraysSGI(GLint first, GLsizei count)
687{
688}
689
690void glUnlockArraysSGI()
691{
692}
693
694
695/* SGI_cull_vertex */
696void glCullParameterdvSGI(GLenum pname, GLdouble* params)
697{
698}
699
700void glCullParameterfvSGI(GLenum pname, GLfloat* params)
701{
702}
703
704/* SGI_index_func */
705void glIndexFuncSGI(GLenum func, GLclampf ref)
706{
707}
708
709/* SGI_index_material */
710void glIndexMaterialSGI(GLenum face, GLenum mode)
711{
712}
713
714/* WIN_swap_hint */
715void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height)
716{
717}
718
a3081354
VZ
719
720//---------------------------------------------------------------------------
721// wxGLApp
722//---------------------------------------------------------------------------
723
724IMPLEMENT_CLASS(wxGLApp, wxApp)
725
726bool wxGLApp::InitGLVisual(int *attribList)
727{
728 int pixelFormat;
729 PIXELFORMATDESCRIPTOR pfd = {
730 sizeof(PIXELFORMATDESCRIPTOR), /* size */
731 1, /* version */
732 PFD_SUPPORT_OPENGL |
733 PFD_DRAW_TO_WINDOW |
734 PFD_DOUBLEBUFFER, /* support double-buffering */
735 PFD_TYPE_RGBA, /* color type */
736 16, /* prefered color depth */
737 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
738 0, /* no alpha buffer */
739 0, /* alpha bits (ignored) */
740 0, /* no accumulation buffer */
741 0, 0, 0, 0, /* accum bits (ignored) */
742 16, /* depth buffer */
743 0, /* no stencil buffer */
744 0, /* no auxiliary buffers */
745 PFD_MAIN_PLANE, /* main layer */
746 0, /* reserved */
747 0, 0, 0, /* no layer, visible, damage masks */
748 };
749
750 AdjustPFDForAttributes(pfd, attribList);
751
752 // use DC for whole (root) screen, since no windows have yet been created
753 pixelFormat = ChoosePixelFormat((HDC) ::GetDC(NULL), &pfd);
754
755 if (pixelFormat == 0) {
756 wxLogError(_("Failed to initialize OpenGL"));
757 return FALSE;
758 }
759
760 return TRUE;
761}
762
763wxGLApp::~wxGLApp()
764{
765}
766
8b089c5e
JS
767#endif
768 // wxUSE_GLCANVAS