Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-z64/src/rgl_rendermode.cpp
2 views
1
/*
2
* z64
3
*
4
* Copyright (C) 2007 ziggy
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 along
17
* with this program; if not, write to the Free Software Foundation, Inc.,
18
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
**/
21
22
#include "rdp.h"
23
#include "rgl.h"
24
25
#include <SDL.h>
26
27
void rglRenderMode(rglRenderChunk_t & chunk)
28
{
29
//int i;
30
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
31
if (RDP_GETOM_CYCLE_TYPE(chunk.rdpState.otherModes) < 2) {
32
glDepthMask(RDP_GETOM_Z_UPDATE_EN(chunk.rdpState.otherModes)? GL_TRUE:GL_FALSE);
33
if (RDP_GETOM_Z_COMPARE_EN(chunk.rdpState.otherModes))
34
glDepthFunc(GL_LESS);
35
else
36
glDepthFunc(GL_ALWAYS);
37
} else {
38
glDepthMask(GL_FALSE);
39
glDepthFunc(GL_ALWAYS);
40
}
41
42
43
// if (RDP_GETOM_Z_MODE(chunk.rdpState.otherModes) & 1) {
44
// glEnable( GL_POLYGON_OFFSET_FILL );
45
// switch(RDP_GETOM_Z_MODE(chunk.rdpState.otherModes)) {
46
// case 3:
47
// glPolygonOffset( -3, -300 );
48
// break;
49
// default:
50
// // FIXME tune this value
51
// //glPolygonOffset( -3.0f, -3.0f );
52
// glPolygonOffset( -3, -40 );
53
// break;
54
// }
55
// //glDepthMask(GL_FALSE);
56
// } else {
57
// glDisable( GL_POLYGON_OFFSET_FILL );
58
// }
59
}
60
61
62
63
struct rglCombiner_t {
64
rdpCombineModes_t combineModes;
65
rdpOtherModes_t otherModes;
66
rglShader_t * shader;
67
#ifndef RGL_EXACT_BLEND
68
GLuint srcBlend, dstBlend;
69
#endif
70
int format;
71
};
72
#define RGL_MAX_COMBINERS 128
73
static int rglNbCombiners;
74
static rglCombiner_t rglCombiners[RGL_MAX_COMBINERS];
75
76
void rglClearCombiners()
77
{
78
int i;
79
for (i=0; i<rglNbCombiners; i++)
80
rglDeleteShader(rglCombiners[i].shader);
81
rglNbCombiners = 0;
82
}
83
84
85
int rglT1Usage(rdpState_t & state)
86
{
87
//return 1;
88
int cycle = RDP_GETOM_CYCLE_TYPE(state.otherModes);
89
if (cycle == RDP_CYCLE_TYPE_COPY) return 1;
90
if (cycle >= 2) return 0;
91
if (cycle == 1 && (
92
RDP_GETCM_SUB_A_RGB1(state.combineModes)==2 ||
93
RDP_GETCM_SUB_B_RGB1(state.combineModes)==2 ||
94
RDP_GETCM_MUL_RGB1(state.combineModes)==2 ||
95
RDP_GETCM_MUL_RGB1(state.combineModes)==9 ||
96
RDP_GETCM_ADD_RGB1(state.combineModes)==2 ||
97
RDP_GETCM_SUB_A_A1(state.combineModes)==2 ||
98
RDP_GETCM_SUB_B_A1(state.combineModes)==2 ||
99
RDP_GETCM_MUL_A1(state.combineModes)==2 ||
100
RDP_GETCM_ADD_A1(state.combineModes)==2))
101
return 1;
102
if (
103
(RDP_GETOM_CVG_TIMES_ALPHA(state.otherModes) &&
104
!RDP_GETOM_ALPHA_CVG_SELECT(state.otherModes)) ||
105
106
RDP_GETCM_SUB_A_RGB0(state.combineModes)==1 ||
107
RDP_GETCM_SUB_B_RGB0(state.combineModes)==1 ||
108
RDP_GETCM_MUL_RGB0(state.combineModes)==1 ||
109
RDP_GETCM_MUL_RGB0(state.combineModes)==8 ||
110
RDP_GETCM_ADD_RGB0(state.combineModes)==1 ||
111
RDP_GETCM_SUB_A_A0(state.combineModes)==1 ||
112
RDP_GETCM_SUB_B_A0(state.combineModes)==1 ||
113
RDP_GETCM_MUL_A0(state.combineModes)==1 ||
114
RDP_GETCM_ADD_A0(state.combineModes)==1)
115
116
return 1;
117
118
return 0;
119
}
120
int rglT2Usage(rdpState_t & state)
121
{
122
//return 1;
123
int cycle = RDP_GETOM_CYCLE_TYPE(state.otherModes);
124
if (cycle >= 2) return 0;
125
if (cycle == 1 && (
126
RDP_GETCM_SUB_A_RGB1(state.combineModes)==1 ||
127
RDP_GETCM_SUB_B_RGB1(state.combineModes)==1 ||
128
RDP_GETCM_MUL_RGB1(state.combineModes)==1 ||
129
RDP_GETCM_MUL_RGB1(state.combineModes)==8 ||
130
RDP_GETCM_ADD_RGB1(state.combineModes)==1 ||
131
RDP_GETCM_SUB_A_A1(state.combineModes)==1 ||
132
RDP_GETCM_SUB_B_A1(state.combineModes)==1 ||
133
RDP_GETCM_MUL_A1(state.combineModes)==1 ||
134
RDP_GETCM_ADD_A1(state.combineModes)==1))
135
return 1;
136
137
if (
138
RDP_GETCM_SUB_A_RGB0(state.combineModes)==2 ||
139
RDP_GETCM_SUB_B_RGB0(state.combineModes)==2 ||
140
RDP_GETCM_MUL_RGB0(state.combineModes)==2 ||
141
RDP_GETCM_MUL_RGB0(state.combineModes)==9 ||
142
RDP_GETCM_ADD_RGB0(state.combineModes)==2 ||
143
RDP_GETCM_SUB_A_A0(state.combineModes)==2 ||
144
RDP_GETCM_SUB_B_A0(state.combineModes)==2 ||
145
RDP_GETCM_MUL_A0(state.combineModes)==2 ||
146
RDP_GETCM_ADD_A0(state.combineModes)==2)
147
148
return 1;
149
150
return 0;
151
}
152
153
154
void rglSetCombiner(rglRenderChunk_t & chunk, int format)
155
{
156
static char _1ma[64];
157
static char t1[64];
158
static char t1a[64];
159
static char t2[64];
160
static char t2a[64];
161
static char prim_lod_frac[64];
162
163
static const char *saRGB[] = {
164
"c", t1, t2, "p/*PRIM*/",
165
"gl_Color", "e", "1.0/*NOISE*/", "1.0",
166
"0.0", "0.0", "0.0", "0.0",
167
"0.0", "0.0", "0.0", "0.0"
168
};
169
170
static const char *mRGB[] = {
171
"c", t1, t2, "p/*PRIM*/",
172
"gl_Color/*SHADE*/","e", "0.0/*SCALE*/", "c.a/*COMBINED_A*/",
173
"t1.a/*TEXEL0_A*/", "t2.a/*TEXEL1_A*/", "p.a/*PRIM_A*/", "gl_Color.a/*SHADEA*/",
174
"e.a/*ENV_ALPHA*/", "0.5/*LOD_FRACTION*/","0.5/*PRIM_LOD_FRAC*/","k5/*K5*/",
175
"0.0", "0.0", "0.0", "0.0",
176
"0.0", "0.0", "0.0", "0.0",
177
"0.0", "0.0", "0.0", "0.0",
178
"0.0", "0.0", "0.0", "0.0"
179
};
180
181
static const char *aRGB[] = {
182
"c", t1, t2, "p/*PRIM*/",
183
"gl_Color/*SHADE*/","e/*ENV*/", "1.0", "0.0",
184
};
185
186
static const char *saA[] = {
187
"c.a", t1a, t2a, "p.a/*PRIM*/",
188
"gl_Color.a", "e.a", "1.0", "0.0",
189
};
190
191
static const char *sbA[] = {
192
"c.a", t1a, t2a, "p.a/*PRIM*/",
193
"gl_Color.a", "e.a", "1.0", "0.0",
194
};
195
196
static const char *mA[] = {
197
"0.5/*LOD_FRACTION*/", t1a, t2a, "p.a/*PRIM*/",
198
"gl_Color.a/*SHADE*/", "e.a", prim_lod_frac, "0.0",
199
};
200
201
static const char *aA[] = {
202
"c.a", t1a, t2a, "p.a/*PRIM*/",
203
"gl_Color.a/*SHADE*/", "e.a", "1.0", "0.0",
204
};
205
206
const static char * bRGB[] =
207
{ "c/*PREV*/", "f", "b", "fog/*FOG*/" };
208
const static char * bA[2][4] =
209
{ {"c.a/*PREVA*/", "fog.a/*FOGA*/", "gl_Color.a/*SHADEA*/", "0.0/*ZERO*/"},
210
{_1ma/*"(1.0-c.a/ *PREVA)"*/, "0.0/*f.a*//*FRAGA*/", "1.0", "0.0"}}; // need clamping on 1-alpha ?
211
212
213
rdpState_t & state = chunk.rdpState;
214
static rglCombiner_t * c;
215
uint32_t cycle = RDP_GETOM_CYCLE_TYPE(state.otherModes);
216
int i; //, fmt, size;
217
char * p;
218
const char * alphaTest;
219
const char * alphaTest2;
220
const char * write;
221
static char src[4*4096];
222
223
float env[4];
224
env[0] = RDP_GETC32_R(state.envColor)/255.0f;
225
env[1] = RDP_GETC32_G(state.envColor)/255.0f;
226
env[2] = RDP_GETC32_B(state.envColor)/255.0f;
227
env[3] = RDP_GETC32_A(state.envColor)/255.0f;
228
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env);
229
230
env[0] = RDP_GETC32_R(state.blendColor)/255.0f;
231
env[1] = RDP_GETC32_G(state.blendColor)/255.0f;
232
env[2] = RDP_GETC32_B(state.blendColor)/255.0f;
233
env[3] = RDP_GETC32_A(state.blendColor)/255.0f;
234
glLightfv(GL_LIGHT0, GL_AMBIENT, env);
235
236
env[0] = RDP_GETC32_R(state.fogColor)/255.0f;
237
env[1] = RDP_GETC32_G(state.fogColor)/255.0f;
238
env[2] = RDP_GETC32_B(state.fogColor)/255.0f;
239
env[3] = RDP_GETC32_A(state.fogColor)/255.0f;
240
glLightfv(GL_LIGHT0, GL_DIFFUSE, env);
241
242
glActiveTextureARB(GL_TEXTURE1_ARB);
243
env[0] = state.k5/255.0f;
244
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env);
245
if (cycle == RDP_CYCLE_TYPE_FILL) {
246
if (0/*fb_size == 3*/) { // FIXME
247
env[0] = RDP_GETC32_R(state.fillColor)/255.0f;
248
env[1] = RDP_GETC32_G(state.fillColor)/255.0f;
249
env[2] = RDP_GETC32_B(state.fillColor)/255.0f;
250
env[3] = RDP_GETC32_A(state.fillColor)/255.0f;
251
} else {
252
env[0] = RDP_GETC16_R(state.fillColor)/31.0f;
253
env[1] = RDP_GETC16_G(state.fillColor)/31.0f;
254
env[2] = RDP_GETC16_B(state.fillColor)/31.0f;
255
env[3] = RDP_GETC16_A(state.fillColor);
256
}
257
} else {
258
env[0] = RDP_GETC32_R(state.primColor)/255.0f;
259
env[1] = RDP_GETC32_G(state.primColor)/255.0f;
260
env[2] = RDP_GETC32_B(state.primColor)/255.0f;
261
env[3] = RDP_GETC32_A(state.primColor)/255.0f;
262
}
263
glLightfv(GL_LIGHT0, GL_SPECULAR, env);
264
glActiveTextureARB(GL_TEXTURE0_ARB);
265
rglAssert(glGetError() == GL_NO_ERROR);
266
267
// if (c && rglNbCombiners &&
268
// RDP_GETOM_CYCLE_TYPE(c->otherModes) == cycle &&
269
// (RDP_GETOM_CYCLE_TYPE(c->otherModes) >= 2 ||
270
// (!memcmp(&c->combineModes, &state.combineModes, sizeof(rdpCombineModes_t)) &&
271
// !memcmp(&c->otherModes, &state.otherModes, sizeof(rdpOtherModes_t))))) {
272
// return;
273
// }
274
275
for (i=0; i<rglNbCombiners; i++) {
276
c = rglCombiners + i;
277
if (c->format == format &&
278
RDP_GETOM_CYCLE_TYPE(c->otherModes) == cycle &&
279
(RDP_GETOM_CYCLE_TYPE(c->otherModes) >= 2 ||
280
(!memcmp(&c->combineModes, &state.combineModes, sizeof(rdpCombineModes_t))
281
&& !memcmp(&c->otherModes, &state.otherModes, sizeof(rdpOtherModes_t))
282
))) {
283
#ifdef RDP_DEBUG
284
chunk.shader = c->shader;
285
#endif
286
rglUseShader(c->shader);
287
goto ok;
288
}
289
}
290
291
if (rglNbCombiners == RGL_MAX_COMBINERS)
292
rglClearCombiners();
293
294
c = rglCombiners + rglNbCombiners++;
295
c->otherModes = state.otherModes;
296
c->combineModes = state.combineModes;
297
c->format = format;
298
#ifndef RGL_EXACT_BLEND
299
c->srcBlend = GL_ONE;
300
c->dstBlend = GL_ZERO;
301
#endif
302
303
switch (format & RGL_COMB_FMT) {
304
case RGL_COMB_FMT_RGBA:
305
write = "gl_FragColor = c;";
306
break;
307
case RGL_COMB_FMT_I:
308
write = "gl_FragColor = vec4(c[0]);";
309
break;
310
case RGL_COMB_FMT_DEPTH:
311
write = "gl_FragDepth = c[0];";
312
break;
313
}
314
315
if (cycle == RDP_CYCLE_TYPE_FILL) {
316
sprintf(
317
src,
318
"void main() \n"
319
"{ \n"
320
//" c = gl_TextureEnvColor[1];\n"
321
" vec4 c = gl_LightSource[0].specular;\n"
322
" %s\n"
323
"} \n",
324
write);
325
c->shader = rglCreateShader(
326
"void main() \n"
327
"{ \n"
328
" gl_Position = ftransform(); \n"
329
" gl_FrontColor = gl_Color; \n"
330
" gl_BackColor = gl_Color; \n"
331
" gl_TexCoord[0] = gl_MultiTexCoord0; \n"
332
"} \n"
333
,
334
src
335
);
336
#ifdef RDP_DEBUG
337
chunk.shader = c->shader;
338
#endif
339
rglUseShader(c->shader);
340
goto ok;
341
}
342
343
alphaTest = "";
344
alphaTest2 = "";
345
346
if (//cycle < 2 && // CHECK THIS
347
RDP_GETOM_CVG_TIMES_ALPHA(chunk.rdpState.otherModes)
348
//&& rglT1Usage(chunk.rdpState)
349
) {
350
if (RDP_GETOM_ALPHA_CVG_SELECT(chunk.rdpState.otherModes))
351
alphaTest = "if (c.a < 0.5) discard; \n";
352
else
353
alphaTest = "if (t1.a < 0.5) discard; \n";
354
alphaTest2 = "if (c.a < 0.5) discard; \n";
355
}
356
else if (RDP_GETOM_ALPHA_COMPARE_EN(chunk.rdpState.otherModes) &&
357
!RDP_GETOM_ALPHA_CVG_SELECT(chunk.rdpState.otherModes)) {
358
if (RDP_GETC32_A(chunk.rdpState.blendColor) > 0) {
359
alphaTest = "if (c.a < b.a) discard; \n";
360
alphaTest2 =
361
" vec4 b = gl_LightSource[0].ambient; \n"
362
" if (c.a < b.a) discard; \n";
363
//alphaTest2 = "if (c.a < 0.5) discard; \n";
364
} else {
365
alphaTest = "if (c.a == 0.0) discard; \n";
366
alphaTest2 = "if (c.a == 0.0) discard; \n";
367
}
368
}
369
370
if (cycle == RDP_CYCLE_TYPE_COPY) {
371
sprintf(
372
src,
373
"uniform sampler2D texture0; \n"
374
" \n"
375
"void main() \n"
376
"{ \n"
377
" vec4 c = texture2D(texture0, vec2(gl_TexCoord[0])); \n"
378
" %s"
379
" %s\n"
380
"} \n",
381
alphaTest2,
382
write
383
);
384
c->shader = rglCreateShader(
385
"void main() \n"
386
"{ \n"
387
" gl_Position = ftransform(); \n"
388
" gl_FrontColor = gl_Color; \n"
389
" gl_BackColor = gl_Color; \n"
390
" gl_TexCoord[0] = gl_MultiTexCoord0; \n"
391
"} \n"
392
,
393
src
394
);
395
#ifdef RDP_DEBUG
396
chunk.shader = c->shader;
397
#endif
398
rglUseShader(c->shader);
399
goto ok;
400
}
401
402
403
p = src;
404
p +=
405
sprintf(p,
406
"uniform sampler2D texture0; \n"
407
"uniform sampler2D texture2; \n"
408
#ifdef RGL_EXACT_BLEND
409
"uniform sampler2D texture1; \n"
410
#endif
411
" \n"
412
"void main() \n"
413
"{ \n"
414
"vec4 c = vec4(0,0,0,0);\n"
415
"vec4 e = gl_TextureEnvColor[0];\n"
416
"float k5 = gl_TextureEnvColor[1][0];\n"
417
"vec4 p = gl_LightSource[0].specular;\n"
418
#ifdef RGL_EXACT_BLEND
419
"vec4 f = texture2D(texture1, vec2(gl_FragCoord.x/(2048.0*gl_TexCoord[1].x), gl_FragCoord.y/(2048.0*gl_TexCoord[1].y))); \n"
420
#endif
421
"vec4 fog = gl_LightSource[0].diffuse; \n"
422
"vec4 b = gl_LightSource[0].ambient; \n");
423
424
switch (format & RGL_COMB_IN0) {
425
case 0:
426
p +=
427
sprintf(p,
428
"vec4 t1 = texture2D(texture0, vec2(gl_TexCoord[0]));\n");
429
break;
430
case RGL_COMB_IN0_DEPTH:
431
p +=
432
sprintf(p,
433
"vec4 t1 = vec4(texture2D(texture0, vec2(gl_TexCoord[0]))[0]);\n");
434
break;
435
}
436
switch (format & RGL_COMB_IN1) {
437
case 0:
438
p +=
439
sprintf(p,
440
"vec4 t2 = texture2D(texture2, vec2(gl_TexCoord[2]));\n");
441
break;
442
case RGL_COMB_IN1_DEPTH:
443
p +=
444
sprintf(p,
445
"vec4 t2 = vec4(texture2D(texture2, vec2(gl_TexCoord[2]))[0]);\n");
446
break;
447
}
448
449
const char * comb, * comb2;
450
comb2 = 0;
451
// switch (RDP_GETOM_CVG_DEST(state.otherModes))
452
// {
453
// case 3:
454
// comb = "c = clamp(vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s), 0.0, 1.0);\n";
455
// break;
456
// case 2:
457
// comb = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s);\n";
458
// //comb = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), t1.a*((%s - %s) * %s + %s));\n";
459
// break;
460
// case 0:
461
// //comb2 = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), t1.a);\n";
462
// case 1:
463
// comb = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s);\n";
464
// break;
465
// }
466
comb = "c = clamp(vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s), 0.0, 1.0);\n";
467
strcpy(prim_lod_frac, "0.5/*PRIM_LOD_FRAC*/");
468
strcpy(t1, "t1");
469
strcpy(t1a, "t1.a");
470
if (format & RGL_COMB_TILE7) {
471
strcpy(t2, "t1");
472
strcpy(t2a, "t1.a");
473
} else {
474
strcpy(t2, "t2");
475
strcpy(t2a, "t2.a");
476
}
477
p +=
478
sprintf(p,
479
comb
480
,
481
saRGB[RDP_GETCM_SUB_A_RGB0(state.combineModes)],
482
saRGB[RDP_GETCM_SUB_B_RGB0(state.combineModes)],
483
mRGB[RDP_GETCM_MUL_RGB0(state.combineModes)],
484
aRGB[RDP_GETCM_ADD_RGB0(state.combineModes)],
485
saA[RDP_GETCM_SUB_A_A0(state.combineModes)],
486
sbA[RDP_GETCM_SUB_B_A0(state.combineModes)],
487
mA[RDP_GETCM_MUL_A0(state.combineModes)],
488
aA[RDP_GETCM_ADD_A0(state.combineModes)]
489
);
490
491
if (cycle == RDP_CYCLE_TYPE_2) {
492
if (!(format & RGL_COMB_TILE7)) {
493
strcpy(t1, "t2");
494
strcpy(t1a, "t2.a");
495
strcpy(t2, "t1");
496
strcpy(t2a, "t1.a");
497
}
498
//strcpy(prim_lod_frac, "0.0/*PRIM_LOD_FRAC*/");
499
// if (!RDP_GETOM_ALPHA_CVG_SELECT(chunk.rdpState.otherModes))
500
// p +=
501
// sprintf(p, " c.a = t1.a; \n");
502
503
p +=
504
sprintf(p,
505
comb2? comb2 : comb
506
,
507
saRGB[RDP_GETCM_SUB_A_RGB1(state.combineModes)],
508
saRGB[RDP_GETCM_SUB_B_RGB1(state.combineModes)],
509
mRGB[RDP_GETCM_MUL_RGB1(state.combineModes)],
510
aRGB[RDP_GETCM_ADD_RGB1(state.combineModes)],
511
saA[RDP_GETCM_SUB_A_A1(state.combineModes)],
512
sbA[RDP_GETCM_SUB_B_A1(state.combineModes)],
513
mA[RDP_GETCM_MUL_A1(state.combineModes)],
514
aA[RDP_GETCM_ADD_A1(state.combineModes)]
515
);
516
}
517
518
// if (!RDP_GETOM_CVG_TIMES_ALPHA(state.otherModes))
519
// p += sprintf(p, "c.a = t1.a; \n");
520
521
p += sprintf(p, "%s", alphaTest);
522
523
524
const char * blender;
525
blender = "c = vec4(float(%s)*vec3(%s) + float(%s)*vec3(%s), 1.0); \n";
526
#ifdef RGL_EXACT_BLEND
527
const char * noblender = "c.a = 1.0;\n";
528
#endif
529
530
int m1b, m1a, m2b, m2a;
531
532
//LOG("New combiner / blender :\n%s", rglCombiner2String(state));
533
534
if (cycle == RDP_CYCLE_TYPE_2) {
535
if (RDP_GETOM_FORCE_BLEND(state.otherModes)) {
536
#ifndef RGL_EXACT_BLEND
537
if (RDP_GETOM_BLEND_M1A_0(state.otherModes) != 1 &&
538
RDP_GETOM_BLEND_M2A_0(state.otherModes) != 1) {
539
#endif
540
sprintf(_1ma, "(1.0 - %s)", bA[0][RDP_GETOM_BLEND_M1B_0(state.otherModes)]);
541
p +=
542
sprintf(
543
p,
544
"c = vec4(float(%s)*vec3(%s) + float(%s)*vec3(%s), c.a); \n"
545
,bA[0][RDP_GETOM_BLEND_M1B_0(state.otherModes)],
546
bRGB[RDP_GETOM_BLEND_M1A_0(state.otherModes)],
547
bA[1][RDP_GETOM_BLEND_M2B_0(state.otherModes)],
548
bRGB[RDP_GETOM_BLEND_M2A_0(state.otherModes)]
549
);
550
#ifndef RGL_EXACT_BLEND
551
} else {
552
LOG("Blender error : fragment in cycle 1\n%s", rglCombiner2String(state));
553
}
554
#endif
555
556
m1b = RDP_GETOM_BLEND_M1B_1(state.otherModes);
557
m1a = RDP_GETOM_BLEND_M1A_1(state.otherModes);
558
m2b = RDP_GETOM_BLEND_M2B_1(state.otherModes);
559
m2a = RDP_GETOM_BLEND_M2A_1(state.otherModes);
560
} else {
561
m1b = RDP_GETOM_BLEND_M1B_0(state.otherModes);
562
m1a = RDP_GETOM_BLEND_M1A_0(state.otherModes);
563
m2b = RDP_GETOM_BLEND_M2B_0(state.otherModes);
564
m2a = RDP_GETOM_BLEND_M2A_0(state.otherModes);
565
}
566
} else {
567
m1b = RDP_GETOM_BLEND_M1B_0(state.otherModes);
568
m1a = RDP_GETOM_BLEND_M1A_0(state.otherModes);
569
m2b = RDP_GETOM_BLEND_M2B_0(state.otherModes);
570
m2a = RDP_GETOM_BLEND_M2A_0(state.otherModes);
571
}
572
573
if (RDP_GETOM_FORCE_BLEND(state.otherModes) || cycle == RDP_CYCLE_TYPE_2) {
574
#ifndef RGL_EXACT_BLEND
575
if (m1a == 1 || m2a == 1) {
576
if (/*(m1a != 1 || m1b == 3) &&*/ (m2a == 1 || m2b == 3)) {
577
int src = GL_ZERO, dst = GL_ONE;
578
const char * alpha = "c.a";
579
switch (m1b) {
580
case 0: // c.a
581
src = GL_SRC_ALPHA;
582
break;
583
case 1: // fog.a
584
src = GL_SRC_ALPHA;
585
alpha = "fog.a";
586
// LOGERROR("Unsupported src alpha : FOG\n");
587
// LOGERROR(rglCombiner2String(state));
588
break;
589
case 2: // shade.a
590
src = GL_SRC_ALPHA;
591
alpha = "gl_Color.a";
592
// LOGERROR("Unsupported src alpha : SHADE\n");
593
// LOGERROR(rglCombiner2String(state));
594
break;
595
case 3: // 0
596
src = GL_ZERO;
597
break;
598
}
599
switch (m1a) {
600
case 0: // c
601
if (m1b != 0 /* c.a */)
602
p += sprintf(
603
p, "c.a = %s; \n", alpha);
604
break;
605
case 1: // f
606
LOGERROR("Unsupported src color : FRAG\n");
607
LOGERROR("%s", rglCombiner2String(state));
608
break;
609
case 2: // b
610
p += sprintf(
611
p, "c = vec4(vec3(b), %s); \n", alpha);
612
break;
613
case 3: // fog
614
p += sprintf(
615
p, "c = vec4(vec3(fog), %s); \n", alpha);
616
break;
617
}
618
switch (m2b) {
619
case 0:
620
switch (m1b) {
621
case 3:
622
dst = GL_ONE;
623
break;
624
default:
625
dst = GL_ONE_MINUS_SRC_ALPHA;
626
break;
627
}
628
break;
629
case 1:
630
dst = GL_DST_ALPHA;
631
break;
632
case 2:
633
dst = GL_ONE;
634
break;
635
case 3:
636
dst = GL_ZERO;
637
break;
638
}
639
640
c->srcBlend = src;
641
c->dstBlend = dst;
642
} else {
643
LOGERROR("Unsuported blender :\n");
644
LOGERROR("%s", rglCombiner2String(state));
645
}
646
}
647
else
648
#endif
649
{
650
sprintf(_1ma, "(1.0 - %s)", bA[0][m1b]);
651
p +=
652
sprintf(p, blender, bA[0][m1b], bRGB[m1a], bA[1][m2b], bRGB[m2a]);
653
}
654
} else {
655
#ifdef RGL_EXACT_BLEND
656
p +=
657
sprintf(p,
658
noblender
659
);
660
#endif
661
}
662
663
p +=
664
sprintf(
665
p,
666
"%s \n"
667
"} \n"
668
,write
669
);
670
671
rglAssert(p < src+sizeof(src));
672
673
#ifdef RGL_EXACT_BLEND
674
//printf("Creating combiner : \n%s", src);
675
#endif
676
677
c->shader = rglCreateShader(
678
"void main() \n"
679
"{ \n"
680
" gl_Position = ftransform(); \n"
681
" gl_FrontColor = gl_Color; \n"
682
" gl_BackColor = gl_FrontColor; \n"
683
" gl_TexCoord[0] = gl_MultiTexCoord0; \n"
684
#ifdef RGL_EXACT_BLEND
685
" gl_TexCoord[1] = gl_MultiTexCoord1; \n"
686
#endif
687
" gl_TexCoord[2] = gl_MultiTexCoord2; \n"
688
"} \n"
689
,
690
src);
691
692
#ifdef RDP_DEBUG
693
chunk.shader = c->shader;
694
#endif
695
rglUseShader(c->shader);
696
rglAssert(glGetError() == GL_NO_ERROR);
697
698
int location;
699
location = glGetUniformLocationARB(c->shader->prog, "texture0");
700
glUniform1iARB(location, 0);
701
#ifdef RGL_EXACT_BLEND
702
location = glGetUniformLocationARB(c->shader->prog, "texture1");
703
glUniform1iARB(location, 1);
704
#endif
705
location = glGetUniformLocationARB(c->shader->prog, "texture2");
706
glUniform1iARB(location, 2);
707
rglAssert(glGetError() == GL_NO_ERROR);
708
709
ok:;
710
#ifndef RGL_EXACT_BLEND
711
if ((format & RGL_COMB_FMT) == RGL_COMB_FMT_DEPTH ||
712
(c->srcBlend == GL_ONE && c->dstBlend == GL_ZERO))
713
glDisable(GL_BLEND);
714
else {
715
glEnable(GL_BLEND);
716
if ((format & RGL_COMB_FMT) == RGL_COMB_FMT_RGBA)
717
glBlendFuncSeparate(c->srcBlend, c->dstBlend, GL_ZERO, GL_ONE);
718
else
719
glBlendFunc(c->srcBlend, c->dstBlend);
720
}
721
#endif
722
}
723
724