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(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();
120 glUniform4f(uniColLoc
,(m_col
[0] / 255.0f
), (m_col
[1] / 255.0f
), (m_col
[2] / 255.0f
), (m_col
[3] / 255.0f
));
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
);
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
154 vertices
[0].u1
= texture
.x1
;
155 vertices
[0].v1
= texture
.y1
;
159 vertices
[1].u1
= texture
.x1
;
160 vertices
[1].v1
= texture
.y2
;
164 vertices
[1].u1
= texture
.x2
;
165 vertices
[1].v1
= texture
.y1
;
168 vertices
[2].u1
= texture
.x2
;
169 vertices
[2].v1
= texture
.y2
;
173 vertices
[3].u1
= texture
.x2
;
174 vertices
[3].v1
= texture
.y1
;
178 vertices
[3].u1
= texture
.x1
;
179 vertices
[3].v1
= texture
.y2
;
182 if (m_diffuse
.size())
185 vertices
[0].u2
= diffuse
.x1
;
186 vertices
[0].v2
= diffuse
.y1
;
188 if (m_info
.orientation
& 4)
190 vertices
[1].u2
= diffuse
.x1
;
191 vertices
[1].v2
= diffuse
.y2
;
195 vertices
[1].u2
= diffuse
.x2
;
196 vertices
[1].v2
= diffuse
.y1
;
199 vertices
[2].u2
= diffuse
.x2
;
200 vertices
[2].v2
= diffuse
.y2
;
202 if (m_info
.orientation
& 4)
204 vertices
[3].u2
= diffuse
.x2
;
205 vertices
[3].v2
= diffuse
.y1
;
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
,
237 const CRect
* texCoords
)
239 CRenderSystemGLES
*renderSystem
= dynamic_cast<CRenderSystemGLES
*>(CServiceBroker::GetRenderSystem());
242 texture
->LoadToGPU();
243 texture
->BindToUnit(0);
246 glBlendFunc(GL_SRC_ALPHA
,GL_ONE_MINUS_SRC_ALPHA
);
247 glEnable(GL_BLEND
); // Turn Blending On
254 GLubyte idx
[4] = {0, 1, 3, 2}; //determines order of triangle strip
257 renderSystem
->EnableGUIShader(ShaderMethodGLES::SM_TEXTURE
);
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
);
267 glVertexAttribPointer(tex0Loc
, 2, GL_FLOAT
, 0, 0, tex
);
269 glEnableVertexAttribArray(posLoc
);
271 glEnableVertexAttribArray(tex0Loc
);
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;
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
);
300 glDisableVertexAttribArray(tex0Loc
);
302 renderSystem
->DisableGUIShader();