canvas/Library_oglcanvas.mk | 3 canvas/Module_canvas.mk | 1 canvas/Package_opengl.mk | 22 canvas/opengl/dummyVertexShader.glsl | 17 canvas/opengl/linearMultiColorGradientFragmentShader.glsl | 45 canvas/opengl/linearTwoColorGradientFragmentShader.glsl | 26 canvas/opengl/radialMultiColorGradientFragmentShader.glsl | 48 canvas/opengl/radialTwoColorGradientFragmentShader.glsl | 28 canvas/opengl/rectangularMultiColorGradientFragmentShader.glsl | 44 canvas/opengl/rectangularTwoColorGradientFragmentShader.glsl | 25 canvas/source/opengl/ogl_buffercontext.hxx | 9 canvas/source/opengl/ogl_canvascustomsprite.cxx | 12 canvas/source/opengl/ogl_canvashelper.cxx | 4 canvas/source/opengl/ogl_canvastools.cxx | 5 canvas/source/opengl/ogl_spritecanvas.cxx | 3 canvas/source/opengl/ogl_spritedevicehelper.cxx | 802 ---------- canvas/source/opengl/ogl_spritedevicehelper.hxx | 36 canvas/source/opengl/ogl_texturecache.cxx | 4 canvas/source/opengl/ogl_tools.hxx | 2 configure.ac | 3 include/vcl/opengl/OpenGLContext.hxx | 3 include/vcl/opengl/OpenGLHelper.hxx | 6 vcl/source/opengl/OpenGLContext.cxx | 10 vcl/source/opengl/OpenGLHelper.cxx | 40 24 files changed, 399 insertions(+), 799 deletions(-)
New commits: commit 396fa3b663efb2f0b125c6328732263133590b3f Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Fri Aug 8 05:28:02 2014 +0200 reimplement custom sprite rendering with FBO Change-Id: I8d7a54fac61a3072d4f34615e71e37c70dec4e50 diff --git a/canvas/source/opengl/ogl_buffercontext.hxx b/canvas/source/opengl/ogl_buffercontext.hxx index 7d85e9a..a99446b 100644 --- a/canvas/source/opengl/ogl_buffercontext.hxx +++ b/canvas/source/opengl/ogl_buffercontext.hxx @@ -10,20 +10,25 @@ #ifndef INCLUDED_CANVAS_SOURCE_OPENGL_OGL_BUFFERCONTEXT_HXX #define INCLUDED_CANVAS_SOURCE_OPENGL_OGL_BUFFERCONTEXT_HXX +#include <GL/glew.h> + #include <sal/config.h> #include <boost/shared_ptr.hpp> + namespace oglcanvas { struct IBufferContext { virtual ~IBufferContext() {} - /// start render to buffer. changes gl current context + /// start render to buffer. changes current framebuffer virtual bool startBufferRendering() = 0; - /// end render to buffer. switches to window context, and selects rendered texture + /// end render to buffer. switches to default framebuffer virtual bool endBufferRendering() = 0; + + virtual GLuint getTextureId() = 0; }; typedef ::boost::shared_ptr<IBufferContext> IBufferContextSharedPtr; diff --git a/canvas/source/opengl/ogl_canvascustomsprite.cxx b/canvas/source/opengl/ogl_canvascustomsprite.cxx index 86cbac6..2f2853e 100644 --- a/canvas/source/opengl/ogl_canvascustomsprite.cxx +++ b/canvas/source/opengl/ogl_canvascustomsprite.cxx @@ -159,9 +159,8 @@ namespace oglcanvas // composite that to screen // TODO(P3): buffer texture - // TODO: moggi: reimplement as FBO with rendering to texture - pBufferContext = NULL; - // pBufferContext->startBufferRendering(); + pBufferContext = maCanvasHelper.getDeviceHelper()->createBufferContext(aSpriteSizePixel); + pBufferContext->startBufferRendering(); } // this ends up in pBufferContext, if that one's "current" @@ -174,6 +173,8 @@ namespace oglcanvas // screen now. Calls below switches us back to window // context, and binds to generated, dynamic texture pBufferContext->endBufferRendering(); + GLuint nTexture = pBufferContext->getTextureId(); + glBindTexture(GL_TEXTURE_2D, nTexture); glEnable(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, diff --git a/canvas/source/opengl/ogl_spritedevicehelper.cxx b/canvas/source/opengl/ogl_spritedevicehelper.cxx index cd29f37..3f6b534 100644 --- a/canvas/source/opengl/ogl_spritedevicehelper.cxx +++ b/canvas/source/opengl/ogl_spritedevicehelper.cxx @@ -537,21 +537,29 @@ namespace oglcanvas namespace { - /* - * TODO: mogg: reimplement through FBO with texture as backend class BufferContextImpl : public IBufferContext { ::basegfx::B2IVector maSize; const SpriteDeviceHelper& mrDeviceHelper; + GLuint mnFrambufferId; + GLuint mnDepthId; + GLuint mnTextureId; virtual bool startBufferRendering() SAL_OVERRIDE { - return false; + glBindFramebuffer(GL_FRAMEBUFFER, mnFrambufferId); + return true; } virtual bool endBufferRendering() SAL_OVERRIDE { - return false; + glBindFramebuffer(GL_FRAMEBUFFER, 0); + return true; + } + + virtual GLuint getTextureId() SAL_OVERRIDE + { + return mnTextureId; } public: @@ -559,20 +567,26 @@ namespace oglcanvas const ::basegfx::B2IVector& rSize) : maSize(rSize), mrDeviceHelper(rDeviceHelper), - mnTexture(0) + mnFrambufferId(0), + mnDepthId(0), + mnTextureId(0) { + OpenGLHelper::createFramebuffer(maSize.getX(), maSize.getY(), mnFrambufferId, + mnDepthId, mnTextureId, false); } virtual ~BufferContextImpl() { + glDeleteTextures(1, &mnTextureId); + glDeleteRenderbuffers(1, &mnDepthId); + glDeleteFramebuffers(1, &mnFrambufferId); } }; - */ } - IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& ) const + IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& rSize) const { - return NULL; + return IBufferContextSharedPtr(new BufferContextImpl(*this, rSize)); } TextureCache& SpriteDeviceHelper::getTextureCache() const commit d4b80b6c3ea3bddd041d84dacb990ddf343aa0ad Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Fri Aug 8 05:05:11 2014 +0200 fix variable name Change-Id: I1cfd6d59e5569177d8ad23245435073d30fe1374 diff --git a/include/vcl/opengl/OpenGLHelper.hxx b/include/vcl/opengl/OpenGLHelper.hxx index 0134697..52093c2 100644 --- a/include/vcl/opengl/OpenGLHelper.hxx +++ b/include/vcl/opengl/OpenGLHelper.hxx @@ -34,7 +34,7 @@ public: * This also affects whether to free with glDeleteRenderbuffers or glDeleteTextures */ static void createFramebuffer(long nWidth, long nHeight, GLuint& nFramebufferId, - GLuint& nRenderbufferTextId, GLuint& nRenderbufferColorId, bool bRenderbuffer = true); + GLuint& nRenderbufferDepthId, GLuint& nRenderbufferColorId, bool bRenderbuffer = true); // Get OpenGL version (needs a context) static float getGLVersion(); commit 5ace9183ba92ad44207f8f8e57a1665bd52062ae Author: Markus Mohrhard <markus.mohrh...@collabora.co.uk> Date: Fri Aug 8 04:52:38 2014 +0200 add possibility to generate FBO with texture The caller is responsible to delete the buffers. Depending on bRenderbuffer either with glDeleteRenderbuffers or with glDeleteTextures. Change-Id: I5ccbd49862c381abf04e812765cced485a083f89 diff --git a/include/vcl/opengl/OpenGLHelper.hxx b/include/vcl/opengl/OpenGLHelper.hxx index f80d34b..0134697 100644 --- a/include/vcl/opengl/OpenGLHelper.hxx +++ b/include/vcl/opengl/OpenGLHelper.hxx @@ -30,9 +30,11 @@ public: /** * The caller is responsible for deleting the buffer objects identified by * nFramebufferId, nRenderbufferDepthId and nRenderbufferColorId + * @param bRenderbuffer true => off-screen rendering, false => rendering to texture + * This also affects whether to free with glDeleteRenderbuffers or glDeleteTextures */ - static void createFramebuffer(long nWidth, long nHeight, - GLuint& nFramebufferId, GLuint& nRenderbufferTextId, GLuint& nRenderbufferColorId); + static void createFramebuffer(long nWidth, long nHeight, GLuint& nFramebufferId, + GLuint& nRenderbufferTextId, GLuint& nRenderbufferColorId, bool bRenderbuffer = true); // Get OpenGL version (needs a context) static float getGLVersion(); diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index a34ad75..d58b537 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -275,8 +275,8 @@ std::ostream& operator<<(std::ostream& rStrm, const glm::mat4& rMatrix) return rStrm; } -void OpenGLHelper::createFramebuffer(long nWidth, long nHeight, - GLuint& nFramebufferId, GLuint& nRenderbufferDepthId, GLuint& nRenderbufferColorId) +void OpenGLHelper::createFramebuffer(long nWidth, long nHeight, GLuint& nFramebufferId, + GLuint& nRenderbufferDepthId, GLuint& nRenderbufferColorId, bool bRenderbuffer) { // create a renderbuffer for depth attachment glGenRenderbuffers(1, &nRenderbufferDepthId); @@ -284,13 +284,31 @@ void OpenGLHelper::createFramebuffer(long nWidth, long nHeight, glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, nWidth, nHeight); glBindRenderbuffer(GL_RENDERBUFFER, 0); - // create a renderbuffer for color attachment - glGenRenderbuffers(1, &nRenderbufferColorId); - glBindRenderbuffer(GL_RENDERBUFFER, nRenderbufferColorId); - glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, nWidth, nHeight); - glBindRenderbuffer(GL_RENDERBUFFER, 0); + if(bRenderbuffer) + { + // create a renderbuffer for color attachment + glGenRenderbuffers(1, &nRenderbufferColorId); + glBindRenderbuffer(GL_RENDERBUFFER, nRenderbufferColorId); + glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, nWidth, nHeight); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } + else + { + glGenTextures(1, &nRenderbufferColorId); + glBindTexture(GL_TEXTURE_2D, nRenderbufferColorId); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, nWidth, nHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + glBindTexture(GL_TEXTURE_2D, 0); + + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, nRenderbufferColorId, 0); + } - // create a framebuffer object and attach renderbuffer and texture + // create a framebuffer object and attach renderbuffer glGenFramebuffers(1, &nFramebufferId); glCheckFramebufferStatus(GL_FRAMEBUFFER); glBindFramebuffer(GL_FRAMEBUFFER, nFramebufferId); commit 779ae371b152748aecf2ea81eca1bdbbf0226389 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Fri Aug 8 01:55:33 2014 +0200 reuse OpenGLContext in OGL canvas The only thing that needs to be reimplemented is the pbuffer based custom sprite rendering. We should use a FBO with a texture backend for that. This will also save several OpenGL context switches! Change-Id: I4aef33ae2499e44c8b5f41c296d8721cb94a37a1 diff --git a/canvas/Library_oglcanvas.mk b/canvas/Library_oglcanvas.mk index b179e3b..a5efb6b 100644 --- a/canvas/Library_oglcanvas.mk +++ b/canvas/Library_oglcanvas.mk @@ -43,12 +43,12 @@ $(eval $(call gb_Library_add_exception_objects,oglcanvas,\ $(eval $(call gb_Library_use_externals,oglcanvas,\ boost_headers \ + glew \ )) ifeq ($(strip $(OS)),MACOSX) $(eval $(call gb_Library_use_system_darwin_frameworks,oglcanvas,\ Cocoa \ - GLUT \ OpenGL \ )) diff --git a/canvas/source/opengl/ogl_canvascustomsprite.cxx b/canvas/source/opengl/ogl_canvascustomsprite.cxx index 2943f8a..86cbac6 100644 --- a/canvas/source/opengl/ogl_canvascustomsprite.cxx +++ b/canvas/source/opengl/ogl_canvascustomsprite.cxx @@ -25,10 +25,7 @@ #include <basegfx/polygon/b2dpolygontriangulator.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx> -#include <GL/gl.h> -#include <GL/glu.h> -#include <GL/glext.h> - +#include <GL/glew.h> using namespace ::com::sun::star; @@ -161,10 +158,10 @@ namespace oglcanvas // drats. need to render to temp surface before, and then // composite that to screen - // TODO(P3): buffer pbuffer, maybe even keep content - // (in a texture?) - pBufferContext=maCanvasHelper.getDeviceHelper()->createBufferContext(aSpriteSizePixel); - pBufferContext->startBufferRendering(); + // TODO(P3): buffer texture + // TODO: moggi: reimplement as FBO with rendering to texture + pBufferContext = NULL; + // pBufferContext->startBufferRendering(); } // this ends up in pBufferContext, if that one's "current" diff --git a/canvas/source/opengl/ogl_canvashelper.cxx b/canvas/source/opengl/ogl_canvashelper.cxx index d6db4db..f869179 100644 --- a/canvas/source/opengl/ogl_canvashelper.cxx +++ b/canvas/source/opengl/ogl_canvashelper.cxx @@ -36,9 +36,7 @@ #include "ogl_texturecache.hxx" #include "ogl_tools.hxx" -#include <GL/gl.h> -#include <GL/glu.h> -#include <GL/glext.h> +#include <GL/glew.h> #include <boost/scoped_array.hpp> diff --git a/canvas/source/opengl/ogl_canvastools.cxx b/canvas/source/opengl/ogl_canvastools.cxx index 36693f3..bc5a147 100644 --- a/canvas/source/opengl/ogl_canvastools.cxx +++ b/canvas/source/opengl/ogl_canvastools.cxx @@ -22,10 +22,7 @@ #include <com/sun/star/rendering/ARGBColor.hpp> -#include <GL/gl.h> -#include <GL/glu.h> -#include <GL/glext.h> - +#include <GL/glew.h> using namespace ::com::sun::star; diff --git a/canvas/source/opengl/ogl_spritecanvas.cxx b/canvas/source/opengl/ogl_spritecanvas.cxx index 32f1db4..3073e2b 100644 --- a/canvas/source/opengl/ogl_spritecanvas.cxx +++ b/canvas/source/opengl/ogl_spritecanvas.cxx @@ -27,9 +27,6 @@ #include "ogl_canvascustomsprite.hxx" -#include <GL/gl.h> -#include <GL/glext.h> - #define SPRITECANVAS_SERVICE_NAME "com.sun.star.rendering.SpriteCanvas.OGL" #define SPRITECANVAS_IMPLEMENTATION_NAME "com.sun.star.comp.rendering.SpriteCanvas.OGL" diff --git a/canvas/source/opengl/ogl_spritedevicehelper.cxx b/canvas/source/opengl/ogl_spritedevicehelper.cxx index c7d3bea..cd29f37 100644 --- a/canvas/source/opengl/ogl_spritedevicehelper.cxx +++ b/canvas/source/opengl/ogl_spritedevicehelper.cxx @@ -30,29 +30,10 @@ #include <vcl/canvastools.hxx> #include <toolkit/helper/vclunohelper.hxx> -#define GL_GLEXT_PROTOTYPES -#include <GL/gl.h> -#include <GL/glu.h> -#include <GL/glext.h> - -namespace unx -{ - #include <X11/keysym.h> - #include <X11/X.h> - #include <GL/glx.h> - #include <GL/glxext.h> -} - +#include <vcl/opengl/OpenGLHelper.hxx> using namespace ::com::sun::star; -static bool lcl_bErrorTriggered=false; -static int lcl_XErrorHandler( unx::Display*, unx::XErrorEvent* ) -{ - lcl_bErrorTriggered = true; - return 0; -} - static void initContext() { // need the backside for mirror effects @@ -92,251 +73,14 @@ static void initTransformation(const ::Size& rSize, bool bMirror=false) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -static boost::shared_ptr<SystemChildWindow> createChildWindow( unx::XVisualInfo*& viWin, - unx::XVisualInfo*& viPB, - void*& fbConfig, - Window& rWindow, - unx::Display* pDisplay, - int nScreen ) -{ - // select appropriate visual - static int winAttrList3[] = - { - GLX_RGBA,//only TrueColor or DirectColor - //single buffered - GLX_RED_SIZE,4,//use the maximum red bits, with a minimum of 4 bits - GLX_GREEN_SIZE,4,//use the maximum green bits, with a minimum of 4 bits - GLX_BLUE_SIZE,4,//use the maximum blue bits, with a minimum of 4 bits - GLX_DEPTH_SIZE,0,//no depth buffer - None - }; - static int pBufAttrList3[] = - { - GLX_DOUBLEBUFFER,False,// never doublebuffer pbuffer - GLX_RED_SIZE,4,//use the maximum red bits, with a minimum of 4 bits - GLX_GREEN_SIZE,4,//use the maximum green bits, with a minimum of 4 bits - GLX_BLUE_SIZE,4,//use the maximum blue bits, with a minimum of 4 bits - GLX_ALPHA_SIZE,4, - GLX_DEPTH_SIZE,0,//no depth buffer - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT, - None - }; - static int winAttrList2[] = - { - GLX_RGBA,//only TrueColor or DirectColor - /// single buffered - GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits - GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits - GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits - GLX_DEPTH_SIZE,1,/// use the maximum depth bits, making sure there is a depth buffer - None - }; - static int pBufAttrList2[] = - { - GLX_DOUBLEBUFFER,False,// never doublebuffer pbuffer - GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits - GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits - GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits - GLX_ALPHA_SIZE,4, - GLX_DEPTH_SIZE,1,/// use the maximum depth bits, making sure there is a depth buffer - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT, - None - }; - static int winAttrList1[] = - { - GLX_RGBA,//only TrueColor or DirectColor - GLX_DOUBLEBUFFER,/// only double buffer - GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits - GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits - GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits - GLX_DEPTH_SIZE,0,/// no depth buffer - None - }; - static int pBufAttrList1[] = - { - GLX_DOUBLEBUFFER,False,// never doublebuffer pbuffer - GLX_RED_SIZE,4,/// use the maximum red bits, with a minimum of 4 bits - GLX_GREEN_SIZE,4,/// use the maximum green bits, with a minimum of 4 bits - GLX_BLUE_SIZE,4,/// use the maximum blue bits, with a minimum of 4 bits - GLX_ALPHA_SIZE,4, - GLX_DEPTH_SIZE,0,/// no depth buffer - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT, - None - }; - static int winAttrList0[] = - { - GLX_RGBA,//only TrueColor or DirectColor - GLX_DOUBLEBUFFER,// only double buffer - GLX_RED_SIZE,4,// use the maximum red bits, with a minimum of 4 bits - GLX_GREEN_SIZE,4,// use the maximum green bits, with a minimum of 4 bits - GLX_BLUE_SIZE,4,// use the maximum blue bits, with a minimum of 4 bits - GLX_DEPTH_SIZE,1,// use the maximum depth bits, making sure there is a depth buffer - None - }; - static int pBufAttrList0[] = - { - GLX_DOUBLEBUFFER,False,// never doublebuffer pbuffer - GLX_RED_SIZE,4,// use the maximum red bits, with a minimum of 4 bits - GLX_GREEN_SIZE,4,// use the maximum green bits, with a minimum of 4 bits - GLX_BLUE_SIZE,4,// use the maximum blue bits, with a minimum of 4 bits - GLX_ALPHA_SIZE,4, - GLX_DEPTH_SIZE,1,// use the maximum depth bits, making sure there is a depth buffer - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_DRAWABLE_TYPE, GLX_PBUFFER_BIT | GLX_WINDOW_BIT, - None - }; - static int* winAttrTable[] = - { - winAttrList0, - winAttrList1, - winAttrList2, - winAttrList3, - NULL - }; - static int* pBufAttrTable[] = - { - pBufAttrList0, - pBufAttrList1, - pBufAttrList2, - pBufAttrList3, - NULL - }; - int** pWinAttributeTable = winAttrTable; - int** pBufAttributeTable = pBufAttrTable; - - boost::shared_ptr<SystemChildWindow> pResult; - unx::GLXFBConfig* fbConfigs=NULL; - int nConfigs, nVal; - while( *pWinAttributeTable && *pBufAttributeTable ) - { - // try to find a window visual for the current set of - // attributes - viWin = unx::glXChooseVisual( pDisplay, - nScreen, - *pWinAttributeTable ); - if( viWin ) - { - // try to find a framebuffer config for the current set of - // attributes - fbConfigs = glXChooseFBConfig( pDisplay, - nScreen, - *pBufAttributeTable, - &nConfigs ); - // don't use glXGetFBConfigs, that does not list alpha-configs - // fbConfigs = unx::glXGetFBConfigs(pDisplay, nScreen, &nConfigs); - for(int i=0; i<nConfigs; i++) - { - viPB = glXGetVisualFromFBConfig(pDisplay, fbConfigs[i]); - if( viPB && viPB->visualid != viWin->visualid ) - { - glXGetFBConfigAttrib(pDisplay, - fbConfigs[i], - GLX_DRAWABLE_TYPE, - &nVal); - - if( (GLX_PBUFFER_BIT|GLX_WINDOW_BIT|GLX_PIXMAP_BIT) - == (nVal & (GLX_PBUFFER_BIT|GLX_WINDOW_BIT|GLX_PIXMAP_BIT)) ) - { - SystemWindowData winData; - winData.nSize = sizeof(winData); - SAL_INFO("canvas.ogl", "using VisualID " << viWin->visualid << " for OpenGL canvas"); - winData.pVisual = (void*)(viWin->visual); - pResult.reset( new SystemChildWindow(&rWindow, 0, &winData, false) ); - - if( pResult->GetSystemData() ) - { - fbConfig = &fbConfigs[i]; - return pResult; - } - - pResult.reset(); - } - - XFree(viPB); - } - } - - XFree(viWin); - } - - ++pWinAttributeTable; - ++pBufAttributeTable; - } - - return pResult; -} - - namespace oglcanvas { - /** Compile shader program - - Code courtesy rodo - */ - void SpriteDeviceHelper::compileShader(unsigned int& o_rShaderHandle, - unsigned int eShaderType, - const char* pShaderSourceCode) - { - GLint nCompileStatus; - char log[1024]; - - o_rShaderHandle = glCreateShader( eShaderType ); - glShaderSource( o_rShaderHandle, 1, &pShaderSourceCode, NULL ); - glCompileShader( o_rShaderHandle ); - glGetShaderInfoLog( o_rShaderHandle, sizeof(log), NULL, log ); - SAL_INFO("canvas.ogl", "shader compile log: " << log); - - glGetShaderiv( o_rShaderHandle, GL_COMPILE_STATUS, &nCompileStatus ); - if( !nCompileStatus ) - { - glDeleteShader(o_rShaderHandle); - o_rShaderHandle=0; - } - } - - /** Link vertex & fragment shaders - - Code courtesy rodo - */ - void SpriteDeviceHelper::linkShaders(unsigned int& o_rProgramHandle, - unsigned int nVertexProgramId, - unsigned int nFragmentProgramId) - { - if( !nVertexProgramId || !nFragmentProgramId ) - return; - - o_rProgramHandle = glCreateProgram(); - glAttachShader( o_rProgramHandle, nVertexProgramId ); - glAttachShader( o_rProgramHandle, nFragmentProgramId ); - - char log[1024]; - GLint nProgramLinked; - - glLinkProgram( o_rProgramHandle ); - glGetProgramInfoLog( o_rProgramHandle, sizeof(log), NULL, log ); - SAL_INFO("canvas.ogl", "shader program link log: " << log); - glGetProgramiv( o_rProgramHandle, GL_LINK_STATUS, &nProgramLinked ); - - if( !nProgramLinked ) - { - glDeleteProgram(o_rProgramHandle); - o_rProgramHandle=0; - } - } SpriteDeviceHelper::SpriteDeviceHelper() : mpDevice(NULL), mpSpriteCanvas(NULL), maActiveSprites(), maLastUpdate(), - mpChildWindow(), - mpDisplay(NULL), - mpGLContext(NULL), - mpGLPBufContext(NULL), - mpFBConfig(NULL), mpTextureCache(new TextureCache()), mnLinearTwoColorGradientProgram(0), mnLinearMultiColorGradientProgram(0), @@ -357,126 +101,31 @@ namespace oglcanvas VCLUnoHelper::GetInterface(&rWindow), uno::UNO_QUERY_THROW) ); - // init OpenGL - const SystemEnvData* sysData(rWindow.GetSystemData()); - unx::Display* pDisplay=reinterpret_cast<unx::Display*>(sysData->pDisplay); - mpDisplay=pDisplay; - if( !unx::glXQueryExtension(pDisplay, NULL, NULL) ) - return; - - unx::Window xWindow = sysData->aWindow; - unx::XWindowAttributes xAttr; - unx::XGetWindowAttributes( pDisplay, xWindow, &xAttr ); - int nScreen = XScreenNumberOfScreen( xAttr.screen ); - - unx::Window childXWindow=0; - unx::XVisualInfo* viWin=NULL; - unx::XVisualInfo* viPB=NULL; - mpChildWindow=createChildWindow(viWin,viPB,mpFBConfig, - rWindow,pDisplay,nScreen); - - // tweak SysChild window to act as an input-transparent - // overlay - if( mpChildWindow ) - { - childXWindow=mpChildWindow->GetSystemData()->aWindow; - mpChildWindow->SetMouseTransparent(true); - mpChildWindow->SetParentClipMode( PARENTCLIPMODE_NOCLIP ); - mpChildWindow->EnableEraseBackground(false); - mpChildWindow->SetControlForeground(); - mpChildWindow->SetControlBackground(); - mpChildWindow->EnablePaint(false); - - unx::GLXContext pContext1 = - glXCreateContext(pDisplay, - viWin, - 0, - GL_TRUE); - mpGLContext = pContext1; - - unx::GLXContext pContext2 = - glXCreateContext( pDisplay, - viPB, - pContext1, - GL_TRUE ); - mpGLPBufContext = pContext2; - - XFree(viWin); - XFree(viPB); - - if( !glXMakeCurrent( pDisplay, - childXWindow, - pContext1) ) - { - glXDestroyContext(pDisplay, pContext1); - glXDestroyContext(pDisplay, pContext2); - throw lang::NoSupportException("Could not select OpenGL context!"); - } - - const GLubyte* extensions=glGetString( GL_EXTENSIONS ); - if( gluCheckExtension((const GLubyte*)"GLX_SGI_swap_control", extensions) ) - { - // try to enable vsync - typedef GLint (*glXSwapIntervalProc)(GLint); - glXSwapIntervalProc glXSwapInterval = - (glXSwapIntervalProc) unx::glXGetProcAddress((const GLubyte*)"glXSwapIntervalSGI"); - if( glXSwapInterval ) - { - int (*oldHandler)(unx::Display*, unx::XErrorEvent*); - - // synchronize on global mutex - no other ogl - // canvas instance permitted to enter here - { - ::osl::MutexGuard aGuard( *::osl::Mutex::getGlobalMutex() ); - - // replace error handler temporarily - oldHandler = unx::XSetErrorHandler( lcl_XErrorHandler ); - - lcl_bErrorTriggered = false; - - // Note: if this fails, so be it. Buggy - // drivers will then not have vsync. - glXSwapInterval(1); - - // sync so that we possibly get an XError - unx::glXWaitGL(); - XSync(pDisplay, false); - - unx::XSetErrorHandler( oldHandler ); - } - } - } - - // init window context - initContext(); - - mnLinearMultiColorGradientProgram = - OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearMultiColorGradientFragmentShader.glsl"); + maContext.init(&rWindow); + // init window context + initContext(); - mnLinearTwoColorGradientProgram = - OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearTwoColorGradientFragmentShader.glsl"); + mnLinearMultiColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearMultiColorGradientFragmentShader.glsl"); - mnRadialMultiColorGradientProgram = - OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialMultiColorGradientFragmentShader.glsl"); + mnLinearTwoColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearTwoColorGradientFragmentShader.glsl"); - mnRadialTwoColorGradientProgram = - OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialTwoColorGradientFragmentShader.glsl"); + mnRadialMultiColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialMultiColorGradientFragmentShader.glsl"); - mnRectangularMultiColorGradientProgram = - OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularMultiColorGradientFragmentShader.glsl"); + mnRadialTwoColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialTwoColorGradientFragmentShader.glsl"); - mnRectangularTwoColorGradientProgram = - OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularTwoColorGradientFragmentShader.glsl"); + mnRectangularMultiColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularMultiColorGradientFragmentShader.glsl"); - glXMakeCurrent(pDisplay, None, NULL); - } + mnRectangularTwoColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularTwoColorGradientFragmentShader.glsl"); - if( !mpGLContext || glGetError() != GL_NO_ERROR ) - throw lang::NoSupportException( - "Could not create OpenGL context, or an error occurred doing so!"); + maContext.makeCurrent(); notifySizeUpdate(rViewArea); - mpChildWindow->Show(); // TODO(E3): check for GL_ARB_imaging extension } @@ -487,7 +136,7 @@ namespace oglcanvas mpDevice = NULL; mpTextureCache.reset(); - if( mpGLContext ) + if( maContext.isInitialized() ) { glDeleteProgram( mnRectangularTwoColorGradientProgram ); glDeleteProgram( mnRectangularMultiColorGradientProgram ); @@ -495,40 +144,35 @@ namespace oglcanvas glDeleteProgram( mnRadialMultiColorGradientProgram ); glDeleteProgram( mnLinearTwoColorGradientProgram ); glDeleteProgram( mnLinearMultiColorGradientProgram ); - - glXDestroyContext(reinterpret_cast<unx::Display*>(mpDisplay), - reinterpret_cast<unx::GLXContext>(mpGLContext)); } - - mpDisplay = NULL; - mpGLContext = NULL; - mpChildWindow.reset(); } geometry::RealSize2D SpriteDeviceHelper::getPhysicalResolution() { - if( !mpChildWindow ) + if( !maContext.isInitialized() ) return ::canvas::tools::createInfiniteSize2D(); // we're disposed // Map a one-by-one millimeter box to pixel - const MapMode aOldMapMode( mpChildWindow->GetMapMode() ); - mpChildWindow->SetMapMode( MapMode(MAP_MM) ); - const Size aPixelSize( mpChildWindow->LogicToPixel(Size(1,1)) ); - mpChildWindow->SetMapMode( aOldMapMode ); + SystemChildWindow* pChildWindow = maContext.getChildWindow(); + const MapMode aOldMapMode( pChildWindow->GetMapMode() ); + pChildWindow->SetMapMode( MapMode(MAP_MM) ); + const Size aPixelSize( pChildWindow->LogicToPixel(Size(1,1)) ); + pChildWindow->SetMapMode( aOldMapMode ); return ::vcl::unotools::size2DFromSize( aPixelSize ); } geometry::RealSize2D SpriteDeviceHelper::getPhysicalSize() { - if( !mpChildWindow ) + if( !maContext.isInitialized() ) return ::canvas::tools::createInfiniteSize2D(); // we're disposed // Map the pixel dimensions of the output window to millimeter - const MapMode aOldMapMode( mpChildWindow->GetMapMode() ); - mpChildWindow->SetMapMode( MapMode(MAP_MM) ); - const Size aLogSize( mpChildWindow->PixelToLogic(mpChildWindow->GetOutputSizePixel()) ); - mpChildWindow->SetMapMode( aOldMapMode ); + SystemChildWindow* pChildWindow = maContext.getChildWindow(); + const MapMode aOldMapMode( pChildWindow->GetMapMode() ); + pChildWindow->SetMapMode( MapMode(MAP_MM) ); + const Size aLogSize( pChildWindow->PixelToLogic(pChildWindow->GetOutputSizePixel()) ); + pChildWindow->SetMapMode( aOldMapMode ); return ::vcl::unotools::size2DFromSize( aLogSize ); } @@ -650,13 +294,14 @@ namespace oglcanvas bool SpriteDeviceHelper::showBuffer( bool bIsVisible, bool /*bUpdateAll*/ ) { // hidden or disposed? - if( !bIsVisible || !mpChildWindow || !mpSpriteCanvas ) + if( !bIsVisible || !maContext.isInitialized() || !mpSpriteCanvas ) return false; if( !activateWindowContext() ) return false; - const ::Size& rOutputSize=mpChildWindow->GetSizePixel(); + SystemChildWindow* pChildWindow = maContext.getChildWindow(); + const ::Size& rOutputSize = pChildWindow->GetSizePixel(); initTransformation(rOutputSize); // render the actual spritecanvas content @@ -695,13 +340,17 @@ namespace oglcanvas aVec.push_back(mpTextureCache->getCacheHitCount()); renderOSD( aVec, 20 ); + /* + * TODO: moggi: fix it! // switch buffer, sync etc. - const unx::Window aXWindow=mpChildWindow->GetSystemData()->aWindow; + const unx::Window aXWindow=pChildWindow->GetSystemData()->aWindow; unx::glXSwapBuffers(reinterpret_cast<unx::Display*>(mpDisplay), aXWindow); - mpChildWindow->Show(); + pChildWindow->Show(); unx::glXWaitGL(); XSync( reinterpret_cast<unx::Display*>(mpDisplay), false ); + */ + maContext.swapBuffers(); // flush texture cache, such that it does not build up // indefinitely. @@ -725,7 +374,8 @@ namespace oglcanvas uno::Any SpriteDeviceHelper::getDeviceHandle() const { - return uno::makeAny( reinterpret_cast< sal_Int64 >(mpChildWindow.get()) ); + const SystemChildWindow* pChildWindow = maContext.getChildWindow(); + return uno::makeAny( reinterpret_cast< sal_Int64 >(pChildWindow) ); } uno::Any SpriteDeviceHelper::getSurfaceHandle() const @@ -743,9 +393,12 @@ namespace oglcanvas void SpriteDeviceHelper::notifySizeUpdate( const awt::Rectangle& rBounds ) { - if( mpChildWindow ) - mpChildWindow->setPosSizePixel( + if( maContext.isInitialized() ) + { + SystemChildWindow* pChildWindow = maContext.getChildWindow(); + pChildWindow->setPosSizePixel( 0,0,rBounds.Width,rBounds.Height); + } } void SpriteDeviceHelper::dumpScreenContent() const @@ -875,146 +528,51 @@ namespace oglcanvas setupUniforms(mnRectangularTwoColorGradientProgram, pColors[0], pColors[1], rTexTransform); } - bool SpriteDeviceHelper::activatePBufferContext(const ::basegfx::B2IVector& rSize, - unsigned int PBuffer) const + bool SpriteDeviceHelper::activateWindowContext() { - if( !glXMakeCurrent( reinterpret_cast<unx::Display*>(mpDisplay), - PBuffer, - reinterpret_cast<unx::GLXContext>(mpGLPBufContext)) ) - { - SAL_INFO("canvas.ogl", "SpriteDeviceHelper::activatePBufferContext(): cannot activate GL context"); - return false; - } - - initContext(); - initTransformation( - ::Size( - rSize.getX(), - rSize.getY()), - true); - - return true; - } - - bool SpriteDeviceHelper::activateWindowContext() const - { - const unx::Window aXWindow=mpChildWindow->GetSystemData()->aWindow; - if( !glXMakeCurrent( reinterpret_cast<unx::Display*>(mpDisplay), - aXWindow, - reinterpret_cast<unx::GLXContext>(mpGLContext)) ) - { - SAL_INFO("canvas.ogl", "SpriteDeviceHelper::activateWindowContext(): cannot activate GL context"); - return false; - } - - return true; - } - - bool SpriteDeviceHelper::updatePBufferTexture( const ::basegfx::B2IVector& rSize, - unsigned int nTextId ) const - { - glBindTexture( GL_TEXTURE_2D, nTextId ); - glEnable(GL_TEXTURE_2D); - glCopyTexSubImage2D( GL_TEXTURE_2D, - 0, 0, 0, 0, 0, - rSize.getX(), - rSize.getY() ); - glBindTexture(GL_TEXTURE_2D, 0); - + maContext.makeCurrent(); return true; } namespace { + + /* + * TODO: mogg: reimplement through FBO with texture as backend class BufferContextImpl : public IBufferContext { ::basegfx::B2IVector maSize; const SpriteDeviceHelper& mrDeviceHelper; - unx::GLXPbuffer mpPBuffer; -#if 0 - unx::Display* mpDisplay; -#endif - unsigned int mnTexture; virtual bool startBufferRendering() SAL_OVERRIDE { - return mrDeviceHelper.activatePBufferContext(maSize,mpPBuffer); + return false; } virtual bool endBufferRendering() SAL_OVERRIDE { - mrDeviceHelper.updatePBufferTexture(maSize,mnTexture); - if( !mrDeviceHelper.activateWindowContext() ) - return false; - - glBindTexture( GL_TEXTURE_2D, mnTexture ); - - return true; + return false; } public: BufferContextImpl(const SpriteDeviceHelper& rDeviceHelper, - unx::GLXPbuffer pBuffer, - unx::Display* -#if 0 - pDisplay -#endif - , const ::basegfx::B2IVector& rSize) : maSize(rSize), mrDeviceHelper(rDeviceHelper), - mpPBuffer(pBuffer), -#if 0 - mpDisplay(pDisplay), -#endif mnTexture(0) { - glGenTextures( 1, &mnTexture ); -#if 1 - glBindTexture( GL_TEXTURE_2D, mnTexture ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, - maSize.getX(), maSize.getY(), - 0, GL_RGBA, GL_UNSIGNED_BYTE, new int[maSize.getX()*maSize.getY()] ); -#endif } virtual ~BufferContextImpl() { -#if 0 - glBindTexture(GL_TEXTURE_2D, 0); - glDeleteTextures( 1, &mnTexture ); - glXDestroyPbuffer( mpDisplay, mpPBuffer ); -#endif } }; + */ } - IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& rSize) const + IBufferContextSharedPtr SpriteDeviceHelper::createBufferContext(const ::basegfx::B2IVector& ) const { - int pBufAttribs[] = - { - GLX_PBUFFER_WIDTH, rSize.getX(), - GLX_PBUFFER_HEIGHT, rSize.getY(), - GLX_LARGEST_PBUFFER, False, - None - }; - - unx::GLXPbuffer pBuffer; - pBuffer = unx::glXCreatePbuffer( reinterpret_cast<unx::Display*>(mpDisplay), - *reinterpret_cast<unx::GLXFBConfig*>(mpFBConfig), - pBufAttribs ); - - IBufferContextSharedPtr pRet; - if( pBuffer ) - pRet.reset(new BufferContextImpl( - *this, - pBuffer, - reinterpret_cast<unx::Display*>(mpDisplay), - rSize)); - - return pRet; + return NULL; } TextureCache& SpriteDeviceHelper::getTextureCache() const diff --git a/canvas/source/opengl/ogl_spritedevicehelper.hxx b/canvas/source/opengl/ogl_spritedevicehelper.hxx index 5fe9ed1..f43a3af 100644 --- a/canvas/source/opengl/ogl_spritedevicehelper.hxx +++ b/canvas/source/opengl/ogl_spritedevicehelper.hxx @@ -10,6 +10,8 @@ #ifndef INCLUDED_CANVAS_SOURCE_OPENGL_OGL_SPRITEDEVICEHELPER_HXX #define INCLUDED_CANVAS_SOURCE_OPENGL_OGL_SPRITEDEVICEHELPER_HXX +#include <vcl/opengl/OpenGLContext.hxx> + #include <rtl/ref.hxx> #include <canvas/elapsedtime.hxx> #include <com/sun/star/rendering/XGraphicDevice.hpp> @@ -20,7 +22,6 @@ #include <set> - class Window; class SystemChildWindow; namespace basegfx{ class B2IVector; class B2DHomMatrix; } @@ -113,26 +114,11 @@ namespace oglcanvas /// Get instance of internal texture cache TextureCache& getTextureCache() const; - - - // nobody except IBufferContext implementations are supposed - // to use this - bool activatePBufferContext(const ::basegfx::B2IVector& rSize, - unsigned int PBuffer) const; - bool activateWindowContext() const; - bool updatePBufferTexture( const ::basegfx::B2IVector&, - unsigned int ) const; + bool activateWindowContext(); private: void resize( const ::basegfx::B2IVector& rNewSize ); - void compileShader(unsigned int& o_rShaderHandle, - unsigned int eShaderType, - const char* pShaderSourceCode); - void linkShaders(unsigned int& o_rProgramHandle, - unsigned int nVertexProgramId, - unsigned int nFragmentProgramId); - /** Phyical output device Deliberately not a refcounted reference, because of @@ -149,28 +135,16 @@ namespace oglcanvas /// For the frame counter timings ::canvas::tools::ElapsedTime maLastUpdate; - boost::shared_ptr<SystemChildWindow> mpChildWindow; - void* mpDisplay; - void* mpGLContext; - void* mpGLPBufContext; - void* mpFBConfig; - boost::shared_ptr<TextureCache> mpTextureCache; - unsigned int mnDummyVertexProgram; - - unsigned int mnLinearTwoColorGradientFragmentProgram; - unsigned int mnLinearMultiColorGradientFragmentProgram; - unsigned int mnRadialTwoColorGradientFragmentProgram; - unsigned int mnRadialMultiColorGradientFragmentProgram; - unsigned int mnRectangularTwoColorGradientFragmentProgram; - unsigned int mnRectangularMultiColorGradientFragmentProgram; unsigned int mnLinearTwoColorGradientProgram; unsigned int mnLinearMultiColorGradientProgram; unsigned int mnRadialTwoColorGradientProgram; unsigned int mnRadialMultiColorGradientProgram; unsigned int mnRectangularTwoColorGradientProgram; unsigned int mnRectangularMultiColorGradientProgram; + + OpenGLContext maContext; }; } diff --git a/canvas/source/opengl/ogl_texturecache.cxx b/canvas/source/opengl/ogl_texturecache.cxx index 952f36a..426e69c 100644 --- a/canvas/source/opengl/ogl_texturecache.cxx +++ b/canvas/source/opengl/ogl_texturecache.cxx @@ -13,9 +13,7 @@ #include <com/sun/star/geometry/IntegerSize2D.hpp> -#include <GL/gl.h> -#include <GL/glu.h> -#include <GL/glext.h> +#include <GL/glew.h> using namespace ::com::sun::star; diff --git a/canvas/source/opengl/ogl_tools.hxx b/canvas/source/opengl/ogl_tools.hxx index 6c23be7..8133212 100644 --- a/canvas/source/opengl/ogl_tools.hxx +++ b/canvas/source/opengl/ogl_tools.hxx @@ -11,7 +11,7 @@ #define INCLUDED_CANVAS_SOURCE_OPENGL_OGL_TOOLS_HXX #include <sal/config.h> -#include <GL/gl.h> +#include <GL/glew.h> namespace oglcanvas diff --git a/configure.ac b/configure.ac index ee388ea..38cb6bd 100644 --- a/configure.ac +++ b/configure.ac @@ -10556,8 +10556,7 @@ if test "x$enable_opengl" = "xno"; then elif test "$_os" = "Darwin"; then # We use frameworks on Mac OS X, no need for detail checks ENABLE_OPENGL=TRUE - ENABLE_OPENGL_CANVAS= - add_warning "openGL canvas not adapted for Mac yet - disabling" + ENABLE_OPENGL_CANVAS=TRUE SYSTEM_MESA_HEADERS=TRUE AC_MSG_RESULT([yes]) elif test $_os = WINNT; then diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx index 0dc0fa5..8faaf7b 100644 --- a/include/vcl/opengl/OpenGLContext.hxx +++ b/include/vcl/opengl/OpenGLContext.hxx @@ -162,6 +162,9 @@ public: void setWinSize(const Size& rSize); GLWindow& getOpenGLWindow() { return m_aGLWin;} + SystemChildWindow* getChildWindow(); + const SystemChildWindow* getChildWindow() const; + void renderToFile(); bool isInitialized() diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx index c17bcac..ca61f0e 100644 --- a/vcl/source/opengl/OpenGLContext.cxx +++ b/vcl/source/opengl/OpenGLContext.cxx @@ -898,4 +898,14 @@ void OpenGLContext::show() m_pWindow->Show(); } +SystemChildWindow* OpenGLContext::getChildWindow() +{ + return m_pChildWindow; +} + +const SystemChildWindow* OpenGLContext::getChildWindow() const +{ + return m_pChildWindow; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit a7f3c73fd76b6955862a77cbb403b7b5b47582bd Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Thu Aug 7 00:01:02 2014 +0200 extract shaders to own file and use shared shader loading Change-Id: I1af7e03a3e46f3cb49162be9351ce22f54d08c52 diff --git a/canvas/Library_oglcanvas.mk b/canvas/Library_oglcanvas.mk index fca6996..b179e3b 100644 --- a/canvas/Library_oglcanvas.mk +++ b/canvas/Library_oglcanvas.mk @@ -20,6 +20,7 @@ $(eval $(call gb_Library_use_libraries,oglcanvas,\ cppuhelper \ comphelper \ vcl \ + vclopengl \ tk \ tl \ i18nlangtag \ diff --git a/canvas/Module_canvas.mk b/canvas/Module_canvas.mk index 310ad2a..a655ed1 100644 --- a/canvas/Module_canvas.mk +++ b/canvas/Module_canvas.mk @@ -24,6 +24,7 @@ $(eval $(call gb_Module_add_targets,canvas,\ Library_canvastools \ Library_simplecanvas \ Library_vclcanvas \ + Package_opengl \ )) ifeq ($(ENABLE_CAIRO_CANVAS),TRUE) diff --git a/canvas/Package_opengl.mk b/canvas/Package_opengl.mk new file mode 100644 index 0000000..af256bf --- /dev/null +++ b/canvas/Package_opengl.mk @@ -0,0 +1,22 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_Package_Package,canvas_opengl_shader,$(SRCDIR)/canvas/opengl)) + +$(eval $(call gb_Package_add_files,canvas_opengl_shader,$(LIBO_BIN_FOLDER)/opengl,\ + dummyVertexShader.glsl \ + linearMultiColorGradientFragmentShader.glsl \ + linearTwoColorGradientFragmentShader.glsl \ + radialMultiColorGradientFragmentShader.glsl \ + radialTwoColorGradientFragmentShader.glsl \ + rectangularMultiColorGradientFragmentShader.glsl \ + rectangularTwoColorGradientFragmentShader.glsl \ +)) + +# vim: set noet sw=4 ts=4: diff --git a/canvas/opengl/dummyVertexShader.glsl b/canvas/opengl/dummyVertexShader.glsl new file mode 100644 index 0000000..2948ee9 --- /dev/null +++ b/canvas/opengl/dummyVertexShader.glsl @@ -0,0 +1,17 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +varying vec2 v_textureCoords2d; +void main(void) +{ + gl_Position = ftransform(); + v_textureCoords2d = gl_MultiTexCoord0.st; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/opengl/linearMultiColorGradientFragmentShader.glsl b/canvas/opengl/linearMultiColorGradientFragmentShader.glsl new file mode 100644 index 0000000..a3f3358 --- /dev/null +++ b/canvas/opengl/linearMultiColorGradientFragmentShader.glsl @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#version 120 + +uniform int i_nColors; +uniform sampler1D t_colorArray4d; +uniform sampler1D t_stopArray1d; +uniform mat3x2 m_transform; +varying vec2 v_textureCoords2d; + +int findBucket(float t) +{ + int nMinBucket=0; + while( nMinBucket < i_nColors && + texture1D(t_stopArray1d, nMinBucket).s < t ) + ++nMinBucket; + return max(nMinBucket-1,0); +} + +void main(void) +{ + const float fAlpha = + clamp( (m_transform * vec3(v_textureCoords2d,1)).s, + 0.0, 1.0 ); + + const int nMinBucket=findBucket( fAlpha ); + + const float fLerp = + (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) / + (texture1D(t_stopArray1d, nMinBucket+1).s - + texture1D(t_stopArray1d, nMinBucket).s); + + gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket), + texture1D(t_colorArray4d, nMinBucket+1), + fLerp); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/opengl/linearTwoColorGradientFragmentShader.glsl b/canvas/opengl/linearTwoColorGradientFragmentShader.glsl new file mode 100644 index 0000000..8659bfd --- /dev/null +++ b/canvas/opengl/linearTwoColorGradientFragmentShader.glsl @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#version 120 + +uniform vec4 v_startColor4d; +uniform vec4 v_endColor4d; +uniform mat3x2 m_transform; +varying vec2 v_textureCoords2d; + +void main(void) +{ + gl_FragColor = mix(v_startColor4d, + v_endColor4d, + clamp( + (m_transform * vec3(v_textureCoords2d,1)).s, + 0.0, 1.0)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/opengl/radialMultiColorGradientFragmentShader.glsl b/canvas/opengl/radialMultiColorGradientFragmentShader.glsl new file mode 100644 index 0000000..6f61a76 --- /dev/null +++ b/canvas/opengl/radialMultiColorGradientFragmentShader.glsl @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#version 120 + +uniform int i_nColors; +uniform sampler1D t_colorArray4d; +uniform sampler1D t_stopArray1d; +uniform mat3x2 m_transform; +varying vec2 v_textureCoords2d; +const vec2 v_center2d = vec2(0,0); + +int findBucket(float t) +{ + int nMinBucket=0; + while( nMinBucket < i_nColors && + texture1D(t_stopArray1d, nMinBucket).s < t ) + ++nMinBucket; + return max(nMinBucket-1,0); +} + +void main(void) +{ + const float fAlpha = + clamp( 1.0 - distance( + vec2( m_transform * vec3(v_textureCoords2d,1)), + v_center2d), + 0.0, 1.0 ); + + const int nMinBucket=findBucket( fAlpha ); + + const float fLerp = + (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) / + (texture1D(t_stopArray1d, nMinBucket+1).s - + texture1D(t_stopArray1d, nMinBucket).s); + + gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket), + texture1D(t_colorArray4d, nMinBucket+1), + fLerp); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/opengl/radialTwoColorGradientFragmentShader.glsl b/canvas/opengl/radialTwoColorGradientFragmentShader.glsl new file mode 100644 index 0000000..a5d6134 --- /dev/null +++ b/canvas/opengl/radialTwoColorGradientFragmentShader.glsl @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#version 120 + +uniform vec4 v_startColor4d; +uniform vec4 v_endColor4d; +uniform mat3x2 m_transform; +varying vec2 v_textureCoords2d; +const vec2 v_center2d = vec2(0,0); + +void main(void) +{ + gl_FragColor = mix(v_startColor4d, + v_endColor4d, + 1.0 - distance( + vec2( + m_transform * vec3(v_textureCoords2d,1)), + v_center2d)); + } + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/opengl/rectangularMultiColorGradientFragmentShader.glsl b/canvas/opengl/rectangularMultiColorGradientFragmentShader.glsl new file mode 100644 index 0000000..05a8ae5 --- /dev/null +++ b/canvas/opengl/rectangularMultiColorGradientFragmentShader.glsl @@ -0,0 +1,44 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#version 120 + +uniform int i_nColors; +uniform sampler1D t_colorArray4d; +uniform sampler1D t_stopArray1d; +uniform mat3x2 m_transform; +varying vec2 v_textureCoords2d; + +int findBucket(float t) +{ + int nMinBucket=0; + while( nMinBucket < i_nColors && + texture1D(t_stopArray1d, nMinBucket).s < t ) + ++nMinBucket; + return max(nMinBucket-1,0); +} + +void main(void) +{ + const vec2 v = abs( vec2(m_transform * vec3(v_textureCoords2d,1)) ); + const float fAlpha = 1 - max(v.x, v.y); + + const int nMinBucket=findBucket( fAlpha ); + + const float fLerp = + (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) / + (texture1D(t_stopArray1d, nMinBucket+1).s - + texture1D(t_stopArray1d, nMinBucket).s); + + gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket), + texture1D(t_colorArray4d, nMinBucket+1), + fLerp); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/opengl/rectangularTwoColorGradientFragmentShader.glsl b/canvas/opengl/rectangularTwoColorGradientFragmentShader.glsl new file mode 100644 index 0000000..a92a533 --- /dev/null +++ b/canvas/opengl/rectangularTwoColorGradientFragmentShader.glsl @@ -0,0 +1,25 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#version 120 + +uniform vec4 v_startColor4d; +uniform vec4 v_endColor4d; +uniform mat3x2 m_transform; +varying vec2 v_textureCoords2d; +void main(void) +{ + const vec2 v = abs( vec2(m_transform * vec3(v_textureCoords2d,1)) ); + const float t = max(v.x, v.y); + gl_FragColor = mix(v_startColor4d, + v_endColor4d, + 1.0-t); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/canvas/source/opengl/ogl_spritedevicehelper.cxx b/canvas/source/opengl/ogl_spritedevicehelper.cxx index 781beaf..c7d3bea 100644 --- a/canvas/source/opengl/ogl_spritedevicehelper.cxx +++ b/canvas/source/opengl/ogl_spritedevicehelper.cxx @@ -53,197 +53,6 @@ static int lcl_XErrorHandler( unx::Display*, unx::XErrorEvent* ) return 0; } -/** Dummy vertex processing. Simply uses default pipeline for vertex - transformation, and forwards texture coodinates to fragment shader - */ -static const char dummyVertexShader[] = -{ - "varying vec2 v_textureCoords2d; " - "void main(void) " - "{ " - " gl_Position = ftransform(); " - " v_textureCoords2d = gl_MultiTexCoord0.st; " - "} " -}; - -/** Two-color linear gradient - */ -static const char linearTwoColorGradientFragmentShader[] = -{ - "#version 120 \n" - "uniform vec4 v_startColor4d; " - "uniform vec4 v_endColor4d; " - "uniform mat3x2 m_transform; " - "varying vec2 v_textureCoords2d; " - "void main(void) " - "{ " - " gl_FragColor = mix(v_startColor4d, " - " v_endColor4d, " - " clamp( " - " (m_transform * vec3(v_textureCoords2d,1)).s, " - " 0.0, 1.0)); " - "} " -}; - -/** N-color linear gradient - */ -static const char linearMultiColorGradientFragmentShader[] = -{ - "#version 120 \n" - "uniform int i_nColors; " - "uniform sampler1D t_colorArray4d; " - "uniform sampler1D t_stopArray1d; " - "uniform mat3x2 m_transform; " - "varying vec2 v_textureCoords2d; " - " " - "int findBucket(float t) " - "{ " - " int nMinBucket=0; " - " while( nMinBucket < i_nColors && " - " texture1D(t_stopArray1d, nMinBucket).s < t ) " - " ++nMinBucket; " - " return max(nMinBucket-1,0); " - "} " - " " - "void main(void) " - "{ " - " const float fAlpha = " - " clamp( (m_transform * vec3(v_textureCoords2d,1)).s, " - " 0.0, 1.0 ); " - " " - " const int nMinBucket=findBucket( fAlpha ); " - " " - " const float fLerp = " - " (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) / " - " (texture1D(t_stopArray1d, nMinBucket+1).s - " - " texture1D(t_stopArray1d, nMinBucket).s); " - " " - " gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket), " - " texture1D(t_colorArray4d, nMinBucket+1), " - " fLerp); " - "} " -}; - -/** Two-color radial gradient - */ -static const char radialTwoColorGradientFragmentShader[] = -{ - "#version 120 \n" - "uniform vec4 v_startColor4d; " - "uniform vec4 v_endColor4d; " - "uniform mat3x2 m_transform; " - "varying vec2 v_textureCoords2d; " - "const vec2 v_center2d = vec2(0,0); " - "void main(void) " - "{ " - " gl_FragColor = mix(v_startColor4d, " - " v_endColor4d, " - " 1.0 - distance( " - " vec2( " - " m_transform * vec3(v_textureCoords2d,1)), " - " v_center2d)); " - "} " -}; - -/** Multi-color radial gradient - */ -static const char radialMultiColorGradientFragmentShader[] = -{ - "#version 120 \n" - "uniform int i_nColors; " - "uniform sampler1D t_colorArray4d; " - "uniform sampler1D t_stopArray1d; " - "uniform mat3x2 m_transform; " - "varying vec2 v_textureCoords2d; " - "const vec2 v_center2d = vec2(0,0); " - " " - "int findBucket(float t) " - "{ " - " int nMinBucket=0; " - " while( nMinBucket < i_nColors && " - " texture1D(t_stopArray1d, nMinBucket).s < t ) " - " ++nMinBucket; " - " return max(nMinBucket-1,0); " - "} " - " " - "void main(void) " - "{ " - " const float fAlpha = " - " clamp( 1.0 - distance( " - " vec2( m_transform * vec3(v_textureCoords2d,1)), " - " v_center2d), " - " 0.0, 1.0 ); " - " " - " const int nMinBucket=findBucket( fAlpha ); " - " " - " const float fLerp = " - " (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) / " - " (texture1D(t_stopArray1d, nMinBucket+1).s - " - " texture1D(t_stopArray1d, nMinBucket).s); " - " " - " gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket), " - " texture1D(t_colorArray4d, nMinBucket+1), " - " fLerp); " - "} " -}; - -/** Two-color rectangular gradient - */ -static const char rectangularTwoColorGradientFragmentShader[] = -{ - "#version 120 \n" - "uniform vec4 v_startColor4d; " - "uniform vec4 v_endColor4d; " - "uniform mat3x2 m_transform; " - "varying vec2 v_textureCoords2d; " - "void main(void) " - "{ " - " const vec2 v = abs( vec2(m_transform * vec3(v_textureCoords2d,1)) ); " - " const float t = max(v.x, v.y); " - " gl_FragColor = mix(v_startColor4d, " - " v_endColor4d, " - " 1.0-t); " - "} " -}; - -/** Multi-color rectangular gradient - */ -static const char rectangularMultiColorGradientFragmentShader[] = -{ - "#version 120 \n" - "uniform int i_nColors; " - "uniform sampler1D t_colorArray4d; " - "uniform sampler1D t_stopArray1d; " - "uniform mat3x2 m_transform; " - "varying vec2 v_textureCoords2d; " - " " - "int findBucket(float t) " - "{ " - " int nMinBucket=0; " - " while( nMinBucket < i_nColors && " - " texture1D(t_stopArray1d, nMinBucket).s < t ) " - " ++nMinBucket; " - " return max(nMinBucket-1,0); " - "} " - " " - "void main(void) " - "{ " - " const vec2 v = abs( vec2(m_transform * vec3(v_textureCoords2d,1)) ); " - " const float fAlpha = 1 - max(v.x, v.y); " - " " - " const int nMinBucket=findBucket( fAlpha ); " - " " - " const float fLerp = " - " (fAlpha-texture1D(t_stopArray1d, nMinBucket).s) / " - " (texture1D(t_stopArray1d, nMinBucket+1).s - " - " texture1D(t_stopArray1d, nMinBucket).s); " - " " - " gl_FragColor = mix(texture1D(t_colorArray4d, nMinBucket), " - " texture1D(t_colorArray4d, nMinBucket+1), " - " fLerp); " - "} " -}; - static void initContext() { // need the backside for mirror effects @@ -529,13 +338,6 @@ namespace oglcanvas mpGLPBufContext(NULL), mpFBConfig(NULL), mpTextureCache(new TextureCache()), - mnDummyVertexProgram(0), - mnLinearTwoColorGradientFragmentProgram(0), - mnLinearMultiColorGradientFragmentProgram(0), - mnRadialTwoColorGradientFragmentProgram(0), - mnRadialMultiColorGradientFragmentProgram(0), - mnRectangularTwoColorGradientFragmentProgram(0), - mnRectangularMultiColorGradientFragmentProgram(0), mnLinearTwoColorGradientProgram(0), mnLinearMultiColorGradientProgram(0), mnRadialTwoColorGradientProgram(0), @@ -648,46 +450,23 @@ namespace oglcanvas // init window context initContext(); - // compile & link shaders - code courtesy rodo - compileShader(mnDummyVertexProgram, - GL_VERTEX_SHADER, - dummyVertexShader); - compileShader(mnLinearTwoColorGradientFragmentProgram, - GL_FRAGMENT_SHADER, - linearTwoColorGradientFragmentShader); - compileShader(mnLinearMultiColorGradientFragmentProgram, - GL_FRAGMENT_SHADER, - linearMultiColorGradientFragmentShader); - compileShader(mnRadialTwoColorGradientFragmentProgram, - GL_FRAGMENT_SHADER, - radialTwoColorGradientFragmentShader); - compileShader(mnRadialMultiColorGradientFragmentProgram, - GL_FRAGMENT_SHADER, - radialMultiColorGradientFragmentShader); - compileShader(mnRectangularTwoColorGradientFragmentProgram, - GL_FRAGMENT_SHADER, - rectangularTwoColorGradientFragmentShader); - compileShader(mnRectangularMultiColorGradientFragmentProgram, - GL_FRAGMENT_SHADER, - rectangularMultiColorGradientFragmentShader); - linkShaders(mnLinearTwoColorGradientProgram, - mnDummyVertexProgram, - mnLinearTwoColorGradientFragmentProgram); - linkShaders(mnLinearMultiColorGradientProgram, - mnDummyVertexProgram, - mnLinearMultiColorGradientFragmentProgram); - linkShaders(mnRadialTwoColorGradientProgram, - mnDummyVertexProgram, - mnRadialTwoColorGradientFragmentProgram); - linkShaders(mnRadialMultiColorGradientProgram, - mnDummyVertexProgram, - mnRadialMultiColorGradientFragmentProgram); - linkShaders(mnRectangularTwoColorGradientProgram, - mnDummyVertexProgram, - mnRectangularTwoColorGradientFragmentProgram); - linkShaders(mnRectangularMultiColorGradientProgram, - mnDummyVertexProgram, - mnRectangularMultiColorGradientFragmentProgram); + mnLinearMultiColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearMultiColorGradientFragmentShader.glsl"); + + mnLinearTwoColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "linearTwoColorGradientFragmentShader.glsl"); + + mnRadialMultiColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialMultiColorGradientFragmentShader.glsl"); + + mnRadialTwoColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "radialTwoColorGradientFragmentShader.glsl"); + + mnRectangularMultiColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularMultiColorGradientFragmentShader.glsl"); + + mnRectangularTwoColorGradientProgram = + OpenGLHelper::LoadShaders("dummyVertexShader.glsl", "rectangularTwoColorGradientFragmentShader.glsl"); glXMakeCurrent(pDisplay, None, NULL); } @@ -716,13 +495,6 @@ namespace oglcanvas glDeleteProgram( mnRadialMultiColorGradientProgram ); glDeleteProgram( mnLinearTwoColorGradientProgram ); glDeleteProgram( mnLinearMultiColorGradientProgram ); - glDeleteShader( mnRectangularTwoColorGradientFragmentProgram ); - glDeleteShader( mnRectangularMultiColorGradientFragmentProgram ); - glDeleteShader( mnRadialTwoColorGradientFragmentProgram ); - glDeleteShader( mnRadialMultiColorGradientFragmentProgram ); - glDeleteShader( mnLinearTwoColorGradientFragmentProgram ); - glDeleteShader( mnLinearMultiColorGradientFragmentProgram ); - glDeleteShader( mnDummyVertexProgram ); glXDestroyContext(reinterpret_cast<unx::Display*>(mpDisplay), reinterpret_cast<unx::GLXContext>(mpGLContext)); commit 56d45b721f15946acaf1c6ee7c4c0003fbe1d554 Author: Markus Mohrhard <markus.mohrh...@googlemail.com> Date: Wed Aug 6 23:49:30 2014 +0200 make sure that we always delete the shader and not only the program Change-Id: Ia02fb20d335e2172f607f13a0de78ea666d094f5 diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index 84a1399..a34ad75 100644 --- a/vcl/source/opengl/OpenGLHelper.cxx +++ b/vcl/source/opengl/OpenGLHelper.cxx @@ -122,6 +122,9 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString glAttachShader(ProgramID, FragmentShaderID); glLinkProgram(ProgramID); + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + // Check the program glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); if ( !Result ) @@ -140,9 +143,6 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString return 0; } - glDeleteShader(VertexShaderID); - glDeleteShader(FragmentShaderID); - return ProgramID; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits