1 /******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *****************************************************************************/
22 #include "SimpleTexEnvCombiner.h"
23 #include "CombinerStructs.h"
24 #include "MultiTexturingExt.h"
25 #include "ExtensionChecker.h"
29 //-----------------------------------------------------------------------------
31 //-----------------------------------------------------------------------------
32 SimpleTexEnvCombiner::SimpleTexEnvCombiner()
36 //-----------------------------------------------------------------------------
38 //-----------------------------------------------------------------------------
39 SimpleTexEnvCombiner::~SimpleTexEnvCombiner()
43 //-----------------------------------------------------------------------------
45 //! Checks if multitexturing is supported
46 //-----------------------------------------------------------------------------
47 void SimpleTexEnvCombiner::initialize()
49 ARB_multitexture = isExtensionSupported("GL_ARB_multitexture");
52 //-----------------------------------------------------------------------------
53 //* Begin Texture Update
54 //! Called before texture channels are updated on the RDP
55 //-----------------------------------------------------------------------------
56 void SimpleTexEnvCombiner::beginTextureUpdate()
61 //-----------------------------------------------------------------------------
62 //* End Texture Update
63 //! Called after texture channels are updated on the RDP
64 //! @param[in] texEnv Texture Environment
65 //-----------------------------------------------------------------------------
66 void SimpleTexEnvCombiner::endTextureUpdate(TexEnvCombiner* texEnv)
71 //-----------------------------------------------------------------------------
72 //! Set Texture Envirorment Colors
73 //! @param[in] texEnv Texture Environment
74 //-----------------------------------------------------------------------------
75 void SimpleTexEnvCombiner::setTextureEnviromentColors(TexEnvCombiner* texEnv)
80 //-----------------------------------------------------------------------------
81 //* Set Texture Environment
82 //! Enables texturing and sets texture environment in OpenGL
83 //! @param[in] texEnv Texture Environment
84 //-----------------------------------------------------------------------------
85 void SimpleTexEnvCombiner::setTextureEnviroment(TexEnvCombiner* texEnv)
87 if ( ARB_multitexture )
88 glActiveTextureARB( GL_TEXTURE0_ARB );
90 if (texEnv->usesT0 || texEnv->usesT1)
91 glEnable( GL_TEXTURE_2D );
93 glDisable( GL_TEXTURE_2D );
96 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texEnv->mode);
99 //-----------------------------------------------------------------------------
100 //* Create New Texture Enviornment
101 //! Allocates a new texture enviroment
102 //! @param[in] colorCombiner How to combine and get a color
103 //! @param[in] alphaCombiner How to combine and get an alpha value
104 //! @return The texture enviroment that was created
105 //-----------------------------------------------------------------------------
106 TexEnvCombiner* SimpleTexEnvCombiner::createNewTextureEnviroment(Combiner* colorCombiner, Combiner *alphaCombiner)
108 TexEnvCombiner* texEnv = new TexEnvCombiner();
110 bool m_usesTexture0 = false;
111 bool m_usesTexture1 = false;
112 int mode = GL_REPLACE;
113 unsigned short m_color = COMBINED;
114 unsigned short m_alpha = COMBINED;
116 //For each stage in alpha combiner
117 for (int i = 0; i < alphaCombiner->numStages; i++)
119 //For each operation in stage
120 for (int j = 0; j < alphaCombiner->stage[i].numOps; j++)
122 CombinerOp* op = &alphaCombiner->stage[i].op[j];
125 switch ( alphaCombiner->stage[i].op[j].op )
128 if ( op->param1 != TEXEL0_ALPHA && op->param1 != TEXEL1_ALPHA )
130 m_alpha = op->param1;
131 m_usesTexture0 = false;
132 m_usesTexture1 = false;
137 m_usesTexture0 = op->param1 == TEXEL0_ALPHA;
138 m_usesTexture1 = op->param1 == TEXEL1_ALPHA;
142 CombinerOp* prevOp = &alphaCombiner->stage[i].op[j-1];
144 if (((op->param1 == TEXEL0_ALPHA) || (op->param1 == TEXEL1_ALPHA)) &&
145 ((prevOp->param1 != TEXEL0_ALPHA) || (prevOp->param1 != TEXEL1_ALPHA)))
149 else if ( ( op->param1 != TEXEL0_ALPHA || op->param1 != TEXEL1_ALPHA) &&
150 (prevOp->param1 == TEXEL0_ALPHA || prevOp->param1 == TEXEL1_ALPHA) )
152 m_alpha = op->param1;
162 //For each stage in colorCombiner
163 for (int i = 0; i < colorCombiner->numStages; i++)
165 for (int j = 0; j < colorCombiner->stage[i].numOps; j++)
167 CombinerOp* op = &colorCombiner->stage[i].op[j];
169 switch ( colorCombiner->stage[i].op[j].op )
172 if (op->param1 == TEXEL0 || op->param1 == TEXEL0_ALPHA)
174 if ( mode == GL_MODULATE )
177 m_usesTexture0 = true;
178 m_usesTexture1 = false;
180 else if ( op->param1 == TEXEL1 || op->param1 == TEXEL1_ALPHA )
182 if ( mode == GL_MODULATE )
185 m_usesTexture0 = false;
186 m_usesTexture1 = true;
190 m_color = op->param1;
191 m_usesTexture0 = m_usesTexture1 = false;
195 if ( op->param1 == TEXEL0 || op->param1 == TEXEL0_ALPHA )
197 if (!m_usesTexture0 && !m_usesTexture1)
200 m_usesTexture0 = true;
201 m_usesTexture1 = false;
204 else if ( op->param1 == TEXEL1 || op->param1 == TEXEL1_ALPHA )
206 if (!m_usesTexture0 && !m_usesTexture1)
209 m_usesTexture0 = false;
210 m_usesTexture1 = true;
213 else if ( m_usesTexture0 || m_usesTexture1 )
216 m_color = op->param1;
220 if ((op->param1 == TEXEL0) &&
221 ((op->param2 != TEXEL0) && (op->param2 != TEXEL0_ALPHA) &&
222 (op->param2 != TEXEL1) && (op->param2 != TEXEL1_ALPHA)) &&
223 (op->param3 == TEXEL0_ALPHA))
226 m_color = op->param2;
227 m_usesTexture0 = true;
228 m_usesTexture1 = false;
230 else if ((op->param1 == TEXEL0) &&
231 ((op->param2 != TEXEL0) && (op->param2 != TEXEL0_ALPHA) &&
232 (op->param2 != TEXEL1) && (op->param2 != TEXEL1_ALPHA)) &&
233 (op->param3 == TEXEL0_ALPHA))
236 m_color = op->param2;
237 m_usesTexture0 = false;
238 m_usesTexture1 = true;
245 texEnv->usesT0 = m_usesTexture0;
246 texEnv->usesT1 = m_usesTexture1;
248 texEnv->vertex.color = m_color;
249 texEnv->vertex.alpha = m_alpha;