Fix keymap.
[vuplus_xbmc] / xbmc / guilib / GUITextureD3D.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 "Texture.h"
22 #include "GUITextureD3D.h"
23 #include "windowing/WindowingFactory.h"
24
25 #ifdef HAS_DX
26
27 CGUITextureD3D::CGUITextureD3D(float posX, float posY, float width, float height, const CTextureInfo &texture)
28 : CGUITextureBase(posX, posY, width, height, texture)
29 {
30 }
31
32 void CGUITextureD3D::Begin(color_t color)
33 {
34   int unit = 0;
35   CBaseTexture* texture = m_texture.m_textures[m_currentFrame];
36   LPDIRECT3DDEVICE9 p3DDevice = g_Windowing.Get3DDevice();
37
38   texture->LoadToGPU();
39   if (m_diffuse.size())
40     m_diffuse.m_textures[0]->LoadToGPU();
41   // Set state to render the image
42   texture->BindToUnit(unit);
43   p3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP  , D3DTOP_MODULATE );
44   p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_TEXTURE   );
45   p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG2, D3DTA_DIFFUSE   );
46   p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP  , D3DTOP_MODULATE );
47   p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG1, D3DTA_TEXTURE   );
48   p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE   );
49   unit++;
50
51   if (m_diffuse.size())
52   {
53     m_diffuse.m_textures[0]->BindToUnit(1);
54     p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_TEXTURE   );
55     p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG2, D3DTA_CURRENT   );
56     p3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP  , D3DTOP_MODULATE );
57     p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG1, D3DTA_TEXTURE   );
58     p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAARG2, D3DTA_CURRENT   );
59     p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP  , D3DTOP_MODULATE );
60     unit++;
61   }
62
63   if(g_Windowing.UseLimitedColor())
64   {
65     m_col = D3DCOLOR_RGBA(GET_R(color) * (235 - 16) / 255
66                         , GET_G(color) * (235 - 16) / 255
67                         , GET_B(color) * (235 - 16) / 255
68                         , GET_A(color));
69     p3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP  , D3DTOP_ADD );
70     p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG1, D3DTA_CURRENT) ;
71     p3DDevice->SetRenderState( D3DRS_TEXTUREFACTOR, D3DCOLOR_RGBA(16,16,16, 0) );
72     p3DDevice->SetTextureStageState( unit, D3DTSS_COLORARG2, D3DTA_TFACTOR );
73     unit++;
74   }
75   else
76     m_col = color;
77
78   p3DDevice->SetTextureStageState( unit, D3DTSS_COLOROP, D3DTOP_DISABLE);
79   p3DDevice->SetTextureStageState( unit, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
80
81   p3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
82   p3DDevice->SetRenderState( D3DRS_ALPHAREF, 0 );
83   p3DDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
84   p3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
85   p3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
86   p3DDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
87   p3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
88   p3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
89   p3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
90   p3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
91   p3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
92   p3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE);
93
94   p3DDevice->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 );
95 }
96
97 void CGUITextureD3D::End()
98 {
99   // unset the texture and palette or the texture caching crashes because the runtime still has a reference
100   g_Windowing.Get3DDevice()->SetTexture( 0, NULL );
101   if (m_diffuse.size())
102     g_Windowing.Get3DDevice()->SetTexture( 1, NULL );
103 }
104
105 void CGUITextureD3D::Draw(float *x, float *y, float *z, const CRect &texture, const CRect &diffuse, int orientation)
106 {
107   struct CUSTOMVERTEX {
108       FLOAT x, y, z;
109       DWORD color;
110       FLOAT tu, tv;   // Texture coordinates
111       FLOAT tu2, tv2;
112   };
113
114   // D3D aligns to half pixel boundaries
115   for (int i = 0; i < 4; i++)
116   {
117     x[i] -= 0.5f;
118     y[i] -= 0.5f;
119   };
120
121   CUSTOMVERTEX verts[4];
122   verts[0].x = x[0]; verts[0].y = y[0]; verts[0].z = z[0];
123   verts[0].tu = texture.x1;   verts[0].tv = texture.y1;
124   verts[0].tu2 = diffuse.x1;  verts[0].tv2 = diffuse.y1;
125   verts[0].color = m_col;
126
127   verts[1].x = x[1]; verts[1].y = y[1]; verts[1].z = z[1];
128   if (orientation & 4)
129   {
130     verts[1].tu = texture.x1;
131     verts[1].tv = texture.y2;
132   }
133   else
134   {
135     verts[1].tu = texture.x2;
136     verts[1].tv = texture.y1;
137   }
138   if (m_info.orientation & 4)
139   {
140     verts[1].tu2 = diffuse.x1;
141     verts[1].tv2 = diffuse.y2;
142   }
143   else
144   {
145     verts[1].tu2 = diffuse.x2;
146     verts[1].tv2 = diffuse.y1;
147   }
148   verts[1].color = m_col;
149
150   verts[2].x = x[2]; verts[2].y = y[2]; verts[2].z = z[2];
151   verts[2].tu = texture.x2;   verts[2].tv = texture.y2;
152   verts[2].tu2 = diffuse.x2;  verts[2].tv2 = diffuse.y2;
153   verts[2].color = m_col;
154
155   verts[3].x = x[3]; verts[3].y = y[3]; verts[3].z = z[3];
156   if (orientation & 4)
157   {
158     verts[3].tu = texture.x2;
159     verts[3].tv = texture.y1;
160   }
161   else
162   {
163     verts[3].tu = texture.x1;
164     verts[3].tv = texture.y2;
165   }
166   if (m_info.orientation & 4)
167   {
168     verts[3].tu2 = diffuse.x2;
169     verts[3].tv2 = diffuse.y1;
170   }
171   else
172   {
173     verts[3].tu2 = diffuse.x1;
174     verts[3].tv2 = diffuse.y2;
175   }
176   verts[3].color = m_col;
177
178   g_Windowing.Get3DDevice()->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(CUSTOMVERTEX));
179 }
180
181 void CGUITextureD3D::DrawQuad(const CRect &rect, color_t color, CBaseTexture *texture, const CRect *texCoords)
182 {
183   struct CUSTOMVERTEX {
184       FLOAT x, y, z;
185       DWORD color;
186       FLOAT tu, tv;   // Texture coordinates
187       FLOAT tu2, tv2;
188   };
189
190   LPDIRECT3DDEVICE9 p3DDevice = g_Windowing.Get3DDevice();
191
192   if (texture)
193   {
194     texture->LoadToGPU();
195     texture->BindToUnit(0);
196     // Set state to render the image
197     p3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
198     p3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
199     p3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
200     p3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
201     p3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
202     p3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
203     p3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
204     p3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
205   }
206   else
207     p3DDevice->SetTexture( 0, NULL );
208
209   p3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
210   p3DDevice->SetRenderState( D3DRS_ALPHAREF, 0 );
211   p3DDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
212   p3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
213   p3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
214   p3DDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
215   p3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
216   p3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
217   p3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
218   p3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
219   p3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
220   p3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE);
221
222   p3DDevice->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX2 );
223
224   CRect coords = texCoords ? *texCoords : CRect(0.0f, 0.0f, 1.0f, 1.0f);
225   CUSTOMVERTEX verts[4] = {
226     { rect.x1 - 0.5f, rect.y1 - 0.5f, 0, color, coords.x1, coords.y1, 0, 0 },
227     { rect.x2 - 0.5f, rect.y1 - 0.5f, 0, color, coords.x2, coords.y1, 0, 0 },
228     { rect.x2 - 0.5f, rect.y2 - 0.5f, 0, color, coords.x2, coords.y2, 0, 0 },
229     { rect.x1 - 0.5f, rect.y2 - 0.5f, 0, color, coords.x1, coords.y2, 0, 0 },
230   };
231   p3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, verts, sizeof(CUSTOMVERTEX));
232
233   if (texture)
234     p3DDevice->SetTexture( 0, NULL );
235 }
236
237 #endif