Rice GLES2 (from mupen64plus-ae) plugin. Compile but doesn't works well on the OpenPa...
[mupen64plus-pandora.git] / source / gles2rice / src / OGLCombiner.cpp
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - OGLCombiner.cpp                                         *
3  *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
4  *   Copyright (C) 2003 Rice1964                                           *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
20  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 #include "osal_opengl.h"
23
24 #include "OGLCombiner.h"
25 #include "OGLDebug.h"
26 #include "OGLRender.h"
27 #include "OGLGraphicsContext.h"
28 #include "OGLDecodedMux.h"
29 #include "OGLTexture.h"
30
31 //========================================================================
32 uint32 DirectX_OGL_BlendFuncMaps [] =
33 {
34     GL_SRC_ALPHA,               //Nothing
35     GL_ZERO,                    //BLEND_ZERO               = 1,
36     GL_ONE,                     //BLEND_ONE                = 2,
37     GL_SRC_COLOR,               //BLEND_SRCCOLOR           = 3,
38     GL_ONE_MINUS_SRC_COLOR,     //BLEND_INVSRCCOLOR        = 4,
39     GL_SRC_ALPHA,               //BLEND_SRCALPHA           = 5,
40     GL_ONE_MINUS_SRC_ALPHA,     //BLEND_INVSRCALPHA        = 6,
41     GL_DST_ALPHA,               //BLEND_DESTALPHA          = 7,
42     GL_ONE_MINUS_DST_ALPHA,     //BLEND_INVDESTALPHA       = 8,
43     GL_DST_COLOR,               //BLEND_DESTCOLOR          = 9,
44     GL_ONE_MINUS_DST_COLOR,     //BLEND_INVDESTCOLOR       = 10,
45     GL_SRC_ALPHA_SATURATE,      //BLEND_SRCALPHASAT        = 11,
46     GL_SRC_ALPHA_SATURATE,      //BLEND_BOTHSRCALPHA       = 12,    
47     GL_SRC_ALPHA_SATURATE,      //BLEND_BOTHINVSRCALPHA    = 13,
48 };
49
50 //========================================================================
51 COGLColorCombiner::COGLColorCombiner(CRender *pRender) :
52     CColorCombiner(pRender),
53     m_pOGLRender((OGLRender*)pRender),
54     m_bSupportAdd(false), m_bSupportSubtract(false)
55 {
56     m_pDecodedMux = new COGLDecodedMux;
57     m_pDecodedMux->m_maxConstants = 0;
58     m_pDecodedMux->m_maxTextures = 1;
59 }
60
61 COGLColorCombiner::~COGLColorCombiner()
62 {
63     delete m_pDecodedMux;
64     m_pDecodedMux = NULL;
65 }
66
67 bool COGLColorCombiner::Initialize(void)
68 {
69     m_bSupportAdd = false;
70     m_bSupportSubtract = false;
71     m_supportedStages = 1;
72     m_bSupportMultiTexture = false;
73
74     COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
75     if( pcontext->IsExtensionSupported(OSAL_GL_ARB_TEXTURE_ENV_ADD) || pcontext->IsExtensionSupported("GL_EXT_texture_env_add") )
76     {
77         m_bSupportAdd = true;
78     }
79
80     if( pcontext->IsExtensionSupported("GL_EXT_blend_subtract") )
81     {
82         m_bSupportSubtract = true;
83     }
84
85     return true;
86 }
87
88 void COGLColorCombiner::DisableCombiner(void)
89 {
90     m_pOGLRender->DisableMultiTexture();
91     glEnable(GL_BLEND);
92     OPENGL_CHECK_ERRORS;
93     glBlendFunc(GL_ONE, GL_ZERO);
94     OPENGL_CHECK_ERRORS;
95     
96     if( m_bTexelsEnable )
97     {
98         COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
99         if( pTexture ) 
100         {
101             m_pOGLRender->EnableTexUnit(0,TRUE);
102             m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
103             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
104             OPENGL_CHECK_ERRORS;
105             m_pOGLRender->SetAllTexelRepeatFlag();
106         }
107 #ifdef DEBUGGER
108         else
109         {
110             DebuggerAppendMsg("Check me, texture is NULL but it is enabled");
111         }
112 #endif
113     }
114     else
115     {
116         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
117         OPENGL_CHECK_ERRORS;
118         m_pOGLRender->EnableTexUnit(0,FALSE);
119     }
120 }
121
122 void COGLColorCombiner::InitCombinerCycleCopy(void)
123 {
124     m_pOGLRender->DisableMultiTexture();
125     m_pOGLRender->EnableTexUnit(0,TRUE);
126     COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
127     if( pTexture )
128     {
129         m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
130         m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile);
131     }
132 #ifdef DEBUGGER
133     else
134     {
135         DebuggerAppendMsg("Check me, texture is NULL");
136     }
137 #endif
138
139     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
140     OPENGL_CHECK_ERRORS;
141 }
142
143 void COGLColorCombiner::InitCombinerCycleFill(void)
144 {
145     m_pOGLRender->DisableMultiTexture();
146     m_pOGLRender->EnableTexUnit(0,FALSE);
147 }
148
149
150 void COGLColorCombiner::InitCombinerCycle12(void)
151 {
152     m_pOGLRender->DisableMultiTexture();
153     if( !m_bTexelsEnable )
154     {
155         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
156         OPENGL_CHECK_ERRORS;
157         m_pOGLRender->EnableTexUnit(0,FALSE);
158         return;
159     }
160
161 #if SDL_VIDEO_OPENGL
162     uint32 mask = 0x1f;
163     COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
164     if( pTexture )
165     {
166         m_pOGLRender->EnableTexUnit(0,TRUE);
167         m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
168         m_pOGLRender->SetAllTexelRepeatFlag();
169     }
170 #ifdef DEBUGGER
171     else
172     {
173         DebuggerAppendMsg("Check me, texture is NULL");
174     }
175 #endif
176
177     bool texIsUsed = m_pDecodedMux->isUsed(MUX_TEXEL0);
178     bool shadeIsUsedInColor = m_pDecodedMux->isUsedInCycle(MUX_SHADE, 0, COLOR_CHANNEL);
179     bool texIsUsedInColor = m_pDecodedMux->isUsedInCycle(MUX_TEXEL0, 0, COLOR_CHANNEL);
180
181     if( texIsUsed )
182     {
183         // Parse the simplified the mux, because the OGL 1.1 combiner function is so much
184         // limited, we only parse the 1st N64 combiner setting and only the RGB part
185
186         N64CombinerType & comb = m_pDecodedMux->m_n64Combiners[0];
187         switch( m_pDecodedMux->mType )
188         {
189         case CM_FMT_TYPE_NOT_USED:
190         case CM_FMT_TYPE_D:             // = A
191             glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
192             OPENGL_CHECK_ERRORS;
193             break;
194         case CM_FMT_TYPE_A_ADD_D:           // = A+D
195             if( shadeIsUsedInColor && texIsUsedInColor )
196             {
197                 if( m_bSupportAdd )
198                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
199                 else
200                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
201             }
202             else if( texIsUsedInColor )
203             {
204                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
205             }
206             else
207                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
208             OPENGL_CHECK_ERRORS;
209             break;
210         case CM_FMT_TYPE_A_SUB_B:           // = A-B
211             if( shadeIsUsedInColor && texIsUsedInColor )
212             {
213                 if( m_bSupportSubtract )
214                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SUBTRACT_ARB);
215                 else
216                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
217             }
218             else if( texIsUsedInColor )
219             {
220                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
221             }
222             else
223                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
224             OPENGL_CHECK_ERRORS;
225             break;
226         case CM_FMT_TYPE_A_MOD_C:           // = A*C
227         case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D
228             if( shadeIsUsedInColor && texIsUsedInColor )
229             {
230                 if( ((comb.c & mask) == MUX_SHADE && !(comb.c&MUX_COMPLEMENT)) ||
231                     ((comb.a & mask) == MUX_SHADE && !(comb.a&MUX_COMPLEMENT)) )
232                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
233                 else
234                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
235             }
236             else if( texIsUsedInColor )
237             {
238                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
239             }
240             else
241                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
242             OPENGL_CHECK_ERRORS;
243             break;
244         case CM_FMT_TYPE_A_LERP_B_C:    // = A*C+D
245             if( (comb.b&mask) == MUX_SHADE && (comb.c&mask)==MUX_TEXEL0 && ((comb.a&mask)==MUX_PRIM||(comb.a&mask)==MUX_ENV))
246             {
247                 float *fv;
248                 if( (comb.a&mask)==MUX_PRIM )
249                 {
250                     fv = GetPrimitiveColorfv();
251                 }
252                 else
253                 {
254                     fv = GetEnvColorfv();
255                 }
256
257                 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
258                 OPENGL_CHECK_ERRORS;
259                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
260                 OPENGL_CHECK_ERRORS;
261                 break;
262             }
263         default:        // = (A-B)*C+D
264             if( shadeIsUsedInColor )
265             {
266                 if( ((comb.c & mask) == MUX_SHADE && !(comb.c&MUX_COMPLEMENT)) ||
267                     ((comb.a & mask) == MUX_SHADE && !(comb.a&MUX_COMPLEMENT)) )
268                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
269                 else
270                     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
271             }
272             else
273             {
274                 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
275             }
276             OPENGL_CHECK_ERRORS;
277             break;
278         }
279     }
280     else
281     {
282         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
283         OPENGL_CHECK_ERRORS;
284     }
285 #endif
286 }
287
288 void COGLBlender::NormalAlphaBlender(void)
289 {
290     glEnable(GL_BLEND);
291     OPENGL_CHECK_ERRORS;
292     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
293     OPENGL_CHECK_ERRORS;
294 }
295
296 void COGLBlender::DisableAlphaBlender(void)
297 {
298     glEnable(GL_BLEND);
299     OPENGL_CHECK_ERRORS;
300     glBlendFunc(GL_ONE, GL_ZERO);
301     OPENGL_CHECK_ERRORS;
302 }
303
304
305 void COGLBlender::BlendFunc(uint32 srcFunc, uint32 desFunc)
306 {
307     glBlendFunc(DirectX_OGL_BlendFuncMaps[srcFunc], DirectX_OGL_BlendFuncMaps[desFunc]);
308     OPENGL_CHECK_ERRORS;
309 }
310
311 void COGLBlender::Enable()
312 {
313     glEnable(GL_BLEND);
314     OPENGL_CHECK_ERRORS;
315 }
316
317 void COGLBlender::Disable()
318 {
319     glDisable(GL_BLEND);
320     OPENGL_CHECK_ERRORS;
321 }
322
323 void COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
324 {
325     m_pOGLRender->DisableMultiTexture();
326     if( g_textures[tile].m_pCTexture )
327     {
328         m_pOGLRender->EnableTexUnit(0,TRUE);
329         glBindTexture(GL_TEXTURE_2D, ((COGLTexture*)(g_textures[tile].m_pCTexture))->m_dwTextureName);
330         OPENGL_CHECK_ERRORS;
331     }
332     m_pOGLRender->SetAllTexelRepeatFlag();
333
334     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
335     OPENGL_CHECK_ERRORS;
336     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
337     OPENGL_CHECK_ERRORS;
338     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
339     OPENGL_CHECK_ERRORS;
340     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
341     OPENGL_CHECK_ERRORS;
342
343     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
344     OPENGL_CHECK_ERRORS;
345     m_pOGLRender->SetAlphaTestEnable(FALSE);
346 }
347
348 #ifdef DEBUGGER
349 extern const char *translatedCombTypes[];
350 void COGLColorCombiner::DisplaySimpleMuxString(void)
351 {
352     TRACE0("\nSimplified Mux\n");
353     m_pDecodedMux->DisplaySimpliedMuxString("Used");
354 }
355 #endif
356