2 * Copyright (C) 2005-2024 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.
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 CGLShader::CGLShader(const char* shader
, const std::string
& prefix
)
23 m_clipPossible
= false;
25 VertexShader()->LoadSource("gl_shader_vert.glsl");
26 PixelShader()->LoadSource(shader
, prefix
);
29 CGLShader::CGLShader(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 CGLShader::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");
48 // Variables passed directly to the Vertex shader
49 m_hProj
= glGetUniformLocation(ProgramHandle(), "m_proj");
50 m_hModel
= glGetUniformLocation(ProgramHandle(), "m_model");
51 m_hMatrix
= glGetUniformLocation(ProgramHandle(), "m_matrix");
52 m_hShaderClip
= glGetUniformLocation(ProgramHandle(), "m_shaderClip");
53 m_hCoordStep
= glGetUniformLocation(ProgramHandle(), "m_cordStep");
54 m_hDepth
= glGetUniformLocation(ProgramHandle(), "m_depth");
57 m_hPos
= glGetAttribLocation(ProgramHandle(), "m_attrpos");
58 m_hCol
= glGetAttribLocation(ProgramHandle(), "m_attrcol");
59 m_hCord0
= glGetAttribLocation(ProgramHandle(), "m_attrcord0");
60 m_hCord1
= glGetAttribLocation(ProgramHandle(), "m_attrcord1");
62 // It's okay to do this only one time. Textures units never change.
63 glUseProgram(ProgramHandle());
64 glUniform1i(m_hTex0
, 0);
65 glUniform1i(m_hTex1
, 1);
66 glUniform4f(m_hUniCol
, 1.0, 1.0, 1.0, 1.0);
71 bool CGLShader::OnEnabled()
73 // This is called after glUseProgram()
75 const GLfloat
*projMatrix
= glMatrixProject
.Get();
76 const GLfloat
*modelMatrix
= glMatrixModview
.Get();
77 glUniformMatrix4fv(m_hProj
, 1, GL_FALSE
, projMatrix
);
78 glUniformMatrix4fv(m_hModel
, 1, GL_FALSE
, modelMatrix
);
80 const TransformMatrix
&guiMatrix
= CServiceBroker::GetWinSystem()->GetGfxContext().GetGUIMatrix();
81 CRect viewPort
; // absolute positions of corners
82 CServiceBroker::GetRenderSystem()->GetViewPort(viewPort
);
84 /* glScissor operates in window coordinates. In order that we can use it to
85 * perform clipping, we must ensure that there is an independent linear
86 * transformation from the coordinate system used by CGraphicContext::ClipRect
87 * to window coordinates, separately for X and Y (in other words, no
88 * rotation or shear is introduced at any stage). To do, this, we need to
89 * check that zeros are present in the following locations:
95 * ^ TransformMatrix::TransformX/Y/ZCoord are only ever called with
96 * input z = 0, so this column doesn't matter
101 * \ * * * * / <- eye w has no influence on window x/y (last column below
102 * is either 0 or ignored)
106 * | * * * * | <- normalised device coordinate z has no influence on window x/y
109 * Some of these zeros are not strictly required to ensure this, but they tend
110 * to be zeroed in the common case, so by checking for zeros here, we simplify
111 * the calculation of the window x/y coordinates further down the line.
113 * (Minor detail: we don't quite deal in window coordinates as defined by
114 * OpenGL, because CRenderSystemGLES::SetScissors flips the Y axis. But all
115 * that's needed to handle that is an effective negation at the stage where
116 * Y is in normalised device coordinates.)
118 m_clipPossible
= guiMatrix
.m
[0][1] == 0 &&
119 guiMatrix
.m
[1][0] == 0 &&
120 guiMatrix
.m
[2][0] == 0 &&
121 guiMatrix
.m
[2][1] == 0 &&
122 modelMatrix
[0+1*4] == 0 &&
123 modelMatrix
[0+2*4] == 0 &&
124 modelMatrix
[1+0*4] == 0 &&
125 modelMatrix
[1+2*4] == 0 &&
126 modelMatrix
[2+0*4] == 0 &&
127 modelMatrix
[2+1*4] == 0 &&
128 projMatrix
[0+1*4] == 0 &&
129 projMatrix
[0+2*4] == 0 &&
130 projMatrix
[0+3*4] == 0 &&
131 projMatrix
[1+0*4] == 0 &&
132 projMatrix
[1+2*4] == 0 &&
133 projMatrix
[1+3*4] == 0 &&
134 projMatrix
[3+0*4] == 0 &&
135 projMatrix
[3+1*4] == 0 &&
136 projMatrix
[3+3*4] == 0;
145 m_clipXFactor
= guiMatrix
.m
[0][0] * modelMatrix
[0+0*4] * projMatrix
[0+0*4];
146 m_clipXOffset
= (guiMatrix
.m
[0][3] * modelMatrix
[0+0*4] + modelMatrix
[0+3*4]) * projMatrix
[0+0*4];
147 m_clipYFactor
= guiMatrix
.m
[1][1] * modelMatrix
[1+1*4] * projMatrix
[1+1*4];
148 m_clipYOffset
= (guiMatrix
.m
[1][3] * modelMatrix
[1+1*4] + modelMatrix
[1+3*4]) * projMatrix
[1+1*4];
149 float clipW
= (guiMatrix
.m
[2][3] * modelMatrix
[2+2*4] + modelMatrix
[2+3*4]) * projMatrix
[3+2*4];
150 float xMult
= (viewPort
.x2
- viewPort
.x1
) / (2 * clipW
);
151 float yMult
= (viewPort
.y1
- viewPort
.y2
) / (2 * clipW
); // correct for inverted window coordinate scheme
152 m_clipXFactor
= m_clipXFactor
* xMult
;
153 m_clipXOffset
= m_clipXOffset
* xMult
+ (viewPort
.x2
+ viewPort
.x1
) / 2;
154 m_clipYFactor
= m_clipYFactor
* yMult
;
155 m_clipYOffset
= m_clipYOffset
* yMult
+ (viewPort
.y2
+ viewPort
.y1
) / 2;
161 void CGLShader::Free()
164 CGLSLShaderProgram::Free();