X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Frice_gles%2Fsrc%2FOGLExtCombiner.cpp;fp=source%2Frice_gles%2Fsrc%2FOGLExtCombiner.cpp;h=b7702e96a41f001e9228f3d859eb6bf365fda72f;hb=d07c171fa694cae985ad7045f9ce2b2f1a5699b4;hp=0000000000000000000000000000000000000000;hpb=ca22e7b76883b946060a6b40bb8709c1981e1cf6;p=mupen64plus-pandora.git diff --git a/source/rice_gles/src/OGLExtCombiner.cpp b/source/rice_gles/src/OGLExtCombiner.cpp new file mode 100644 index 0000000..b7702e9 --- /dev/null +++ b/source/rice_gles/src/OGLExtCombiner.cpp @@ -0,0 +1,1263 @@ +/* +Copyright (C) 2003 Rice1964 + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include +#include "osal_opengl.h" + +#if SDL_VIDEO_OPENGL +#include "OGLExtensions.h" +#endif +#include "OGLDebug.h" +#include "OGLExtCombiner.h" +#include "OGLExtRender.h" +#include "OGLDecodedMux.h" +#include "OGLGraphicsContext.h" +#include "OGLTexture.h" +#include "DirectXDecodedMux.h" + +#define GL_MODULATE_ADD_ATI 0x8744 +#define GL_MODULATE_SUBTRACT_ATI 0x8746 + +//======================================================================== +COGLColorCombiner4::COGLColorCombiner4(CRender *pRender) + :COGLColorCombiner(pRender), m_maxTexUnits(0), m_lastIndex(-1), + m_dwLastMux0(0), m_dwLastMux1(0) +{ + m_bOGLExtCombinerSupported=false; + m_bSupportModAdd_ATI = false; + m_bSupportModSub_ATI = false; + delete m_pDecodedMux; + m_pDecodedMux = new COGLExtDecodedMux; +} + +COGLColorCombiner4v2::COGLColorCombiner4v2(CRender *pRender) + :COGLColorCombiner4(pRender) +{ + delete m_pDecodedMux; + m_pDecodedMux = new DecodedMuxForOGL14V2; +} + +COGLColorCombiner2::COGLColorCombiner2(CRender *pRender) + :COGLColorCombiner4(pRender) +{ + delete m_pDecodedMux; + m_pDecodedMux = new CDirectXDecodedMux; // Use Mux for DirectX because we support only 1 texture for each stage + m_ppGeneralDecodedMux = &m_pDecodedMux; +} + +////////////////////////////////////////////////////////////////////////// +bool COGLColorCombiner4::Initialize(void) +{ + m_bOGLExtCombinerSupported = false; + m_bSupportModAdd_ATI = false; + m_bSupportModSub_ATI = false; + m_maxTexUnits = 1; + +#if SDL_VIDEO_OPENGL + if( COGLColorCombiner::Initialize() ) + { + m_bSupportMultiTexture = true; + COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext); +#ifndef HAVE_GLES + if( pcontext->IsExtensionSupported("GL_EXT_texture_env_combine") || pcontext->IsExtensionSupported("GL_ARB_texture_env_combine") ) +#endif + { + m_bOGLExtCombinerSupported = true; + glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&m_maxTexUnits); + OPENGL_CHECK_ERRORS; + if( m_maxTexUnits > 8 ) m_maxTexUnits = 8; + + TRACE0("Starting Ogl 1.4 multitexture combiner" ); + TRACE1("m_maxTexUnits = %d", m_maxTexUnits); +#ifndef HAVE_GLES + if( pcontext->IsExtensionSupported("ATI_texture_env_combine3") ) + { + m_bSupportModAdd_ATI = true; + m_bSupportModSub_ATI = true; + } +#endif + } +#ifndef HAVE_GLES + else + { + DebugMessage(M64MSG_ERROR, "Your video card does not support OpenGL extension combiner, you can only use the basic OpenGL combiner functions"); + } +#endif + m_supportedStages = m_maxTexUnits; + return true; + } + return false; + +#elif SDL_VIDEO_OPENGL_ES2 + return true; +#endif +} + +bool COGLColorCombiner2::Initialize(void) +{ + TRACE0("Starting Ogl 1.2/1.3 multitexture combiner" ); + if( COGLColorCombiner4::Initialize() ) + { + // For general combiner flags + m_dwGeneralMaxStages = m_supportedStages; + + m_bTxtOpAdd = m_bSupportAdd; + m_bTxtOpSub = m_bSupportSubtract; + m_bTxtOpLerp = true; + + m_bTxtOpAddSmooth = true; + m_bTxtOpBlendCurAlpha = true; + m_bTxtOpBlendDifAlpha = true; + m_bTxtOpBlendFacAlpha = true; + m_bTxtOpBlendTxtAlpha = true; + m_bTxtOpMulAdd = m_bSupportModAdd_ATI; + + return true; + } + else + { + return false; + } +} +//======================================================================== +void COGLColorCombiner4::InitCombinerCycleFill(void) +{ + for( int i=0; iEnableTexUnit(i,FALSE); + } + + //pglActiveTexture(GL_TEXTURE0_ARB); + //m_pOGLRender->EnableTexUnit(0,FALSE); + //pglActiveTexture(GL_TEXTURE1_ARB); + //m_pOGLRender->EnableTexUnit(1,FALSE); +} + +////////////////////////////////////////////////////////////////////////// +void COGLColorCombiner4::InitCombinerCycle12(void) +{ + if( !m_bOGLExtCombinerSupported ) + { + COGLColorCombiner::InitCombinerCycle12(); + return; + } + +#ifdef DEBUGGER + if( debuggerDropCombiners ) + { + UpdateCombiner(m_pDecodedMux->m_dwMux0,m_pDecodedMux->m_dwMux1); + m_vCompiledSettings.clear(); + m_dwLastMux0 = m_dwLastMux1 = 0; + debuggerDropCombiners = false; + } +#endif + + m_pOGLRender->EnableMultiTexture(); + + bool combinerIsChanged = false; + + if( m_pDecodedMux->m_dwMux0 != m_dwLastMux0 || m_pDecodedMux->m_dwMux1 != m_dwLastMux1 || m_lastIndex < 0 ) + { + combinerIsChanged = true; + m_lastIndex = FindCompiledMux(); + if( m_lastIndex < 0 ) // Can not found + { + m_lastIndex = ParseDecodedMux(); +#ifdef DEBUGGER + DisplaySimpleMuxString(); +#endif + } + + m_dwLastMux0 = m_pDecodedMux->m_dwMux0; + m_dwLastMux1 = m_pDecodedMux->m_dwMux1; + } + + + if( m_bCycleChanged || combinerIsChanged || gRDP.texturesAreReloaded || gRDP.colorsAreReloaded ) + { + if( m_bCycleChanged || combinerIsChanged ) + { + GenerateCombinerSettingConstants(m_lastIndex); + GenerateCombinerSetting(m_lastIndex); + } + else if( gRDP.colorsAreReloaded ) + { + GenerateCombinerSettingConstants(m_lastIndex); + } + + m_pOGLRender->SetAllTexelRepeatFlag(); + + gRDP.colorsAreReloaded = false; + gRDP.texturesAreReloaded = false; + } + else + { + m_pOGLRender->SetAllTexelRepeatFlag(); + } +} + +////////////////////////////////////////////////////////////////////////// +int COGLColorCombiner4::ParseDecodedMux() +{ +#define nextUnit() {unitNo++;} +#if SDL_VIDEO_OPENGL + if( m_maxTexUnits<3) + return ParseDecodedMux2Units(); + + OGLExtCombinerSaveType res; + for( int k=0; k<8; k++ ) + res.units[k].tex = -1; + + COGLDecodedMux &mux = *(COGLDecodedMux*)m_pDecodedMux; + + int unitNos[2]; + for( int rgbalpha = 0; rgbalpha<2; rgbalpha++ ) + { + unitNos[rgbalpha] = 0; + for( int cycle = 0; cycle<2; cycle++ ) + { + int &unitNo = unitNos[rgbalpha]; + OGLExtCombinerType &unit = res.units[unitNo]; + OGLExt1CombType &comb = unit.Combs[rgbalpha]; + CombinerFormatType type = m_pDecodedMux->splitType[cycle*2+rgbalpha]; + N64CombinerType &m = m_pDecodedMux->m_n64Combiners[cycle*2+rgbalpha]; + comb.arg0 = comb.arg1 = comb.arg2 = CM_IGNORE_BYTE; + + switch( type ) + { + case CM_FMT_TYPE_NOT_USED: + comb.arg0 = MUX_COMBINED; + unit.ops[rgbalpha] = GL_REPLACE; + nextUnit(); + break; + case CM_FMT_TYPE_D: // = A + comb.arg0 = m.d; + unit.ops[rgbalpha] = GL_REPLACE; + nextUnit(); + break; + case CM_FMT_TYPE_A_ADD_D: // = A+D + comb.arg0 = m.a; + comb.arg1 = m.d; + unit.ops[rgbalpha] = GL_ADD; + nextUnit(); + break; + case CM_FMT_TYPE_A_SUB_B: // = A-B + comb.arg0 = m.a; + comb.arg1 = m.b; + unit.ops[rgbalpha] = GL_SUBTRACT_ARB; + nextUnit(); + break; + case CM_FMT_TYPE_A_MOD_C: // = A*C + comb.arg0 = m.a; + comb.arg1 = m.c; + unit.ops[rgbalpha] = GL_MODULATE; + nextUnit(); + break; + case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D + if( m_bSupportModAdd_ATI ) + { + comb.arg0 = m.a; + comb.arg2 = m.c; + comb.arg1 = m.d; + unit.ops[rgbalpha] = GL_MODULATE_ADD_ATI; + nextUnit(); + } + else + { + if( unitNo < m_maxTexUnits-1 ) + { + comb.arg0 = m.a; + comb.arg1 = m.c; + unit.ops[rgbalpha] = GL_MODULATE; + nextUnit(); + res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED; + res.units[unitNo].Combs[rgbalpha].arg1 = m.d; + res.units[unitNo].ops[rgbalpha] = GL_ADD; + nextUnit(); + } + else + { + comb.arg0 = m.a; + comb.arg1 = m.c; + comb.arg2 = m.d; + unit.ops[rgbalpha] = GL_INTERPOLATE_ARB; + nextUnit(); + } + } + break; + case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B + comb.arg0 = m.a; + comb.arg1 = m.b; + comb.arg2 = m.c; + unit.ops[rgbalpha] = GL_INTERPOLATE_ARB; + nextUnit(); + break; + case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D + if( unitNo < m_maxTexUnits-1 ) + { + comb.arg0 = m.a; + comb.arg1 = m.b; + unit.ops[rgbalpha] = GL_SUBTRACT_ARB; + nextUnit(); + res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED; + res.units[unitNo].Combs[rgbalpha].arg1 = m.d; + res.units[unitNo].ops[rgbalpha] = GL_ADD; + nextUnit(); + } + else + { + comb.arg0 = m.a; + comb.arg1 = m.c; + comb.arg2 = m.d; + unit.ops[rgbalpha] = GL_INTERPOLATE_ARB; + nextUnit(); + } + break; + case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C + if( unitNo < m_maxTexUnits-1 ) + { + comb.arg0 = m.a; + comb.arg1 = m.b; + unit.ops[rgbalpha] = GL_SUBTRACT_ARB; + nextUnit(); + res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED; + res.units[unitNo].Combs[rgbalpha].arg1 = m.c; + res.units[unitNo].ops[rgbalpha] = GL_MODULATE; + nextUnit(); + } + else + { + comb.arg0 = m.a; + comb.arg1 = m.c; + comb.arg2 = m.d; + unit.ops[rgbalpha] = GL_INTERPOLATE_ARB; + nextUnit(); + } + break; + case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D + default: + if( unitNo < m_maxTexUnits-1 ) + { + comb.arg0 = m.a; + comb.arg1 = m.b; + unit.ops[rgbalpha] = GL_SUBTRACT_ARB; + nextUnit(); + if( m_bSupportModAdd_ATI ) + { + res.units[unitNo].Combs[rgbalpha].arg0 = MUX_COMBINED; + res.units[unitNo].Combs[rgbalpha].arg2 = m.c; + res.units[unitNo].Combs[rgbalpha].arg1 = m.d; + res.units[unitNo].ops[rgbalpha] = GL_MODULATE_ADD_ATI; + nextUnit(); + } + else + { + res.units[unitNo].Combs[rgbalpha].arg0 = m.a; + res.units[unitNo].Combs[rgbalpha].arg1 = m.b; + res.units[unitNo].Combs[rgbalpha].arg2 = m.c; + res.units[unitNo].ops[rgbalpha] = GL_INTERPOLATE_ARB; + nextUnit(); + } + } + else + { + comb.arg0 = m.a; + comb.arg1 = m.c; + comb.arg2 = m.d; + unit.ops[rgbalpha] = GL_INTERPOLATE_ARB; + nextUnit(); + } + break; + } + } + } + + res.numOfUnits = min(m_maxTexUnits, max(unitNos[0],unitNos[1])); + + if( unitNos[0]>m_maxTexUnits || unitNos[1]>m_maxTexUnits ) + { + TRACE0("Unit overflows"); + } + + for( int j=0; j<2; j++ ) + { + if( unitNos[j]splitType[i]; + N64CombinerType &m = m_pDecodedMux->m_n64Combiners[i]; + + comb.arg0 = comb.arg1 = comb.arg2 = MUX_0; + + switch( type ) + { + case CM_FMT_TYPE_NOT_USED: + comb.arg0 = MUX_COMBINED; + unit.ops[i%2] = GL_REPLACE; + break; + case CM_FMT_TYPE_D: // = A + comb.arg0 = m.d; + unit.ops[i%2] = GL_REPLACE; + break; +#if SDL_VIDEO_OPENGL + case CM_FMT_TYPE_A_ADD_D: // = A+D + comb.arg0 = m.a; + comb.arg1 = m.d; + unit.ops[i%2] = GL_ADD; + break; + case CM_FMT_TYPE_A_SUB_B: // = A-B + comb.arg0 = m.a; + comb.arg1 = m.b; + unit.ops[i%2] = GL_SUBTRACT_ARB; + break; + case CM_FMT_TYPE_A_MOD_C: // = A*C + comb.arg0 = m.a; + comb.arg1 = m.c; + unit.ops[i%2] = GL_MODULATE; + break; + case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D + comb.arg0 = m.a; + comb.arg1 = m.c; + comb.arg2 = m.d; + unit.ops[i%2] = GL_INTERPOLATE_ARB; + break; + case CM_FMT_TYPE_A_LERP_B_C: // = (A-B)*C+B + comb.arg0 = m.a; + comb.arg1 = m.b; + comb.arg2 = m.c; + unit.ops[i%2] = GL_INTERPOLATE_ARB; + break; + case CM_FMT_TYPE_A_SUB_B_ADD_D: // = A-B+D + // fix me, to use 2 texture units + comb.arg0 = m.a; + comb.arg1 = m.b; + unit.ops[i%2] = GL_SUBTRACT_ARB; + break; + case CM_FMT_TYPE_A_SUB_B_MOD_C: // = (A-B)*C + // fix me, to use 2 texture units + comb.arg0 = m.a; + comb.arg1 = m.c; + unit.ops[i%2] = GL_MODULATE; + break; + break; + case CM_FMT_TYPE_A_B_C_D: // = (A-B)*C+D +#endif + default: + comb.arg0 = m.a; + comb.arg1 = m.b; + comb.arg2 = m.c; + unit.ops[i%2] = GL_INTERPOLATE_ARB; + break; + } + } + + if( m_pDecodedMux->splitType[2] == CM_FMT_TYPE_NOT_USED && m_pDecodedMux->splitType[3] == CM_FMT_TYPE_NOT_USED && !m_bTex1Enabled ) + { + res.numOfUnits = 1; + } + + res.units[0].tex = 0; + res.units[1].tex = 1; + + return SaveParsedResult(res); +} + +const char* COGLColorCombiner4::GetOpStr(GLenum op) +{ + switch( op ) + { + case GL_REPLACE: + return "REPLACE"; +#if SDL_VIDEO_OPENGL + case GL_MODULATE: + return "MOD"; + case GL_ADD: + return "ADD"; + case GL_ADD_SIGNED_ARB: + return "ADD_SIGNED"; + case GL_INTERPOLATE_ARB: + return "INTERPOLATE"; + case GL_SUBTRACT_ARB: + return "SUB"; +#endif + case GL_MODULATE_ADD_ATI: + return "MULADD"; + default: + return "SUB"; + } +} + +int COGLColorCombiner4::SaveParsedResult(OGLExtCombinerSaveType &result) +{ + result.dwMux0 = m_pDecodedMux->m_dwMux0; + result.dwMux1 = m_pDecodedMux->m_dwMux1; + + for( int n=0; n= GL_TEXTURE0_ARB && val <= GL_TEXTURE7_ARB ) + return true; + else + return false; +} + +int COGLColorCombiner4v2::SaveParsedResult(OGLExtCombinerSaveType &result) +{ + result.dwMux0 = m_pDecodedMux->m_dwMux0; + result.dwMux1 = m_pDecodedMux->m_dwMux1; + + int n; + + for( n=0; nm_dwMux0 && m_vCompiledSettings[i].dwMux1 == m_pDecodedMux->m_dwMux1 ) + return (int)i; + } + + return -1; +} + +//======================================================================== + +GLint COGLColorCombiner4::RGBArgsMap4[] = +{ +#if SDL_VIDEO_OPENGL + GL_PRIMARY_COLOR_ARB, //MUX_0 + GL_PRIMARY_COLOR_ARB, //MUX_1 + GL_PREVIOUS_ARB, //MUX_COMBINED, +#endif + GL_TEXTURE0_ARB, //MUX_TEXEL0, +#if SDL_VIDEO_OPENGL + GL_TEXTURE1_ARB, //MUX_TEXEL1, + GL_CONSTANT_ARB, //MUX_PRIM, + GL_PRIMARY_COLOR_ARB, //MUX_SHADE, + GL_CONSTANT_ARB, //MUX_ENV, + GL_PREVIOUS_ARB, //MUX_COMBALPHA, +#endif + GL_TEXTURE0_ARB, //MUX_T0_ALPHA, +#if SDL_VIDEO_OPENGL + GL_TEXTURE1_ARB, //MUX_T1_ALPHA, + GL_CONSTANT_ARB, //MUX_PRIM_ALPHA, + GL_PRIMARY_COLOR_ARB, //MUX_SHADE_ALPHA, + GL_CONSTANT_ARB, //MUX_ENV_ALPHA, + GL_CONSTANT_ARB, //MUX_LODFRAC, + GL_CONSTANT_ARB, //MUX_PRIMLODFRAC, + GL_PRIMARY_COLOR_ARB, //MUX_K5 + GL_PRIMARY_COLOR_ARB //MUX_UNK +#endif +}; + +GLint COGLColorCombiner4v2::RGBArgsMap4v2[] = +{ +#if SDL_VIDEO_OPENGL + GL_PRIMARY_COLOR_ARB, //MUX_0 + GL_PRIMARY_COLOR_ARB, //MUX_1 + GL_PREVIOUS_ARB, //MUX_COMBINED, +#endif + GL_TEXTURE0_ARB, //MUX_TEXEL0, +#if SDL_VIDEO_OPENGL + GL_TEXTURE1_ARB, //MUX_TEXEL1, + GL_CONSTANT_ARB, //MUX_PRIM, + GL_PRIMARY_COLOR_ARB, //MUX_SHADE, + GL_TEXTURE2_ARB, //MUX_ENV, + //{GL_TEXTURE1_ARB, }, //MUX_ENV, + GL_PREVIOUS_ARB, //MUX_COMBALPHA, + GL_TEXTURE0_ARB, //MUX_T0_ALPHA, + GL_TEXTURE1_ARB, //MUX_T1_ALPHA, + GL_CONSTANT_ARB, //MUX_PRIM_ALPHA, + GL_PRIMARY_COLOR_ARB, //MUX_SHADE_ALPHA, + GL_TEXTURE2_ARB, //MUX_ENV_ALPHA, + //{GL_TEXTURE1_ARB, }, //MUX_ENV_ALPHA, + //{GL_TEXTURE3_ARB, }, //MUX_LODFRAC, + //{GL_TEXTURE3_ARB, }, //MUX_PRIMLODFRAC, + GL_TEXTURE1_ARB, //MUX_LODFRAC, + GL_TEXTURE1_ARB, //MUX_PRIMLODFRAC, + GL_PRIMARY_COLOR_ARB, //MUX_K5 + GL_PRIMARY_COLOR_ARB //MUX_UNK +#endif +}; + +GLint COGLColorCombiner2::RGBArgsMap2[] = +{ +#if SDL_VIDEO_OPENGL + GL_PRIMARY_COLOR_ARB, //MUX_0 + GL_PRIMARY_COLOR_ARB, //MUX_1 + GL_PREVIOUS_ARB, //MUX_COMBINED, + //{GL_TEXTURE, }, //MUX_TEXEL0, + //{GL_TEXTURE, }, //MUX_TEXEL1, +#endif + GL_TEXTURE0_ARB, //MUX_TEXEL0, +#if SDL_VIDEO_OPENGL + GL_TEXTURE1_ARB, //MUX_TEXEL1, + GL_CONSTANT_ARB, //MUX_PRIM, + GL_PRIMARY_COLOR_ARB, //MUX_SHADE, + GL_CONSTANT_ARB, //MUX_ENV, + GL_PREVIOUS_ARB, //MUX_COMBALPHA, + //{GL_TEXTURE, }, //MUX_T0_ALPHA, + //{GL_TEXTURE, }, //MUX_T1_ALPHA, + GL_TEXTURE0_ARB, //MUX_TEXEL0, + GL_TEXTURE1_ARB, //MUX_TEXEL1, + GL_CONSTANT_ARB, //MUX_PRIM_ALPHA, + GL_PRIMARY_COLOR_ARB, //MUX_SHADE_ALPHA, + GL_CONSTANT_ARB, //MUX_ENV_ALPHA, + GL_CONSTANT_ARB, //MUX_LODFRAC, + GL_CONSTANT_ARB, //MUX_PRIMLODFRAC, + GL_PRIMARY_COLOR_ARB, //MUX_K5 + GL_PRIMARY_COLOR_ARB //MUX_UNK +#endif +}; + +//======================================================================== + +GLint COGLColorCombiner4::MapRGBArgs(uint8 arg) +{ + return RGBArgsMap4[arg&MUX_MASK]; +} + +GLint COGLColorCombiner4v2::MapRGBArgs(uint8 arg) +{ + return RGBArgsMap4v2[arg&MUX_MASK]; +} + +GLint COGLColorCombiner2::MapRGBArgs(uint8 arg) +{ + return RGBArgsMap2[arg&MUX_MASK]; +} + +GLint COGLColorCombiner4::MapRGBArgFlags(uint8 arg) +{ + if( (arg & MUX_ALPHAREPLICATE) && (arg & MUX_COMPLEMENT) ) + { + return GL_ONE_MINUS_SRC_ALPHA; + } + else if( (arg & MUX_ALPHAREPLICATE) ) + { + return GL_SRC_ALPHA; + } + else if(arg & MUX_COMPLEMENT) + { + return GL_ONE_MINUS_SRC_COLOR; + } + else + return GL_SRC_COLOR; +} + +GLint COGLColorCombiner4::MapAlphaArgs(uint8 arg) +{ + return RGBArgsMap4[arg&MUX_MASK]; +} + +GLint COGLColorCombiner4v2::MapAlphaArgs(uint8 arg) +{ + return RGBArgsMap4v2[arg&MUX_MASK]; +} + +GLint COGLColorCombiner2::MapAlphaArgs(uint8 arg) +{ + return RGBArgsMap2[arg&MUX_MASK]; +} + +GLint COGLColorCombiner4::MapAlphaArgFlags(uint8 arg) +{ + if(arg & MUX_COMPLEMENT) + { + return GL_ONE_MINUS_SRC_ALPHA; + } + else + return GL_SRC_ALPHA; +} + +//======================================================================== + +void ApplyFor1Unit(OGLExtCombinerType &unit) +{ +#if SDL_VIDEO_OPENGL + glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, unit.rgbOp); + OPENGL_CHECK_ERRORS; + + if( unit.rgbArg0 != CM_IGNORE_BYTE ) + { + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, (unit.rgbArg0gl)); + OPENGL_CHECK_ERRORS; + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, (unit.rgbFlag0gl)); + OPENGL_CHECK_ERRORS; + } + + if( unit.rgbArg1 != CM_IGNORE_BYTE ) + { + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, (unit.rgbArg1gl)); + OPENGL_CHECK_ERRORS; + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, (unit.rgbFlag1gl)); + OPENGL_CHECK_ERRORS; + } + + if( unit.rgbArg2 != CM_IGNORE_BYTE ) + { + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, (unit.rgbArg2gl)); + OPENGL_CHECK_ERRORS; + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, (unit.rgbFlag2gl)); + OPENGL_CHECK_ERRORS; + } + + if( unit.alphaArg0 != CM_IGNORE_BYTE ) + { + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, (unit.alphaArg0gl)); + OPENGL_CHECK_ERRORS; + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, (unit.alphaFlag0gl)); + OPENGL_CHECK_ERRORS; + } + + if( unit.alphaArg1 != CM_IGNORE_BYTE ) + { + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, (unit.alphaArg1gl)); + OPENGL_CHECK_ERRORS; + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, (unit.alphaFlag1gl)); + OPENGL_CHECK_ERRORS; + } + + if( unit.alphaArg2 != CM_IGNORE_BYTE ) + { + glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, (unit.alphaArg2gl)); + OPENGL_CHECK_ERRORS; + glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, (unit.alphaFlag2gl)); + OPENGL_CHECK_ERRORS; + } +#endif +} + +////////////////////////////////////////////////////////////////////////// + +void COGLColorCombiner4::GenerateCombinerSetting(int index) +{ + OGLExtCombinerSaveType &res = m_vCompiledSettings[index]; + + // Texture unit 0 + COGLTexture* pTexture = NULL; + COGLTexture* pTexture1 = NULL; + + if( m_bTex0Enabled || m_bTex1Enabled || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY ) + { + if( m_bTex0Enabled || gRDP.otherMode.cycle_type == CYCLE_TYPE_COPY ) + { + pTexture = g_textures[gRSP.curTile].m_pCOGLTexture; + if( pTexture ) m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0); + } + if( m_bTex1Enabled ) + { + pTexture1 = g_textures[(gRSP.curTile+1)&7].m_pCOGLTexture; + if( pTexture1 ) m_pOGLRender->BindTexture(pTexture1->m_dwTextureName, 1); + } + } + + + + for( int i=0; iEnableTexUnit(i,TRUE); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + OPENGL_CHECK_ERRORS; + ApplyFor1Unit(res.units[i]); + } + + if( res.numOfUnits < m_maxTexUnits ) + { + for( int i=res.numOfUnits; iDisBindTexture(0, i); + m_pOGLRender->EnableTexUnit(i,FALSE); + } + } +} + + +void COGLColorCombiner4::GenerateCombinerSettingConstants(int index) +{ + OGLExtCombinerSaveType &res = m_vCompiledSettings[index]; + + float *fv; + float tempf[4]; + + bool isused = true; + + if( res.primIsUsed ) + { + fv = GetPrimitiveColorfv(); // CONSTANT COLOR + } + else if( res.envIsUsed ) + { + fv = GetEnvColorfv(); // CONSTANT COLOR + } + else if( res.lodFracIsUsed ) + { + float frac = gRDP.LODFrac / 255.0f; + tempf[0] = tempf[1] = tempf[2] = tempf[3] = frac; + fv = &tempf[0]; + } + else + { + isused = false; + } + + if( isused ) + { + for( int i=0; iEnableTexUnit(2,TRUE); + TxtrCacheEntry *pEntry = gTextureManager.GetConstantColorTexture(MUX_ENV); + prender->SetCurrentTexture( (gRSP.curTile+2)%7, pEntry->pTexture, 4, 4, pEntry); + prender->SetTexelRepeatFlags((gRSP.curTile+2)%7); + } + + if( res.lodFracIsUsed) + { + int unit = 3; + if( !res.envIsUsed ) + unit = 2; + + // Set Texture unit 3 to LODFRAC + pglActiveTexture(GL_TEXTURE0_ARB+unit); + OPENGL_CHECK_ERRORS; + prender->EnableTexUnit(unit,TRUE); + TxtrCacheEntry *pEntry = gTextureManager.GetConstantColorTexture(MUX_LODFRAC); + prender->SetCurrentTexture( (gRSP.curTile+unit)%7, pEntry->pTexture, 4, 4, pEntry); + prender->SetTexelRepeatFlags((gRSP.curTile+unit)%7); + } + else + { + int unit = 3; + if( !res.envIsUsed ) + unit = 2; + + // Disable texture unit 3 + pglActiveTexture(GL_TEXTURE0_ARB+unit); + OPENGL_CHECK_ERRORS; + prender->EnableTexUnit(unit,FALSE); + prender->SetTextureToTextureUnitMap(-1,unit); + } +} + + +GLenum GeneralToGLMaps[]= +{ + GL_REPLACE, //CM_REPLACE, +#if SDL_VIDEO_OPENGL + GL_MODULATE, //CM_MODULATE, + GL_ADD, //CM_ADD, + GL_SUBTRACT_ARB, //CM_SUBTRACT, + GL_INTERPOLATE_ARB, //CM_INTERPOLATE, + GL_INTERPOLATE_ARB, //CM_ADDSMOOTH, + GL_INTERPOLATE_ARB, //CM_BLENDCURRENTALPHA + GL_INTERPOLATE_ARB, //CM_BLENDDIFFUSEALPHA + GL_INTERPOLATE_ARB, //CM_BLENDFACTORALPHA, + GL_INTERPOLATE_ARB, //CM_BLENDTEXTUREALPHA +#endif + GL_MODULATE_ADD_ATI, //CM_MULTIPLYADD, +}; + + +////////////////////////////////////////////////////////////////////////// +int COGLColorCombiner2::ParseDecodedMux() +{ + //return COGLColorCombiner4::ParseDecodedMux(); + + int generalCombinerIndex = CGeneralCombiner::FindCompiledMux(); + if( generalCombinerIndex < 0 ) // Can not found + { + generalCombinerIndex = CGeneralCombiner::ParseDecodedMux(); + } + + GeneralCombinerInfo &generalRes = m_vCompiledCombinerStages[generalCombinerIndex]; + OGLExtCombinerSaveType res; + + // Convert generalRes to OGLExtCombinerSaveType + for( int unitNo=0; unitNoSetTextureToTextureUnitMap(res.units[i].tex,i); + m_pOGLRender->EnableTexUnit(i,TRUE); + COGLTexture* pTexture = g_textures[(gRSP.curTile+res.units[i].tex)&7].m_pCOGLTexture; + if( pTexture ) m_pOGLRender->BindTexture(pTexture->m_dwTextureName, i); + } + /* + else + { + m_pOGLRender->EnableTexUnit(i,TRUE); + prender->SetTextureToTextureUnitMap(-1,i); + //m_pOGLRender->EnableTexUnit(i,FALSE); + //m_pOGLRender->DisBindTexture(0, i); + } + */ + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + OPENGL_CHECK_ERRORS; + ApplyFor1Unit(res.units[i]); + } + + if( res.numOfUnits < m_maxTexUnits ) + { + for( int i=res.numOfUnits; iEnableTexUnit(i,FALSE); + prender->SetTextureToTextureUnitMap(-1,i); + } + } +} +