diff options
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/Package_opengl.mk | 4 | ||||
-rw-r--r-- | vcl/inc/opengl/program.hxx | 19 | ||||
-rw-r--r-- | vcl/opengl/combinedFragmentShader.glsl | 45 | ||||
-rw-r--r-- | vcl/opengl/combinedTextureFragmentShader.glsl | 64 | ||||
-rw-r--r-- | vcl/opengl/combinedTextureVertexShader.glsl | 32 | ||||
-rw-r--r-- | vcl/opengl/combinedVertexShader.glsl | 47 | ||||
-rw-r--r-- | vcl/opengl/gdiimpl.cxx | 69 | ||||
-rw-r--r-- | vcl/opengl/program.cxx | 18 |
8 files changed, 273 insertions, 25 deletions
diff --git a/vcl/Package_opengl.mk b/vcl/Package_opengl.mk index a0f6e9a27128..2fa917eeac42 100644 --- a/vcl/Package_opengl.mk +++ b/vcl/Package_opengl.mk @@ -21,6 +21,10 @@ $(eval $(call gb_Package_add_files,vcl_opengl_shader,$(LIBO_ETC_FOLDER)/opengl,\ invert50FragmentShader.glsl \ convolutionFragmentShader.glsl \ linearGradientFragmentShader.glsl \ + combinedTextureFragmentShader.glsl \ + combinedTextureVertexShader.glsl \ + combinedFragmentShader.glsl \ + combinedVertexShader.glsl \ lineFragmentShader.glsl \ lineVertexShader.glsl \ maskFragmentShader.glsl \ diff --git a/vcl/inc/opengl/program.hxx b/vcl/inc/opengl/program.hxx index 5944c72be127..2fab98c6b4d5 100644 --- a/vcl/inc/opengl/program.hxx +++ b/vcl/inc/opengl/program.hxx @@ -27,6 +27,21 @@ typedef std::unordered_map< OString, GLuint, OStringHash > UniformCache; typedef std::list< OpenGLTexture > TextureList; +enum class TextureShaderType +{ + Normal = 0, + Blend, + Masked, + Diff, + MaskedColor +}; + +enum class DrawShaderType +{ + Normal = 0, + Line +}; + class VCL_PLUGIN_PUBLIC OpenGLProgram { private: @@ -78,6 +93,10 @@ public: void SetTransform( const OString& rName, const OpenGLTexture& rTexture, const basegfx::B2DPoint& rNull, const basegfx::B2DPoint& rX, const basegfx::B2DPoint& rY ); + void SetIdentityTransform(const OString& rName); + void SetShaderType(TextureShaderType eTextureShaderType); + void SetShaderType(DrawShaderType eDrawShaderType); + void SetBlendMode( GLenum nSFactor, GLenum nDFactor ); void ApplyMatrix(float fWidth, float fHeight, float fPixelOffset = 0.0f); diff --git a/vcl/opengl/combinedFragmentShader.glsl b/vcl/opengl/combinedFragmentShader.glsl new file mode 100644 index 000000000000..c44e75c09373 --- /dev/null +++ b/vcl/opengl/combinedFragmentShader.glsl @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +varying float fade_factor; // 0->1 fade factor used for AA +uniform vec4 color; + +uniform float line_width; +uniform float feather; + +#define TYPE_NORMAL 0 +#define TYPE_LINE 1 + +uniform int type; + +void main() +{ + float alpha = 1.0; + + if (type == TYPE_LINE) + { + float start = (line_width / 2.0) - feather; // where we start to apply alpha + float end = (line_width / 2.0) + feather; // where we end to apply alpha + + // Calculate the multiplier so we can transform the 0->1 fade factor + // to take feather and line width into account. + float multiplied = 1.0 / (1.0 - (start / end)); + + float dist = (1.0 - abs(fade_factor)) * multiplied; + + alpha = clamp(dist, 0.0, 1.0); + } + + vec4 result_color = color; + result_color.a = result_color.a * alpha; + + gl_FragColor = result_color; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/combinedTextureFragmentShader.glsl b/vcl/opengl/combinedTextureFragmentShader.glsl new file mode 100644 index 000000000000..d8864cfe21c5 --- /dev/null +++ b/vcl/opengl/combinedTextureFragmentShader.glsl @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +varying vec2 tex_coord; +varying vec2 alpha_coord; +varying vec2 mask_coord; + +uniform sampler2D texture; +uniform sampler2D mask; +uniform sampler2D alpha; + +uniform vec4 color; + +uniform int type; + +#define TYPE_NORMAL 0 +#define TYPE_BLEND 1 +#define TYPE_MASKED 2 +#define TYPE_DIFF 3 +#define TYPE_MASKED_COLOR 4 + +void main() +{ + vec4 texelTexture = texture2D(texture, tex_coord); + + if (type == TYPE_NORMAL) + { + gl_FragColor = texelTexture; + } + else if (type == TYPE_BLEND) + { + vec4 texelMask = texture2D(mask, mask_coord); + vec4 texelAlpha = texture2D(alpha, alpha_coord); + gl_FragColor = texelTexture; + gl_FragColor.a = 1.0 - (1.0 - floor(texelAlpha.r)) * texelMask.r; + } + else if (type == TYPE_MASKED) + { + vec4 texelMask = texture2D(mask, mask_coord); + gl_FragColor = texelTexture; + gl_FragColor.a = 1.0 - texelMask.r; + } + else if (type == TYPE_DIFF) + { + vec4 texelMask = texture2D(mask, mask_coord); + float alpha = 1.0 - abs(texelTexture.r - texelMask.r); + if (alpha > 0.0) + gl_FragColor = texelMask / alpha; + gl_FragColor.a = alpha; + } + else if (type == TYPE_MASKED_COLOR) + { + gl_FragColor = color; + gl_FragColor.a = 1.0 - texelTexture.r; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/combinedTextureVertexShader.glsl b/vcl/opengl/combinedTextureVertexShader.glsl new file mode 100644 index 000000000000..883ec631fa73 --- /dev/null +++ b/vcl/opengl/combinedTextureVertexShader.glsl @@ -0,0 +1,32 @@ +/* -*- 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; +attribute vec2 mask_coord_in; +attribute vec2 alpha_coord_in; + +varying vec2 tex_coord; +varying vec2 mask_coord; +varying vec2 alpha_coord; + +uniform mat4 mvp; +uniform mat4 transform; + +uniform int type; + +void main() +{ + gl_Position = mvp * transform * position; + tex_coord = tex_coord_in; + mask_coord = mask_coord_in; + alpha_coord = alpha_coord_in; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/combinedVertexShader.glsl b/vcl/opengl/combinedVertexShader.glsl new file mode 100644 index 000000000000..9272544c33ef --- /dev/null +++ b/vcl/opengl/combinedVertexShader.glsl @@ -0,0 +1,47 @@ +/* -*- 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 vec2 position; +attribute vec4 extrusion_vectors; + +varying float fade_factor; // fade factor for anti-aliasing + +uniform float line_width; +uniform float feather; // width where we fade the line + +uniform mat4 mvp; + +#define TYPE_NORMAL 0 +#define TYPE_LINE 1 + +uniform int type; + +void main() +{ + vec4 final_position = vec4(position, 0.0, 1.0); + + if (type == TYPE_LINE) + { + vec2 extrusion_vector = extrusion_vectors.xy; + // miter factor to additionaly lenghten the distance of vertex (needed for miter) + // if 1.0 - miter_factor has no effect + float miter_factor = 1.0f / abs(extrusion_vectors.z); + // fade factor is always -1.0 or 1.0 -> we transport that info together with length + fade_factor = sign(extrusion_vectors.z); + + float rendered_thickness = (line_width + feather * 2.0) * miter_factor; + + // lengthen the vertex in directon of the extrusion vector by line width. + final_position = vec4(position + (extrusion_vector * (rendered_thickness / 2.0) ), 0.0, 1.0); + } + + gl_Position = mvp * final_position; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/opengl/gdiimpl.cxx b/vcl/opengl/gdiimpl.cxx index a92e5b3fca5e..58b4d62cca2e 100644 --- a/vcl/opengl/gdiimpl.cxx +++ b/vcl/opengl/gdiimpl.cxx @@ -544,8 +544,9 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, sal_uInt8 nTransparency ) { if( nColor == SALCOLOR_NONE ) return false; - if( !UseProgram( "dumbVertexShader", "solidFragmentShader" ) ) + if (!UseProgram("combinedVertexShader", "combinedFragmentShader")) return false; + mpProgram->SetShaderType(DrawShaderType::Normal); mpProgram->SetColor( "color", nColor, nTransparency ); #ifdef DBG_UTIL mProgramIsSolidColor = true; @@ -560,8 +561,9 @@ bool OpenGLSalGraphicsImpl::UseSolid( SalColor nColor, double fTransparency ) { if( nColor == SALCOLOR_NONE ) return false; - if( !UseProgram( "dumbVertexShader", "solidFragmentShader" ) ) + if (!UseProgram("combinedVertexShader", "combinedFragmentShader")) return false; + mpProgram->SetShaderType(DrawShaderType::Normal); mpProgram->SetColorf( "color", nColor, fTransparency ); #ifdef DBG_UTIL mProgramIsSolidColor = true; @@ -925,12 +927,13 @@ bool OpenGLSalGraphicsImpl::UseLine(SalColor nColor, double fTransparency, GLflo { if( nColor == SALCOLOR_NONE ) return false; - if( !UseProgram( "lineVertexShader", "lineFragmentShader" ) ) + if (!UseProgram("combinedVertexShader", "combinedFragmentShader")) return false; + mpProgram->SetShaderType(DrawShaderType::Line); mpProgram->SetColorf("color", nColor, fTransparency); mpProgram->SetUniform1f("line_width", fLineWidth); // The width of the feather - area we make lineary transparent in VS. - // Good AA value is 0.5 + // Good AA value is 0.5f, no AA if feather 0.0f mpProgram->SetUniform1f("feather", bUseAA ? 0.5f : 0.0f); // We need blending or AA won't work correctly mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); @@ -970,7 +973,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( sal_uInt32 nPoints, const SalPoin #endif SalColor lastSolidColor = mProgramSolidColor; double lastSolidTransparency = mProgramSolidTransparency; - if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true)) + if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f, true)) { for( i = 0; i < nPoints; ++i ) { @@ -1013,7 +1016,7 @@ void OpenGLSalGraphicsImpl::DrawConvexPolygon( const tools::Polygon& rPolygon, b #endif SalColor lastSolidColor = mProgramSolidColor; double lastSolidTransparency = mProgramSolidTransparency; - if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true)) + if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f, true)) { for( i = 0; i < nPoints; ++i ) { @@ -1063,7 +1066,7 @@ void OpenGLSalGraphicsImpl::DrawTrapezoid( const basegfx::B2DTrapezoid& trapezoi #endif SalColor lastSolidColor = mProgramSolidColor; double lastSolidTransparency = mProgramSolidTransparency; - if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f ,true)) + if (UseLine(lastSolidColor, lastSolidTransparency, 1.0f, true)) { for( i = 0; i < nPoints; ++i ) { @@ -1184,9 +1187,11 @@ void OpenGLSalGraphicsImpl::DrawTexture( OpenGLTexture& rTexture, const SalTwoRe SAL_INFO("vcl.opengl", "draw texture"); - if( !UseProgram( "textureVertexShader", "textureFragmentShader" ) ) + if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader")) return; - mpProgram->SetTexture( "sampler", rTexture ); + mpProgram->SetShaderType(TextureShaderType::Normal); + mpProgram->SetIdentityTransform("transform"); + mpProgram->SetTexture("texture", rTexture); DrawTextureRect( rTexture, pPosAry, bInverted ); mpProgram->Clean(); } @@ -1393,9 +1398,11 @@ void OpenGLSalGraphicsImpl::DrawAlphaTexture( OpenGLTexture& rTexture, const Sal { OpenGLZone aZone; - if( !UseProgram( "textureVertexShader", "textureFragmentShader" ) ) + if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader")) return; - mpProgram->SetTexture( "sampler", rTexture ); + mpProgram->SetShaderType(TextureShaderType::Normal); + mpProgram->SetIdentityTransform("transform"); + mpProgram->SetTexture("texture", rTexture); mpProgram->SetBlendMode( bPremultiplied ? GL_ONE : GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); DrawTextureRect( rTexture, rPosAry, bInverted ); @@ -1406,8 +1413,10 @@ void OpenGLSalGraphicsImpl::DrawTextureDiff( OpenGLTexture& rTexture, OpenGLText { OpenGLZone aZone; - if( !UseProgram( "maskedTextureVertexShader", "diffTextureFragmentShader" ) ) + if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader")) return; + mpProgram->SetShaderType(TextureShaderType::Diff); + mpProgram->SetIdentityTransform("transform"); mpProgram->SetTexture( "texture", rTexture ); mpProgram->SetTexture( "mask", rMask ); mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); @@ -1424,9 +1433,11 @@ void OpenGLSalGraphicsImpl::DrawTextureWithMask( OpenGLTexture& rTexture, OpenGL { OpenGLZone aZone; - if( !UseProgram( "maskedTextureVertexShader", "maskedTextureFragmentShader" ) ) + if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader")) return; - mpProgram->SetTexture( "sampler", rTexture ); + mpProgram->SetShaderType(TextureShaderType::Masked); + mpProgram->SetIdentityTransform("transform"); + mpProgram->SetTexture( "texture", rTexture ); mpProgram->SetTexture( "mask", rMask ); mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); @@ -1446,9 +1457,10 @@ void OpenGLSalGraphicsImpl::DrawBlendedTexture( OpenGLTexture& rTexture, OpenGLT { OpenGLZone aZone; - if( !UseProgram( "blendedTextureVertexShader", "blendedTextureFragmentShader" ) ) + if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader")) return; - mpProgram->SetTexture( "sampler", rTexture ); + mpProgram->SetShaderType(TextureShaderType::Blend); + mpProgram->SetTexture( "texture", rTexture ); mpProgram->SetTexture( "mask", rMask ); mpProgram->SetTexture( "alpha", rAlpha ); @@ -1469,10 +1481,12 @@ void OpenGLSalGraphicsImpl::DrawMask( OpenGLTexture& rMask, SalColor nMaskColor, { OpenGLZone aZone; - if( !UseProgram( "textureVertexShader", "maskFragmentShader" ) ) + if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader")) return; + mpProgram->SetShaderType(TextureShaderType::MaskedColor); + mpProgram->SetIdentityTransform("transform"); mpProgram->SetColor( "color", nMaskColor, 0 ); - mpProgram->SetTexture( "sampler", rMask ); + mpProgram->SetTexture("texture", rMask); mpProgram->SetBlendMode( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); DrawTextureRect( rMask, pPosAry ); mpProgram->Clean(); @@ -1530,15 +1544,16 @@ void OpenGLSalGraphicsImpl::FlushDeferredDrawing() } #endif - if( !UseProgram( "textureVertexShader", "maskFragmentShader" ) ) + if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader")) return; - + mpProgram->SetShaderType(TextureShaderType::MaskedColor); + mpProgram->SetIdentityTransform("transform"); mpProgram->SetBlendMode(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for (auto& rPair : mpAccumulatedTextures->getAccumulatedTexturesMap()) { OpenGLTexture& rTexture = rPair.second->maTexture; - mpProgram->SetTexture("sampler", rTexture); + mpProgram->SetTexture("texture", rTexture); for (auto& rColorTwoRectPair: rPair.second->maColorTextureDrawParametersMap) { mpProgram->SetColor("color", rColorTwoRectPair.first, 0); @@ -2048,11 +2063,13 @@ bool OpenGLSalGraphicsImpl::blendBitmap( VCL_GL_INFO( "::blendBitmap" ); PreDraw(); - if (!UseProgram("textureVertexShader", "textureFragmentShader")) + if (!UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader")) return true; + mpProgram->SetShaderType(TextureShaderType::Normal); + mpProgram->SetIdentityTransform("transform"); + mpProgram->SetTexture("texture", rTexture); mpProgram->SetBlendMode(GL_ZERO, GL_SRC_COLOR); - mpProgram->SetTexture("sampler", rTexture); DrawTextureRect(rTexture, rPosAry); mpProgram->Clean(); @@ -2332,12 +2349,14 @@ void OpenGLSalGraphicsImpl::doFlush() VCL_GL_INFO( "Texture height " << maOffscreenTex.GetHeight() << " vs. window height " << GetHeight() ); OpenGLProgram *pProgram = - mpWindowContext->UseProgram( "textureVertexShader", "textureFragmentShader", "// flush shader\n" ); // flush helps profiling + mpWindowContext->UseProgram("combinedTextureVertexShader", "combinedTextureFragmentShader", "// flush shader\n" ); // flush helps profiling if( !pProgram ) VCL_GL_INFO( "Can't compile simple copying shader !" ); else { - pProgram->SetTexture( "sampler", maOffscreenTex ); + pProgram->SetShaderType(TextureShaderType::Normal); + pProgram->SetIdentityTransform("transform"); + pProgram->SetTexture("texture", maOffscreenTex); SalTwoRect aPosAry( 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight(), 0, 0, maOffscreenTex.GetWidth(), maOffscreenTex.GetHeight() ); diff --git a/vcl/opengl/program.cxx b/vcl/opengl/program.cxx index 71530cbf75cb..2331080d28c1 100644 --- a/vcl/opengl/program.cxx +++ b/vcl/opengl/program.cxx @@ -135,6 +135,16 @@ void OpenGLProgram::SetExtrusionVectors(const GLvoid* pData) SetVertexAttrib(mnNormalAttrib, "extrusion_vectors", pData, 3); } +void OpenGLProgram::SetShaderType(TextureShaderType eTextureShaderType) +{ + SetUniform1i("type", GLint(eTextureShaderType)); +} + +void OpenGLProgram::SetShaderType(DrawShaderType eDrawShaderType) +{ + SetUniform1i("type", GLint(eDrawShaderType)); +} + GLuint OpenGLProgram::GetUniformLocation( const OString& rName ) { auto it = maUniformLocations.find( rName ); @@ -286,6 +296,14 @@ void OpenGLProgram::SetTransform( CHECK_GL_ERROR(); } +void OpenGLProgram::SetIdentityTransform(const OString& rName) +{ + GLuint nUniform = GetUniformLocation(rName); + glm::mat4 aMatrix = glm::mat4(); + glUniformMatrix4fv(nUniform, 1, GL_FALSE, glm::value_ptr( aMatrix ) ); + CHECK_GL_ERROR(); +} + void OpenGLProgram::ApplyMatrix(float fWidth, float fHeight, float fPixelOffset) { |