Kaydet (Commit) 99ade27b authored tarafından Louis-Francis Ratté-Boulianne's avatar Louis-Francis Ratté-Boulianne Kaydeden (comit) Jan Holesovsky

vcl: Only load OpenGL shaders once for each context

Change-Id: Idbf9026c5e64ef41d4c913153dfddf36923ff7de
üst 0d4233ef
......@@ -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();
......@@ -240,6 +271,9 @@ private:
OpenGLFramebuffer* mpFirstFramebuffer;
OpenGLFramebuffer* mpLastFramebuffer;
boost::unordered_map<ProgramKey, OpenGLProgram*> maPrograms;
OpenGLProgram* mpCurrentProgram;
public:
vcl::Region maClipRegion;
int mnPainting;
......
......@@ -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 \
......
......@@ -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 \
......
/* -*- 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: */
......@@ -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 );
......
......@@ -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();
......
......@@ -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 );
......
This diff is collapsed.
/* -*- 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: */
/* -*- 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: */
/* -*- 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: */
......@@ -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)
{
}
......
......@@ -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;
......
......@@ -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 );
......
......@@ -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: */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment