comparison trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevicewxGLCanvas.h @ 397:7a573750b186

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