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 void setDefaultRenderState(const RenderStateSlot& rs_slot)
00484 {
00485 mDefaultRenderStates[rs_slot.type()] = rs_slot;
00486
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
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
00561
00562
00563 RenderStateSlot mDefaultRenderStates[RS_RenderStateCount];
00564
00565
00566 ref< NaryQuickMap<EEnable, EEnable, EN_EnableCount> > mCurrentEnableSet;
00567 ref< NaryQuickMap<EEnable, EEnable, EN_EnableCount> > mNewEnableSet;
00568
00569
00570 ref< NaryQuickMap<ERenderState, RenderStateSlot, RS_RenderStateCount> > mCurrentRenderStateSet;
00571 ref< NaryQuickMap<ERenderState, RenderStateSlot, RS_RenderStateCount> > mNewRenderStateSet;
00572
00573
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
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
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