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