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 "GUITextureGL.h"
11 #include "ServiceBroker.h"
13 #include "rendering/gl/RenderSystemGL.h"
14 #include "utils/GLUtils.h"
15 #include "utils/Geometry.h"
16 #include "utils/log.h"
17 #include "windowing/WinSystem.h"
21 #include "PlatformDefs.h"
23 void CGUITextureGL::Register()
25 CGUITexture::Register(CGUITextureGL::CreateTexture
, CGUITextureGL::DrawQuad
);
28 CGUITexture
* CGUITextureGL::CreateTexture(
29 float posX
, float posY
, float width
, float height
, const CTextureInfo
& texture
)
31 return new CGUITextureGL(posX
, posY
, width
, height
, texture
);
34 CGUITextureGL::CGUITextureGL(
35 float posX
, float posY
, float width
, float height
, const CTextureInfo
& texture
)
36 : CGUITexture(posX
, posY
, width
, height
, texture
)
38 m_renderSystem
= dynamic_cast<CRenderSystemGL
*>(CServiceBroker::GetRenderSystem());
41 CGUITextureGL
* CGUITextureGL::Clone() const
43 return new CGUITextureGL(*this);
46 void CGUITextureGL::Begin(UTILS::COLOR::Color color
)
48 CTexture
* texture
= m_texture
.m_textures
[m_currentFrame
].get();
51 m_diffuse
.m_textures
[0]->LoadToGPU();
53 texture
->BindToUnit(0);
56 m_col
[0] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::R
, color
);
57 m_col
[1] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::G
, color
);
58 m_col
[2] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::B
, color
);
59 m_col
[3] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::A
, color
);
61 bool hasAlpha
= m_texture
.m_textures
[m_currentFrame
]->HasAlpha() || m_col
[3] < 255;
65 if (m_col
[0] == 255 && m_col
[1] == 255 && m_col
[2] == 255 && m_col
[3] == 255 )
67 m_renderSystem
->EnableShader(ShaderMethodGL::SM_MULTI
);
71 m_renderSystem
->EnableShader(ShaderMethodGL::SM_MULTI_BLENDCOLOR
);
74 hasAlpha
|= m_diffuse
.m_textures
[0]->HasAlpha();
76 m_diffuse
.m_textures
[0]->BindToUnit(1);
80 if (m_col
[0] == 255 && m_col
[1] == 255 && m_col
[2] == 255 && m_col
[3] == 255)
82 m_renderSystem
->EnableShader(ShaderMethodGL::SM_TEXTURE_NOBLEND
);
86 m_renderSystem
->EnableShader(ShaderMethodGL::SM_TEXTURE
);
92 glBlendFuncSeparate(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
, GL_ONE_MINUS_DST_ALPHA
, GL_ONE
);
99 m_packedVertices
.clear();
103 void CGUITextureGL::End()
105 if (m_packedVertices
.size())
107 GLint posLoc
= m_renderSystem
->ShaderGetPos();
108 GLint tex0Loc
= m_renderSystem
->ShaderGetCoord0();
109 GLint tex1Loc
= m_renderSystem
->ShaderGetCoord1();
110 GLint uniColLoc
= m_renderSystem
->ShaderGetUniCol();
111 GLint depthLoc
= m_renderSystem
->ShaderGetDepth();
116 glGenBuffers(1, &VertexVBO
);
117 glBindBuffer(GL_ARRAY_BUFFER
, VertexVBO
);
118 glBufferData(GL_ARRAY_BUFFER
, sizeof(PackedVertex
)*m_packedVertices
.size(), &m_packedVertices
[0], GL_STATIC_DRAW
);
120 glUniform1f(depthLoc
, m_depth
);
124 glUniform4f(uniColLoc
,(m_col
[0] / 255.0f
), (m_col
[1] / 255.0f
), (m_col
[2] / 255.0f
), (m_col
[3] / 255.0f
));
127 if (m_diffuse
.size())
129 glVertexAttribPointer(tex1Loc
, 2, GL_FLOAT
, 0, sizeof(PackedVertex
),
130 reinterpret_cast<const GLvoid
*>(offsetof(PackedVertex
, u2
)));
131 glEnableVertexAttribArray(tex1Loc
);
134 glVertexAttribPointer(posLoc
, 3, GL_FLOAT
, 0, sizeof(PackedVertex
),
135 reinterpret_cast<const GLvoid
*>(offsetof(PackedVertex
, x
)));
136 glEnableVertexAttribArray(posLoc
);
137 glVertexAttribPointer(tex0Loc
, 2, GL_FLOAT
, 0, sizeof(PackedVertex
),
138 reinterpret_cast<const GLvoid
*>(offsetof(PackedVertex
, u1
)));
139 glEnableVertexAttribArray(tex0Loc
);
141 glGenBuffers(1, &IndexVBO
);
142 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, IndexVBO
);
143 glBufferData(GL_ELEMENT_ARRAY_BUFFER
, sizeof(ushort
)*m_idx
.size(), m_idx
.data(), GL_STATIC_DRAW
);
145 glDrawElements(GL_TRIANGLES
, m_packedVertices
.size()*6 / 4, GL_UNSIGNED_SHORT
, 0);
147 if (m_diffuse
.size())
148 glDisableVertexAttribArray(tex1Loc
);
150 glDisableVertexAttribArray(posLoc
);
151 glDisableVertexAttribArray(tex0Loc
);
153 glBindBuffer(GL_ARRAY_BUFFER
, 0);
154 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 0);
155 glDeleteBuffers(1, &VertexVBO
);
156 glDeleteBuffers(1, &IndexVBO
);
159 if (m_diffuse
.size())
160 glActiveTexture(GL_TEXTURE0
);
163 m_renderSystem
->DisableShader();
166 void CGUITextureGL::Draw(float *x
, float *y
, float *z
, const CRect
&texture
, const CRect
&diffuse
, int orientation
)
168 PackedVertex vertices
[4];
170 // Setup texture coordinates
172 vertices
[0].u1
= texture
.x1
;
173 vertices
[0].v1
= texture
.y1
;
178 vertices
[1].u1
= texture
.x1
;
179 vertices
[1].v1
= texture
.y2
;
183 vertices
[1].u1
= texture
.x2
;
184 vertices
[1].v1
= texture
.y1
;
188 vertices
[2].u1
= texture
.x2
;
189 vertices
[2].v1
= texture
.y2
;
194 vertices
[3].u1
= texture
.x2
;
195 vertices
[3].v1
= texture
.y1
;
199 vertices
[3].u1
= texture
.x1
;
200 vertices
[3].v1
= texture
.y2
;
203 if (m_diffuse
.size())
206 vertices
[0].u2
= diffuse
.x1
;
207 vertices
[0].v2
= diffuse
.y1
;
210 if (m_info
.orientation
& 4)
212 vertices
[1].u2
= diffuse
.x1
;
213 vertices
[1].v2
= diffuse
.y2
;
217 vertices
[1].u2
= diffuse
.x2
;
218 vertices
[1].v2
= diffuse
.y1
;
222 vertices
[2].u2
= diffuse
.x2
;
223 vertices
[2].v2
= diffuse
.y2
;
226 if (m_info
.orientation
& 4)
228 vertices
[3].u2
= diffuse
.x2
;
229 vertices
[3].v2
= diffuse
.y1
;
233 vertices
[3].u2
= diffuse
.x1
;
234 vertices
[3].v2
= diffuse
.y2
;
238 for (int i
=0; i
<4; i
++)
240 vertices
[i
].x
= x
[i
];
241 vertices
[i
].y
= y
[i
];
242 vertices
[i
].z
= z
[i
];
243 m_packedVertices
.push_back(vertices
[i
]);
246 if ((m_packedVertices
.size() / 4) > (m_idx
.size() / 6))
248 size_t i
= m_packedVertices
.size() - 4;
249 m_idx
.push_back(i
+0);
250 m_idx
.push_back(i
+1);
251 m_idx
.push_back(i
+2);
252 m_idx
.push_back(i
+2);
253 m_idx
.push_back(i
+3);
254 m_idx
.push_back(i
+0);
258 void CGUITextureGL::DrawQuad(const CRect
& rect
,
259 UTILS::COLOR::Color color
,
261 const CRect
* texCoords
,
265 CRenderSystemGL
*renderSystem
= dynamic_cast<CRenderSystemGL
*>(CServiceBroker::GetRenderSystem());
268 texture
->LoadToGPU();
269 texture
->BindToUnit(0);
274 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
285 GLubyte idx
[4] = {0, 1, 3, 2}; //determines order of the vertices
296 renderSystem
->EnableShader(ShaderMethodGL::SM_TEXTURE
);
298 renderSystem
->EnableShader(ShaderMethodGL::SM_DEFAULT
);
300 GLint posLoc
= renderSystem
->ShaderGetPos();
301 GLint tex0Loc
= renderSystem
->ShaderGetCoord0();
302 GLint uniColLoc
= renderSystem
->ShaderGetUniCol();
303 GLint depthLoc
= renderSystem
->ShaderGetDepth();
306 col
[0] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::R
, color
);
307 col
[1] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::G
, color
);
308 col
[2] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::B
, color
);
309 col
[3] = KODI::UTILS::GL::GetChannelFromARGB(KODI::UTILS::GL::ColorChannel::A
, color
);
311 glUniform4f(uniColLoc
, col
[0] / 255.0f
, col
[1] / 255.0f
, col
[2] / 255.0f
, col
[3] / 255.0f
);
312 glUniform1f(depthLoc
, depth
);
315 vertex
[0].x
= rect
.x1
;
316 vertex
[0].y
= rect
.y1
;
320 vertex
[1].x
= rect
.x2
;
321 vertex
[1].y
= rect
.y1
;
325 vertex
[2].x
= rect
.x2
;
326 vertex
[2].y
= rect
.y2
;
330 vertex
[3].x
= rect
.x1
;
331 vertex
[3].y
= rect
.y2
;
336 CRect coords
= texCoords
? *texCoords
: CRect(0.0f
, 0.0f
, 1.0f
, 1.0f
);
337 vertex
[0].u1
= vertex
[3].u1
= coords
.x1
;
338 vertex
[0].v1
= vertex
[1].v1
= coords
.y1
;
339 vertex
[1].u1
= vertex
[2].u1
= coords
.x2
;
340 vertex
[2].v1
= vertex
[3].v1
= coords
.y2
;
343 glGenBuffers(1, &vertexVBO
);
344 glBindBuffer(GL_ARRAY_BUFFER
, vertexVBO
);
345 glBufferData(GL_ARRAY_BUFFER
, sizeof(PackedVertex
)*4, &vertex
[0], GL_STATIC_DRAW
);
347 glVertexAttribPointer(posLoc
, 3, GL_FLOAT
, 0, sizeof(PackedVertex
),
348 reinterpret_cast<const GLvoid
*>(offsetof(PackedVertex
, x
)));
349 glEnableVertexAttribArray(posLoc
);
353 glVertexAttribPointer(tex0Loc
, 2, GL_FLOAT
, 0, sizeof(PackedVertex
),
354 reinterpret_cast<const GLvoid
*>(offsetof(PackedVertex
, u1
)));
355 glEnableVertexAttribArray(tex0Loc
);
358 glGenBuffers(1, &indexVBO
);
359 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, indexVBO
);
360 glBufferData(GL_ELEMENT_ARRAY_BUFFER
, sizeof(GLubyte
)*4, idx
, GL_STATIC_DRAW
);
362 glDrawElements(GL_TRIANGLE_STRIP
, 4, GL_UNSIGNED_BYTE
, 0);
364 glDisableVertexAttribArray(posLoc
);
366 glDisableVertexAttribArray(tex0Loc
);
368 glBindBuffer(GL_ARRAY_BUFFER
, 0);
369 glDeleteBuffers(1, &vertexVBO
);
370 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER
, 0);
371 glDeleteBuffers(1, &indexVBO
);
373 renderSystem
->DisableShader();