diff --git a/oxygine/src/core/SharedContext.cpp b/oxygine/src/core/SharedContext.cpp new file mode 100644 index 000000000..3564d6860 --- /dev/null +++ b/oxygine/src/core/SharedContext.cpp @@ -0,0 +1,60 @@ +#include "SharedContext.h" +#include +#include "oxygine.h" +#include "gl/oxgl.h" + +namespace oxygine +{ + /** Allows the usage of shared OpenGL contexts. Needs to be called before core::init(). */ + void SharedContext::Enable() + { + //SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1); + } + + /** Creates a shared context. Can be called from the main thread. */ + void SharedContext::create() + { + OX_ASSERT(_context == NULL); + + SDL_GLContext currentContext = SDL_GL_GetCurrentContext(); + + OX_ASSERT(currentContext != NULL); + + _context = SDL_GL_CreateContext( core::getWindow() ); + + CHECKGL(); + + OX_ASSERT(_context != NULL); + + // restore the previous context + SDL_GL_MakeCurrent( core::getWindow(), currentContext ); + } + + /** Makes this context the current one. Must be called from within the thread that will use it. */ + void SharedContext::makeCurrent() + { + OX_ASSERT(_context != NULL); + + SDL_GL_MakeCurrent( core::getWindow(), _context ); + + CHECKGL(); + } + + /** The destructor which releases the context again. */ + SharedContext::~SharedContext() + { + if(_context != NULL) + { + // disable the context if it is this one + if( SDL_GL_GetCurrentContext() == _context ) + SDL_GL_MakeCurrent( core::getWindow(), NULL ); + + SDL_GL_DeleteContext(_context); + + CHECKGL(); + + // just be safe in case of other destructor code accessing this object + _context = NULL; + } + } +} diff --git a/oxygine/src/core/SharedContext.h b/oxygine/src/core/SharedContext.h new file mode 100644 index 000000000..b74a1f809 --- /dev/null +++ b/oxygine/src/core/SharedContext.h @@ -0,0 +1,60 @@ +#ifndef SHAREDCONTEXT_H +#define SHAREDCONTEXT_H + +typedef void *SDL_GLContext; + +namespace oxygine +{ + /** This class creates a shared context that can be used to call OpenGL functions inside of other threads. + * + * Usage: + * + * main thread + * SharedContext::Enable(); + * + * core::init(); + * + * mythread.sharedContext.create(); + * + * mythread + * void run() + * { + * sharedContext.makeCurrent(); + * + * while(true) { } + * } + */ + + class SharedContext + { + private: + + /** The shared context that was created. */ + SDL_GLContext _context; + + public: + + /** Allows the usage of shared OpenGL contexts. Needs to be called before core::init(). */ + static void Enable(); + + /** Creates a shared context object with no OpenGL context being created yet. */ + SharedContext() : + _context(0) + { + } + + /** Returns true when the context was created. Can be used to wait for a thread to create its context. */ + bool created() const { return _context != 0; } + + /** Creates a shared context. Can be called from the main thread. */ + void create(); + + /** Makes this context the current one. Must be called from within the thread that will use it. */ + void makeCurrent(); + + /** The destructor which releases the context again. */ + ~SharedContext(); + }; +} + +#endif // SHAREDCONTEXT_H diff --git a/oxygine/src/core/oxygine.cpp b/oxygine/src/core/oxygine.cpp index 618392264..4ccbe604e 100644 --- a/oxygine/src/core/oxygine.cpp +++ b/oxygine/src/core/oxygine.cpp @@ -574,6 +574,11 @@ namespace oxygine return STDRenderer::isReady(); } + void makeContextCurrent() + { + SDL_GL_MakeCurrent(_window, _context); + } + bool beginRendering(window w) { diff --git a/oxygine/src/core/oxygine.h b/oxygine/src/core/oxygine.h index 06383cc4c..379c8a153 100644 --- a/oxygine/src/core/oxygine.h +++ b/oxygine/src/core/oxygine.h @@ -89,6 +89,10 @@ namespace oxygine /**returns True if device is ready for rendering*/ bool isReady2Render(); + + /***makes the global context the current one. Handy for when sharing OpenGL contexts*/ + void makeContextCurrent(); + /**returns True if device is ready for rendering*/ bool beginRendering(window i = 0);