Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlGraphics/OpenGLContext.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2011, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef OpenGLContext_INCLUDE_ONCE
00033 #define OpenGLContext_INCLUDE_ONCE
00034 
00035 #include <vlCore/Object.hpp>
00036 #include <vlGraphics/UIEventListener.hpp>
00037 #include <vlGraphics/FramebufferObject.hpp> // Framebuffer and FramebufferObject
00038 #include <vlGraphics/RenderState.hpp>
00039 #include <vlGraphics/NaryQuickMap.hpp>
00040 #include <vector>
00041 #include <set>
00042 
00043 namespace vl
00044 {
00045   class EnableSet;
00046   class RenderStateSet;
00047   class UniformSet;
00048   class IVertexAttribSet;
00049   class ArrayAbstract;
00050 
00051   //-----------------------------------------------------------------------------
00052   // OpenGLContextFormat
00053   //-----------------------------------------------------------------------------
00055   class OpenGLContextFormat
00056   {
00057   public:
00058     OpenGLContextFormat():
00059       mRGBABits(ivec4(8,8,8,8)),
00060       mAccumRGBABits(ivec4(0,0,0,0)),
00061       mHasDoubleBuffer(true),
00062       mZBufferBits(24),
00063       mStencilBufferBits(8),
00064       mHasMultisample(false),
00065       mMultisampleSamples(16),
00066       mStereo(false),
00067       mFullscreen(false),
00068       mVSync(false),
00069       mContextClientVersion(1) {}
00070 
00071     void setRGBABits(int r, int g, int b, int a) { mRGBABits = ivec4(r,g,b,a); }
00072     void setAccumRGBABits(int r, int g, int b, int a) { mAccumRGBABits = ivec4(r,g,b,a); }
00073     void setDoubleBuffer(bool double_buffer_on) { mHasDoubleBuffer = double_buffer_on; }
00074     void setDepthBufferBits(int bits) { mZBufferBits = bits; }
00075     void setStencilBufferBits(int bits) { mStencilBufferBits = bits; }
00076     void setMultisample(bool multisample_on) { mHasMultisample = multisample_on; }
00077     void setMultisampleSamples(int samples) { mMultisampleSamples = samples; }
00078     void setStereo(bool stereo_on) { mStereo = stereo_on; }
00079     void setFullscreen(bool fullscreent) { mFullscreen = fullscreent; }
00080     void setVSync(bool vsync_on) { mVSync = vsync_on; }
00082     void setContextClientVersion(int version) { mContextClientVersion = version; }
00083 
00084     const ivec4& rgbaBits() const { return mRGBABits; }
00085     const ivec4& accumRGBABits() const { return mAccumRGBABits; }
00086     bool doubleBuffer() const { return mHasDoubleBuffer; }
00087     int depthBufferBits() const { return mZBufferBits; }
00088     int stencilBufferBits() const { return mStencilBufferBits; }
00089     bool multisample() const { return mHasMultisample; }
00090     int multisampleSamples() const { return mMultisampleSamples; }
00091     bool stereo() const { return mStereo; }
00092     bool fullscreen() const { return mFullscreen; }
00093     bool vSync() const { return mVSync; }
00095     int contextClientVersion() const { return mContextClientVersion; }
00096 
00098     int bitsPerPixel() const { return rgbaBits().r() + rgbaBits().g() + rgbaBits().b() + rgbaBits().a(); }
00099 
00100   protected:
00101     ivec4 mRGBABits;
00102     ivec4 mAccumRGBABits;
00103     bool mHasDoubleBuffer;
00104     int mZBufferBits;
00105     int mStencilBufferBits;
00106     bool mHasMultisample;
00107     int mMultisampleSamples;
00108     bool mStereo;
00109     bool mFullscreen;
00110     bool mVSync;
00111     int mContextClientVersion;
00112   };
00113   //-----------------------------------------------------------------------------
00114   // OpenGLContext
00115   //-----------------------------------------------------------------------------
00127   class VLGRAPHICS_EXPORT OpenGLContext: public Object
00128   {
00129     VL_INSTRUMENT_ABSTRACT_CLASS(vl::OpenGLContext, Object)
00130     friend class VertexAttrib;
00131     friend class Color;
00132     friend class SecondaryColor;
00133     friend class Normal;
00134 
00135   public:
00137     OpenGLContext(int w=0, int h=0);
00138 
00140     ~OpenGLContext();
00141 
00143     virtual void swapBuffers() = 0;
00144 
00146     virtual void makeCurrent() = 0;
00147 
00149     bool initGLContext(bool log=true);
00150 
00152     void logOpenGLInfo();
00153 
00155     const std::string& extensions() const { return mExtensions; }
00156     
00159     bool isExtensionSupported(const char* ext_name);
00160 
00162     void* getProcAddress(const char* function_name);
00163 
00167     Framebuffer* leftFramebuffer() { return mLeftFramebuffer.get(); }
00168     
00172     const Framebuffer* leftFramebuffer() const { return mLeftFramebuffer.get(); }
00173 
00177     Framebuffer* rightFramebuffer() { return mRightFramebuffer.get(); }
00178     
00182     const Framebuffer* rightFramebuffer() const { return mRightFramebuffer.get(); }
00183 
00186     Framebuffer* framebuffer() { return leftFramebuffer(); }
00187 
00190     const Framebuffer* framebuffer() const { return leftFramebuffer(); }
00191 
00193     ref<FramebufferObject> createFramebufferObject() { return createFramebufferObject(0,0); }
00194 
00197     ref<FramebufferObject> createFramebufferObject(int width, int height, 
00198       EReadDrawBuffer draw_buffer=RDB_COLOR_ATTACHMENT0, 
00199       EReadDrawBuffer read_buffer=RDB_COLOR_ATTACHMENT0);
00200 
00202     void destroyFramebufferObject(FramebufferObject* fbort);
00203 
00205     void destroyAllFramebufferObjects();
00206 
00208     virtual void quitApplication() {}
00209 
00211     virtual void update() = 0;
00212 
00214     virtual void setWindowTitle(const String&) {}
00215 
00217     virtual bool setFullscreen(bool) { mFullscreen = false; return false; }
00218 
00220     virtual bool fullscreen() const { return mFullscreen; }
00221 
00223     virtual void show() {}
00224 
00226     virtual void hide() {}
00227 
00229     virtual void setPosition(int /*x*/, int /*y*/) {}
00230 
00232     virtual ivec2 position() const { return ivec2(); }
00233 
00235     virtual void setSize(int /*w*/, int /*h*/) {}
00236 
00238     int width() const { return framebuffer()->width(); }
00239     
00241     int height() const { return framebuffer()->height(); }
00242 
00244     virtual void setMouseVisible(bool) { mMouseVisible=false; }
00245 
00247     virtual bool mouseVisible() const { return mMouseVisible; }
00248 
00250     virtual void setMousePosition(int /*x*/, int /*y*/) {}
00251 
00253     virtual void getFocus() {}
00254 
00256     void setVSyncEnabled(bool enable);
00257 
00259     bool vsyncEnabled() const;
00260 
00262     virtual void setContinuousUpdate(bool continuous) { mContinuousUpdate = continuous; }
00263 
00265     bool continuousUpdate() const { return mContinuousUpdate; }
00266 
00270     void addEventListener(UIEventListener* el);
00271     
00273     void removeEventListener(UIEventListener* el);
00274     
00276     void eraseAllEventListeners();
00277     
00279     const std::vector< ref<UIEventListener> >& eventListeners() const { return mEventListeners; }
00280     
00282     const UIEventListener* eventListener(int i) const { return mEventListeners[i].get(); }
00283     
00285     UIEventListener* eventListener(int i) { return mEventListeners[i].get(); }
00286     
00288     int eventListenerCount() const { return (int)mEventListeners.size(); }
00289 
00291     const OpenGLContextFormat& openglContextInfo() const { return mGLContextInfo; }
00292     
00294     void setOpenGLContextInfo(const OpenGLContextFormat& info) { mGLContextInfo = info; }
00295 
00297     void ignoreNextMouseMoveEvent() { mIgnoreNextMouseMoveEvent = true; }
00298 
00301     void dispatchResizeEvent(int w, int h) 
00302     {
00303       makeCurrent();
00304       leftFramebuffer()->setWidth(w);
00305       leftFramebuffer()->setHeight(h);
00306       rightFramebuffer()->setWidth(w);
00307       rightFramebuffer()->setHeight(h);
00308 
00309       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00310       for( unsigned i=0; i<temp_clients.size(); ++i )
00311         if ( temp_clients[i]->isEnabled() )
00312           temp_clients[i]->resizeEvent( w, h );
00313     }
00314 
00316     void dispatchMouseMoveEvent(int x, int y)
00317     {
00318       makeCurrent();
00319       if (mIgnoreNextMouseMoveEvent)
00320         mIgnoreNextMouseMoveEvent = false;
00321       else
00322       {
00323         std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00324         for( unsigned i=0; i<temp_clients.size(); ++i )
00325           if ( temp_clients[i]->isEnabled() )
00326             temp_clients[i]->mouseMoveEvent(x, y);
00327       }
00328     }
00329     
00331     void dispatchMouseUpEvent(EMouseButton button, int x, int y) 
00332     {
00333       makeCurrent();
00334       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00335       for( unsigned i=0; i<temp_clients.size(); ++i )
00336         if ( temp_clients[i]->isEnabled() )
00337           temp_clients[i]->mouseUpEvent(button, x, y);
00338     }
00339     
00341     void dispatchMouseDownEvent(EMouseButton button, int x, int y) 
00342     {
00343       makeCurrent();
00344       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00345       for( unsigned i=0; i<temp_clients.size(); ++i )
00346         if ( temp_clients[i]->isEnabled() )
00347           temp_clients[i]->mouseDownEvent(button, x, y);
00348     }
00349     
00351     void dispatchMouseWheelEvent(int n) 
00352     {
00353       makeCurrent();
00354       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00355       for( unsigned i=0; i<temp_clients.size(); ++i )
00356         if ( temp_clients[i]->isEnabled() )
00357           temp_clients[i]->mouseWheelEvent(n);
00358     }
00359     
00361     void dispatchKeyPressEvent(unsigned short unicode_ch, EKey key) 
00362     {
00363       makeCurrent();
00364       keyPress(key);
00365       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00366       for( unsigned i=0; i<temp_clients.size(); ++i )
00367         if ( temp_clients[i]->isEnabled() )
00368           temp_clients[i]->keyPressEvent(unicode_ch, key);
00369     }
00370     
00372     void dispatchKeyReleaseEvent(unsigned short unicode_ch, EKey key) 
00373     {
00374       makeCurrent();
00375       keyRelease(key);
00376       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00377       for( unsigned i=0; i<temp_clients.size(); ++i )
00378         if ( temp_clients[i]->isEnabled() )
00379           temp_clients[i]->keyReleaseEvent(unicode_ch, key);
00380     }
00381 
00385     void dispatchDestroyEvent()
00386     {
00387       makeCurrent();
00388       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00389       for( unsigned i=0; i<temp_clients.size(); ++i )
00390         if ( temp_clients[i]->isEnabled() )
00391           temp_clients[i]->destroyEvent();
00392       destroyAllFramebufferObjects();
00393       eraseAllEventListeners();
00394     }
00395 
00397     void dispatchRunEvent()
00398     {
00399       makeCurrent();
00400       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00401       for( unsigned i=0; i<temp_clients.size(); ++i )
00402         if ( temp_clients[i]->isEnabled() )
00403           temp_clients[i]->updateEvent();
00404     }
00405 
00407     void dispatchVisibilityEvent(bool visible) 
00408     {
00409       makeCurrent();
00410       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00411       for( unsigned i=0; i<temp_clients.size(); ++i )
00412         if ( temp_clients[i]->isEnabled() )
00413           temp_clients[i]->visibilityEvent(visible);
00414     }
00415 
00417     // - called as soon as the OpenGL context is available but before the first resize event
00418     // - when initEvent() is called all the supported OpenGL extensions are already available
00419     // - when initEvent() is called the window has already acquired its width and height
00420     // - only the enabled event listeners receive this message
00421     void dispatchInitEvent()
00422     {
00423       makeCurrent();
00424       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00425       for( unsigned i=0; i<temp_clients.size(); ++i )
00426         if ( temp_clients[i]->isEnabled() )
00427           temp_clients[i]->initEvent();
00428     }
00429 
00431     void dispatchFileDroppedEvent(const std::vector<String>& files)
00432     {
00433       makeCurrent();
00434       std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00435       for( unsigned i=0; i<temp_clients.size(); ++i )
00436         if ( temp_clients[i]->isEnabled() )
00437           temp_clients[i]->fileDroppedEvent(files);
00438     }
00439     
00441     const std::set<EKey>& keyboard() const { return mKeyboard; }
00442 
00444     bool isKeyPressed(EKey key) const { return mKeyboard.find(key) != mKeyboard.end(); }
00445 
00447     void keyPress(EKey key) { mKeyboard.insert(key); }
00448 
00450     void keyRelease(EKey key) { mKeyboard.erase(key); }
00451 
00453     bool isInitialized() const { return mIsInitialized; }
00454 
00456     int textureUnitCount() const { return mTextureSamplerCount; }
00457 
00459     bool hasDoubleBuffer() const { return mHasDoubleBuffer; }
00460 
00461     // --- render states management ---
00462 
00468     void bindVAS(const IVertexAttribSet* vas, bool use_vbo, bool force);
00469 
00471     void applyEnables( const EnableSet* cur );
00472 
00474     void applyRenderStates( const RenderStateSet* cur, const Camera* camera );
00475 
00477     void resetEnables();
00478 
00480     void resetRenderStates();
00481 
00483     void setDefaultRenderState(const RenderStateSlot& rs_slot) 
00484     { 
00485       mDefaultRenderStates[rs_slot.type()] = rs_slot; 
00486       // if we are in the default render state then apply it immediately
00487       if (!mCurrentRenderStateSet->hasKey(rs_slot.type()))
00488       {
00489         mDefaultRenderStates[rs_slot.type()].apply(NULL, this); VL_CHECK_OGL();
00490       }
00491     }
00492 
00494     const RenderStateSlot& defaultRenderState(ERenderState rs) { return mDefaultRenderStates[rs]; }
00495 
00497     void resetContextStates(EResetContextStates start_or_finish);
00498 
00500     void setTexUnitBinding(int unit_i, ETextureDimension target) 
00501     { 
00502       VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00503       mTexUnitBinding[unit_i] = target; 
00504     }
00505 
00507     ETextureDimension texUnitBinding(int unit_i) const
00508     {
00509       VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00510       return mTexUnitBinding[unit_i]; 
00511     }
00512 
00514     static bool areUniformsColliding(const UniformSet* u1, const UniformSet* u2);
00515 
00534     bool isCleanState(bool verbose);
00535 
00536   public:
00537     // constant color
00538     const fvec3& normal() const { return mNormal; }
00539     const fvec4& color() const { return mColor; }
00540     const fvec3& secondaryColor() const { return mSecondaryColor; }
00541     const fvec4& vertexAttribValue(int i) const { VL_CHECK(i<VL_MAX_GENERIC_VERTEX_ATTRIB); return mVertexAttribValue[i]; }
00542 
00543   protected:
00544     ref<Framebuffer> mLeftFramebuffer;
00545     ref<Framebuffer> mRightFramebuffer;
00546     std::vector< ref<FramebufferObject> > mFramebufferObject;
00547     std::vector< ref<UIEventListener> > mEventListeners;
00548     std::set<EKey> mKeyboard;
00549     OpenGLContextFormat mGLContextInfo;
00550     int mMaxVertexAttrib;
00551     int mTextureSamplerCount;
00552     bool mMouseVisible;
00553     bool mContinuousUpdate;
00554     bool mIgnoreNextMouseMoveEvent;
00555     bool mFullscreen;
00556     bool mHasDoubleBuffer;
00557     bool mIsInitialized;
00558     std::string mExtensions;
00559 
00560     // --- Render States ---
00561   
00562     // default render states
00563     RenderStateSlot mDefaultRenderStates[RS_RenderStateCount];
00564 
00565     // applyEnables()
00566     ref< NaryQuickMap<EEnable, EEnable, EN_EnableCount> > mCurrentEnableSet;
00567     ref< NaryQuickMap<EEnable, EEnable, EN_EnableCount> > mNewEnableSet;
00568 
00569     // applyRenderStates()
00570     ref< NaryQuickMap<ERenderState, RenderStateSlot, RS_RenderStateCount> > mCurrentRenderStateSet;
00571     ref< NaryQuickMap<ERenderState, RenderStateSlot, RS_RenderStateCount> > mNewRenderStateSet;
00572 
00573     // for each texture unit tells which target has been bound last.
00574     ETextureDimension mTexUnitBinding[VL_MAX_TEXTURE_UNITS];
00575 
00576   private:
00577     struct VertexArrayInfo
00578     {
00579       VertexArrayInfo(): mBufferObject(0), mPtr(0), mState(0), mEnabled(false) {}
00580       int   mBufferObject;
00581       const unsigned char* mPtr;
00582       int mState;
00583       bool mEnabled;
00584     };
00585 
00586   protected:
00587     // --- VertexAttribSet Management ---
00588     const IVertexAttribSet* mCurVAS;
00589     VertexArrayInfo mVertexArray;
00590     VertexArrayInfo mNormalArray;
00591     VertexArrayInfo mColorArray;
00592     VertexArrayInfo mSecondaryColorArray;
00593     VertexArrayInfo mFogArray;
00594     VertexArrayInfo mTexCoordArray[VL_MAX_TEXTURE_UNITS];
00595     VertexArrayInfo mVertexAttrib[VL_MAX_GENERIC_VERTEX_ATTRIB];
00596 
00597     // save and restore constant attributes
00598     fvec3 mNormal;
00599     fvec4 mColor;
00600     fvec3 mSecondaryColor;
00601     fvec4 mVertexAttribValue[VL_MAX_GENERIC_VERTEX_ATTRIB];
00602 
00603   private:
00604     void setupDefaultRenderStates();
00605   };
00606   // ----------------------------------------------------------------------------
00607 }
00608 
00609 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:38.
Permission is granted to use this page to write and publish articles regarding Visualization Library.