Merge pull request #4687 from ruuk/textboxgettext
[vuplus_xbmc] / xbmc / guilib / GUITextureGL.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_GL)
23 #include "GUITextureGL.h"
24 #endif
25 #include "Texture.h"
26 #include "utils/log.h"
27 #include "utils/GLUtils.h"
28 #include "guilib/Geometry.h"
29 #include "windowing/WindowingFactory.h"
30
31 #if defined(HAS_GL)
32
33 CGUITextureGL::CGUITextureGL(float posX, float posY, float width, float height, const CTextureInfo &texture)
34 : CGUITextureBase(posX, posY, width, height, texture)
35 {
36   memset(m_col, 0, sizeof(m_col));
37 }
38
39 void CGUITextureGL::Begin(color_t color)
40 {
41   int range, unit = 0;
42   if(g_Windowing.UseLimitedColor())
43     range = 235 - 16;
44   else
45     range = 255 -  0;
46
47   m_col[0] = GET_R(color) * range / 255;
48   m_col[1] = GET_G(color) * range / 255;
49   m_col[2] = GET_B(color) * range / 255;
50   m_col[3] = GET_A(color);
51
52   CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
53   texture->LoadToGPU();
54   if (m_diffuse.size())
55     m_diffuse.m_textures[0]->LoadToGPU();
56
57   texture->BindToUnit(unit++);
58
59   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
60   glEnable(GL_BLEND);          // Turn Blending On
61   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
62
63   // diffuse coloring
64   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
65   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
66   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
67   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
68   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
69   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
70
71   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
72   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
73   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PRIMARY_COLOR);
74   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
75   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
76   VerifyGLState();
77
78   if (m_diffuse.size())
79   {
80     m_diffuse.m_textures[0]->BindToUnit(unit++);
81     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
82     glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
83     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
84     glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
85     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
86     glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
87
88     glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
89     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
90     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
91     glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
92     glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
93     VerifyGLState();
94   }
95
96   if(g_Windowing.UseLimitedColor())
97   {
98     texture->BindToUnit(unit++); // dummy bind
99     const GLfloat rgba[4] = {16.0f / 255.0f, 16.0f / 255.0f, 16.0f / 255.0f, 0.0f};
100     glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE , GL_COMBINE);
101     glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, rgba);
102     glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_RGB      , GL_ADD);
103     glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_RGB      , GL_PREVIOUS);
104     glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE1_RGB      , GL_CONSTANT);
105     glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB     , GL_SRC_COLOR);
106     glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB     , GL_SRC_COLOR);
107
108     glTexEnvi (GL_TEXTURE_ENV, GL_COMBINE_ALPHA    , GL_REPLACE);
109     glTexEnvi (GL_TEXTURE_ENV, GL_SOURCE0_ALPHA    , GL_PREVIOUS);
110     VerifyGLState();
111   }
112
113   //glDisable(GL_TEXTURE_2D); // uncomment these 2 lines to switch to wireframe rendering
114   //glBegin(GL_LINE_LOOP);
115   glBegin(GL_QUADS);
116 }
117
118 void CGUITextureGL::End()
119 {
120   glEnd();
121   glActiveTexture(GL_TEXTURE2_ARB);
122   glBindTexture(GL_TEXTURE_2D, 0);
123   glDisable(GL_TEXTURE_2D);
124   glActiveTexture(GL_TEXTURE1_ARB);
125   glBindTexture(GL_TEXTURE_2D, 0);
126   glDisable(GL_TEXTURE_2D);
127   glActiveTexture(GL_TEXTURE0_ARB);
128   glBindTexture(GL_TEXTURE_2D, 0);
129   glDisable(GL_TEXTURE_2D);
130 }
131
132 void CGUITextureGL::Draw(float *x, float *y, float *z, const CRect &texture, const CRect &diffuse, int orientation)
133 {
134   // Top-left vertex (corner)
135   glColor4ub(m_col[0], m_col[1], m_col[2], m_col[3]);
136   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x1, texture.y1);
137   if (m_diffuse.size())
138     glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x1, diffuse.y1);
139   glVertex3f(x[0], y[0], z[0]);
140
141   // Top-right vertex (corner)
142   glColor4ub(m_col[0], m_col[1], m_col[2], m_col[3]);
143   if (orientation & 4)
144     glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x1, texture.y2);
145   else
146     glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x2, texture.y1);
147   if (m_diffuse.size())
148   {
149     if (m_info.orientation & 4)
150       glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x1, diffuse.y2);
151     else
152       glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x2, diffuse.y1);
153   }
154   glVertex3f(x[1], y[1], z[1]);
155
156   // Bottom-right vertex (corner)
157   glColor4ub(m_col[0], m_col[1], m_col[2], m_col[3]);
158   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x2, texture.y2);
159   if (m_diffuse.size())
160     glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x2, diffuse.y2);
161   glVertex3f(x[2], y[2], z[2]);
162
163   // Bottom-left vertex (corner)
164   glColor4ub(m_col[0], m_col[1], m_col[2], m_col[3]);
165   if (orientation & 4)
166     glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x2, texture.y1);
167   else
168     glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x1, texture.y2);
169   if (m_diffuse.size())
170   {
171     if (m_info.orientation & 4)
172       glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x2, diffuse.y1);
173     else
174       glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x1, diffuse.y2);
175   }
176   glVertex3f(x[3], y[3], z[3]);
177 }
178
179 void CGUITextureGL::DrawQuad(const CRect &rect, color_t color, CBaseTexture *texture, const CRect *texCoords)
180 {
181   if (texture)
182   {
183     texture->LoadToGPU();
184     texture->BindToUnit(0);
185     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
186     glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
187     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1);
188     glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
189     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
190     glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
191   }
192   else
193   glDisable(GL_TEXTURE_2D);
194
195   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
196   glEnable(GL_BLEND);          // Turn Blending On
197   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
198
199   // diffuse coloring
200   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
201   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
202   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
203   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
204   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
205   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
206   VerifyGLState();
207
208   glBegin(GL_QUADS);
209
210   glColor4ub((GLubyte)GET_R(color), (GLubyte)GET_G(color), (GLubyte)GET_B(color), (GLubyte)GET_A(color));
211
212   CRect coords = texCoords ? *texCoords : CRect(0.0f, 0.0f, 1.0f, 1.0f);
213   glTexCoord2f(coords.x1, coords.y1);
214   glVertex3f(rect.x1, rect.y1, 0);
215   glTexCoord2f(coords.x2, coords.y1);
216   glVertex3f(rect.x2, rect.y1, 0);
217   glTexCoord2f(coords.x2, coords.y2);
218   glVertex3f(rect.x2, rect.y2, 0);
219   glTexCoord2f(coords.x1, coords.y2);
220   glVertex3f(rect.x1, rect.y2, 0);
221
222   glEnd();
223   if (texture)
224     glDisable(GL_TEXTURE_2D);
225 }
226
227 #endif