[guilib] fix labelcontrols with auto width always being marked as dirty if they speci...
[vuplus_xbmc] / xbmc / guilib / GUITextureGLES.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20
21 #include "system.h"
22 #if defined(HAS_GLES)
23 #include "GUITextureGLES.h"
24 #endif
25 #include "Texture.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"
31
32 #if defined(HAS_GLES)
33
34
35 CGUITextureGLES::CGUITextureGLES(float posX, float posY, float width, float height, const CTextureInfo &texture)
36 : CGUITextureBase(posX, posY, width, height, texture)
37 {
38 }
39
40 void CGUITextureGLES::Begin(color_t color)
41 {
42   CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
43   texture->LoadToGPU();
44   if (m_diffuse.size())
45     m_diffuse.m_textures[0]->LoadToGPU();
46
47   texture->BindToUnit(0);
48
49   // Setup Colors
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);
54
55   bool hasAlpha = m_texture.m_textures[m_currentFrame]->HasAlpha() || m_col[3] < 255;
56
57   if (m_diffuse.size())
58   {
59     if (m_col[0] == 255 && m_col[1] == 255 && m_col[2] == 255 && m_col[3] == 255 )
60     {
61       g_Windowing.EnableGUIShader(SM_MULTI);
62     }
63     else
64     {
65       g_Windowing.EnableGUIShader(SM_MULTI_BLENDCOLOR);
66     }
67
68     hasAlpha |= m_diffuse.m_textures[0]->HasAlpha();
69
70     m_diffuse.m_textures[0]->BindToUnit(1);
71
72   }
73   else
74   {
75     if (m_col[0] == 255 && m_col[1] == 255 && m_col[2] == 255 && m_col[3] == 255)
76     {
77       g_Windowing.EnableGUIShader(SM_TEXTURE_NOBLEND);
78     }
79     else
80     {
81       g_Windowing.EnableGUIShader(SM_TEXTURE);
82     }
83   }
84
85   if ( hasAlpha )
86   {
87     glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE);
88     glEnable( GL_BLEND );
89   }
90   else
91   {
92     glDisable(GL_BLEND);
93   }
94   m_packedVertices.clear();
95 }
96
97 void CGUITextureGLES::End()
98 {
99   GLint posLoc  = g_Windowing.GUIShaderGetPos();
100   GLint tex0Loc = g_Windowing.GUIShaderGetCoord0();
101   GLint tex1Loc = g_Windowing.GUIShaderGetCoord1();
102   GLint uniColLoc = g_Windowing.GUIShaderGetUniCol();
103
104   if(uniColLoc >= 0)
105   {
106     glUniform4f(uniColLoc,(m_col[0] / 255.0f), (m_col[1] / 255.0f), (m_col[2] / 255.0f), (m_col[3] / 255.0f));
107   }
108
109   if(m_diffuse.size())
110   {
111     glVertexAttribPointer(tex1Loc, 2, GL_FLOAT, 0, sizeof(PackedVertex), (char*)&m_packedVertices[0] + offsetof(PackedVertex, u2));
112     glEnableVertexAttribArray(tex1Loc);
113   }
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);
118
119   glDrawElements(GL_TRIANGLES, m_packedVertices.size()*6 / 4, GL_UNSIGNED_SHORT, m_idx.data());
120
121   if (m_diffuse.size())
122   {
123     glDisableVertexAttribArray(tex1Loc);
124     glActiveTexture(GL_TEXTURE0);
125   }
126
127   glDisableVertexAttribArray(posLoc);
128   glDisableVertexAttribArray(tex0Loc);
129
130   glEnable(GL_BLEND);
131   g_Windowing.DisableGUIShader();
132 }
133
134 void CGUITextureGLES::Draw(float *x, float *y, float *z, const CRect &texture, const CRect &diffuse, int orientation)
135 {
136   PackedVertex vertices[4];
137
138   // Setup texture coordinates
139   //TopLeft
140   vertices[0].u1 = texture.x1;
141   vertices[0].v1 = texture.y1;
142   //TopRight
143   if (orientation & 4)
144   {
145     vertices[1].u1 = texture.x1;
146     vertices[1].v1 = texture.y2;
147   }
148   else
149   {
150     vertices[1].u1 = texture.x2;
151     vertices[1].v1 = texture.y1;
152   }
153   //BottomRight
154   vertices[2].u1 = texture.x2;
155   vertices[2].v1 = texture.y2;
156   //BottomLeft
157   if (orientation & 4)
158   {
159     vertices[3].u1 = texture.x2;
160     vertices[3].v1 = texture.y1;
161   }
162   else
163   {
164     vertices[3].u1 = texture.x1;
165     vertices[3].v1 = texture.y2;
166   }
167
168   if (m_diffuse.size())
169   {
170     //TopLeft
171     vertices[0].u2 = diffuse.x1;
172     vertices[0].v2 = diffuse.y1;
173     //TopRight
174     if (m_info.orientation & 4)
175     {
176       vertices[1].u2 = diffuse.x1;
177       vertices[1].v2 = diffuse.y2;
178     }
179     else
180     {
181       vertices[1].u2 = diffuse.x2;
182       vertices[1].v2 = diffuse.y1;
183     }
184     //BottomRight
185     vertices[2].u2 = diffuse.x2;
186     vertices[2].v2 = diffuse.y2;
187     //BottomLeft
188     if (m_info.orientation & 4)
189     {
190       vertices[3].u2 = diffuse.x2;
191       vertices[3].v2 = diffuse.y1;
192     }
193     else
194     {
195       vertices[3].u2 = diffuse.x1;
196       vertices[3].v2 = diffuse.y2;
197     }
198   }
199
200   for (int i=0; i<4; i++)
201   {
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]);
206   }
207
208   if ((m_packedVertices.size() / 4) > (m_idx.size() / 6))
209   {
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);
217   }
218 }
219
220 void CGUITextureGLES::DrawQuad(const CRect &rect, color_t color, CBaseTexture *texture, const CRect *texCoords)
221 {
222   if (texture)
223   {
224     texture->LoadToGPU();
225     texture->BindToUnit(0);
226   }
227
228   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
229   glEnable(GL_BLEND);          // Turn Blending On
230
231   VerifyGLState();
232
233   GLubyte col[4];
234   GLfloat ver[4][3];
235   GLfloat tex[4][2];
236   GLubyte idx[4] = {0, 1, 3, 2};        //determines order of triangle strip
237
238   if (texture)
239     g_Windowing.EnableGUIShader(SM_TEXTURE);
240   else
241     g_Windowing.EnableGUIShader(SM_DEFAULT);
242
243   GLint posLoc   = g_Windowing.GUIShaderGetPos();
244   GLint tex0Loc  = g_Windowing.GUIShaderGetCoord0();
245   GLint uniColLoc= g_Windowing.GUIShaderGetUniCol();
246
247   glVertexAttribPointer(posLoc,  3, GL_FLOAT, 0, 0, ver);
248   if (texture)
249     glVertexAttribPointer(tex0Loc, 2, GL_FLOAT, 0, 0, tex);
250
251   glEnableVertexAttribArray(posLoc);
252   if (texture)
253     glEnableVertexAttribArray(tex0Loc);
254
255   // Setup Colors
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);
260
261   glUniform4f(uniColLoc, col[0] / 255.0f, col[1] / 255.0f, col[2] / 255.0f, col[3] / 255.0f);
262
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;
268
269   if (texture)
270   {
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;
277   }
278   glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, idx);
279
280   glDisableVertexAttribArray(posLoc);
281   if (texture)
282     glDisableVertexAttribArray(tex0Loc);
283
284   g_Windowing.DisableGUIShader();
285 }
286
287 #endif