Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / OGLCombinerTNT2.cpp
1 /*
2 Copyright (C) 2003 Rice1964
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 */
18
19 #include "OGLExtensions.h"
20
21 #include "OGLCombinerTNT2.h"
22 #include "OGLRender.h"
23 #include "OGLGraphicsContext.h"
24 #include "OGLTexture.h"
25
26 //========================================================================
27 COGLColorCombinerTNT2::COGLColorCombinerTNT2(CRender *pRender)
28 :COGLColorCombiner4(pRender)
29 {
30     m_bTNT2Supported=false;
31     delete m_pDecodedMux;
32     m_pDecodedMux = new COGLDecodedMux;
33     m_ppDecodedMux = &m_pDecodedMux;
34 }
35
36
37 bool COGLColorCombinerTNT2::Initialize(void)
38 {
39     m_bTNT2Supported = false;
40
41     if( COGLColorCombiner4::Initialize() )
42     {
43         m_bSupportMultiTexture = true;
44         COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
45         if( pcontext->IsExtensionSupported("GL_NV_texture_env_combine4") )
46         {
47             m_bTNT2Supported = true;
48         }
49         else
50         {
51             DebugMessage(M64MSG_ERROR, "Your video card does not support OpenGL TNT2 extension combiner, you can only use the OpenGL Ext combiner functions");
52         }
53         return true;
54     }
55     return false;
56 }
57
58 //========================================================================
59
60 void COGLColorCombinerTNT2::InitCombinerCycle12(void)
61 {
62     if( !m_bOGLExtCombinerSupported )   { COGLColorCombiner4::InitCombinerCycle12(); return;}
63
64 #ifdef DEBUGGER
65     if( debuggerDropCombiners )
66     {
67         m_vCompiledTNTSettings.clear();
68         m_dwLastMux0 = m_dwLastMux1 = 0;
69         debuggerDropCombiners = false;
70     }
71 #endif
72
73     m_pOGLRender->EnableMultiTexture();
74
75     bool combinerIsChanged = false;
76
77     if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 )
78     {
79         combinerIsChanged = true;
80         m_lastIndex = CNvTNTCombiner::FindCompiledMux();
81         if( m_lastIndex < 0 )       // Can not found
82         {
83             m_lastIndex = CNvTNTCombiner::ParseDecodedMux();
84         }
85         m_dwLastMux0 = m_pDecodedMux->m_dwMux0;
86         m_dwLastMux1 = m_pDecodedMux->m_dwMux1;
87     }
88
89     m_pOGLRender->SetAllTexelRepeatFlag();
90
91     if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded )
92     {
93         gRDP.texturesAreReloaded = false;
94
95         if( m_bCycleChanged || combinerIsChanged )
96         {
97             GenerateCombinerSettingConstants(m_lastIndex);
98             GenerateCombinerSetting(m_lastIndex);
99         }
100         else if( gRDP.colorsAreReloaded )
101         {
102             GenerateCombinerSettingConstants(m_lastIndex);
103         }
104
105         gRDP.colorsAreReloaded = false;
106     }
107 }
108
109 const char* COGLColorCombinerTNT2::GetOpStr(GLenum op)
110 {
111     switch( op )
112     {
113     case GL_ADD:
114         return "MOD";
115     default:
116         return "ADD_SIGNED";
117     }
118 }
119
120
121 #ifdef DEBUGGER
122 void COGLColorCombinerTNT2::DisplaySimpleMuxString(void)
123 {
124     COGLColorCombiner::DisplaySimpleMuxString();
125     CNvTNTCombiner::DisplaySimpleMuxString();
126 }
127 #endif
128
129 //========================================================================
130
131 GLint COGLColorCombinerTNT2::RGBArgsMap[] =
132 {
133     GL_ZERO,                        //MUX_0
134     GL_ZERO,                        //MUX_1
135     GL_PREVIOUS_EXT,                //MUX_COMBINED,
136     GL_TEXTURE0_ARB,                //MUX_TEXEL0,
137     GL_TEXTURE1_ARB,                //MUX_TEXEL1,
138     GL_CONSTANT_EXT,                //MUX_PRIM,
139     GL_PRIMARY_COLOR_EXT,           //MUX_SHADE,
140     GL_CONSTANT_EXT,                //MUX_ENV,
141     GL_PREVIOUS_EXT,                //MUX_COMBALPHA,
142     GL_TEXTURE0_ARB,                //MUX_T0_ALPHA,
143     GL_TEXTURE1_ARB,                //MUX_T1_ALPHA,
144     GL_CONSTANT_EXT,                //MUX_PRIM_ALPHA,
145     GL_PRIMARY_COLOR_EXT,           //MUX_SHADE_ALPHA,
146     GL_CONSTANT_EXT,                //MUX_ENV_ALPHA,
147     GL_CONSTANT_EXT,                //MUX_LODFRAC,
148     GL_CONSTANT_EXT,                //MUX_PRIMLODFRAC,
149     GL_ZERO,                        //MUX_K5
150     GL_ZERO                     //MUX_UNK
151 };
152
153
154 //========================================================================
155
156 GLint COGLColorCombinerTNT2::MapRGBArgs(uint8 arg)
157 {
158     return RGBArgsMap[arg&MUX_MASK];
159 }
160
161 GLint COGLColorCombinerTNT2::MapRGBArgFlags(uint8 arg)
162 {
163     if( (arg & MUX_ALPHAREPLICATE) && (arg & MUX_COMPLEMENT) )
164     {
165         return GL_ONE_MINUS_SRC_ALPHA;
166     }
167     else if( (arg & MUX_ALPHAREPLICATE) )
168     {
169         if( arg == MUX_1 )
170             return GL_ONE_MINUS_SRC_ALPHA;
171         else
172             return GL_SRC_ALPHA;
173     }
174     else if(arg & MUX_COMPLEMENT || arg == MUX_1) 
175     {
176         return GL_ONE_MINUS_SRC_COLOR;
177     }
178     else
179         return GL_SRC_COLOR;
180 }
181
182 GLint COGLColorCombinerTNT2::MapAlphaArgs(uint8 arg)
183 {
184     return RGBArgsMap[arg&MUX_MASK];
185 }
186
187 GLint COGLColorCombinerTNT2::MapAlphaArgFlags(uint8 arg)
188 {
189     if(arg & MUX_COMPLEMENT || arg == MUX_1) 
190     {
191         return GL_ONE_MINUS_SRC_ALPHA;
192     }
193     else
194         return GL_SRC_ALPHA;
195 }
196
197 //========================================================================
198
199 void COGLColorCombinerTNT2::GenerateCombinerSetting(int index)
200 {
201     TNT2CombinerSaveType &res = m_vCompiledTNTSettings[index];
202
203     // Texture unit 0
204     COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
205     COGLTexture* pTexture1 = g_textures[(gRSP.curTile+1)&7].m_pCOGLTexture;
206
207     if( pTexture )  m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
208     if( pTexture1 ) m_pOGLRender->BindTexture(pTexture1->m_dwTextureName, 1);
209
210     // Texture unit 0
211     pglActiveTexture(GL_TEXTURE0_ARB);
212     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
213     m_pOGLRender->EnableTexUnit(0,TRUE);
214     glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, res.unit1.rgbOp);
215     glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, res.unit1.alphaOp);
216
217     if( res.unit1.rgbOp == GL_SUBTRACT_ARB )
218     {
219         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, MapRGBArgs(res.unit1.rgbArg0^MUX_COMPLEMENT));
220         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, MapRGBArgFlags(res.unit1.rgbArg0^MUX_COMPLEMENT));
221     }
222     else
223     {
224         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, MapRGBArgs(res.unit1.rgbArg0));
225         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, MapRGBArgFlags(res.unit1.rgbArg0));
226     }
227
228     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, MapRGBArgs(res.unit1.rgbArg1));
229     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, MapRGBArgFlags(res.unit1.rgbArg1));
230
231     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, MapRGBArgs(res.unit1.rgbArg2));
232     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, MapRGBArgFlags(res.unit1.rgbArg2));
233
234     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_EXT, MapRGBArgs(res.unit1.rgbArg3));
235     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_EXT, MapRGBArgFlags(res.unit1.rgbArg3));
236
237     if( res.unit1.alphaOp == GL_SUBTRACT_ARB )
238     {
239         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, MapRGBArgs(res.unit1.alphaArg0^MUX_COMPLEMENT));
240         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, MapAlphaArgFlags(res.unit1.alphaArg0^MUX_COMPLEMENT));
241     }
242     else
243     {
244         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, MapRGBArgs(res.unit1.alphaArg0));
245         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, MapAlphaArgFlags(res.unit1.alphaArg0));
246     }
247
248     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, MapRGBArgs(res.unit1.alphaArg1));
249     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, MapAlphaArgFlags(res.unit1.alphaArg1));
250
251     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, MapRGBArgs(res.unit1.alphaArg2));
252     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, MapAlphaArgFlags(res.unit1.alphaArg2));
253
254     glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_EXT, MapRGBArgs(res.unit1.rgbArg3));
255     glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_EXT, MapAlphaArgFlags(res.unit1.rgbArg3));
256
257     pglActiveTexture(GL_TEXTURE1_ARB);
258     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV);
259
260     if( m_maxTexUnits > 1 && res.numOfUnits > 1 )
261     {
262         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, res.unit2.rgbOp);
263         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, res.unit2.alphaOp);
264
265         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, MapRGBArgs(res.unit2.rgbArg0));
266         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, MapRGBArgFlags(res.unit2.rgbArg0));
267
268         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, MapRGBArgs(res.unit2.rgbArg1));
269         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, MapRGBArgFlags(res.unit2.rgbArg1));
270
271         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, MapRGBArgs(res.unit2.rgbArg2));
272         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, MapRGBArgFlags(res.unit2.rgbArg2));
273
274         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_RGB_EXT, MapRGBArgs(res.unit2.rgbArg3));
275         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_RGB_EXT, MapRGBArgFlags(res.unit2.rgbArg3));
276
277         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, MapRGBArgs(res.unit2.alphaArg0));
278         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, MapAlphaArgFlags(res.unit2.alphaArg0));
279
280         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, MapRGBArgs(res.unit2.alphaArg1));
281         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, MapAlphaArgFlags(res.unit2.alphaArg1));
282
283         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, MapRGBArgs(res.unit2.alphaArg2));
284         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, MapAlphaArgFlags(res.unit2.alphaArg2));
285
286         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE3_ALPHA_EXT, MapRGBArgs(res.unit2.alphaArg3));
287         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND3_ALPHA_EXT, MapAlphaArgFlags(res.unit2.alphaArg3));
288
289         m_pOGLRender->EnableTexUnit(1,TRUE);
290     }
291     else
292     {
293         //m_pOGLRender->EnableTexUnit(1,FALSE);
294     }
295 }
296
297 void COGLColorCombinerTNT2::GenerateCombinerSettingConstants(int index)
298 {
299     TNT2CombinerSaveType &res = m_vCompiledTNTSettings[index];
300     for( int i=0; i<2; i++ )
301     {
302         float *fv;
303         pglActiveTextureARB(GL_TEXTURE0_ARB+i);
304         switch( res.units[i].constant & MUX_MASK )
305         {
306         case MUX_PRIM:
307             fv = GetPrimitiveColorfv();
308             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
309             break;
310         case MUX_ENV:
311             fv = GetEnvColorfv();
312             glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
313             break;
314         case MUX_LODFRAC:
315             {
316                 float frac = gRDP.LODFrac / 255.0f;
317                 float tempf[4] = {frac,frac,frac,frac};
318                 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,tempf);
319                 break;
320             }
321         case MUX_PRIMLODFRAC:
322             {
323                 float frac = gRDP.primLODFrac / 255.0f;
324                 float tempf[4] = {frac,frac,frac,frac};
325                 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,tempf);
326                 break;
327             }
328         }
329     }
330 }
331
332