1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include "opengl/program.hxx"
11 #include "opengl/RenderState.hxx"
13 #include <vcl/opengl/OpenGLHelper.hxx>
14 #include <vcl/opengl/OpenGLContext.hxx>
16 #include <glm/glm.hpp>
17 #include <glm/gtc/type_ptr.hpp>
18 #include <glm/gtc/matrix_transform.hpp>
20 OpenGLProgram::OpenGLProgram() :
22 mnEnabledAttribs( 0 ),
23 mnPositionAttrib( SAL_MAX_UINT32
),
24 mnTexCoordAttrib( SAL_MAX_UINT32
),
25 mnAlphaCoordAttrib( SAL_MAX_UINT32
),
26 mnMaskCoordAttrib( SAL_MAX_UINT32
),
27 mnNormalAttrib( SAL_MAX_UINT32
),
31 mfLastPixelOffset(0.0)
35 OpenGLProgram::~OpenGLProgram()
37 maUniformLocations
.clear();
40 glDeleteProgram( mnId
);
45 bool OpenGLProgram::Load( const OUString
& rVertexShader
,
46 const OUString
& rFragmentShader
,
47 const rtl::OString
& preamble
,
48 const rtl::OString
& rDigest
)
50 mnId
= OpenGLHelper::LoadShaders( rVertexShader
, rFragmentShader
, preamble
, rDigest
);
54 void OpenGLProgram::Reuse()
59 bool OpenGLProgram::Use()
70 bool OpenGLProgram::Clean()
72 // unbind all textures
73 for (OpenGLTexture
& rTexture
: maTextures
)
79 // disable any enabled vertex attrib array
80 if( mnEnabledAttribs
)
82 for( int i
= 0; i
< 32; i
++ )
84 if( mnEnabledAttribs
& ( 1 << i
) )
86 glDisableVertexAttribArray( i
);
96 void OpenGLProgram::SetVertexAttrib( GLuint
& rAttrib
, const OString
& rName
, const GLvoid
* pData
, GLint nSize
)
98 if( rAttrib
== SAL_MAX_UINT32
)
100 rAttrib
= glGetAttribLocation( mnId
, rName
.getStr() );
103 if( (mnEnabledAttribs
& ( 1 << rAttrib
)) == 0 )
105 glEnableVertexAttribArray( rAttrib
);
107 mnEnabledAttribs
|= ( 1 << rAttrib
);
109 glVertexAttribPointer( rAttrib
, nSize
, GL_FLOAT
, GL_FALSE
, 0, pData
);
113 void OpenGLProgram::SetVertices( const GLvoid
* pData
)
115 SetVertexAttrib( mnPositionAttrib
, "position", pData
);
118 void OpenGLProgram::SetTextureCoord( const GLvoid
* pData
)
120 SetVertexAttrib( mnTexCoordAttrib
, "tex_coord_in", pData
);
123 void OpenGLProgram::SetAlphaCoord( const GLvoid
* pData
)
125 SetVertexAttrib( mnAlphaCoordAttrib
, "alpha_coord_in", pData
);
128 void OpenGLProgram::SetMaskCoord(const GLvoid
* pData
)
130 SetVertexAttrib(mnMaskCoordAttrib
, "mask_coord_in", pData
);
133 void OpenGLProgram::SetExtrusionVectors(const GLvoid
* pData
)
135 SetVertexAttrib(mnNormalAttrib
, "extrusion_vectors", pData
, 3);
138 void OpenGLProgram::SetShaderType(TextureShaderType eTextureShaderType
)
140 SetUniform1i("type", GLint(eTextureShaderType
));
143 void OpenGLProgram::SetShaderType(DrawShaderType eDrawShaderType
)
145 SetUniform1i("type", GLint(eDrawShaderType
));
148 GLuint
OpenGLProgram::GetUniformLocation( const OString
& rName
)
150 auto it
= maUniformLocations
.find( rName
);
151 if( it
== maUniformLocations
.end() )
153 GLuint nLocation
= glGetUniformLocation( mnId
, rName
.getStr() );
155 maUniformLocations
[rName
] = nLocation
;
162 void OpenGLProgram::DrawArrays(GLenum aMode
, std::vector
<GLfloat
>& aVertices
)
165 OpenGLContext::getVCLContext()->state()->blend().disable();
167 SetVertices(aVertices
.data());
168 glDrawArrays(aMode
, 0, aVertices
.size() / 2);
171 void OpenGLProgram::SetUniform1f( const OString
& rName
, GLfloat v1
)
173 GLuint nUniform
= GetUniformLocation( rName
);
174 glUniform1f( nUniform
, v1
);
178 void OpenGLProgram::SetUniform2f( const OString
& rName
, GLfloat v1
, GLfloat v2
)
180 GLuint nUniform
= GetUniformLocation( rName
);
181 glUniform2f( nUniform
, v1
, v2
);
185 void OpenGLProgram::SetUniform1fv( const OString
& rName
, GLsizei nCount
, GLfloat
* aValues
)
187 GLuint nUniform
= GetUniformLocation( rName
);
188 glUniform1fv( nUniform
, nCount
, aValues
);
192 void OpenGLProgram::SetUniform2fv( const OString
& rName
, GLsizei nCount
, GLfloat
* aValues
)
194 GLuint nUniform
= GetUniformLocation( rName
);
195 glUniform2fv( nUniform
, nCount
, aValues
);
199 void OpenGLProgram::SetUniform1i( const OString
& rName
, GLint v1
)
201 GLuint nUniform
= GetUniformLocation( rName
);
202 glUniform1i( nUniform
, v1
);
206 void OpenGLProgram::SetColor( const OString
& rName
, SalColor nColor
, sal_uInt8 nTransparency
)
208 GLuint nUniform
= GetUniformLocation( rName
);
209 glUniform4f( nUniform
,
210 ((float) SALCOLOR_RED( nColor
)) / 255,
211 ((float) SALCOLOR_GREEN( nColor
)) / 255,
212 ((float) SALCOLOR_BLUE( nColor
)) / 255,
213 (100 - nTransparency
) * (1.0 / 100) );
216 if( nTransparency
> 0 )
217 SetBlendMode( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
220 void OpenGLProgram::SetColorf( const OString
& rName
, SalColor nColor
, double fTransparency
)
222 GLuint nUniform
= GetUniformLocation( rName
);
223 glUniform4f( nUniform
,
224 ((float) SALCOLOR_RED( nColor
)) / 255,
225 ((float) SALCOLOR_GREEN( nColor
)) / 255,
226 ((float) SALCOLOR_BLUE( nColor
)) / 255,
227 (1.0f
- fTransparency
) );
230 if( fTransparency
> 0.0 )
231 SetBlendMode( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
234 void OpenGLProgram::SetColor( const OString
& rName
, const Color
& rColor
)
236 GLuint nUniform
= GetUniformLocation( rName
);
237 glUniform4f( nUniform
,
238 ((float) rColor
.GetRed()) / 255,
239 ((float) rColor
.GetGreen()) / 255,
240 ((float) rColor
.GetBlue()) / 255,
241 1.0f
- ((float) rColor
.GetTransparency()) / 255 );
244 if( rColor
.GetTransparency() > 0 )
245 SetBlendMode( GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
248 void OpenGLProgram::SetColorWithIntensity( const OString
& rName
, const Color
& rColor
, long nFactor
)
250 GLuint nUniform
= GetUniformLocation( rName
);
251 glUniform4f( nUniform
,
252 ((float) rColor
.GetRed()) * nFactor
/ 25500.0,
253 ((float) rColor
.GetGreen()) * nFactor
/ 25500.0,
254 ((float) rColor
.GetBlue()) * nFactor
/ 25500.0,
259 void OpenGLProgram::SetTexture( const OString
& rName
, OpenGLTexture
& rTexture
)
261 GLuint nUniform
= GetUniformLocation( rName
);
262 int nIndex
= maTextures
.size();
264 glUniform1i( nUniform
, nIndex
);
267 std::unique_ptr
<RenderState
>& rState
= OpenGLContext::getVCLContext()->state();
268 rState
->texture().active(nIndex
);
271 maTextures
.push_back(rTexture
);
274 void OpenGLProgram::SetTransform(
275 const OString
& rName
,
276 const OpenGLTexture
& rTexture
,
277 const basegfx::B2DPoint
& rNull
,
278 const basegfx::B2DPoint
& rX
,
279 const basegfx::B2DPoint
& rY
)
281 auto nTexWidth
= rTexture
.GetWidth();
282 auto nTexHeight
= rTexture
.GetHeight();
283 if (nTexWidth
== 0 || nTexHeight
== 0)
286 GLuint nUniform
= GetUniformLocation( rName
);
287 const basegfx::B2DVector aXRel
= rX
- rNull
;
288 const basegfx::B2DVector aYRel
= rY
- rNull
;
289 const float aValues
[] = {
290 (float) aXRel
.getX()/nTexWidth
, (float) aXRel
.getY()/nTexWidth
, 0, 0,
291 (float) aYRel
.getX()/nTexHeight
, (float) aYRel
.getY()/nTexHeight
, 0, 0,
293 (float) rNull
.getX(), (float) rNull
.getY(), 0, 1 };
294 glm::mat4 aMatrix
= glm::make_mat4( aValues
);
295 glUniformMatrix4fv( nUniform
, 1, GL_FALSE
, glm::value_ptr( aMatrix
) );
299 void OpenGLProgram::SetIdentityTransform(const OString
& rName
)
301 GLuint nUniform
= GetUniformLocation(rName
);
302 glm::mat4 aMatrix
= glm::mat4();
303 glUniformMatrix4fv(nUniform
, 1, GL_FALSE
, glm::value_ptr( aMatrix
) );
307 void OpenGLProgram::ApplyMatrix(float fWidth
, float fHeight
, float fPixelOffset
)
310 if (mfLastWidth
== fWidth
&& mfLastHeight
== fHeight
&& mfLastPixelOffset
== fPixelOffset
)
313 mfLastWidth
= fWidth
;
314 mfLastHeight
= fHeight
;
315 mfLastPixelOffset
= fPixelOffset
;
317 OString
sProjectionMatrix("mvp");
318 GLuint nUniform
= GetUniformLocation(sProjectionMatrix
);
320 glm::mat4 aMVP
= glm::ortho(0.0f
, fWidth
, fHeight
, 0.0f
, 0.0f
, 1.0f
);
322 if (fPixelOffset
!= 0.0f
)
323 aMVP
= glm::translate(aMVP
, glm::vec3(fPixelOffset
, fPixelOffset
, 0.0f
));
325 glUniformMatrix4fv(nUniform
, 1, GL_FALSE
, glm::value_ptr(aMVP
));
329 void OpenGLProgram::SetBlendMode(GLenum nSFactor
, GLenum nDFactor
)
331 OpenGLContext::getVCLContext()->state()->blend().enable();
332 OpenGLContext::getVCLContext()->state()->blend().func(nSFactor
, nDFactor
);
336 bool OpenGLProgram::DrawTexture( const OpenGLTexture
& rTexture
)
341 float fWidth
= rTexture
.GetWidth();
342 float fHeight
= rTexture
.GetHeight();
345 float fMaxX
= fWidth
;
347 float fMaxY
= fHeight
;
349 std::vector
<GLfloat
> aPosition
{
355 GLfloat aTexCoord
[8];
357 rTexture
.GetWholeCoord( aTexCoord
);
358 SetTextureCoord( aTexCoord
);
359 ApplyMatrix(fWidth
, fHeight
);
360 DrawArrays(GL_TRIANGLE_FAN
, aPosition
);
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */