/**************************************************************************************/ /* */ /* Visualization Library */ /* http://visualizationlibrary.org */ /* */ /* Copyright (c) 2005-2020, Michele Bosi */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or without modification, */ /* are permitted provided that the following conditions are met: */ /* */ /* - Redistributions of source code must retain the above copyright notice, this */ /* list of conditions and the following disclaimer. */ /* */ /* - Redistributions in binary form must reproduce the above copyright notice, this */ /* list of conditions and the following disclaimer in the documentation and/or */ /* other materials provided with the distribution. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */ /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */ /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /**************************************************************************************/ #ifndef OpenGLContext_INCLUDE_ONCE #define OpenGLContext_INCLUDE_ONCE #include #include #include // Framebuffer and FramebufferObject #include #include #include #include #include namespace vl { class EnableSet; class RenderStateSet; class UniformSet; class IVertexAttribSet; class ArrayAbstract; //----------------------------------------------------------------------------- // OpenGLContextFormat //----------------------------------------------------------------------------- //! The OpenGLContextFormat class encapsulates the settings of an OpenGL rendering context. class OpenGLContextFormat { public: OpenGLContextFormat(): mRGBABits(ivec4(8,8,8,0)), mAccumRGBABits(ivec4(0,0,0,0)), mZBufferBits(24), mStencilBufferBits(8), mMultisampleSamples(16), mContextClientVersion(1), mMajVersion(0), mMinVersion(0), mHasDoubleBuffer(true), mHasMultisample(false), mStereo(false), mFullscreen(false), mVSync(false), mProfile(GLP_Compatibility) {} void setRGBABits(int r, int g, int b, int a) { mRGBABits = ivec4(r,g,b,a); } void setAccumRGBABits(int r, int g, int b, int a) { mAccumRGBABits = ivec4(r,g,b,a); } void setDoubleBuffer(bool double_buffer_on) { mHasDoubleBuffer = double_buffer_on; } void setDepthBufferBits(int bits) { mZBufferBits = bits; } void setStencilBufferBits(int bits) { mStencilBufferBits = bits; } void setMultisample(bool multisample_on) { mHasMultisample = multisample_on; } void setMultisampleSamples(int samples) { mMultisampleSamples = samples; } void setStereo(bool stereo_on) { mStereo = stereo_on; } void setFullscreen(bool fullscreent) { mFullscreen = fullscreent; } void setVSync(bool vsync_on) { mVSync = vsync_on; } //! Used by EGLWindow to initialize either GLES 1.x or GLES 2.x contexts. void setContextClientVersion(int version) { mContextClientVersion = version; } const ivec4& rgbaBits() const { return mRGBABits; } const ivec4& accumRGBABits() const { return mAccumRGBABits; } bool doubleBuffer() const { return mHasDoubleBuffer; } int depthBufferBits() const { return mZBufferBits; } int stencilBufferBits() const { return mStencilBufferBits; } bool multisample() const { return mHasMultisample; } int multisampleSamples() const { return mMultisampleSamples; } bool stereo() const { return mStereo; } bool fullscreen() const { return mFullscreen; } bool vSync() const { return mVSync; } //! Used by EGLWindow to initialize either GLES 1.x or GLES 2.x contexts. int contextClientVersion() const { return mContextClientVersion; } //! Returns rgbaBits().r() + rgbaBits().g() + rgbaBits().b() + rgbaBits().a() int bitsPerPixel() const { return rgbaBits().r() + rgbaBits().g() + rgbaBits().b() + rgbaBits().a(); } //! The OpenGL profile you'd like to access. //! When using vl::GLP_Compatibility or vl::GLP_Core you must also specify a min/maj version using setVersion() which defaults to 3.3 or a compatible higher version. void setOpenGLProfile(EOpenGLProfile p) { mProfile = p; } EOpenGLProfile openGLProfile() const { return mProfile; } //! Sets the OpenGL version you want to access when using vl::GLP_Compatibility or vl::GLP_Core profiles (default is 3.3 which will yield also any compatible higher version). void setVersion( int majv, int minv ) { mMajVersion = majv; mMinVersion = minv; } int majVersion() const { return mMajVersion; } int minVersion() const { return mMinVersion; } protected: ivec4 mRGBABits; ivec4 mAccumRGBABits; int mZBufferBits; int mStencilBufferBits; int mMultisampleSamples; int mContextClientVersion; int mMajVersion; int mMinVersion; bool mHasDoubleBuffer; bool mHasMultisample; bool mStereo; bool mFullscreen; bool mVSync; EOpenGLProfile mProfile; }; //----------------------------------------------------------------------------- // OpenGLContext //----------------------------------------------------------------------------- //! Represents an OpenGL context, possibly a widget or a pbuffer, which can also respond to keyboard, mouse or system events. //! //! OpenGLContext is an abstract class that wraps a minimal common subset of GUI APIs like Win32, Qt, wxWidgets, SDL, GLUT, etc. \n //! In order to respond to the events generated by the OpenGLContext you must subclass an UIEventListener and bind it to the OpenGLContext //! using the functions addEventListener(ref) and removeEventListener(ref). //! //! \par OpenGLContext Custom Implementation //! - Key_Alt/Ctrl/Shift events must always be notified before Key_Left/Right-Alt/Ctrl/Shift events. //! - Always update the mKeyboard structure appropriately especially with respect to Key_[Left/Right]-Alt/Ctrl/Shift events. //! - When cycling through EventListeners to dispatch the events you must do it on a temporary copy of mEventListeners so that //! the EventListeners can safely add/remove themselves or other EventListeners to the OpenGLContext itself. */ class VLGRAPHICS_EXPORT OpenGLContext: public Object { VL_INSTRUMENT_ABSTRACT_CLASS(vl::OpenGLContext, Object) friend class VertexAttrib; friend class Color; friend class SecondaryColor; friend class Normal; public: //! Constructor. OpenGLContext(int w=0, int h=0); //! Destructor. ~OpenGLContext(); //! Swaps the back and front buffers to present the last rendering. virtual void swapBuffers() = 0; //! Sets the OpenGL context as current for the calling thread. virtual void makeCurrent() = 0; //! Initializes the supported OpenGL extensions. bool initGLContext(bool log=true); //! Logs some information about the OpenGL context void logOpenGLInfo(); //! Returns the list of OpenGL extensions supported separated by '|' characters. const std::string& extensions() const { return mExtensions; } //! Returns true if the given extension is supported. //! \note This is a relatively slow function, don't use it inside loops and similar. bool isExtensionSupported(const char* ext_name); //! Returns the address of an OpenGL extension function void* getProcAddress(const char* function_name); //! The render target representing the default left framebuffer. //! It's basically just a Framebuffer with both draw-buffer and read-buffer set to RDB_BACK_LEFT by default. //! The returned Framebuffer's dimensions will be automatically updated to the OpenGLContext's dimensions. Framebuffer* leftFramebuffer() { return mLeftFramebuffer.get(); } //! The render target representing the default left framebuffer. //! It's basically just a Framebuffer with both draw-buffer and read-buffer set to RDB_BACK_LEFT by default. //! The returned Framebuffer's dimensions will be automatically updated to the OpenGLContext's dimensions. const Framebuffer* leftFramebuffer() const { return mLeftFramebuffer.get(); } //! The render target representing the default right framebuffer (if a stereo OpenGL context is present). //! It's basically just a Framebuffer with both draw-buffer and read-buffer set to RDB_BACK_RIGHT by default. //! The returned Framebuffer's dimensions will be automatically updated to the OpenGLContext's dimensions. Framebuffer* rightFramebuffer() { return mRightFramebuffer.get(); } //! The render target representing the default right framebuffer (if a stereo OpenGL context is present). //! It's basically just a Framebuffer with both draw-buffer and read-buffer set to RDB_BACK_RIGHT by default. //! The returned Framebuffer's dimensions will be automatically updated to the OpenGLContext's dimensions. const Framebuffer* rightFramebuffer() const { return mRightFramebuffer.get(); } //! The default render target (always returns leftFramebuffer()). //! The returned Framebuffer's dimensions will be automatically updated to the OpenGLContext's dimensions. Framebuffer* framebuffer() { return leftFramebuffer(); } //! The default render target (always returns leftFramebuffer()). //! The returned Framebuffer's dimensions will be automatically updated to the OpenGLContext's dimensions. const Framebuffer* framebuffer() const { return leftFramebuffer(); } //! Equivalent to \p "createFramebufferObject(0,0);". ref createFramebufferObject() { return createFramebufferObject(0,0); } //! Creates a new FramebufferObject (framebuffer object Framebuffer). //! \note A framebuffer object always belongs to an OpenGL context and in order to render on it the appropriate OpenGL context must be active. ref createFramebufferObject(int width, int height, EReadDrawBuffer draw_buffer=RDB_COLOR_ATTACHMENT0, EReadDrawBuffer read_buffer=RDB_COLOR_ATTACHMENT0); //! Destroys the specified FramebufferObject. void destroyFramebufferObject(FramebufferObject* fbort); //! Removes all FramebufferObjects belonging to an OpenGLContext. void destroyAllFramebufferObjects(); //! Removes all OpenGL resources handled by the OpenGLContext. void destroyAllOpenGLResources(); //! Asks to the windowing system that is managing the OpenGLContext to quit the application. virtual void quitApplication() {} //! If the OpenGLContext is a widget this function requests a redraw and generates an updateEvent(). virtual void update() = 0; //! If the OpenGL context is a top window this function sets its title. virtual void setWindowTitle(const String&) {} //! If the OpenGL context is a widget this function requests a maximization to fullscreen. virtual bool setFullscreen(bool) { mFullscreen = false; return false; } //! If the OpenGL context is a widget this function returns whether it has been maximized to fullscreen. virtual bool fullscreen() const { return mFullscreen; } //! If the OpenGL context is a widget this function makes it visible to the user. virtual void show() {} //! If the OpenGL context is a widget this function makes it invisible to the user. virtual void hide() {} //! If the OpenGL context is a widget this function sets its position. virtual void setPosition(int /*x*/, int /*y*/) {} //! If the OpenGL context is a widget this function returns its position. virtual ivec2 position() const { return ivec2(); } //! If the OpenGL context is a widget this function sets its size. virtual void setSize(int /*w*/, int /*h*/) {} //! Returns the width in pixels of an OpenGLContext. int width() const { return framebuffer()->width(); } //! Returns the height in pixels of an OpenGLContext. int height() const { return framebuffer()->height(); } //! If the OpenGL context is a widget this function sets whether the mouse is visible over it or not. virtual void setMouseVisible(bool) { mMouseVisible=false; } //! If the OpenGL context is a widget this function returns whether the mouse is visible over it or not. virtual bool mouseVisible() const { return mMouseVisible; } //! If the OpenGL context is a widget this function sets the mouse position. virtual void setMousePosition(int /*x*/, int /*y*/) {} //! If the OpenGL context is a widget this function requests the mouse focus on it. virtual void getFocus() {} //! If the OpenGL context is a widget this function enabled/disables double buffer swapping to the monitor's vertical synch. void setVSyncEnabled(bool enable); //! If the OpenGL context is a widget this function returns whether vsync is enabled or not. bool vsyncEnabled() const; //! If the OpenGL context is a widget this function sets whether its area is continuously updated at each frame. virtual void setContinuousUpdate(bool continuous) { mContinuousUpdate = continuous; } //! If the OpenGL context is a widget this function returns whether its area is continuously updated at each frame. bool continuousUpdate() const { return mContinuousUpdate; } //! Adds an UIEventListener to be notified of OpenGLContext related events. //! This method triggers immediately an UIEventListener::addedListenerEvent() and if the OpenGLContext is initialized also an UIEventListener::initEvent(). //! \note An \p UIEventListener can be associated only to one OpenGLContext at a time. void addEventListener(UIEventListener* el); //! Removes an UIEventListener void removeEventListener(UIEventListener* el); //! Removes all UIEventListener previously registered void eraseAllEventListeners(); //! The currently UIEventListener registered to be notified of OpenGLContext related events. const std::vector< ref >& eventListeners() const { return mEventListeners; } //! Returns the \p i-th UIEventListener registered to an OpenGLContext. const UIEventListener* eventListener(int i) const { return mEventListeners[i].get(); } //! Returns the \p i-th UIEventListener registered to an OpenGLContext. UIEventListener* eventListener(int i) { return mEventListeners[i].get(); } //! Returns the number of UIEventListener registered to an OpenGLContext. int eventListenerCount() const { return (int)mEventListeners.size(); } //! Returns an OpenGLContextFormat structure describing an OpenGLContext. const OpenGLContextFormat& openglContextInfo() const { return mGLContextInfo; } //! Sets the OpenGLContextFormat associated to an OpenGLContext. void setOpenGLContextInfo(const OpenGLContextFormat& info) { mGLContextInfo = info; } //! Requests not to dispatch the next mouse move event. void ignoreNextMouseMoveEvent() { mIgnoreNextMouseMoveEvent = true; } //! Dispatches the UIEventListener::resizeEvent() notification to the subscribed UIEventListener objects. //! Call this function at the beginning if you reimplement it void dispatchResizeEvent(int w, int h) { makeCurrent(); leftFramebuffer()->setWidth(w); leftFramebuffer()->setHeight(h); rightFramebuffer()->setWidth(w); rightFramebuffer()->setHeight(h); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->resizeEvent( w, h ); } //! Dispatches the UIEventListener::mouseMoveEvent() notification to the subscribed UIEventListener objects. void dispatchMouseMoveEvent(int x, int y) { makeCurrent(); if (mIgnoreNextMouseMoveEvent) mIgnoreNextMouseMoveEvent = false; else { std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->mouseMoveEvent(x, y); } } //! Dispatches the UIEventListener::mouseUpEvent() notification to the subscribed UIEventListener objects. void dispatchMouseUpEvent(EMouseButton button, int x, int y) { makeCurrent(); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->mouseUpEvent(button, x, y); } //! Dispatches the UIEventListener::mouseDownEvent() notification to the subscribed UIEventListener objects. void dispatchMouseDownEvent(EMouseButton button, int x, int y) { makeCurrent(); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->mouseDownEvent(button, x, y); } //! Dispatches the UIEventListener::mouseWheelEvent() notification to the subscribed UIEventListener objects. void dispatchMouseWheelEvent(int n) { makeCurrent(); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->mouseWheelEvent(n); } //! Dispatches the UIEventListener::keyPressEvent() notification to the subscribed UIEventListener objects. void dispatchKeyPressEvent(unsigned short unicode_ch, EKey key) { makeCurrent(); keyPress(key); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->keyPressEvent(unicode_ch, key); } //! Dispatches the UIEventListener::keyReleaseEvent() notification to the subscribed UIEventListener objects. void dispatchKeyReleaseEvent(unsigned short unicode_ch, EKey key) { makeCurrent(); keyRelease(key); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->keyReleaseEvent(unicode_ch, key); } //! Dispatches the UIEventListener::destroyEvent() notification to the subscribed UIEventListener(s), //! calls destroyAllOpenGLResources() and eraseAllEventListeners() //! This event must be issued just before the actual GL context is destroyed. void dispatchDestroyEvent() { makeCurrent(); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->destroyEvent(); destroyAllOpenGLResources(); eraseAllEventListeners(); } //! Dispatches the UIEventListener::updateEvent() notification to the subscribed UIEventListener objects. void dispatchUpdateEvent() { makeCurrent(); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->updateEvent(); } //! Dispatches the UIEventListener::visibilityEvent() notification to the subscribed UIEventListener objects. void dispatchVisibilityEvent(bool visible) { makeCurrent(); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->visibilityEvent(visible); } //! Dispatches the UIEventListener::initEvent() notification to the subscribed UIEventListener objects. // - called as soon as the OpenGL context is available but before the first resize event // - when initEvent() is called all the supported OpenGL extensions are already available // - when initEvent() is called the window has already acquired its width and height // - only the enabled event listeners receive this message void dispatchInitEvent() { makeCurrent(); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->initEvent(); } //! Dispatches the UIEventListener::fileDroppedEvent() notification to the subscribed UIEventListener objects. void dispatchFileDroppedEvent(const std::vector& files) { makeCurrent(); std::vector< ref > temp_clients = eventListeners(); for( unsigned i=0; iisEnabled() ) temp_clients[i]->fileDroppedEvent(files); } //! Returns the std::set containing the currently pressed keys. const std::set& keyboard() const { return mKeyboard; } //! Returns true if the given key is pressed. bool isKeyPressed(EKey key) const { return mKeyboard.find(key) != mKeyboard.end(); } //! Inserts the specified key in the set of currently active keys - For internal use only. void keyPress(EKey key) { mKeyboard.insert(key); } //! Removes the specified key from the set of currently active keys - For internal use only. void keyRelease(EKey key) { mKeyboard.erase(key); } //! Returns true if the OpenGLContext is in an initialized state. bool isInitialized() const { return mIsInitialized; } //! The number (clamped to VA_MaxAttribCount) of generic vertex attributes as returned by glGet(GL_MAX_VERTEX_ATTRIBS) int vertexAttribCount() const { return mVertexAttribCount; } //! The number (clamped to VL_MAX_TEXTURE_IMAGE_UNITS) of texture image units supported by the current hardware. int textureImageUnitCount() const { return mTextureImageUnitCount; } //! The number (clamped to VL_MAX_LEGACY_TEXTURE_UNITS) of fixed function pipeline texture units supported by the current hardware. //! This is the number of texture units that support vl::TexEnv, vl::TexGen, vl::TextureMatrix and glClientActiveTexture(). int textureCoordCount() const { return mTextureCoordCount; } //! Returns \p true if an OpenGLContext supports double buffering. bool hasDoubleBuffer() const { return mHasDoubleBuffer; } // --- render states management --- //! Activates the given GLSLProgram or unbinds the current one if `glsl` is NULL. void useGLSLProgram(const GLSLProgram* glsl); //! Activates the specified vertex attribute set - For internal use only. //! \param vas The IVertexAttribSet to be activated. It can be NULL, in which case all vertex attributes are disabled. //! If \p vas is the same as the last activated IVertexAttribSet then no operation is done. //! \param use_vbo Whether vertex-buffer-objects should be used when activating the vertex attributes. //! \param force Binds \p vas even if it was the last to be activated (this is also valid for NULL). void bindVAS(const IVertexAttribSet* vas, bool use_vbo, bool force); void bindVAS_Attribs(const IVertexAttribSet* vas, bool use_vbo); void bindVAS_Fixed(const IVertexAttribSet* vas, bool use_vbo); void bindVAS_Reset(); //! Applies an EnableSet to an OpenGLContext - Typically for internal use only. void applyEnables( const EnableSet* cur ); //! Applies a RenderStateSet to an OpenGLContext - Typically for internal use only. void applyRenderStates( const RenderStateSet* cur, const Camera* camera ); //! Resets all the interanal enable-tables - For internal use only. void resetEnables(); //! Resets all the interanal render-states-tables - For internal use only. void resetRenderStates(); //! Defines the default render state slot to be used by the opengl context. void setDefaultRenderState(const RenderStateSlot& rs_slot) { mDefaultRenderStates[rs_slot.type()] = rs_slot; // if we are in the default render state then apply it immediately if (!mCurrentRenderStateSet->hasKey(rs_slot.type())) { mDefaultRenderStates[rs_slot.type()].apply(NULL, this); VL_CHECK_OGL(); } } //! Returns the default render state slot used by VL when a specific render state type is left undefined. const RenderStateSlot& defaultRenderState(ERenderState rs) { return mDefaultRenderStates[rs]; } //! Resets the OpenGL states necessary to begin and finish a rendering. - For internal use only. void resetContextStates(EResetContextStates start_or_finish); //! Declares that texture unit \p unit_i is currently bound to the specified texture target. - For internal use only. void setTexUnitBinding(int unit_i, ETextureDimension target) { VL_CHECK(unit_i <= VL_MAX_TEXTURE_IMAGE_UNITS); mTexUnitBinding[unit_i] = target; } //! Returnes the texture target currently active for the specified texture unit. - For internal use only. ETextureDimension texUnitBinding(int unit_i) const { VL_CHECK(unit_i <= VL_MAX_TEXTURE_IMAGE_UNITS); return mTexUnitBinding[unit_i]; } const GLSLProgram* glslProgram() const { return mGLSLProgram.get(); } GLSLProgram* glslProgram() { return mGLSLProgram.get(); } //! Returns \p true if the two UniformSet contain at least one Uniform variable with the same name. static bool areUniformsColliding(const UniformSet* u1, const UniformSet* u2); //! Checks whether the OpenGL state is clean or not. //! \par Clean state conditions: //! - All functionalities must be disabled, no GL_LIGHTING, GL_DEPTH_TEST, GL_LIGHTn, GL_CLIP_PLANEn etc. enabled, //! with the sole exception of GL_MULTISAMPLE and GL_DITHER. //! - All buffer objects targets such as GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER etc. must be bound to buffer object #0. //! - Current texture unit and client texture unit must be #0. //! - All texture matrices must be set to identity. //! - All texture targets must be bound to texture #0. //! - All GL_TEXTURE_COORD_ARRAYs must be disabled. //! - All texture targets such as GL_TEXTURE_1D, GL_TEXTURE_2D etc. must be disabled. //! - All texture targets should be bound to texture #0. //! - All texture coordinate generation modes such as GL_TEXTURE_GEN_S/T/R/Q must be disable for all texture units. //! - All vertex arrays such as GL_COLOR_ARRAY, GL_NORMAL_ARRAY etc. must be disabled, including the ones enabled with glEnableVertexAttribArray() //! - NOTE: blending function must be set to glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). //! - Color write-mask should be glColorMask(GL_TRUE ,GL_TRUE, GL_TRUE, GL_TRUE). //! - Depth write-mask should be glDepthMask(GL_TRUE). //! - Polygon mode should be glPolygonMode(GL_FRONT_AND_BACK, GL_FILL). //! - In general all OpenGL render states should be set to their default values. bool isCleanState(bool verbose); public: // constant color const fvec3& normal() const { return mNormal; } const fvec4& color() const { return mColor; } const fvec3& secondaryColor() const { return mSecondaryColor; } const fvec4& vertexAttribValue(int i) const { VL_CHECK(i mLeftFramebuffer; ref mRightFramebuffer; std::vector< ref > mFramebufferObject; std::vector< ref > mEventListeners; std::set mKeyboard; OpenGLContextFormat mGLContextInfo; int mVertexAttribCount; int mTextureImageUnitCount; int mTextureCoordCount; bool mMouseVisible; bool mContinuousUpdate; bool mIgnoreNextMouseMoveEvent; bool mFullscreen; bool mHasDoubleBuffer; bool mIsInitialized; std::string mExtensions; // --- Render States --- // default render states RenderStateSlot mDefaultRenderStates[RS_RenderStateCount]; // applyEnables() ref< NaryQuickMap > mCurrentEnableSet; ref< NaryQuickMap > mNewEnableSet; // applyRenderStates() ref< NaryQuickMap > mCurrentRenderStateSet; ref< NaryQuickMap > mNewRenderStateSet; // for each texture unit tells which target has been bound last. ETextureDimension mTexUnitBinding[VL_MAX_TEXTURE_IMAGE_UNITS]; // current GLSL ref mGLSLProgram; bool mGLSLUpdated; private: struct VertexArrayInfo { VertexArrayInfo(): mBufferObject(0), mPtr(0), mEnabled(false) {} int mBufferObject; const unsigned char* mPtr; bool mEnabled; }; protected: // --- VertexAttribSet Management --- const IVertexAttribSet* mCurVAS; VertexArrayInfo mVertexArray; VertexArrayInfo mNormalArray; VertexArrayInfo mColorArray; VertexArrayInfo mSecondaryColorArray; VertexArrayInfo mFogArray; VertexArrayInfo mTexCoordArray[VA_MaxTexCoordCount]; VertexArrayInfo mVertexAttrib[VA_MaxAttribCount]; // save and restore constant attributes fvec3 mNormal; fvec4 mColor; fvec3 mSecondaryColor; fvec4 mVertexAttribValue[VA_MaxAttribCount]; GLuint mDefaultVAO; private: void setupDefaultRenderStates(); }; // ---------------------------------------------------------------------------- } #endif