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;
74 COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
75 if( pcontext->IsExtensionSupported(OSAL_GL_ARB_TEXTURE_ENV_ADD) || pcontext->IsExtensionSupported("GL_EXT_texture_env_add") )
80 if( pcontext->IsExtensionSupported("GL_EXT_blend_subtract") )
82 m_bSupportSubtract = true;
88 void COGLColorCombiner::DisableCombiner(void)
90 m_pOGLRender->DisableMultiTexture();
93 glBlendFunc(GL_ONE, GL_ZERO);
98 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
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);
105 m_pOGLRender->SetAllTexelRepeatFlag();
110 DebuggerAppendMsg("Check me, texture is NULL but it is enabled");
116 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
118 m_pOGLRender->EnableTexUnit(0,FALSE);
122 void COGLColorCombiner::InitCombinerCycleCopy(void)
124 m_pOGLRender->DisableMultiTexture();
125 m_pOGLRender->EnableTexUnit(0,TRUE);
126 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
129 m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
130 m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile);
135 DebuggerAppendMsg("Check me, texture is NULL");
139 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
143 void COGLColorCombiner::InitCombinerCycleFill(void)
145 m_pOGLRender->DisableMultiTexture();
146 m_pOGLRender->EnableTexUnit(0,FALSE);
150 void COGLColorCombiner::InitCombinerCycle12(void)
152 m_pOGLRender->DisableMultiTexture();
153 if( !m_bTexelsEnable )
155 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
157 m_pOGLRender->EnableTexUnit(0,FALSE);
163 COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
166 m_pOGLRender->EnableTexUnit(0,TRUE);
167 m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
168 m_pOGLRender->SetAllTexelRepeatFlag();
173 DebuggerAppendMsg("Check me, texture is NULL");
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);
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
186 N64CombinerType & comb = m_pDecodedMux->m_n64Combiners[0];
187 switch( m_pDecodedMux->mType )
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);
194 case CM_FMT_TYPE_A_ADD_D: // = A+D
195 if( shadeIsUsedInColor && texIsUsedInColor )
198 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
200 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
202 else if( texIsUsedInColor )
204 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
207 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
210 case CM_FMT_TYPE_A_SUB_B: // = A-B
211 if( shadeIsUsedInColor && texIsUsedInColor )
213 if( m_bSupportSubtract )
214 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SUBTRACT_ARB);
216 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
218 else if( texIsUsedInColor )
220 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
223 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
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 )
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);
234 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
236 else if( texIsUsedInColor )
238 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
241 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
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))
248 if( (comb.a&mask)==MUX_PRIM )
250 fv = GetPrimitiveColorfv();
254 fv = GetEnvColorfv();
257 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
259 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
263 default: // = (A-B)*C+D
264 if( shadeIsUsedInColor )
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);
270 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
274 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
282 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
288 void COGLBlender::NormalAlphaBlender(void)
292 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
296 void COGLBlender::DisableAlphaBlender(void)
300 glBlendFunc(GL_ONE, GL_ZERO);
305 void COGLBlender::BlendFunc(uint32 srcFunc, uint32 desFunc)
307 glBlendFunc(DirectX_OGL_BlendFuncMaps[srcFunc], DirectX_OGL_BlendFuncMaps[desFunc]);
311 void COGLBlender::Enable()
317 void COGLBlender::Disable()
323 void COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
325 m_pOGLRender->DisableMultiTexture();
326 if( g_textures[tile].m_pCTexture )
328 m_pOGLRender->EnableTexUnit(0,TRUE);
329 glBindTexture(GL_TEXTURE_2D, ((COGLTexture*)(g_textures[tile].m_pCTexture))->m_dwTextureName);
332 m_pOGLRender->SetAllTexelRepeatFlag();
334 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
336 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
338 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
340 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
343 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
345 m_pOGLRender->SetAlphaTestEnable(FALSE);
349 extern const char *translatedCombTypes[];
350 void COGLColorCombiner::DisplaySimpleMuxString(void)
352 TRACE0("\nSimplified Mux\n");
353 m_pDecodedMux->DisplaySimpliedMuxString("Used");