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 "GUITextureGLES.h"
11 #include "ServiceBroker.h"
13 #include "rendering/gles/RenderSystemGLES.h"
14 #include "utils/GLUtils.h"
15 #include "utils/MathUtils.h"
16 #include "utils/log.h"
17 #include "windowing/GraphicContext.h"
18 #include "windowing/WinSystem.h"
22 void CGUITextureGLES::Register()
24 CGUITexture::Register(CGUITextureGLES::CreateTexture
, CGUITextureGLES::DrawQuad
);
27 CGUITexture
* CGUITextureGLES::CreateTexture(
28 float posX
, float posY
, float width
, float height
, const CTextureInfo
& texture
)
30 return new CGUITextureGLES(posX
, posY
, width
, height
, texture
);
33 CGUITextureGLES::CGUITextureGLES(
34 float posX
, float posY
, float width
, float height
, const CTextureInfo
& texture
)
35 : CGUITexture(posX
, posY
, width
, height
, texture
)
37 m_renderSystem
= dynamic_cast<CRenderSystemGLES
*>(CServiceBroker::GetRenderSystem());
40 CGUITextureGLES
* CGUITextureGLES::Clone() const
42 return new CGUITextureGLES(*this);
45 void CGUITextureGLES::Begin(KODI::UTILS::COLOR::Color color
)
47 CTexture
* texture
= m_texture
.m_textures
[m_currentFrame
].get();
50 m_diffuse
.m_textures
[0]->LoadToGPU();
52 texture
->BindToUnit(0);
55 m_col
[0] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::R
, color
);
56 m_col
[1] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::G
, color
);
57 m_col
[2] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::B
, color
);
58 m_col
[3] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::A
, color
);
60 if (CServiceBroker::GetWinSystem()->UseLimitedColor())
62 m_col
[0] = (235 - 16) * m_col
[0] / 255 + 16;
63 m_col
[1] = (235 - 16) * m_col
[1] / 255 + 16;
64 m_col
[2] = (235 - 16) * m_col
[2] / 255 + 16;
67 bool hasAlpha
= m_texture
.m_textures
[m_currentFrame
]->HasAlpha() || m_col
[3] < 255;
71 if (m_col
[0] == 255 && m_col
[1] == 255 && m_col
[2] == 255 && m_col
[3] == 255 )
73 m_renderSystem
->EnableGUIShader(ShaderMethodGLES::SM_MULTI
);
77 m_renderSystem
->EnableGUIShader(ShaderMethodGLES::SM_MULTI_BLENDCOLOR
);
80 hasAlpha
|= m_diffuse
.m_textures
[0]->HasAlpha();
82 m_diffuse
.m_textures
[0]->BindToUnit(1);
87 if (m_col
[0] == 255 && m_col
[1] == 255 && m_col
[2] == 255 && m_col
[3] == 255)
89 m_renderSystem
->EnableGUIShader(ShaderMethodGLES::SM_TEXTURE_NOBLEND
);
93 m_renderSystem
->EnableGUIShader(ShaderMethodGLES::SM_TEXTURE
);
99 glBlendFuncSeparate(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
, GL_ONE_MINUS_DST_ALPHA
, GL_ONE
);
100 glEnable( GL_BLEND
);
106 m_packedVertices
.clear();
109 void CGUITextureGLES::End()
111 if (m_packedVertices
.size())
113 GLint posLoc
= m_renderSystem
->GUIShaderGetPos();
114 GLint tex0Loc
= m_renderSystem
->GUIShaderGetCoord0();
115 GLint tex1Loc
= m_renderSystem
->GUIShaderGetCoord1();
116 GLint uniColLoc
= m_renderSystem
->GUIShaderGetUniCol();
117 GLint depthLoc
= m_renderSystem
->GUIShaderGetDepth();
121 glUniform4f(uniColLoc
,(m_col
[0] / 255.0f
), (m_col
[1] / 255.0f
), (m_col
[2] / 255.0f
), (m_col
[3] / 255.0f
));
124 glUniform1f(depthLoc
, m_depth
);
128 glVertexAttribPointer(tex1Loc
, 2, GL_FLOAT
, 0, sizeof(PackedVertex
), (char*)&m_packedVertices
[0] + offsetof(PackedVertex
, u2
));
129 glEnableVertexAttribArray(tex1Loc
);
131 glVertexAttribPointer(posLoc
, 3, GL_FLOAT
, 0, sizeof(PackedVertex
), (char*)&m_packedVertices
[0] + offsetof(PackedVertex
, x
));
132 glEnableVertexAttribArray(posLoc
);
133 glVertexAttribPointer(tex0Loc
, 2, GL_FLOAT
, 0, sizeof(PackedVertex
), (char*)&m_packedVertices
[0] + offsetof(PackedVertex
, u1
));
134 glEnableVertexAttribArray(tex0Loc
);
136 glDrawElements(GL_TRIANGLES
, m_packedVertices
.size()*6 / 4, GL_UNSIGNED_SHORT
, m_idx
.data());
138 if (m_diffuse
.size())
139 glDisableVertexAttribArray(tex1Loc
);
141 glDisableVertexAttribArray(posLoc
);
142 glDisableVertexAttribArray(tex0Loc
);
145 if (m_diffuse
.size())
146 glActiveTexture(GL_TEXTURE0
);
148 m_renderSystem
->DisableGUIShader();
151 void CGUITextureGLES::Draw(float *x
, float *y
, float *z
, const CRect
&texture
, const CRect
&diffuse
, int orientation
)
153 PackedVertex vertices
[4];
155 // Setup texture coordinates
157 vertices
[0].u1
= texture
.x1
;
158 vertices
[0].v1
= texture
.y1
;
162 vertices
[1].u1
= texture
.x1
;
163 vertices
[1].v1
= texture
.y2
;
167 vertices
[1].u1
= texture
.x2
;
168 vertices
[1].v1
= texture
.y1
;
171 vertices
[2].u1
= texture
.x2
;
172 vertices
[2].v1
= texture
.y2
;
176 vertices
[3].u1
= texture
.x2
;
177 vertices
[3].v1
= texture
.y1
;
181 vertices
[3].u1
= texture
.x1
;
182 vertices
[3].v1
= texture
.y2
;
185 if (m_diffuse
.size())
188 vertices
[0].u2
= diffuse
.x1
;
189 vertices
[0].v2
= diffuse
.y1
;
191 if (m_info
.orientation
& 4)
193 vertices
[1].u2
= diffuse
.x1
;
194 vertices
[1].v2
= diffuse
.y2
;
198 vertices
[1].u2
= diffuse
.x2
;
199 vertices
[1].v2
= diffuse
.y1
;
202 vertices
[2].u2
= diffuse
.x2
;
203 vertices
[2].v2
= diffuse
.y2
;
205 if (m_info
.orientation
& 4)
207 vertices
[3].u2
= diffuse
.x2
;
208 vertices
[3].v2
= diffuse
.y1
;
212 vertices
[3].u2
= diffuse
.x1
;
213 vertices
[3].v2
= diffuse
.y2
;
217 for (int i
=0; i
<4; i
++)
219 vertices
[i
].x
= x
[i
];
220 vertices
[i
].y
= y
[i
];
221 vertices
[i
].z
= z
[i
];
222 m_packedVertices
.push_back(vertices
[i
]);
225 if ((m_packedVertices
.size() / 4) > (m_idx
.size() / 6))
227 size_t i
= m_packedVertices
.size() - 4;
228 m_idx
.push_back(i
+0);
229 m_idx
.push_back(i
+1);
230 m_idx
.push_back(i
+2);
231 m_idx
.push_back(i
+2);
232 m_idx
.push_back(i
+3);
233 m_idx
.push_back(i
+0);
237 void CGUITextureGLES::DrawQuad(const CRect
& rect
,
238 KODI::UTILS::COLOR::Color color
,
240 const CRect
* texCoords
,
244 CRenderSystemGLES
*renderSystem
= dynamic_cast<CRenderSystemGLES
*>(CServiceBroker::GetRenderSystem());
247 texture
->LoadToGPU();
248 texture
->BindToUnit(0);
253 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
266 GLubyte idx
[4] = {0, 1, 3, 2}; //determines order of triangle strip
269 renderSystem
->EnableGUIShader(ShaderMethodGLES::SM_TEXTURE
);
271 renderSystem
->EnableGUIShader(ShaderMethodGLES::SM_DEFAULT
);
273 GLint posLoc
= renderSystem
->GUIShaderGetPos();
274 GLint tex0Loc
= renderSystem
->GUIShaderGetCoord0();
275 GLint uniColLoc
= renderSystem
->GUIShaderGetUniCol();
276 GLint depthLoc
= renderSystem
->GUIShaderGetDepth();
278 glVertexAttribPointer(posLoc
, 3, GL_FLOAT
, 0, 0, ver
);
280 glVertexAttribPointer(tex0Loc
, 2, GL_FLOAT
, 0, 0, tex
);
282 glEnableVertexAttribArray(posLoc
);
284 glEnableVertexAttribArray(tex0Loc
);
287 col
[0] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::R
, color
);
288 col
[1] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::G
, color
);
289 col
[2] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::B
, color
);
290 col
[3] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::A
, color
);
292 glUniform4f(uniColLoc
, col
[0] / 255.0f
, col
[1] / 255.0f
, col
[2] / 255.0f
, col
[3] / 255.0f
);
293 glUniform1f(depthLoc
, depth
);
295 ver
[0][0] = ver
[3][0] = rect
.x1
;
296 ver
[0][1] = ver
[1][1] = rect
.y1
;
297 ver
[1][0] = ver
[2][0] = rect
.x2
;
298 ver
[2][1] = ver
[3][1] = rect
.y2
;
299 ver
[0][2] = ver
[1][2] = ver
[2][2] = ver
[3][2]= 0;
303 // Setup texture coordinates
304 CRect coords
= texCoords
? *texCoords
: CRect(0.0f
, 0.0f
, 1.0f
, 1.0f
);
305 tex
[0][0] = tex
[3][0] = coords
.x1
;
306 tex
[0][1] = tex
[1][1] = coords
.y1
;
307 tex
[1][0] = tex
[2][0] = coords
.x2
;
308 tex
[2][1] = tex
[3][1] = coords
.y2
;
310 glDrawElements(GL_TRIANGLE_STRIP
, 4, GL_UNSIGNED_BYTE
, idx
);
312 glDisableVertexAttribArray(posLoc
);
314 glDisableVertexAttribArray(tex0Loc
);
316 renderSystem
->DisableGUIShader();