annotate trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevicewxGLCanvas.h @ 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 3ee03a6b95a0
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 #ifndef __GRAPHICS_OUTPUT_DEVICE_GL_CANVAS_H__
tomwalters@397 28 #define __GRAPHICS_OUTPUT_DEVICE_GL_CANVAS_H__
tomwalters@397 29
tomwalters@397 30 // Precompiled wxWidgets headers
tomwalters@397 31 #include "stdwx.h"
tomwalters@397 32
tomwalters@397 33 // Make sure GLCANVAS is compiled into wxWidgets
tomwalters@397 34 #if !wxUSE_GLCANVAS
tomwalters@398 35 # error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
tomwalters@397 36 #endif
tomwalters@397 37
tomwalters@397 38 #if defined (_MACOSX)
tomwalters@398 39 # include <OpenGL/gl.h>
tomwalters@398 40 # include <OpenGl/glext.h>
tomwalters@397 41 #elif defined (_WINDOWS)
tomwalters@398 42 # include <GL/gl.h>
tomwalters@398 43 # define GL_GET_PROC_ADDRESS wglGetProcAddress
tomwalters@397 44 #else
tomwalters@398 45 # include <GL/gl.h>
tomwalters@398 46 # define GL_GET_PROC_ADDRESS(x) glXGetProcAddress((const GLubyte*)x)
tomwalters@397 47 #endif
tomwalters@397 48 /* Define them just ourselves, easiest way to get it working cross-platform
tomwalters@397 49 * and -Mesa/OpenGL-version. */
tomwalters@397 50 #ifndef APIENTRY
tomwalters@398 51 # define APIENTRY
tomwalters@397 52 #endif
tomwalters@397 53 typedef void (APIENTRY * LOCAL_PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count);
tomwalters@397 54 typedef void (APIENTRY * LOCAL_PFNGLUNLOCKARRAYSEXTPROC) (void);
tomwalters@397 55
tomwalters@397 56 #ifdef FTGL_SUBDIR
tomwalters@398 57 # include <FTGL/FTGLBitmapFont.h>
tomwalters@397 58 #else
tomwalters@398 59 # include <FTGLBitmapFont.h>
tomwalters@397 60 #endif
tomwalters@397 61
tomwalters@397 62 #include "Output/GraphicsOutputDevice.h"
tomwalters@397 63
tomwalters@397 64 // Use by default
tomwalters@397 65 #define WITH_GL_VERTEX_ARRAYS
tomwalters@397 66
tomwalters@397 67 /*!
tomwalters@397 68 * \class GraphicsOutputDevicewxGLCanvas "Output/GraphicsOutputDevicewxGLCanvas.h"
tomwalters@397 69 * \brief Output class for output to a wxWidgets OpenGL canvas
tomwalters@397 70 *
tomwalters@397 71 * On windows, OpenGL needs a different context when two different threads
tomwalters@397 72 * want to issue OpenGL commands. This is handled automatically for two
tomwalters@397 73 * wxThread s.
tomwalters@397 74 */
tomwalters@397 75 class GraphicsOutputDevicewxGLCanvas : public wxGLCanvas,
tomwalters@397 76 public GraphicsOutputDevice {
tomwalters@397 77 public:
tomwalters@397 78 GraphicsOutputDevicewxGLCanvas(Parameters *pParam,
tomwalters@398 79 wxWindow *parent,
tomwalters@397 80 wxWindowID id = wxID_ANY,
tomwalters@397 81 const wxPoint& pos = wxDefaultPosition,
tomwalters@397 82 const wxSize& size = wxDefaultSize,
tomwalters@397 83 long style = 0,
tomwalters@397 84 const wxString& name
tomwalters@397 85 = _T("GraphicsOutputDeviceGLCanvas"));
tomwalters@397 86 virtual ~GraphicsOutputDevicewxGLCanvas();
tomwalters@397 87 void OnPaint(wxPaintEvent& event);
tomwalters@397 88 void OnSize(wxSizeEvent& event);
tomwalters@397 89 void OnEraseBackground(wxEraseEvent& event);
tomwalters@397 90
tomwalters@398 91 /*! \param iVerticesMax Maximum number of vertices to be draw inside a gBegin()..gEnd()
tomwalters@398 92 *
tomwalters@398 93 * When iVerticesMax is zero, this variable will not be updated. Note that is _has_
tomwalters@398 94 * to be set at least once before using this class.
tomwalters@398 95 */
tomwalters@398 96 bool Initialize(unsigned int iVerticesMax);
tomwalters@398 97 bool Initialize();
tomwalters@397 98
tomwalters@398 99 void Start();
tomwalters@397 100
tomwalters@397 101 void gGrab();
tomwalters@397 102 void gBeginLineStrip();
tomwalters@397 103 void gBeginQuadStrip();
tomwalters@398 104 using GraphicsOutputDevice::gVertex3f; // Because we overload it
tomwalters@398 105 void gVertex3f(float x, float y, float z);
tomwalters@398 106 void gColor3f(float r, float g, float b);
tomwalters@397 107 void gEnd();
tomwalters@398 108 void gText3f(float x, float y, float z, const char *sStr, bool bRotated = false);
tomwalters@398 109 void gRelease();
tomwalters@397 110 protected:
tomwalters@398 111 /*! \brief Smarter SetCurrent() replacement
tomwalters@398 112 * \return true on success, false on error
tomwalters@398 113 *
tomwalters@398 114 * This function tries GetContext() first. If that fails, it returns false.
tomwalters@398 115 */
tomwalters@398 116 bool SetCurrent();
tomwalters@398 117 void Render();
tomwalters@397 118
tomwalters@398 119 /*! \brief Initialize the OpenGL environment.
tomwalters@398 120 *
tomwalters@398 121 * This must be called after the canvas is realized but before any other
tomwalters@398 122 * OpenGL operation is done. Make sure to run SetCurrent() beforehand.
tomwalters@398 123 * Usually only needed when m_init is false.
tomwalters@398 124 */
tomwalters@397 125 void InitGL();
tomwalters@397 126
tomwalters@398 127 /*! \brief Handle a resize (notify OpenGL of the new area)
tomwalters@398 128 *
tomwalters@398 129 * This is a separate function, because in multi-threading environments
tomwalters@398 130 * multiple contexts have to call it.
tomwalters@398 131 */
tomwalters@398 132 void DoResize();
tomwalters@397 133
tomwalters@398 134 /*! \brief Only need to initialize OpenGL once.
tomwalters@398 135 *
tomwalters@398 136 * This is false at start and true when OpenGL has been initialized.
tomwalters@398 137 * No mutex needed, since it's set once at InitGL() and only read afterwards.
tomwalters@398 138 */
tomwalters@397 139 bool m_init;
tomwalters@397 140
tomwalters@398 141 /*! \brief Vertex list for last drawing so it can be updated on repaint.
tomwalters@398 142 *
tomwalters@398 143 * No mutex needed, since it's set once at InitGL() and only read afterwards.
tomwalters@398 144 */
tomwalters@397 145 GLuint m_gllist;
tomwalters@397 146
tomwalters@398 147 //! \brief OpenGL context for worker thread, use when wxIsMainThread() returns false.
tomwalters@398 148 wxGLContext *m_pWorkerContext;
tomwalters@397 149
tomwalters@398 150 //! \brief Mutex for inter-thread communication
tomwalters@398 151 wxMutex s_mutexOpenGL;
tomwalters@397 152
tomwalters@398 153 //! \brief When true, OpenGL needs to be reinitialized (in the worker thread)
tomwalters@398 154 bool s_bWorkerNeedsInit;
tomwalters@397 155
tomwalters@398 156 //! \brief OpenGL attributes used for initialization.
tomwalters@397 157 static int GLAttrlist[];
tomwalters@397 158
tomwalters@398 159 //! \brief Whether to use anti-aliasing or not
tomwalters@398 160 bool m_bAntialiasing;
tomwalters@397 161
tomwalters@398 162 //! \brief FTGL Font class
tomwalters@398 163 FTFont *m_pFont;
tomwalters@398 164 //! \brief Current font filename
tomwalters@398 165 const char *m_sFontFile;
tomwalters@398 166 //! \brief Current font size
tomwalters@398 167 int m_iFontsize;
tomwalters@397 168
tomwalters@397 169 #if defined(WITH_GL_VERTEX_ARRAYS) || defined(DOXYGEN)
tomwalters@398 170 //! \brief OpenGL vertex type of the current m_pVertices, or 0xffff is outside gBegin()..gEnd()
tomwalters@398 171 int m_iVertexType;
tomwalters@398 172 //! \brief Maximum number of vertices begin gBegin()..gEnd()
tomwalters@398 173 unsigned int m_iVerticesMax;
tomwalters@398 174 //! \brief Vertex array to draw at gEnd(), this becomes m_pVertices[m_iVerticesMax*3]
tomwalters@398 175 GLfloat *m_pVertices;
tomwalters@398 176 //! \brief The current number of vertices inside m_pVertices
tomwalters@398 177 unsigned int m_iVertexCount;
tomwalters@397 178
tomwalters@398 179 /*! \brief Whether to use coloring in vertex lists
tomwalters@398 180 *
tomwalters@398 181 * This variable must not change after Initialize(), or the program may crash.
tomwalters@398 182 * When this variable is true, color information is stored in vertex lists. If
tomwalters@398 183 * it is false, only vertex data is stored.
tomwalters@398 184 *
tomwalters@398 185 * This variable exists for performance reasons, but is currently only set in
tomwalters@398 186 * the constructor of this object.
tomwalters@398 187 */
tomwalters@398 188 bool m_bStaticColor;
tomwalters@398 189 //! \brief Current color for vertex list drawing
tomwalters@398 190 float m_fCurColorR, m_fCurColorG, m_fCurColorB;
tomwalters@397 191
tomwalters@398 192 //! \brief Whether to use vertex array locking or not
tomwalters@398 193 bool m_bVertexArrayLock;
tomwalters@398 194 //! \brief Pointer to vertex array locking function; can be NULL.
tomwalters@398 195 LOCAL_PFNGLLOCKARRAYSEXTPROC m_glLockArraysEXT;
tomwalters@398 196 //! \brief Pointer to vertex array unlocking function; can be NULL.
tomwalters@398 197 LOCAL_PFNGLUNLOCKARRAYSEXTPROC m_glUnlockArraysEXT;
tomwalters@397 198 #endif
tomwalters@397 199
tomwalters@398 200 /*! \brief wxMutexGuiEnter() / wxMutexGuiLeave() wrapper
tomwalters@398 201 *
tomwalters@398 202 * This is a wxMutexLocker-alike for the main gui mutex. Any method that
tomwalters@398 203 * is public, can be called from within another thread and does OpenGL or
tomwalters@398 204 * other gui calls must use this. Example:
tomwalters@398 205 * \code
tomwalters@398 206 * void DoFoo() {
tomwalters@398 207 * AimwxGuiLocker __lock__;
tomwalters@398 208 * glAmazingMethod();
tomwalters@398 209 * }
tomwalters@398 210 * \endcode
tomwalters@398 211 *
tomwalters@398 212 * It is mostly on X-Windows (Xorg/XFree86) that the gui mutex appears to
tomwalters@398 213 * be needed. Otherwise the error "Xlib: unexpected async reply" can occur.
tomwalters@398 214 *
tomwalters@398 215 * On windows, the ui may occasionally lock up for a short while with these
tomwalters@398 216 * mutexes. Since they aren't really needed on that platform, it's left out
tomwalters@398 217 * alltogether.
tomwalters@398 218 */
tomwalters@398 219 class AimwxGuiLocker {
tomwalters@398 220 public:
tomwalters@398 221 inline AimwxGuiLocker() {
tomwalters@397 222 #ifndef _WINDOWS
tomwalters@398 223 if (!wxIsMainThread()) wxMutexGuiEnter();
tomwalters@397 224 #endif
tomwalters@398 225 }
tomwalters@398 226 inline ~AimwxGuiLocker() {
tomwalters@397 227 #ifndef _WINDOWS
tomwalters@398 228 if (!wxIsMainThread()) wxMutexGuiLeave();
tomwalters@397 229 #endif
tomwalters@398 230 }
tomwalters@398 231 };
tomwalters@397 232 DECLARE_EVENT_TABLE()
tomwalters@397 233 };
tomwalters@397 234 #endif /* __GRAPHICS_OUTPUT_DEVICE_GL_CANVAS_H__ */