annotate trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevicewxGLCanvas.cc @ 706:f8e90b5d85fd tip

Delete CARFAC code from this repository. It has been moved to https://github.com/google/carfac Please email me with your github username to get access. I've also created a new mailing list to discuss CARFAC development: https://groups.google.com/forum/#!forum/carfac-dev
author ronw@google.com
date Thu, 18 Jul 2013 20:56:51 +0000
parents a908972d234e
children
rev   line source
tomwalters@397 1 // Copyright 2006, Willem van Engen
tomwalters@397 2 //
tomwalters@397 3 // AIM-C: A C++ implementation of the Auditory Image Model
tomwalters@397 4 // http://www.acousticscale.org/AIMC
tomwalters@397 5 //
tomwalters@397 6 // Licensed under the Apache License, Version 2.0 (the "License");
tomwalters@397 7 // you may not use this file except in compliance with the License.
tomwalters@397 8 // You may obtain a copy of the License at
tomwalters@397 9 //
tomwalters@397 10 // http://www.apache.org/licenses/LICENSE-2.0
tomwalters@397 11 //
tomwalters@397 12 // Unless required by applicable law or agreed to in writing, software
tomwalters@397 13 // distributed under the License is distributed on an "AS IS" BASIS,
tomwalters@397 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
tomwalters@397 15 // See the License for the specific language governing permissions and
tomwalters@397 16 // limitations under the License.
tomwalters@397 17
tomwalters@397 18 /*!
tomwalters@397 19 * \file
tomwalters@397 20 * \brief Output device for output to a wxWidgets OpenGL canvas
tomwalters@397 21 *
tomwalters@397 22 * \author Willem van Engen <cnbh@willem.engen.nl>
tomwalters@397 23 * \date created 2006/09/21
tomwalters@397 24 * \version \$Id: $
tomwalters@397 25 */
tomwalters@397 26
tomwalters@397 27 #include "Support/Common.h"
tomwalters@397 28
tomwalters@397 29 /*! \class GraphicsOutputDevicewxGLCanvas
tomwalters@397 30 *
tomwalters@397 31 * Graphics output takes a large part of the application's performance at the
tomwalters@397 32 * moment when it is inline with the Process() loop. Much is gained by
tomwalters@397 33 * putting it in a separate thread, which can be done using ShotTargetThreaded.
tomwalters@397 34 *
tomwalters@397 35 * OpenGL-related documents:
tomwalters@397 36 * - http://www.opengl.org/
tomwalters@397 37 * - http://www.sgi.com/products/software/opengl/
tomwalters@397 38 * - http://developer.apple.com/graphicsimaging/opengl/
tomwalters@397 39 * - http://developer.nvidia.com/page/documentation.html
tomwalters@397 40 * - Vertex arrays
tomwalters@397 41 * - http://www.opengl.org/registry/specs/EXT/vertex_array.txt
tomwalters@397 42 * - http://www.awprofessional.com/articles/article.asp?p=461848&seqNum=2&rl=1
tomwalters@397 43 * - http://jdobry.webpark.cz/opengl/opengl_maximum_performance.html
tomwalters@397 44 * - Fonts and OpenGL
tomwalters@397 45 * - http://gltt.sourceforge.net/
tomwalters@397 46 */
tomwalters@397 47
tomwalters@397 48 // And finally our own
tomwalters@397 49 #include "Support/util.h"
tomwalters@397 50 #include "Output/GraphicsOutputDevice.h"
tomwalters@397 51 #include "Output/GraphicsOutputDevicewxGLCanvas.h"
tomwalters@397 52
tomwalters@397 53 BEGIN_EVENT_TABLE(GraphicsOutputDevicewxGLCanvas, wxGLCanvas)
tomwalters@397 54 EVT_SIZE(GraphicsOutputDevicewxGLCanvas::OnSize)
tomwalters@397 55 EVT_PAINT(GraphicsOutputDevicewxGLCanvas::OnPaint)
tomwalters@397 56 EVT_ERASE_BACKGROUND(GraphicsOutputDevicewxGLCanvas::OnEraseBackground)
tomwalters@397 57 END_EVENT_TABLE()
tomwalters@397 58
tomwalters@397 59 // wxGLCanvas attributes
tomwalters@397 60 int GraphicsOutputDevicewxGLCanvas::GLAttrlist[] = {
tomwalters@397 61 WX_GL_RGBA, 1,
tomwalters@397 62 WX_GL_DOUBLEBUFFER, 1,
tomwalters@397 63 WX_GL_MIN_RED, 5,
tomwalters@397 64 WX_GL_MIN_GREEN, 5,
tomwalters@397 65 WX_GL_MIN_BLUE, 5,
tomwalters@397 66 WX_GL_MIN_ALPHA, 3,
tomwalters@397 67 WX_GL_DEPTH_SIZE, 16,
tomwalters@397 68 0
tomwalters@397 69 };
tomwalters@397 70
tomwalters@397 71 // OpenGL get procaddress function pointer, differs across platforms
tomwalters@397 72 typedef void (*(*glGetProcAddressPtr_t)(const char*))();
tomwalters@397 73
tomwalters@397 74 GraphicsOutputDevicewxGLCanvas::GraphicsOutputDevicewxGLCanvas(Parameters *pParam,
tomwalters@398 75 wxWindow *parent,
tomwalters@397 76 wxWindowID id,
tomwalters@397 77 const wxPoint& pos,
tomwalters@397 78 const wxSize& size,
tomwalters@397 79 long style,
tomwalters@397 80 const wxString& name)
tomwalters@398 81 : wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size,
tomwalters@397 82 style|wxFULL_REPAINT_ON_RESIZE, name, GLAttrlist),
tomwalters@398 83 GraphicsOutputDevice(pParam) {
tomwalters@398 84 m_init = false;
tomwalters@398 85 m_gllist = 0;
tomwalters@398 86 m_pWorkerContext = NULL;
tomwalters@398 87 m_bAntialiasing = true;
tomwalters@398 88 m_pFont = NULL;
tomwalters@398 89 m_sFontFile = NULL;
tomwalters@398 90 m_iFontsize = -1;
tomwalters@397 91 #if !defined(_MACOSX)
tomwalters@398 92 s_bWorkerNeedsInit = false;
tomwalters@397 93 #endif
tomwalters@397 94
tomwalters@397 95 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 96 m_iVertexType = 0xffff; // no gBegin() has happened yet
tomwalters@398 97 m_bStaticColor = false;
tomwalters@398 98 m_pVertices = NULL;
tomwalters@398 99 m_iVerticesMax = 0;
tomwalters@398 100 // Enable vertex arrays if possible
tomwalters@397 101 #ifdef _MACOSX
tomwalters@398 102 m_glLockArraysEXT = ::glLockArraysEXT;
tomwalters@398 103 m_glUnlockArraysEXT = ::glUnlockArraysEXT;
tomwalters@398 104 m_bVertexArrayLock = true;
tomwalters@397 105 #else
tomwalters@398 106 m_bVertexArrayLock = false;
tomwalters@398 107 // OpenGL command needed to fetch entry point, do it in InitGL()
tomwalters@397 108 #endif /* _MACOSX */
tomwalters@397 109 #endif /* WITH_GL_VERTEX_ARRAYS */
tomwalters@397 110 }
tomwalters@397 111
tomwalters@397 112 GraphicsOutputDevicewxGLCanvas::~GraphicsOutputDevicewxGLCanvas() {
tomwalters@398 113 // Cleanup OpenGL display list
tomwalters@398 114 if (m_init) {
tomwalters@398 115 glDeleteLists(m_gllist, 1);
tomwalters@398 116 }
tomwalters@398 117 DELETE_IF_NONNULL(m_pWorkerContext);
tomwalters@398 118 DELETE_IF_NONNULL(m_pFont);
tomwalters@397 119 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 120 DELETE_ARRAY_IF_NONNULL(m_pVertices);
tomwalters@397 121 #endif
tomwalters@397 122 }
tomwalters@397 123
tomwalters@397 124 void GraphicsOutputDevicewxGLCanvas::Start() {
tomwalters@398 125 // This seems to be needed to prevent a crash on windows, but why????
tomwalters@398 126 SetCurrent();
tomwalters@398 127 return GraphicsOutputDevice::Start();
tomwalters@397 128 }
tomwalters@397 129
tomwalters@397 130 bool GraphicsOutputDevicewxGLCanvas::Initialize(unsigned int iVerticesMax) {
tomwalters@398 131 AIM_ASSERT(m_pParam);
tomwalters@398 132 // Give a chance to update anti-aliasing settings
tomwalters@398 133 if (m_bAntialiasing != m_pParam->GetBool("output.antialias")) {
tomwalters@398 134 m_bAntialiasing = m_pParam->GetBool("output.antialias");
tomwalters@398 135 if (SetCurrent()) {
tomwalters@398 136 InitGL();
tomwalters@397 137 #if !defined(_MACOSX)
tomwalters@398 138 {
tomwalters@398 139 wxMutexLocker lock(s_mutexOpenGL);
tomwalters@398 140 s_bWorkerNeedsInit = true;
tomwalters@398 141 }
tomwalters@397 142 #endif
tomwalters@398 143 }
tomwalters@398 144 }
tomwalters@397 145
tomwalters@397 146 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 147 // Re-allocate vertices
tomwalters@398 148 if (iVerticesMax > m_iVerticesMax) {
tomwalters@398 149 DELETE_IF_NONNULL(m_pVertices);
tomwalters@398 150 m_iVerticesMax = iVerticesMax;
tomwalters@398 151 // If color is static, we need not store the color
tomwalters@398 152 if (m_bStaticColor)
tomwalters@398 153 m_pVertices = new GLfloat[(iVerticesMax+1)*3];
tomwalters@398 154 else
tomwalters@398 155 m_pVertices = new GLfloat[(iVerticesMax+1)*6];
tomwalters@398 156 }
tomwalters@397 157 #endif
tomwalters@397 158
tomwalters@397 159 // Change font if requested
tomwalters@398 160 const char *sFontFile = m_pParam->GetString("output.gl.fontfile");
tomwalters@398 161 unsigned int iFontsize = m_pParam->GetUInt("output.fontsize");
tomwalters@398 162 if (!m_sFontFile
tomwalters@397 163 || !strcmp(m_sFontFile,sFontFile)==0
tomwalters@397 164 || m_iFontsize!=(int)iFontsize) {
tomwalters@398 165 wxMutexLocker lock(s_mutexOpenGL);
tomwalters@398 166 DELETE_IF_NONNULL(m_pFont);
tomwalters@398 167 wxString sWorkingFontFilename = wxString::FromAscii(sFontFile);
tomwalters@398 168 if (!wxFileExists(sWorkingFontFilename)) {
tomwalters@398 169 sWorkingFontFilename = wxString::FromAscii(aimDataDir());
tomwalters@398 170 sWorkingFontFilename += _T("/");
tomwalters@398 171 sWorkingFontFilename += wxString::FromAscii(sFontFile);
tomwalters@398 172 }
tomwalters@398 173 //if (!wxFileExists(sWorkingFontFilename))
tomwalters@398 174 //sWorkingFontFilename.replace("Font:").append(sFontFile);
tomwalters@398 175 m_pFont = static_cast<FTFont*>(new FTGLBitmapFont(sWorkingFontFilename.fn_str()));
tomwalters@398 176 if (!m_pFont || m_pFont->Error()) {
tomwalters@398 177 aimERROR(_T("Couldn't load font '%s'"), sFontFile);
tomwalters@398 178 DELETE_IF_NONNULL(m_pFont);
tomwalters@398 179 } else {
tomwalters@398 180 // Display lists don't mix with our own usage :(
tomwalters@398 181 // May not be needed for a Bitmap font
tomwalters@398 182 //m_pFont->UseDisplayList(false);
tomwalters@398 183 if ( !m_pFont->FaceSize(iFontsize) ) {
tomwalters@398 184 AIM_ERROR(_T("Couldn't select font size %u on font '%s'"), iFontsize, sFontFile);
tomwalters@398 185 DELETE_IF_NONNULL(m_pFont);
tomwalters@398 186 }
tomwalters@398 187 }
tomwalters@398 188 m_sFontFile = sFontFile;
tomwalters@398 189 m_iFontsize = iFontsize;
tomwalters@398 190 }
tomwalters@398 191 return true;
tomwalters@397 192 }
tomwalters@397 193 bool GraphicsOutputDevicewxGLCanvas::Initialize() {
tomwalters@398 194 return Initialize(0);
tomwalters@397 195 }
tomwalters@397 196
tomwalters@397 197 void GraphicsOutputDevicewxGLCanvas::Render() {
tomwalters@398 198 wxPaintDC dc(this);
tomwalters@398 199 // We want to initialize first from main thread.
tomwalters@398 200 if (!m_init) {
tomwalters@398 201 if (!SetCurrent()) return;
tomwalters@398 202 InitGL();
tomwalters@398 203 }
tomwalters@398 204 // Render saved list only if not animating (redrawn anyway in that case)
tomwalters@398 205 if (!m_bRunning) {
tomwalters@398 206 if (!SetCurrent()) {
tomwalters@397 207 return;
tomwalters@397 208 }
tomwalters@398 209 glClear(GL_COLOR_BUFFER_BIT/*|GL_DEPTH_BUFFER_BIT*/);
tomwalters@398 210 glCallList(m_gllist);
tomwalters@398 211 SwapBuffers();
tomwalters@398 212 }
tomwalters@397 213 }
tomwalters@397 214
tomwalters@397 215 void GraphicsOutputDevicewxGLCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
tomwalters@397 216 Render();
tomwalters@397 217 }
tomwalters@397 218
tomwalters@397 219 void GraphicsOutputDevicewxGLCanvas::OnSize(wxSizeEvent& event) {
tomwalters@397 220 // this is also necessary to update the context on some platforms
tomwalters@397 221 wxGLCanvas::OnSize(event);
tomwalters@397 222
tomwalters@397 223 // set GL viewport
tomwalters@398 224 // (not called by wxGLCanvas::OnSize on all platforms...)
tomwalters@397 225 if (SetCurrent()) {
tomwalters@398 226 DoResize();
tomwalters@398 227 // It is only sensible to update the other thread when it's running
tomwalters@398 228 // Don't acquire the mutex when s_bWorkerNeedsInit already to avoid deadlock
tomwalters@398 229 if (/*m_bRunning &&*/ !s_bWorkerNeedsInit) {
tomwalters@398 230 wxMutexLocker lock(s_mutexOpenGL);
tomwalters@398 231 s_bWorkerNeedsInit = true;
tomwalters@398 232 }
tomwalters@398 233 }
tomwalters@397 234 }
tomwalters@397 235
tomwalters@397 236 void GraphicsOutputDevicewxGLCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event)) {
tomwalters@397 237 }
tomwalters@397 238
tomwalters@397 239 bool GraphicsOutputDevicewxGLCanvas::SetCurrent() {
tomwalters@397 240 bool bRet=true;
tomwalters@397 241
tomwalters@397 242 #ifndef __WXMOTIF__
tomwalters@398 243 bRet = (GetContext()!=NULL);
tomwalters@398 244 if (bRet)
tomwalters@397 245 #endif
tomwalters@398 246 {
tomwalters@398 247 wxGLCanvas::SetCurrent();
tomwalters@398 248 }
tomwalters@398 249 return bRet;
tomwalters@397 250 }
tomwalters@397 251
tomwalters@397 252 void GraphicsOutputDevicewxGLCanvas::DoResize() {
tomwalters@397 253 int w, h;
tomwalters@398 254 GetClientSize(&w, &h);
tomwalters@398 255 glViewport(0, 0, (GLint)w, (GLint)h);
tomwalters@397 256 }
tomwalters@397 257
tomwalters@397 258 void GraphicsOutputDevicewxGLCanvas::InitGL() {
tomwalters@397 259 /* No SetCurrent() here, because this can be called from different GL contexts.
tomwalters@398 260 * Convenient for multi-threaded operation. */
tomwalters@397 261 //aimERROR(_T("InitGL Called"));
tomwalters@397 262 #if defined(WITH_GL_VERTEX_ARRAYS) && !defined(_MACOSX)
tomwalters@398 263 if (!m_init) {
tomwalters@398 264 /* This needs to be done here, because OpenGL commands may need SetCurrent()
tomwalters@398 265 * and an already shown window. */
tomwalters@398 266 char *extensions = (char *)glGetString(GL_EXTENSIONS);
tomwalters@398 267 if (!extensions) {
tomwalters@398 268 AIM_INFO(_T("Could not query OpenGL extensions, vertex arrays disabled"));
tomwalters@398 269 } else if (strstr(extensions, "GL_EXT_compiled_vertex_array")) {
tomwalters@398 270 m_glLockArraysEXT = (LOCAL_PFNGLLOCKARRAYSEXTPROC)GL_GET_PROC_ADDRESS("glLockArraysEXT");
tomwalters@398 271 m_glUnlockArraysEXT = (LOCAL_PFNGLUNLOCKARRAYSEXTPROC)GL_GET_PROC_ADDRESS("glUnlockArraysEXT");
tomwalters@411 272 if (!m_glLockArraysEXT || !m_glUnlockArraysEXT)
tomwalters@398 273 AIM_ERROR(_T("OpenGL error on GL_EXT_compiled_vertex_array"));
tomwalters@398 274 else
tomwalters@398 275 m_bVertexArrayLock = true;
tomwalters@398 276 }
tomwalters@398 277 }
tomwalters@397 278 #endif
tomwalters@398 279 DoResize();
tomwalters@398 280 glClearColor(0, 0, 0, 1);
tomwalters@398 281 glMatrixMode( GL_PROJECTION );
tomwalters@398 282 glLoadIdentity( );
tomwalters@397 283
tomwalters@398 284 glEnable(GL_VERTEX_ARRAY);
tomwalters@397 285
tomwalters@398 286 // Window limits in OpenGL co-ordiantes
tomwalters@398 287 //! \todo Make this configurable, or change and document fixed values
tomwalters@398 288 glOrtho(0.0, 1.0, 0.0, 1.0, 0.0, 1.0);
tomwalters@398 289 glTranslatef(0.0, 0.0, 0.0);
tomwalters@397 290
tomwalters@398 291 if (m_bAntialiasing) {
tomwalters@398 292 glEnable(GL_LINE_SMOOTH);
tomwalters@398 293 glEnable(GL_BLEND);
tomwalters@398 294 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
tomwalters@398 295 //glBlendFunc(GL_ONE, GL_ONE);
tomwalters@398 296 glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
tomwalters@398 297 } else {
tomwalters@398 298 glDisable(GL_LINE_SMOOTH);
tomwalters@398 299 glDisable(GL_BLEND);
tomwalters@398 300 }
tomwalters@398 301 glLineWidth(1.0);
tomwalters@397 302
tomwalters@398 303 // Get a free display list only the first time
tomwalters@398 304 if (!m_init) {
tomwalters@397 305 #if !defined(_MACOSX)
tomwalters@398 306 // Windows and Linux need a separate worker context
tomwalters@398 307 aimASSERT(wxIsMainThread());
tomwalters@397 308 #if wxCHECK_VERSION(2,8,0)
tomwalters@398 309 m_pWorkerContext = new wxGLContext(this, m_glContext);
tomwalters@397 310 #else
tomwalters@398 311 m_pWorkerContext = new wxGLContext(true,
tomwalters@397 312 this,
tomwalters@397 313 wxNullPalette,
tomwalters@397 314 m_glContext);
tomwalters@397 315 #endif
tomwalters@398 316 aimASSERT(m_pWorkerContext);
tomwalters@398 317 s_bWorkerNeedsInit = true;
tomwalters@397 318 #endif
tomwalters@398 319 m_gllist = glGenLists(1);
tomwalters@398 320 aimASSERT(m_gllist);
tomwalters@398 321 // Empty window at start
tomwalters@398 322 glNewList(m_gllist, GL_COMPILE_AND_EXECUTE);
tomwalters@398 323 glEndList();
tomwalters@398 324 m_init = true;
tomwalters@398 325 }
tomwalters@397 326 }
tomwalters@397 327
tomwalters@397 328 // Call before any other render* functions
tomwalters@397 329 void GraphicsOutputDevicewxGLCanvas::gGrab() {
tomwalters@398 330 AimwxGuiLocker __lock__;
tomwalters@397 331 #if !defined(_MACOSX)
tomwalters@398 332 // Detect if we're the main thread or not.
tomwalters@398 333 if (!wxIsMainThread()) {
tomwalters@398 334 // We're called by a worker thread, make sure there's a right context
tomwalters@398 335 AIM_ASSERT(m_pWorkerContext);
tomwalters@397 336 #if wxCHECK_VERSION(2,8,0)
tomwalters@398 337 m_pWorkerContext->SetCurrent(*this);
tomwalters@397 338 #else
tomwalters@398 339 m_pWorkerContext->SetCurrent();
tomwalters@397 340 #endif
tomwalters@398 341 // Update OpenGL settings if needed
tomwalters@398 342 wxMutexLocker lock(s_mutexOpenGL);
tomwalters@398 343 if (s_bWorkerNeedsInit) {
tomwalters@398 344 InitGL();
tomwalters@398 345 s_bWorkerNeedsInit = false;
tomwalters@398 346 }
tomwalters@398 347 } else
tomwalters@397 348 #endif
tomwalters@398 349 {
tomwalters@398 350 // Either called by main thread, or we need no special worker glContext
tomwalters@398 351 if (!SetCurrent()) {
tomwalters@398 352 return;
tomwalters@398 353 }
tomwalters@398 354 // Init OpenGL once, but after SetCurrent
tomwalters@398 355 if (!m_init) {
tomwalters@398 356 InitGL();
tomwalters@398 357 }
tomwalters@398 358 }
tomwalters@398 359 glClear(GL_COLOR_BUFFER_BIT);
tomwalters@397 360
tomwalters@398 361 // Start and store in a display list for redrawing
tomwalters@398 362 glNewList(m_gllist, GL_COMPILE);
tomwalters@397 363 }
tomwalters@397 364
tomwalters@397 365 void GraphicsOutputDevicewxGLCanvas::gBeginLineStrip() {
tomwalters@397 366 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 367 aimASSERT(m_iVertexType == 0xffff); // Previous gBegin*() must be gEnd()ed
tomwalters@398 368 // New lines vertex array
tomwalters@398 369 m_iVertexCount = 0;
tomwalters@398 370 m_iVertexType = GL_LINE_STRIP;
tomwalters@397 371 #else
tomwalters@398 372 AimwxGuiLocker __lock__;
tomwalters@398 373 glBegin(GL_LINE_STRIP);
tomwalters@397 374 #endif
tomwalters@397 375 }
tomwalters@397 376
tomwalters@397 377 void GraphicsOutputDevicewxGLCanvas::gBeginQuadStrip() {
tomwalters@397 378 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 379 aimASSERT(m_iVertexType == 0xffff); // Previous gBegin*() must be gEnd()ed
tomwalters@398 380 // New quads vertex array
tomwalters@398 381 m_iVertexCount = 0;
tomwalters@398 382 m_iVertexType = GL_QUAD_STRIP;
tomwalters@397 383 #else
tomwalters@398 384 AimwxGuiLocker __lock__;
tomwalters@398 385 glBegin(GL_QUAD_STRIP);
tomwalters@397 386 #endif
tomwalters@397 387 }
tomwalters@397 388
tomwalters@397 389 void GraphicsOutputDevicewxGLCanvas::gVertex3f(float x, float y, float z) {
tomwalters@397 390 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 391 aimASSERT(m_iVertexType != 0xffff); // Must be inside gBegin*()
tomwalters@398 392 if (m_iVertexCount>=m_iVerticesMax) {
tomwalters@398 393 static bool errShown=false;
tomwalters@398 394 if (!errShown) {
tomwalters@398 395 aimERROR(_T("Error: max vertex count reached: %d"), m_iVertexCount);
tomwalters@398 396 errShown=true;
tomwalters@398 397 }
tomwalters@398 398 return;
tomwalters@398 399 }
tomwalters@398 400 if (m_bStaticColor) {
tomwalters@398 401 m_pVertices[m_iVertexCount*3+0] = x;
tomwalters@398 402 m_pVertices[m_iVertexCount*3+1] = y;
tomwalters@398 403 m_pVertices[m_iVertexCount*3+2] = z;
tomwalters@398 404 } else {
tomwalters@398 405 m_pVertices[m_iVertexCount*6+0] = m_fCurColorR;
tomwalters@398 406 m_pVertices[m_iVertexCount*6+1] = m_fCurColorG;
tomwalters@398 407 m_pVertices[m_iVertexCount*6+2] = m_fCurColorB;
tomwalters@398 408 m_pVertices[m_iVertexCount*6+3] = x;
tomwalters@398 409 m_pVertices[m_iVertexCount*6+4] = y;
tomwalters@398 410 m_pVertices[m_iVertexCount*6+5] = z;
tomwalters@398 411 }
tomwalters@398 412 m_iVertexCount++;
tomwalters@397 413 #else
tomwalters@398 414 AimwxGuiLocker __lock__;
tomwalters@398 415 glVertex3f(x,y,z);
tomwalters@397 416 #endif
tomwalters@397 417 }
tomwalters@397 418
tomwalters@397 419 void GraphicsOutputDevicewxGLCanvas::gColor3f(float r, float g, float b) {
tomwalters@397 420 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 421 if (m_iVertexType==0xffff || m_bStaticColor) {
tomwalters@398 422 // If not inside vertex array run, use the ordinary command
tomwalters@398 423 glColor3f(r, g, b);
tomwalters@398 424 }
tomwalters@398 425 if (!m_bStaticColor) {
tomwalters@398 426 // Set current color for vertex array usage
tomwalters@398 427 m_fCurColorR = r;
tomwalters@398 428 m_fCurColorG = g;
tomwalters@398 429 m_fCurColorB = b;
tomwalters@398 430 }
tomwalters@397 431 #else
tomwalters@398 432 AimwxGuiLocker __lock__;
tomwalters@397 433 glColor3f(r, g, b);
tomwalters@397 434 #endif
tomwalters@397 435 }
tomwalters@397 436
tomwalters@397 437 void GraphicsOutputDevicewxGLCanvas::gEnd() {
tomwalters@397 438 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 439 aimASSERT(m_iVertexType != 0xffff); // Must be inside gBegin*()
tomwalters@398 440 AimwxGuiLocker __lock__;
tomwalters@397 441
tomwalters@398 442 // Draw the vertex array
tomwalters@398 443 glEnableClientState(GL_VERTEX_ARRAY);
tomwalters@397 444
tomwalters@398 445 // Draw vertices
tomwalters@398 446 if (m_bStaticColor)
tomwalters@398 447 glVertexPointer(3, GL_FLOAT, 0, m_pVertices);
tomwalters@398 448 else
tomwalters@398 449 glInterleavedArrays(GL_C3F_V3F, 0, m_pVertices);
tomwalters@398 450 if (m_bVertexArrayLock) m_glLockArraysEXT(0, m_iVertexCount);
tomwalters@398 451 glDrawArrays(m_iVertexType, 0, m_iVertexCount);
tomwalters@398 452 if (m_bVertexArrayLock) m_glUnlockArraysEXT();
tomwalters@397 453
tomwalters@398 454 glDisableClientState(GL_VERTEX_ARRAY);
tomwalters@397 455
tomwalters@398 456 // Remember we're outside a gBegin()..gEnd() loop
tomwalters@398 457 m_iVertexType = 0xffff;
tomwalters@397 458 #else
tomwalters@398 459 AimwxGuiLocker __lock__;
tomwalters@398 460 glEnd();
tomwalters@397 461 #endif
tomwalters@397 462 }
tomwalters@397 463
tomwalters@397 464 void GraphicsOutputDevicewxGLCanvas::gText3f(float x,
tomwalters@397 465 float y,
tomwalters@397 466 float z,
tomwalters@397 467 const char *sStr,
tomwalters@397 468 bool bRotated) {
tomwalters@397 469 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 470 aimASSERT(m_iVertexType == 0xffff); // Must be outside gBegin*()
tomwalters@397 471 #endif
tomwalters@397 472
tomwalters@398 473 if (!m_pFont)
tomwalters@398 474 return;
tomwalters@397 475
tomwalters@398 476 //! \todo make rotation work
tomwalters@398 477 if (bRotated)
tomwalters@398 478 return;
tomwalters@397 479
tomwalters@398 480 {
tomwalters@398 481 AimwxGuiLocker __lock__;
tomwalters@398 482 /*
tomwalters@398 483 if (bRotated) {
tomwalters@398 484 glPushMatrix();
tomwalters@398 485 glTranslatef(x,y,z);
tomwalters@398 486 glRotatef(90.0f, 0, 0, 1.0f);
tomwalters@398 487 glRasterPos3f(0,0,0);
tomwalters@398 488 m_pFont->Render(sStr);
tomwalters@398 489 glPopMatrix();
tomwalters@398 490 } else {
tomwalters@398 491 */
tomwalters@398 492 glRasterPos3f(x, y, z);
tomwalters@398 493 m_pFont->Render(sStr);
tomwalters@398 494 }
tomwalters@397 495 }
tomwalters@397 496
tomwalters@397 497 void GraphicsOutputDevicewxGLCanvas::gRelease() {
tomwalters@397 498 #ifdef WITH_GL_VERTEX_ARRAYS
tomwalters@398 499 aimASSERT(m_iVertexType == 0xffff); // Must be gEnd()ed
tomwalters@397 500 #endif
tomwalters@398 501 AimwxGuiLocker __lock__;
tomwalters@398 502 glEndList();
tomwalters@398 503 glCallList(m_gllist);
tomwalters@398 504 //glFlush();
tomwalters@398 505 SwapBuffers(); // Doesn't matter in what context
tomwalters@397 506 }