[release] version bump to 13.0 beta1
[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   if (m_diffuse.size())
122     glDisable(GL_TEXTURE_2D);
123   glActiveTexture(GL_TEXTURE0_ARB);
124   glDisable(GL_TEXTURE_2D);
125 }
126
127 void CGUITextureGL::Draw(float *x, float *y, float *z, const CRect &texture, const CRect &diffuse, int orientation)
128 {
129   // Top-left vertex (corner)
130   glColor4ub(m_col[0], m_col[1], m_col[2], m_col[3]);
131   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x1, texture.y1);
132   if (m_diffuse.size())
133     glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x1, diffuse.y1);
134   glVertex3f(x[0], y[0], z[0]);
135
136   // Top-right vertex (corner)
137   glColor4ub(m_col[0], m_col[1], m_col[2], m_col[3]);
138   if (orientation & 4)
139     glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x1, texture.y2);
140   else
141     glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x2, texture.y1);
142   if (m_diffuse.size())
143   {
144     if (m_info.orientation & 4)
145       glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x1, diffuse.y2);
146     else
147       glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x2, diffuse.y1);
148   }
149   glVertex3f(x[1], y[1], z[1]);
150
151   // Bottom-right vertex (corner)
152   glColor4ub(m_col[0], m_col[1], m_col[2], m_col[3]);
153   glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x2, texture.y2);
154   if (m_diffuse.size())
155     glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x2, diffuse.y2);
156   glVertex3f(x[2], y[2], z[2]);
157
158   // Bottom-left vertex (corner)
159   glColor4ub(m_col[0], m_col[1], m_col[2], m_col[3]);
160   if (orientation & 4)
161     glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x2, texture.y1);
162   else
163     glMultiTexCoord2fARB(GL_TEXTURE0_ARB, texture.x1, texture.y2);
164   if (m_diffuse.size())
165   {
166     if (m_info.orientation & 4)
167       glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x2, diffuse.y1);
168     else
169       glMultiTexCoord2fARB(GL_TEXTURE1_ARB, diffuse.x1, diffuse.y2);
170   }
171   glVertex3f(x[3], y[3], z[3]);
172 }
173
174 void CGUITextureGL::DrawQuad(const CRect &rect, color_t color, CBaseTexture *texture, const CRect *texCoords)
175 {
176   if (texture)
177   {
178     texture->LoadToGPU();
179     texture->BindToUnit(0);
180     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
181     glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
182     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1);
183     glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
184     glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
185     glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
186   }
187   else
188   glDisable(GL_TEXTURE_2D);
189
190   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
191   glEnable(GL_BLEND);          // Turn Blending On
192   glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
193
194   // diffuse coloring
195   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
196   glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
197   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
198   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
199   glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
200   glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
201   VerifyGLState();
202
203   glBegin(GL_QUADS);
204
205   glColor4ub((GLubyte)GET_R(color), (GLubyte)GET_G(color), (GLubyte)GET_B(color), (GLubyte)GET_A(color));
206
207   CRect coords = texCoords ? *texCoords : CRect(0.0f, 0.0f, 1.0f, 1.0f);
208   glTexCoord2f(coords.x1, coords.y1);
209   glVertex3f(rect.x1, rect.y1, 0);
210   glTexCoord2f(coords.x2, coords.y1);
211   glVertex3f(rect.x2, rect.y1, 0);
212   glTexCoord2f(coords.x2, coords.y2);
213   glVertex3f(rect.x2, rect.y2, 0);
214   glTexCoord2f(coords.x1, coords.y2);
215   glVertex3f(rect.x1, rect.y2, 0);
216
217   glEnd();
218   if (texture)
219     glDisable(GL_TEXTURE_2D);
220 }
221
222 #endif