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 <vector>
00040 #include <set>
00041
00042 namespace vl
00043 {
00044 class EnableSet;
00045 class RenderStateSet;
00046 class UniformSet;
00047 class IVertexAttribSet;
00048 class ArrayAbstract;
00049
00050
00051
00052
00054 class OpenGLContextFormat
00055 {
00056 public:
00057 OpenGLContextFormat():
00058 mRGBABits(ivec4(8,8,8,8)),
00059 mAccumRGBABits(ivec4(0,0,0,0)),
00060 mHasDoubleBuffer(true),
00061 mZBufferBits(24),
00062 mStencilBufferBits(8),
00063 mHasMultisample(false),
00064 mMultisampleSamples(16),
00065 mStereo(false),
00066 mFullscreen(false),
00067 mVSync(false),
00068 mContextClientVersion(1) {}
00069
00070 void setRGBABits(int r, int g, int b, int a) { mRGBABits = ivec4(r,g,b,a); }
00071 void setAccumRGBABits(int r, int g, int b, int a) { mAccumRGBABits = ivec4(r,g,b,a); }
00072 void setDoubleBuffer(bool double_buffer_on) { mHasDoubleBuffer = double_buffer_on; }
00073 void setDepthBufferBits(int bits) { mZBufferBits = bits; }
00074 void setStencilBufferBits(int bits) { mStencilBufferBits = bits; }
00075 void setMultisample(bool multisample_on) { mHasMultisample = multisample_on; }
00076 void setMultisampleSamples(int samples) { mMultisampleSamples = samples; }
00077 void setStereo(bool stereo_on) { mStereo = stereo_on; }
00078 void setFullscreen(bool fullscreent) { mFullscreen = fullscreent; }
00079 void setVSync(bool vsync_on) { mVSync = vsync_on; }
00081 void setContextClientVersion(int version) { mContextClientVersion = version; }
00082
00083 const ivec4& rgbaBits() const { return mRGBABits; }
00084 const ivec4& accumRGBABits() const { return mAccumRGBABits; }
00085 bool doubleBuffer() const { return mHasDoubleBuffer; }
00086 int depthBufferBits() const { return mZBufferBits; }
00087 int stencilBufferBits() const { return mStencilBufferBits; }
00088 bool multisample() const { return mHasMultisample; }
00089 int multisampleSamples() const { return mMultisampleSamples; }
00090 bool stereo() const { return mStereo; }
00091 bool fullscreen() const { return mFullscreen; }
00092 bool vSync() const { return mVSync; }
00094 int contextClientVersion() const { return mContextClientVersion; }
00095
00097 int bitsPerPixel() const { return rgbaBits().r() + rgbaBits().g() + rgbaBits().b() + rgbaBits().a(); }
00098
00099 protected:
00100 ivec4 mRGBABits;
00101 ivec4 mAccumRGBABits;
00102 bool mHasDoubleBuffer;
00103 int mZBufferBits;
00104 int mStencilBufferBits;
00105 bool mHasMultisample;
00106 int mMultisampleSamples;
00107 bool mStereo;
00108 bool mFullscreen;
00109 bool mVSync;
00110 int mContextClientVersion;
00111 };
00112
00113
00114
00126 class VLGRAPHICS_EXPORT OpenGLContext: public Object
00127 {
00128 VL_INSTRUMENT_ABSTRACT_CLASS(vl::OpenGLContext, Object)
00129 friend class VertexAttrib;
00130 friend class Color;
00131 friend class SecondaryColor;
00132 friend class Normal;
00133
00134 public:
00136 OpenGLContext(int w=0, int h=0);
00137
00139 ~OpenGLContext();
00140
00142 virtual void swapBuffers() = 0;
00143
00145 virtual void makeCurrent() = 0;
00146
00148 bool initGLContext(bool log=true);
00149
00151 void logOpenGLInfo();
00152
00154 const std::string& extensions() const { return mExtensions; }
00155
00158 bool isExtensionSupported(const char* ext_name);
00159
00161 void* getProcAddress(const char* function_name);
00162
00166 Framebuffer* leftFramebuffer() { return mLeftFramebuffer.get(); }
00167
00171 const Framebuffer* leftFramebuffer() const { return mLeftFramebuffer.get(); }
00172
00176 Framebuffer* rightFramebuffer() { return mRightFramebuffer.get(); }
00177
00181 const Framebuffer* rightFramebuffer() const { return mRightFramebuffer.get(); }
00182
00185 Framebuffer* framebuffer() { return leftFramebuffer(); }
00186
00189 const Framebuffer* framebuffer() const { return leftFramebuffer(); }
00190
00192 ref<FramebufferObject> createFramebufferObject() { return createFramebufferObject(0,0); }
00193
00196 ref<FramebufferObject> createFramebufferObject(int width, int height,
00197 EReadDrawBuffer draw_buffer=RDB_COLOR_ATTACHMENT0,
00198 EReadDrawBuffer read_buffer=RDB_COLOR_ATTACHMENT0);
00199
00201 void destroyFramebufferObject(FramebufferObject* fbort);
00202
00204 void destroyAllFramebufferObjects();
00205
00207 virtual void quitApplication() {}
00208
00210 virtual void update() = 0;
00211
00213 virtual void setWindowTitle(const String&) {}
00214
00216 virtual bool setFullscreen(bool) { mFullscreen = false; return false; }
00217
00219 virtual bool fullscreen() const { return mFullscreen; }
00220
00222 virtual void show() {}
00223
00225 virtual void hide() {}
00226
00228 virtual void setPosition(int , int ) {}
00229
00231 virtual ivec2 position() const { return ivec2(); }
00232
00234 virtual void setSize(int , int ) {}
00235
00237 int width() const { return framebuffer()->width(); }
00238
00240 int height() const { return framebuffer()->height(); }
00241
00243 virtual void setMouseVisible(bool) { mMouseVisible=false; }
00244
00246 virtual bool mouseVisible() const { return mMouseVisible; }
00247
00249 virtual void setMousePosition(int , int ) {}
00250
00252 virtual void getFocus() {}
00253
00255 void setVSyncEnabled(bool enable);
00256
00258 bool vsyncEnabled() const;
00259
00261 virtual void setContinuousUpdate(bool continuous) { mContinuousUpdate = continuous; }
00262
00264 bool continuousUpdate() const { return mContinuousUpdate; }
00265
00269 void addEventListener(UIEventListener* el);
00270
00272 void removeEventListener(UIEventListener* el);
00273
00275 void eraseAllEventListeners();
00276
00278 const std::vector< ref<UIEventListener> >& eventListeners() const { return mEventListeners; }
00279
00281 const UIEventListener* eventListener(int i) const { return mEventListeners[i].get(); }
00282
00284 UIEventListener* eventListener(int i) { return mEventListeners[i].get(); }
00285
00287 int eventListenerCount() const { return (int)mEventListeners.size(); }
00288
00290 const OpenGLContextFormat& openglContextInfo() const { return mGLContextInfo; }
00291
00293 void setOpenGLContextInfo(const OpenGLContextFormat& info) { mGLContextInfo = info; }
00294
00296 void ignoreNextMouseMoveEvent() { mIgnoreNextMouseMoveEvent = true; }
00297
00300 void dispatchResizeEvent(int w, int h)
00301 {
00302 makeCurrent();
00303 leftFramebuffer()->setWidth(w);
00304 leftFramebuffer()->setHeight(h);
00305 rightFramebuffer()->setWidth(w);
00306 rightFramebuffer()->setHeight(h);
00307
00308 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00309 for( unsigned i=0; i<temp_clients.size(); ++i )
00310 if ( temp_clients[i]->isEnabled() )
00311 temp_clients[i]->resizeEvent( w, h );
00312 }
00313
00315 void dispatchMouseMoveEvent(int x, int y)
00316 {
00317 makeCurrent();
00318 if (mIgnoreNextMouseMoveEvent)
00319 mIgnoreNextMouseMoveEvent = false;
00320 else
00321 {
00322 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00323 for( unsigned i=0; i<temp_clients.size(); ++i )
00324 if ( temp_clients[i]->isEnabled() )
00325 temp_clients[i]->mouseMoveEvent(x, y);
00326 }
00327 }
00328
00330 void dispatchMouseUpEvent(EMouseButton button, int x, int y)
00331 {
00332 makeCurrent();
00333 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00334 for( unsigned i=0; i<temp_clients.size(); ++i )
00335 if ( temp_clients[i]->isEnabled() )
00336 temp_clients[i]->mouseUpEvent(button, x, y);
00337 }
00338
00340 void dispatchMouseDownEvent(EMouseButton button, int x, int y)
00341 {
00342 makeCurrent();
00343 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00344 for( unsigned i=0; i<temp_clients.size(); ++i )
00345 if ( temp_clients[i]->isEnabled() )
00346 temp_clients[i]->mouseDownEvent(button, x, y);
00347 }
00348
00350 void dispatchMouseWheelEvent(int n)
00351 {
00352 makeCurrent();
00353 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00354 for( unsigned i=0; i<temp_clients.size(); ++i )
00355 if ( temp_clients[i]->isEnabled() )
00356 temp_clients[i]->mouseWheelEvent(n);
00357 }
00358
00360 void dispatchKeyPressEvent(unsigned short unicode_ch, EKey key)
00361 {
00362 makeCurrent();
00363 keyPress(key);
00364 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00365 for( unsigned i=0; i<temp_clients.size(); ++i )
00366 if ( temp_clients[i]->isEnabled() )
00367 temp_clients[i]->keyPressEvent(unicode_ch, key);
00368 }
00369
00371 void dispatchKeyReleaseEvent(unsigned short unicode_ch, EKey key)
00372 {
00373 makeCurrent();
00374 keyRelease(key);
00375 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00376 for( unsigned i=0; i<temp_clients.size(); ++i )
00377 if ( temp_clients[i]->isEnabled() )
00378 temp_clients[i]->keyReleaseEvent(unicode_ch, key);
00379 }
00380
00384 void dispatchDestroyEvent()
00385 {
00386 makeCurrent();
00387 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00388 for( unsigned i=0; i<temp_clients.size(); ++i )
00389 if ( temp_clients[i]->isEnabled() )
00390 temp_clients[i]->destroyEvent();
00391 destroyAllFramebufferObjects();
00392 eraseAllEventListeners();
00393 }
00394
00396 void dispatchRunEvent()
00397 {
00398 makeCurrent();
00399 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00400 for( unsigned i=0; i<temp_clients.size(); ++i )
00401 if ( temp_clients[i]->isEnabled() )
00402 temp_clients[i]->updateEvent();
00403 }
00404
00406 void dispatchVisibilityEvent(bool visible)
00407 {
00408 makeCurrent();
00409 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00410 for( unsigned i=0; i<temp_clients.size(); ++i )
00411 if ( temp_clients[i]->isEnabled() )
00412 temp_clients[i]->visibilityEvent(visible);
00413 }
00414
00416
00417
00418
00419
00420 void dispatchInitEvent()
00421 {
00422 makeCurrent();
00423 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00424 for( unsigned i=0; i<temp_clients.size(); ++i )
00425 if ( temp_clients[i]->isEnabled() )
00426 temp_clients[i]->initEvent();
00427 }
00428
00430 void dispatchFileDroppedEvent(const std::vector<String>& files)
00431 {
00432 makeCurrent();
00433 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00434 for( unsigned i=0; i<temp_clients.size(); ++i )
00435 if ( temp_clients[i]->isEnabled() )
00436 temp_clients[i]->fileDroppedEvent(files);
00437 }
00438
00440 const std::set<EKey>& keyboard() const { return mKeyboard; }
00441
00443 bool isKeyPressed(EKey key) const { return mKeyboard.find(key) != mKeyboard.end(); }
00444
00446 void keyPress(EKey key) { mKeyboard.insert(key); }
00447
00449 void keyRelease(EKey key) { mKeyboard.erase(key); }
00450
00452 bool isInitialized() const { return mIsInitialized; }
00453
00455 int textureUnitCount() const { return mTextureSamplerCount; }
00456
00458 bool hasDoubleBuffer() const { return mHasDoubleBuffer; }
00459
00460
00461
00467 void bindVAS(const IVertexAttribSet* vas, bool use_vbo, bool force);
00468
00470 void applyEnables( const EnableSet* cur );
00471
00473 void applyRenderStates( const RenderStateSet* cur, const Camera* camera );
00474
00476 void resetEnables();
00477
00479 void resetRenderStates();
00480
00482 void resetContextStates(EResetContextStates start_or_finish);
00483
00485 void setTexUnitBinding(int unit_i, ETextureDimension target)
00486 {
00487 VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00488 mTexUnitBinding[unit_i] = target;
00489 }
00490
00492 ETextureDimension texUnitBinding(int unit_i) const
00493 {
00494 VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00495 return mTexUnitBinding[unit_i];
00496 }
00497
00499 static bool areUniformsColliding(const UniformSet* u1, const UniformSet* u2);
00500
00519 bool isCleanState(bool verbose);
00520
00521 public:
00522
00523 const fvec3& normal() const { return mNormal; }
00524 const fvec4& color() const { return mColor; }
00525 const fvec3& secondaryColor() const { return mSecondaryColor; }
00526 const fvec4& vertexAttribValue(int i) const { VL_CHECK(i<VL_MAX_GENERIC_VERTEX_ATTRIB); return mVertexAttribValue[i]; }
00527
00528 protected:
00529 ref<Framebuffer> mLeftFramebuffer;
00530 ref<Framebuffer> mRightFramebuffer;
00531 std::vector< ref<FramebufferObject> > mFramebufferObject;
00532 std::vector< ref<UIEventListener> > mEventListeners;
00533 std::set<EKey> mKeyboard;
00534 OpenGLContextFormat mGLContextInfo;
00535 int mMaxVertexAttrib;
00536 int mTextureSamplerCount;
00537 bool mMouseVisible;
00538 bool mContinuousUpdate;
00539 bool mIgnoreNextMouseMoveEvent;
00540 bool mFullscreen;
00541 bool mHasDoubleBuffer;
00542 bool mIsInitialized;
00543 std::string mExtensions;
00544
00545
00546
00547 int mEnableTable[EN_EnableCount];
00548 int mRenderStateTable[RS_RenderStateCount];
00549
00550 bool mCurrentEnable[EN_EnableCount];
00551 const RenderState* mCurrentRenderState[RS_RenderStateCount];
00552
00553 EEnable mPrevEnables[EN_EnableCount];
00554 size_t mPrevEnablesCount;
00555 ERenderState mPrevRenderStates[RS_RenderStateCount];
00556 size_t mPrevRenderStatesCount;
00557
00558 RenderStateSlot mDefaultRenderStates[RS_RenderStateCount];
00559
00560
00561 ETextureDimension mTexUnitBinding[VL_MAX_TEXTURE_UNITS];
00562
00563 private:
00564 struct VertexArrayInfo
00565 {
00566 VertexArrayInfo(): mBufferObject(0), mPtr(0), mState(0), mEnabled(false) {}
00567 int mBufferObject;
00568 const unsigned char* mPtr;
00569 int mState;
00570 bool mEnabled;
00571 };
00572
00573 protected:
00574
00575 const IVertexAttribSet* mCurVAS;
00576 VertexArrayInfo mVertexArray;
00577 VertexArrayInfo mNormalArray;
00578 VertexArrayInfo mColorArray;
00579 VertexArrayInfo mSecondaryColorArray;
00580 VertexArrayInfo mFogArray;
00581 VertexArrayInfo mTexCoordArray[VL_MAX_TEXTURE_UNITS];
00582 VertexArrayInfo mVertexAttrib[VL_MAX_GENERIC_VERTEX_ATTRIB];
00583
00584
00585 fvec3 mNormal;
00586 fvec4 mColor;
00587 fvec3 mSecondaryColor;
00588 fvec4 mVertexAttribValue[VL_MAX_GENERIC_VERTEX_ATTRIB];
00589
00590 private:
00591 void setupDefaultRenderStates();
00592 };
00593
00594 }
00595
00596 #endif