]> git.saurik.com Git - wxWidgets.git/blame - src/msw/glcanvas.cpp
make file for wxUniversal and Borland/MSW
[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
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
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{
402 int pixelFormat;
403 PIXELFORMATDESCRIPTOR pfd = {
b225f659
VZ
404 sizeof(PIXELFORMATDESCRIPTOR), /* size */
405 1, /* version */
406 PFD_SUPPORT_OPENGL |
407 PFD_DRAW_TO_WINDOW |
408 PFD_DOUBLEBUFFER, /* support double-buffering */
409 PFD_TYPE_RGBA, /* color type */
410 16, /* prefered color depth */
411 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
412 0, /* no alpha buffer */
413 0, /* alpha bits (ignored) */
414 0, /* no accumulation buffer */
415 0, 0, 0, 0, /* accum bits (ignored) */
416 16, /* depth buffer */
417 0, /* no stencil buffer */
418 0, /* no auxiliary buffers */
419 PFD_MAIN_PLANE, /* main layer */
420 0, /* reserved */
421 0, 0, 0, /* no layer, visible, damage masks */
422 };
a3081354
VZ
423
424 AdjustPFDForAttributes(pfd, attribList);
425
f48d169c
UN
426 pixelFormat = ChoosePixelFormat((HDC) m_hDC, &pfd);
427 if (pixelFormat == 0) {
a3081354 428 wxLogWarning(_("ChoosePixelFormat failed."));
f48d169c 429 }
a3081354
VZ
430 else {
431 if (SetPixelFormat((HDC) m_hDC, pixelFormat, &pfd) != TRUE) {
432 wxLogWarning(_("SetPixelFormat failed."));
433 }
f48d169c 434 }
8b089c5e
JS
435}
436
437void wxGLCanvas::SetupPalette(const wxPalette& palette)
438{
439 int pixelFormat = GetPixelFormat((HDC) m_hDC);
440 PIXELFORMATDESCRIPTOR pfd;
441
442 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
443
444 if (pfd.dwFlags & PFD_NEED_PALETTE)
445 {
446 }
447 else
448 {
b225f659 449 return;
8b089c5e
JS
450 }
451
452 m_palette = palette;
453
454 if ( !m_palette.Ok() )
455 {
456 m_palette = CreateDefaultPalette();
457 }
458
459 if (m_palette.Ok())
460 {
461 SelectPalette((HDC) m_hDC, (HPALETTE) m_palette.GetHPALETTE(), FALSE);
462 RealizePalette((HDC) m_hDC);
463 }
464}
465
466wxPalette wxGLCanvas::CreateDefaultPalette()
467{
468 PIXELFORMATDESCRIPTOR pfd;
469 int paletteSize;
470 int pixelFormat = GetPixelFormat((HDC) m_hDC);
471
472 DescribePixelFormat((HDC) m_hDC, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
473
f48d169c 474 paletteSize = 1 << pfd.cColorBits;
8b089c5e
JS
475
476 LOGPALETTE* pPal =
477 (LOGPALETTE*) malloc(sizeof(LOGPALETTE) + paletteSize * sizeof(PALETTEENTRY));
478 pPal->palVersion = 0x300;
479 pPal->palNumEntries = paletteSize;
480
481 /* build a simple RGB color palette */
482 {
b225f659
VZ
483 int redMask = (1 << pfd.cRedBits) - 1;
484 int greenMask = (1 << pfd.cGreenBits) - 1;
485 int blueMask = (1 << pfd.cBlueBits) - 1;
486 int i;
487
488 for (i=0; i<paletteSize; ++i) {
489 pPal->palPalEntry[i].peRed =
490 (((i >> pfd.cRedShift) & redMask) * 255) / redMask;
491 pPal->palPalEntry[i].peGreen =
492 (((i >> pfd.cGreenShift) & greenMask) * 255) / greenMask;
493 pPal->palPalEntry[i].peBlue =
494 (((i >> pfd.cBlueShift) & blueMask) * 255) / blueMask;
495 pPal->palPalEntry[i].peFlags = 0;
496 }
8b089c5e
JS
497 }
498
499 HPALETTE hPalette = CreatePalette(pPal);
500 free(pPal);
501
502 wxPalette palette;
503 palette.SetHPALETTE((WXHPALETTE) hPalette);
504
505 return palette;
506}
507
508void wxGLCanvas::SwapBuffers()
509{
510 if (m_glContext)
511 m_glContext->SwapBuffers();
512}
513
514void wxGLCanvas::OnSize(wxSizeEvent& event)
515{
8b089c5e
JS
516}
517
518void wxGLCanvas::SetCurrent()
519{
520 if (m_glContext)
521 {
522 m_glContext->SetCurrent();
523 }
524}
525
526void wxGLCanvas::SetColour(const char *colour)
527{
528 if (m_glContext)
529 m_glContext->SetColour(colour);
530}
531
532// TODO: Have to have this called by parent frame (?)
533// So we need wxFrame to call OnQueryNewPalette for all children...
534void wxGLCanvas::OnQueryNewPalette(wxQueryNewPaletteEvent& event)
535{
f48d169c
UN
536 /* realize palette if this is the current window */
537 if ( GetPalette()->Ok() ) {
538 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
539 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
540 ::RealizePalette((HDC) GetHDC());
541 Refresh();
542 event.SetPaletteRealized(TRUE);
543 }
544 else
545 event.SetPaletteRealized(FALSE);
8b089c5e
JS
546}
547
548// I think this doesn't have to be propagated to child windows.
549void wxGLCanvas::OnPaletteChanged(wxPaletteChangedEvent& event)
550{
f48d169c
UN
551 /* realize palette if this is *not* the current window */
552 if ( GetPalette() &&
8b089c5e 553 GetPalette()->Ok() && (this != event.GetChangedWindow()) )
f48d169c
UN
554 {
555 ::UnrealizeObject((HPALETTE) GetPalette()->GetHPALETTE());
556 ::SelectPalette((HDC) GetHDC(), (HPALETTE) GetPalette()->GetHPALETTE(), FALSE);
557 ::RealizePalette((HDC) GetHDC());
558 Refresh();
559 }
8b089c5e
JS
560}
561
562/* Give extensions proper function names. */
563
564/* EXT_vertex_array */
565void glArrayElementEXT(GLint i)
566{
567}
568
569void glColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
570{
571}
572
573void glDrawArraysEXT(GLenum mode, GLint first, GLsizei count)
574{
575#ifdef GL_EXT_vertex_array
576 static PFNGLDRAWARRAYSEXTPROC proc = 0;
577
578 if ( !proc )
579 {
580 proc = (PFNGLDRAWARRAYSEXTPROC) wglGetProcAddress("glDrawArraysEXT");
581 }
582
583 if ( proc )
584 (* proc) (mode, first, count);
585#endif
586}
587
588void glEdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *pointer)
589{
590}
591
592void glGetPointervEXT(GLenum pname, GLvoid* *params)
593{
594}
595
596void glIndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
597{
598}
599
600void glNormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
601{
602#ifdef GL_EXT_vertex_array
f48d169c 603 static PFNGLNORMALPOINTEREXTPROC proc = 0;
8b089c5e 604
f48d169c
UN
605 if ( !proc )
606 {
607 proc = (PFNGLNORMALPOINTEREXTPROC) wglGetProcAddress("glNormalPointerEXT");
608 }
8b089c5e 609
f48d169c
UN
610 if ( proc )
611 (* proc) (type, stride, count, pointer);
8b089c5e
JS
612#endif
613}
614
615void glTexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
616{
617}
618
619void glVertexPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer)
620{
621#ifdef GL_EXT_vertex_array
f48d169c 622 static PFNGLVERTEXPOINTEREXTPROC proc = 0;
8b089c5e 623
f48d169c
UN
624 if ( !proc )
625 {
626 proc = (PFNGLVERTEXPOINTEREXTPROC) wglGetProcAddress("glVertexPointerEXT");
627 }
628 if ( proc )
629 (* proc) (size, type, stride, count, pointer);
8b089c5e
JS
630#endif
631}
632
633/* EXT_color_subtable */
634void glColorSubtableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *table)
635{
636}
637
638/* EXT_color_table */
639void glColorTableEXT(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table)
640{
641}
642
643void glCopyColorTableEXT(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width)
644{
645}
646
647void glGetColorTableEXT(GLenum target, GLenum format, GLenum type, GLvoid *table)
648{
649}
650
651void glGetColorTableParamaterfvEXT(GLenum target, GLenum pname, GLfloat *params)
652{
653}
654
655void glGetColorTavleParameterivEXT(GLenum target, GLenum pname, GLint *params)
656{
657}
658
659/* SGI_compiled_vertex_array */
660void glLockArraysSGI(GLint first, GLsizei count)
661{
662}
663
664void glUnlockArraysSGI()
665{
666}
667
668
669/* SGI_cull_vertex */
670void glCullParameterdvSGI(GLenum pname, GLdouble* params)
671{
672}
673
674void glCullParameterfvSGI(GLenum pname, GLfloat* params)
675{
676}
677
678/* SGI_index_func */
679void glIndexFuncSGI(GLenum func, GLclampf ref)
680{
681}
682
683/* SGI_index_material */
684void glIndexMaterialSGI(GLenum face, GLenum mode)
685{
686}
687
688/* WIN_swap_hint */
689void glAddSwapHintRectWin(GLint x, GLint y, GLsizei width, GLsizei height)
690{
691}
692
a3081354
VZ
693
694//---------------------------------------------------------------------------
695// wxGLApp
696//---------------------------------------------------------------------------
697
698IMPLEMENT_CLASS(wxGLApp, wxApp)
699
700bool wxGLApp::InitGLVisual(int *attribList)
701{
702 int pixelFormat;
703 PIXELFORMATDESCRIPTOR pfd = {
b225f659
VZ
704 sizeof(PIXELFORMATDESCRIPTOR), /* size */
705 1, /* version */
706 PFD_SUPPORT_OPENGL |
707 PFD_DRAW_TO_WINDOW |
708 PFD_DOUBLEBUFFER, /* support double-buffering */
709 PFD_TYPE_RGBA, /* color type */
710 16, /* prefered color depth */
711 0, 0, 0, 0, 0, 0, /* color bits (ignored) */
712 0, /* no alpha buffer */
713 0, /* alpha bits (ignored) */
714 0, /* no accumulation buffer */
715 0, 0, 0, 0, /* accum bits (ignored) */
716 16, /* depth buffer */
717 0, /* no stencil buffer */
718 0, /* no auxiliary buffers */
719 PFD_MAIN_PLANE, /* main layer */
720 0, /* reserved */
721 0, 0, 0, /* no layer, visible, damage masks */
722 };
a3081354
VZ
723
724 AdjustPFDForAttributes(pfd, attribList);
725
726 // use DC for whole (root) screen, since no windows have yet been created
2b8646e0 727 pixelFormat = ChoosePixelFormat(ScreenHDC(), &pfd);
a3081354
VZ
728
729 if (pixelFormat == 0) {
730 wxLogError(_("Failed to initialize OpenGL"));
731 return FALSE;
732 }
733
734 return TRUE;
735}
736
737wxGLApp::~wxGLApp()
738{
739}
740
8b089c5e
JS
741#endif
742 // wxUSE_GLCANVAS