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 {}
00069 virtual const char* className() { return "vl::OpenGLContextFormat"; }
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; }
00081
00082 const ivec4& rgbaBits() const { return mRGBABits; }
00083 const ivec4& accumRGBABits() const { return mAccumRGBABits; }
00084 bool doubleBuffer() const { return mHasDoubleBuffer; }
00085 int depthBufferBits() const { return mZBufferBits; }
00086 int stencilBufferBits() const { return mStencilBufferBits; }
00087 bool multisample() const { return mHasMultisample; }
00088 int multisampleSamples() const { return mMultisampleSamples; }
00089 bool stereo() const { return mStereo; }
00090 bool fullscreen() const { return mFullscreen; }
00091 bool vSync() const { return mVSync; }
00092
00094 int bitsPerPixel() const { return rgbaBits().r() + rgbaBits().g() + rgbaBits().b() + rgbaBits().a(); }
00095
00096 protected:
00097 ivec4 mRGBABits;
00098 ivec4 mAccumRGBABits;
00099 bool mHasDoubleBuffer;
00100 int mZBufferBits;
00101 int mStencilBufferBits;
00102 bool mHasMultisample;
00103 int mMultisampleSamples;
00104 bool mStereo;
00105 bool mFullscreen;
00106 bool mVSync;
00107 };
00108
00109
00110
00122 class VLGRAPHICS_EXPORT OpenGLContext: public Object
00123 {
00124 public:
00125 virtual const char* className() { return "vl::OpenGLContext"; }
00126
00128 OpenGLContext(int w=0, int h=0);
00129
00131 ~OpenGLContext();
00132
00134 virtual void swapBuffers() = 0;
00135
00137 virtual void makeCurrent() = 0;
00138
00140 void initGLContext(bool log=true);
00141
00143 void logOpenGLInfo();
00144
00147 bool isExtensionSupported(const char* ext_name);
00148
00150 void* getProcAddress(const char* function_name);
00151
00154 RenderTarget* renderTarget() { return mRenderTarget.get(); }
00155
00158 const RenderTarget* renderTarget() const { return mRenderTarget.get(); }
00159
00161 ref<FBORenderTarget> createFBORenderTarget() { return createFBORenderTarget(0,0); }
00162
00165 ref<FBORenderTarget> createFBORenderTarget(int width, int height);
00166
00168 void destroyFBORenderTarget(FBORenderTarget* fbort);
00169
00171 void destroyAllFBORenderTargets();
00172
00174 virtual void quitApplication() {}
00175
00177 virtual void update() = 0;
00178
00180 virtual void setWindowTitle(const String&) {}
00181
00183 virtual bool setFullscreen(bool) { mFullscreen = false; return false; }
00184
00186 virtual bool fullscreen() const { return mFullscreen; }
00187
00189 virtual void show() {}
00190
00192 virtual void hide() {}
00193
00195 virtual void setPosition(int , int ) {}
00196
00198 virtual ivec2 position() const { return ivec2(); }
00199
00201 virtual void setSize(int , int ) {}
00202
00204 int width() const { return mRenderTarget->width(); }
00205
00207 int height() const { return mRenderTarget->height(); }
00208
00210 virtual void setMouseVisible(bool) { mMouseVisible=false; }
00211
00213 virtual bool mouseVisible() const { return mMouseVisible; }
00214
00216 virtual void setMousePosition(int , int ) {}
00217
00219 virtual void getFocus() {}
00220
00222 void setVSyncEnabled(bool enable);
00223
00225 bool vsyncEnabled() const;
00226
00228 virtual void setContinuousUpdate(bool continuous) { mContinuousUpdate = continuous; }
00229
00231 bool continuousUpdate() const { return mContinuousUpdate; }
00232
00236 void addEventListener(UIEventListener* el);
00237
00239 void removeEventListener(UIEventListener* el);
00240
00242 void eraseAllEventListeners();
00243
00245 const std::vector< ref<UIEventListener> >& eventListeners() const { return mEventListeners; }
00246
00248 UIEventListener* eventListener(int i) const { return mEventListeners[i].get(); }
00249
00251 int eventListenerCount() const { return (int)mEventListeners.size(); }
00252
00254 const OpenGLContextFormat& openglContextInfo() const { return mGLContextInfo; }
00255
00257 void setOpenGLContextInfo(const OpenGLContextFormat& info) { mGLContextInfo = info; }
00258
00260 void ignoreNextMouseMoveEvent() { mIgnoreNextMouseMoveEvent = true; }
00261
00264 void dispatchResizeEvent(int w, int h)
00265 {
00266 makeCurrent();
00267 mRenderTarget->setWidth(w);
00268 mRenderTarget->setHeight(h);
00269
00270 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00271 for( unsigned i=0; i<temp_clients.size(); ++i )
00272 if ( temp_clients[i]->isEnabled() )
00273 temp_clients[i]->resizeEvent( w, h );
00274 }
00275
00277 void dispatchMouseMoveEvent(int x, int y)
00278 {
00279 makeCurrent();
00280 if (mIgnoreNextMouseMoveEvent)
00281 mIgnoreNextMouseMoveEvent = false;
00282 else
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]->mouseMoveEvent(x, y);
00288 }
00289 }
00290
00292 void dispatchMouseUpEvent(EMouseButton button, int x, int y)
00293 {
00294 makeCurrent();
00295 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00296 for( unsigned i=0; i<temp_clients.size(); ++i )
00297 if ( temp_clients[i]->isEnabled() )
00298 temp_clients[i]->mouseUpEvent(button, x, y);
00299 }
00300
00302 void dispatchMouseDownEvent(EMouseButton button, int x, int y)
00303 {
00304 makeCurrent();
00305 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00306 for( unsigned i=0; i<temp_clients.size(); ++i )
00307 if ( temp_clients[i]->isEnabled() )
00308 temp_clients[i]->mouseDownEvent(button, x, y);
00309 }
00310
00312 void dispatchMouseWheelEvent(int n)
00313 {
00314 makeCurrent();
00315 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00316 for( unsigned i=0; i<temp_clients.size(); ++i )
00317 if ( temp_clients[i]->isEnabled() )
00318 temp_clients[i]->mouseWheelEvent(n);
00319 }
00320
00322 void dispatchKeyPressEvent(unsigned short unicode_ch, EKey key)
00323 {
00324 makeCurrent();
00325 keyPress(key);
00326 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00327 for( unsigned i=0; i<temp_clients.size(); ++i )
00328 if ( temp_clients[i]->isEnabled() )
00329 temp_clients[i]->keyPressEvent(unicode_ch, key);
00330 }
00331
00333 void dispatchKeyReleaseEvent(unsigned short unicode_ch, EKey key)
00334 {
00335 makeCurrent();
00336 keyRelease(key);
00337 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00338 for( unsigned i=0; i<temp_clients.size(); ++i )
00339 if ( temp_clients[i]->isEnabled() )
00340 temp_clients[i]->keyReleaseEvent(unicode_ch, key);
00341 }
00342
00346 void dispatchDestroyEvent()
00347 {
00348 makeCurrent();
00349 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00350 for( unsigned i=0; i<temp_clients.size(); ++i )
00351 if ( temp_clients[i]->isEnabled() )
00352 temp_clients[i]->destroyEvent();
00353 destroyAllFBORenderTargets();
00354 eraseAllEventListeners();
00355 }
00356
00358 void dispatchRunEvent()
00359 {
00360 makeCurrent();
00361 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00362 for( unsigned i=0; i<temp_clients.size(); ++i )
00363 if ( temp_clients[i]->isEnabled() )
00364 temp_clients[i]->updateEvent();
00365 }
00366
00368 void dispatchVisibilityEvent(bool visible)
00369 {
00370 makeCurrent();
00371 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00372 for( unsigned i=0; i<temp_clients.size(); ++i )
00373 if ( temp_clients[i]->isEnabled() )
00374 temp_clients[i]->visibilityEvent(visible);
00375 }
00376
00378
00379
00380
00381
00382 void dispatchInitEvent()
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]->initEvent();
00389 }
00390
00392 void dispatchFileDroppedEvent(const std::vector<String>& files)
00393 {
00394 makeCurrent();
00395 std::vector< ref<UIEventListener> > temp_clients = eventListeners();
00396 for( unsigned i=0; i<temp_clients.size(); ++i )
00397 if ( temp_clients[i]->isEnabled() )
00398 temp_clients[i]->fileDroppedEvent(files);
00399 }
00400
00402 const std::set<EKey>& keyboard() const { return mKeyboard; }
00403
00405 bool isKeyPressed(EKey key) const { return mKeyboard.find(key) != mKeyboard.end(); }
00406
00408 void keyPress(EKey key) { mKeyboard.insert(key); }
00409
00411 void keyRelease(EKey key) { mKeyboard.erase(key); }
00412
00414 bool isInitialized() const { return mIsInitialized; }
00415
00417 int textureUnitCount() const { return mTextureUnitCount; }
00418
00420 bool hasDoubleBuffer() const { return mHasDoubleBuffer; }
00421
00423 bool isCompatible() const { return mIsCompatible; }
00424
00426 int openglVersionMajorNumber() const { return mMajorVersion; }
00427
00429 int openglVersionMinorNumber() const { return mMinorVersion; }
00430
00431
00432
00438 void bindVAS(const IVertexAttribSet* vas, bool use_vbo, bool force);
00439
00441 void applyEnables( const EnableSet* prev, const EnableSet* cur );
00442
00444 void applyRenderStates( const RenderStateSet* prev, const RenderStateSet* cur, const Camera* camera );
00445
00447 void resetEnables();
00448
00450 void resetRenderStates();
00451
00453 void resetContextStates();
00454
00456 void setTexUnitBinding(int unit_i, ETextureDimension target)
00457 {
00458 VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00459 mTexUnitBinding[unit_i] = target;
00460 }
00461
00463 ETextureDimension texUnitBinding(int unit_i) const
00464 {
00465 VL_CHECK(unit_i <= VL_MAX_TEXTURE_UNITS);
00466 return mTexUnitBinding[unit_i];
00467 }
00468
00470 static bool areUniformsColliding(const UniformSet* u1, const UniformSet* u2);
00471
00490 bool isCleanState(bool verbose);
00491
00492 protected:
00493 ref<RenderTarget> mRenderTarget;
00494 std::vector< ref<FBORenderTarget> > mFBORenderTarget;
00495 std::vector< ref<UIEventListener> > mEventListeners;
00496 std::set<EKey> mKeyboard;
00497 OpenGLContextFormat mGLContextInfo;
00498 int mMaxVertexAttrib;
00499 int mTextureUnitCount;
00500 int mMajorVersion;
00501 int mMinorVersion;
00502 bool mMouseVisible;
00503 bool mContinuousUpdate;
00504 bool mIgnoreNextMouseMoveEvent;
00505 bool mFullscreen;
00506 bool mHasDoubleBuffer;
00507 bool mIsInitialized;
00508 bool mIsCompatible;
00509
00510
00511
00512 int mEnableTable[EN_EnableCount];
00513 int mRenderStateTable[RS_COUNT];
00514
00515 bool mCurrentEnable[EN_EnableCount];
00516 const RenderState* mCurrentRenderState[RS_COUNT];
00517
00518 ref<RenderState> mDefaultRenderStates[RS_COUNT];
00519
00520
00521 ETextureDimension mTexUnitBinding[VL_MAX_TEXTURE_UNITS];
00522
00523 private:
00524 struct VertexArrayInfo
00525 {
00526 VertexArrayInfo(): mVBO(0), mPtr(0), mState(0), mEnabled(false) {}
00527 int mVBO;
00528 const unsigned char* mPtr;
00529 int mState;
00530 bool mEnabled;
00531 };
00532 protected:
00533
00534 const IVertexAttribSet* mCurVAS;
00535 VertexArrayInfo mVertexArray;
00536 VertexArrayInfo mNormalArray;
00537 VertexArrayInfo mColorArray;
00538 VertexArrayInfo mSecondaryColorArray;
00539 VertexArrayInfo mFogArray;
00540 VertexArrayInfo mTexCoordArray[VL_MAX_TEXTURE_UNITS];
00541 VertexArrayInfo mVertexAttrib[VL_MAX_GENERIC_VERTEX_ATTRIB];
00542
00543 private:
00544 void setupDefaultRenderStates();
00545 };
00546
00547 }
00548
00549 #endif