Merge pull request #22816 from CastagnaIT/fix_tx3g
[xbmc.git] / xbmc / guilib / GUITextureGLES.cpp
blobd92201ae7fcced79279a25101f14d8abc8f6a026
1 /*
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.
7 */
9 #include "GUITextureGLES.h"
11 #include "ServiceBroker.h"
12 #include "Texture.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"
20 #include <cstddef>
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(UTILS::COLOR::Color color)
47 CTexture* texture = m_texture.m_textures[m_currentFrame].get();
48 texture->LoadToGPU();
49 if (m_diffuse.size())
50 m_diffuse.m_textures[0]->LoadToGPU();
52 texture->BindToUnit(0);
54 // Setup Colors
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;
69 if (m_diffuse.size())
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);
75 else
77 m_renderSystem->EnableGUIShader(ShaderMethodGLES::SM_MULTI_BLENDCOLOR);
80 hasAlpha |= m_diffuse.m_textures[0]->HasAlpha();
82 m_diffuse.m_textures[0]->BindToUnit(1);
85 else
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);
91 else
93 m_renderSystem->EnableGUIShader(ShaderMethodGLES::SM_TEXTURE);
97 if ( hasAlpha )
99 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
100 glEnable( GL_BLEND );
102 else
104 glDisable(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();
118 if(uniColLoc >= 0)
120 glUniform4f(uniColLoc,(m_col[0] / 255.0f), (m_col[1] / 255.0f), (m_col[2] / 255.0f), (m_col[3] / 255.0f));
123 if(m_diffuse.size())
125 glVertexAttribPointer(tex1Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), (char*)&m_packedVertices[0] + offsetof(PackedVertex, u2));
126 glEnableVertexAttribArray(tex1Loc);
128 glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), (char*)&m_packedVertices[0] + offsetof(PackedVertex, x));
129 glEnableVertexAttribArray(posLoc);
130 glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), (char*)&m_packedVertices[0] + offsetof(PackedVertex, u1));
131 glEnableVertexAttribArray(tex0Loc);
133 glDrawElements(GL_TRIANGLES, m_packedVertices.size()*6 / 4, GL_UNSIGNED_SHORT, m_idx.data());
135 if (m_diffuse.size())
136 glDisableVertexAttribArray(tex1Loc);
138 glDisableVertexAttribArray(posLoc);
139 glDisableVertexAttribArray(tex0Loc);
142 if (m_diffuse.size())
143 glActiveTexture(GL_TEXTURE0);
144 glEnable(GL_BLEND);
145 m_renderSystem->DisableGUIShader();
148 void CGUITextureGLES::Draw(float *x, float *y, float *z, const CRect &texture, const CRect &diffuse, int orientation)
150 PackedVertex vertices[4];
152 // Setup texture coordinates
153 //TopLeft
154 vertices[0].u1 = texture.x1;
155 vertices[0].v1 = texture.y1;
156 //TopRight
157 if (orientation & 4)
159 vertices[1].u1 = texture.x1;
160 vertices[1].v1 = texture.y2;
162 else
164 vertices[1].u1 = texture.x2;
165 vertices[1].v1 = texture.y1;
167 //BottomRight
168 vertices[2].u1 = texture.x2;
169 vertices[2].v1 = texture.y2;
170 //BottomLeft
171 if (orientation & 4)
173 vertices[3].u1 = texture.x2;
174 vertices[3].v1 = texture.y1;
176 else
178 vertices[3].u1 = texture.x1;
179 vertices[3].v1 = texture.y2;
182 if (m_diffuse.size())
184 //TopLeft
185 vertices[0].u2 = diffuse.x1;
186 vertices[0].v2 = diffuse.y1;
187 //TopRight
188 if (m_info.orientation & 4)
190 vertices[1].u2 = diffuse.x1;
191 vertices[1].v2 = diffuse.y2;
193 else
195 vertices[1].u2 = diffuse.x2;
196 vertices[1].v2 = diffuse.y1;
198 //BottomRight
199 vertices[2].u2 = diffuse.x2;
200 vertices[2].v2 = diffuse.y2;
201 //BottomLeft
202 if (m_info.orientation & 4)
204 vertices[3].u2 = diffuse.x2;
205 vertices[3].v2 = diffuse.y1;
207 else
209 vertices[3].u2 = diffuse.x1;
210 vertices[3].v2 = diffuse.y2;
214 for (int i=0; i<4; i++)
216 vertices[i].x = x[i];
217 vertices[i].y = y[i];
218 vertices[i].z = z[i];
219 m_packedVertices.push_back(vertices[i]);
222 if ((m_packedVertices.size() / 4) > (m_idx.size() / 6))
224 size_t i = m_packedVertices.size() - 4;
225 m_idx.push_back(i+0);
226 m_idx.push_back(i+1);
227 m_idx.push_back(i+2);
228 m_idx.push_back(i+2);
229 m_idx.push_back(i+3);
230 m_idx.push_back(i+0);
234 void CGUITextureGLES::DrawQuad(const CRect& rect,
235 UTILS::COLOR::Color color,
236 CTexture* texture,
237 const CRect* texCoords)
239 CRenderSystemGLES *renderSystem = dynamic_cast<CRenderSystemGLES*>(CServiceBroker::GetRenderSystem());
240 if (texture)
242 texture->LoadToGPU();
243 texture->BindToUnit(0);
246 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
247 glEnable(GL_BLEND); // Turn Blending On
249 VerifyGLState();
251 GLubyte col[4];
252 GLfloat ver[4][3];
253 GLfloat tex[4][2];
254 GLubyte idx[4] = {0, 1, 3, 2}; //determines order of triangle strip
256 if (texture)
257 renderSystem->EnableGUIShader(ShaderMethodGLES::SM_TEXTURE);
258 else
259 renderSystem->EnableGUIShader(ShaderMethodGLES::SM_DEFAULT);
261 GLint posLoc = renderSystem->GUIShaderGetPos();
262 GLint tex0Loc = renderSystem->GUIShaderGetCoord0();
263 GLint uniColLoc= renderSystem->GUIShaderGetUniCol();
265 glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, 0, ver);
266 if (texture)
267 glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, 0, tex);
269 glEnableVertexAttribArray(posLoc);
270 if (texture)
271 glEnableVertexAttribArray(tex0Loc);
273 // Setup Colors
274 col[0] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::R, color);
275 col[1] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::G, color);
276 col[2] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::B, color);
277 col[3] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::A, color);
279 glUniform4f(uniColLoc, col[0] / 255.0f, col[1] / 255.0f, col[2] / 255.0f, col[3] / 255.0f);
281 ver[0][0] = ver[3][0] = rect.x1;
282 ver[0][1] = ver[1][1] = rect.y1;
283 ver[1][0] = ver[2][0] = rect.x2;
284 ver[2][1] = ver[3][1] = rect.y2;
285 ver[0][2] = ver[1][2] = ver[2][2] = ver[3][2]= 0;
287 if (texture)
289 // Setup texture coordinates
290 CRect coords = texCoords ? *texCoords : CRect(0.0f, 0.0f, 1.0f, 1.0f);
291 tex[0][0] = tex[3][0] = coords.x1;
292 tex[0][1] = tex[1][1] = coords.y1;
293 tex[1][0] = tex[2][0] = coords.x2;
294 tex[2][1] = tex[3][1] = coords.y2;
296 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
298 glDisableVertexAttribArray(posLoc);
299 if (texture)
300 glDisableVertexAttribArray(tex0Loc);
302 renderSystem->DisableGUIShader();