2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "GLESShader.h"
11 #include "ServiceBroker.h"
12 #include "rendering/MatrixGL.h"
13 #include "rendering/RenderSystem.h"
14 #include "utils/log.h"
15 #include "windowing/GraphicContext.h"
17 using namespace Shaders
;
19 CGLESShader::CGLESShader(const char* shader
, const std::string
& prefix
)
23 m_clipPossible
= false;
25 VertexShader()->LoadSource("gles_shader.vert");
26 PixelShader()->LoadSource(shader
, prefix
);
29 CGLESShader::CGLESShader(const char* vshader
, const char* fshader
, const std::string
& prefix
)
33 m_clipPossible
= false;
35 VertexShader()->LoadSource(vshader
, prefix
);
36 PixelShader()->LoadSource(fshader
, prefix
);
39 void CGLESShader::OnCompiledAndLinked()
41 // This is called after CompileAndLink()
43 // Variables passed directly to the Fragment shader
44 m_hTex0
= glGetUniformLocation(ProgramHandle(), "m_samp0");
45 m_hTex1
= glGetUniformLocation(ProgramHandle(), "m_samp1");
46 m_hUniCol
= glGetUniformLocation(ProgramHandle(), "m_unicol");
47 m_hField
= glGetUniformLocation(ProgramHandle(), "m_field");
48 m_hStep
= glGetUniformLocation(ProgramHandle(), "m_step");
49 m_hContrast
= glGetUniformLocation(ProgramHandle(), "m_contrast");
50 m_hBrightness
= glGetUniformLocation(ProgramHandle(), "m_brightness");
52 // Variables passed directly to the Vertex shader
53 m_hProj
= glGetUniformLocation(ProgramHandle(), "m_proj");
54 m_hModel
= glGetUniformLocation(ProgramHandle(), "m_model");
55 m_hCoord0Matrix
= glGetUniformLocation(ProgramHandle(), "m_coord0Matrix");
58 m_hPos
= glGetAttribLocation(ProgramHandle(), "m_attrpos");
59 m_hCol
= glGetAttribLocation(ProgramHandle(), "m_attrcol");
60 m_hCord0
= glGetAttribLocation(ProgramHandle(), "m_attrcord0");
61 m_hCord1
= glGetAttribLocation(ProgramHandle(), "m_attrcord1");
63 // It's okay to do this only one time. Textures units never change.
64 glUseProgram( ProgramHandle() );
65 glUniform1i(m_hTex0
, 0);
66 glUniform1i(m_hTex1
, 1);
67 glUniform4f(m_hUniCol
, 1.0, 1.0, 1.0, 1.0);
69 const float identity
[16] = {
70 1.0f
, 0.0f
, 0.0f
, 0.0f
,
71 0.0f
, 1.0f
, 0.0f
, 0.0f
,
72 0.0f
, 0.0f
, 1.0f
, 0.0f
,
73 0.0f
, 0.0f
, 0.0f
, 1.0f
75 glUniformMatrix4fv(m_hCoord0Matrix
, 1, GL_FALSE
, identity
);
80 bool CGLESShader::OnEnabled()
82 // This is called after glUseProgram()
84 const GLfloat
*projMatrix
= glMatrixProject
.Get();
85 const GLfloat
*modelMatrix
= glMatrixModview
.Get();
86 glUniformMatrix4fv(m_hProj
, 1, GL_FALSE
, projMatrix
);
87 glUniformMatrix4fv(m_hModel
, 1, GL_FALSE
, modelMatrix
);
89 const TransformMatrix
&guiMatrix
= CServiceBroker::GetWinSystem()->GetGfxContext().GetGUIMatrix();
90 CRect viewPort
; // absolute positions of corners
91 CServiceBroker::GetRenderSystem()->GetViewPort(viewPort
);
93 /* glScissor operates in window coordinates. In order that we can use it to
94 * perform clipping, we must ensure that there is an independent linear
95 * transformation from the coordinate system used by CGraphicContext::ClipRect
96 * to window coordinates, separately for X and Y (in other words, no
97 * rotation or shear is introduced at any stage). To do, this, we need to
98 * check that zeros are present in the following locations:
104 * ^ TransformMatrix::TransformX/Y/ZCoord are only ever called with
105 * input z = 0, so this column doesn't matter
110 * \ * * * * / <- eye w has no influence on window x/y (last column below
111 * is either 0 or ignored)
115 * | * * * * | <- normalised device coordinate z has no influence on window x/y
118 * Some of these zeros are not strictly required to ensure this, but they tend
119 * to be zeroed in the common case, so by checking for zeros here, we simplify
120 * the calculation of the window x/y coordinates further down the line.
122 * (Minor detail: we don't quite deal in window coordinates as defined by
123 * OpenGL, because CRenderSystemGLES::SetScissors flips the Y axis. But all
124 * that's needed to handle that is an effective negation at the stage where
125 * Y is in normalised device coordinates.)
127 m_clipPossible
= guiMatrix
.m
[0][1] == 0 &&
128 guiMatrix
.m
[1][0] == 0 &&
129 guiMatrix
.m
[2][0] == 0 &&
130 guiMatrix
.m
[2][1] == 0 &&
131 modelMatrix
[0+1*4] == 0 &&
132 modelMatrix
[0+2*4] == 0 &&
133 modelMatrix
[1+0*4] == 0 &&
134 modelMatrix
[1+2*4] == 0 &&
135 modelMatrix
[2+0*4] == 0 &&
136 modelMatrix
[2+1*4] == 0 &&
137 projMatrix
[0+1*4] == 0 &&
138 projMatrix
[0+2*4] == 0 &&
139 projMatrix
[0+3*4] == 0 &&
140 projMatrix
[1+0*4] == 0 &&
141 projMatrix
[1+2*4] == 0 &&
142 projMatrix
[1+3*4] == 0 &&
143 projMatrix
[3+0*4] == 0 &&
144 projMatrix
[3+1*4] == 0 &&
145 projMatrix
[3+3*4] == 0;
154 m_clipXFactor
= guiMatrix
.m
[0][0] * modelMatrix
[0+0*4] * projMatrix
[0+0*4];
155 m_clipXOffset
= (guiMatrix
.m
[0][3] * modelMatrix
[0+0*4] + modelMatrix
[0+3*4]) * projMatrix
[0+0*4];
156 m_clipYFactor
= guiMatrix
.m
[1][1] * modelMatrix
[1+1*4] * projMatrix
[1+1*4];
157 m_clipYOffset
= (guiMatrix
.m
[1][3] * modelMatrix
[1+1*4] + modelMatrix
[1+3*4]) * projMatrix
[1+1*4];
158 float clipW
= (guiMatrix
.m
[2][3] * modelMatrix
[2+2*4] + modelMatrix
[2+3*4]) * projMatrix
[3+2*4];
159 float xMult
= (viewPort
.x2
- viewPort
.x1
) / (2 * clipW
);
160 float yMult
= (viewPort
.y1
- viewPort
.y2
) / (2 * clipW
); // correct for inverted window coordinate scheme
161 m_clipXFactor
= m_clipXFactor
* xMult
;
162 m_clipXOffset
= m_clipXOffset
* xMult
+ (viewPort
.x2
+ viewPort
.x1
) / 2;
163 m_clipYFactor
= m_clipYFactor
* yMult
;
164 m_clipYOffset
= m_clipYOffset
* yMult
+ (viewPort
.y2
+ viewPort
.y1
) / 2;
167 glUniform1f(m_hBrightness
, 0.0f
);
168 glUniform1f(m_hContrast
, 1.0f
);
173 void CGLESShader::Free()
176 CGLSLShaderProgram::Free();