00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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>
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
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
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 , int ) {}
00230
00232 virtual ivec2 position() const { return ivec2(); }
00233
00235 virtual void setSize(int , int ) {}
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 , int ) {}
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
00418
00419
00420
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
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 RenderState* defaultRenderState(ERenderState rs) { return mDefaultRenderStates[rs].mRS.get(); }
00484
00486 const RenderState* defaultRenderState(ERenderState rs) const { return mDefaultRenderStates[rs].mRS.get(); }
00487
00489 void resetContextStates(EResetContextStates start_or_finish);
00490
00492 void setTexUnitBinding(int unit_i, ETextureDimension target)
00493 {
00494 VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00495 mTexUnitBinding[unit_i] = target;
00496 }
00497
00499 ETextureDimension texUnitBinding(int unit_i) const
00500 {
00501 VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00502 return mTexUnitBinding[unit_i];
00503 }
00504
00506 static bool areUniformsColliding(const UniformSet* u1, const UniformSet* u2);
00507
00526 bool isCleanState(bool verbose);
00527
00528 public:
00529
00530 const fvec3& normal() const { return mNormal; }
00531 const fvec4& color() const { return mColor; }
00532 const fvec3& secondaryColor() const { return mSecondaryColor; }
00533 const fvec4& vertexAttribValue(int i) const { VL_CHECK(i<VL_MAX_GENERIC_VERTEX_ATTRIB); return mVertexAttribValue[i]; }
00534
00535 protected:
00536 ref<Framebuffer> mLeftFramebuffer;
00537 ref<Framebuffer> mRightFramebuffer;
00538 std::vector< ref<FramebufferObject> > mFramebufferObject;
00539 std::vector< ref<UIEventListener> > mEventListeners;
00540 std::set<EKey> mKeyboard;
00541 OpenGLContextFormat mGLContextInfo;
00542 int mMaxVertexAttrib;
00543 int mTextureSamplerCount;
00544 bool mMouseVisible;
00545 bool mContinuousUpdate;
00546 bool mIgnoreNextMouseMoveEvent;
00547 bool mFullscreen;
00548 bool mHasDoubleBuffer;
00549 bool mIsInitialized;
00550 std::string mExtensions;
00551
00552
00553
00554
00555 RenderStateSlot mDefaultRenderStates[RS_RenderStateCount];
00556
00557
00558 ref< NaryQuickMap<EEnable, EEnable, EN_EnableCount> > mCurrentEnableSet;
00559 ref< NaryQuickMap<EEnable, EEnable, EN_EnableCount> > mNewEnableSet;
00560
00561
00562 ref< NaryQuickMap<ERenderState, RenderStateSlot, RS_RenderStateCount> > mCurrentRenderStateSet;
00563 ref< NaryQuickMap<ERenderState, RenderStateSlot, RS_RenderStateCount> > mNewRenderStateSet;
00564
00565
00566 ETextureDimension mTexUnitBinding[VL_MAX_TEXTURE_UNITS];
00567
00568 private:
00569 struct VertexArrayInfo
00570 {
00571 VertexArrayInfo(): mBufferObject(0), mPtr(0), mState(0), mEnabled(false) {}
00572 int mBufferObject;
00573 const unsigned char* mPtr;
00574 int mState;
00575 bool mEnabled;
00576 };
00577
00578 protected:
00579
00580 const IVertexAttribSet* mCurVAS;
00581 VertexArrayInfo mVertexArray;
00582 VertexArrayInfo mNormalArray;
00583 VertexArrayInfo mColorArray;
00584 VertexArrayInfo mSecondaryColorArray;
00585 VertexArrayInfo mFogArray;
00586 VertexArrayInfo mTexCoordArray[VL_MAX_TEXTURE_UNITS];
00587 VertexArrayInfo mVertexAttrib[VL_MAX_GENERIC_VERTEX_ATTRIB];
00588
00589
00590 fvec3 mNormal;
00591 fvec4 mColor;
00592 fvec3 mSecondaryColor;
00593 fvec4 mVertexAttribValue[VL_MAX_GENERIC_VERTEX_ATTRIB];
00594
00595 private:
00596 void setupDefaultRenderStates();
00597 };
00598
00599 }
00600
00601 #endif