[D3D] Final DungeonSiege fixes...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



(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,

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux