diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index ee56e9ce76b..a2b07dbe65d 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -144,6 +144,9 @@ void shader_generate_arb_declarations( unsigned max_constantsF = min(This->baseShader.limits.constant_float, (pshader ? GL_LIMITS(pshader_constantsF) : GL_LIMITS(vshader_constantsF))); + /* Temporary Output register */ + shader_addline(buffer, "TEMP TMP_OUT;\n"); + for(i = 0; i < This->baseShader.limits.temporary; i++) { if (reg_maps->temporary[i]) shader_addline(buffer, "TEMP R%lu;\n", i); @@ -168,6 +171,7 @@ void shader_generate_arb_declarations( /* Need to PARAM the environment parameters (constants) so we can use relative addressing */ shader_addline(buffer, "PARAM C[%d] = { program.env[0..%d] };\n", max_constantsF, max_constantsF - 1); + shader_addline(buffer, "PARAM PROJECTION = state.matrix.projection.row[1];\n"); } static const char* shift_tab[] = { @@ -344,7 +348,7 @@ static void vshader_program_add_param(SHADER_OPCODE_ARG *arg, const DWORD param, IWineD3DVertexShaderImpl* This = (IWineD3DVertexShaderImpl*) arg->shader; /* oPos, oFog and oPts in D3D */ - static const char* hwrastout_reg_names[] = { "result.position", "TMP_FOG", "result.pointsize" }; + static const char* hwrastout_reg_names[] = { "TMP_OUT", "TMP_FOG", "result.pointsize" }; DWORD reg = param & D3DSP_REGNUM_MASK; DWORD regtype = shader_get_regtype(param); diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c index 51d41e7af5d..5b3549418a8 100644 --- a/dlls/wined3d/directx.c +++ b/dlls/wined3d/directx.c @@ -247,8 +247,10 @@ void select_shader_max_constants(WineD3D_GL_Info *gl_info) { gl_info->max_vshader_constantsF = gl_info->vs_glsl_constantsF - MAX_CONST_B - MAX_CONST_I; break; case SHADER_ARB: - /* ARB shaders seem to have an implicit PARAM when fog is used, so we need to subtract 1 from the total available */ - gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 1; + /* We have to subtract any other PARAMs that we might use in our shader programs. + * ATI seems to count 2 implicit PARAMs when we use fog and NVIDIA counts 1, + * and we reference one row of the PROJECTION matrix which counts as 1 PARAM. */ + gl_info->max_vshader_constantsF = gl_info->vs_arb_constantsF - 3; break; case SHADER_SW: gl_info->max_vshader_constantsF = 96; /* TODO: Fixup software shaders */ diff --git a/dlls/wined3d/drawprim.c b/dlls/wined3d/drawprim.c index a7dd644d3ef..ab6162c14d5 100644 --- a/dlls/wined3d/drawprim.c +++ b/dlls/wined3d/drawprim.c @@ -304,9 +304,6 @@ static void primitiveInitState( } /* Vertex Shader output is already transformed, so set up identity matrices */ - /* FIXME: Actually, only true for software emulated ones, so when h/w ones - come along this needs to take into account whether s/w ones were - requested or not */ if (useVS) { glMatrixMode(GL_MODELVIEW); checkGLcall("glMatrixMode"); diff --git a/dlls/wined3d/vertexshader.c b/dlls/wined3d/vertexshader.c index c0ee39957bb..923f953652d 100644 --- a/dlls/wined3d/vertexshader.c +++ b/dlls/wined3d/vertexshader.c @@ -718,6 +718,11 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader( This->usesFog = 1; shader_addline(&buffer, "gl_FogFragCoord = clamp(gl_FogFragCoord, 0.0, 1.0);\n"); } + + /* Write the final position. + * Account for any inverted textures (render to texture case) by reversing the y coordinate + * (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices) */ + shader_addline(&buffer, "gl_Position.y = gl_Position.y * gl_ProjectionMatrix[1][1];\n"); shader_addline(&buffer, "}\n\0"); @@ -754,6 +759,12 @@ static VOID IWineD3DVertexShaderImpl_GenerateShader( if (reg_maps->fog) shader_addline(&buffer, "MAX result.fogcoord, TMP_FOG, 0.0;\n"); + /* Write the final position. + * Account for any inverted textures (render to texture case) by reversing the y coordinate + * (this is handled in drawPrim() when it sets the MODELVIEW and PROJECTION matrices) */ + shader_addline(&buffer, "MOV result.position, TMP_OUT;\n"); + shader_addline(&buffer, "MUL result.position.y, TMP_OUT.y, state.matrix.projection.row[1].y;\n"); + shader_addline(&buffer, "END\n\0"); /* TODO: change to resource.glObjectHandle or something like that */