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
00165 Framebuffer* framebuffer() { return mFramebuffer.get(); }
00166
00169 const Framebuffer* framebuffer() const { return mFramebuffer.get(); }
00170
00172 ref<FramebufferObject> createFramebufferObject() { return createFramebufferObject(0,0); }
00173
00176 ref<FramebufferObject> createFramebufferObject(int width, int height);
00177
00179 void destroyFramebufferObject(FramebufferObject* fbort);
00180
00182 void destroyAllFramebufferObjects();
00183
00185 virtual void quitApplication() {}
00186
00188 virtual void update() = 0;
00189
00191 virtual void setWindowTitle(const String&) {}
00192
00194 virtual bool setFullscreen(bool) { mFullscreen = false; return false; }
00195
00197 virtual bool fullscreen() const { return mFullscreen; }
00198
00200 virtual void show() {}
00201
00203 virtual void hide() {}
00204
00206 virtual void setPosition(int , int ) {}
00207
00209 virtual ivec2 position() const { return ivec2(); }
00210
00212 virtual void setSize(int , int ) {}
00213
00215 int width() const { return mFramebuffer->width(); }
00216
00218 int height() const { return mFramebuffer->height(); }
00219
00221 virtual void setMouseVisible(bool) { mMouseVisible=false; }
00222
00224 virtual bool mouseVisible() const { return mMouseVisible; }
00225
00227 virtual void setMousePosition(int , int ) {}
00228
00230 virtual void getFocus() {}
00231
00233 void setVSyncEnabled(bool enable);
00234
00236 bool vsyncEnabled() const;
00237
00239 virtual void setContinuousUpdate(bool continuous) { mContinuousUpdate = continuous; }
00240
00242 bool continuousUpdate() const { return mContinuousUpdate; }
00243
00247 void addEventListener(UIEventListener* el);
00248
00250 void removeEventListener(UIEventListener* el);
00251
00253 void eraseAllEventListeners();
00254
00256 const std::vector< ref<UIEventListener> >& eventListeners() const { return mEventListeners; }
00257
00259 const UIEventListener* eventListener(int i) const { return mEventListeners[i].get(); }
00260
00262 UIEventListener* eventListener(int i) { return mEventListeners[i].get(); }
00263
00265 int eventListenerCount() const { return (int)mEventListeners.size(); }
00266
00268 const OpenGLContextFormat& openglContextInfo() const { return mGLContextInfo; }
00269
00271 void setOpenGLContextInfo(const OpenGLContextFormat& info) { mGLContextInfo = info; }
00272
00274 void ignoreNextMouseMoveEvent() { mIgnoreNextMouseMoveEvent = true; }
00275
00278 void dispatchResizeEvent(int w, int h)
00279 {
00280 makeCurrent();
00281 mFramebuffer->setWidth(w);
00282 mFramebuffer->setHeight(h);
00283
00284 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00285 for( unsigned i=0; i<temp_clients.size(); ++i )
00286 if ( temp_clients[i]->isEnabled() )
00287 temp_clients[i]->resizeEvent( w, h );
00288 }
00289
00291 void dispatchMouseMoveEvent(int x, int y)
00292 {
00293 makeCurrent();
00294 if (mIgnoreNextMouseMoveEvent)
00295 mIgnoreNextMouseMoveEvent = false;
00296 else
00297 {
00298 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00299 for( unsigned i=0; i<temp_clients.size(); ++i )
00300 if ( temp_clients[i]->isEnabled() )
00301 temp_clients[i]->mouseMoveEvent(x, y);
00302 }
00303 }
00304
00306 void dispatchMouseUpEvent(EMouseButton button, int x, int y)
00307 {
00308 makeCurrent();
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]->mouseUpEvent(button, x, y);
00313 }
00314
00316 void dispatchMouseDownEvent(EMouseButton button, int x, int y)
00317 {
00318 makeCurrent();
00319 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00320 for( unsigned i=0; i<temp_clients.size(); ++i )
00321 if ( temp_clients[i]->isEnabled() )
00322 temp_clients[i]->mouseDownEvent(button, x, y);
00323 }
00324
00326 void dispatchMouseWheelEvent(int n)
00327 {
00328 makeCurrent();
00329 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00330 for( unsigned i=0; i<temp_clients.size(); ++i )
00331 if ( temp_clients[i]->isEnabled() )
00332 temp_clients[i]->mouseWheelEvent(n);
00333 }
00334
00336 void dispatchKeyPressEvent(unsigned short unicode_ch, EKey key)
00337 {
00338 makeCurrent();
00339 keyPress(key);
00340 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00341 for( unsigned i=0; i<temp_clients.size(); ++i )
00342 if ( temp_clients[i]->isEnabled() )
00343 temp_clients[i]->keyPressEvent(unicode_ch, key);
00344 }
00345
00347 void dispatchKeyReleaseEvent(unsigned short unicode_ch, EKey key)
00348 {
00349 makeCurrent();
00350 keyRelease(key);
00351 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00352 for( unsigned i=0; i<temp_clients.size(); ++i )
00353 if ( temp_clients[i]->isEnabled() )
00354 temp_clients[i]->keyReleaseEvent(unicode_ch, key);
00355 }
00356
00360 void dispatchDestroyEvent()
00361 {
00362 makeCurrent();
00363 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00364 for( unsigned i=0; i<temp_clients.size(); ++i )
00365 if ( temp_clients[i]->isEnabled() )
00366 temp_clients[i]->destroyEvent();
00367 destroyAllFramebufferObjects();
00368 eraseAllEventListeners();
00369 }
00370
00372 void dispatchRunEvent()
00373 {
00374 makeCurrent();
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]->updateEvent();
00379 }
00380
00382 void dispatchVisibilityEvent(bool visible)
00383 {
00384 makeCurrent();
00385 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00386 for( unsigned i=0; i<temp_clients.size(); ++i )
00387 if ( temp_clients[i]->isEnabled() )
00388 temp_clients[i]->visibilityEvent(visible);
00389 }
00390
00392
00393
00394
00395
00396 void dispatchInitEvent()
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]->initEvent();
00403 }
00404
00406 void dispatchFileDroppedEvent(const std::vector<String>& files)
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]->fileDroppedEvent(files);
00413 }
00414
00416 const std::set<EKey>& keyboard() const { return mKeyboard; }
00417
00419 bool isKeyPressed(EKey key) const { return mKeyboard.find(key) != mKeyboard.end(); }
00420
00422 void keyPress(EKey key) { mKeyboard.insert(key); }
00423
00425 void keyRelease(EKey key) { mKeyboard.erase(key); }
00426
00428 bool isInitialized() const { return mIsInitialized; }
00429
00431 int textureUnitCount() const { return mTextureSamplerCount; }
00432
00434 bool hasDoubleBuffer() const { return mHasDoubleBuffer; }
00435
00436
00437
00443 void bindVAS(const IVertexAttribSet* vas, bool use_vbo, bool force);
00444
00446 void applyEnables( const EnableSet* cur );
00447
00449 void applyRenderStates( const RenderStateSet* cur, const Camera* camera );
00450
00452 void resetEnables();
00453
00455 void resetRenderStates();
00456
00458 void resetContextStates(EResetContextStates start_or_finish);
00459
00461 void setTexUnitBinding(int unit_i, ETextureDimension target)
00462 {
00463 VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00464 mTexUnitBinding[unit_i] = target;
00465 }
00466
00468 ETextureDimension texUnitBinding(int unit_i) const
00469 {
00470 VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00471 return mTexUnitBinding[unit_i];
00472 }
00473
00475 static bool areUniformsColliding(const UniformSet* u1, const UniformSet* u2);
00476
00495 bool isCleanState(bool verbose);
00496
00497 public:
00498
00499 const fvec3& normal() const { return mNormal; }
00500 const fvec4& color() const { return mColor; }
00501 const fvec3& secondaryColor() const { return mSecondaryColor; }
00502 const fvec4& vertexAttribValue(int i) const { VL_CHECK(i<VL_MAX_GENERIC_VERTEX_ATTRIB); return mVertexAttribValue[i]; }
00503
00504 protected:
00505 ref<Framebuffer> mFramebuffer;
00506 std::vector< ref<FramebufferObject> > mFramebufferObject;
00507 std::vector< ref<UIEventListener> > mEventListeners;
00508 std::set<EKey> mKeyboard;
00509 OpenGLContextFormat mGLContextInfo;
00510 int mMaxVertexAttrib;
00511 int mTextureSamplerCount;
00512 bool mMouseVisible;
00513 bool mContinuousUpdate;
00514 bool mIgnoreNextMouseMoveEvent;
00515 bool mFullscreen;
00516 bool mHasDoubleBuffer;
00517 bool mIsInitialized;
00518 std::string mExtensions;
00519
00520
00521
00522 int mEnableTable[EN_EnableCount];
00523 int mRenderStateTable[RS_RenderStateCount];
00524
00525 bool mCurrentEnable[EN_EnableCount];
00526 const RenderState* mCurrentRenderState[RS_RenderStateCount];
00527
00528 EEnable mPrevEnables[EN_EnableCount];
00529 size_t mPrevEnablesCount;
00530 ERenderState mPrevRenderStates[RS_RenderStateCount];
00531 size_t mPrevRenderStatesCount;
00532
00533 RenderStateSlot mDefaultRenderStates[RS_RenderStateCount];
00534
00535
00536 ETextureDimension mTexUnitBinding[VL_MAX_TEXTURE_UNITS];
00537
00538 private:
00539 struct VertexArrayInfo
00540 {
00541 VertexArrayInfo(): mBufferObject(0), mPtr(0), mState(0), mEnabled(false) {}
00542 int mBufferObject;
00543 const unsigned char* mPtr;
00544 int mState;
00545 bool mEnabled;
00546 };
00547
00548 protected:
00549
00550 const IVertexAttribSet* mCurVAS;
00551 VertexArrayInfo mVertexArray;
00552 VertexArrayInfo mNormalArray;
00553 VertexArrayInfo mColorArray;
00554 VertexArrayInfo mSecondaryColorArray;
00555 VertexArrayInfo mFogArray;
00556 VertexArrayInfo mTexCoordArray[VL_MAX_TEXTURE_UNITS];
00557 VertexArrayInfo mVertexAttrib[VL_MAX_GENERIC_VERTEX_ATTRIB];
00558
00559
00560 fvec3 mNormal;
00561 fvec4 mColor;
00562 fvec3 mSecondaryColor;
00563 fvec4 mVertexAttribValue[VL_MAX_GENERIC_VERTEX_ATTRIB];
00564
00565 private:
00566 void setupDefaultRenderStates();
00567 };
00568
00569 }
00570
00571 #endif