From eea2c95727a2d6ba2ab9955b661c59d411412ab9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20D=C3=B6singer?= Date: Sat, 12 Jul 2008 11:45:33 -0500 Subject: [PATCH] wined3d: Move set_tex_op(_nvrc) to their specific files. --- dlls/wined3d/nvidia_texture_shader.c | 385 +++++++ dlls/wined3d/state.c | 1109 +++++++++++++++++++ dlls/wined3d/utils.c | 1496 +------------------------- dlls/wined3d/wined3d_private.h | 3 +- 4 files changed, 1499 insertions(+), 1494 deletions(-) diff --git a/dlls/wined3d/nvidia_texture_shader.c b/dlls/wined3d/nvidia_texture_shader.c index 6844a9b88ea..e2176785553 100644 --- a/dlls/wined3d/nvidia_texture_shader.c +++ b/dlls/wined3d/nvidia_texture_shader.c @@ -65,6 +65,391 @@ void nvts_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, W } } +typedef struct { + GLenum input[3]; + GLenum mapping[3]; + GLenum component_usage[3]; +} tex_op_args; + +static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) { + switch (d3dta) { + case WINED3DTA_DIFFUSE: + return GL_PRIMARY_COLOR_NV; + + case WINED3DTA_CURRENT: + if (stage) return GL_SPARE0_NV; + else return GL_PRIMARY_COLOR_NV; + + case WINED3DTA_TEXTURE: + if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx; + else return GL_PRIMARY_COLOR_NV; + + case WINED3DTA_TFACTOR: + return GL_CONSTANT_COLOR0_NV; + + case WINED3DTA_SPECULAR: + return GL_SECONDARY_COLOR_NV; + + case WINED3DTA_TEMP: + return GL_SPARE1_NV; + + case WINED3DTA_CONSTANT: + /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */ + FIXME("WINED3DTA_CONSTANT, not properly supported.\n"); + return GL_CONSTANT_COLOR1_NV; + + default: + FIXME("Unrecognized texture arg %#x\n", d3dta); + return GL_TEXTURE; + } +} + +static GLenum invert_mapping(GLenum mapping) { + if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV; + else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV; + + FIXME("Unhandled mapping %#x\n", mapping); + return mapping; +} + +static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) { + /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should + * be used. */ + if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV; + else *mapping = GL_SIGNED_IDENTITY_NV; + + /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input + * should be used for all input components. */ + if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA; + else *component_usage = GL_RGB; + + *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx); +} + +void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface; + tex_op_args tex_op_args = {{0}, {0}, {0}}; + GLenum portion = is_alpha ? GL_ALPHA : GL_RGB; + GLenum target = GL_COMBINER0_NV + stage; + GLenum output; + IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* For GLINFO_LOCATION */ + + TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", + stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx); + + /* If a texture stage references an invalid texture unit the stage just + * passes through the result from the previous stage */ + if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) { + arg1 = WINED3DTA_CURRENT; + op = WINED3DTOP_SELECTARG1; + } + + get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0], + &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx); + get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1], + &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx); + get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2], + &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx); + + + if(dst == WINED3DTA_TEMP) { + output = GL_SPARE1_NV; + } else { + output = GL_SPARE0_NV; + } + + /* This is called by a state handler which has the gl lock held and a context for the thread */ + switch(op) + { + case WINED3DTOP_DISABLE: + /* Only for alpha */ + if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n"); + /* Input, prev_alpha*1 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_SELECTARG1: + case WINED3DTOP_SELECTARG2: + /* Input, arg*1 */ + if (op == WINED3DTOP_SELECTARG1) { + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + } else { + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + } + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MODULATE: + case WINED3DTOP_MODULATE2X: + case WINED3DTOP_MODULATE4X: + /* Input, arg1*arg2 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + + /* Output */ + if (op == WINED3DTOP_MODULATE) { + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + } else if (op == WINED3DTOP_MODULATE2X) { + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + } else if (op == WINED3DTOP_MODULATE4X) { + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + } + break; + + case WINED3DTOP_ADD: + case WINED3DTOP_ADDSIGNED: + case WINED3DTOP_ADDSIGNED2X: + /* Input, arg1*1+arg2*1 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + if (op == WINED3DTOP_ADD) { + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + } else if (op == WINED3DTOP_ADDSIGNED) { + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE)); + } else if (op == WINED3DTOP_ADDSIGNED2X) { + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE)); + } + break; + + case WINED3DTOP_SUBTRACT: + /* Input, arg1*1+-arg2*1 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_ADDSMOOTH: + /* Input, arg1*1+(1-arg1)*arg2 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_BLENDDIFFUSEALPHA: + case WINED3DTOP_BLENDTEXTUREALPHA: + case WINED3DTOP_BLENDFACTORALPHA: + case WINED3DTOP_BLENDTEXTUREALPHAPM: + case WINED3DTOP_BLENDCURRENTALPHA: + { + GLenum alpha_src = GL_PRIMARY_COLOR_NV; + if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx); + else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx); + else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx); + else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx); + else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx); + else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op)); + + /* Input, arg1*alpha_src+arg2*(1-alpha_src) */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) + { + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + } else { + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA)); + } + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + } + + case WINED3DTOP_MODULATEALPHA_ADDCOLOR: + /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */ + if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n"); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MODULATECOLOR_ADDALPHA: + /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */ + if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n"); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: + /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */ + if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n"); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: + /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */ + if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n"); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_DOTPRODUCT3: + /* Input, arg1 . arg2 */ + /* FIXME: DX7 uses a different calculation? */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1])); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_MULTIPLYADD: + /* Input, arg3*1+arg1*arg2 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_LERP: + /* Input, arg3*arg1+(1-arg3)*arg2 */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, + tex_op_args.input[2], invert_mapping(tex_op_args.mapping[2]), tex_op_args.component_usage[2])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + + /* Output */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, + output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + + case WINED3DTOP_BUMPENVMAPLUMINANCE: + case WINED3DTOP_BUMPENVMAP: + if(GL_SUPPORT(NV_TEXTURE_SHADER)) { + /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to + * perform bump mapping and source from the current stage. Pretty much a SELECTARG2. + * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1 + * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage + */ + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, + tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); + GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, + GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); + /* Always pass through to CURRENT, ignore temp arg */ + GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV, + GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); + break; + } + + default: + FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", + stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx); + } + + checkGLcall("set_tex_op_nvrc()\n"); + +} + + static void nvrc_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE; DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage]; diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 9ff10a1a39f..9e29d78fd33 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -1840,6 +1840,1115 @@ static void state_ckeyblend(DWORD state, IWineD3DStateBlockImpl *stateblock, Win } } +/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/ +#if defined (GL_VERSION_1_3) +# define useext(A) A +#elif defined (GL_EXT_texture_env_combine) +# define useext(A) A##_EXT +#elif defined (GL_ARB_texture_env_combine) +# define useext(A) A##_ARB +#endif + +static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) { + /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the + * input should be used for all input components. The WINED3DTA_COMPLEMENT + * flag specifies the complement of the input should be used. */ + BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE; + BOOL complement = arg & WINED3DTA_COMPLEMENT; + + /* Calculate the operand */ + if (complement) { + if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA; + else *operand = GL_ONE_MINUS_SRC_COLOR; + } else { + if (from_alpha) *operand = GL_SRC_ALPHA; + else *operand = GL_SRC_COLOR; + } + + /* Calculate the source */ + switch (arg & WINED3DTA_SELECTMASK) { + case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break; + case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break; + case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break; + case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break; + case WINED3DTA_SPECULAR: + /* + * According to the GL_ARB_texture_env_combine specs, SPECULAR is + * 'Secondary color' and isn't supported until base GL supports it + * There is no concept of temp registers as far as I can tell + */ + FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n"); + *source = GL_TEXTURE; + break; + default: + FIXME("Unrecognized texture arg %#x\n", arg); + *source = GL_TEXTURE; + break; + } +} + +/* Setup the texture operations texture stage states */ +static void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) +{ + GLenum src1, src2, src3; + GLenum opr1, opr2, opr3; + GLenum comb_target; + GLenum src0_target, src1_target, src2_target; + GLenum opr0_target, opr1_target, opr2_target; + GLenum scal_target; + GLenum opr=0, invopr, src3_target, opr3_target; + BOOL Handled = FALSE; + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; + IWineD3DStateBlockImpl *stateblock = This->stateBlock; /* for GLINFO_LOCATION */ + + TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3); + + /* This is called by a state handler which has the gl lock held and a context for the thread */ + + /* Note: Operations usually involve two ars, src0 and src1 and are operations of + the form (a1 a2). However, some of the more complex operations + take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added + in a third parameter called a0. Therefore these are operations of the form + a0 a1 a2, i.e., the new parameter goes to the front. + + However, below we treat the new (a0) parameter as src2/opr2, so in the actual + functions below, expect their syntax to differ slightly to those listed in the + manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2 + This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */ + + if (isAlpha) { + comb_target = useext(GL_COMBINE_ALPHA); + src0_target = useext(GL_SOURCE0_ALPHA); + src1_target = useext(GL_SOURCE1_ALPHA); + src2_target = useext(GL_SOURCE2_ALPHA); + opr0_target = useext(GL_OPERAND0_ALPHA); + opr1_target = useext(GL_OPERAND1_ALPHA); + opr2_target = useext(GL_OPERAND2_ALPHA); + scal_target = GL_ALPHA_SCALE; + } + else { + comb_target = useext(GL_COMBINE_RGB); + src0_target = useext(GL_SOURCE0_RGB); + src1_target = useext(GL_SOURCE1_RGB); + src2_target = useext(GL_SOURCE2_RGB); + opr0_target = useext(GL_OPERAND0_RGB); + opr1_target = useext(GL_OPERAND1_RGB); + opr2_target = useext(GL_OPERAND2_RGB); + scal_target = useext(GL_RGB_SCALE); + } + + /* If a texture stage references an invalid texture unit the stage just + * passes through the result from the previous stage */ + if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) { + arg1 = WINED3DTA_CURRENT; + op = WINED3DTOP_SELECTARG1; + } + + /* From MSDN (WINED3DTSS_ALPHAARG1) : + The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage, + then the default argument is WINED3DTA_DIFFUSE. + FIXME? If texture added/removed, may need to reset back as well? */ + if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) { + get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1); + } else { + get_src_and_opr(arg1, isAlpha, &src1, &opr1); + } + get_src_and_opr(arg2, isAlpha, &src2, &opr2); + get_src_and_opr(arg3, isAlpha, &src3, &opr3); + + TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3); + + Handled = TRUE; /* Assume will be handled */ + + /* Other texture operations require special extensions: */ + if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { + if (isAlpha) { + opr = GL_SRC_ALPHA; + invopr = GL_ONE_MINUS_SRC_ALPHA; + src3_target = GL_SOURCE3_ALPHA_NV; + opr3_target = GL_OPERAND3_ALPHA_NV; + } else { + opr = GL_SRC_COLOR; + invopr = GL_ONE_MINUS_SRC_COLOR; + src3_target = GL_SOURCE3_RGB_NV; + opr3_target = GL_OPERAND3_RGB_NV; + } + switch (op) { + case WINED3DTOP_DISABLE: /* Only for alpha */ + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + break; + case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */ + case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */ + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + if (op == WINED3DTOP_SELECTARG1) { + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + } else { + glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); + checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); + } + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + break; + + case WINED3DTOP_MODULATE: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATE2X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); + checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); + break; + case WINED3DTOP_MODULATE4X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); + checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); + break; + + case WINED3DTOP_ADD: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + + case WINED3DTOP_ADDSIGNED: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + + case WINED3DTOP_ADDSIGNED2X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); + checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); + break; + + case WINED3DTOP_ADDSMOOTH: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); + checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + + case WINED3DTOP_BLENDDIFFUSEALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)); + checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)); + checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDTEXTUREALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDFACTORALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)); + checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)); + checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDTEXTUREALPHAPM: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATEALPHA_ADDCOLOR: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */ + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */ + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */ + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */ + glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); + checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); + switch (opr) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATECOLOR_ADDALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); + checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); + checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); + checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MULTIPLYADD: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); + checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src3_target, src2); + checkGLcall("GL_TEXTURE_ENV, src3_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + + case WINED3DTOP_BUMPENVMAP: + { + } + + case WINED3DTOP_BUMPENVMAPLUMINANCE: + FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n"); + + default: + Handled = FALSE; + } + if (Handled) { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV); + checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV"); + + return; + } + } /* GL_NV_texture_env_combine4 */ + + Handled = TRUE; /* Again, assume handled */ + switch (op) { + case WINED3DTOP_DISABLE: /* Only for alpha */ + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); + checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_SELECTARG1: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_SELECTARG2: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); + checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATE: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_MODULATE2X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); + checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); + break; + case WINED3DTOP_MODULATE4X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); + checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); + break; + case WINED3DTOP_ADD: + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_ADDSIGNED: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_ADDSIGNED2X: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); + checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); + break; + case WINED3DTOP_SUBTRACT: + if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else { + FIXME("This version of opengl does not support GL_SUBTRACT\n"); + } + break; + + case WINED3DTOP_BLENDDIFFUSEALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR)); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDTEXTUREALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDFACTORALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT)); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_BLENDCURRENTALPHA: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS)); + checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_DOTPRODUCT3: + if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB"); + } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT"); + } else { + FIXME("This version of opengl does not support GL_DOT3\n"); + } + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_LERP: + glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); + checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); + checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src3); + checkGLcall("GL_TEXTURE_ENV, src2_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + break; + case WINED3DTOP_ADDSMOOTH: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_BLENDTEXTUREALPHAPM: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE); + checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA); + checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MODULATEALPHA_ADDCOLOR: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MODULATECOLOR_ADDALPHA: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; + case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); + switch (opr1) { + case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; + case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; + } + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_MULTIPLYADD: + if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); + checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src3); + checkGLcall("GL_TEXTURE_ENV, src1_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); + checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); + } else + Handled = FALSE; + break; + case WINED3DTOP_BUMPENVMAPLUMINANCE: + if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) { + /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although + * they check for the non-luminance cap flag. Well, give them what they asked + * for :-) + */ + WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n"); + } else { + Handled = FALSE; + break; + } + /* Fall through */ + case WINED3DTOP_BUMPENVMAP: + if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) { + TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1); + glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI); + checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)"); + glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1); + checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)"); + glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); + checkGLcall("GL_TEXTURE_ENV, src0_target, src3"); + glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); + checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3"); + glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); + checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); + glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); + checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); + glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); + checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); + + Handled = TRUE; + break; + } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { + /* Technically texture shader support without register combiners is possible, but not expected to occur + * on real world cards, so for now a fixme should be enough + */ + FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n"); + } + default: + Handled = FALSE; + } + + if (Handled) { + BOOL combineOK = TRUE; + if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { + DWORD op2; + + if (isAlpha) { + op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP]; + } else { + op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP]; + } + + /* Note: If COMBINE4 in effect can't go back to combine! */ + switch (op2) { + case WINED3DTOP_ADDSMOOTH: + case WINED3DTOP_BLENDTEXTUREALPHAPM: + case WINED3DTOP_MODULATEALPHA_ADDCOLOR: + case WINED3DTOP_MODULATECOLOR_ADDALPHA: + case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: + case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: + case WINED3DTOP_MULTIPLYADD: + /* Ignore those implemented in both cases */ + switch (op) { + case WINED3DTOP_SELECTARG1: + case WINED3DTOP_SELECTARG2: + combineOK = FALSE; + Handled = FALSE; + break; + default: + FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha); + return; + } + } + } + + if (combineOK) { + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)); + checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)"); + + return; + } + } + + /* After all the extensions, if still unhandled, report fixme */ + FIXME("Unhandled texture operation %s\n", debug_d3dtop(op)); +} + + static void tex_colorop(DWORD state, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context) { DWORD stage = (state - STATE_TEXTURESTAGE(0, 0)) / WINED3D_HIGHEST_TEXTURE_STATE; DWORD mapped_stage = stateblock->wineD3DDevice->texUnitMap[stage]; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index 245c2c24a78..dd18b274243 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -942,7 +942,7 @@ const char* debug_d3dtexturestate(DWORD state) { } } -static const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) { +const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop) { switch (d3dtop) { #define D3DTOP_TO_STR(u) case u: return #u D3DTOP_TO_STR(WINED3DTOP_DISABLE); @@ -1107,68 +1107,7 @@ GLenum CompareFunc(DWORD func) { } } -static GLenum d3dta_to_combiner_input(DWORD d3dta, DWORD stage, INT texture_idx) { - switch (d3dta) { - case WINED3DTA_DIFFUSE: - return GL_PRIMARY_COLOR_NV; - - case WINED3DTA_CURRENT: - if (stage) return GL_SPARE0_NV; - else return GL_PRIMARY_COLOR_NV; - - case WINED3DTA_TEXTURE: - if (texture_idx > -1) return GL_TEXTURE0_ARB + texture_idx; - else return GL_PRIMARY_COLOR_NV; - - case WINED3DTA_TFACTOR: - return GL_CONSTANT_COLOR0_NV; - - case WINED3DTA_SPECULAR: - return GL_SECONDARY_COLOR_NV; - - case WINED3DTA_TEMP: - return GL_SPARE1_NV; - - case WINED3DTA_CONSTANT: - /* TODO: Support per stage constants (WINED3DTSS_CONSTANT, NV_register_combiners2) */ - FIXME("WINED3DTA_CONSTANT, not properly supported.\n"); - return GL_CONSTANT_COLOR1_NV; - - default: - FIXME("Unrecognized texture arg %#x\n", d3dta); - return GL_TEXTURE; - } -} - -static GLenum invert_mapping(GLenum mapping) { - if (mapping == GL_UNSIGNED_INVERT_NV) return GL_SIGNED_IDENTITY_NV; - else if (mapping == GL_SIGNED_IDENTITY_NV) return GL_UNSIGNED_INVERT_NV; - - FIXME("Unhandled mapping %#x\n", mapping); - return mapping; -} - -static void get_src_and_opr_nvrc(DWORD stage, DWORD arg, BOOL is_alpha, GLenum* input, GLenum* mapping, GLenum *component_usage, INT texture_idx) { - /* The WINED3DTA_COMPLEMENT flag specifies the complement of the input should - * be used. */ - if (arg & WINED3DTA_COMPLEMENT) *mapping = GL_UNSIGNED_INVERT_NV; - else *mapping = GL_SIGNED_IDENTITY_NV; - - /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the input - * should be used for all input components. */ - if (is_alpha || arg & WINED3DTA_ALPHAREPLICATE) *component_usage = GL_ALPHA; - else *component_usage = GL_RGB; - - *input = d3dta_to_combiner_input(arg & WINED3DTA_SELECTMASK, stage, texture_idx); -} - -typedef struct { - GLenum input[3]; - GLenum mapping[3]; - GLenum component_usage[3]; -} tex_op_args; - -static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) { +BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) { if (op == WINED3DTOP_DISABLE) return FALSE; if (This->stateBlock->textures[stage]) return FALSE; @@ -1182,1436 +1121,6 @@ static BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP return FALSE; } -void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst) { - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl*)iface; - tex_op_args tex_op_args = {{0}, {0}, {0}}; - GLenum portion = is_alpha ? GL_ALPHA : GL_RGB; - GLenum target = GL_COMBINER0_NV + stage; - GLenum output; - - TRACE("stage %d, is_alpha %d, op %s, arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", - stage, is_alpha, debug_d3dtop(op), arg1, arg2, arg3, texture_idx); - - /* If a texture stage references an invalid texture unit the stage just - * passes through the result from the previous stage */ - if (is_invalid_op(This, stage, op, arg1, arg2, arg3)) { - arg1 = WINED3DTA_CURRENT; - op = WINED3DTOP_SELECTARG1; - } - - get_src_and_opr_nvrc(stage, arg1, is_alpha, &tex_op_args.input[0], - &tex_op_args.mapping[0], &tex_op_args.component_usage[0], texture_idx); - get_src_and_opr_nvrc(stage, arg2, is_alpha, &tex_op_args.input[1], - &tex_op_args.mapping[1], &tex_op_args.component_usage[1], texture_idx); - get_src_and_opr_nvrc(stage, arg3, is_alpha, &tex_op_args.input[2], - &tex_op_args.mapping[2], &tex_op_args.component_usage[2], texture_idx); - - - if(dst == WINED3DTA_TEMP) { - output = GL_SPARE1_NV; - } else { - output = GL_SPARE0_NV; - } - - /* This is called by a state handler which has the gl lock held and a context for the thread */ - switch(op) - { - case WINED3DTOP_DISABLE: - /* Only for alpha */ - if (!is_alpha) ERR("Shouldn't be called for WINED3DTSS_COLOROP (WINED3DTOP_DISABLE)\n"); - /* Input, prev_alpha*1 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, GL_ALPHA)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_SELECTARG1: - case WINED3DTOP_SELECTARG2: - /* Input, arg*1 */ - if (op == WINED3DTOP_SELECTARG1) { - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - } else { - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - } - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MODULATE: - case WINED3DTOP_MODULATE2X: - case WINED3DTOP_MODULATE4X: - /* Input, arg1*arg2 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - - /* Output */ - if (op == WINED3DTOP_MODULATE) { - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - } else if (op == WINED3DTOP_MODULATE2X) { - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_SCALE_BY_TWO_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - } else if (op == WINED3DTOP_MODULATE4X) { - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_SCALE_BY_FOUR_NV, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - } - break; - - case WINED3DTOP_ADD: - case WINED3DTOP_ADDSIGNED: - case WINED3DTOP_ADDSIGNED2X: - /* Input, arg1*1+arg2*1 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - if (op == WINED3DTOP_ADD) { - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - } else if (op == WINED3DTOP_ADDSIGNED) { - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE)); - } else if (op == WINED3DTOP_ADDSIGNED2X) { - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_SCALE_BY_TWO_NV, GL_BIAS_BY_NEGATIVE_ONE_HALF_NV, GL_FALSE, GL_FALSE, GL_FALSE)); - } - break; - - case WINED3DTOP_SUBTRACT: - /* Input, arg1*1+-arg2*1 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[1], GL_SIGNED_NEGATE_NV, tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_ADDSMOOTH: - /* Input, arg1*1+(1-arg1)*arg2 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_BLENDDIFFUSEALPHA: - case WINED3DTOP_BLENDTEXTUREALPHA: - case WINED3DTOP_BLENDFACTORALPHA: - case WINED3DTOP_BLENDTEXTUREALPHAPM: - case WINED3DTOP_BLENDCURRENTALPHA: - { - GLenum alpha_src = GL_PRIMARY_COLOR_NV; - if (op == WINED3DTOP_BLENDDIFFUSEALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_DIFFUSE, stage, texture_idx); - else if (op == WINED3DTOP_BLENDTEXTUREALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx); - else if (op == WINED3DTOP_BLENDFACTORALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_TFACTOR, stage, texture_idx); - else if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) alpha_src = d3dta_to_combiner_input(WINED3DTA_TEXTURE, stage, texture_idx); - else if (op == WINED3DTOP_BLENDCURRENTALPHA) alpha_src = d3dta_to_combiner_input(WINED3DTA_CURRENT, stage, texture_idx); - else FIXME("Unhandled WINED3DTOP %s, shouldn't happen\n", debug_d3dtop(op)); - - /* Input, arg1*alpha_src+arg2*(1-alpha_src) */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - if (op == WINED3DTOP_BLENDTEXTUREALPHAPM) - { - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - } else { - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - alpha_src, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA)); - } - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - alpha_src, GL_UNSIGNED_INVERT_NV, GL_ALPHA)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - } - - case WINED3DTOP_MODULATEALPHA_ADDCOLOR: - /* Input, arg1_alpha*arg2_rgb+arg1_rgb*1 */ - if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEALPHA_ADDCOLOR)\n"); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MODULATECOLOR_ADDALPHA: - /* Input, arg1_rgb*arg2_rgb+arg1_alpha*1 */ - if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATECOLOR_ADDALPHA)\n"); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: - /* Input, (1-arg1_alpha)*arg2_rgb+arg1_rgb*1 */ - if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVALPHA_ADDCOLOR)\n"); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: - /* Input, (1-arg1_rgb)*arg2_rgb+arg1_alpha*1 */ - if (is_alpha) ERR("Only supported for WINED3DTSS_COLOROP (WINED3DTOP_MODULATEINVCOLOR_ADDALPHA)\n"); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], invert_mapping(tex_op_args.mapping[0]), tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], GL_ALPHA)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_DOTPRODUCT3: - /* Input, arg1 . arg2 */ - /* FIXME: DX7 uses a different calculation? */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[0], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[1], GL_EXPAND_NORMAL_NV, tex_op_args.component_usage[1])); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, output, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_TRUE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_MULTIPLYADD: - /* Input, arg3*1+arg1*arg2 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_LERP: - /* Input, arg3*arg1+(1-arg3)*arg2 */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[2], tex_op_args.mapping[2], tex_op_args.component_usage[2])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - tex_op_args.input[0], tex_op_args.mapping[0], tex_op_args.component_usage[0])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_C_NV, - tex_op_args.input[2], invert_mapping(tex_op_args.mapping[2]), tex_op_args.component_usage[2])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_D_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - - /* Output */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_DISCARD_NV, GL_DISCARD_NV, - output, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - - case WINED3DTOP_BUMPENVMAPLUMINANCE: - case WINED3DTOP_BUMPENVMAP: - if(GL_SUPPORT(NV_TEXTURE_SHADER)) { - /* The bump map stage itself isn't exciting, just read the texture. But tell the next stage to - * perform bump mapping and source from the current stage. Pretty much a SELECTARG2. - * ARG2 is passed through unmodified(apps will most likely use D3DTA_CURRENT for arg2, arg1 - * (which will most likely be D3DTA_TEXTURE) is available as a texture shader input for the next stage - */ - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_A_NV, - tex_op_args.input[1], tex_op_args.mapping[1], tex_op_args.component_usage[1])); - GL_EXTCALL(glCombinerInputNV(target, portion, GL_VARIABLE_B_NV, - GL_ZERO, GL_UNSIGNED_INVERT_NV, portion)); - /* Always pass through to CURRENT, ignore temp arg */ - GL_EXTCALL(glCombinerOutputNV(target, portion, GL_SPARE0_NV, GL_DISCARD_NV, - GL_DISCARD_NV, GL_NONE, GL_NONE, GL_FALSE, GL_FALSE, GL_FALSE)); - break; - } - - default: - FIXME("Unhandled WINED3DTOP: stage %d, is_alpha %d, op %s (%#x), arg1 %#x, arg2 %#x, arg3 %#x, texture_idx %d\n", - stage, is_alpha, debug_d3dtop(op), op, arg1, arg2, arg3, texture_idx); - } - - checkGLcall("set_tex_op_nvrc()\n"); - -} - -static void get_src_and_opr(DWORD arg, BOOL is_alpha, GLenum* source, GLenum* operand) { - /* The WINED3DTA_ALPHAREPLICATE flag specifies the alpha component of the - * input should be used for all input components. The WINED3DTA_COMPLEMENT - * flag specifies the complement of the input should be used. */ - BOOL from_alpha = is_alpha || arg & WINED3DTA_ALPHAREPLICATE; - BOOL complement = arg & WINED3DTA_COMPLEMENT; - - /* Calculate the operand */ - if (complement) { - if (from_alpha) *operand = GL_ONE_MINUS_SRC_ALPHA; - else *operand = GL_ONE_MINUS_SRC_COLOR; - } else { - if (from_alpha) *operand = GL_SRC_ALPHA; - else *operand = GL_SRC_COLOR; - } - - /* Calculate the source */ - switch (arg & WINED3DTA_SELECTMASK) { - case WINED3DTA_CURRENT: *source = GL_PREVIOUS_EXT; break; - case WINED3DTA_DIFFUSE: *source = GL_PRIMARY_COLOR_EXT; break; - case WINED3DTA_TEXTURE: *source = GL_TEXTURE; break; - case WINED3DTA_TFACTOR: *source = GL_CONSTANT_EXT; break; - case WINED3DTA_SPECULAR: - /* - * According to the GL_ARB_texture_env_combine specs, SPECULAR is - * 'Secondary color' and isn't supported until base GL supports it - * There is no concept of temp registers as far as I can tell - */ - FIXME("Unhandled texture arg WINED3DTA_SPECULAR\n"); - *source = GL_TEXTURE; - break; - default: - FIXME("Unrecognized texture arg %#x\n", arg); - *source = GL_TEXTURE; - break; - } -} - -/* Set texture operations up - The following avoids lots of ifdefs in this routine!*/ -#if defined (GL_VERSION_1_3) -# define useext(A) A -#elif defined (GL_EXT_texture_env_combine) -# define useext(A) A##_EXT -#elif defined (GL_ARB_texture_env_combine) -# define useext(A) A##_ARB -#endif - -/* Setup the texture operations texture stage states */ -void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3) -{ - GLenum src1, src2, src3; - GLenum opr1, opr2, opr3; - GLenum comb_target; - GLenum src0_target, src1_target, src2_target; - GLenum opr0_target, opr1_target, opr2_target; - GLenum scal_target; - GLenum opr=0, invopr, src3_target, opr3_target; - BOOL Handled = FALSE; - IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; - - TRACE("Alpha?(%d), Stage:%d Op(%s), a1(%d), a2(%d), a3(%d)\n", isAlpha, Stage, debug_d3dtop(op), arg1, arg2, arg3); - - /* This is called by a state handler which has the gl lock held and a context for the thread */ - - /* Note: Operations usually involve two ars, src0 and src1 and are operations of - the form (a1 a2). However, some of the more complex operations - take 3 parameters. Instead of the (sensible) addition of a3, Microsoft added - in a third parameter called a0. Therefore these are operations of the form - a0 a1 a2, i.e., the new parameter goes to the front. - - However, below we treat the new (a0) parameter as src2/opr2, so in the actual - functions below, expect their syntax to differ slightly to those listed in the - manuals, i.e., replace arg1 with arg3, arg2 with arg1 and arg3 with arg2 - This affects WINED3DTOP_MULTIPLYADD and WINED3DTOP_LERP */ - - if (isAlpha) { - comb_target = useext(GL_COMBINE_ALPHA); - src0_target = useext(GL_SOURCE0_ALPHA); - src1_target = useext(GL_SOURCE1_ALPHA); - src2_target = useext(GL_SOURCE2_ALPHA); - opr0_target = useext(GL_OPERAND0_ALPHA); - opr1_target = useext(GL_OPERAND1_ALPHA); - opr2_target = useext(GL_OPERAND2_ALPHA); - scal_target = GL_ALPHA_SCALE; - } - else { - comb_target = useext(GL_COMBINE_RGB); - src0_target = useext(GL_SOURCE0_RGB); - src1_target = useext(GL_SOURCE1_RGB); - src2_target = useext(GL_SOURCE2_RGB); - opr0_target = useext(GL_OPERAND0_RGB); - opr1_target = useext(GL_OPERAND1_RGB); - opr2_target = useext(GL_OPERAND2_RGB); - scal_target = useext(GL_RGB_SCALE); - } - - /* If a texture stage references an invalid texture unit the stage just - * passes through the result from the previous stage */ - if (is_invalid_op(This, Stage, op, arg1, arg2, arg3)) { - arg1 = WINED3DTA_CURRENT; - op = WINED3DTOP_SELECTARG1; - } - - /* From MSDN (WINED3DTSS_ALPHAARG1) : - The default argument is WINED3DTA_TEXTURE. If no texture is set for this stage, - then the default argument is WINED3DTA_DIFFUSE. - FIXME? If texture added/removed, may need to reset back as well? */ - if (isAlpha && This->stateBlock->textures[Stage] == NULL && arg1 == WINED3DTA_TEXTURE) { - get_src_and_opr(WINED3DTA_DIFFUSE, isAlpha, &src1, &opr1); - } else { - get_src_and_opr(arg1, isAlpha, &src1, &opr1); - } - get_src_and_opr(arg2, isAlpha, &src2, &opr2); - get_src_and_opr(arg3, isAlpha, &src3, &opr3); - - TRACE("ct(%x), 1:(%x,%x), 2:(%x,%x), 3:(%x,%x)\n", comb_target, src1, opr1, src2, opr2, src3, opr3); - - Handled = TRUE; /* Assume will be handled */ - - /* Other texture operations require special extensions: */ - if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { - if (isAlpha) { - opr = GL_SRC_ALPHA; - invopr = GL_ONE_MINUS_SRC_ALPHA; - src3_target = GL_SOURCE3_ALPHA_NV; - opr3_target = GL_OPERAND3_ALPHA_NV; - } else { - opr = GL_SRC_COLOR; - invopr = GL_ONE_MINUS_SRC_COLOR; - src3_target = GL_SOURCE3_RGB_NV; - opr3_target = GL_OPERAND3_RGB_NV; - } - switch (op) { - case WINED3DTOP_DISABLE: /* Only for alpha */ - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - break; - case WINED3DTOP_SELECTARG1: /* = a1 * 1 + 0 * 0 */ - case WINED3DTOP_SELECTARG2: /* = a2 * 1 + 0 * 0 */ - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - if (op == WINED3DTOP_SELECTARG1) { - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - } else { - glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); - checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); - } - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - break; - - case WINED3DTOP_MODULATE: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATE2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - case WINED3DTOP_MODULATE4X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); - checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); - break; - - case WINED3DTOP_ADD: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case WINED3DTOP_ADDSIGNED: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case WINED3DTOP_ADDSIGNED2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - - case WINED3DTOP_ADDSMOOTH: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); - checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case WINED3DTOP_BLENDDIFFUSEALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)); - checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_PRIMARY_COLOR)"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)); - checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_PRIMARY_COLOR)"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDTEXTUREALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDFACTORALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)); - checkGLcall("GL_TEXTURE_ENV, src1_target, useext(GL_CONSTANT)"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)); - checkGLcall("GL_TEXTURE_ENV, src3_target, useext(GL_CONSTANT)"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDTEXTUREALPHAPM: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr3_target, GL_ONE_MINUS_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATEALPHA_ADDCOLOR: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); /* Add = a0*a1 + a2*a3 */ - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); /* a0 = src1/opr1 */ - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); /* a1 = 1 (see docs) */ - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); /* a2 = arg2 */ - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); /* a3 = src1 alpha */ - glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); - checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); - switch (opr) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATECOLOR_ADDALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); - checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, src1); - checkGLcall("GL_TEXTURE_ENV, src3_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); - checkGLcall("GL_TEXTURE_ENV, src2_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src3_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr3_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MULTIPLYADD: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, GL_ZERO); - checkGLcall("GL_TEXTURE_ENV, src1_target, GL_ZERO"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, invopr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, invopr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src1); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src3_target, src2); - checkGLcall("GL_TEXTURE_ENV, src3_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr3_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr3_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - - case WINED3DTOP_BUMPENVMAP: - { - } - - case WINED3DTOP_BUMPENVMAPLUMINANCE: - FIXME("Implement bump environment mapping in GL_NV_texture_env_combine4 path\n"); - - default: - Handled = FALSE; - } - if (Handled) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV); - checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE4_NV"); - - return; - } - } /* GL_NV_texture_env_combine4 */ - - Handled = TRUE; /* Again, assume handled */ - switch (op) { - case WINED3DTOP_DISABLE: /* Only for alpha */ - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT); - checkGLcall("GL_TEXTURE_ENV, src0_target, GL_PREVIOUS_EXT"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_SELECTARG1: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_SELECTARG2: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_REPLACE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_REPLACE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src2); - checkGLcall("GL_TEXTURE_ENV, src0_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATE: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_MODULATE2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - case WINED3DTOP_MODULATE4X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 4); - checkGLcall("GL_TEXTURE_ENV, scal_target, 4"); - break; - case WINED3DTOP_ADD: - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_ADD); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_ADD"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_ADDSIGNED: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext((GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_ADDSIGNED2X: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_ADD_SIGNED)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 2); - checkGLcall("GL_TEXTURE_ENV, scal_target, 2"); - break; - case WINED3DTOP_SUBTRACT: - if (GL_SUPPORT(ARB_TEXTURE_ENV_COMBINE)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_SUBTRACT); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_SUBTRACT)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else { - FIXME("This version of opengl does not support GL_SUBTRACT\n"); - } - break; - - case WINED3DTOP_BLENDDIFFUSEALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PRIMARY_COLOR)); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PRIMARY_COLOR"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDTEXTUREALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDFACTORALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_CONSTANT)); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_CONSTANT"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_BLENDCURRENTALPHA: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, useext(GL_PREVIOUS)); - checkGLcall("GL_TEXTURE_ENV, src2_target, GL_PREVIOUS"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr2_target, GL_SRC_ALPHA"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_DOTPRODUCT3: - if (GL_SUPPORT(ARB_TEXTURE_ENV_DOT3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_ARB"); - } else if (GL_SUPPORT(EXT_TEXTURE_ENV_DOT3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_DOT3_RGBA_EXT"); - } else { - FIXME("This version of opengl does not support GL_DOT3\n"); - } - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_LERP: - glTexEnvi(GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)); - checkGLcall("GL_TEXTURE_ENV, comb_target, useext(GL_INTERPOLATE)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src2); - checkGLcall("GL_TEXTURE_ENV, src1_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src3); - checkGLcall("GL_TEXTURE_ENV, src2_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - break; - case WINED3DTOP_ADDSMOOTH: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_BLENDTEXTUREALPHAPM: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, GL_TEXTURE); - checkGLcall("GL_TEXTURE_ENV, src0_target, GL_TEXTURE"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_ALPHA); - checkGLcall("GL_TEXTURE_ENV, opr0_target, GL_ONE_MINUS_SRC_APHA"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MODULATEALPHA_ADDCOLOR: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MODULATECOLOR_ADDALPHA: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_ONE_MINUS_SRC_COLOR; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_SRC_COLOR; break; - case GL_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src1_target, src1"); - switch (opr1) { - case GL_SRC_COLOR: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_COLOR: opr = GL_ONE_MINUS_SRC_ALPHA; break; - case GL_SRC_ALPHA: opr = GL_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: opr = GL_ONE_MINUS_SRC_ALPHA; break; - } - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_MULTIPLYADD: - if (GL_SUPPORT(ATI_TEXTURE_ENV_COMBINE3)) { - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI); - checkGLcall("GL_TEXTURE_ENV, comb_target, GL_MODULATE_ADD_ATI"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src3); - checkGLcall("GL_TEXTURE_ENV, src1_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src2_target, src2"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - glTexEnvi(GL_TEXTURE_ENV, scal_target, 1); - checkGLcall("GL_TEXTURE_ENV, scal_target, 1"); - } else - Handled = FALSE; - break; - case WINED3DTOP_BUMPENVMAPLUMINANCE: - if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) { - /* Some apps use BUMPENVMAPLUMINANCE instead of D3DTOP_BUMPENVMAP, although - * they check for the non-luminance cap flag. Well, give them what they asked - * for :-) - */ - WARN("Application uses WINED3DTOP_BUMPENVMAPLUMINANCE\n"); - } else { - Handled = FALSE; - break; - } - /* Fall through */ - case WINED3DTOP_BUMPENVMAP: - if(GL_SUPPORT(ATI_ENVMAP_BUMPMAP)) { - TRACE("Using ati bumpmap on stage %d, target %d\n", Stage, Stage + 1); - glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, comb_target, GL_BUMP_ENVMAP_ATI)"); - glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1); - checkGLcall("glTexEnvi(GL_TEXTURE_ENV, GL_BUMP_TARGET_ATI, GL_TEXTURE0_ARB + Stage + 1)"); - glTexEnvi(GL_TEXTURE_ENV, src0_target, src3); - checkGLcall("GL_TEXTURE_ENV, src0_target, src3"); - glTexEnvi(GL_TEXTURE_ENV, opr0_target, opr3); - checkGLcall("GL_TEXTURE_ENV, opr0_target, opr3"); - glTexEnvi(GL_TEXTURE_ENV, src1_target, src1); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr1_target, opr1); - checkGLcall("GL_TEXTURE_ENV, opr1_target, opr1"); - glTexEnvi(GL_TEXTURE_ENV, src2_target, src2); - checkGLcall("GL_TEXTURE_ENV, src0_target, src1"); - glTexEnvi(GL_TEXTURE_ENV, opr2_target, opr2); - checkGLcall("GL_TEXTURE_ENV, opr2_target, opr2"); - - Handled = TRUE; - break; - } else if(GL_SUPPORT(NV_TEXTURE_SHADER2)) { - /* Technically texture shader support without register combiners is possible, but not expected to occur - * on real world cards, so for now a fixme should be enough - */ - FIXME("Implement bump mapping with GL_NV_texture_shader in non register combiner path\n"); - } - default: - Handled = FALSE; - } - - if (Handled) { - BOOL combineOK = TRUE; - if (GL_SUPPORT(NV_TEXTURE_ENV_COMBINE4)) { - DWORD op2; - - if (isAlpha) { - op2 = This->stateBlock->textureState[Stage][WINED3DTSS_COLOROP]; - } else { - op2 = This->stateBlock->textureState[Stage][WINED3DTSS_ALPHAOP]; - } - - /* Note: If COMBINE4 in effect can't go back to combine! */ - switch (op2) { - case WINED3DTOP_ADDSMOOTH: - case WINED3DTOP_BLENDTEXTUREALPHAPM: - case WINED3DTOP_MODULATEALPHA_ADDCOLOR: - case WINED3DTOP_MODULATECOLOR_ADDALPHA: - case WINED3DTOP_MODULATEINVALPHA_ADDCOLOR: - case WINED3DTOP_MODULATEINVCOLOR_ADDALPHA: - case WINED3DTOP_MULTIPLYADD: - /* Ignore those implemented in both cases */ - switch (op) { - case WINED3DTOP_SELECTARG1: - case WINED3DTOP_SELECTARG2: - combineOK = FALSE; - Handled = FALSE; - break; - default: - FIXME("Can't use COMBINE4 and COMBINE together, thisop=%s, otherop=%s, isAlpha(%d)\n", debug_d3dtop(op), debug_d3dtop(op2), isAlpha); - return; - } - } - } - - if (combineOK) { - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)); - checkGLcall("GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, useext(GL_COMBINE)"); - - return; - } - } - - /* After all the extensions, if still unhandled, report fixme */ - FIXME("Unhandled texture operation %s\n", debug_d3dtop(op)); -#undef GLINFO_LOCATION -} - /* Setup this textures matrix according to the texture flags*/ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype) { @@ -2701,6 +1210,7 @@ void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, B glLoadMatrixf(mat); checkGLcall("glLoadMatrixf(mat)"); } +#undef GLINFO_LOCATION #define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index fdbb4a3fb0a..61b29839c07 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -1730,11 +1730,12 @@ const char *debug_fbostatus(GLenum status); const char *debug_glerror(GLenum error); const char *debug_d3dbasis(WINED3DBASISTYPE basis); const char *debug_d3ddegree(WINED3DDEGREETYPE order); +const char* debug_d3dtop(WINED3DTEXTUREOP d3dtop); /* Routines for GL <-> D3D values */ GLenum StencilOp(DWORD op); GLenum CompareFunc(DWORD func); -void set_tex_op(IWineD3DDevice *iface, BOOL isAlpha, int Stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3); +BOOL is_invalid_op(IWineD3DDeviceImpl *This, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3); void set_tex_op_nvrc(IWineD3DDevice *iface, BOOL is_alpha, int stage, WINED3DTEXTUREOP op, DWORD arg1, DWORD arg2, DWORD arg3, INT texture_idx, DWORD dst); void set_texture_matrix(const float *smat, DWORD flags, BOOL calculatedCoords, BOOL transformed, DWORD coordtype); void texture_activate_dimensions(DWORD stage, IWineD3DStateBlockImpl *stateblock, WineD3DContext *context);