Path: blob/master/libmupen64plus/mupen64plus-video-rice/src/OGLCombiner.cpp
2 views
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *1* Mupen64plus - OGLCombiner.cpp *2* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *3* Copyright (C) 2003 Rice1964 *4* *5* This program is free software; you can redistribute it and/or modify *6* it under the terms of the GNU General Public License as published by *7* the Free Software Foundation; either version 2 of the License, or *8* (at your option) any later version. *9* *10* This program is distributed in the hope that it will be useful, *11* but WITHOUT ANY WARRANTY; without even the implied warranty of *12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *13* GNU General Public License for more details. *14* *15* You should have received a copy of the GNU General Public License *16* along with this program; if not, write to the *17* Free Software Foundation, Inc., *18* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *19* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */2021#include "osal_opengl.h"2223#include "OGLCombiner.h"24#include "OGLDebug.h"25#include "OGLRender.h"26#include "OGLGraphicsContext.h"27#include "OGLDecodedMux.h"28#include "OGLTexture.h"2930//========================================================================31uint32 DirectX_OGL_BlendFuncMaps [] =32{33GL_SRC_ALPHA, //Nothing34GL_ZERO, //BLEND_ZERO = 1,35GL_ONE, //BLEND_ONE = 2,36GL_SRC_COLOR, //BLEND_SRCCOLOR = 3,37GL_ONE_MINUS_SRC_COLOR, //BLEND_INVSRCCOLOR = 4,38GL_SRC_ALPHA, //BLEND_SRCALPHA = 5,39GL_ONE_MINUS_SRC_ALPHA, //BLEND_INVSRCALPHA = 6,40GL_DST_ALPHA, //BLEND_DESTALPHA = 7,41GL_ONE_MINUS_DST_ALPHA, //BLEND_INVDESTALPHA = 8,42GL_DST_COLOR, //BLEND_DESTCOLOR = 9,43GL_ONE_MINUS_DST_COLOR, //BLEND_INVDESTCOLOR = 10,44GL_SRC_ALPHA_SATURATE, //BLEND_SRCALPHASAT = 11,45GL_SRC_ALPHA_SATURATE, //BLEND_BOTHSRCALPHA = 12,46GL_SRC_ALPHA_SATURATE, //BLEND_BOTHINVSRCALPHA = 13,47};4849//========================================================================50COGLColorCombiner::COGLColorCombiner(CRender *pRender) :51CColorCombiner(pRender),52m_pOGLRender((OGLRender*)pRender),53m_bSupportAdd(false), m_bSupportSubtract(false)54{55m_pDecodedMux = new COGLDecodedMux;56m_pDecodedMux->m_maxConstants = 0;57m_pDecodedMux->m_maxTextures = 1;58}5960COGLColorCombiner::~COGLColorCombiner()61{62delete m_pDecodedMux;63m_pDecodedMux = NULL;64}6566bool COGLColorCombiner::Initialize(void)67{68m_bSupportAdd = false;69m_bSupportSubtract = false;70m_supportedStages = 1;71m_bSupportMultiTexture = false;7273COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);74if( pcontext->IsExtensionSupported(OSAL_GL_ARB_TEXTURE_ENV_ADD) || pcontext->IsExtensionSupported("GL_EXT_texture_env_add") )75{76m_bSupportAdd = true;77}7879if( pcontext->IsExtensionSupported("GL_EXT_blend_subtract") )80{81m_bSupportSubtract = true;82}8384return true;85}8687void COGLColorCombiner::DisableCombiner(void)88{89m_pOGLRender->DisableMultiTexture();90glEnable(GL_BLEND);91OPENGL_CHECK_ERRORS;92glBlendFunc(GL_ONE, GL_ZERO);93OPENGL_CHECK_ERRORS;9495if( m_bTexelsEnable )96{97COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;98if( pTexture )99{100m_pOGLRender->EnableTexUnit(0,TRUE);101m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);102glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);103OPENGL_CHECK_ERRORS;104m_pOGLRender->SetAllTexelRepeatFlag();105}106#ifdef DEBUGGER107else108{109DebuggerAppendMsg("Check me, texture is NULL but it is enabled");110}111#endif112}113else114{115glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);116OPENGL_CHECK_ERRORS;117m_pOGLRender->EnableTexUnit(0,FALSE);118}119}120121void COGLColorCombiner::InitCombinerCycleCopy(void)122{123m_pOGLRender->DisableMultiTexture();124m_pOGLRender->EnableTexUnit(0,TRUE);125COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;126if( pTexture )127{128m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);129m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile);130}131#ifdef DEBUGGER132else133{134DebuggerAppendMsg("Check me, texture is NULL");135}136#endif137138glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);139OPENGL_CHECK_ERRORS;140}141142void COGLColorCombiner::InitCombinerCycleFill(void)143{144m_pOGLRender->DisableMultiTexture();145m_pOGLRender->EnableTexUnit(0,FALSE);146}147148149void COGLColorCombiner::InitCombinerCycle12(void)150{151m_pOGLRender->DisableMultiTexture();152if( !m_bTexelsEnable )153{154glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);155OPENGL_CHECK_ERRORS;156m_pOGLRender->EnableTexUnit(0,FALSE);157return;158}159160#if SDL_VIDEO_OPENGL161uint32 mask = 0x1f;162COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;163if( pTexture )164{165m_pOGLRender->EnableTexUnit(0,TRUE);166m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);167m_pOGLRender->SetAllTexelRepeatFlag();168}169#ifdef DEBUGGER170else171{172DebuggerAppendMsg("Check me, texture is NULL");173}174#endif175176bool texIsUsed = m_pDecodedMux->isUsed(MUX_TEXEL0);177bool shadeIsUsedInColor = m_pDecodedMux->isUsedInCycle(MUX_SHADE, 0, COLOR_CHANNEL);178bool texIsUsedInColor = m_pDecodedMux->isUsedInCycle(MUX_TEXEL0, 0, COLOR_CHANNEL);179180if( texIsUsed )181{182// Parse the simplified the mux, because the OGL 1.1 combiner function is so much183// limited, we only parse the 1st N64 combiner setting and only the RGB part184185N64CombinerType & comb = m_pDecodedMux->m_n64Combiners[0];186switch( m_pDecodedMux->mType )187{188case CM_FMT_TYPE_NOT_USED:189case CM_FMT_TYPE_D: // = A190glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);191OPENGL_CHECK_ERRORS;192break;193case CM_FMT_TYPE_A_ADD_D: // = A+D194if( shadeIsUsedInColor && texIsUsedInColor )195{196if( m_bSupportAdd )197glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);198else199glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);200}201else if( texIsUsedInColor )202{203glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);204}205else206glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);207OPENGL_CHECK_ERRORS;208break;209case CM_FMT_TYPE_A_SUB_B: // = A-B210if( shadeIsUsedInColor && texIsUsedInColor )211{212if( m_bSupportSubtract )213glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SUBTRACT_ARB);214else215glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);216}217else if( texIsUsedInColor )218{219glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);220}221else222glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);223OPENGL_CHECK_ERRORS;224break;225case CM_FMT_TYPE_A_MOD_C: // = A*C226case CM_FMT_TYPE_A_MOD_C_ADD_D: // = A*C+D227if( shadeIsUsedInColor && texIsUsedInColor )228{229if( ((comb.c & mask) == MUX_SHADE && !(comb.c&MUX_COMPLEMENT)) ||230((comb.a & mask) == MUX_SHADE && !(comb.a&MUX_COMPLEMENT)) )231glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);232else233glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);234}235else if( texIsUsedInColor )236{237glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);238}239else240glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);241OPENGL_CHECK_ERRORS;242break;243case CM_FMT_TYPE_A_LERP_B_C: // = A*C+D244if( (comb.b&mask) == MUX_SHADE && (comb.c&mask)==MUX_TEXEL0 && ((comb.a&mask)==MUX_PRIM||(comb.a&mask)==MUX_ENV))245{246float *fv;247if( (comb.a&mask)==MUX_PRIM )248{249fv = GetPrimitiveColorfv();250}251else252{253fv = GetEnvColorfv();254}255256glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);257OPENGL_CHECK_ERRORS;258glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);259OPENGL_CHECK_ERRORS;260break;261}262default: // = (A-B)*C+D263if( shadeIsUsedInColor )264{265if( ((comb.c & mask) == MUX_SHADE && !(comb.c&MUX_COMPLEMENT)) ||266((comb.a & mask) == MUX_SHADE && !(comb.a&MUX_COMPLEMENT)) )267glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);268else269glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);270}271else272{273glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);274}275OPENGL_CHECK_ERRORS;276break;277}278}279else280{281glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);282OPENGL_CHECK_ERRORS;283}284#endif285}286287void COGLBlender::NormalAlphaBlender(void)288{289glEnable(GL_BLEND);290OPENGL_CHECK_ERRORS;291glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);292OPENGL_CHECK_ERRORS;293}294295void COGLBlender::DisableAlphaBlender(void)296{297glEnable(GL_BLEND);298OPENGL_CHECK_ERRORS;299glBlendFunc(GL_ONE, GL_ZERO);300OPENGL_CHECK_ERRORS;301}302303304void COGLBlender::BlendFunc(uint32 srcFunc, uint32 desFunc)305{306glBlendFunc(DirectX_OGL_BlendFuncMaps[srcFunc], DirectX_OGL_BlendFuncMaps[desFunc]);307OPENGL_CHECK_ERRORS;308}309310void COGLBlender::Enable()311{312glEnable(GL_BLEND);313OPENGL_CHECK_ERRORS;314}315316void COGLBlender::Disable()317{318glDisable(GL_BLEND);319OPENGL_CHECK_ERRORS;320}321322void COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)323{324m_pOGLRender->DisableMultiTexture();325if( g_textures[tile].m_pCTexture )326{327m_pOGLRender->EnableTexUnit(0,TRUE);328glBindTexture(GL_TEXTURE_2D, ((COGLTexture*)(g_textures[tile].m_pCTexture))->m_dwTextureName);329OPENGL_CHECK_ERRORS;330}331m_pOGLRender->SetAllTexelRepeatFlag();332333glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);334OPENGL_CHECK_ERRORS;335glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);336OPENGL_CHECK_ERRORS;337glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering338OPENGL_CHECK_ERRORS;339glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering340OPENGL_CHECK_ERRORS;341342glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);343OPENGL_CHECK_ERRORS;344m_pOGLRender->SetAlphaTestEnable(FALSE);345}346347#ifdef DEBUGGER348extern const char *translatedCombTypes[];349void COGLColorCombiner::DisplaySimpleMuxString(void)350{351TRACE0("\nSimplified Mux\n");352m_pDecodedMux->DisplaySimpliedMuxString("Used");353}354#endif355356357358