Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-rice/src/OGLCombiner.cpp
2 views
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
* Mupen64plus - OGLCombiner.cpp *
3
* Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4
* Copyright (C) 2003 Rice1964 *
5
* *
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. *
10
* *
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. *
15
* *
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22
#include "osal_opengl.h"
23
24
#include "OGLCombiner.h"
25
#include "OGLDebug.h"
26
#include "OGLRender.h"
27
#include "OGLGraphicsContext.h"
28
#include "OGLDecodedMux.h"
29
#include "OGLTexture.h"
30
31
//========================================================================
32
uint32 DirectX_OGL_BlendFuncMaps [] =
33
{
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,
48
};
49
50
//========================================================================
51
COGLColorCombiner::COGLColorCombiner(CRender *pRender) :
52
CColorCombiner(pRender),
53
m_pOGLRender((OGLRender*)pRender),
54
m_bSupportAdd(false), m_bSupportSubtract(false)
55
{
56
m_pDecodedMux = new COGLDecodedMux;
57
m_pDecodedMux->m_maxConstants = 0;
58
m_pDecodedMux->m_maxTextures = 1;
59
}
60
61
COGLColorCombiner::~COGLColorCombiner()
62
{
63
delete m_pDecodedMux;
64
m_pDecodedMux = NULL;
65
}
66
67
bool COGLColorCombiner::Initialize(void)
68
{
69
m_bSupportAdd = false;
70
m_bSupportSubtract = false;
71
m_supportedStages = 1;
72
m_bSupportMultiTexture = false;
73
74
COGLGraphicsContext *pcontext = (COGLGraphicsContext *)(CGraphicsContext::g_pGraphicsContext);
75
if( pcontext->IsExtensionSupported(OSAL_GL_ARB_TEXTURE_ENV_ADD) || pcontext->IsExtensionSupported("GL_EXT_texture_env_add") )
76
{
77
m_bSupportAdd = true;
78
}
79
80
if( pcontext->IsExtensionSupported("GL_EXT_blend_subtract") )
81
{
82
m_bSupportSubtract = true;
83
}
84
85
return true;
86
}
87
88
void COGLColorCombiner::DisableCombiner(void)
89
{
90
m_pOGLRender->DisableMultiTexture();
91
glEnable(GL_BLEND);
92
OPENGL_CHECK_ERRORS;
93
glBlendFunc(GL_ONE, GL_ZERO);
94
OPENGL_CHECK_ERRORS;
95
96
if( m_bTexelsEnable )
97
{
98
COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
99
if( pTexture )
100
{
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);
104
OPENGL_CHECK_ERRORS;
105
m_pOGLRender->SetAllTexelRepeatFlag();
106
}
107
#ifdef DEBUGGER
108
else
109
{
110
DebuggerAppendMsg("Check me, texture is NULL but it is enabled");
111
}
112
#endif
113
}
114
else
115
{
116
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
117
OPENGL_CHECK_ERRORS;
118
m_pOGLRender->EnableTexUnit(0,FALSE);
119
}
120
}
121
122
void COGLColorCombiner::InitCombinerCycleCopy(void)
123
{
124
m_pOGLRender->DisableMultiTexture();
125
m_pOGLRender->EnableTexUnit(0,TRUE);
126
COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
127
if( pTexture )
128
{
129
m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
130
m_pOGLRender->SetTexelRepeatFlags(gRSP.curTile);
131
}
132
#ifdef DEBUGGER
133
else
134
{
135
DebuggerAppendMsg("Check me, texture is NULL");
136
}
137
#endif
138
139
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
140
OPENGL_CHECK_ERRORS;
141
}
142
143
void COGLColorCombiner::InitCombinerCycleFill(void)
144
{
145
m_pOGLRender->DisableMultiTexture();
146
m_pOGLRender->EnableTexUnit(0,FALSE);
147
}
148
149
150
void COGLColorCombiner::InitCombinerCycle12(void)
151
{
152
m_pOGLRender->DisableMultiTexture();
153
if( !m_bTexelsEnable )
154
{
155
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
156
OPENGL_CHECK_ERRORS;
157
m_pOGLRender->EnableTexUnit(0,FALSE);
158
return;
159
}
160
161
#if SDL_VIDEO_OPENGL
162
uint32 mask = 0x1f;
163
COGLTexture* pTexture = g_textures[gRSP.curTile].m_pCOGLTexture;
164
if( pTexture )
165
{
166
m_pOGLRender->EnableTexUnit(0,TRUE);
167
m_pOGLRender->BindTexture(pTexture->m_dwTextureName, 0);
168
m_pOGLRender->SetAllTexelRepeatFlag();
169
}
170
#ifdef DEBUGGER
171
else
172
{
173
DebuggerAppendMsg("Check me, texture is NULL");
174
}
175
#endif
176
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);
180
181
if( texIsUsed )
182
{
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
185
186
N64CombinerType & comb = m_pDecodedMux->m_n64Combiners[0];
187
switch( m_pDecodedMux->mType )
188
{
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);
192
OPENGL_CHECK_ERRORS;
193
break;
194
case CM_FMT_TYPE_A_ADD_D: // = A+D
195
if( shadeIsUsedInColor && texIsUsedInColor )
196
{
197
if( m_bSupportAdd )
198
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
199
else
200
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
201
}
202
else if( texIsUsedInColor )
203
{
204
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
205
}
206
else
207
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
208
OPENGL_CHECK_ERRORS;
209
break;
210
case CM_FMT_TYPE_A_SUB_B: // = A-B
211
if( shadeIsUsedInColor && texIsUsedInColor )
212
{
213
if( m_bSupportSubtract )
214
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_SUBTRACT_ARB);
215
else
216
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
217
}
218
else if( texIsUsedInColor )
219
{
220
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
221
}
222
else
223
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
224
OPENGL_CHECK_ERRORS;
225
break;
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 )
229
{
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);
233
else
234
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
235
}
236
else if( texIsUsedInColor )
237
{
238
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
239
}
240
else
241
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
242
OPENGL_CHECK_ERRORS;
243
break;
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))
246
{
247
float *fv;
248
if( (comb.a&mask)==MUX_PRIM )
249
{
250
fv = GetPrimitiveColorfv();
251
}
252
else
253
{
254
fv = GetEnvColorfv();
255
}
256
257
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,fv);
258
OPENGL_CHECK_ERRORS;
259
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
260
OPENGL_CHECK_ERRORS;
261
break;
262
}
263
default: // = (A-B)*C+D
264
if( shadeIsUsedInColor )
265
{
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);
269
else
270
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
271
}
272
else
273
{
274
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
275
}
276
OPENGL_CHECK_ERRORS;
277
break;
278
}
279
}
280
else
281
{
282
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
283
OPENGL_CHECK_ERRORS;
284
}
285
#endif
286
}
287
288
void COGLBlender::NormalAlphaBlender(void)
289
{
290
glEnable(GL_BLEND);
291
OPENGL_CHECK_ERRORS;
292
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
293
OPENGL_CHECK_ERRORS;
294
}
295
296
void COGLBlender::DisableAlphaBlender(void)
297
{
298
glEnable(GL_BLEND);
299
OPENGL_CHECK_ERRORS;
300
glBlendFunc(GL_ONE, GL_ZERO);
301
OPENGL_CHECK_ERRORS;
302
}
303
304
305
void COGLBlender::BlendFunc(uint32 srcFunc, uint32 desFunc)
306
{
307
glBlendFunc(DirectX_OGL_BlendFuncMaps[srcFunc], DirectX_OGL_BlendFuncMaps[desFunc]);
308
OPENGL_CHECK_ERRORS;
309
}
310
311
void COGLBlender::Enable()
312
{
313
glEnable(GL_BLEND);
314
OPENGL_CHECK_ERRORS;
315
}
316
317
void COGLBlender::Disable()
318
{
319
glDisable(GL_BLEND);
320
OPENGL_CHECK_ERRORS;
321
}
322
323
void COGLColorCombiner::InitCombinerBlenderForSimpleTextureDraw(uint32 tile)
324
{
325
m_pOGLRender->DisableMultiTexture();
326
if( g_textures[tile].m_pCTexture )
327
{
328
m_pOGLRender->EnableTexUnit(0,TRUE);
329
glBindTexture(GL_TEXTURE_2D, ((COGLTexture*)(g_textures[tile].m_pCTexture))->m_dwTextureName);
330
OPENGL_CHECK_ERRORS;
331
}
332
m_pOGLRender->SetAllTexelRepeatFlag();
333
334
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
335
OPENGL_CHECK_ERRORS;
336
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
337
OPENGL_CHECK_ERRORS;
338
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // Linear Filtering
339
OPENGL_CHECK_ERRORS;
340
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // Linear Filtering
341
OPENGL_CHECK_ERRORS;
342
343
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
344
OPENGL_CHECK_ERRORS;
345
m_pOGLRender->SetAlphaTestEnable(FALSE);
346
}
347
348
#ifdef DEBUGGER
349
extern const char *translatedCombTypes[];
350
void COGLColorCombiner::DisplaySimpleMuxString(void)
351
{
352
TRACE0("\nSimplified Mux\n");
353
m_pDecodedMux->DisplaySimpliedMuxString("Used");
354
}
355
#endif
356
357
358