1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - OGLCombiner.cpp *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2003 Rice1964 *
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. *
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. *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22 #include "osal_opengl.h"
24 #include "OGLCombiner.h"
26 #include "OGLRender.h"
27 #include "OGLGraphicsContext.h"
28 #include "OGLDecodedMux.h"
29 #include "OGLTexture.h"
31 //========================================================================
32 uint32 DirectX_OGL_BlendFuncMaps [] =
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,
50 //========================================================================
51 COGLColorCombiner::COGLColorCombiner(CRender *pRender) :
52 CColorCombiner(pRender),
53 m_pOGLRender((OGLRender*)pRender),
54 m_bSupportAdd(false), m_bSupportSubtract(false)
56 m_pDecodedMux = new COGLDecodedMux;
57 m_pDecodedMux->m_maxConstants = 0;
58 m_pDecodedMux->m_maxTextures = 1;
61 COGLColorCombiner::~COGLColorCombiner()
67 bool COGLColorCombiner::Initialize(void)
69 m_bSupportAdd = false;
70 m_bSupportSubtract = false;
71 m_supportedStages = 1;
72 m_bSupportMultiTexture = false;
75 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
76 if( pcontext->IsExtensionSupported(OSAL_GL_ARB_TEXTURE_ENV_ADD) || pcontext->IsExtensionSupported("GL_EXT_texture_env_add") )
82 if( pcontext->IsExtensionSupported("GL_EXT_blend_subtract") )
85 m_bSupportSubtract = true;
91 void COGLColorCombiner::DisableCombiner(void)
93 m_pOGLRender->DisableMultiTexture();
96 glBlendFunc(GL_ONE, GL_ZERO);
101 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
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);
108 m_pOGLRender->SetAllTexelRepeatFlag();
113 DebuggerAppendMsg("Check me, texture is NULL but it is enabled");
119 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
121 m_pOGLRender->EnableTexUnit(0,FALSE);
125 void COGLColorCombiner::InitCombinerCycleCopy(void)
127 m_pOGLRender->DisableMultiTexture();
128 m_pOGLRender->EnableTexUnit(0,TRUE);
129 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
132 m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
133 m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile);
138 DebuggerAppendMsg("Check me, texture is NULL");
142 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
146 void COGLColorCombiner::InitCombinerCycleFill(void)
148 m_pOGLRender->DisableMultiTexture();
149 m_pOGLRender->EnableTexUnit(0,FALSE);
153 void COGLColorCombiner::InitCombinerCycle12(void)
155 m_pOGLRender->DisableMultiTexture();
156 if( !m_bTexelsEnable )
158 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
160 m_pOGLRender->EnableTexUnit(0,FALSE);
166 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
169 m_pOGLRender->EnableTexUnit(0,TRUE);
170 m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
171 m_pOGLRender->SetAllTexelRepeatFlag();
176 DebuggerAppendMsg("Check me, texture is NULL");
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);
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
189 N64CombinerType & comb = m_pDecodedMux->m_n64Combiners[0];
190 switch( m_pDecodedMux->mType )
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);
197 case CM_FMT_TYPE_A_ADD_D: // = A+D
198 if( shadeIsUsedInColor && texIsUsedInColor )
201 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
203 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
205 else if( texIsUsedInColor )
207 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
210 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
213 case CM_FMT_TYPE_A_SUB_B: // = A-B
214 if( shadeIsUsedInColor && texIsUsedInColor )
216 if( m_bSupportSubtract )
217 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SUBTRACT_ARB);
219 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
221 else if( texIsUsedInColor )
223 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
226 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
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 )
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);
237 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
239 else if( texIsUsedInColor )
241 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
244 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
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))
251 if( (comb.a&mask)==MUX_PRIM )
253 fv = GetPrimitiveColorfv();
257 fv = GetEnvColorfv();
260 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
262 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
266 default: // = (A-B)*C+D
267 if( shadeIsUsedInColor )
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);
273 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
277 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
285 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
291 void COGLBlender::NormalAlphaBlender(void)
295 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
299 void COGLBlender::DisableAlphaBlender(void)
303 glBlendFunc(GL_ONE, GL_ZERO);
308 void COGLBlender::BlendFunc(uint32 srcFunc, uint32 desFunc)
310 glBlendFunc(DirectX_OGL_BlendFuncMaps[srcFunc], DirectX_OGL_BlendFuncMaps[desFunc]);
314 void COGLBlender::Enable()
320 void COGLBlender::Disable()
326 void COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
328 m_pOGLRender->DisableMultiTexture();
329 if( g_textures[tile].m_pCTexture )
331 m_pOGLRender->EnableTexUnit(0,TRUE);
332 glBindTexture(GL_TEXTURE_2D, ((COGLTexture*)(g_textures[tile].m_pCTexture))->m_dwTextureName);
335 m_pOGLRender->SetAllTexelRepeatFlag();
337 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
339 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
341 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
343 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
346 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
348 m_pOGLRender->SetAlphaTestEnable(FALSE);
352 extern const char *translatedCombTypes[];
353 void COGLColorCombiner::DisplaySimpleMuxString(void)
355 TRACE0("\nSimplified Mux\n");
356 m_pDecodedMux->DisplaySimpliedMuxString("Used");