Rice Video Plugin for GLES1.1
[mupen64plus-pandora.git] / source / rice_gles / src / OGLCombiner.cpp
CommitLineData
d07c171f 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//========================================================================
32uint32 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//========================================================================
51COGLColorCombiner::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
61COGLColorCombiner::~COGLColorCombiner()
62{
63 delete m_pDecodedMux;
64 m_pDecodedMux = NULL;
65}
66
67bool COGLColorCombiner::Initialize(void)
68{
69 m_bSupportAdd = false;
70 m_bSupportSubtract = false;
71 m_supportedStages = 1;
72 m_bSupportMultiTexture = false;
73
74#ifndef HAVE_GLES
75 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
76 if( pcontext->IsExtensionSupported(OSAL_GL_ARB_TEXTURE_ENV_ADD) || pcontext->IsExtensionSupported("GL_EXT_texture_env_add") )
77#endif
78 {
79 m_bSupportAdd = true;
80 }
81#ifndef HAVE_GLES
82 if( pcontext->IsExtensionSupported("GL_EXT_blend_subtract") )
83#endif
84 {
85 m_bSupportSubtract = true;
86 }
87
88 return true;
89}
90
91void COGLColorCombiner::DisableCombiner(void)
92{
93 m_pOGLRender->DisableMultiTexture();
94 glEnable(GL_BLEND);
95 OPENGL_CHECK_ERRORS;
96 glBlendFunc(GL_ONE, GL_ZERO);
97 OPENGL_CHECK_ERRORS;
98
99 if( m_bTexelsEnable )
100 {
101 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
102 if( pTexture )
103 {
104 m_pOGLRender->EnableTexUnit(0,TRUE);
105 m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
106 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
107 OPENGL_CHECK_ERRORS;
108 m_pOGLRender->SetAllTexelRepeatFlag();
109 }
110#ifdef DEBUGGER
111 else
112 {
113 DebuggerAppendMsg("Check me, texture is NULL but it is enabled");
114 }
115#endif
116 }
117 else
118 {
119 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
120 OPENGL_CHECK_ERRORS;
121 m_pOGLRender->EnableTexUnit(0,FALSE);
122 }
123}
124
125void COGLColorCombiner::InitCombinerCycleCopy(void)
126{
127 m_pOGLRender->DisableMultiTexture();
128 m_pOGLRender->EnableTexUnit(0,TRUE);
129 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
130 if( pTexture )
131 {
132 m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
133 m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile);
134 }
135#ifdef DEBUGGER
136 else
137 {
138 DebuggerAppendMsg("Check me, texture is NULL");
139 }
140#endif
141
142 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
143 OPENGL_CHECK_ERRORS;
144}
145
146void COGLColorCombiner::InitCombinerCycleFill(void)
147{
148 m_pOGLRender->DisableMultiTexture();
149 m_pOGLRender->EnableTexUnit(0,FALSE);
150}
151
152
153void COGLColorCombiner::InitCombinerCycle12(void)
154{
155 m_pOGLRender->DisableMultiTexture();
156 if( !m_bTexelsEnable )
157 {
158 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
159 OPENGL_CHECK_ERRORS;
160 m_pOGLRender->EnableTexUnit(0,FALSE);
161 return;
162 }
163
164#if SDL_VIDEO_OPENGL
165 uint32 mask = 0x1f;
166 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
167 if( pTexture )
168 {
169 m_pOGLRender->EnableTexUnit(0,TRUE);
170 m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
171 m_pOGLRender->SetAllTexelRepeatFlag();
172 }
173#ifdef DEBUGGER
174 else
175 {
176 DebuggerAppendMsg("Check me, texture is NULL");
177 }
178#endif
179
180 bool texIsUsed = m_pDecodedMux->isUsed(MUX_TEXEL0);
181 bool shadeIsUsedInColor = m_pDecodedMux->isUsedInCycle(MUX_SHADE, 0, COLOR_CHANNEL);
182 bool texIsUsedInColor = m_pDecodedMux->isUsedInCycle(MUX_TEXEL0, 0, COLOR_CHANNEL);
183
184 if( texIsUsed )
185 {
186 // Parse the simplified the mux, because the OGL 1.1 combiner function is so much
187 // limited, we only parse the 1st N64 combiner setting and only the RGB part
188
189 N64CombinerType & comb = m_pDecodedMux->m_n64Combiners[0];
190 switch( m_pDecodedMux->mType )
191 {
192 case CM_FMT_TYPE_NOT_USED:
193 case CM_FMT_TYPE_D: // = A
194 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
195 OPENGL_CHECK_ERRORS;
196 break;
197 case CM_FMT_TYPE_A_ADD_D: // = A+D
198 if( shadeIsUsedInColor && texIsUsedInColor )
199 {
200 if( m_bSupportAdd )
201 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
202 else
203 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
204 }
205 else if( texIsUsedInColor )
206 {
207 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
208 }
209 else
210 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
211 OPENGL_CHECK_ERRORS;
212 break;
213 case CM_FMT_TYPE_A_SUB_B: // = A-B
214 if( shadeIsUsedInColor && texIsUsedInColor )
215 {
216 if( m_bSupportSubtract )
217 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SUBTRACT_ARB);
218 else
219 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
220 }
221 else if( texIsUsedInColor )
222 {
223 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
224 }
225 else
226 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
227 OPENGL_CHECK_ERRORS;
228 break;
229 case CM_FMT_TYPE_A_MOD_C: // = A*C
230 case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D
231 if( shadeIsUsedInColor && texIsUsedInColor )
232 {
233 if( ((comb.c & mask) == MUX_SHADE && !(comb.c&MUX_COMPLEMENT)) ||
234 ((comb.a & mask) == MUX_SHADE && !(comb.a&MUX_COMPLEMENT)) )
235 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
236 else
237 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
238 }
239 else if( texIsUsedInColor )
240 {
241 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
242 }
243 else
244 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
245 OPENGL_CHECK_ERRORS;
246 break;
247 case CM_FMT_TYPE_A_LERP_B_C: // = A*C+D
248 if( (comb.b&mask) == MUX_SHADE && (comb.c&mask)==MUX_TEXEL0 && ((comb.a&mask)==MUX_PRIM||(comb.a&mask)==MUX_ENV))
249 {
250 float *fv;
251 if( (comb.a&mask)==MUX_PRIM )
252 {
253 fv = GetPrimitiveColorfv();
254 }
255 else
256 {
257 fv = GetEnvColorfv();
258 }
259
260 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
261 OPENGL_CHECK_ERRORS;
262 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
263 OPENGL_CHECK_ERRORS;
264 break;
265 }
266 default: // = (A-B)*C+D
267 if( shadeIsUsedInColor )
268 {
269 if( ((comb.c & mask) == MUX_SHADE && !(comb.c&MUX_COMPLEMENT)) ||
270 ((comb.a & mask) == MUX_SHADE && !(comb.a&MUX_COMPLEMENT)) )
271 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
272 else
273 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
274 }
275 else
276 {
277 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
278 }
279 OPENGL_CHECK_ERRORS;
280 break;
281 }
282 }
283 else
284 {
285 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
286 OPENGL_CHECK_ERRORS;
287 }
288#endif
289}
290
291void COGLBlender::NormalAlphaBlender(void)
292{
293 glEnable(GL_BLEND);
294 OPENGL_CHECK_ERRORS;
295 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
296 OPENGL_CHECK_ERRORS;
297}
298
299void COGLBlender::DisableAlphaBlender(void)
300{
301 glEnable(GL_BLEND);
302 OPENGL_CHECK_ERRORS;
303 glBlendFunc(GL_ONE, GL_ZERO);
304 OPENGL_CHECK_ERRORS;
305}
306
307
308void COGLBlender::BlendFunc(uint32 srcFunc, uint32 desFunc)
309{
310 glBlendFunc(DirectX_OGL_BlendFuncMaps[srcFunc], DirectX_OGL_BlendFuncMaps[desFunc]);
311 OPENGL_CHECK_ERRORS;
312}
313
314void COGLBlender::Enable()
315{
316 glEnable(GL_BLEND);
317 OPENGL_CHECK_ERRORS;
318}
319
320void COGLBlender::Disable()
321{
322 glDisable(GL_BLEND);
323 OPENGL_CHECK_ERRORS;
324}
325
326void COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
327{
328 m_pOGLRender->DisableMultiTexture();
329 if( g_textures[tile].m_pCTexture )
330 {
331 m_pOGLRender->EnableTexUnit(0,TRUE);
332 glBindTexture(GL_TEXTURE_2D, ((COGLTexture*)(g_textures[tile].m_pCTexture))->m_dwTextureName);
333 OPENGL_CHECK_ERRORS;
334 }
335 m_pOGLRender->SetAllTexelRepeatFlag();
336
337 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
338 OPENGL_CHECK_ERRORS;
339 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
340 OPENGL_CHECK_ERRORS;
341 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
342 OPENGL_CHECK_ERRORS;
343 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
344 OPENGL_CHECK_ERRORS;
345
346 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
347 OPENGL_CHECK_ERRORS;
348 m_pOGLRender->SetAlphaTestEnable(FALSE);
349}
350
351#ifdef DEBUGGER
352extern const char *translatedCombTypes[];
353void COGLColorCombiner::DisplaySimpleMuxString(void)
354{
355 TRACE0("\nSimplified Mux\n");
356 m_pDecodedMux->DisplaySimpliedMuxString("Used");
357}
358#endif
359