diff options
author | Louis-Francis Ratté-Boulianne <lfrb@collabora.com> | 2014-11-28 14:56:08 -0500 |
---|---|---|
committer | Jan Holesovsky <kendy@collabora.com> | 2014-12-02 11:58:45 +0100 |
commit | 99ade27b04d3d492648eadb620cda8ea9909bf45 (patch) | |
tree | 45a9221e508acc90e73db3ad998eeaa819099686 /vcl | |
parent | 0d4233ef90a4350d63da0c9d1b98ced64b773ce0 (diff) |
vcl: Only load OpenGL shaders once for each context
Change-Id: Idbf9026c5e64ef41d4c913153dfddf36923ff7de
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Library_vcl.mk | 1 | ||||
-rw-r--r-- | vcl/Package_opengl.mk | 4 | ||||
-rw-r--r-- | vcl/inc/opengl/program.hxx | 72 | ||||
-rw-r--r-- | vcl/inc/opengl/salbmp.hxx | 11 | ||||
-rw-r--r-- | vcl/inc/opengl/texture.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/openglgdiimpl.hxx | 67 | ||||
-rw-r--r-- | vcl/opengl/dumbVertexShader.glsl (renamed from vcl/opengl/solidVertexShader.glsl) | 0 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 763 | ||||
-rw-r--r-- | vcl/opengl/maskVertexShader.glsl | 19 | ||||
-rw-r--r-- | vcl/opengl/maskedTextureVertexShader.glsl | 19 | ||||
-rw-r--r-- | vcl/opengl/program.cxx | 238 | ||||
-rw-r--r-- | vcl/opengl/salbmp.cxx | 7 | ||||
-rw-r--r-- | vcl/opengl/scale.cxx | 96 | ||||
-rw-r--r-- | vcl/opengl/texture.cxx | 29 | ||||
-rw-r--r-- | vcl/source/opengl/OpenGLContext.cxx | 35 |
15 files changed, 537 insertions, 825 deletions
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk index 737a0310c2fd..1adccabb7d64 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 2f0dd29e3139..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,242 +561,105 @@ void OpenGLSalGraphicsImpl::DrawTransformedTexture( const basegfx::B2DPoint& rX, const basegfx::B2DPoint& rY ) { - const int nTexWidth = rTexture.GetWidth(); - const int nTexHeight = rTexture.GetHeight(); - if (nTexWidth == 0 || nTexHeight == 0) - return; - - const basegfx::B2DVector aXRel = rX - rNull; - const basegfx::B2DVector aYRel = rY - rNull; - const float aValues[] = { - (float) aXRel.getX()/nTexWidth, (float) aXRel.getY()/nTexWidth, 0, 0, - (float) aYRel.getX()/nTexHeight, (float) aYRel.getY()/nTexHeight, 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) nTexHeight, 0, 0, - (float) nTexWidth, 0, (float) nTexWidth, (float) nTexHeight }; + 0, (float) rTexture.GetHeight(), 0, 0, + (float) rTexture.GetWidth(), 0, (float) rTexture.GetWidth(), (float) rTexture.GetHeight() }; GLfloat aTexCoord[8]; 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; @@ -1093,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. @@ -1158,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; @@ -1194,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(); } @@ -1216,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(); } } @@ -1229,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(); } } @@ -1242,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(); } } @@ -1254,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 ); @@ -1269,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(); @@ -1285,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(); } } @@ -1311,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(); } @@ -1336,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(); @@ -1364,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(); @@ -1449,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; @@ -1498,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(); } @@ -1638,9 +1158,8 @@ void OpenGLSalGraphicsImpl::invert( } else // just invert { - BeginInvert(); - DrawRect( nX, nY, nWidth, nHeight ); - EndInvert(); + if( UseInvert() ) + DrawRect( nX, nY, nWidth, nHeight ); } PostDraw(); @@ -1660,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(); @@ -1798,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(); } @@ -1846,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 84d6bbebccae..37eaf6756540 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) @@ -1391,4 +1393,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: */ |