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