summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis-Francis Ratté-Boulianne <lfrb@collabora.com>2014-11-28 14:56:08 -0500
committerJan Holesovsky <kendy@collabora.com>2014-12-02 15:47:33 +0100
commit5933c72dd39d597037528f8473fa2bf67e59a757 (patch)
tree69e6b55c32f6c5fdb68109be9757db3177835e7f
parent44239d8002792c1f6d9373db46382ac9f4d27466 (diff)
vcl: Only load OpenGL shaders once for each context
Change-Id: Idbf9026c5e64ef41d4c913153dfddf36923ff7de
-rw-r--r--include/vcl/opengl/OpenGLContext.hxx34
-rw-r--r--vcl/Library_vcl.mk1
-rw-r--r--vcl/Package_opengl.mk4
-rw-r--r--vcl/inc/opengl/program.hxx72
-rw-r--r--vcl/inc/opengl/salbmp.hxx11
-rw-r--r--vcl/inc/opengl/texture.hxx1
-rw-r--r--vcl/inc/openglgdiimpl.hxx67
-rw-r--r--vcl/opengl/dumbVertexShader.glsl (renamed from vcl/opengl/solidVertexShader.glsl)0
-rw-r--r--vcl/opengl/gdiimpl.cxx754
-rw-r--r--vcl/opengl/maskVertexShader.glsl19
-rw-r--r--vcl/opengl/maskedTextureVertexShader.glsl19
-rw-r--r--vcl/opengl/program.cxx238
-rw-r--r--vcl/opengl/salbmp.cxx7
-rw-r--r--vcl/opengl/scale.cxx96
-rw-r--r--vcl/opengl/texture.cxx29
-rw-r--r--vcl/source/opengl/OpenGLContext.cxx35
16 files changed, 569 insertions, 818 deletions
diff --git a/include/vcl/opengl/OpenGLContext.hxx b/include/vcl/opengl/OpenGLContext.hxx
index 6d9948864bdf..843821dd75d4 100644
--- a/include/vcl/opengl/OpenGLContext.hxx
+++ b/include/vcl/opengl/OpenGLContext.hxx
@@ -51,11 +51,13 @@ class NSOpenGLView;
#include <vcl/vclopengl_dllapi.hxx>
#include <boost/scoped_ptr.hpp>
+#include <boost/unordered_map.hpp>
#include <vcl/window.hxx>
#include <tools/gen.hxx>
#include <vcl/syschild.hxx>
class OpenGLFramebuffer;
+class OpenGLProgram;
class OpenGLTexture;
/// Holds the information of our new child window
@@ -156,6 +158,31 @@ struct GLWindow
~GLWindow();
};
+struct ProgramKey
+{
+ OUString maVertexShader;
+ OUString maFragmentShader;
+
+ ProgramKey( const OUString& rVertexShader, const OUString& rFragmentShader )
+ {
+ maVertexShader = rVertexShader;
+ maFragmentShader = rFragmentShader;
+ }
+};
+
+inline bool operator==( ProgramKey const& k1, ProgramKey const& k2 )
+{
+ return k1.maVertexShader == k2.maVertexShader && k1.maFragmentShader == k2.maFragmentShader;
+}
+
+inline std::size_t hash_value( ProgramKey const& rKey )
+{
+ std::size_t nSeed = 0x9e3779b9;
+ nSeed = rKey.maVertexShader.hashCode();
+ nSeed = rKey.maFragmentShader.hashCode() + 0x9e3779b9 + (nSeed << 6) + (nSeed >> 2);
+ return nSeed;
+}
+
class VCLOPENGL_DLLPUBLIC OpenGLContext
{
public:
@@ -185,6 +212,10 @@ public:
OpenGLFramebuffer* AcquireFramebuffer( const OpenGLTexture& rTexture );
void ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer );
+ // retrieve a program from the cache or compile/link it
+ OpenGLProgram* GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
+ OpenGLProgram* UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
+
void makeCurrent();
void resetCurrent();
void swapBuffers();
@@ -241,6 +272,9 @@ private:
OpenGLFramebuffer* mpFirstFramebuffer;
OpenGLFramebuffer* mpLastFramebuffer;
+ boost::unordered_map<ProgramKey, OpenGLProgram*> maPrograms;
+ OpenGLProgram* mpCurrentProgram;
+
public:
vcl::Region maClipRegion;
int mnPainting;
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index a7b901fe6fbe..ccf3ddb1aeea 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -127,6 +127,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/opengl/salbmp \
vcl/opengl/scale \
vcl/opengl/framebuffer \
+ vcl/opengl/program \
vcl/opengl/texture \
vcl/source/opengl/OpenGLContext \
vcl/source/opengl/OpenGLHelper \
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk
index d81c0ec4bd0c..98ff78b5d77c 100644
--- a/vcl/Package_opengl.mk
+++ b/vcl/Package_opengl.mk
@@ -12,16 +12,14 @@ $(eval $(call gb_Package_Package,vcl_opengl_shader,$(SRCDIR)/vcl/opengl))
$(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\
blendedTextureFragmentShader.glsl \
blendedTextureVertexShader.glsl \
+ dumbVertexShader.glsl \
diffTextureFragmentShader.glsl \
convolutionFragmentShader.glsl \
linearGradientFragmentShader.glsl \
maskFragmentShader.glsl \
- maskVertexShader.glsl \
maskedTextureFragmentShader.glsl \
- maskedTextureVertexShader.glsl \
radialGradientFragmentShader.glsl \
solidFragmentShader.glsl \
- solidVertexShader.glsl \
textureFragmentShader.glsl \
textureVertexShader.glsl \
transformedTextureVertexShader.glsl \
diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx
new file mode 100644
index 000000000000..4b2b26ffb95e
--- /dev/null
+++ b/vcl/inc/opengl/program.hxx
@@ -0,0 +1,72 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_VCL_INC_OPENGL_PROGRAM_H
+#define INCLUDED_VCL_INC_OPENGL_PROGRAM_H
+
+#include <GL/glew.h>
+#include <vcl/dllapi.h>
+
+#include <basegfx/point/b2dpoint.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/color.hxx>
+#include <opengl/texture.hxx>
+
+#include <boost/unordered_map.hpp>
+
+typedef boost::unordered_map< OString, GLuint, OStringHash > UniformCache;
+typedef std::list< OpenGLTexture > TextureList;
+
+class VCL_PLUGIN_PUBLIC OpenGLProgram
+{
+private:
+ GLuint mnId;
+ UniformCache maUniformLocations;
+ sal_uInt32 mnEnabledAttribs;
+ GLuint mnAttribIndex;
+ GLuint mnPositionAttrib;
+ GLuint mnTexCoordAttrib;
+ GLuint mnAlphaCoordAttrib;
+ TextureList maTextures;
+ bool mbBlending;
+
+public:
+ OpenGLProgram();
+ ~OpenGLProgram();
+
+ bool Load( const OUString& rVertexShader, const OUString& rFragmentShader );
+ bool Use();
+ bool Clean();
+
+ void SetVertices( const GLvoid* pData );
+ void SetTextureCoord( const GLvoid* pData );
+ void SetAlphaCoord( const GLvoid* pData );
+
+ void SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 );
+ void SetUniform1fv( const OString& rName, GLsizei nCount, GLfloat* aValues );
+ void SetUniform2fv( const OString& rName, GLsizei nCount, GLfloat* aValues );
+ void SetColor( const OString& rName, SalColor nColor, sal_uInt8 nTransparency );
+ void SetColorf( const OString& rName, SalColor nColor, double fTransparency );
+ void SetColorWithIntensity( const OString& rName, const Color& rColor, long nFactor );
+ void SetTexture( const OString& rName, OpenGLTexture& rTexture );
+ void SetTransform( const OString& rName, const OpenGLTexture& rTexture,
+ const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX,
+ const basegfx::B2DPoint& rY );
+ void SetBlendMode( GLenum nSFactor, GLenum nDFactor );
+
+ bool DrawTexture( OpenGLTexture& rTexture );
+
+protected:
+ void SetVertexAttrib( GLuint& rAttrib, const OString& rName, const GLvoid* pData );
+ GLuint GetUniformLocation( const OString& rName );
+};
+
+#endif // INCLUDED_VCL_INC_OPENGL_PROGRAM_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/inc/opengl/salbmp.hxx b/vcl/inc/opengl/salbmp.hxx
index bc232b123380..6938a22a1846 100644
--- a/vcl/inc/opengl/salbmp.hxx
+++ b/vcl/inc/opengl/salbmp.hxx
@@ -99,17 +99,6 @@ private:
private:
- GLuint ImplGetTextureProgram();
- GLuint mnTexProgram;
- GLuint mnTexSamplerUniform;
-
- GLuint ImplGetConvolutionProgram();
- GLuint mnConvProgram;
- GLuint mnConvSamplerUniform;
- GLuint mnConvKernelUniform;
- GLuint mnConvKernelSizeUniform;
- GLuint mnConvOffsetsUniform;
-
bool ImplScaleFilter( const double& rScaleX, const double& rScaleY, GLenum nFilter );
void ImplCreateKernel( const double& fScale, const Kernel& rKernel, GLfloat*& pWeights, sal_uInt32& aKernelSize );
bool ImplScaleConvolution( const double& rScaleX, const double& rScaleY, const Kernel& aKernel );
diff --git a/vcl/inc/opengl/texture.hxx b/vcl/inc/opengl/texture.hxx
index ad4738a6948d..3d99526d2646 100644
--- a/vcl/inc/opengl/texture.hxx
+++ b/vcl/inc/opengl/texture.hxx
@@ -65,6 +65,7 @@ public:
int GetWidth() const;
int GetHeight() const;
void GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool bInverted=false ) const;
+ void GetWholeCoord( GLfloat* pCoord ) const;
void Bind();
void Unbind();
diff --git a/vcl/inc/openglgdiimpl.hxx b/vcl/inc/openglgdiimpl.hxx
index 39e39fc77752..3f3ef4ed29a1 100644
--- a/vcl/inc/openglgdiimpl.hxx
+++ b/vcl/inc/openglgdiimpl.hxx
@@ -25,6 +25,7 @@
#include <vcl/dllapi.h>
#include "opengl/framebuffer.hxx"
+#include "opengl/program.hxx"
#include "opengl/texture.hxx"
#include "regionband.hxx"
@@ -44,6 +45,7 @@ protected:
/// Pointer to the SalFrame or SalVirtualDevice
SalGeometryProvider* mpParent;
OpenGLFramebuffer* mpFramebuffer;
+ OpenGLProgram* mpProgram;
// clipping
vcl::Region maClipRegion;
@@ -56,72 +58,17 @@ protected:
SalColor mnLineColor;
SalColor mnFillColor;
- GLuint mnSolidProgram;
- GLuint mnColorUniform;
-
- GLuint mnTextureProgram;
- GLuint mnSamplerUniform;
-
- GLuint mnTransformedTextureProgram;
- GLuint mnTransformedViewportUniform;
- GLuint mnTransformedTransformUniform;
- GLuint mnTransformedSamplerUniform;
-
- GLuint mnTransformedMaskedTextureProgram;
- GLuint mnTransformedMaskedViewportUniform;
- GLuint mnTransformedMaskedTransformUniform;
- GLuint mnTransformedMaskedSamplerUniform;
- GLuint mnTransformedMaskedMaskUniform;
-
- GLuint mnDiffTextureProgram;
- GLuint mnDiffTextureUniform;
- GLuint mnDiffMaskUniform;
-
- GLuint mnMaskedTextureProgram;
- GLuint mnMaskedSamplerUniform;
- GLuint mnMaskSamplerUniform;
-
- GLuint mnBlendedTextureProgram;
- GLuint mnBlendedTextureUniform;
- GLuint mnBlendedMaskUniform;
- GLuint mnBlendedAlphaUniform;
-
- GLuint mnMaskProgram;
- GLuint mnMaskUniform;
- GLuint mnMaskColorUniform;
-
- GLuint mnLinearGradientProgram;
- GLuint mnLinearGradientStartColorUniform;
- GLuint mnLinearGradientEndColorUniform;
-
- GLuint mnRadialGradientProgram;
- GLuint mnRadialGradientStartColorUniform;
- GLuint mnRadialGradientEndColorUniform;
- GLuint mnRadialGradientCenterUniform;
-
void ImplInitClipRegion();
void ImplSetClipBit( const vcl::Region& rClip, GLuint nMask );
bool CheckOffscreenTexture();
- bool CreateSolidProgram( void );
- bool CreateTextureProgram( void );
- bool CreateTransformedTextureProgram( void );
- bool CreateDiffTextureProgram( void );
- bool CreateMaskedTextureProgram( void );
- bool CreateBlendedTextureProgram( void );
- bool CreateTransformedMaskedTextureProgram( void );
- bool CreateMaskProgram( void );
- bool CreateLinearGradientProgram( void );
- bool CreateRadialGradientProgram( void );
-
public:
- void BeginSolid( SalColor nColor, sal_uInt8 nTransparency );
- void BeginSolid( SalColor nColor, double fTransparency );
- void BeginSolid( SalColor nColor );
- void EndSolid( void );
- void BeginInvert( void );
- void EndInvert( void );
+ bool UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader );
+ bool UseSolid( SalColor nColor, sal_uInt8 nTransparency );
+ bool UseSolid( SalColor nColor, double fTransparency );
+ bool UseSolid( SalColor nColor );
+ bool UseInvert();
void DrawPoint( long nX, long nY );
void DrawLine( long nX1, long nY1, long nX2, long nY2 );
diff --git a/vcl/opengl/solidVertexShader.glsl b/vcl/opengl/dumbVertexShader.glsl
index 47061f6e4223..47061f6e4223 100644
--- a/vcl/opengl/solidVertexShader.glsl
+++ b/vcl/opengl/dumbVertexShader.glsl
diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx
index acc84a1bf309..4d362b15b4fc 100644
--- a/vcl/opengl/gdiimpl.cxx
+++ b/vcl/opengl/gdiimpl.cxx
@@ -34,77 +34,18 @@
#include "svdata.hxx"
#include "opengl/salbmp.hxx"
-#include <glm/glm.hpp>
-#include <glm/gtc/type_ptr.hpp>
#include <vector>
-#define GL_ATTRIB_POS 0
-#define GL_ATTRIB_TEX 1
-#define GL_ATTRIB_TEX2 2
-
-#define glUniformColor(nUniform, nColor, nTransparency) \
- glUniform4f( nUniform, \
- ((float) SALCOLOR_RED( nColor )) / 255, \
- ((float) SALCOLOR_GREEN( nColor )) / 255, \
- ((float) SALCOLOR_BLUE( nColor )) / 255, \
- (100 - nTransparency) * (1.0 / 100) )
-
-#define glUniformColorf(nUniform, nColor, fTransparency) \
- glUniform4f( nUniform, \
- ((float) SALCOLOR_RED( nColor )) / 255, \
- ((float) SALCOLOR_GREEN( nColor )) / 255, \
- ((float) SALCOLOR_BLUE( nColor )) / 255, \
- (1.0f - fTransparency) )
-
-#define glUniformColorIntensity(nUniform, aColor, nFactor) \
- glUniform4f( nUniform, \
- ((float) aColor.GetRed()) * nFactor / 25500.0, \
- ((float) aColor.GetGreen()) * nFactor / 25500.0, \
- ((float) aColor.GetBlue()) * nFactor / 25500.0, \
- 1.0f )
-
OpenGLSalGraphicsImpl::OpenGLSalGraphicsImpl(SalGeometryProvider* pParent)
: mpContext(0)
, mpParent(pParent)
, mpFramebuffer(NULL)
+ , mpProgram(NULL)
, mbUseScissor(false)
, mbUseStencil(false)
, mbOffscreen(false)
, mnLineColor(SALCOLOR_NONE)
, mnFillColor(SALCOLOR_NONE)
- , mnSolidProgram(0)
- , mnColorUniform(0)
- , mnTextureProgram(0)
- , mnSamplerUniform(0)
- , mnTransformedTextureProgram(0)
- , mnTransformedViewportUniform(0)
- , mnTransformedTransformUniform(0)
- , mnTransformedSamplerUniform(0)
- , mnTransformedMaskedTextureProgram(0)
- , mnTransformedMaskedViewportUniform(0)
- , mnTransformedMaskedTransformUniform(0)
- , mnTransformedMaskedSamplerUniform(0)
- , mnTransformedMaskedMaskUniform(0)
- , mnDiffTextureProgram(0)
- , mnDiffTextureUniform(0)
- , mnDiffMaskUniform(0)
- , mnMaskedTextureProgram(0)
- , mnMaskedSamplerUniform(0)
- , mnMaskSamplerUniform(0)
- , mnBlendedTextureProgram(0)
- , mnBlendedTextureUniform(0)
- , mnBlendedMaskUniform(0)
- , mnBlendedAlphaUniform(0)
- , mnMaskProgram(0)
- , mnMaskUniform(0)
- , mnMaskColorUniform(0)
- , mnLinearGradientProgram(0)
- , mnLinearGradientStartColorUniform(0)
- , mnLinearGradientEndColorUniform(0)
- , mnRadialGradientProgram(0)
- , mnRadialGradientStartColorUniform(0)
- , mnRadialGradientEndColorUniform(0)
- , mnRadialGradientCenterUniform(0)
{
}
@@ -198,6 +139,11 @@ void OpenGLSalGraphicsImpl::PostDraw()
glDisable( GL_SCISSOR_TEST );
if( mbUseStencil )
glDisable( GL_STENCIL_TEST );
+ if( mpProgram )
+ {
+ mpProgram->Clean();
+ mpProgram = NULL;
+ }
mpContext->ReleaseFramebuffer( mpFramebuffer );
mpFramebuffer = NULL;
@@ -219,12 +165,13 @@ void OpenGLSalGraphicsImpl::ImplSetClipBit( const vcl::Region& rClip, GLuint nMa
glStencilOp( GL_REPLACE, GL_KEEP, GL_KEEP );
glClear( GL_STENCIL_BUFFER_BIT );
- BeginSolid( MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) );
- if( rClip.getRegionBand() )
- DrawRegionBand( *rClip.getRegionBand() );
- else
- DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() );
- EndSolid();
+ if( UseSolid( MAKE_SALCOLOR( 0xFF, 0xFF, 0xFF ) ) )
+ {
+ if( rClip.getRegionBand() )
+ DrawRegionBand( *rClip.getRegionBand() );
+ else
+ DrawPolyPolygon( rClip.GetAsB2DPolyPolygon() );
+ }
glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
glStencilMask( 0x00 );
@@ -375,231 +322,45 @@ bool OpenGLSalGraphicsImpl::CheckOffscreenTexture()
return true;
}
-bool OpenGLSalGraphicsImpl::CreateSolidProgram( void )
-{
- SAL_INFO( "vcl.opengl", "::CreateSolidProgram" );
- mnSolidProgram = OpenGLHelper::LoadShaders( "solidVertexShader", "solidFragmentShader" );
- if( mnSolidProgram == 0 )
- return false;
-
- SAL_INFO( "vcl.opengl", "Solid Program Created" );
- glBindAttribLocation( mnSolidProgram, GL_ATTRIB_POS, "position" );
- mnColorUniform = glGetUniformLocation( mnSolidProgram, "color" );
-
- CHECK_GL_ERROR();
- return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateTextureProgram( void )
-{
- mnTextureProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "textureFragmentShader" );
- if( mnTextureProgram == 0 )
- return false;
-
- glBindAttribLocation( mnTextureProgram, GL_ATTRIB_POS, "position" );
- glBindAttribLocation( mnTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
- mnSamplerUniform = glGetUniformLocation( mnTextureProgram, "sampler" );
-
- CHECK_GL_ERROR();
- return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateTransformedTextureProgram( void )
-{
- mnTransformedTextureProgram = OpenGLHelper::LoadShaders( "transformedTextureVertexShader", "textureFragmentShader" );
- if( mnTransformedTextureProgram == 0 )
- return false;
-
- glBindAttribLocation( mnTransformedTextureProgram, GL_ATTRIB_POS, "position" );
- glBindAttribLocation( mnTransformedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
- mnTransformedViewportUniform = glGetUniformLocation( mnTransformedTextureProgram, "viewport" );
- mnTransformedTransformUniform = glGetUniformLocation( mnTransformedTextureProgram, "transform" );
- mnTransformedSamplerUniform = glGetUniformLocation( mnTransformedTextureProgram, "sampler" );
-
- CHECK_GL_ERROR();
- return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateDiffTextureProgram( void )
+bool OpenGLSalGraphicsImpl::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader )
{
- mnDiffTextureProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "diffTextureFragmentShader" );
- if( mnDiffTextureProgram == 0 )
- return false;
-
- glBindAttribLocation( mnDiffTextureProgram, GL_ATTRIB_POS, "position" );
- glBindAttribLocation( mnDiffTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
- mnDiffTextureUniform = glGetUniformLocation( mnDiffTextureProgram, "texture" );
- mnDiffMaskUniform = glGetUniformLocation( mnDiffTextureProgram, "mask" );
-
- CHECK_GL_ERROR();
- return true;
+ mpProgram = mpContext->UseProgram( rVertexShader, rFragmentShader );
+ return ( mpProgram != NULL );
}
-bool OpenGLSalGraphicsImpl::CreateMaskedTextureProgram( void )
+bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, sal_uInt8 nTransparency )
{
- mnMaskedTextureProgram = OpenGLHelper::LoadShaders( "maskedTextureVertexShader", "maskedTextureFragmentShader" );
- if( mnMaskedTextureProgram == 0 )
+ if( nColor == SALCOLOR_NONE )
return false;
-
- glBindAttribLocation( mnMaskedTextureProgram, GL_ATTRIB_POS, "position" );
- glBindAttribLocation( mnMaskedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
- mnMaskedSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "sampler" );
- mnMaskSamplerUniform = glGetUniformLocation( mnMaskedTextureProgram, "mask" );
-
- CHECK_GL_ERROR();
- return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateTransformedMaskedTextureProgram( void )
-{
- mnTransformedMaskedTextureProgram = OpenGLHelper::LoadShaders( "transformedTextureVertexShader", "maskedTextureFragmentShader" );
- if( mnTransformedMaskedTextureProgram == 0 )
+ if( !UseProgram( "dumbVertexShader", "solidFragmentShader" ) )
return false;
-
- glBindAttribLocation( mnTransformedMaskedTextureProgram, GL_ATTRIB_POS, "position" );
- glBindAttribLocation( mnTransformedMaskedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
- mnTransformedMaskedViewportUniform = glGetUniformLocation( mnTransformedMaskedTextureProgram, "viewport" );
- mnTransformedMaskedTransformUniform = glGetUniformLocation( mnTransformedMaskedTextureProgram, "transform" );
- mnTransformedMaskedSamplerUniform = glGetUniformLocation( mnTransformedMaskedTextureProgram, "sampler" );
- mnTransformedMaskedMaskUniform = glGetUniformLocation( mnTransformedMaskedTextureProgram, "mask" );
-
- CHECK_GL_ERROR();
+ mpProgram->SetColor( "color", nColor, nTransparency );
return true;
}
-bool OpenGLSalGraphicsImpl::CreateBlendedTextureProgram( void )
+bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, double fTransparency )
{
- mnBlendedTextureProgram = OpenGLHelper::LoadShaders( "blendedTextureVertexShader", "blendedTextureFragmentShader" );
- if( mnBlendedTextureProgram == 0 )
+ if( nColor == SALCOLOR_NONE )
return false;
-
- glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_POS, "position" );
- glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX, "tex_coord_in" );
- glBindAttribLocation( mnBlendedTextureProgram, GL_ATTRIB_TEX2, "alpha_coord_in" );
- mnBlendedTextureUniform = glGetUniformLocation( mnBlendedTextureProgram, "sampler" );
- mnBlendedMaskUniform = glGetUniformLocation( mnBlendedTextureProgram, "mask" );
- mnBlendedAlphaUniform = glGetUniformLocation( mnBlendedTextureProgram, "alpha" );
-
- CHECK_GL_ERROR();
- return true;
-}
-
-bool OpenGLSalGraphicsImpl::CreateMaskProgram( void )
-{
- mnMaskProgram = OpenGLHelper::LoadShaders( "maskVertexShader", "maskFragmentShader" );
- if( mnMaskProgram == 0 )
+ if( !UseProgram( "dumbVertexShader", "solidFragmentShader" ) )
return false;
-
- glBindAttribLocation( mnMaskProgram, GL_ATTRIB_POS, "position" );
- glBindAttribLocation( mnMaskProgram, GL_ATTRIB_TEX, "tex_coord_in" );
- mnMaskUniform = glGetUniformLocation( mnMaskProgram, "sampler" );
- mnMaskColorUniform = glGetUniformLocation( mnMaskProgram, "color" );
-
- CHECK_GL_ERROR();
+ mpProgram->SetColorf( "color", nColor, fTransparency );
return true;
}
-bool OpenGLSalGraphicsImpl::CreateLinearGradientProgram( void )
+bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor )
{
- mnLinearGradientProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "linearGradientFragmentShader" );
- if( mnLinearGradientProgram == 0 )
- return false;
-
- glBindAttribLocation( mnLinearGradientProgram, GL_ATTRIB_POS, "position" );
- glBindAttribLocation( mnLinearGradientProgram, GL_ATTRIB_TEX, "tex_coord_in" );
- mnLinearGradientStartColorUniform = glGetUniformLocation( mnLinearGradientProgram, "start_color" );
- mnLinearGradientEndColorUniform = glGetUniformLocation( mnLinearGradientProgram, "end_color" );
-
- CHECK_GL_ERROR();
- return true;
+ return UseSolid( nColor, 0.0f );
}
-bool OpenGLSalGraphicsImpl::CreateRadialGradientProgram( void )
+bool OpenGLSalGraphicsImpl::UseInvert()
{
- mnRadialGradientProgram = OpenGLHelper::LoadShaders( "textureVertexShader", "radialGradientFragmentShader" );
- if( mnRadialGradientProgram == 0 )
+ if( !UseSolid( MAKE_SALCOLOR( 255, 255, 255 ) ) )
return false;
-
- glBindAttribLocation( mnRadialGradientProgram, GL_ATTRIB_POS, "position" );
- glBindAttribLocation( mnRadialGradientProgram, GL_ATTRIB_TEX, "tex_coord_in" );
- mnRadialGradientStartColorUniform = glGetUniformLocation( mnRadialGradientProgram, "start_color" );
- mnRadialGradientEndColorUniform = glGetUniformLocation( mnRadialGradientProgram, "end_color" );
- mnRadialGradientCenterUniform = glGetUniformLocation( mnRadialGradientProgram, "center" );
-
- CHECK_GL_ERROR();
+ mpProgram->SetBlendMode( GL_ONE_MINUS_DST_COLOR, GL_ZERO );
return true;
}
-void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, sal_uInt8 nTransparency )
-{
- if( mnSolidProgram == 0 )
- {
- glClearColor( 1, 1, 1, 1 );
- glClear( GL_COLOR_BUFFER_BIT );
- if( !CreateSolidProgram() )
- return;
- }
-
- if( nTransparency > 0 )
- {
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- }
- glUseProgram( mnSolidProgram );
- glUniformColor( mnColorUniform, nColor, nTransparency );
-
- CHECK_GL_ERROR();
-}
-
-void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor, double fTransparency )
-{
- if( mnSolidProgram == 0 )
- {
- if( !CreateSolidProgram() )
- return;
- }
-
- if( fTransparency > 0.0f )
- {
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- }
- glUseProgram( mnSolidProgram );
- glUniformColorf( mnColorUniform, nColor, fTransparency );
-
- CHECK_GL_ERROR();
-}
-
-void OpenGLSalGraphicsImpl::BeginSolid( SalColor nColor )
-{
- BeginSolid( nColor, 0.0f );
-}
-
-void OpenGLSalGraphicsImpl::EndSolid( void )
-{
- glUseProgram( 0 );
- glDisable( GL_BLEND );
-
- CHECK_GL_ERROR();
-}
-
-void OpenGLSalGraphicsImpl::BeginInvert( void )
-{
- glEnable( GL_BLEND );
- glBlendFunc( GL_ONE_MINUS_DST_COLOR, GL_ZERO );
- BeginSolid( MAKE_SALCOLOR( 255, 255, 255 ) );
-
- CHECK_GL_ERROR();
-}
-
-void OpenGLSalGraphicsImpl::EndInvert( void )
-{
- EndSolid();
- glDisable( GL_BLEND );
-
- CHECK_GL_ERROR();
-}
-
void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
{
GLfloat pPoint[2];
@@ -607,12 +368,8 @@ void OpenGLSalGraphicsImpl::DrawPoint( long nX, long nY )
pPoint[0] = 2 * nX / GetWidth() - 1.0f;
pPoint[1] = 1.0f - 2 * nY / GetHeight();
- glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pPoint );
+ mpProgram->SetVertices( pPoint );
glDrawArrays( GL_POINTS, 0, 1 );
- glDisableVertexAttribArray( GL_ATTRIB_POS );
-
- CHECK_GL_ERROR();
}
void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
@@ -624,12 +381,8 @@ void OpenGLSalGraphicsImpl::DrawLine( long nX1, long nY1, long nX2, long nY2 )
pPoints[2] = (2 * nX2) / GetWidth() - 1.0;;
pPoints[3] = 1.0f - 2 * nY2 / GetHeight();
- glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, pPoints );
+ mpProgram->SetVertices( pPoints );
glDrawArrays( GL_LINES, 0, 2 );
- glDisableVertexAttribArray( GL_ATTRIB_POS );
-
- CHECK_GL_ERROR();
}
void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAry, bool bClose )
@@ -643,15 +396,11 @@ void OpenGLSalGraphicsImpl::DrawLines( sal_uInt32 nPoints, const SalPoint* pPtAr
aPoints[j++] = 1.0f - (2 * pPtAry[i].mnY) / GetHeight();
}
- glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aPoints[0] );
+ mpProgram->SetVertices( &aPoints[0] );
if( bClose )
glDrawArrays( GL_LINE_LOOP, 0, nPoints );
else
glDrawArrays( GL_LINE_STRIP, 0, nPoints );
- glDisableVertexAttribArray( GL_ATTRIB_POS );
-
- CHECK_GL_ERROR();
}
void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
@@ -665,12 +414,8 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin
aVertices[j+1] = 1.0 - (2 * pPtAry[i].mnY / GetHeight());
}
- glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+ mpProgram->SetVertices( &aVertices[0] );
glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
- glDisableVertexAttribArray( GL_ATTRIB_POS );
-
- CHECK_GL_ERROR();
}
void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon )
@@ -686,12 +431,8 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const Polygon& rPolygon )
aVertices[j+1] = 1.0 - (2 * rPt.Y() / GetHeight());
}
- glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+ mpProgram->SetVertices( &aVertices[0] );
glDrawArrays( GL_TRIANGLE_FAN, 0, nPoints );
- glDisableVertexAttribArray( GL_ATTRIB_POS );
-
- CHECK_GL_ERROR();
}
void OpenGLSalGraphicsImpl::DrawRect( long nX, long nY, long nWidth, long nHeight )
@@ -759,10 +500,8 @@ void OpenGLSalGraphicsImpl::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rPol
}
}
- glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, aVertices.data() );
+ mpProgram->SetVertices( aVertices.data() );
glDrawArrays( GL_TRIANGLES, 0, aVertices.size() / 2 );
- glDisableVertexAttribArray( GL_ATTRIB_POS );
CHECK_GL_ERROR();
}
@@ -794,50 +533,25 @@ void OpenGLSalGraphicsImpl::DrawRegionBand( const RegionBand& rRegion )
#undef ADD_VERTICE
- glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+ mpProgram->SetVertices( &aVertices[0] );
glDrawArrays( GL_TRIANGLES, 0, aVertices.size() / 2 );
- glDisableVertexAttribArray( GL_ATTRIB_POS );
-
- CHECK_GL_ERROR();
}
void OpenGLSalGraphicsImpl::DrawTextureRect( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted )
{
GLfloat aTexCoord[8];
-
rTexture.GetCoord( aTexCoord, rPosAry, bInverted );
- glEnableVertexAttribArray( GL_ATTRIB_TEX );
- glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-
+ mpProgram->SetTextureCoord( aTexCoord );
DrawRect( rPosAry.mnDestX, rPosAry.mnDestY, rPosAry.mnDestWidth, rPosAry.mnDestHeight );
-
- glDisableVertexAttribArray( GL_ATTRIB_TEX );
-
- CHECK_GL_ERROR();
}
void OpenGLSalGraphicsImpl::DrawTexture( OpenGLTexture& rTexture, const SalTwoRect& pPosAry, bool bInverted )
{
- if( mnTextureProgram == 0 )
- {
- if( !CreateTextureProgram() )
- return;
- }
-
- glUseProgram( mnTextureProgram );
- glUniform1i( mnSamplerUniform, 0 );
- glActiveTexture( GL_TEXTURE0 );
- CHECK_GL_ERROR();
-
- rTexture.Bind();
+ if( !UseProgram( "textureVertexShader", "textureFragmentShader" ) )
+ return;
+ mpProgram->SetTexture( "sampler", rTexture );
DrawTextureRect( rTexture, pPosAry, bInverted );
- rTexture.Unbind();
- CHECK_GL_ERROR();
-
- glUseProgram( 0 );
-
- CHECK_GL_ERROR();
+ mpProgram->Clean();
}
void OpenGLSalGraphicsImpl::DrawTransformedTexture(
@@ -847,14 +561,6 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
const basegfx::B2DPoint& rX,
const basegfx::B2DPoint& rY )
{
- const basegfx::B2DVector aXRel = rX - rNull;
- const basegfx::B2DVector aYRel = rY - rNull;
- const float aValues[] = {
- (float) aXRel.getX()/rTexture.GetWidth(), (float) aXRel.getY()/rTexture.GetWidth(), 0, 0,
- (float) aYRel.getX()/rTexture.GetHeight(), (float) aYRel.getY()/rTexture.GetHeight(), 0, 0,
- 0, 0, 1, 0,
- (float) rNull.getX(), (float) rNull.getY(), 0, 1 };
- glm::mat4 mMatrix = glm::make_mat4( aValues );
GLfloat aVertices[8] = {
0, (float) rTexture.GetHeight(), 0, 0,
(float) rTexture.GetWidth(), 0, (float) rTexture.GetWidth(), (float) rTexture.GetHeight() };
@@ -862,222 +568,98 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture(
if( rMask )
{
- if( mnTransformedMaskedTextureProgram == 0 )
- {
- if( !CreateTransformedMaskedTextureProgram() )
- return;
- }
- glUseProgram( mnTransformedMaskedTextureProgram );
- glUniform2f( mnTransformedMaskedViewportUniform, GetWidth(), GetHeight() );
- glUniformMatrix4fv( mnTransformedMaskedTransformUniform, 1, GL_FALSE, glm::value_ptr( mMatrix ) );
- glUniform1i( mnTransformedMaskedSamplerUniform, 0 );
- glUniform1i( mnTransformedMaskedMaskUniform, 1 );
- glActiveTexture( GL_TEXTURE1 );
- rMask.Bind();
+ if( !UseProgram( "transformedTextureVertexShader", "maskedTextureFragmentShader" ) )
+ return;
+ mpProgram->SetTexture( "mask", rMask );
rMask.SetFilter( GL_LINEAR );
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
}
else
{
- if( mnTransformedTextureProgram == 0 )
- {
- if( !CreateTransformedTextureProgram() )
- return;
- }
- glUseProgram( mnTransformedTextureProgram );
- glUniform2f( mnTransformedViewportUniform, GetWidth(), GetHeight() );
- glUniformMatrix4fv( mnTransformedTransformUniform, 1, GL_FALSE, glm::value_ptr( mMatrix ) );
- glUniform1i( mnTransformedSamplerUniform, 0 );
+ if( !UseProgram( "transformedTextureVertexShader", "textureFragmentShader" ) )
+ return;
}
- glActiveTexture( GL_TEXTURE0 );
- rTexture.Bind();
+ mpProgram->SetUniform2f( "viewport", GetWidth(), GetHeight() );
+ mpProgram->SetTransform( "transform", rTexture, rNull, rX, rY );
+ rTexture.GetWholeCoord( aTexCoord );
+ mpProgram->SetTexture( "sampler", rTexture );
rTexture.SetFilter( GL_LINEAR );
- CHECK_GL_ERROR();
-
- GLfloat fWidth = rTexture.GetWidth();
- GLfloat fHeight = rTexture.GetHeight();
- SalTwoRect aPosAry(0, 0, fWidth, fHeight, 0, 0, fWidth, fHeight);
- rTexture.GetCoord( aTexCoord, aPosAry );
- glEnableVertexAttribArray( GL_ATTRIB_TEX );
- glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
- glEnableVertexAttribArray( GL_ATTRIB_POS );
- glVertexAttribPointer( GL_ATTRIB_POS, 2, GL_FLOAT, GL_FALSE, 0, &aVertices[0] );
+ mpProgram->SetTextureCoord( aTexCoord );
+ mpProgram->SetVertices( &aVertices[0] );
glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
- glDisableVertexAttribArray( GL_ATTRIB_POS );
- glDisableVertexAttribArray( GL_ATTRIB_TEX );
-
- if( rMask )
- {
- glDisable( GL_BLEND );
- glActiveTexture( GL_TEXTURE1 );
- rMask.Unbind();
- }
-
- glActiveTexture( GL_TEXTURE0 );
- rTexture.Unbind();
- glUseProgram( 0 );
- CHECK_GL_ERROR();
+ mpProgram->Clean();
}
void OpenGLSalGraphicsImpl::DrawAlphaTexture( OpenGLTexture& rTexture, const SalTwoRect& rPosAry, bool bInverted, bool bPremultiplied )
{
- glEnable( GL_BLEND );
- if( bPremultiplied )
- glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
- else
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
- DrawTexture( rTexture, rPosAry, bInverted );
- glDisable( GL_BLEND );
- CHECK_GL_ERROR();
+ if( !UseProgram( "textureVertexShader", "textureFragmentShader" ) )
+ return;
+ mpProgram->SetTexture( "sampler", rTexture );
+ mpProgram->SetBlendMode( bPremultiplied ? GL_ONE : GL_SRC_ALPHA,
+ GL_ONE_MINUS_SRC_ALPHA );
+ DrawTextureRect( rTexture, rPosAry, bInverted );
+ mpProgram->Clean();
}
void OpenGLSalGraphicsImpl::DrawTextureDiff( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& rPosAry, bool bInverted )
{
- if( mnDiffTextureProgram == 0 )
- {
- if( !CreateDiffTextureProgram() )
- return;
- }
-
- glUseProgram( mnDiffTextureProgram );
- glUniform1i( mnDiffTextureUniform, 0 );
- glUniform1i( mnDiffMaskUniform, 1 );
- glActiveTexture( GL_TEXTURE0 );
- rTexture.Bind();
- glActiveTexture( GL_TEXTURE1 );
- rMask.Bind();
-
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ if( !UseProgram( "textureVertexShader", "diffTextureFragmentShader" ) )
+ return;
+ mpProgram->SetTexture( "texture", rTexture );
+ mpProgram->SetTexture( "mask", rMask );
+ mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
DrawTextureRect( rTexture, rPosAry, bInverted );
- glDisable( GL_BLEND );
-
- glActiveTexture( GL_TEXTURE1 );
- rMask.Unbind();
- glActiveTexture( GL_TEXTURE0 );
- rTexture.Unbind();
- glUseProgram( 0 );
-
- CHECK_GL_ERROR();
+ mpProgram->Clean();
}
void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGLTexture& rMask, const SalTwoRect& pPosAry )
{
- if( mnMaskedTextureProgram == 0 )
- {
- if( !CreateMaskedTextureProgram() )
- return;
- }
-
- glUseProgram( mnMaskedTextureProgram );
- glUniform1i( mnMaskedSamplerUniform, 0 );
- glUniform1i( mnMaskSamplerUniform, 1 );
- glActiveTexture( GL_TEXTURE0 );
- rTexture.Bind();
- glActiveTexture( GL_TEXTURE1 );
- rMask.Bind();
-
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ if( !UseProgram( "textureVertexShader", "maskedTextureFragmentShader" ) )
+ return;
+ mpProgram->SetTexture( "sampler", rTexture );
+ mpProgram->SetTexture( "mask", rMask );
+ mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
DrawTextureRect( rTexture, pPosAry );
- glDisable( GL_BLEND );
-
- glActiveTexture( GL_TEXTURE1 );
- rMask.Unbind();
- glActiveTexture( GL_TEXTURE0 );
- rTexture.Unbind();
- glUseProgram( 0 );
-
- CHECK_GL_ERROR();
+ mpProgram->Clean();
}
void OpenGLSalGraphicsImpl::DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLTexture& rMask, OpenGLTexture& rAlpha, const SalTwoRect& rPosAry )
{
GLfloat aTexCoord[8];
-
- if( mnBlendedTextureProgram == 0 )
- {
- if( !CreateBlendedTextureProgram() )
- return;
- }
-
- glUseProgram( mnBlendedTextureProgram );
- glUniform1i( mnBlendedTextureUniform, 0 );
- glUniform1i( mnBlendedMaskUniform, 1 );
- glUniform1i( mnBlendedAlphaUniform, 2 );
- glActiveTexture( GL_TEXTURE0 );
- rTexture.Bind();
- glActiveTexture( GL_TEXTURE1 );
- rMask.Bind();
- glActiveTexture( GL_TEXTURE2 );
- rAlpha.Bind();
-
+ if( !UseProgram( "blendedTextureVertexShader", "blendedTextureFragmentShader" ) )
+ return;
+ mpProgram->SetTexture( "sampler", rTexture );
+ mpProgram->SetTexture( "mask", rMask );
+ mpProgram->SetTexture( "alpha", rAlpha );
rAlpha.GetCoord( aTexCoord, rPosAry );
- glEnableVertexAttribArray( GL_ATTRIB_TEX2 );
- glVertexAttribPointer( GL_ATTRIB_TEX2, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ mpProgram->SetAlphaCoord( aTexCoord );
+ mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
DrawTextureRect( rTexture, rPosAry );
- glDisable( GL_BLEND );
-
- glDisableVertexAttribArray( GL_ATTRIB_TEX2 );
-
- glActiveTexture( GL_TEXTURE0 );
- rTexture.Unbind();
- glActiveTexture( GL_TEXTURE1 );
- rMask.Unbind();
- glActiveTexture( GL_TEXTURE2 );
- rAlpha.Unbind();
- glActiveTexture( GL_TEXTURE0 );
- glUseProgram( 0 );
-
- CHECK_GL_ERROR();
+ mpProgram->Clean();
}
void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, SalColor nMaskColor, const SalTwoRect& pPosAry )
{
- if( mnMaskProgram == 0 )
- {
- if( !CreateMaskProgram() )
- return;
- }
-
- glUseProgram( mnMaskProgram );
- glUniformColor( mnMaskColorUniform, nMaskColor, 0 );
- glUniform1i( mnMaskUniform, 0 );
- glActiveTexture( GL_TEXTURE0 );
- rMask.Bind();
-
- glEnable( GL_BLEND );
- glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+ if( !UseProgram( "textureVertexShader", "maskFragmentShader" ) )
+ return;
+ mpProgram->SetColor( "color", nMaskColor, 0 );
+ mpProgram->SetTexture( "sampler", rMask );
+ mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
DrawTextureRect( rMask, pPosAry );
- glDisable( GL_BLEND );
-
- rMask.Unbind();
- glUseProgram( 0 );
-
- CHECK_GL_ERROR();
+ mpProgram->Clean();
}
void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const Rectangle& rRect )
{
- if( mnLinearGradientProgram == 0 )
- {
- if( !CreateLinearGradientProgram() )
- return;
- }
-
- glUseProgram( mnLinearGradientProgram );
-
+ if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) )
+ return;
Color aStartCol = rGradient.GetStartColor();
Color aEndCol = rGradient.GetEndColor();
long nFactor = rGradient.GetStartIntensity();
- glUniformColorIntensity( mnLinearGradientStartColorUniform, aStartCol, nFactor );
+ mpProgram->SetColorWithIntensity( "start_color", aStartCol, nFactor );
nFactor = rGradient.GetEndIntensity();
- glUniformColorIntensity( mnLinearGradientEndColorUniform, aEndCol, nFactor );
+ mpProgram->SetColorWithIntensity( "end_color", aEndCol, nFactor );
Rectangle aBoundRect;
Point aCenter;
@@ -1088,35 +670,20 @@ void OpenGLSalGraphicsImpl::DrawLinearGradient( const Gradient& rGradient, const
GLfloat aTexCoord[8] = { 0, 1, 1, 1, 1, 0, 0, 0 };
GLfloat fMin = 1.0 - 100.0 / (100.0 - rGradient.GetBorder());
aTexCoord[5] = aTexCoord[7] = fMin;
- glEnableVertexAttribArray( GL_ATTRIB_TEX );
- glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-
+ mpProgram->SetTextureCoord( aTexCoord );
DrawConvexPolygon( aPoly );
-
- glDisableVertexAttribArray( GL_ATTRIB_TEX );
- CHECK_GL_ERROR();
-
- glUseProgram( 0 );
-
- CHECK_GL_ERROR();
}
void OpenGLSalGraphicsImpl::DrawAxialGradient( const Gradient& rGradient, const Rectangle& rRect )
{
- if( mnLinearGradientProgram == 0 )
- {
- if( !CreateLinearGradientProgram() )
- return;
- }
-
- glUseProgram( mnLinearGradientProgram );
-
+ if( !UseProgram( "textureVertexShader", "linearGradientFragmentShader" ) )
+ return;
Color aStartCol = rGradient.GetStartColor();
Color aEndCol = rGradient.GetEndColor();
long nFactor = rGradient.GetStartIntensity();
- glUniformColorIntensity( mnLinearGradientStartColorUniform, aStartCol, nFactor );
+ mpProgram->SetColorWithIntensity( "start_color", aStartCol, nFactor );
nFactor = rGradient.GetEndIntensity();
- glUniformColorIntensity( mnLinearGradientEndColorUniform, aEndCol, nFactor );
+ mpProgram->SetColorWithIntensity( "end_color", aEndCol, nFactor );
/**
* Draw two rectangles with linear gradient.
@@ -1153,33 +720,20 @@ void OpenGLSalGraphicsImpl::DrawAxialGradient( const Gradient& rGradient, const
GLfloat aTexCoord[12] = { 0, 1, 1, 0, 2, 0, 3, 1, 4, 0, 5, 0 };
GLfloat fMin = 1.0 - 100.0 / (100.0 - rGradient.GetBorder());
aTexCoord[3] = aTexCoord[5] = aTexCoord[9] = aTexCoord[11] = fMin;
- glEnableVertexAttribArray( GL_ATTRIB_TEX );
- glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-
+ mpProgram->SetTextureCoord( aTexCoord );
DrawConvexPolygon( aPoly );
-
- glDisableVertexAttribArray( GL_ATTRIB_TEX );
- glUseProgram( 0 );
-
- CHECK_GL_ERROR();
}
void OpenGLSalGraphicsImpl::DrawRadialGradient( const Gradient& rGradient, const Rectangle& rRect )
{
- if( mnRadialGradientProgram == 0 )
- {
- if( !CreateRadialGradientProgram() )
- return;
- }
-
- glUseProgram( mnRadialGradientProgram );
-
+ if( !UseProgram( "textureVertexShader", "radialGradientFragmentShader" ) )
+ return;
Color aStartCol = rGradient.GetStartColor();
Color aEndCol = rGradient.GetEndColor();
long nFactor = rGradient.GetStartIntensity();
- glUniformColorIntensity( mnRadialGradientStartColorUniform, aStartCol, nFactor );
+ mpProgram->SetColorWithIntensity( "start_color", aStartCol, nFactor );
nFactor = rGradient.GetEndIntensity();
- glUniformColorIntensity( mnRadialGradientEndColorUniform, aEndCol, nFactor );
+ mpProgram->SetColorWithIntensity( "end_color", aEndCol, nFactor );
Rectangle aRect;
Point aCenter;
@@ -1189,18 +743,11 @@ void OpenGLSalGraphicsImpl::DrawRadialGradient( const Gradient& rGradient, const
double fRadius = aRect.GetWidth() / 2.0f;
GLfloat fWidth = rRect.GetWidth() / fRadius;
GLfloat fHeight = rRect.GetHeight() / fRadius;
- glUniform2f( mnRadialGradientCenterUniform, (aCenter.X() -rRect.Left()) / fRadius, (aCenter.Y() - rRect.Top()) / fRadius );
-
GLfloat aTexCoord[8] = { 0, 0, 0, fHeight, fWidth, fHeight, fWidth, 0 };
- glEnableVertexAttribArray( GL_ATTRIB_TEX );
- glVertexAttribPointer( GL_ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, 0, aTexCoord );
-
+ mpProgram->SetTextureCoord( aTexCoord );
+ mpProgram->SetUniform2f( "center", (aCenter.X() - rRect.Left()) / fRadius,
+ (aCenter.Y() - rRect.Top()) / fRadius );
DrawRect( rRect );
-
- glDisableVertexAttribArray( GL_ATTRIB_TEX );
- glUseProgram( 0 );
-
- CHECK_GL_ERROR();
}
@@ -1211,9 +758,8 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY )
if( mnLineColor != SALCOLOR_NONE )
{
PreDraw();
- BeginSolid( mnLineColor );
- DrawPoint( nX, nY );
- EndSolid();
+ if( UseSolid( mnLineColor ) )
+ DrawPoint( nX, nY );
PostDraw();
}
}
@@ -1224,9 +770,8 @@ void OpenGLSalGraphicsImpl::drawPixel( long nX, long nY, SalColor nSalColor )
if( nSalColor != SALCOLOR_NONE )
{
PreDraw();
- BeginSolid( nSalColor );
- DrawPoint( nX, nY );
- EndSolid();
+ if( UseSolid( nSalColor ) )
+ DrawPoint( nX, nY );
PostDraw();
}
}
@@ -1237,9 +782,8 @@ void OpenGLSalGraphicsImpl::drawLine( long nX1, long nY1, long nX2, long nY2 )
if( mnLineColor != SALCOLOR_NONE )
{
PreDraw();
- BeginSolid( mnLineColor );
- DrawLine( nX1, nY1, nX2, nY2 );
- EndSolid();
+ if( UseSolid( mnLineColor ) )
+ DrawLine( nX1, nY1, nX2, nY2 );
PostDraw();
}
}
@@ -1249,14 +793,10 @@ void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeigh
SAL_INFO( "vcl.opengl", "::drawRect" );
PreDraw();
- if( mnFillColor != SALCOLOR_NONE )
- {
- BeginSolid( mnFillColor );
+ if( UseSolid( mnFillColor ) )
DrawRect( nX, nY, nWidth, nHeight );
- EndSolid();
- }
- if( mnLineColor != SALCOLOR_NONE )
+ if( UseSolid( mnLineColor ) )
{
const long nX1( nX );
const long nY1( nY );
@@ -1264,10 +804,7 @@ void OpenGLSalGraphicsImpl::drawRect( long nX, long nY, long nWidth, long nHeigh
const long nY2( nY + nHeight );
const SalPoint aPoints[] = { { nX1, nY1 }, { nX2, nY1 },
{ nX2, nY2 }, { nX1, nY2 } };
-
- BeginSolid( mnLineColor );
DrawLines( 4, aPoints, true );
- EndSolid();
}
PostDraw();
@@ -1280,9 +817,8 @@ void OpenGLSalGraphicsImpl::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pP
if( mnLineColor != SALCOLOR_NONE && nPoints > 1 )
{
PreDraw();
- BeginSolid( mnLineColor );
- DrawLines( nPoints, pPtAry, false );
- EndSolid();
+ if( UseSolid( mnLineColor ) )
+ DrawLines( nPoints, pPtAry, false );
PostDraw();
}
}
@@ -1306,19 +842,11 @@ void OpenGLSalGraphicsImpl::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPt
PreDraw();
- if( mnFillColor != SALCOLOR_NONE )
- {
- BeginSolid( mnFillColor );
+ if( UseSolid( mnFillColor ) )
DrawPolygon( nPoints, pPtAry );
- EndSolid();
- }
- if( mnLineColor != SALCOLOR_NONE )
- {
- BeginSolid( mnLineColor );
+ if( UseSolid( mnLineColor ) )
DrawLines( nPoints, pPtAry, true );
- EndSolid();
- }
PostDraw();
}
@@ -1331,21 +859,17 @@ void OpenGLSalGraphicsImpl::drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32*
PreDraw();
- if( mnFillColor != SALCOLOR_NONE )
+ if( UseSolid( mnFillColor ) )
{
- BeginSolid( mnFillColor );
for( sal_uInt32 i = 0; i < nPoly; i++ )
DrawPolygon( pPoints[i], pPtAry[i] );
- EndSolid();
}
- if( mnLineColor != SALCOLOR_NONE )
+ if( UseSolid( mnLineColor ) )
{
- // TODO performance: Use glMultiDrawElements or primitive restart
- BeginSolid( mnLineColor );
+ // TODO Use glMultiDrawElements or primitive restart
for( sal_uInt32 i = 0; i < nPoly; i++ )
DrawLines( pPoints[i], pPtAry[i], true );
- EndSolid();
}
PostDraw();
@@ -1359,15 +883,13 @@ bool OpenGLSalGraphicsImpl::drawPolyPolygon( const ::basegfx::B2DPolyPolygon& rP
PreDraw();
- if( mnFillColor != SALCOLOR_NONE )
+ if( UseSolid( mnFillColor, fTransparency ) )
{
- BeginSolid( mnFillColor, fTransparency );
for( sal_uInt32 i = 0; i < rPolyPolygon.count(); i++ )
{
const ::basegfx::B2DPolyPolygon aOnePoly( rPolyPolygon.getB2DPolygon( i ) );
DrawPolyPolygon( aOnePoly );
}
- EndSolid();
}
PostDraw();
@@ -1444,13 +966,14 @@ bool OpenGLSalGraphicsImpl::drawPolyLine(
}
PreDraw();
- BeginSolid( mnLineColor, fTransparency );
- for( sal_uInt32 i = 0; i < aAreaPolyPoly.count(); i++ )
+ if( UseSolid( mnLineColor, fTransparency ) )
{
- const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( i ) );
- DrawPolyPolygon( aOnePoly );
+ for( sal_uInt32 i = 0; i < aAreaPolyPoly.count(); i++ )
+ {
+ const ::basegfx::B2DPolyPolygon aOnePoly( aAreaPolyPoly.getB2DPolygon( i ) );
+ DrawPolyPolygon( aOnePoly );
+ }
}
- EndSolid();
PostDraw();
return true;
@@ -1493,7 +1016,9 @@ void OpenGLSalGraphicsImpl::copyArea(
SalTwoRect aPosAry(0, 0, nSrcWidth, nSrcHeight, nDestX, nDestY, nSrcWidth, nSrcHeight);
PreDraw();
- aTexture = OpenGLTexture( nSrcX, GetHeight() - nSrcY - nSrcHeight, nSrcWidth, nSrcHeight );
+ // TODO offscreen case
+ aTexture = OpenGLTexture( nSrcX, GetHeight() - nSrcY - nSrcHeight,
+ nSrcWidth, nSrcHeight );
DrawTexture( aTexture, aPosAry );
PostDraw();
}
@@ -1633,9 +1158,8 @@ void OpenGLSalGraphicsImpl::invert(
}
else // just invert
{
- BeginInvert();
- DrawRect( nX, nY, nWidth, nHeight );
- EndInvert();
+ if( UseInvert() )
+ DrawRect( nX, nY, nWidth, nHeight );
}
PostDraw();
@@ -1655,9 +1179,8 @@ void OpenGLSalGraphicsImpl::invert( sal_uInt32 nPoints, const SalPoint* pPtAry,
}
else // just invert
{
- BeginInvert();
- DrawPolygon( nPoints, pPtAry );
- EndInvert();
+ if( UseInvert() )
+ DrawPolygon( nPoints, pPtAry );
}
PostDraw();
@@ -1793,9 +1316,8 @@ bool OpenGLSalGraphicsImpl::drawAlphaRect(
if( mnFillColor != SALCOLOR_NONE && nTransparency < 100 )
{
PreDraw();
- BeginSolid( mnFillColor, nTransparency );
+ UseSolid( mnFillColor, nTransparency );
DrawRect( nX, nY, nWidth, nHeight );
- EndSolid();
PostDraw();
}
@@ -1841,10 +1363,10 @@ bool OpenGLSalGraphicsImpl::drawGradient(const tools::PolyPolygon& rPolyPoly,
{
Color aCol = rGradient.GetStartColor();
long nF = rGradient.GetStartIntensity();
- BeginSolid( MAKE_SALCOLOR( aCol.GetRed() * nF / 100,
- aCol.GetGreen() * nF / 100,
- aCol.GetBlue() * nF / 100 ) );
- DrawRect( aBoundRect );
+ if( UseSolid( MAKE_SALCOLOR( aCol.GetRed() * nF / 100,
+ aCol.GetGreen() * nF / 100,
+ aCol.GetBlue() * nF / 100 ) ) )
+ DrawRect( aBoundRect );
}
else if( rGradient.GetStyle() == GradientStyle_LINEAR )
{
diff --git a/vcl/opengl/maskVertexShader.glsl b/vcl/opengl/maskVertexShader.glsl
deleted file mode 100644
index 99d7f37eb05f..000000000000
--- a/vcl/opengl/maskVertexShader.glsl
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- 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/.
- */
-
-attribute vec4 position;
-attribute vec2 tex_coord_in;
-varying vec2 tex_coord;
-
-void main() {
- gl_Position = position;
- tex_coord = tex_coord_in;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/maskedTextureVertexShader.glsl b/vcl/opengl/maskedTextureVertexShader.glsl
deleted file mode 100644
index 99d7f37eb05f..000000000000
--- a/vcl/opengl/maskedTextureVertexShader.glsl
+++ /dev/null
@@ -1,19 +0,0 @@
-/* -*- 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/.
- */
-
-attribute vec4 position;
-attribute vec2 tex_coord_in;
-varying vec2 tex_coord;
-
-void main() {
- gl_Position = position;
- tex_coord = tex_coord_in;
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx
new file mode 100644
index 000000000000..c9542c726c75
--- /dev/null
+++ b/vcl/opengl/program.cxx
@@ -0,0 +1,238 @@
+/* -*- 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/.
+ */
+
+#include <opengl/program.hxx>
+
+#include <vcl/opengl/OpenGLHelper.hxx>
+
+#include <glm/glm.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+OpenGLProgram::OpenGLProgram() :
+ mnId( 0 ),
+ mnEnabledAttribs( 0 ),
+ mnAttribIndex( 0 ),
+ mnPositionAttrib( SAL_MAX_UINT32 ),
+ mnTexCoordAttrib( SAL_MAX_UINT32 ),
+ mnAlphaCoordAttrib( SAL_MAX_UINT32 ),
+ mbBlending( false )
+{
+}
+
+OpenGLProgram::~OpenGLProgram()
+{
+ maUniformLocations.clear();
+ if( mnId != 0 )
+ glDeleteProgram( mnId );
+}
+
+bool OpenGLProgram::Load( const OUString& rVertexShader, const OUString& rFragmentShader )
+{
+ mnId = OpenGLHelper::LoadShaders( rVertexShader, rFragmentShader );
+ return ( mnId != 0 );
+}
+
+bool OpenGLProgram::Use()
+{
+ if( !mnId )
+ return false;
+
+ glUseProgram( mnId );
+ return true;
+}
+
+bool OpenGLProgram::Clean()
+{
+ // unbind all textures
+ if( !maTextures.empty() )
+ {
+ int nIndex( maTextures.size() - 1 );
+ TextureList::reverse_iterator it( maTextures.rbegin() );
+ while( it != maTextures.rend() )
+ {
+ glActiveTexture( GL_TEXTURE0 + nIndex-- );
+ it->Unbind();
+ it++;
+ }
+ maTextures.clear();
+ }
+
+ // disable any enabled vertex attrib array
+ if( mnEnabledAttribs )
+ {
+ for( int i = 0; i < 32; i++ )
+ {
+ if( mnEnabledAttribs & ( 1 << i ) )
+ glDisableVertexAttribArray( i );
+ }
+ mnEnabledAttribs = 0;
+ }
+
+ // disable blending if enabled
+ if( mbBlending )
+ {
+ mbBlending = false;
+ glDisable( GL_BLEND );
+ }
+
+ CHECK_GL_ERROR();
+ return true;
+}
+
+void OpenGLProgram::SetVertexAttrib( GLuint& rAttrib, const OString& rName, const GLvoid* pData )
+{
+ if( rAttrib == SAL_MAX_UINT32 )
+ rAttrib = glGetAttribLocation( mnId, (char*) rName.getStr() );
+ if( (mnEnabledAttribs & ( 1 << rAttrib )) == 0 )
+ {
+ glEnableVertexAttribArray( rAttrib );
+ mnEnabledAttribs |= ( 1 << rAttrib );
+ }
+ glVertexAttribPointer( rAttrib, 2, GL_FLOAT, GL_FALSE, 0, pData );
+}
+
+void OpenGLProgram::SetVertices( const GLvoid* pData )
+{
+ SetVertexAttrib( mnPositionAttrib, "position", pData );
+}
+
+void OpenGLProgram::SetTextureCoord( const GLvoid* pData )
+{
+ SetVertexAttrib( mnTexCoordAttrib, "tex_coord_in", pData );
+}
+
+void OpenGLProgram::SetAlphaCoord( const GLvoid* pData )
+{
+ SetVertexAttrib( mnAlphaCoordAttrib, "alpha_coord_in", pData );
+}
+
+GLuint OpenGLProgram::GetUniformLocation( const OString& rName )
+{
+ boost::unordered_map<OString, GLuint>::iterator it;
+
+ it = maUniformLocations.find( rName );
+ if( it == maUniformLocations.end() )
+ {
+ GLuint nLocation = glGetUniformLocation( mnId, (char*) rName.getStr() );
+ maUniformLocations[rName] = nLocation;
+ return nLocation;
+ }
+
+ return it->second;
+}
+
+void OpenGLProgram::SetUniform2f( const OString& rName, GLfloat v1, GLfloat v2 )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ glUniform2f( nUniform, v1, v2 );
+}
+
+void OpenGLProgram::SetUniform1fv( const OString& rName, GLsizei nCount, GLfloat* aValues )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ glUniform1fv( nUniform, nCount, aValues );
+}
+
+void OpenGLProgram::SetUniform2fv( const OString& rName, GLsizei nCount, GLfloat* aValues )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ glUniform2fv( nUniform, nCount, aValues );
+}
+
+void OpenGLProgram::SetColor( const OString& rName, SalColor nColor, sal_uInt8 nTransparency )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ glUniform4f( nUniform,
+ ((float) SALCOLOR_RED( nColor )) / 255,
+ ((float) SALCOLOR_GREEN( nColor )) / 255,
+ ((float) SALCOLOR_BLUE( nColor )) / 255,
+ (100 - nTransparency) * (1.0 / 100) );
+
+ if( nTransparency > 0 )
+ SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+}
+
+void OpenGLProgram::SetColorf( const OString& rName, SalColor nColor, double fTransparency )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ glUniform4f( nUniform,
+ ((float) SALCOLOR_RED( nColor )) / 255,
+ ((float) SALCOLOR_GREEN( nColor )) / 255,
+ ((float) SALCOLOR_BLUE( nColor )) / 255,
+ (1.0f - fTransparency) );
+
+ if( fTransparency > 0.0 )
+ SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
+}
+
+void OpenGLProgram::SetColorWithIntensity( const OString& rName, const Color& rColor, long nFactor )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ glUniform4f( nUniform,
+ ((float) rColor.GetRed()) * nFactor / 25500.0,
+ ((float) rColor.GetGreen()) * nFactor / 25500.0,
+ ((float) rColor.GetBlue()) * nFactor / 25500.0,
+ 1.0f );
+}
+
+void OpenGLProgram::SetTexture( const OString& rName, OpenGLTexture& rTexture )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ int nIndex = maTextures.size();
+
+ glUniform1i( nUniform, nIndex );
+ glActiveTexture( GL_TEXTURE0 + nIndex );
+ rTexture.Bind();
+ maTextures.push_back( rTexture );
+}
+
+void OpenGLProgram::SetTransform(
+ const OString& rName,
+ const OpenGLTexture& rTexture,
+ const basegfx::B2DPoint& rNull,
+ const basegfx::B2DPoint& rX,
+ const basegfx::B2DPoint& rY )
+{
+ GLuint nUniform = GetUniformLocation( rName );
+ const basegfx::B2DVector aXRel = rX - rNull;
+ const basegfx::B2DVector aYRel = rY - rNull;
+ const float aValues[] = {
+ (float) aXRel.getX()/rTexture.GetWidth(), (float) aXRel.getY()/rTexture.GetWidth(), 0, 0,
+ (float) aYRel.getX()/rTexture.GetHeight(), (float) aYRel.getY()/rTexture.GetHeight(), 0, 0,
+ 0, 0, 1, 0,
+ (float) rNull.getX(), (float) rNull.getY(), 0, 1 };
+ glm::mat4 mMatrix = glm::make_mat4( aValues );
+ glUniformMatrix4fv( nUniform, 1, GL_FALSE, glm::value_ptr( mMatrix ) );
+}
+
+void OpenGLProgram::SetBlendMode( GLenum nSFactor, GLenum nDFactor )
+{
+ glEnable( GL_BLEND );
+ glBlendFunc( nSFactor, nDFactor );
+ mbBlending = true;
+}
+
+bool OpenGLProgram::DrawTexture( OpenGLTexture& rTexture )
+{
+ GLfloat aPosition[8] = { -1, -1, -1, 1, 1, 1, 1, -1 };
+ GLfloat aTexCoord[8];
+
+ if( !rTexture )
+ return false;
+
+ rTexture.GetWholeCoord( aTexCoord );
+ SetVertices( aPosition );
+ SetTextureCoord( aTexCoord );
+ glDrawArrays( GL_TRIANGLE_FAN, 0, 4 );
+ CHECK_GL_ERROR();
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx
index 6fdb2af578c8..db2bb1cfd454 100644
--- a/vcl/opengl/salbmp.cxx
+++ b/vcl/opengl/salbmp.cxx
@@ -43,13 +43,6 @@ OpenGLSalBitmap::OpenGLSalBitmap()
, mnHeight(0)
, mnBufWidth(0)
, mnBufHeight(0)
-, mnTexProgram(0)
-, mnTexSamplerUniform(0)
-, mnConvProgram(0)
-, mnConvSamplerUniform(0)
-, mnConvKernelUniform(0)
-, mnConvKernelSizeUniform(0)
-, mnConvOffsetsUniform(0)
{
}
diff --git a/vcl/opengl/scale.cxx b/vcl/opengl/scale.cxx
index d3966521136f..7bcf7c030cbc 100644
--- a/vcl/opengl/scale.cxx
+++ b/vcl/opengl/scale.cxx
@@ -25,6 +25,7 @@
#include "opengl/bmpop.hxx"
#include "opengl/salbmp.hxx"
+#include "opengl/program.hxx"
#include "opengl/texture.hxx"
class ScaleOp : public OpenGLSalBitmapOp
@@ -42,75 +43,32 @@ public:
void GetSize( Size& rSize ) const SAL_OVERRIDE;
};
-
-GLuint OpenGLSalBitmap::ImplGetTextureProgram()
-{
- if( mnTexProgram == 0 )
- {
- mnTexProgram = OpenGLHelper::LoadShaders( "textureVertexShader",
- "textureFragmentShader" );
- if( mnTexProgram == 0 )
- return 0;
-
- glBindAttribLocation( mnTexProgram, 0, "position" );
- glBindAttribLocation( mnTexProgram, 1, "tex_coord_in" );
- mnTexSamplerUniform = glGetUniformLocation( mnTexProgram, "sampler" );
- }
-
- CHECK_GL_ERROR();
- return mnTexProgram;
-}
-
-GLuint OpenGLSalBitmap::ImplGetConvolutionProgram()
-{
- if( mnConvProgram == 0 )
- {
- mnConvProgram = OpenGLHelper::LoadShaders( "textureVertexShader",
- "convolutionFragmentShader" );
- if( mnConvProgram == 0 )
- return 0;
-
- glBindAttribLocation( mnConvProgram, 0, "position" );
- glBindAttribLocation( mnConvProgram, 1, "tex_coord_in" );
- mnConvSamplerUniform = glGetUniformLocation( mnConvProgram, "sampler" );
- mnConvKernelUniform = glGetUniformLocation( mnConvProgram, "kernel" );
- mnConvOffsetsUniform = glGetUniformLocation( mnConvProgram, "offsets" );
- }
-
- CHECK_GL_ERROR();
- return mnConvProgram;
-}
-
bool OpenGLSalBitmap::ImplScaleFilter(
const double& rScaleX,
const double& rScaleY,
GLenum nFilter )
{
OpenGLFramebuffer* pFramebuffer;
- GLuint nProgram;
+ OpenGLProgram* pProgram;
GLenum nOldFilter;
int nNewWidth( mnWidth * rScaleX );
int nNewHeight( mnHeight * rScaleY );
- nProgram = ImplGetTextureProgram();
- if( nProgram == 0 )
+ pProgram = mpContext->UseProgram( "textureVertexShader",
+ "textureFragmentShader" );
+ if( !pProgram )
return false;
OpenGLTexture aNewTex = OpenGLTexture( nNewWidth, nNewHeight );
pFramebuffer = mpContext->AcquireFramebuffer( aNewTex );
- glUseProgram( nProgram );
- glUniform1i( mnTexSamplerUniform, 0 );
- glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
- glClear( GL_COLOR_BUFFER_BIT );
- maTexture.Bind();
+ pProgram->SetTexture( "sampler", maTexture );
nOldFilter = maTexture.GetFilter();
maTexture.SetFilter( nFilter );
- maTexture.Draw();
+ pProgram->DrawTexture( maTexture );
maTexture.SetFilter( nOldFilter );
- maTexture.Unbind();
+ pProgram->Clean();
- glUseProgram( 0 );
mpContext->ReleaseFramebuffer( pFramebuffer );
mnWidth = nNewWidth;
@@ -165,8 +123,8 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
const Kernel& aKernel )
{
OpenGLFramebuffer* pFramebuffer;
+ OpenGLProgram* pProgram;
GLfloat* pWeights( 0 );
- GLuint nProgram;
sal_uInt32 nKernelSize;
GLfloat aOffsets[32];
int nNewWidth( mnWidth * rScaleX );
@@ -174,14 +132,11 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
// TODO Make sure the framebuffer is alright
- nProgram = ImplGetConvolutionProgram();
- if( nProgram == 0 )
+ pProgram = mpContext->UseProgram( "textureVertexShader",
+ "convolutionFragmentShader" );
+ if( pProgram == 0 )
return false;
- glUseProgram( nProgram );
- glUniform1i( mnConvSamplerUniform, 0 );
- CHECK_GL_ERROR();
-
// horizontal scaling in scratch texture
if( mnWidth != nNewWidth )
{
@@ -194,14 +149,11 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
aOffsets[i * 2 + 1] = 0;
}
ImplCreateKernel( rScaleX, aKernel, pWeights, nKernelSize );
- glUniform1fv( mnConvKernelUniform, 16, pWeights );
- CHECK_GL_ERROR();
- glUniform2fv( mnConvOffsetsUniform, 16, aOffsets );
- CHECK_GL_ERROR();
-
- maTexture.Bind();
- maTexture.Draw();
- maTexture.Unbind();
+ pProgram->SetUniform1fv( "kernel", 16, pWeights );
+ pProgram->SetUniform2fv( "offsets", 16, aOffsets );
+ pProgram->SetTexture( "sampler", maTexture );
+ pProgram->DrawTexture( maTexture );
+ pProgram->Clean();
maTexture = aScratchTex;
mpContext->ReleaseFramebuffer( pFramebuffer );
@@ -219,20 +171,16 @@ bool OpenGLSalBitmap::ImplScaleConvolution(
aOffsets[i * 2 + 1] = i / (double) mnHeight;
}
ImplCreateKernel( rScaleY, aKernel, pWeights, nKernelSize );
- glUniform1fv( mnConvKernelUniform, 16, pWeights );
- glUniform2fv( mnConvOffsetsUniform, 16, aOffsets );
- CHECK_GL_ERROR();
-
- maTexture.Bind();
- maTexture.Draw();
- maTexture.Unbind();
+ pProgram->SetUniform1fv( "kernel", 16, pWeights );
+ pProgram->SetUniform2fv( "offsets", 16, aOffsets );
+ pProgram->SetTexture( "sampler", maTexture );
+ pProgram->DrawTexture( maTexture );
+ pProgram->Clean();
maTexture = aScratchTex;
mpContext->ReleaseFramebuffer( pFramebuffer );
}
- glUseProgram( 0 );
-
mnWidth = nNewWidth;
mnHeight = nNewHeight;
diff --git a/vcl/opengl/texture.cxx b/vcl/opengl/texture.cxx
index c8f46848e6d6..7618c04d6471 100644
--- a/vcl/opengl/texture.cxx
+++ b/vcl/opengl/texture.cxx
@@ -188,6 +188,24 @@ void OpenGLTexture::GetCoord( GLfloat* pCoord, const SalTwoRect& rPosAry, bool b
}
}
+void OpenGLTexture::GetWholeCoord( GLfloat* pCoord ) const
+{
+ if( GetWidth() != mpImpl->mnWidth || GetHeight() != mpImpl->mnHeight )
+ {
+ pCoord[0] = pCoord[2] = maRect.Left() / (double) mpImpl->mnWidth;
+ pCoord[4] = pCoord[6] = maRect.Right() / (double) mpImpl->mnWidth;
+ pCoord[3] = pCoord[5] = 1.0f - maRect.Top() / (double) mpImpl->mnHeight;
+ pCoord[1] = pCoord[7] = 1.0f - maRect.Bottom() / (double) mpImpl->mnHeight;
+ }
+ else
+ {
+ pCoord[0] = pCoord[2] = 0;
+ pCoord[4] = pCoord[6] = 1;
+ pCoord[1] = pCoord[7] = 0;
+ pCoord[3] = pCoord[5] = 1;
+ }
+}
+
GLenum OpenGLTexture::GetFilter() const
{
if( mpImpl )
@@ -226,7 +244,7 @@ void OpenGLTexture::Unbind()
bool OpenGLTexture::Draw()
{
GLfloat aPosition[8] = { -1, -1, -1, 1, 1, 1, 1, -1 };
- GLfloat aTexCoord[8] = { 0, 0, 0, 1, 1, 1, 1, 0 };
+ GLfloat aTexCoord[8];
if( mpImpl == NULL )
{
@@ -235,15 +253,8 @@ bool OpenGLTexture::Draw()
}
SAL_INFO( "vcl.opengl", "Drawing texture " << Id() << " [" << maRect.Left() << "," << maRect.Top() << "] " << GetWidth() << "x" << GetHeight() );
- if( GetWidth() != mpImpl->mnWidth || GetHeight() != mpImpl->mnHeight )
- {
- // FIXME: lfrb: check math
- aTexCoord[0] = aTexCoord[2] = maRect.Left() / (double) mpImpl->mnWidth;
- aTexCoord[4] = aTexCoord[6] = maRect.Right() / (double) mpImpl->mnWidth;
- aTexCoord[1] = aTexCoord[7] = maRect.Top() / (double) mpImpl->mnHeight;
- aTexCoord[3] = aTexCoord[5] = maRect.Bottom() / (double) mpImpl->mnHeight;
- }
+ GetWholeCoord( aTexCoord );
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, mpImpl->mnTexture );
glEnableVertexAttribArray( 0 );
diff --git a/vcl/source/opengl/OpenGLContext.cxx b/vcl/source/opengl/OpenGLContext.cxx
index a41bfe8f0c0f..c02573d0cd2c 100644
--- a/vcl/source/opengl/OpenGLContext.cxx
+++ b/vcl/source/opengl/OpenGLContext.cxx
@@ -30,6 +30,7 @@
#include "svdata.hxx"
#include <opengl/framebuffer.hxx>
+#include <opengl/program.hxx>
#include <opengl/texture.hxx>
using namespace com::sun::star;
@@ -58,6 +59,7 @@ OpenGLContext::OpenGLContext():
mpCurrentFramebuffer(NULL),
mpFirstFramebuffer(NULL),
mpLastFramebuffer(NULL),
+ mpCurrentProgram(NULL),
mnPainting(0),
mpPrevContext(NULL),
mpNextContext(NULL)
@@ -1386,4 +1388,37 @@ void OpenGLContext::ReleaseFramebuffer( OpenGLFramebuffer* pFramebuffer )
pFramebuffer->DetachTexture();
}
+OpenGLProgram* OpenGLContext::GetProgram( const OUString& rVertexShader, const OUString& rFragmentShader )
+{
+ boost::unordered_map<ProgramKey, OpenGLProgram*>::iterator it;
+ ProgramKey aKey( rVertexShader, rFragmentShader );
+
+ it = maPrograms.find( aKey );
+ if( it != maPrograms.end() )
+ return it->second;
+
+ OpenGLProgram* pProgram = new OpenGLProgram;
+ if( !pProgram->Load( rVertexShader, rFragmentShader ) )
+ {
+ delete pProgram;
+ return NULL;
+ }
+
+ maPrograms[aKey] = pProgram;
+ return pProgram;
+}
+
+OpenGLProgram* OpenGLContext::UseProgram( const OUString& rVertexShader, const OUString& rFragmentShader )
+{
+ OpenGLProgram* pProgram = GetProgram( rVertexShader, rFragmentShader );
+
+ if( pProgram == mpCurrentProgram )
+ return pProgram;
+
+ mpCurrentProgram = pProgram;
+ mpCurrentProgram->Use();
+
+ return mpCurrentProgram;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */