From 75386a99b4116745d6d07445c572013a4bb12af5 Mon Sep 17 00:00:00 2001 From: Matteo Bruni Date: Tue, 1 Feb 2011 02:42:22 +0100 Subject: [PATCH] wined3d: Make clip planes independent from offscreen/onscreen drawing. --- dlls/wined3d/arb_program_shader.c | 46 ++++++++++++++++--------------- dlls/wined3d/glsl_shader.c | 14 ++++------ dlls/wined3d/state.c | 13 ++------- 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/dlls/wined3d/arb_program_shader.c b/dlls/wined3d/arb_program_shader.c index 4efca9f787b..8770e054e4a 100644 --- a/dlls/wined3d/arb_program_shader.c +++ b/dlls/wined3d/arb_program_shader.c @@ -3111,35 +3111,24 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx, * the fog frag coord is thrown away. If the fog frag coord is used, but not written by * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0) */ - if(args->super.fog_src == VS_FOG_Z) { + if (args->super.fog_src == VS_FOG_Z) shader_addline(buffer, "MOV result.fogcoord, TMP_OUT.z;\n"); - } else if (!reg_maps->fog) { - /* posFixup.x is always 1.0, so we can savely use it */ + else if (!reg_maps->fog) + /* posFixup.x is always 1.0, so we can safely use it */ shader_addline(buffer, "ADD result.fogcoord, posFixup.x, -posFixup.x;\n"); - } - /* Write the final position. - * - * OpenGL coordinates specify the center of the pixel while d3d coords specify - * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains - * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x - * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that. - */ - shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n"); - shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n"); - shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n"); - - if(use_nv_clip(gl_info) && priv_ctx->target_version >= NV2) + /* Clipplanes are always stored without y inversion */ + if (use_nv_clip(gl_info) && priv_ctx->target_version >= NV2) { - if(args->super.clip_enabled) + if (args->super.clip_enabled) { - for(i = 0; i < priv_ctx->vs_clipplanes; i++) + for (i = 0; i < priv_ctx->vs_clipplanes; i++) { shader_addline(buffer, "DP4 result.clip[%u].x, TMP_OUT, state.clip[%u].plane;\n", i, i); } } } - else if(args->clip.boolclip.clip_texcoord) + else if (args->clip.boolclip.clip_texcoord) { unsigned int cur_clip = 0; char component[4] = {'x', 'y', 'z', 'w'}; @@ -3147,13 +3136,13 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx, for (i = 0; i < gl_info->limits.clipplanes; ++i) { - if(args->clip.boolclip.clipplane_mask & (1 << i)) + if (args->clip.boolclip.clipplane_mask & (1 << i)) { shader_addline(buffer, "DP4 TA.%c, TMP_OUT, state.clip[%u].plane;\n", component[cur_clip++], i); } } - switch(cur_clip) + switch (cur_clip) { case 0: shader_addline(buffer, "MOV TA, %s;\n", zero); @@ -3172,6 +3161,17 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx, args->clip.boolclip.clip_texcoord - 1); } + /* Write the final position. + * + * OpenGL coordinates specify the center of the pixel while d3d coords specify + * the corner. The offsets are stored in z and w in posFixup. posFixup.y contains + * 1.0 or -1.0 to turn the rendering upside down for offscreen rendering. PosFixup.x + * contains 1.0 to allow a mad, but arb vs swizzles are too restricted for that. + */ + shader_addline(buffer, "MUL TA, posFixup, TMP_OUT.w;\n"); + shader_addline(buffer, "ADD TMP_OUT.x, TMP_OUT.x, TA.z;\n"); + shader_addline(buffer, "MAD TMP_OUT.y, TMP_OUT.y, posFixup.y, TA.w;\n"); + /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c * and the glsl equivalent */ @@ -3179,7 +3179,9 @@ static void vshader_add_footer(struct shader_arb_ctx_priv *priv_ctx, { const char *two = arb_get_helper_value(WINED3D_SHADER_TYPE_VERTEX, ARB_TWO); shader_addline(buffer, "MAD TMP_OUT.z, TMP_OUT.z, %s, -TMP_OUT.w;\n", two); - } else { + } + else + { shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, TMP_OUT.z;\n"); shader_addline(buffer, "ADD TMP_OUT.z, TMP_OUT.z, -TMP_OUT.w;\n"); } diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c index e349e2673e2..6d54871ed74 100644 --- a/dlls/wined3d/glsl_shader.c +++ b/dlls/wined3d/glsl_shader.c @@ -4079,9 +4079,7 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context shader_addline(buffer, "#version 120\n"); if (gl_info->supported[EXT_GPU_SHADER4]) - { shader_addline(buffer, "#extension GL_EXT_gpu_shader4 : enable\n"); - } memset(&priv_ctx, 0, sizeof(priv_ctx)); priv_ctx.cur_vs_args = args; @@ -4100,11 +4098,14 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context * the fog frag coord is thrown away. If the fog frag coord is used, but not written by * the shader, it is set to 0.0(fully fogged, since start = 1.0, end = 0.0) */ - if(args->fog_src == VS_FOG_Z) { + if (args->fog_src == VS_FOG_Z) shader_addline(buffer, "gl_FogFragCoord = gl_Position.z;\n"); - } else if (!reg_maps->fog) { + else if (!reg_maps->fog) shader_addline(buffer, "gl_FogFragCoord = 0.0;\n"); - } + + /* We always store the clipplanes without y inversion */ + if (args->clip_enabled) + shader_addline(buffer, "gl_ClipVertex = gl_Position;\n"); /* Write the final position. * @@ -4115,9 +4116,6 @@ static GLuint shader_glsl_generate_vshader(const struct wined3d_context *context */ shader_addline(buffer, "gl_Position.y = gl_Position.y * posFixup.y;\n"); shader_addline(buffer, "gl_Position.xy += posFixup.zw * gl_Position.ww;\n"); - if(args->clip_enabled) { - shader_addline(buffer, "gl_ClipVertex = gl_Position;\n"); - } /* Z coord [0;1]->[-1;1] mapping, see comment in transform_projection in state.c * diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c index 1c13413b8b3..2761ca48e29 100644 --- a/dlls/wined3d/state.c +++ b/dlls/wined3d/state.c @@ -3798,24 +3798,17 @@ static void clipplane(DWORD state_id, struct wined3d_stateblock *stateblock, str return; } + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + /* Clip Plane settings are affected by the model view in OpenGL, the View transform in direct3d */ if (!use_vs(state)) - { - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); glLoadMatrixf(&state->transforms[WINED3DTS_VIEW].u.m[0][0]); - } else - { /* with vertex shaders, clip planes are not transformed in direct3d, * in OpenGL they are still transformed by the model view. - * Use this to swap the y coordinate if necessary */ - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); glLoadIdentity(); - if (context->render_offscreen) glScalef(1.0f, -1.0f, 1.0f); - } TRACE("Clipplane [%.8e, %.8e, %.8e, %.8e]\n", state->clip_planes[index][0],