Path: blob/master/libmupen64plus/mupen64plus-video-z64/src/rgl_rendermode.cpp
2 views
/*1* z642*3* Copyright (C) 2007 ziggy4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* (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 of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public License along16* with this program; if not, write to the Free Software Foundation, Inc.,17* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.18*19**/2021#include "rdp.h"22#include "rgl.h"2324#include <SDL.h>2526void rglRenderMode(rglRenderChunk_t & chunk)27{28//int i;29glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);30if (RDP_GETOM_CYCLE_TYPE(chunk.rdpState.otherModes) < 2) {31glDepthMask(RDP_GETOM_Z_UPDATE_EN(chunk.rdpState.otherModes)? GL_TRUE:GL_FALSE);32if (RDP_GETOM_Z_COMPARE_EN(chunk.rdpState.otherModes))33glDepthFunc(GL_LESS);34else35glDepthFunc(GL_ALWAYS);36} else {37glDepthMask(GL_FALSE);38glDepthFunc(GL_ALWAYS);39}404142// if (RDP_GETOM_Z_MODE(chunk.rdpState.otherModes) & 1) {43// glEnable( GL_POLYGON_OFFSET_FILL );44// switch(RDP_GETOM_Z_MODE(chunk.rdpState.otherModes)) {45// case 3:46// glPolygonOffset( -3, -300 );47// break;48// default:49// // FIXME tune this value50// //glPolygonOffset( -3.0f, -3.0f );51// glPolygonOffset( -3, -40 );52// break;53// }54// //glDepthMask(GL_FALSE);55// } else {56// glDisable( GL_POLYGON_OFFSET_FILL );57// }58}59606162struct rglCombiner_t {63rdpCombineModes_t combineModes;64rdpOtherModes_t otherModes;65rglShader_t * shader;66#ifndef RGL_EXACT_BLEND67GLuint srcBlend, dstBlend;68#endif69int format;70};71#define RGL_MAX_COMBINERS 12872static int rglNbCombiners;73static rglCombiner_t rglCombiners[RGL_MAX_COMBINERS];7475void rglClearCombiners()76{77int i;78for (i=0; i<rglNbCombiners; i++)79rglDeleteShader(rglCombiners[i].shader);80rglNbCombiners = 0;81}828384int rglT1Usage(rdpState_t & state)85{86//return 1;87int cycle = RDP_GETOM_CYCLE_TYPE(state.otherModes);88if (cycle == RDP_CYCLE_TYPE_COPY) return 1;89if (cycle >= 2) return 0;90if (cycle == 1 && (91RDP_GETCM_SUB_A_RGB1(state.combineModes)==2 ||92RDP_GETCM_SUB_B_RGB1(state.combineModes)==2 ||93RDP_GETCM_MUL_RGB1(state.combineModes)==2 ||94RDP_GETCM_MUL_RGB1(state.combineModes)==9 ||95RDP_GETCM_ADD_RGB1(state.combineModes)==2 ||96RDP_GETCM_SUB_A_A1(state.combineModes)==2 ||97RDP_GETCM_SUB_B_A1(state.combineModes)==2 ||98RDP_GETCM_MUL_A1(state.combineModes)==2 ||99RDP_GETCM_ADD_A1(state.combineModes)==2))100return 1;101if (102(RDP_GETOM_CVG_TIMES_ALPHA(state.otherModes) &&103!RDP_GETOM_ALPHA_CVG_SELECT(state.otherModes)) ||104105RDP_GETCM_SUB_A_RGB0(state.combineModes)==1 ||106RDP_GETCM_SUB_B_RGB0(state.combineModes)==1 ||107RDP_GETCM_MUL_RGB0(state.combineModes)==1 ||108RDP_GETCM_MUL_RGB0(state.combineModes)==8 ||109RDP_GETCM_ADD_RGB0(state.combineModes)==1 ||110RDP_GETCM_SUB_A_A0(state.combineModes)==1 ||111RDP_GETCM_SUB_B_A0(state.combineModes)==1 ||112RDP_GETCM_MUL_A0(state.combineModes)==1 ||113RDP_GETCM_ADD_A0(state.combineModes)==1)114115return 1;116117return 0;118}119int rglT2Usage(rdpState_t & state)120{121//return 1;122int cycle = RDP_GETOM_CYCLE_TYPE(state.otherModes);123if (cycle >= 2) return 0;124if (cycle == 1 && (125RDP_GETCM_SUB_A_RGB1(state.combineModes)==1 ||126RDP_GETCM_SUB_B_RGB1(state.combineModes)==1 ||127RDP_GETCM_MUL_RGB1(state.combineModes)==1 ||128RDP_GETCM_MUL_RGB1(state.combineModes)==8 ||129RDP_GETCM_ADD_RGB1(state.combineModes)==1 ||130RDP_GETCM_SUB_A_A1(state.combineModes)==1 ||131RDP_GETCM_SUB_B_A1(state.combineModes)==1 ||132RDP_GETCM_MUL_A1(state.combineModes)==1 ||133RDP_GETCM_ADD_A1(state.combineModes)==1))134return 1;135136if (137RDP_GETCM_SUB_A_RGB0(state.combineModes)==2 ||138RDP_GETCM_SUB_B_RGB0(state.combineModes)==2 ||139RDP_GETCM_MUL_RGB0(state.combineModes)==2 ||140RDP_GETCM_MUL_RGB0(state.combineModes)==9 ||141RDP_GETCM_ADD_RGB0(state.combineModes)==2 ||142RDP_GETCM_SUB_A_A0(state.combineModes)==2 ||143RDP_GETCM_SUB_B_A0(state.combineModes)==2 ||144RDP_GETCM_MUL_A0(state.combineModes)==2 ||145RDP_GETCM_ADD_A0(state.combineModes)==2)146147return 1;148149return 0;150}151152153void rglSetCombiner(rglRenderChunk_t & chunk, int format)154{155static char _1ma[64];156static char t1[64];157static char t1a[64];158static char t2[64];159static char t2a[64];160static char prim_lod_frac[64];161162static const char *saRGB[] = {163"c", t1, t2, "p/*PRIM*/",164"gl_Color", "e", "1.0/*NOISE*/", "1.0",165"0.0", "0.0", "0.0", "0.0",166"0.0", "0.0", "0.0", "0.0"167};168169static const char *mRGB[] = {170"c", t1, t2, "p/*PRIM*/",171"gl_Color/*SHADE*/","e", "0.0/*SCALE*/", "c.a/*COMBINED_A*/",172"t1.a/*TEXEL0_A*/", "t2.a/*TEXEL1_A*/", "p.a/*PRIM_A*/", "gl_Color.a/*SHADEA*/",173"e.a/*ENV_ALPHA*/", "0.5/*LOD_FRACTION*/","0.5/*PRIM_LOD_FRAC*/","k5/*K5*/",174"0.0", "0.0", "0.0", "0.0",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};179180static const char *aRGB[] = {181"c", t1, t2, "p/*PRIM*/",182"gl_Color/*SHADE*/","e/*ENV*/", "1.0", "0.0",183};184185static const char *saA[] = {186"c.a", t1a, t2a, "p.a/*PRIM*/",187"gl_Color.a", "e.a", "1.0", "0.0",188};189190static const char *sbA[] = {191"c.a", t1a, t2a, "p.a/*PRIM*/",192"gl_Color.a", "e.a", "1.0", "0.0",193};194195static const char *mA[] = {196"0.5/*LOD_FRACTION*/", t1a, t2a, "p.a/*PRIM*/",197"gl_Color.a/*SHADE*/", "e.a", prim_lod_frac, "0.0",198};199200static const char *aA[] = {201"c.a", t1a, t2a, "p.a/*PRIM*/",202"gl_Color.a/*SHADE*/", "e.a", "1.0", "0.0",203};204205const static char * bRGB[] =206{ "c/*PREV*/", "f", "b", "fog/*FOG*/" };207const static char * bA[2][4] =208{ {"c.a/*PREVA*/", "fog.a/*FOGA*/", "gl_Color.a/*SHADEA*/", "0.0/*ZERO*/"},209{_1ma/*"(1.0-c.a/ *PREVA)"*/, "0.0/*f.a*//*FRAGA*/", "1.0", "0.0"}}; // need clamping on 1-alpha ?210211212rdpState_t & state = chunk.rdpState;213static rglCombiner_t * c;214uint32_t cycle = RDP_GETOM_CYCLE_TYPE(state.otherModes);215int i; //, fmt, size;216char * p;217const char * alphaTest;218const char * alphaTest2;219const char * write;220static char src[4*4096];221222float env[4];223env[0] = RDP_GETC32_R(state.envColor)/255.0f;224env[1] = RDP_GETC32_G(state.envColor)/255.0f;225env[2] = RDP_GETC32_B(state.envColor)/255.0f;226env[3] = RDP_GETC32_A(state.envColor)/255.0f;227glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env);228229env[0] = RDP_GETC32_R(state.blendColor)/255.0f;230env[1] = RDP_GETC32_G(state.blendColor)/255.0f;231env[2] = RDP_GETC32_B(state.blendColor)/255.0f;232env[3] = RDP_GETC32_A(state.blendColor)/255.0f;233glLightfv(GL_LIGHT0, GL_AMBIENT, env);234235env[0] = RDP_GETC32_R(state.fogColor)/255.0f;236env[1] = RDP_GETC32_G(state.fogColor)/255.0f;237env[2] = RDP_GETC32_B(state.fogColor)/255.0f;238env[3] = RDP_GETC32_A(state.fogColor)/255.0f;239glLightfv(GL_LIGHT0, GL_DIFFUSE, env);240241glActiveTextureARB(GL_TEXTURE1_ARB);242env[0] = state.k5/255.0f;243glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, env);244if (cycle == RDP_CYCLE_TYPE_FILL) {245if (0/*fb_size == 3*/) { // FIXME246env[0] = RDP_GETC32_R(state.fillColor)/255.0f;247env[1] = RDP_GETC32_G(state.fillColor)/255.0f;248env[2] = RDP_GETC32_B(state.fillColor)/255.0f;249env[3] = RDP_GETC32_A(state.fillColor)/255.0f;250} else {251env[0] = RDP_GETC16_R(state.fillColor)/31.0f;252env[1] = RDP_GETC16_G(state.fillColor)/31.0f;253env[2] = RDP_GETC16_B(state.fillColor)/31.0f;254env[3] = RDP_GETC16_A(state.fillColor);255}256} else {257env[0] = RDP_GETC32_R(state.primColor)/255.0f;258env[1] = RDP_GETC32_G(state.primColor)/255.0f;259env[2] = RDP_GETC32_B(state.primColor)/255.0f;260env[3] = RDP_GETC32_A(state.primColor)/255.0f;261}262glLightfv(GL_LIGHT0, GL_SPECULAR, env);263glActiveTextureARB(GL_TEXTURE0_ARB);264rglAssert(glGetError() == GL_NO_ERROR);265266// if (c && rglNbCombiners &&267// RDP_GETOM_CYCLE_TYPE(c->otherModes) == cycle &&268// (RDP_GETOM_CYCLE_TYPE(c->otherModes) >= 2 ||269// (!memcmp(&c->combineModes, &state.combineModes, sizeof(rdpCombineModes_t)) &&270// !memcmp(&c->otherModes, &state.otherModes, sizeof(rdpOtherModes_t))))) {271// return;272// }273274for (i=0; i<rglNbCombiners; i++) {275c = rglCombiners + i;276if (c->format == format &&277RDP_GETOM_CYCLE_TYPE(c->otherModes) == cycle &&278(RDP_GETOM_CYCLE_TYPE(c->otherModes) >= 2 ||279(!memcmp(&c->combineModes, &state.combineModes, sizeof(rdpCombineModes_t))280&& !memcmp(&c->otherModes, &state.otherModes, sizeof(rdpOtherModes_t))281))) {282#ifdef RDP_DEBUG283chunk.shader = c->shader;284#endif285rglUseShader(c->shader);286goto ok;287}288}289290if (rglNbCombiners == RGL_MAX_COMBINERS)291rglClearCombiners();292293c = rglCombiners + rglNbCombiners++;294c->otherModes = state.otherModes;295c->combineModes = state.combineModes;296c->format = format;297#ifndef RGL_EXACT_BLEND298c->srcBlend = GL_ONE;299c->dstBlend = GL_ZERO;300#endif301302switch (format & RGL_COMB_FMT) {303case RGL_COMB_FMT_RGBA:304write = "gl_FragColor = c;";305break;306case RGL_COMB_FMT_I:307write = "gl_FragColor = vec4(c[0]);";308break;309case RGL_COMB_FMT_DEPTH:310write = "gl_FragDepth = c[0];";311break;312}313314if (cycle == RDP_CYCLE_TYPE_FILL) {315sprintf(316src,317"void main() \n"318"{ \n"319//" c = gl_TextureEnvColor[1];\n"320" vec4 c = gl_LightSource[0].specular;\n"321" %s\n"322"} \n",323write);324c->shader = rglCreateShader(325"void main() \n"326"{ \n"327" gl_Position = ftransform(); \n"328" gl_FrontColor = gl_Color; \n"329" gl_BackColor = gl_Color; \n"330" gl_TexCoord[0] = gl_MultiTexCoord0; \n"331"} \n"332,333src334);335#ifdef RDP_DEBUG336chunk.shader = c->shader;337#endif338rglUseShader(c->shader);339goto ok;340}341342alphaTest = "";343alphaTest2 = "";344345if (//cycle < 2 && // CHECK THIS346RDP_GETOM_CVG_TIMES_ALPHA(chunk.rdpState.otherModes)347//&& rglT1Usage(chunk.rdpState)348) {349if (RDP_GETOM_ALPHA_CVG_SELECT(chunk.rdpState.otherModes))350alphaTest = "if (c.a < 0.5) discard; \n";351else352alphaTest = "if (t1.a < 0.5) discard; \n";353alphaTest2 = "if (c.a < 0.5) discard; \n";354}355else if (RDP_GETOM_ALPHA_COMPARE_EN(chunk.rdpState.otherModes) &&356!RDP_GETOM_ALPHA_CVG_SELECT(chunk.rdpState.otherModes)) {357if (RDP_GETC32_A(chunk.rdpState.blendColor) > 0) {358alphaTest = "if (c.a < b.a) discard; \n";359alphaTest2 =360" vec4 b = gl_LightSource[0].ambient; \n"361" if (c.a < b.a) discard; \n";362//alphaTest2 = "if (c.a < 0.5) discard; \n";363} else {364alphaTest = "if (c.a == 0.0) discard; \n";365alphaTest2 = "if (c.a == 0.0) discard; \n";366}367}368369if (cycle == RDP_CYCLE_TYPE_COPY) {370sprintf(371src,372"uniform sampler2D texture0; \n"373" \n"374"void main() \n"375"{ \n"376" vec4 c = texture2D(texture0, vec2(gl_TexCoord[0])); \n"377" %s"378" %s\n"379"} \n",380alphaTest2,381write382);383c->shader = rglCreateShader(384"void main() \n"385"{ \n"386" gl_Position = ftransform(); \n"387" gl_FrontColor = gl_Color; \n"388" gl_BackColor = gl_Color; \n"389" gl_TexCoord[0] = gl_MultiTexCoord0; \n"390"} \n"391,392src393);394#ifdef RDP_DEBUG395chunk.shader = c->shader;396#endif397rglUseShader(c->shader);398goto ok;399}400401402p = src;403p +=404sprintf(p,405"uniform sampler2D texture0; \n"406"uniform sampler2D texture2; \n"407#ifdef RGL_EXACT_BLEND408"uniform sampler2D texture1; \n"409#endif410" \n"411"void main() \n"412"{ \n"413"vec4 c = vec4(0,0,0,0);\n"414"vec4 e = gl_TextureEnvColor[0];\n"415"float k5 = gl_TextureEnvColor[1][0];\n"416"vec4 p = gl_LightSource[0].specular;\n"417#ifdef RGL_EXACT_BLEND418"vec4 f = texture2D(texture1, vec2(gl_FragCoord.x/(2048.0*gl_TexCoord[1].x), gl_FragCoord.y/(2048.0*gl_TexCoord[1].y))); \n"419#endif420"vec4 fog = gl_LightSource[0].diffuse; \n"421"vec4 b = gl_LightSource[0].ambient; \n");422423switch (format & RGL_COMB_IN0) {424case 0:425p +=426sprintf(p,427"vec4 t1 = texture2D(texture0, vec2(gl_TexCoord[0]));\n");428break;429case RGL_COMB_IN0_DEPTH:430p +=431sprintf(p,432"vec4 t1 = vec4(texture2D(texture0, vec2(gl_TexCoord[0]))[0]);\n");433break;434}435switch (format & RGL_COMB_IN1) {436case 0:437p +=438sprintf(p,439"vec4 t2 = texture2D(texture2, vec2(gl_TexCoord[2]));\n");440break;441case RGL_COMB_IN1_DEPTH:442p +=443sprintf(p,444"vec4 t2 = vec4(texture2D(texture2, vec2(gl_TexCoord[2]))[0]);\n");445break;446}447448const char * comb, * comb2;449comb2 = 0;450// switch (RDP_GETOM_CVG_DEST(state.otherModes))451// {452// case 3:453// comb = "c = clamp(vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s), 0.0, 1.0);\n";454// break;455// case 2:456// comb = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s);\n";457// //comb = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), t1.a*((%s - %s) * %s + %s));\n";458// break;459// case 0:460// //comb2 = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), t1.a);\n";461// case 1:462// comb = "c = vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s);\n";463// break;464// }465comb = "c = clamp(vec4((vec3(%s) - vec3(%s)) * vec3(%s) + vec3(%s), (%s - %s) * %s + %s), 0.0, 1.0);\n";466strcpy(prim_lod_frac, "0.5/*PRIM_LOD_FRAC*/");467strcpy(t1, "t1");468strcpy(t1a, "t1.a");469if (format & RGL_COMB_TILE7) {470strcpy(t2, "t1");471strcpy(t2a, "t1.a");472} else {473strcpy(t2, "t2");474strcpy(t2a, "t2.a");475}476p +=477sprintf(p,478comb479,480saRGB[RDP_GETCM_SUB_A_RGB0(state.combineModes)],481saRGB[RDP_GETCM_SUB_B_RGB0(state.combineModes)],482mRGB[RDP_GETCM_MUL_RGB0(state.combineModes)],483aRGB[RDP_GETCM_ADD_RGB0(state.combineModes)],484saA[RDP_GETCM_SUB_A_A0(state.combineModes)],485sbA[RDP_GETCM_SUB_B_A0(state.combineModes)],486mA[RDP_GETCM_MUL_A0(state.combineModes)],487aA[RDP_GETCM_ADD_A0(state.combineModes)]488);489490if (cycle == RDP_CYCLE_TYPE_2) {491if (!(format & RGL_COMB_TILE7)) {492strcpy(t1, "t2");493strcpy(t1a, "t2.a");494strcpy(t2, "t1");495strcpy(t2a, "t1.a");496}497//strcpy(prim_lod_frac, "0.0/*PRIM_LOD_FRAC*/");498// if (!RDP_GETOM_ALPHA_CVG_SELECT(chunk.rdpState.otherModes))499// p +=500// sprintf(p, " c.a = t1.a; \n");501502p +=503sprintf(p,504comb2? comb2 : comb505,506saRGB[RDP_GETCM_SUB_A_RGB1(state.combineModes)],507saRGB[RDP_GETCM_SUB_B_RGB1(state.combineModes)],508mRGB[RDP_GETCM_MUL_RGB1(state.combineModes)],509aRGB[RDP_GETCM_ADD_RGB1(state.combineModes)],510saA[RDP_GETCM_SUB_A_A1(state.combineModes)],511sbA[RDP_GETCM_SUB_B_A1(state.combineModes)],512mA[RDP_GETCM_MUL_A1(state.combineModes)],513aA[RDP_GETCM_ADD_A1(state.combineModes)]514);515}516517// if (!RDP_GETOM_CVG_TIMES_ALPHA(state.otherModes))518// p += sprintf(p, "c.a = t1.a; \n");519520p += sprintf(p, "%s", alphaTest);521522523const char * blender;524blender = "c = vec4(float(%s)*vec3(%s) + float(%s)*vec3(%s), 1.0); \n";525#ifdef RGL_EXACT_BLEND526const char * noblender = "c.a = 1.0;\n";527#endif528529int m1b, m1a, m2b, m2a;530531//LOG("New combiner / blender :\n%s", rglCombiner2String(state));532533if (cycle == RDP_CYCLE_TYPE_2) {534if (RDP_GETOM_FORCE_BLEND(state.otherModes)) {535#ifndef RGL_EXACT_BLEND536if (RDP_GETOM_BLEND_M1A_0(state.otherModes) != 1 &&537RDP_GETOM_BLEND_M2A_0(state.otherModes) != 1) {538#endif539sprintf(_1ma, "(1.0 - %s)", bA[0][RDP_GETOM_BLEND_M1B_0(state.otherModes)]);540p +=541sprintf(542p,543"c = vec4(float(%s)*vec3(%s) + float(%s)*vec3(%s), c.a); \n"544,bA[0][RDP_GETOM_BLEND_M1B_0(state.otherModes)],545bRGB[RDP_GETOM_BLEND_M1A_0(state.otherModes)],546bA[1][RDP_GETOM_BLEND_M2B_0(state.otherModes)],547bRGB[RDP_GETOM_BLEND_M2A_0(state.otherModes)]548);549#ifndef RGL_EXACT_BLEND550} else {551LOG("Blender error : fragment in cycle 1\n%s", rglCombiner2String(state));552}553#endif554555m1b = RDP_GETOM_BLEND_M1B_1(state.otherModes);556m1a = RDP_GETOM_BLEND_M1A_1(state.otherModes);557m2b = RDP_GETOM_BLEND_M2B_1(state.otherModes);558m2a = RDP_GETOM_BLEND_M2A_1(state.otherModes);559} else {560m1b = RDP_GETOM_BLEND_M1B_0(state.otherModes);561m1a = RDP_GETOM_BLEND_M1A_0(state.otherModes);562m2b = RDP_GETOM_BLEND_M2B_0(state.otherModes);563m2a = RDP_GETOM_BLEND_M2A_0(state.otherModes);564}565} else {566m1b = RDP_GETOM_BLEND_M1B_0(state.otherModes);567m1a = RDP_GETOM_BLEND_M1A_0(state.otherModes);568m2b = RDP_GETOM_BLEND_M2B_0(state.otherModes);569m2a = RDP_GETOM_BLEND_M2A_0(state.otherModes);570}571572if (RDP_GETOM_FORCE_BLEND(state.otherModes) || cycle == RDP_CYCLE_TYPE_2) {573#ifndef RGL_EXACT_BLEND574if (m1a == 1 || m2a == 1) {575if (/*(m1a != 1 || m1b == 3) &&*/ (m2a == 1 || m2b == 3)) {576int src = GL_ZERO, dst = GL_ONE;577const char * alpha = "c.a";578switch (m1b) {579case 0: // c.a580src = GL_SRC_ALPHA;581break;582case 1: // fog.a583src = GL_SRC_ALPHA;584alpha = "fog.a";585// LOGERROR("Unsupported src alpha : FOG\n");586// LOGERROR(rglCombiner2String(state));587break;588case 2: // shade.a589src = GL_SRC_ALPHA;590alpha = "gl_Color.a";591// LOGERROR("Unsupported src alpha : SHADE\n");592// LOGERROR(rglCombiner2String(state));593break;594case 3: // 0595src = GL_ZERO;596break;597}598switch (m1a) {599case 0: // c600if (m1b != 0 /* c.a */)601p += sprintf(602p, "c.a = %s; \n", alpha);603break;604case 1: // f605LOGERROR("Unsupported src color : FRAG\n");606LOGERROR("%s", rglCombiner2String(state));607break;608case 2: // b609p += sprintf(610p, "c = vec4(vec3(b), %s); \n", alpha);611break;612case 3: // fog613p += sprintf(614p, "c = vec4(vec3(fog), %s); \n", alpha);615break;616}617switch (m2b) {618case 0:619switch (m1b) {620case 3:621dst = GL_ONE;622break;623default:624dst = GL_ONE_MINUS_SRC_ALPHA;625break;626}627break;628case 1:629dst = GL_DST_ALPHA;630break;631case 2:632dst = GL_ONE;633break;634case 3:635dst = GL_ZERO;636break;637}638639c->srcBlend = src;640c->dstBlend = dst;641} else {642LOGERROR("Unsuported blender :\n");643LOGERROR("%s", rglCombiner2String(state));644}645}646else647#endif648{649sprintf(_1ma, "(1.0 - %s)", bA[0][m1b]);650p +=651sprintf(p, blender, bA[0][m1b], bRGB[m1a], bA[1][m2b], bRGB[m2a]);652}653} else {654#ifdef RGL_EXACT_BLEND655p +=656sprintf(p,657noblender658);659#endif660}661662p +=663sprintf(664p,665"%s \n"666"} \n"667,write668);669670rglAssert(p < src+sizeof(src));671672#ifdef RGL_EXACT_BLEND673//printf("Creating combiner : \n%s", src);674#endif675676c->shader = rglCreateShader(677"void main() \n"678"{ \n"679" gl_Position = ftransform(); \n"680" gl_FrontColor = gl_Color; \n"681" gl_BackColor = gl_FrontColor; \n"682" gl_TexCoord[0] = gl_MultiTexCoord0; \n"683#ifdef RGL_EXACT_BLEND684" gl_TexCoord[1] = gl_MultiTexCoord1; \n"685#endif686" gl_TexCoord[2] = gl_MultiTexCoord2; \n"687"} \n"688,689src);690691#ifdef RDP_DEBUG692chunk.shader = c->shader;693#endif694rglUseShader(c->shader);695rglAssert(glGetError() == GL_NO_ERROR);696697int location;698location = glGetUniformLocationARB(c->shader->prog, "texture0");699glUniform1iARB(location, 0);700#ifdef RGL_EXACT_BLEND701location = glGetUniformLocationARB(c->shader->prog, "texture1");702glUniform1iARB(location, 1);703#endif704location = glGetUniformLocationARB(c->shader->prog, "texture2");705glUniform1iARB(location, 2);706rglAssert(glGetError() == GL_NO_ERROR);707708ok:;709#ifndef RGL_EXACT_BLEND710if ((format & RGL_COMB_FMT) == RGL_COMB_FMT_DEPTH ||711(c->srcBlend == GL_ONE && c->dstBlend == GL_ZERO))712glDisable(GL_BLEND);713else {714glEnable(GL_BLEND);715if ((format & RGL_COMB_FMT) == RGL_COMB_FMT_RGBA)716glBlendFuncSeparate(c->srcBlend, c->dstBlend, GL_ZERO, GL_ONE);717else718glBlendFunc(c->srcBlend, c->dstBlend);719}720#endif721}722723724