2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
23 #include "GUITextureGLES.h"
26 #include "utils/log.h"
27 #include "utils/GLUtils.h"
28 #include "utils/MathUtils.h"
29 #include "windowing/WindowingFactory.h"
30 #include "guilib/GraphicContext.h"
35 CGUITextureGLES::CGUITextureGLES(float posX, float posY, float width, float height, const CTextureInfo &texture)
36 : CGUITextureBase(posX, posY, width, height, texture)
40 void CGUITextureGLES::Begin(color_t color)
42 CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
45 m_diffuse.m_textures[0]->LoadToGPU();
47 texture->BindToUnit(0);
50 m_col[0] = (GLubyte)GET_R(color);
51 m_col[1] = (GLubyte)GET_G(color);
52 m_col[2] = (GLubyte)GET_B(color);
53 m_col[3] = (GLubyte)GET_A(color);
55 bool hasAlpha = m_texture.m_textures[m_currentFrame]->HasAlpha() || m_col[3] < 255;
59 if (m_col[0] == 255 && m_col[1] == 255 && m_col[2] == 255 && m_col[3] == 255 )
61 g_Windowing.EnableGUIShader(SM_MULTI);
65 g_Windowing.EnableGUIShader(SM_MULTI_BLENDCOLOR);
68 hasAlpha |= m_diffuse.m_textures[0]->HasAlpha();
70 m_diffuse.m_textures[0]->BindToUnit(1);
75 if (m_col[0] == 255 && m_col[1] == 255 && m_col[2] == 255 && m_col[3] == 255)
77 g_Windowing.EnableGUIShader(SM_TEXTURE_NOBLEND);
81 g_Windowing.EnableGUIShader(SM_TEXTURE);
87 glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
94 m_packedVertices.clear();
97 void CGUITextureGLES::End()
99 GLint posLoc = g_Windowing.GUIShaderGetPos();
100 GLint tex0Loc = g_Windowing.GUIShaderGetCoord0();
101 GLint tex1Loc = g_Windowing.GUIShaderGetCoord1();
102 GLint uniColLoc = g_Windowing.GUIShaderGetUniCol();
106 glUniform4f(uniColLoc,(m_col[0] / 255.0f), (m_col[1] / 255.0f), (m_col[2] / 255.0f), (m_col[3] / 255.0f));
111 glVertexAttribPointer(tex1Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), (char*)&m_packedVertices[0] + offsetof(PackedVertex, u2));
112 glEnableVertexAttribArray(tex1Loc);
114 glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, sizeof(PackedVertex), (char*)&m_packedVertices[0] + offsetof(PackedVertex, x));
115 glEnableVertexAttribArray(posLoc);
116 glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), (char*)&m_packedVertices[0] + offsetof(PackedVertex, u1));
117 glEnableVertexAttribArray(tex0Loc);
119 glDrawElements(GL_TRIANGLES, m_packedVertices.size()*6 / 4, GL_UNSIGNED_SHORT, m_idx.data());
121 if (m_diffuse.size())
123 glDisableVertexAttribArray(tex1Loc);
124 glActiveTexture(GL_TEXTURE0);
127 glDisableVertexAttribArray(posLoc);
128 glDisableVertexAttribArray(tex0Loc);
131 g_Windowing.DisableGUIShader();
134 void CGUITextureGLES::Draw(float *x, float *y, float *z, const CRect &texture, const CRect &diffuse, int orientation)
136 PackedVertex vertices[4];
138 // Setup texture coordinates
140 vertices[0].u1 = texture.x1;
141 vertices[0].v1 = texture.y1;
145 vertices[1].u1 = texture.x1;
146 vertices[1].v1 = texture.y2;
150 vertices[1].u1 = texture.x2;
151 vertices[1].v1 = texture.y1;
154 vertices[2].u1 = texture.x2;
155 vertices[2].v1 = texture.y2;
159 vertices[3].u1 = texture.x2;
160 vertices[3].v1 = texture.y1;
164 vertices[3].u1 = texture.x1;
165 vertices[3].v1 = texture.y2;
168 if (m_diffuse.size())
171 vertices[0].u2 = diffuse.x1;
172 vertices[0].v2 = diffuse.y1;
174 if (m_info.orientation & 4)
176 vertices[1].u2 = diffuse.x1;
177 vertices[1].v2 = diffuse.y2;
181 vertices[1].u2 = diffuse.x2;
182 vertices[1].v2 = diffuse.y1;
185 vertices[2].u2 = diffuse.x2;
186 vertices[2].v2 = diffuse.y2;
188 if (m_info.orientation & 4)
190 vertices[3].u2 = diffuse.x2;
191 vertices[3].v2 = diffuse.y1;
195 vertices[3].u2 = diffuse.x1;
196 vertices[3].v2 = diffuse.y2;
200 for (int i=0; i<4; i++)
202 vertices[i].x = x[i];
203 vertices[i].y = y[i];
204 vertices[i].z = z[i];
205 m_packedVertices.push_back(vertices[i]);
208 if ((m_packedVertices.size() / 4) > (m_idx.size() / 6))
210 size_t i = m_packedVertices.size() - 4;
211 m_idx.push_back(i+0);
212 m_idx.push_back(i+1);
213 m_idx.push_back(i+2);
214 m_idx.push_back(i+2);
215 m_idx.push_back(i+3);
216 m_idx.push_back(i+0);
220 void CGUITextureGLES::DrawQuad(const CRect &rect, color_t color, CBaseTexture *texture, const CRect *texCoords)
224 texture->LoadToGPU();
225 texture->BindToUnit(0);
228 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
229 glEnable(GL_BLEND); // Turn Blending On
236 GLubyte idx[4] = {0, 1, 3, 2}; //determines order of triangle strip
239 g_Windowing.EnableGUIShader(SM_TEXTURE);
241 g_Windowing.EnableGUIShader(SM_DEFAULT);
243 GLint posLoc = g_Windowing.GUIShaderGetPos();
244 GLint tex0Loc = g_Windowing.GUIShaderGetCoord0();
245 GLint uniColLoc= g_Windowing.GUIShaderGetUniCol();
247 glVertexAttribPointer(posLoc, 3, GL_FLOAT, 0, 0, ver);
249 glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, 0, tex);
251 glEnableVertexAttribArray(posLoc);
253 glEnableVertexAttribArray(tex0Loc);
256 col[0] = (GLubyte)GET_R(color);
257 col[1] = (GLubyte)GET_G(color);
258 col[2] = (GLubyte)GET_B(color);
259 col[3] = (GLubyte)GET_A(color);
261 glUniform4f(uniColLoc, col[0] / 255.0f, col[1] / 255.0f, col[2] / 255.0f, col[3] / 255.0f);
263 ver[0][0] = ver[3][0] = rect.x1;
264 ver[0][1] = ver[1][1] = rect.y1;
265 ver[1][0] = ver[2][0] = rect.x2;
266 ver[2][1] = ver[3][1] = rect.y2;
267 ver[0][2] = ver[1][2] = ver[2][2] = ver[3][2]= 0;
271 // Setup texture coordinates
272 CRect coords = texCoords ? *texCoords : CRect(0.0f, 0.0f, 1.0f, 1.0f);
273 tex[0][0] = tex[3][0] = coords.x1;
274 tex[0][1] = tex[1][1] = coords.y1;
275 tex[1][0] = tex[2][0] = coords.x2;
276 tex[2][1] = tex[3][1] = coords.y2;
278 glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
280 glDisableVertexAttribArray(posLoc);
282 glDisableVertexAttribArray(tex0Loc);
284 g_Windowing.DisableGUIShader();