(re)Hi all, After finding out that texture parameters are per-texture objects in GL and global in D3D, this patch fixes the last graphical glitches in DungeonSiege. Now I just need to find how to fix the lock-up at the beginning without my hack and the demo is fully playable (no idea about the retail version though). Changelog: - fix texture parameters handling on texture change Lionel PS: I hope you are not all fed up / lost by all the patches :-) -- Lionel Ulmer - http://www.bbrox.org/
--- dlls/ddraw_CVS/d3ddevice/mesa.c Mon May 26 14:51:52 2003 +++ dlls/ddraw/d3ddevice/mesa.c Mon May 26 15:58:00 2003 @@ -1505,6 +1505,24 @@ return gl_state; } +static GLenum +convert_tex_address_to_GL(D3DTEXTUREADDRESS dwState) +{ + GLenum gl_state; + switch (dwState) { + case D3DTADDRESS_WRAP: gl_state = GL_REPEAT; break; + case D3DTADDRESS_CLAMP: gl_state = GL_CLAMP; break; + case D3DTADDRESS_BORDER: gl_state = GL_CLAMP_TO_EDGE; break; +#if defined(GL_VERSION_1_4) + case D3DTADDRESS_MIRROR: gl_state = GL_MIRRORED_REPEAT; break; +#elif defined(GL_ARB_texture_mirrored_repeat) + case D3DTADDRESS_MIRROR: gl_state = GL_MIRRORED_REPEAT_ARB; break; +#endif + default: gl_state = GL_REPEAT; break; + } + return gl_state; +} + /* We need a static function for that to handle the 'special' case of 'SELECT_ARG2' */ static BOOLEAN handle_color_alpha_args(IDirect3DDeviceImpl *This, DWORD dwStage, D3DTEXTURESTAGESTATETYPE d3dTexStageStateType, DWORD dwState, D3DTEXTUREOP tex_op) @@ -1678,18 +1696,20 @@ case D3DTSS_ADDRESS: case D3DTSS_ADDRESSU: case D3DTSS_ADDRESSV: { - GLenum arg = GL_REPEAT; /* Default value */ + GLenum arg = convert_tex_address_to_GL(dwState); + switch ((D3DTEXTUREADDRESS) dwState) { - case D3DTADDRESS_WRAP: TRACE(" Stage type is : %s => D3DTADDRESS_WRAP\n", type); arg = GL_REPEAT; break; - case D3DTADDRESS_CLAMP: TRACE(" Stage type is : %s => D3DTADDRESS_CLAMP\n", type); arg = GL_CLAMP; break; - case D3DTADDRESS_BORDER: TRACE(" Stage type is : %s => D3DTADDRESS_BORDER\n", type); arg = GL_CLAMP_TO_EDGE; break; + case D3DTADDRESS_WRAP: TRACE(" Stage type is : %s => D3DTADDRESS_WRAP\n", type); break; + case D3DTADDRESS_CLAMP: TRACE(" Stage type is : %s => D3DTADDRESS_CLAMP\n", type); break; + case D3DTADDRESS_BORDER: TRACE(" Stage type is : %s => D3DTADDRESS_BORDER\n", type); break; #if defined(GL_VERSION_1_4) - case D3DTADDRESS_MIRROR: TRACE(" Stage type is : %s => D3DTADDRESS_MIRROR\n", type); arg = GL_MIRRORED_REPEAT; break; + case D3DTADDRESS_MIRROR: TRACE(" Stage type is : %s => D3DTADDRESS_MIRROR\n", type); break; #elif defined(GL_ARB_texture_mirrored_repeat) - case D3DTADDRESS_MIRROR: TRACE(" Stage type is : %s => D3DTADDRESS_MIRROR\n", type); arg = GL_MIRRORED_REPEAT_ARB; break; + case D3DTADDRESS_MIRROR: TRACE(" Stage type is : %s => D3DTADDRESS_MIRROR\n", type); break; #endif default: FIXME(" Unhandled stage type : %s => %08lx\n", type, dwState); break; } + if ((d3dTexStageStateType == D3DTSS_ADDRESS) || (d3dTexStageStateType == D3DTSS_ADDRESSU)) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, arg); @@ -2007,10 +2027,16 @@ } else { IDirectDrawSurfaceImpl *tex_impl = ICOM_OBJECT(IDirectDrawSurfaceImpl, IDirectDrawSurface7, lpTexture2); GLint max_mip_level; + GLfloat color[4]; - This->current_texture[dwStage] = tex_impl; IDirectDrawSurface7_AddRef(ICOM_INTERFACE(tex_impl, IDirectDrawSurface7)); /* Not sure about this either */ + if (This->current_texture[dwStage] == tex_impl) { + /* No need to do anything as the texture did not change. */ + return DD_OK; + } + This->current_texture[dwStage] = tex_impl; + if (This->state_block.texture_stage_state[dwStage][D3DTSS_COLOROP - 1] != D3DTOP_DISABLE) { /* Do not re-enable texturing if it was disabled due to the COLOROP code */ glEnable(GL_TEXTURE_2D); @@ -2023,13 +2049,23 @@ } else { max_mip_level = tex_impl->surface_desc.u2.dwMipMapCount - 1; } - + + /* Now we need to reset all glTexParameter calls for this particular texture... */ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, convert_mag_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MAGFILTER - 1])); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, convert_min_filter_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_MINFILTER - 1], This->state_block.texture_stage_state[dwStage][D3DTSS_MIPFILTER - 1])); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, + convert_tex_address_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSU - 1])); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, + convert_tex_address_to_GL(This->state_block.texture_stage_state[dwStage][D3DTSS_ADDRESSV - 1])); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, max_mip_level); + color[0] = ((This->state_block.texture_stage_state[dwStage][D3DTSS_BORDERCOLOR - 1] >> 16) & 0xFF) / 255.0; + color[1] = ((This->state_block.texture_stage_state[dwStage][D3DTSS_BORDERCOLOR - 1] >> 8) & 0xFF) / 255.0; + color[2] = ((This->state_block.texture_stage_state[dwStage][D3DTSS_BORDERCOLOR - 1] >> 0) & 0xFF) / 255.0; + color[3] = ((This->state_block.texture_stage_state[dwStage][D3DTSS_BORDERCOLOR - 1] >> 24) & 0xFF) / 255.0; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color); } LEAVE_GL(); @@ -2971,6 +3007,8 @@ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, UNLOCK_TEX_SIZE, UNLOCK_TEX_SIZE, 0, GL_RGB, buffer_type, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); } else { glBindTexture(GL_TEXTURE_2D, gl_d3d_dev->unlock_tex); } @@ -2983,8 +3021,6 @@ glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); glDisable(GL_FOG); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); for (x = loc_rect.left; x < loc_rect.right; x += UNLOCK_TEX_SIZE) { for (y = loc_rect.top; y < loc_rect.bottom; y += UNLOCK_TEX_SIZE) { @@ -3026,8 +3062,6 @@ glDisable(GL_SCISSOR_TEST); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glPixelStorei(GL_UNPACK_SWAP_BYTES, FALSE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, max_tex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_tex); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tex_env); glDepthRange(d3d_dev->active_viewport.dvMinZ, d3d_dev->active_viewport.dvMaxZ); glViewport(d3d_dev->active_viewport.dwX,