Mercurial > hg > aimc
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/trunk/src/Modules/Output/Graphics/Devices/GraphicsOutputDevicewxGLCanvas.h Fri Oct 15 05:40:53 2010 +0000 @@ -0,0 +1,234 @@ +// Copyright 2006, Willem van Engen +// +// AIM-C: A C++ implementation of the Auditory Image Model +// http://www.acousticscale.org/AIMC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +/*! + * \file + * \brief Output device for output to a wxWidgets OpenGL canvas + * + * \author Willem van Engen <cnbh@willem.engen.nl> + * \date created 2006/09/21 + * \version \$Id: $ + */ + +#ifndef __GRAPHICS_OUTPUT_DEVICE_GL_CANVAS_H__ +#define __GRAPHICS_OUTPUT_DEVICE_GL_CANVAS_H__ + +// Precompiled wxWidgets headers +#include "stdwx.h" + +// Make sure GLCANVAS is compiled into wxWidgets +#if !wxUSE_GLCANVAS +# error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library" +#endif + +#if defined (_MACOSX) +# include <OpenGL/gl.h> +# include <OpenGl/glext.h> +#elif defined (_WINDOWS) +# include <GL/gl.h> +# define GL_GET_PROC_ADDRESS wglGetProcAddress +#else +# include <GL/gl.h> +# define GL_GET_PROC_ADDRESS(x) glXGetProcAddress((const GLubyte*)x) +#endif +/* Define them just ourselves, easiest way to get it working cross-platform + * and -Mesa/OpenGL-version. */ +#ifndef APIENTRY +# define APIENTRY +#endif +typedef void (APIENTRY * LOCAL_PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); +typedef void (APIENTRY * LOCAL_PFNGLUNLOCKARRAYSEXTPROC) (void); + +#ifdef FTGL_SUBDIR +# include <FTGL/FTGLBitmapFont.h> +#else +# include <FTGLBitmapFont.h> +#endif + +#include "Output/GraphicsOutputDevice.h" + +// Use by default +#define WITH_GL_VERTEX_ARRAYS + +/*! + * \class GraphicsOutputDevicewxGLCanvas "Output/GraphicsOutputDevicewxGLCanvas.h" + * \brief Output class for output to a wxWidgets OpenGL canvas + * + * On windows, OpenGL needs a different context when two different threads + * want to issue OpenGL commands. This is handled automatically for two + * wxThread s. + */ +class GraphicsOutputDevicewxGLCanvas : public wxGLCanvas, + public GraphicsOutputDevice { + public: + GraphicsOutputDevicewxGLCanvas(Parameters *pParam, + wxWindow *parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = 0, + const wxString& name + = _T("GraphicsOutputDeviceGLCanvas")); + virtual ~GraphicsOutputDevicewxGLCanvas(); + void OnPaint(wxPaintEvent& event); + void OnSize(wxSizeEvent& event); + void OnEraseBackground(wxEraseEvent& event); + + /*! \param iVerticesMax Maximum number of vertices to be draw inside a gBegin()..gEnd() + * + * When iVerticesMax is zero, this variable will not be updated. Note that is _has_ + * to be set at least once before using this class. + */ + bool Initialize(unsigned int iVerticesMax); + bool Initialize(); + + void Start(); + + void gGrab(); + void gBeginLineStrip(); + void gBeginQuadStrip(); + using GraphicsOutputDevice::gVertex3f; // Because we overload it + void gVertex3f(float x, float y, float z); + void gColor3f(float r, float g, float b); + void gEnd(); + void gText3f(float x, float y, float z, const char *sStr, bool bRotated = false); + void gRelease(); + protected: + /*! \brief Smarter SetCurrent() replacement + * \return true on success, false on error + * + * This function tries GetContext() first. If that fails, it returns false. + */ + bool SetCurrent(); + void Render(); + + /*! \brief Initialize the OpenGL environment. + * + * This must be called after the canvas is realized but before any other + * OpenGL operation is done. Make sure to run SetCurrent() beforehand. + * Usually only needed when m_init is false. + */ + void InitGL(); + + /*! \brief Handle a resize (notify OpenGL of the new area) + * + * This is a separate function, because in multi-threading environments + * multiple contexts have to call it. + */ + void DoResize(); + + /*! \brief Only need to initialize OpenGL once. + * + * This is false at start and true when OpenGL has been initialized. + * No mutex needed, since it's set once at InitGL() and only read afterwards. + */ + bool m_init; + + /*! \brief Vertex list for last drawing so it can be updated on repaint. + * + * No mutex needed, since it's set once at InitGL() and only read afterwards. + */ + GLuint m_gllist; + + //! \brief OpenGL context for worker thread, use when wxIsMainThread() returns false. + wxGLContext *m_pWorkerContext; + + //! \brief Mutex for inter-thread communication + wxMutex s_mutexOpenGL; + + //! \brief When true, OpenGL needs to be reinitialized (in the worker thread) + bool s_bWorkerNeedsInit; + + //! \brief OpenGL attributes used for initialization. + static int GLAttrlist[]; + + //! \brief Whether to use anti-aliasing or not + bool m_bAntialiasing; + + //! \brief FTGL Font class + FTFont *m_pFont; + //! \brief Current font filename + const char *m_sFontFile; + //! \brief Current font size + int m_iFontsize; + +#if defined(WITH_GL_VERTEX_ARRAYS) || defined(DOXYGEN) + //! \brief OpenGL vertex type of the current m_pVertices, or 0xffff is outside gBegin()..gEnd() + int m_iVertexType; + //! \brief Maximum number of vertices begin gBegin()..gEnd() + unsigned int m_iVerticesMax; + //! \brief Vertex array to draw at gEnd(), this becomes m_pVertices[m_iVerticesMax*3] + GLfloat *m_pVertices; + //! \brief The current number of vertices inside m_pVertices + unsigned int m_iVertexCount; + + /*! \brief Whether to use coloring in vertex lists + * + * This variable must not change after Initialize(), or the program may crash. + * When this variable is true, color information is stored in vertex lists. If + * it is false, only vertex data is stored. + * + * This variable exists for performance reasons, but is currently only set in + * the constructor of this object. + */ + bool m_bStaticColor; + //! \brief Current color for vertex list drawing + float m_fCurColorR, m_fCurColorG, m_fCurColorB; + + //! \brief Whether to use vertex array locking or not + bool m_bVertexArrayLock; + //! \brief Pointer to vertex array locking function; can be NULL. + LOCAL_PFNGLLOCKARRAYSEXTPROC m_glLockArraysEXT; + //! \brief Pointer to vertex array unlocking function; can be NULL. + LOCAL_PFNGLUNLOCKARRAYSEXTPROC m_glUnlockArraysEXT; +#endif + + /*! \brief wxMutexGuiEnter() / wxMutexGuiLeave() wrapper + * + * This is a wxMutexLocker-alike for the main gui mutex. Any method that + * is public, can be called from within another thread and does OpenGL or + * other gui calls must use this. Example: + * \code + * void DoFoo() { + * AimwxGuiLocker __lock__; + * glAmazingMethod(); + * } + * \endcode + * + * It is mostly on X-Windows (Xorg/XFree86) that the gui mutex appears to + * be needed. Otherwise the error "Xlib: unexpected async reply" can occur. + * + * On windows, the ui may occasionally lock up for a short while with these + * mutexes. Since they aren't really needed on that platform, it's left out + * alltogether. + */ + class AimwxGuiLocker { + public: + inline AimwxGuiLocker() { +#ifndef _WINDOWS + if (!wxIsMainThread()) wxMutexGuiEnter(); +#endif + } + inline ~AimwxGuiLocker() { +#ifndef _WINDOWS + if (!wxIsMainThread()) wxMutexGuiLeave(); +#endif + } + }; + DECLARE_EVENT_TABLE() +}; +#endif /* __GRAPHICS_OUTPUT_DEVICE_GL_CANVAS_H__ */