Mercurial > hg > aimc
comparison trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevicewxGLCanvas.cc @ 398:3ee03a6b95a0
- All \t to two spaces (style guide compliance)
author | tomwalters |
---|---|
date | Fri, 15 Oct 2010 05:46:53 +0000 |
parents | 7a573750b186 |
children | a908972d234e |
comparison
equal
deleted
inserted
replaced
397:7a573750b186 | 398:3ee03a6b95a0 |
---|---|
70 | 70 |
71 // OpenGL get procaddress function pointer, differs across platforms | 71 // OpenGL get procaddress function pointer, differs across platforms |
72 typedef void (*(*glGetProcAddressPtr_t)(const char*))(); | 72 typedef void (*(*glGetProcAddressPtr_t)(const char*))(); |
73 | 73 |
74 GraphicsOutputDevicewxGLCanvas::GraphicsOutputDevicewxGLCanvas(Parameters *pParam, | 74 GraphicsOutputDevicewxGLCanvas::GraphicsOutputDevicewxGLCanvas(Parameters *pParam, |
75 wxWindow *parent, | 75 wxWindow *parent, |
76 wxWindowID id, | 76 wxWindowID id, |
77 const wxPoint& pos, | 77 const wxPoint& pos, |
78 const wxSize& size, | 78 const wxSize& size, |
79 long style, | 79 long style, |
80 const wxString& name) | 80 const wxString& name) |
81 : wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size, | 81 : wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size, |
82 style|wxFULL_REPAINT_ON_RESIZE, name, GLAttrlist), | 82 style|wxFULL_REPAINT_ON_RESIZE, name, GLAttrlist), |
83 GraphicsOutputDevice(pParam) { | 83 GraphicsOutputDevice(pParam) { |
84 m_init = false; | 84 m_init = false; |
85 m_gllist = 0; | 85 m_gllist = 0; |
86 m_pWorkerContext = NULL; | 86 m_pWorkerContext = NULL; |
87 m_bAntialiasing = true; | 87 m_bAntialiasing = true; |
88 m_pFont = NULL; | 88 m_pFont = NULL; |
89 m_sFontFile = NULL; | 89 m_sFontFile = NULL; |
90 m_iFontsize = -1; | 90 m_iFontsize = -1; |
91 #if !defined(_MACOSX) | 91 #if !defined(_MACOSX) |
92 s_bWorkerNeedsInit = false; | 92 s_bWorkerNeedsInit = false; |
93 #endif | 93 #endif |
94 | 94 |
95 #ifdef WITH_GL_VERTEX_ARRAYS | 95 #ifdef WITH_GL_VERTEX_ARRAYS |
96 m_iVertexType = 0xffff; // no gBegin() has happened yet | 96 m_iVertexType = 0xffff; // no gBegin() has happened yet |
97 m_bStaticColor = false; | 97 m_bStaticColor = false; |
98 m_pVertices = NULL; | 98 m_pVertices = NULL; |
99 m_iVerticesMax = 0; | 99 m_iVerticesMax = 0; |
100 // Enable vertex arrays if possible | 100 // Enable vertex arrays if possible |
101 #ifdef _MACOSX | 101 #ifdef _MACOSX |
102 m_glLockArraysEXT = ::glLockArraysEXT; | 102 m_glLockArraysEXT = ::glLockArraysEXT; |
103 m_glUnlockArraysEXT = ::glUnlockArraysEXT; | 103 m_glUnlockArraysEXT = ::glUnlockArraysEXT; |
104 m_bVertexArrayLock = true; | 104 m_bVertexArrayLock = true; |
105 #else | 105 #else |
106 m_bVertexArrayLock = false; | 106 m_bVertexArrayLock = false; |
107 // OpenGL command needed to fetch entry point, do it in InitGL() | 107 // OpenGL command needed to fetch entry point, do it in InitGL() |
108 #endif /* _MACOSX */ | 108 #endif /* _MACOSX */ |
109 #endif /* WITH_GL_VERTEX_ARRAYS */ | 109 #endif /* WITH_GL_VERTEX_ARRAYS */ |
110 } | 110 } |
111 | 111 |
112 GraphicsOutputDevicewxGLCanvas::~GraphicsOutputDevicewxGLCanvas() { | 112 GraphicsOutputDevicewxGLCanvas::~GraphicsOutputDevicewxGLCanvas() { |
113 // Cleanup OpenGL display list | 113 // Cleanup OpenGL display list |
114 if (m_init) { | 114 if (m_init) { |
115 glDeleteLists(m_gllist, 1); | 115 glDeleteLists(m_gllist, 1); |
116 } | 116 } |
117 DELETE_IF_NONNULL(m_pWorkerContext); | 117 DELETE_IF_NONNULL(m_pWorkerContext); |
118 DELETE_IF_NONNULL(m_pFont); | 118 DELETE_IF_NONNULL(m_pFont); |
119 #ifdef WITH_GL_VERTEX_ARRAYS | 119 #ifdef WITH_GL_VERTEX_ARRAYS |
120 DELETE_ARRAY_IF_NONNULL(m_pVertices); | 120 DELETE_ARRAY_IF_NONNULL(m_pVertices); |
121 #endif | 121 #endif |
122 } | 122 } |
123 | 123 |
124 void GraphicsOutputDevicewxGLCanvas::Start() { | 124 void GraphicsOutputDevicewxGLCanvas::Start() { |
125 // This seems to be needed to prevent a crash on windows, but why???? | 125 // This seems to be needed to prevent a crash on windows, but why???? |
126 SetCurrent(); | 126 SetCurrent(); |
127 return GraphicsOutputDevice::Start(); | 127 return GraphicsOutputDevice::Start(); |
128 } | 128 } |
129 | 129 |
130 bool GraphicsOutputDevicewxGLCanvas::Initialize(unsigned int iVerticesMax) { | 130 bool GraphicsOutputDevicewxGLCanvas::Initialize(unsigned int iVerticesMax) { |
131 AIM_ASSERT(m_pParam); | 131 AIM_ASSERT(m_pParam); |
132 // Give a chance to update anti-aliasing settings | 132 // Give a chance to update anti-aliasing settings |
133 if (m_bAntialiasing != m_pParam->GetBool("output.antialias")) { | 133 if (m_bAntialiasing != m_pParam->GetBool("output.antialias")) { |
134 m_bAntialiasing = m_pParam->GetBool("output.antialias"); | 134 m_bAntialiasing = m_pParam->GetBool("output.antialias"); |
135 if (SetCurrent()) { | 135 if (SetCurrent()) { |
136 InitGL(); | 136 InitGL(); |
137 #if !defined(_MACOSX) | 137 #if !defined(_MACOSX) |
138 { | 138 { |
139 wxMutexLocker lock(s_mutexOpenGL); | 139 wxMutexLocker lock(s_mutexOpenGL); |
140 s_bWorkerNeedsInit = true; | 140 s_bWorkerNeedsInit = true; |
141 } | 141 } |
142 #endif | 142 #endif |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 #ifdef WITH_GL_VERTEX_ARRAYS | 146 #ifdef WITH_GL_VERTEX_ARRAYS |
147 // Re-allocate vertices | 147 // Re-allocate vertices |
148 if (iVerticesMax > m_iVerticesMax) { | 148 if (iVerticesMax > m_iVerticesMax) { |
149 DELETE_IF_NONNULL(m_pVertices); | 149 DELETE_IF_NONNULL(m_pVertices); |
150 m_iVerticesMax = iVerticesMax; | 150 m_iVerticesMax = iVerticesMax; |
151 // If color is static, we need not store the color | 151 // If color is static, we need not store the color |
152 if (m_bStaticColor) | 152 if (m_bStaticColor) |
153 m_pVertices = new GLfloat[(iVerticesMax+1)*3]; | 153 m_pVertices = new GLfloat[(iVerticesMax+1)*3]; |
154 else | 154 else |
155 m_pVertices = new GLfloat[(iVerticesMax+1)*6]; | 155 m_pVertices = new GLfloat[(iVerticesMax+1)*6]; |
156 } | 156 } |
157 #endif | 157 #endif |
158 | 158 |
159 // Change font if requested | 159 // Change font if requested |
160 const char *sFontFile = m_pParam->GetString("output.gl.fontfile"); | 160 const char *sFontFile = m_pParam->GetString("output.gl.fontfile"); |
161 unsigned int iFontsize = m_pParam->GetUInt("output.fontsize"); | 161 unsigned int iFontsize = m_pParam->GetUInt("output.fontsize"); |
162 if (!m_sFontFile | 162 if (!m_sFontFile |
163 || !strcmp(m_sFontFile,sFontFile)==0 | 163 || !strcmp(m_sFontFile,sFontFile)==0 |
164 || m_iFontsize!=(int)iFontsize) { | 164 || m_iFontsize!=(int)iFontsize) { |
165 wxMutexLocker lock(s_mutexOpenGL); | 165 wxMutexLocker lock(s_mutexOpenGL); |
166 DELETE_IF_NONNULL(m_pFont); | 166 DELETE_IF_NONNULL(m_pFont); |
167 wxString sWorkingFontFilename = wxString::FromAscii(sFontFile); | 167 wxString sWorkingFontFilename = wxString::FromAscii(sFontFile); |
168 if (!wxFileExists(sWorkingFontFilename)) { | 168 if (!wxFileExists(sWorkingFontFilename)) { |
169 sWorkingFontFilename = wxString::FromAscii(aimDataDir()); | 169 sWorkingFontFilename = wxString::FromAscii(aimDataDir()); |
170 sWorkingFontFilename += _T("/"); | 170 sWorkingFontFilename += _T("/"); |
171 sWorkingFontFilename += wxString::FromAscii(sFontFile); | 171 sWorkingFontFilename += wxString::FromAscii(sFontFile); |
172 } | 172 } |
173 //if (!wxFileExists(sWorkingFontFilename)) | 173 //if (!wxFileExists(sWorkingFontFilename)) |
174 //sWorkingFontFilename.replace("Font:").append(sFontFile); | 174 //sWorkingFontFilename.replace("Font:").append(sFontFile); |
175 m_pFont = static_cast<FTFont*>(new FTGLBitmapFont(sWorkingFontFilename.fn_str())); | 175 m_pFont = static_cast<FTFont*>(new FTGLBitmapFont(sWorkingFontFilename.fn_str())); |
176 if (!m_pFont || m_pFont->Error()) { | 176 if (!m_pFont || m_pFont->Error()) { |
177 aimERROR(_T("Couldn't load font '%s'"), sFontFile); | 177 aimERROR(_T("Couldn't load font '%s'"), sFontFile); |
178 DELETE_IF_NONNULL(m_pFont); | 178 DELETE_IF_NONNULL(m_pFont); |
179 } else { | 179 } else { |
180 // Display lists don't mix with our own usage :( | 180 // Display lists don't mix with our own usage :( |
181 // May not be needed for a Bitmap font | 181 // May not be needed for a Bitmap font |
182 //m_pFont->UseDisplayList(false); | 182 //m_pFont->UseDisplayList(false); |
183 if ( !m_pFont->FaceSize(iFontsize) ) { | 183 if ( !m_pFont->FaceSize(iFontsize) ) { |
184 AIM_ERROR(_T("Couldn't select font size %u on font '%s'"), iFontsize, sFontFile); | 184 AIM_ERROR(_T("Couldn't select font size %u on font '%s'"), iFontsize, sFontFile); |
185 DELETE_IF_NONNULL(m_pFont); | 185 DELETE_IF_NONNULL(m_pFont); |
186 } | 186 } |
187 } | 187 } |
188 m_sFontFile = sFontFile; | 188 m_sFontFile = sFontFile; |
189 m_iFontsize = iFontsize; | 189 m_iFontsize = iFontsize; |
190 } | 190 } |
191 return true; | 191 return true; |
192 } | 192 } |
193 bool GraphicsOutputDevicewxGLCanvas::Initialize() { | 193 bool GraphicsOutputDevicewxGLCanvas::Initialize() { |
194 return Initialize(0); | 194 return Initialize(0); |
195 } | 195 } |
196 | 196 |
197 void GraphicsOutputDevicewxGLCanvas::Render() { | 197 void GraphicsOutputDevicewxGLCanvas::Render() { |
198 wxPaintDC dc(this); | 198 wxPaintDC dc(this); |
199 // We want to initialize first from main thread. | 199 // We want to initialize first from main thread. |
200 if (!m_init) { | 200 if (!m_init) { |
201 if (!SetCurrent()) return; | 201 if (!SetCurrent()) return; |
202 InitGL(); | 202 InitGL(); |
203 } | 203 } |
204 // Render saved list only if not animating (redrawn anyway in that case) | 204 // Render saved list only if not animating (redrawn anyway in that case) |
205 if (!m_bRunning) { | 205 if (!m_bRunning) { |
206 if (!SetCurrent()) { | 206 if (!SetCurrent()) { |
207 return; | 207 return; |
208 } | 208 } |
209 glClear(GL_COLOR_BUFFER_BIT/*|GL_DEPTH_BUFFER_BIT*/); | 209 glClear(GL_COLOR_BUFFER_BIT/*|GL_DEPTH_BUFFER_BIT*/); |
210 glCallList(m_gllist); | 210 glCallList(m_gllist); |
211 SwapBuffers(); | 211 SwapBuffers(); |
212 } | 212 } |
213 } | 213 } |
214 | 214 |
215 void GraphicsOutputDevicewxGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { | 215 void GraphicsOutputDevicewxGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { |
216 Render(); | 216 Render(); |
217 } | 217 } |
219 void GraphicsOutputDevicewxGLCanvas::OnSize(wxSizeEvent& event) { | 219 void GraphicsOutputDevicewxGLCanvas::OnSize(wxSizeEvent& event) { |
220 // this is also necessary to update the context on some platforms | 220 // this is also necessary to update the context on some platforms |
221 wxGLCanvas::OnSize(event); | 221 wxGLCanvas::OnSize(event); |
222 | 222 |
223 // set GL viewport | 223 // set GL viewport |
224 // (not called by wxGLCanvas::OnSize on all platforms...) | 224 // (not called by wxGLCanvas::OnSize on all platforms...) |
225 if (SetCurrent()) { | 225 if (SetCurrent()) { |
226 DoResize(); | 226 DoResize(); |
227 // It is only sensible to update the other thread when it's running | 227 // It is only sensible to update the other thread when it's running |
228 // Don't acquire the mutex when s_bWorkerNeedsInit already to avoid deadlock | 228 // Don't acquire the mutex when s_bWorkerNeedsInit already to avoid deadlock |
229 if (/*m_bRunning &&*/ !s_bWorkerNeedsInit) { | 229 if (/*m_bRunning &&*/ !s_bWorkerNeedsInit) { |
230 wxMutexLocker lock(s_mutexOpenGL); | 230 wxMutexLocker lock(s_mutexOpenGL); |
231 s_bWorkerNeedsInit = true; | 231 s_bWorkerNeedsInit = true; |
232 } | 232 } |
233 } | 233 } |
234 } | 234 } |
235 | 235 |
236 void GraphicsOutputDevicewxGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event)) { | 236 void GraphicsOutputDevicewxGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event)) { |
237 } | 237 } |
238 | 238 |
239 bool GraphicsOutputDevicewxGLCanvas::SetCurrent() { | 239 bool GraphicsOutputDevicewxGLCanvas::SetCurrent() { |
240 bool bRet=true; | 240 bool bRet=true; |
241 | 241 |
242 #ifndef __WXMOTIF__ | 242 #ifndef __WXMOTIF__ |
243 bRet = (GetContext()!=NULL); | 243 bRet = (GetContext()!=NULL); |
244 if (bRet) | 244 if (bRet) |
245 #endif | 245 #endif |
246 { | 246 { |
247 wxGLCanvas::SetCurrent(); | 247 wxGLCanvas::SetCurrent(); |
248 } | 248 } |
249 return bRet; | 249 return bRet; |
250 } | 250 } |
251 | 251 |
252 void GraphicsOutputDevicewxGLCanvas::DoResize() { | 252 void GraphicsOutputDevicewxGLCanvas::DoResize() { |
253 int w, h; | 253 int w, h; |
254 GetClientSize(&w, &h); | 254 GetClientSize(&w, &h); |
255 glViewport(0, 0, (GLint)w, (GLint)h); | 255 glViewport(0, 0, (GLint)w, (GLint)h); |
256 } | 256 } |
257 | 257 |
258 void GraphicsOutputDevicewxGLCanvas::InitGL() { | 258 void GraphicsOutputDevicewxGLCanvas::InitGL() { |
259 /* No SetCurrent() here, because this can be called from different GL contexts. | 259 /* No SetCurrent() here, because this can be called from different GL contexts. |
260 * Convenient for multi-threaded operation. */ | 260 * Convenient for multi-threaded operation. */ |
261 //aimERROR(_T("InitGL Called")); | 261 //aimERROR(_T("InitGL Called")); |
262 #if defined(WITH_GL_VERTEX_ARRAYS) && !defined(_MACOSX) | 262 #if defined(WITH_GL_VERTEX_ARRAYS) && !defined(_MACOSX) |
263 if (!m_init) { | 263 if (!m_init) { |
264 /* This needs to be done here, because OpenGL commands may need SetCurrent() | 264 /* This needs to be done here, because OpenGL commands may need SetCurrent() |
265 * and an already shown window. */ | 265 * and an already shown window. */ |
266 char *extensions = (char *)glGetString(GL_EXTENSIONS); | 266 char *extensions = (char *)glGetString(GL_EXTENSIONS); |
267 if (!extensions) { | 267 if (!extensions) { |
268 AIM_INFO(_T("Could not query OpenGL extensions, vertex arrays disabled")); | 268 AIM_INFO(_T("Could not query OpenGL extensions, vertex arrays disabled")); |
269 } else if (strstr(extensions, "GL_EXT_compiled_vertex_array")) { | 269 } else if (strstr(extensions, "GL_EXT_compiled_vertex_array")) { |
270 m_glLockArraysEXT = (LOCAL_PFNGLLOCKARRAYSEXTPROC)GL_GET_PROC_ADDRESS("glLockArraysEXT"); | 270 m_glLockArraysEXT = (LOCAL_PFNGLLOCKARRAYSEXTPROC)GL_GET_PROC_ADDRESS("glLockArraysEXT"); |
271 m_glUnlockArraysEXT = (LOCAL_PFNGLUNLOCKARRAYSEXTPROC)GL_GET_PROC_ADDRESS("glUnlockArraysEXT"); | 271 m_glUnlockArraysEXT = (LOCAL_PFNGLUNLOCKARRAYSEXTPROC)GL_GET_PROC_ADDRESS("glUnlockArraysEXT"); |
272 if(!m_glLockArraysEXT || !m_glUnlockArraysEXT) | 272 if(!m_glLockArraysEXT || !m_glUnlockArraysEXT) |
273 AIM_ERROR(_T("OpenGL error on GL_EXT_compiled_vertex_array")); | 273 AIM_ERROR(_T("OpenGL error on GL_EXT_compiled_vertex_array")); |
274 else | 274 else |
275 m_bVertexArrayLock = true; | 275 m_bVertexArrayLock = true; |
276 } | 276 } |
277 } | 277 } |
278 #endif | 278 #endif |
279 DoResize(); | 279 DoResize(); |
280 glClearColor(0, 0, 0, 1); | 280 glClearColor(0, 0, 0, 1); |
281 glMatrixMode( GL_PROJECTION ); | 281 glMatrixMode( GL_PROJECTION ); |
282 glLoadIdentity( ); | 282 glLoadIdentity( ); |
283 | 283 |
284 glEnable(GL_VERTEX_ARRAY); | 284 glEnable(GL_VERTEX_ARRAY); |
285 | 285 |
286 // Window limits in OpenGL co-ordiantes | 286 // Window limits in OpenGL co-ordiantes |
287 //! \todo Make this configurable, or change and document fixed values | 287 //! \todo Make this configurable, or change and document fixed values |
288 glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0); | 288 glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0); |
289 glTranslatef(0.0, 0.0, 0.0); | 289 glTranslatef(0.0, 0.0, 0.0); |
290 | 290 |
291 if (m_bAntialiasing) { | 291 if (m_bAntialiasing) { |
292 glEnable(GL_LINE_SMOOTH); | 292 glEnable(GL_LINE_SMOOTH); |
293 glEnable(GL_BLEND); | 293 glEnable(GL_BLEND); |
294 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 294 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
295 //glBlendFunc(GL_ONE, GL_ONE); | 295 //glBlendFunc(GL_ONE, GL_ONE); |
296 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); | 296 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); |
297 } else { | 297 } else { |
298 glDisable(GL_LINE_SMOOTH); | 298 glDisable(GL_LINE_SMOOTH); |
299 glDisable(GL_BLEND); | 299 glDisable(GL_BLEND); |
300 } | 300 } |
301 glLineWidth(1.0); | 301 glLineWidth(1.0); |
302 | 302 |
303 // Get a free display list only the first time | 303 // Get a free display list only the first time |
304 if (!m_init) { | 304 if (!m_init) { |
305 #if !defined(_MACOSX) | 305 #if !defined(_MACOSX) |
306 // Windows and Linux need a separate worker context | 306 // Windows and Linux need a separate worker context |
307 aimASSERT(wxIsMainThread()); | 307 aimASSERT(wxIsMainThread()); |
308 #if wxCHECK_VERSION(2,8,0) | 308 #if wxCHECK_VERSION(2,8,0) |
309 m_pWorkerContext = new wxGLContext(this, m_glContext); | 309 m_pWorkerContext = new wxGLContext(this, m_glContext); |
310 #else | 310 #else |
311 m_pWorkerContext = new wxGLContext(true, | 311 m_pWorkerContext = new wxGLContext(true, |
312 this, | 312 this, |
313 wxNullPalette, | 313 wxNullPalette, |
314 m_glContext); | 314 m_glContext); |
315 #endif | 315 #endif |
316 aimASSERT(m_pWorkerContext); | 316 aimASSERT(m_pWorkerContext); |
317 s_bWorkerNeedsInit = true; | 317 s_bWorkerNeedsInit = true; |
318 #endif | 318 #endif |
319 m_gllist = glGenLists(1); | 319 m_gllist = glGenLists(1); |
320 aimASSERT(m_gllist); | 320 aimASSERT(m_gllist); |
321 // Empty window at start | 321 // Empty window at start |
322 glNewList(m_gllist, GL_COMPILE_AND_EXECUTE); | 322 glNewList(m_gllist, GL_COMPILE_AND_EXECUTE); |
323 glEndList(); | 323 glEndList(); |
324 m_init = true; | 324 m_init = true; |
325 } | 325 } |
326 } | 326 } |
327 | 327 |
328 // Call before any other render* functions | 328 // Call before any other render* functions |
329 void GraphicsOutputDevicewxGLCanvas::gGrab() { | 329 void GraphicsOutputDevicewxGLCanvas::gGrab() { |
330 AimwxGuiLocker __lock__; | 330 AimwxGuiLocker __lock__; |
331 #if !defined(_MACOSX) | 331 #if !defined(_MACOSX) |
332 // Detect if we're the main thread or not. | 332 // Detect if we're the main thread or not. |
333 if (!wxIsMainThread()) { | 333 if (!wxIsMainThread()) { |
334 // We're called by a worker thread, make sure there's a right context | 334 // We're called by a worker thread, make sure there's a right context |
335 AIM_ASSERT(m_pWorkerContext); | 335 AIM_ASSERT(m_pWorkerContext); |
336 #if wxCHECK_VERSION(2,8,0) | 336 #if wxCHECK_VERSION(2,8,0) |
337 m_pWorkerContext->SetCurrent(*this); | 337 m_pWorkerContext->SetCurrent(*this); |
338 #else | 338 #else |
339 m_pWorkerContext->SetCurrent(); | 339 m_pWorkerContext->SetCurrent(); |
340 #endif | 340 #endif |
341 // Update OpenGL settings if needed | 341 // Update OpenGL settings if needed |
342 wxMutexLocker lock(s_mutexOpenGL); | 342 wxMutexLocker lock(s_mutexOpenGL); |
343 if (s_bWorkerNeedsInit) { | 343 if (s_bWorkerNeedsInit) { |
344 InitGL(); | 344 InitGL(); |
345 s_bWorkerNeedsInit = false; | 345 s_bWorkerNeedsInit = false; |
346 } | 346 } |
347 } else | 347 } else |
348 #endif | 348 #endif |
349 { | 349 { |
350 // Either called by main thread, or we need no special worker glContext | 350 // Either called by main thread, or we need no special worker glContext |
351 if (!SetCurrent()) { | 351 if (!SetCurrent()) { |
352 return; | 352 return; |
353 } | 353 } |
354 // Init OpenGL once, but after SetCurrent | 354 // Init OpenGL once, but after SetCurrent |
355 if (!m_init) { | 355 if (!m_init) { |
356 InitGL(); | 356 InitGL(); |
357 } | 357 } |
358 } | 358 } |
359 glClear(GL_COLOR_BUFFER_BIT); | 359 glClear(GL_COLOR_BUFFER_BIT); |
360 | 360 |
361 // Start and store in a display list for redrawing | 361 // Start and store in a display list for redrawing |
362 glNewList(m_gllist, GL_COMPILE); | 362 glNewList(m_gllist, GL_COMPILE); |
363 } | 363 } |
364 | 364 |
365 void GraphicsOutputDevicewxGLCanvas::gBeginLineStrip() { | 365 void GraphicsOutputDevicewxGLCanvas::gBeginLineStrip() { |
366 #ifdef WITH_GL_VERTEX_ARRAYS | 366 #ifdef WITH_GL_VERTEX_ARRAYS |
367 aimASSERT(m_iVertexType == 0xffff); // Previous gBegin*() must be gEnd()ed | 367 aimASSERT(m_iVertexType == 0xffff); // Previous gBegin*() must be gEnd()ed |
368 // New lines vertex array | 368 // New lines vertex array |
369 m_iVertexCount = 0; | 369 m_iVertexCount = 0; |
370 m_iVertexType = GL_LINE_STRIP; | 370 m_iVertexType = GL_LINE_STRIP; |
371 #else | 371 #else |
372 AimwxGuiLocker __lock__; | 372 AimwxGuiLocker __lock__; |
373 glBegin(GL_LINE_STRIP); | 373 glBegin(GL_LINE_STRIP); |
374 #endif | 374 #endif |
375 } | 375 } |
376 | 376 |
377 void GraphicsOutputDevicewxGLCanvas::gBeginQuadStrip() { | 377 void GraphicsOutputDevicewxGLCanvas::gBeginQuadStrip() { |
378 #ifdef WITH_GL_VERTEX_ARRAYS | 378 #ifdef WITH_GL_VERTEX_ARRAYS |
379 aimASSERT(m_iVertexType == 0xffff); // Previous gBegin*() must be gEnd()ed | 379 aimASSERT(m_iVertexType == 0xffff); // Previous gBegin*() must be gEnd()ed |
380 // New quads vertex array | 380 // New quads vertex array |
381 m_iVertexCount = 0; | 381 m_iVertexCount = 0; |
382 m_iVertexType = GL_QUAD_STRIP; | 382 m_iVertexType = GL_QUAD_STRIP; |
383 #else | 383 #else |
384 AimwxGuiLocker __lock__; | 384 AimwxGuiLocker __lock__; |
385 glBegin(GL_QUAD_STRIP); | 385 glBegin(GL_QUAD_STRIP); |
386 #endif | 386 #endif |
387 } | 387 } |
388 | 388 |
389 void GraphicsOutputDevicewxGLCanvas::gVertex3f(float x, float y, float z) { | 389 void GraphicsOutputDevicewxGLCanvas::gVertex3f(float x, float y, float z) { |
390 #ifdef WITH_GL_VERTEX_ARRAYS | 390 #ifdef WITH_GL_VERTEX_ARRAYS |
391 aimASSERT(m_iVertexType != 0xffff); // Must be inside gBegin*() | 391 aimASSERT(m_iVertexType != 0xffff); // Must be inside gBegin*() |
392 if (m_iVertexCount>=m_iVerticesMax) { | 392 if (m_iVertexCount>=m_iVerticesMax) { |
393 static bool errShown=false; | 393 static bool errShown=false; |
394 if (!errShown) { | 394 if (!errShown) { |
395 aimERROR(_T("Error: max vertex count reached: %d"), m_iVertexCount); | 395 aimERROR(_T("Error: max vertex count reached: %d"), m_iVertexCount); |
396 errShown=true; | 396 errShown=true; |
397 } | 397 } |
398 return; | 398 return; |
399 } | 399 } |
400 if (m_bStaticColor) { | 400 if (m_bStaticColor) { |
401 m_pVertices[m_iVertexCount*3+0] = x; | 401 m_pVertices[m_iVertexCount*3+0] = x; |
402 m_pVertices[m_iVertexCount*3+1] = y; | 402 m_pVertices[m_iVertexCount*3+1] = y; |
403 m_pVertices[m_iVertexCount*3+2] = z; | 403 m_pVertices[m_iVertexCount*3+2] = z; |
404 } else { | 404 } else { |
405 m_pVertices[m_iVertexCount*6+0] = m_fCurColorR; | 405 m_pVertices[m_iVertexCount*6+0] = m_fCurColorR; |
406 m_pVertices[m_iVertexCount*6+1] = m_fCurColorG; | 406 m_pVertices[m_iVertexCount*6+1] = m_fCurColorG; |
407 m_pVertices[m_iVertexCount*6+2] = m_fCurColorB; | 407 m_pVertices[m_iVertexCount*6+2] = m_fCurColorB; |
408 m_pVertices[m_iVertexCount*6+3] = x; | 408 m_pVertices[m_iVertexCount*6+3] = x; |
409 m_pVertices[m_iVertexCount*6+4] = y; | 409 m_pVertices[m_iVertexCount*6+4] = y; |
410 m_pVertices[m_iVertexCount*6+5] = z; | 410 m_pVertices[m_iVertexCount*6+5] = z; |
411 } | 411 } |
412 m_iVertexCount++; | 412 m_iVertexCount++; |
413 #else | 413 #else |
414 AimwxGuiLocker __lock__; | 414 AimwxGuiLocker __lock__; |
415 glVertex3f(x,y,z); | 415 glVertex3f(x,y,z); |
416 #endif | 416 #endif |
417 } | 417 } |
418 | 418 |
419 void GraphicsOutputDevicewxGLCanvas::gColor3f(float r, float g, float b) { | 419 void GraphicsOutputDevicewxGLCanvas::gColor3f(float r, float g, float b) { |
420 #ifdef WITH_GL_VERTEX_ARRAYS | 420 #ifdef WITH_GL_VERTEX_ARRAYS |
421 if (m_iVertexType==0xffff || m_bStaticColor) { | 421 if (m_iVertexType==0xffff || m_bStaticColor) { |
422 // If not inside vertex array run, use the ordinary command | 422 // If not inside vertex array run, use the ordinary command |
423 glColor3f(r, g, b); | |
424 } | |
425 if (!m_bStaticColor) { | |
426 // Set current color for vertex array usage | |
427 m_fCurColorR = r; | |
428 m_fCurColorG = g; | |
429 m_fCurColorB = b; | |
430 } | |
431 #else | |
432 AimwxGuiLocker __lock__; | |
433 glColor3f(r, g, b); | 423 glColor3f(r, g, b); |
424 } | |
425 if (!m_bStaticColor) { | |
426 // Set current color for vertex array usage | |
427 m_fCurColorR = r; | |
428 m_fCurColorG = g; | |
429 m_fCurColorB = b; | |
430 } | |
431 #else | |
432 AimwxGuiLocker __lock__; | |
433 glColor3f(r, g, b); | |
434 #endif | 434 #endif |
435 } | 435 } |
436 | 436 |
437 void GraphicsOutputDevicewxGLCanvas::gEnd() { | 437 void GraphicsOutputDevicewxGLCanvas::gEnd() { |
438 #ifdef WITH_GL_VERTEX_ARRAYS | 438 #ifdef WITH_GL_VERTEX_ARRAYS |
439 aimASSERT(m_iVertexType != 0xffff); // Must be inside gBegin*() | 439 aimASSERT(m_iVertexType != 0xffff); // Must be inside gBegin*() |
440 AimwxGuiLocker __lock__; | 440 AimwxGuiLocker __lock__; |
441 | 441 |
442 // Draw the vertex array | 442 // Draw the vertex array |
443 glEnableClientState(GL_VERTEX_ARRAY); | 443 glEnableClientState(GL_VERTEX_ARRAY); |
444 | 444 |
445 // Draw vertices | 445 // Draw vertices |
446 if (m_bStaticColor) | 446 if (m_bStaticColor) |
447 glVertexPointer(3, GL_FLOAT, 0, m_pVertices); | 447 glVertexPointer(3, GL_FLOAT, 0, m_pVertices); |
448 else | 448 else |
449 glInterleavedArrays(GL_C3F_V3F, 0, m_pVertices); | 449 glInterleavedArrays(GL_C3F_V3F, 0, m_pVertices); |
450 if (m_bVertexArrayLock) m_glLockArraysEXT(0, m_iVertexCount); | 450 if (m_bVertexArrayLock) m_glLockArraysEXT(0, m_iVertexCount); |
451 glDrawArrays(m_iVertexType, 0, m_iVertexCount); | 451 glDrawArrays(m_iVertexType, 0, m_iVertexCount); |
452 if (m_bVertexArrayLock) m_glUnlockArraysEXT(); | 452 if (m_bVertexArrayLock) m_glUnlockArraysEXT(); |
453 | 453 |
454 glDisableClientState(GL_VERTEX_ARRAY); | 454 glDisableClientState(GL_VERTEX_ARRAY); |
455 | 455 |
456 // Remember we're outside a gBegin()..gEnd() loop | 456 // Remember we're outside a gBegin()..gEnd() loop |
457 m_iVertexType = 0xffff; | 457 m_iVertexType = 0xffff; |
458 #else | 458 #else |
459 AimwxGuiLocker __lock__; | 459 AimwxGuiLocker __lock__; |
460 glEnd(); | 460 glEnd(); |
461 #endif | 461 #endif |
462 } | 462 } |
463 | 463 |
464 void GraphicsOutputDevicewxGLCanvas::gText3f(float x, | 464 void GraphicsOutputDevicewxGLCanvas::gText3f(float x, |
465 float y, | 465 float y, |
466 float z, | 466 float z, |
467 const char *sStr, | 467 const char *sStr, |
468 bool bRotated) { | 468 bool bRotated) { |
469 #ifdef WITH_GL_VERTEX_ARRAYS | 469 #ifdef WITH_GL_VERTEX_ARRAYS |
470 aimASSERT(m_iVertexType == 0xffff); // Must be outside gBegin*() | 470 aimASSERT(m_iVertexType == 0xffff); // Must be outside gBegin*() |
471 #endif | 471 #endif |
472 | 472 |
473 if (!m_pFont) | 473 if (!m_pFont) |
474 return; | 474 return; |
475 | 475 |
476 //! \todo make rotation work | 476 //! \todo make rotation work |
477 if (bRotated) | 477 if (bRotated) |
478 return; | 478 return; |
479 | 479 |
480 { | 480 { |
481 AimwxGuiLocker __lock__; | 481 AimwxGuiLocker __lock__; |
482 /* | 482 /* |
483 if (bRotated) { | 483 if (bRotated) { |
484 glPushMatrix(); | 484 glPushMatrix(); |
485 glTranslatef(x,y,z); | 485 glTranslatef(x,y,z); |
486 glRotatef(90.0f, 0, 0, 1.0f); | 486 glRotatef(90.0f, 0, 0, 1.0f); |
487 glRasterPos3f(0,0,0); | 487 glRasterPos3f(0,0,0); |
488 m_pFont->Render(sStr); | 488 m_pFont->Render(sStr); |
489 glPopMatrix(); | 489 glPopMatrix(); |
490 } else { | 490 } else { |
491 */ | 491 */ |
492 glRasterPos3f(x, y, z); | 492 glRasterPos3f(x, y, z); |
493 m_pFont->Render(sStr); | 493 m_pFont->Render(sStr); |
494 } | 494 } |
495 } | 495 } |
496 | 496 |
497 void GraphicsOutputDevicewxGLCanvas::gRelease() { | 497 void GraphicsOutputDevicewxGLCanvas::gRelease() { |
498 #ifdef WITH_GL_VERTEX_ARRAYS | 498 #ifdef WITH_GL_VERTEX_ARRAYS |
499 aimASSERT(m_iVertexType == 0xffff); // Must be gEnd()ed | 499 aimASSERT(m_iVertexType == 0xffff); // Must be gEnd()ed |
500 #endif | 500 #endif |
501 AimwxGuiLocker __lock__; | 501 AimwxGuiLocker __lock__; |
502 glEndList(); | 502 glEndList(); |
503 glCallList(m_gllist); | 503 glCallList(m_gllist); |
504 //glFlush(); | 504 //glFlush(); |
505 SwapBuffers(); // Doesn't matter in what context | 505 SwapBuffers(); // Doesn't matter in what context |
506 } | 506 } |