#ifdef _WIN32 #include #include #include "glext.h" #else // _WIN32 #include "../winlnxdefs.h" #include #include #include #endif // _WIN32 #include "glide.h" #include "main.h" static int fct[4], source0[4], operand0[4], source1[4], operand1[4], source2[4], operand2[4]; static int fcta[4],sourcea0[4],operanda0[4],sourcea1[4],operanda1[4],sourcea2[4],operanda2[4]; static int alpha_ref, alpha_func; float texture_env_color[4]; static float chroma_color[4]; int fog_enabled; static int chroma_enabled; static int chroma_other_color; static int chroma_other_alpha; #ifdef _WIN32 static float farF; static float nearF; #endif // _WIN32 int need_lambda[2]; float lambda_color[2][4]; // shaders variables int need_to_compile; static GLhandleARB fragment_shader_object; static GLhandleARB vertex_shader_object; static GLhandleARB program_object_default; static GLhandleARB program_object; static int constant_color_location; static int first_color = 1; static int first_alpha = 1; static int first_texture0 = 1; static int first_texture1 = 1; static const char* fragment_shader_header = "uniform sampler2D texture0; \n" "uniform sampler2D texture1; \n" "uniform vec4 constant_color; \n" "uniform vec4 chroma_color; \n" "uniform float lambda; \n" "varying float fogValue; \n" " \n" "void test_chroma(vec4 ctexture1); \n" " \n" "void main() \n" "{ \n" ; static const char* fragment_shader_default = " gl_FragColor = texture2D(texture0, vec2(gl_TexCoord[0])); \n" ; static const char* fragment_shader_fog = " float fog; \n" " fog = (gl_Fog.end - /*gl_FogFragCoord*/gl_SecondaryColor.r*256.0) * gl_Fog.scale; \n" " fog = clamp(fog, 0.0, 1.0); \n" " gl_FragColor = vec4(mix(vec3(gl_Fog.color), gl_FragColor.rgb, fog), gl_FragColor.a); \n" ; /*static const char* fragment_shader_fog = " float fog; \n" " fog = (far - gl_FogFragCoord) / (far - near); \n" " fog = clamp(fog, 0.0, 1.0); \n" " gl_FragColor = vec4(mix(vec3(gl_Fog.color), gl_FragColor.rgb, fog), gl_FragColor.a); \n" ;*/ /*static const char* fragment_shader_fog = " gl_FragColor = vec4(mix(vec3(gl_Fog.color), gl_FragColor.rgb, fogValue), gl_FragColor.a); \n" ;*/ static const char* fragment_shader_end = "} \n" ; #ifdef _WIN32 static const char* vertex_shader = //"uniform float near; \n" //"uniform float far; \n" "varying float fogValue; \n" " \n" "void main() \n" "{ \n" " gl_Position = ftransform(); \n" " gl_FrontColor = gl_Color; \n" " gl_TexCoord[0] = gl_MultiTexCoord0; \n" " gl_TexCoord[1] = gl_MultiTexCoord1; \n" /*" fogValue = clamp(gl_FogCoord, 0.0, 255.0); \n" " fogValue = (gl_Fog.end - fogValue) * gl_Fog.scale; \n" " fogValue = clamp(fogValue, 0.0, 1.0); \n"*/ " fogValue = 0.2; \n" "} \n" ; #endif // _WIN32 static char fragment_shader_color_combiner[1024]; static char fragment_shader_alpha_combiner[1024]; static char fragment_shader_texture1[1024]; static char fragment_shader_texture0[1024]; static char fragment_shader_chroma[1024]; static char shader_log[2048]; void updateCombiner(int i) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, fct[i]); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, source0[i]); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, operand0[i]); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, source1[i]); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, operand1[i]); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, source2[i]); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, operand2[i]); } void updateCombinera(int i) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, fcta[i]); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, sourcea0[i]); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, operanda0[i]); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, sourcea1[i]); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, operanda1[i]); glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_ARB, sourcea2[i]); glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, operanda2[i]); } void init_combiner() { int texture[4] = {0, 0, 0, 0}; glActiveTextureARB(GL_TEXTURE0_ARB); glEnable(GL_TEXTURE_2D); // creating a fake texture glBindTexture(GL_TEXTURE_2D, 32*1024*1024); glTexImage2D(GL_TEXTURE_2D, 0, 3, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTextureARB(GL_TEXTURE1_ARB); glBindTexture(GL_TEXTURE_2D, 32*1024*1024); glEnable(GL_TEXTURE_2D); if(!glsl_support) { if (nbTextureUnits > 2) { glActiveTextureARB(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, 32*1024*1024); glEnable(GL_TEXTURE_2D); } if (nbTextureUnits > 3) { glActiveTextureARB(GL_TEXTURE3_ARB); glBindTexture(GL_TEXTURE_2D, 32*1024*1024); glEnable(GL_TEXTURE_2D); } alpha_ref = 0; need_lambda[0] = need_lambda[1] = 0; } else { int texture0_location; int texture1_location; char *fragment_shader; int log_length; /*glActiveTextureARB(GL_TEXTURE2_ARB); glBindTexture(GL_TEXTURE_2D, 32*1024*1024); glEnable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB);*/ fragment_shader_object = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); fragment_shader = (char*)malloc(strlen(fragment_shader_header)+ strlen(fragment_shader_default)+ strlen(fragment_shader_end)+1); strcpy(fragment_shader, fragment_shader_header); strcat(fragment_shader, fragment_shader_default); strcat(fragment_shader, fragment_shader_end); glShaderSourceARB(fragment_shader_object, 1, (const GLcharARB**)&fragment_shader, NULL); free(fragment_shader); glCompileShaderARB(fragment_shader_object); /*vertex_shader_object = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); glShaderSourceARB(vertex_shader_object, 1, &vertex_shader, NULL); glCompileShaderARB(vertex_shader_object);*/ program_object = glCreateProgramObjectARB(); program_object_default = program_object; glAttachObjectARB(program_object, fragment_shader_object); //glAttachObjectARB(program_object, vertex_shader_object); glLinkProgramARB(program_object); glUseProgramObjectARB(program_object); glGetObjectParameterivARB(program_object, GL_OBJECT_LINK_STATUS_ARB , &log_length); if(!log_length) { glGetInfoLogARB(fragment_shader_object, 2048, &log_length, shader_log); if(log_length) display_warning((unsigned char*)shader_log); glGetInfoLogARB(vertex_shader_object, 2048, &log_length, shader_log); if(log_length) display_warning((unsigned char*)shader_log); glGetInfoLogARB(program_object, 2048, &log_length, shader_log); if(log_length) display_warning((unsigned char*)shader_log); } texture0_location = glGetUniformLocationARB(program_object, "texture0"); texture1_location = glGetUniformLocationARB(program_object, "texture1"); glUniform1iARB(texture0_location, 0); glUniform1iARB(texture1_location, 1); strcpy(fragment_shader_color_combiner, ""); strcpy(fragment_shader_alpha_combiner, ""); strcpy(fragment_shader_texture1, "vec4 ctexture1 = texture2D(texture0, vec2(gl_TexCoord[0])); \n"); strcpy(fragment_shader_texture0, ""); first_color = 1; first_alpha = 1; first_texture0 = 1; first_texture1 = 1; need_to_compile = 0; } fog_enabled = 0; chroma_enabled = 0; } void compile_chroma_shader() { strcpy(fragment_shader_chroma, "\nvoid test_chroma(vec4 ctexture1)\n{\n"); switch(chroma_other_alpha) { case GR_COMBINE_OTHER_ITERATED: strcat(fragment_shader_chroma, "float alpha = gl_Color.a; \n"); break; case GR_COMBINE_OTHER_TEXTURE: strcat(fragment_shader_chroma, "float alpha = ctexture1.a; \n"); break; case GR_COMBINE_OTHER_CONSTANT: strcat(fragment_shader_chroma, "float alpha = constant_color.a; \n"); break; default: display_warning((unsigned char*)"unknown compile_choma_shader_alpha : %x", chroma_other_alpha); } switch(chroma_other_color) { case GR_COMBINE_OTHER_ITERATED: strcat(fragment_shader_chroma, "vec4 color = vec4(vec3(gl_Color),alpha); \n"); break; case GR_COMBINE_OTHER_TEXTURE: strcat(fragment_shader_chroma, "vec4 color = vec4(vec3(ctexture1),alpha); \n"); break; case GR_COMBINE_OTHER_CONSTANT: strcat(fragment_shader_chroma, "vec4 color = vec4(vec3(constant_color),alpha); \n"); break; default: display_warning((unsigned char*)"unknown compile_choma_shader_alpha : %x", chroma_other_color); } strcat(fragment_shader_chroma, "if (color == chroma_color) discard; \n"); strcat(fragment_shader_chroma, "}"); } typedef struct _shader_program_key { int color_combiner; int alpha_combiner; int texture0_combiner; int texture1_combiner; int fog_enabled; int chroma_enabled; GLhandleARB fragment_shader_object; GLhandleARB program_object; } shader_program_key; static shader_program_key* shader_programs = NULL; static int number_of_programs = 0; static int color_combiner_key; static int alpha_combiner_key; static int texture0_combiner_key; static int texture1_combiner_key; void compile_shader() { int texture0_location; int texture1_location; char *fragment_shader; int i; int chroma_color_location; int log_length; /*int near_location; int far_location;*/ need_to_compile = 0; for(i=0; i> 24) & 0xFF) / 255.0f; texture_env_color[0] = ((value >> 16) & 0xFF) / 255.0f; texture_env_color[1] = ((value >> 8) & 0xFF) / 255.0f; texture_env_color[2] = (value & 0xFF) / 255.0f; break; case GR_COLORFORMAT_RGBA: texture_env_color[0] = ((value >> 24) & 0xFF) / 255.0f; texture_env_color[1] = ((value >> 16) & 0xFF) / 255.0f; texture_env_color[2] = ((value >> 8) & 0xFF) / 255.0f; texture_env_color[3] = (value & 0xFF) / 255.0f; break; default: display_warning((unsigned char *)"grConstantColorValue: unknown color format : %x", lfb_color_fmt); } if(!glsl_support) { if (!need_lambda[0]) { glActiveTextureARB(GL_TEXTURE0_ARB); glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texture_env_color); } if (!need_lambda[1]) { glActiveTextureARB(GL_TEXTURE1_ARB); glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texture_env_color); } if (nbTextureUnits > 2) { glActiveTextureARB(GL_TEXTURE2_ARB); glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texture_env_color); } if (nbTextureUnits > 3) { glActiveTextureARB(GL_TEXTURE3_ARB); glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texture_env_color); } } else { constant_color_location = glGetUniformLocationARB(program_object, "constant_color"); glUniform4fARB(constant_color_location, texture_env_color[0], texture_env_color[1], texture_env_color[2], texture_env_color[3]); } } int setOtherColorSource(int other) { switch(other) { case GR_COMBINE_OTHER_ITERATED: return GL_PRIMARY_COLOR_ARB; break; case GR_COMBINE_OTHER_TEXTURE: return GL_PREVIOUS_ARB; break; case GR_COMBINE_OTHER_CONSTANT: return GL_CONSTANT_ARB; break; default: display_warning((unsigned char *)"unknwown other color source : %x", other); } return 0; } int setLocalColorSource(int local) { switch(local) { case GR_COMBINE_LOCAL_ITERATED: return GL_PRIMARY_COLOR_ARB; break; case GR_COMBINE_LOCAL_CONSTANT: return GL_CONSTANT_ARB; break; default: display_warning((unsigned char *)"unknwown local color source : %x", local); } return 0; } void writeGLSLColorOther(int other) { switch(other) { case GR_COMBINE_OTHER_ITERATED: strcat(fragment_shader_color_combiner, "vec4 color_other = gl_Color; \n"); break; case GR_COMBINE_OTHER_TEXTURE: strcat(fragment_shader_color_combiner, "vec4 color_other = ctexture1; \n"); break; case GR_COMBINE_OTHER_CONSTANT: strcat(fragment_shader_color_combiner, "vec4 color_other = constant_color; \n"); break; default: display_warning((unsigned char*)"unknown writeGLSLColorOther : %x", other); } } void writeGLSLColorLocal(int local) { switch(local) { case GR_COMBINE_LOCAL_ITERATED: strcat(fragment_shader_color_combiner, "vec4 color_local = gl_Color; \n"); break; case GR_COMBINE_LOCAL_CONSTANT: strcat(fragment_shader_color_combiner, "vec4 color_local = constant_color; \n"); break; default: display_warning((unsigned char*)"unknown writeGLSLColorLocal : %x", local); } } void writeGLSLColorFactor(int factor, int local, int need_local, int other, int need_other) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(0.0); \n"); break; case GR_COMBINE_FACTOR_LOCAL: if(need_local) writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "vec4 color_factor = color_local; \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: if(need_other) writeGLSLColorOther(other); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(color_other.a); \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: if(need_local) writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(color_local.a); \n"); break; case GR_COMBINE_FACTOR_TEXTURE_ALPHA: strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(ctexture1.a); \n"); break; case GR_COMBINE_FACTOR_TEXTURE_RGB: strcat(fragment_shader_color_combiner, "vec4 color_factor = ctexture1; \n"); break; case GR_COMBINE_FACTOR_ONE: strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: if(need_local) writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - color_local; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: if(need_other) writeGLSLColorOther(other); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - vec4(color_other.a); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: if(need_local) writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - vec4(color_local.a); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: strcat(fragment_shader_color_combiner, "vec4 color_factor = vec4(1.0) - vec4(ctexture1.a); \n"); break; default: display_warning((unsigned char*)"unknown writeGLSLColorFactor : %x", factor); } } FX_ENTRY void FX_CALL grColorCombine( GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert ) { if(glsl_support) { static int last_function = 0; static int last_factor = 0; static int last_local = 0; static int last_other = 0; if(last_function == function && last_factor == factor && last_local == local && last_other == other && first_color == 0) return; first_color = 0; last_function = function; last_factor = factor; last_local = local; last_other = other; if (invert) display_warning((unsigned char*)"grColorCombine : inverted result"); color_combiner_key = function | (factor << 4) | (local << 8) | (other << 10); chroma_other_color = other; strcpy(fragment_shader_color_combiner, ""); switch(function) { case GR_COMBINE_FUNCTION_ZERO: strcat(fragment_shader_color_combiner, "gl_FragColor = vec4(0.0); \n"); break; case GR_COMBINE_FUNCTION_LOCAL: writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "gl_FragColor = color_local; \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: writeGLSLColorLocal(local); strcat(fragment_shader_color_combiner, "gl_FragColor = vec4(color_local.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,1,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * color_other; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * color_other + color_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * color_other + vec4(color_local.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (color_other - color_local); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (color_other - color_local) + color_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLColorLocal(local); writeGLSLColorOther(other); writeGLSLColorFactor(factor,local,0,other,0); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (color_other - color_local) + vec4(color_local.a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLColorLocal(local); writeGLSLColorFactor(factor,local,0,other,1); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (-color_local) + color_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLColorLocal(local); writeGLSLColorFactor(factor,local,0,other,1); strcat(fragment_shader_color_combiner, "gl_FragColor = color_factor * (-color_local) + vec4(color_local.a); \n"); break; default: strcpy(fragment_shader_color_combiner, fragment_shader_default); display_warning((unsigned char*)"grColorCombine : unknown function : %x", function); } //compile_shader(); need_to_compile = 1; } else { int num_tex; if (invert) display_warning((unsigned char*)"grColorCombine : inverted result"); if (nbTextureUnits > 2) { glActiveTextureARB(GL_TEXTURE2_ARB); num_tex = 2; } else { glActiveTextureARB(GL_TEXTURE1_ARB); num_tex = 1; } fct[num_tex+1] = GL_REPLACE; source0[num_tex+1] = GL_PREVIOUS_ARB; operand0[num_tex+1] = GL_SRC_COLOR; switch(function) { case GR_COMBINE_FUNCTION_LOCAL: fct[num_tex] = GL_REPLACE; source0[num_tex] = setLocalColorSource(local); operand0[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: switch(factor) { case GR_COMBINE_FACTOR_LOCAL: fct[num_tex] = GL_MODULATE; source0[num_tex] = setLocalColorSource(local); operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setOtherColorSource(other); operand1[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FACTOR_ONE: fct[num_tex] = GL_REPLACE; source0[num_tex] = setOtherColorSource(other); operand0[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: fct[num_tex] = GL_MODULATE; source0[num_tex] = setLocalColorSource(local); operand0[num_tex] = GL_ONE_MINUS_SRC_COLOR; source1[num_tex] = setOtherColorSource(other); operand1[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FACTOR_OTHER_ALPHA: fct[num_tex] = GL_MODULATE; source0[num_tex] = setOtherColorSource(other); operand0[num_tex] = GL_SRC_ALPHA; source1[num_tex] = setOtherColorSource(other); operand1[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FACTOR_TEXTURE_RGB: fct[num_tex] = GL_MODULATE; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setOtherColorSource(other); operand1[num_tex] = GL_SRC_COLOR; break; default: display_warning((unsigned char*)"grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER) : unknown factor : %x", factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: switch(factor) { case GR_COMBINE_FACTOR_TEXTURE_RGB: fct[num_tex] = GL_MODULATE; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setOtherColorSource(other); operand1[num_tex] = GL_SRC_COLOR; fct[num_tex+1] = GL_ADD; source0[num_tex+1] = GL_PREVIOUS_ARB; operand0[num_tex+1] = GL_SRC_COLOR; source1[num_tex+1] = setLocalColorSource(local); operand1[num_tex+1] = GL_SRC_COLOR; if (source1[num_tex+1] == GL_PREVIOUS_ARB) source1[num_tex+1] = GL_TEXTURE0_ARB; break; case GR_COMBINE_FACTOR_ONE: fct[num_tex] = GL_ADD; source0[num_tex] = setOtherColorSource(other); operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setLocalColorSource(local); operand1[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FACTOR_LOCAL: fct[num_tex] = GL_MODULATE; source0[num_tex] = setLocalColorSource(local); operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setOtherColorSource(other); operand1[num_tex] = GL_SRC_COLOR; fct[num_tex+1] = GL_ADD; source0[num_tex+1] = GL_PREVIOUS_ARB; operand0[num_tex+1] = GL_SRC_COLOR; source1[num_tex+1] = setLocalColorSource(local); operand1[num_tex+1] = GL_SRC_COLOR; if (source1[num_tex+1] == GL_PREVIOUS_ARB) source1[num_tex+1] = GL_TEXTURE0_ARB; break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: fct[num_tex] = GL_MODULATE; source0[num_tex] = setLocalColorSource(local); operand0[num_tex] = GL_SRC_ALPHA; source1[num_tex] = setOtherColorSource(other); operand1[num_tex] = GL_SRC_COLOR; fct[num_tex+1] = GL_ADD; source0[num_tex+1] = GL_PREVIOUS_ARB; operand0[num_tex+1] = GL_SRC_COLOR; source1[num_tex+1] = setLocalColorSource(local); operand1[num_tex+1] = GL_SRC_COLOR; if (source1[num_tex+1] == GL_PREVIOUS_ARB) source1[num_tex+1] = GL_TEXTURE0_ARB; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: fct[num_tex] = GL_MODULATE; source0[num_tex] = setLocalColorSource(local); operand0[num_tex] = GL_ONE_MINUS_SRC_COLOR; source1[num_tex] = setOtherColorSource(other); operand1[num_tex] = GL_SRC_COLOR; fct[num_tex+1] = GL_ADD; source0[num_tex+1] = GL_PREVIOUS_ARB; operand0[num_tex+1] = GL_SRC_COLOR; source1[num_tex+1] = setLocalColorSource(local); operand1[num_tex+1] = GL_SRC_COLOR; if (source1[num_tex+1] == GL_PREVIOUS_ARB) source1[num_tex+1] = GL_TEXTURE0_ARB; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: fct[num_tex] = GL_MODULATE; source0[num_tex] = setLocalColorSource(local); operand0[num_tex] = GL_ONE_MINUS_SRC_ALPHA; source1[num_tex] = setOtherColorSource(other); operand1[num_tex] = GL_SRC_COLOR; fct[num_tex+1] = GL_ADD; source0[num_tex+1] = GL_PREVIOUS_ARB; operand0[num_tex+1] = GL_SRC_COLOR; source1[num_tex+1] = setLocalColorSource(local); operand1[num_tex+1] = GL_SRC_COLOR; if (source1[num_tex+1] == GL_PREVIOUS_ARB) source1[num_tex+1] = GL_TEXTURE0_ARB; break; default: display_warning((unsigned char*)"grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL) : unknown factor : %x", factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: switch(factor) { case GR_COMBINE_FACTOR_TEXTURE_RGB: // this combiner mode isn't implemented correctly and doesn't work on a TNT fct[num_tex] = GL_SUBTRACT_ARB; source0[num_tex] = setOtherColorSource(other); operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setLocalColorSource(local); operand1[num_tex] = GL_SRC_COLOR; fct[num_tex+1] = GL_MODULATE; source0[num_tex+1] = GL_TEXTURE0_ARB; operand0[num_tex+1] = GL_SRC_COLOR; source1[num_tex+1] = GL_PREVIOUS_ARB; operand1[num_tex+1] = GL_SRC_COLOR; break; case GR_COMBINE_FACTOR_ONE: // doesn't work on TNT fct[num_tex] = GL_SUBTRACT_ARB; source0[num_tex] = setOtherColorSource(other); operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setLocalColorSource(local); operand1[num_tex] = GL_SRC_COLOR; break; default: display_warning((unsigned char*)"grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL) : unknown factor : %x", factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: switch(factor) { case GR_COMBINE_FACTOR_OTHER_ALPHA: fct[num_tex] = GL_INTERPOLATE_ARB; source0[num_tex] = setOtherColorSource(other); operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setLocalColorSource(local); operand1[num_tex] = GL_SRC_COLOR; source2[num_tex] = setOtherColorSource(other); operand2[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: fct[num_tex] = GL_INTERPOLATE_ARB; source0[num_tex] = setOtherColorSource(other); operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setLocalColorSource(local); operand1[num_tex] = GL_SRC_COLOR; source2[num_tex] = setLocalColorSource(local); operand2[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_TEXTURE_ALPHA: fct[num_tex] = GL_INTERPOLATE_ARB; source0[num_tex] = setOtherColorSource(other); operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setLocalColorSource(local); operand1[num_tex] = GL_SRC_COLOR; source2[num_tex] = GL_PREVIOUS_ARB; operand2[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_TEXTURE_RGB: fct[num_tex] = GL_INTERPOLATE_ARB; source0[num_tex] = setOtherColorSource(other); operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = setLocalColorSource(local); operand1[num_tex] = GL_SRC_COLOR; source2[num_tex] = GL_PREVIOUS_ARB; operand2[num_tex] = GL_SRC_COLOR; break; default: display_warning((unsigned char*)"grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL) : unknown factor : %x", factor); } break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: switch(factor) { case GR_COMBINE_FACTOR_TEXTURE_RGB: fct[num_tex] = GL_MODULATE; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_ONE_MINUS_SRC_COLOR; source1[num_tex] = setLocalColorSource(local); operand1[num_tex] = GL_SRC_COLOR; break; default: display_warning((unsigned char*)"grColorCombine(GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL) : unknown factor : %x", factor); } break; default: display_warning((unsigned char*)"grColorCombine : unknown function : %x", function); } updateCombiner(num_tex); if (nbTextureUnits > 3) { glActiveTextureARB(GL_TEXTURE3_ARB); updateCombiner(num_tex+1); } } } int setOtherAlphaSource(int other) { switch(other) { case GR_COMBINE_OTHER_ITERATED: return GL_PRIMARY_COLOR_ARB; break; case GR_COMBINE_OTHER_TEXTURE: return GL_PREVIOUS_ARB; break; case GR_COMBINE_OTHER_CONSTANT: return GL_CONSTANT_ARB; break; default: display_warning((unsigned char*)"unknwown other alpha source : %x", other); } return 0; } int setLocalAlphaSource(int local) { switch(local) { case GR_COMBINE_LOCAL_ITERATED: return GL_PRIMARY_COLOR_ARB; break; case GR_COMBINE_LOCAL_CONSTANT: return GL_CONSTANT_ARB; break; default: display_warning((unsigned char*)"unknwown local alpha source : %x", local); } return 0; } void writeGLSLAlphaOther(int other) { switch(other) { case GR_COMBINE_OTHER_ITERATED: strcat(fragment_shader_alpha_combiner, "float alpha_other = gl_Color.a; \n"); break; case GR_COMBINE_OTHER_TEXTURE: strcat(fragment_shader_alpha_combiner, "float alpha_other = ctexture1.a; \n"); break; case GR_COMBINE_OTHER_CONSTANT: strcat(fragment_shader_alpha_combiner, "float alpha_other = constant_color.a; \n"); break; default: display_warning((unsigned char*)"unknown writeGLSLAlphaOther : %x", other); } } void writeGLSLAlphaLocal(int local) { switch(local) { case GR_COMBINE_LOCAL_ITERATED: strcat(fragment_shader_alpha_combiner, "float alpha_local = gl_Color.a; \n"); break; case GR_COMBINE_LOCAL_CONSTANT: strcat(fragment_shader_alpha_combiner, "float alpha_local = constant_color.a; \n"); break; default: display_warning((unsigned char*)"unknown writeGLSLAlphaLocal : %x", local); } } void writeGLSLAlphaFactor(int factor, int local, int need_local, int other, int need_other) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: strcat(fragment_shader_alpha_combiner, "float alpha_factor = 0.0; \n"); break; case GR_COMBINE_FACTOR_LOCAL: if(need_local) writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "float alpha_factor = alpha_local; \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: if(need_other) writeGLSLAlphaOther(other); strcat(fragment_shader_alpha_combiner, "float alpha_factor = alpha_other; \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: if(need_local) writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "float alpha_factor = alpha_local; \n"); break; case GR_COMBINE_FACTOR_TEXTURE_ALPHA: strcat(fragment_shader_alpha_combiner, "float alpha_factor = ctexture1.a; \n"); break; case GR_COMBINE_FACTOR_ONE: strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: if(need_local) writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - alpha_local; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: if(need_other) writeGLSLAlphaOther(other); strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - alpha_other; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: if(need_local) writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - alpha_local; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: strcat(fragment_shader_alpha_combiner, "float alpha_factor = 1.0 - ctexture1.a; \n"); break; default: display_warning((unsigned char*)"unknown writeGLSLAlphaFactor : %x", factor); } } FX_ENTRY void FX_CALL grAlphaCombine( GrCombineFunction_t function, GrCombineFactor_t factor, GrCombineLocal_t local, GrCombineOther_t other, FxBool invert ) { if(glsl_support) { static int last_function = 0; static int last_factor = 0; static int last_local = 0; static int last_other = 0; if(last_function == function && last_factor == factor && last_local == local && last_other == other && first_alpha == 0) return; first_alpha = 0; last_function = function; last_factor = factor; last_local = local; last_other = other; if (invert) display_warning((unsigned char*)"grAlphaCombine : inverted result"); alpha_combiner_key = function | (factor << 4) | (local << 8) | (other << 10); chroma_other_alpha = other; strcpy(fragment_shader_alpha_combiner, ""); switch(function) { case GR_COMBINE_FUNCTION_ZERO: strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = 0.0; \n"); break; case GR_COMBINE_FUNCTION_LOCAL: writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_local; \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: writeGLSLAlphaLocal(local); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,1,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * alpha_other; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * alpha_other + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * alpha_other + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (alpha_other - alpha_local); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (alpha_other - alpha_local) + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLAlphaLocal(local); writeGLSLAlphaOther(other); writeGLSLAlphaFactor(factor,local,0,other,0); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (alpha_other - alpha_local) + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLAlphaLocal(local); writeGLSLAlphaFactor(factor,local,0,other,1); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (-alpha_local) + alpha_local; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLAlphaLocal(local); writeGLSLAlphaFactor(factor,local,0,other,1); strcat(fragment_shader_alpha_combiner, "gl_FragColor.a = alpha_factor * (-alpha_local) + alpha_local; \n"); break; default: display_warning((unsigned char*)"grAlphaCombine : unknown function : %x", function); } //compile_shader(); need_to_compile = 1; } else { int num_tex; if (invert) display_warning((unsigned char*)"grAlphaCombine : inverted result"); if (nbTextureUnits > 2) { glActiveTextureARB(GL_TEXTURE2_ARB); num_tex = 2; } else { glActiveTextureARB(GL_TEXTURE1_ARB); num_tex = 1; } fcta[num_tex+1] = GL_REPLACE; sourcea0[num_tex+1] = GL_PREVIOUS_ARB; operanda0[num_tex+1] = GL_SRC_ALPHA; switch(function) { case GR_COMBINE_FUNCTION_LOCAL: fcta[num_tex] = GL_REPLACE; sourcea0[num_tex] = setLocalAlphaSource(local); operanda0[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: switch (factor) { case GR_COMBINE_FACTOR_ONE: fcta[num_tex] = GL_REPLACE; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_LOCAL: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = setLocalAlphaSource(local); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = setOtherAlphaSource(other); operanda1[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = setLocalAlphaSource(local); operanda0[num_tex] = GL_ONE_MINUS_SRC_ALPHA; sourcea1[num_tex] = setOtherAlphaSource(other); operanda1[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_TEXTURE_ALPHA: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = GL_PREVIOUS_ARB; operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = setOtherAlphaSource(other); operanda1[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = GL_PREVIOUS_ARB; operanda0[num_tex] = GL_ONE_MINUS_SRC_ALPHA; sourcea1[num_tex] = setOtherAlphaSource(other); operanda1[num_tex] = GL_SRC_ALPHA; break; default: display_warning((unsigned char*)"grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER) : unknown factor : %x", factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: switch(factor) { case GR_COMBINE_FACTOR_TEXTURE_ALPHA: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = GL_PREVIOUS_ARB; operanda0[num_tex] = GL_SRC_ALPHA; fcta[num_tex+1] = GL_ADD; sourcea0[num_tex+1] = GL_PREVIOUS_ARB; operanda0[num_tex+1] = GL_SRC_ALPHA; sourcea1[num_tex+1] = setLocalAlphaSource(local); operanda1[num_tex+1] = GL_SRC_ALPHA; if (sourcea1[num_tex+1] == GL_PREVIOUS_ARB) sourcea1[num_tex+1] = GL_TEXTURE0_ARB; break; case GR_COMBINE_FACTOR_ONE_MINUS_TEXTURE_ALPHA: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = GL_PREVIOUS_ARB; operanda0[num_tex] = GL_ONE_MINUS_SRC_ALPHA; fcta[num_tex+1] = GL_ADD; sourcea0[num_tex+1] = GL_PREVIOUS_ARB; operanda0[num_tex+1] = GL_SRC_ALPHA; sourcea1[num_tex+1] = setLocalAlphaSource(local); operanda1[num_tex+1] = GL_SRC_ALPHA; if (sourcea1[num_tex+1] == GL_PREVIOUS_ARB) sourcea1[num_tex+1] = GL_TEXTURE0_ARB; break; case GR_COMBINE_FACTOR_LOCAL: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = setLocalAlphaSource(local); operanda0[num_tex] = GL_SRC_ALPHA; fcta[num_tex+1] = GL_ADD; sourcea0[num_tex+1] = GL_PREVIOUS_ARB; operanda0[num_tex+1] = GL_SRC_ALPHA; sourcea1[num_tex+1] = setLocalAlphaSource(local); operanda1[num_tex+1] = GL_SRC_ALPHA; if (sourcea1[num_tex+1] == GL_PREVIOUS_ARB) sourcea1[num_tex+1] = GL_TEXTURE0_ARB; break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = setLocalAlphaSource(local); operanda0[num_tex] = GL_ONE_MINUS_SRC_ALPHA; fcta[num_tex+1] = GL_ADD; sourcea0[num_tex+1] = GL_PREVIOUS_ARB; operanda0[num_tex+1] = GL_SRC_ALPHA; sourcea1[num_tex+1] = setLocalAlphaSource(local); operanda1[num_tex+1] = GL_SRC_ALPHA; if (sourcea1[num_tex+1] == GL_PREVIOUS_ARB) sourcea1[num_tex+1] = GL_TEXTURE0_ARB; break; case GR_COMBINE_FACTOR_ONE: fcta[num_tex] = GL_ADD; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = setLocalAlphaSource(local); operanda1[num_tex] = GL_SRC_ALPHA; break; default: display_warning((unsigned char*)"grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL) : unknown factor : %x", factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: switch(factor) { case GR_COMBINE_FACTOR_TEXTURE_ALPHA: // this combiner mode isn't implemented correctly and doesn't work on a TNT fcta[num_tex] = GL_SUBTRACT_ARB; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = setLocalAlphaSource(local); operanda1[num_tex] = GL_SRC_ALPHA; fcta[num_tex+1] = GL_MODULATE; sourcea0[num_tex+1] = GL_TEXTURE0_ARB; operanda0[num_tex+1] = GL_SRC_ALPHA; sourcea1[num_tex+1] = GL_PREVIOUS_ARB; operanda1[num_tex+1] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_LOCAL: fcta[num_tex] = GL_SUBTRACT_ARB; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = setLocalAlphaSource(local); operanda1[num_tex] = GL_SRC_ALPHA; fcta[num_tex+1] = GL_MODULATE; sourcea0[num_tex+1] = setLocalAlphaSource(local); operanda0[num_tex+1] = GL_SRC_ALPHA; sourcea1[num_tex+1] = GL_PREVIOUS_ARB; operanda1[num_tex+1] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_ONE: // doesn't work on a TNT fcta[num_tex] = GL_SUBTRACT_ARB; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = setLocalAlphaSource(local); operanda1[num_tex] = GL_SRC_ALPHA; break; default: display_warning((unsigned char*)"grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL) : unknown factor : %x", factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: switch(factor) { case GR_COMBINE_FACTOR_TEXTURE_ALPHA: fcta[num_tex] = GL_INTERPOLATE_ARB; sourcea0[num_tex] = setOtherAlphaSource(other); operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = setLocalAlphaSource(local); operanda1[num_tex] = GL_SRC_ALPHA; sourcea2[num_tex] = GL_PREVIOUS_ARB; operanda2[num_tex] = GL_SRC_ALPHA; break; default: display_warning((unsigned char*)"grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL) : unknown factor : %x", factor); } break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: switch(factor) { case GR_COMBINE_FACTOR_TEXTURE_ALPHA: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = GL_PREVIOUS_ARB; operanda0[num_tex] = GL_ONE_MINUS_SRC_ALPHA; sourcea1[num_tex] = setLocalAlphaSource(local); operanda1[num_tex] = GL_SRC_ALPHA; break; default: display_warning((unsigned char*)"grAlphaCombine(GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL) : unknown factor : %x", factor); } break; default: display_warning((unsigned char*)"grAlphaCombine : unknown function : %x", function); } updateCombinera(num_tex); if (nbTextureUnits > 3) { glActiveTextureARB(GL_TEXTURE3_ARB); updateCombinera(num_tex+1); } } } void writeGLSLTextureColorFactor(int num_tex, int factor) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(0.0); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(0.0); \n"); break; case GR_COMBINE_FACTOR_LOCAL: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = texture2D(texture0, vec2(gl_TexCoord[0])); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = texture2D(texture1, vec2(gl_TexCoord[1])); \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(0.0); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(ctexture0.a); \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(texture2D(texture0, vec2(gl_TexCoord[0])).a); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(texture2D(texture1, vec2(gl_TexCoord[1])).a); \n"); break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(lambda); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(lambda); \n"); break; case GR_COMBINE_FACTOR_ONE: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - texture2D(texture0, vec2(gl_TexCoord[0])); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - texture2D(texture1, vec2(gl_TexCoord[1])); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - vec4(0.0); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - vec4(ctexture0.a); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - vec4(texture2D(texture0, vec2(gl_TexCoord[0])).a); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - vec4(texture2D(texture1, vec2(gl_TexCoord[1])).a); \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 texture0_color_factor = vec4(1.0) - vec4(lambda); \n"); else strcat(fragment_shader_texture1, "vec4 texture1_color_factor = vec4(1.0) - vec4(lambda); \n"); break; default: display_warning((unsigned char*)"unknown writeGLSLTextureColorFactor : %x", factor); } } void writeGLSLTextureAlphaFactor(int num_tex, int factor) { switch(factor) { case GR_COMBINE_FACTOR_ZERO: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = 0.0; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = 0.0; \n"); break; case GR_COMBINE_FACTOR_LOCAL: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FACTOR_OTHER_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = 0.0; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = ctexture0.a; \n"); break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = lambda; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = lambda; \n"); break; case GR_COMBINE_FACTOR_ONE: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_OTHER_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - 0.0; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - ctexture0.a; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_LOCAL_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FACTOR_ONE_MINUS_DETAIL_FACTOR: if(num_tex == 0) strcat(fragment_shader_texture0, "float texture0_alpha_factor = 1.0 - lambda; \n"); else strcat(fragment_shader_texture1, "float texture1_alpha_factor = 1.0 - lambda; \n"); break; default: display_warning((unsigned char*)"unknown writeGLSLTextureAlphaFactor : %x", factor); } } FX_ENTRY void FX_CALL grTexCombine( GrChipID_t tmu, GrCombineFunction_t rgb_function, GrCombineFactor_t rgb_factor, GrCombineFunction_t alpha_function, GrCombineFactor_t alpha_factor, FxBool rgb_invert, FxBool alpha_invert ) { if(glsl_support) { int num_tex; if (rgb_invert) display_warning((unsigned char*)"grTexCombine : inverted rgb result"); if (alpha_invert) display_warning((unsigned char*)"grTexCombine : inverted alpha result"); if (tmu == GR_TMU0) num_tex = 1; else num_tex = 0; if(num_tex == 0) { static int last_function = 0; static int last_factor = 0; static int last_afunction = 0; static int last_afactor = 0; if(last_function == rgb_function && last_factor == rgb_factor && last_afunction == alpha_function && last_afactor == alpha_factor && first_texture0 == 0) return; first_texture0 = 0; last_function = rgb_function; last_factor = rgb_factor; last_afunction = alpha_function; last_afactor = alpha_factor; texture0_combiner_key = rgb_function | (rgb_factor << 4) | (alpha_function << 8) | (alpha_factor << 12); strcpy(fragment_shader_texture0, ""); } else { static int last_function = 0; static int last_factor = 0; static int last_afunction = 0; static int last_afactor = 0; if(last_function == rgb_function && last_factor == rgb_factor && last_afunction == alpha_function && last_afactor == alpha_factor && first_texture1 == 0) return; first_texture1 = 0; last_function = rgb_function; last_factor = rgb_factor; last_afunction = alpha_function; last_afactor = alpha_factor; texture1_combiner_key = rgb_function | (rgb_factor << 4) | (alpha_function << 8) | (alpha_factor << 12); strcpy(fragment_shader_texture1, ""); } switch(rgb_function) { case GR_COMBINE_FUNCTION_ZERO: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = vec4(0.0); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = vec4(0.0); \n"); break; case GR_COMBINE_FUNCTION_LOCAL: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture2D(texture0, vec2(gl_TexCoord[0])); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture2D(texture1, vec2(gl_TexCoord[1])); \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = vec4(texture2D(texture0, vec2(gl_TexCoord[0])).a); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = vec4(texture2D(texture1, vec2(gl_TexCoord[1])).a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLTextureColorFactor(num_tex, rgb_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * vec4(0.0); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * ctexture0; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLTextureColorFactor(num_tex, rgb_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * vec4(0.0) + texture2D(texture0, vec2(gl_TexCoord[0])); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * ctexture0 + texture2D(texture1, vec2(gl_TexCoord[1])); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLTextureColorFactor(num_tex, rgb_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * vec4(0.0) + vec4(texture2D(texture0, vec2(gl_TexCoord[0])).a); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * ctexture0 + vec4(texture2D(texture1, vec2(gl_TexCoord[1])).a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLTextureColorFactor(num_tex, rgb_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (vec4(0.0) - texture2D(texture0, vec2(gl_TexCoord[0]))); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (ctexture0 - texture2D(texture1, vec2(gl_TexCoord[1]))); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureColorFactor(num_tex, rgb_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (vec4(0.0) - texture2D(texture0, vec2(gl_TexCoord[0]))) + texture2D(texture0, vec2(gl_TexCoord[0])); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (ctexture0 - texture2D(texture1, vec2(gl_TexCoord[1]))) + texture2D(texture1, vec2(gl_TexCoord[1])); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureColorFactor(num_tex, rgb_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (vec4(0.0) - texture2D(texture0, vec2(gl_TexCoord[0]))) + vec4(texture2D(texture0, vec2(gl_TexCoord[0])).a); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (ctexture0 - texture2D(texture1, vec2(gl_TexCoord[1]))) + vec4(texture2D(texture1, vec2(gl_TexCoord[1])).a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureColorFactor(num_tex, rgb_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (-texture2D(texture0, vec2(gl_TexCoord[0]))) + texture2D(texture0, vec2(gl_TexCoord[0])); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (-texture2D(texture1, vec2(gl_TexCoord[1]))) + texture2D(texture1, vec2(gl_TexCoord[1])); \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureColorFactor(num_tex, rgb_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture0_color_factor * (-texture2D(texture0, vec2(gl_TexCoord[0]))) + vec4(texture2D(texture0, vec2(gl_TexCoord[0])).a); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture1_color_factor * (-texture2D(texture1, vec2(gl_TexCoord[1]))) + vec4(texture2D(texture1, vec2(gl_TexCoord[1])).a); \n"); break; default: if(num_tex == 0) strcat(fragment_shader_texture0, "vec4 ctexture0 = texture2D(texture0, vec2(gl_TexCoord[0])); \n"); else strcat(fragment_shader_texture1, "vec4 ctexture1 = texture2D(texture1, vec2(gl_TexCoord[1])); \n"); display_warning((unsigned char*)"grTextCombine : unknown rgb function : %x", rgb_function); } switch(alpha_function) { case GR_COMBINE_FACTOR_ZERO: if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = 0.0; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = 0.0; \n"); break; case GR_COMBINE_FUNCTION_LOCAL: if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FUNCTION_LOCAL_ALPHA: if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER: writeGLSLTextureAlphaFactor(num_tex, alpha_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * 0.0; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * ctexture0.a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: writeGLSLTextureAlphaFactor(num_tex, alpha_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * 0.0 + texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * ctexture0.a + texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL_ALPHA: writeGLSLTextureAlphaFactor(num_tex, alpha_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * 0.0 + texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * ctexture0.a + texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: writeGLSLTextureAlphaFactor(num_tex, alpha_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (0.0 - texture2D(texture1, vec2(gl_TexCoord[1])).a); \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (ctexture0.a - texture2D(texture1, vec2(gl_TexCoord[1])).a); \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureAlphaFactor(num_tex, alpha_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (0.0 - texture2D(texture0, vec2(gl_TexCoord[0])).a) + texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (ctexture0.a - texture2D(texture1, vec2(gl_TexCoord[1])).a) + texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureAlphaFactor(num_tex, alpha_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (0.0 - texture2D(texture0, vec2(gl_TexCoord[0])).a) + texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (ctexture0.a - texture2D(texture1, vec2(gl_TexCoord[1])).a) + texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: writeGLSLTextureAlphaFactor(num_tex, alpha_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (-texture2D(texture0, vec2(gl_TexCoord[0])).a) + texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (-texture2D(texture1, vec2(gl_TexCoord[1])).a) + texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: writeGLSLTextureAlphaFactor(num_tex, alpha_factor); if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture0_alpha_factor * (-texture2D(texture0, vec2(gl_TexCoord[0])).a) + texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = texture1_alpha_factor * (-texture2D(texture1, vec2(gl_TexCoord[1])).a) + texture2D(texture1, vec2(gl_TexCoord[1])).a; \n"); break; default: if(num_tex == 0) strcat(fragment_shader_texture0, "ctexture0.a = texture2D(texture0, vec2(gl_TexCoord[0])).a; \n"); else strcat(fragment_shader_texture1, "ctexture1.a = ctexture0.a; \n"); display_warning((unsigned char*)"grTextCombine : unknown alpha function : %x", alpha_function); } //compile_shader(); need_to_compile = 1; } else { int num_tex; int will_need_lambda = 0; if (rgb_invert) display_warning((unsigned char*)"grTexCombine : inverted rgb result"); if (alpha_invert) display_warning((unsigned char*)"grTexCombine : inverted alpha result"); if (tmu == GR_TMU1 && nbTextureUnits <= 2) return; if (tmu == GR_TMU0) { if (nbTextureUnits <= 2) { glActiveTextureARB(GL_TEXTURE0_ARB); num_tex = 0; } else { glActiveTextureARB(GL_TEXTURE1_ARB); num_tex = 1; } } else { glActiveTextureARB(GL_TEXTURE0_ARB); num_tex = 0; } switch(rgb_function) { case GR_COMBINE_FUNCTION_ZERO: fct[num_tex] = GL_REPLACE; source0[num_tex] = GL_PRIMARY_COLOR_ARB; operand0[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FUNCTION_LOCAL: fct[num_tex] = GL_REPLACE; source0[num_tex] = GL_TEXTURE; operand0[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: switch(rgb_factor) { case GR_COMBINE_FACTOR_LOCAL: fct[num_tex] = GL_MODULATE; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = GL_TEXTURE; operand1[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FACTOR_LOCAL_ALPHA: fct[num_tex] = GL_MODULATE; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = GL_TEXTURE; operand1[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_ONE: fct[num_tex] = GL_REPLACE; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_COLOR; break; default: display_warning((unsigned char*)"grTextCombine(GR_COMBINE_FUNCTION_SCALE_OTHER) : unknown rgb factor : %x", rgb_factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: switch(rgb_factor) { case GR_COMBINE_FACTOR_ONE: fct[num_tex] = GL_ADD; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = GL_TEXTURE; operand1[num_tex] = GL_SRC_COLOR; break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: if (num_tex==1) { fct[num_tex-1] = GL_MODULATE; source0[num_tex-1] = GL_TEXTURE; operand0[num_tex-1] = GL_SRC_COLOR; source1[num_tex-1] = GL_CONSTANT_ARB; operand1[num_tex-1] = GL_SRC_ALPHA; fct[num_tex] = GL_ADD; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = GL_TEXTURE; operand1[num_tex] = GL_SRC_COLOR; will_need_lambda = 1; } break; default: display_warning((unsigned char*)"grTextCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL) : unknown rgb factor : %x", rgb_factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: switch(rgb_factor) { case GR_COMBINE_FACTOR_DETAIL_FACTOR: fct[num_tex] = GL_INTERPOLATE_ARB; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = GL_TEXTURE; operand1[num_tex] = GL_SRC_COLOR; source2[num_tex] = GL_CONSTANT_ARB; operand2[num_tex] = GL_SRC_ALPHA; will_need_lambda = 1; break; default: display_warning((unsigned char*)"grTextCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL) : unknown rgb factor : %x", rgb_factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL: switch(rgb_factor) { case GR_COMBINE_FACTOR_LOCAL: // this combiner mode isn't implemented correctly and doesn't work on a TNT if (num_tex==1) { fct[num_tex-1] = GL_SUBTRACT_ARB; source0[num_tex-1] = GL_TEXTURE0_ARB; operand0[num_tex-1] = GL_SRC_COLOR; source1[num_tex-1] = GL_TEXTURE1_ARB; operand1[num_tex-1] = GL_SRC_COLOR; fct[num_tex] = GL_MODULATE; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_COLOR; source1[num_tex] = GL_TEXTURE; operand1[num_tex] = GL_SRC_COLOR; } break; default: display_warning((unsigned char*)"grTextCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL) : unknown rgb factor : %x", rgb_factor); } default: display_warning((unsigned char*)"grTextCombine : unknown rgb function : %x", rgb_function); } switch(alpha_function) { case GR_COMBINE_FUNCTION_ZERO: fcta[num_tex] = GL_REPLACE; sourcea0[num_tex] = GL_PRIMARY_COLOR_ARB; operanda0[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FUNCTION_LOCAL: fcta[num_tex] = GL_REPLACE; sourcea0[num_tex] = GL_TEXTURE; operanda0[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FUNCTION_SCALE_OTHER: switch(alpha_factor) { case GR_COMBINE_FACTOR_LOCAL: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = GL_TEXTURE; operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = GL_PREVIOUS_ARB; operanda1[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_ONE: fcta[num_tex] = GL_REPLACE; sourcea0[num_tex] = GL_PREVIOUS_ARB; operanda0[num_tex] = GL_SRC_ALPHA; break; default: display_warning((unsigned char*)"grTextCombine(GR_COMBINE_FUNCTION_SCALE_OTHER) : unknown alpha factor : %x", alpha_factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL: switch(alpha_factor) { case GR_COMBINE_FACTOR_ONE: fcta[num_tex] = GL_ADD; sourcea0[num_tex] = GL_PREVIOUS_ARB; operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = GL_TEXTURE; operanda1[num_tex] = GL_SRC_ALPHA; break; case GR_COMBINE_FACTOR_DETAIL_FACTOR: if (num_tex==1) { fct[num_tex-1] = GL_MODULATE; source0[num_tex-1] = GL_TEXTURE; operand0[num_tex-1] = GL_SRC_ALPHA; source1[num_tex-1] = GL_CONSTANT_ARB; operand1[num_tex-1] = GL_SRC_ALPHA; fct[num_tex] = GL_ADD; source0[num_tex] = GL_PREVIOUS_ARB; operand0[num_tex] = GL_SRC_ALPHA; source1[num_tex] = GL_TEXTURE; operand1[num_tex] = GL_SRC_ALPHA; will_need_lambda = 1; } break; default: display_warning((unsigned char*)"grTextCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL) : unknown alpha factor : %x", alpha_factor); } break; case GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL: switch(alpha_factor) { case GR_COMBINE_FACTOR_DETAIL_FACTOR: fcta[num_tex] = GL_INTERPOLATE_ARB; sourcea0[num_tex] = GL_PREVIOUS_ARB; operanda0[num_tex] = GL_SRC_ALPHA; sourcea1[num_tex] = GL_TEXTURE; operanda1[num_tex] = GL_SRC_ALPHA; sourcea2[num_tex] = GL_CONSTANT_ARB; operanda2[num_tex] = GL_SRC_ALPHA; will_need_lambda = 1; break; default: display_warning((unsigned char*)"grTextCombine(GR_COMBINE_FUNCTION_SCALE_OTHER_MINUS_LOCAL_ADD_LOCAL) : unknown alpha factor : %x", alpha_factor); } break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL: switch(alpha_factor) { case GR_COMBINE_FACTOR_DETAIL_FACTOR: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = GL_CONSTANT_ARB; operanda0[num_tex] = GL_ONE_MINUS_SRC_ALPHA; sourcea1[num_tex] = GL_TEXTURE; operanda1[num_tex] = GL_SRC_ALPHA; will_need_lambda = 1; break; default: display_warning((unsigned char*)"grTextCombine(GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL) : unknown alpha factor : %x", alpha_factor); } break; case GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA: switch(alpha_factor) { case GR_COMBINE_FACTOR_OTHER_ALPHA: fcta[num_tex] = GL_MODULATE; sourcea0[num_tex] = GL_PREVIOUS_ARB; operanda0[num_tex] = GL_ONE_MINUS_SRC_ALPHA; sourcea1[num_tex] = GL_TEXTURE; operanda1[num_tex] = GL_SRC_ALPHA; break; default: display_warning((unsigned char*)"grTextCombine(GR_COMBINE_FUNCTION_SCALE_MINUS_LOCAL_ADD_LOCAL_ALPHA) : unknown alpha factor : %x", alpha_factor); } break; default: display_warning((unsigned char*)"grTextCombine : unknown alpha function : %x", alpha_function); } if (will_need_lambda != need_lambda[num_tex]) { need_lambda[num_tex] = will_need_lambda; if (need_lambda[num_tex]) { int i; for (i=0; i<3; i++) lambda_color[num_tex][i] = texture_env_color[i]; lambda_color[num_tex][3] = lambda; glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, lambda_color[num_tex]); } else glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, texture_env_color); } updateCombiner(num_tex); updateCombinera(num_tex); } } FX_ENTRY void FX_CALL grAlphaBlendFunction( GrAlphaBlendFnc_t rgb_sf, GrAlphaBlendFnc_t rgb_df, GrAlphaBlendFnc_t alpha_sf, GrAlphaBlendFnc_t alpha_df ) { int sfactorRGB = 0, dfactorRGB = 0, sfactorAlpha = 0, dfactorAlpha = 0; switch(rgb_sf) { case GR_BLEND_ZERO: sfactorRGB = GL_ZERO; break; case GR_BLEND_SRC_ALPHA: sfactorRGB = GL_SRC_ALPHA; break; case GR_BLEND_ONE: sfactorRGB = GL_ONE; break; case GR_BLEND_ONE_MINUS_SRC_ALPHA: sfactorRGB = GL_ONE_MINUS_SRC_ALPHA; break; default: display_warning((unsigned char*)"grAlphaBlendFunction : rgb_sf = %x", rgb_sf); } switch(rgb_df) { case GR_BLEND_ZERO: dfactorRGB = GL_ZERO; break; case GR_BLEND_SRC_ALPHA: dfactorRGB = GL_SRC_ALPHA; break; case GR_BLEND_ONE: dfactorRGB = GL_ONE; break; case GR_BLEND_ONE_MINUS_SRC_ALPHA: dfactorRGB = GL_ONE_MINUS_SRC_ALPHA; break; default: display_warning((unsigned char*)"grAlphaBlendFunction : rgb_df = %x", rgb_df); } switch(alpha_sf) { case GR_BLEND_ZERO: sfactorAlpha = GL_ZERO; break; case GR_BLEND_ONE: sfactorAlpha = GL_ONE; break; default: display_warning((unsigned char*)"grAlphaBlendFunction : alpha_sf = %x", alpha_sf); } switch(alpha_df) { case GR_BLEND_ZERO: dfactorAlpha = GL_ZERO; break; case GR_BLEND_ONE: dfactorAlpha = GL_ONE; break; default: display_warning((unsigned char*)"grAlphaBlendFunction : alpha_df = %x", alpha_df); } glEnable(GL_BLEND); if (blend_func_separate_support) glBlendFuncSeparateEXT(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); else glBlendFunc(sfactorRGB, dfactorRGB); } FX_ENTRY void FX_CALL grAlphaTestReferenceValue( GrAlpha_t value ) { alpha_ref = value; grAlphaTestFunction(alpha_func); } FX_ENTRY void FX_CALL grAlphaTestFunction( GrCmpFnc_t function ) { alpha_func = function; switch(function) { case GR_CMP_GREATER: glAlphaFunc(GL_GREATER, alpha_ref/255.0f); break; case GR_CMP_GEQUAL: glAlphaFunc(GL_GEQUAL, alpha_ref/255.0f); break; case GR_CMP_ALWAYS: glAlphaFunc(GL_ALWAYS, alpha_ref/255.0f); glDisable(GL_ALPHA_TEST); return; break; default: display_warning((unsigned char*)"grAlphaTestFunction : unknown function : %x", function); } glEnable(GL_ALPHA_TEST); } // fog FX_ENTRY void FX_CALL grFogMode( GrFogMode_t mode ) { switch(mode) { case GR_FOG_DISABLE: glDisable(GL_FOG); fog_enabled = 0; break; case GR_FOG_WITH_TABLE_ON_Q: glEnable(GL_FOG); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); fog_enabled = 1; break; case GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT: glEnable(GL_FOG); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); fog_enabled = 2; break; default: display_warning((unsigned char*)"grFogMode : unknown mode : %x", mode); } if(glsl_support) need_to_compile = 1; } FX_ENTRY float FX_CALL guFogTableIndexToW( int i ) { return (float)(pow(2.0, 3.0+(double)(i>>2)) / (8-(i&3))); } FX_ENTRY void FX_CALL guFogGenerateLinear(GrFog_t *fogtable, float nearZ, float farZ ) { /*if(!glsl_support) {*/ glFogi(GL_FOG_MODE, GL_LINEAR); glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); glFogf(GL_FOG_START, nearZ /** 100.0f*/); glFogf(GL_FOG_END, farZ /** 100.0f*/); /*} else { int near_location; int far_location; nearF = nearZ / 256.0f; farF = farF / 256.0f; near_location = glGetUniformLocationARB(program_object, "near"); glUniform1fARB(near_location, nearF); far_location = glGetUniformLocationARB(program_object, "far"); glUniform1fARB(far_location, farF); }*/ } FX_ENTRY void FX_CALL grFogTable( const GrFog_t ft[] ) { } FX_ENTRY void FX_CALL grFogColorValue( GrColor_t fogcolor ) { float color[4]; switch(lfb_color_fmt) { case GR_COLORFORMAT_ARGB: color[3] = ((fogcolor >> 24) & 0xFF) / 255.0f; color[0] = ((fogcolor >> 16) & 0xFF) / 255.0f; color[1] = ((fogcolor >> 8) & 0xFF) / 255.0f; color[2] = (fogcolor & 0xFF) / 255.0f; break; case GR_COLORFORMAT_RGBA: color[0] = ((fogcolor >> 24) & 0xFF) / 255.0f; color[1] = ((fogcolor >> 16) & 0xFF) / 255.0f; color[2] = ((fogcolor >> 8) & 0xFF) / 255.0f; color[3] = (fogcolor & 0xFF) / 255.0f; break; default: display_warning((unsigned char*)"grFogColorValue: unknown color format : %x", lfb_color_fmt); } glFogfv(GL_FOG_COLOR, color); } // chroma FX_ENTRY void FX_CALL grChromakeyMode( GrChromakeyMode_t mode ) { switch(mode) { case GR_CHROMAKEY_DISABLE: chroma_enabled = 0; break; case GR_CHROMAKEY_ENABLE: if(!glsl_support) display_warning((unsigned char*)"grChromakeyMode : unknown mode : %x", mode); else chroma_enabled = 1; break; default: display_warning((unsigned char*)"grChromakeyMode : unknown mode : %x", mode); } } FX_ENTRY void FX_CALL grChromakeyValue( GrColor_t value ) { if(!glsl_support) display_warning((unsigned char*)"grChromakeyValue"); else { int chroma_color_location; switch(lfb_color_fmt) { case GR_COLORFORMAT_ARGB: chroma_color[3] = ((value >> 24) & 0xFF) / 255.0f; chroma_color[0] = ((value >> 16) & 0xFF) / 255.0f; chroma_color[1] = ((value >> 8) & 0xFF) / 255.0f; chroma_color[2] = (value & 0xFF) / 255.0f; break; case GR_COLORFORMAT_RGBA: chroma_color[0] = ((value >> 24) & 0xFF) / 255.0f; chroma_color[1] = ((value >> 16) & 0xFF) / 255.0f; chroma_color[2] = ((value >> 8) & 0xFF) / 255.0f; chroma_color[3] = (value & 0xFF) / 255.0f; break; default: display_warning((unsigned char*)"grChromakeyValue: unknown color format : %x", lfb_color_fmt); } chroma_color_location = glGetUniformLocationARB(program_object, "chroma_color"); glUniform4fARB(chroma_color_location, chroma_color[0], chroma_color[1], chroma_color[2], chroma_color[3]); } }