annotate src/Modules/Output/Graphics/Devices/GraphicsOutputDevicewxGLCanvas.cc @ 117:c5ac2f0c7fc5

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