[D3D 23] Fog, renderstate and a new texture format...

Lionel Ulmer lionel.ulmer at free.fr
Sun Dec 15 14:57:51 CST 2002


Changelog:
 - revert some optimisations breaking some games
 - added a new texture format (4444 ARGB)
 - fixed the computation of colors
 - added new render states and fog support (NOT handled yet for transformed
   vertices)

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- ../wine_base/dlls/ddraw/d3dtexture.c	Sun Dec 15 18:47:58 2002
+++ dlls/ddraw/d3dtexture.c	Sun Dec 15 20:22:27 2002
@@ -397,6 +397,37 @@
 				    GL_RGBA,
 				    GL_UNSIGNED_SHORT_4_4_4_4,
 				    src_d->lpSurface);
+	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000F000) {
+	        /* Move the four Alpha bits... */
+	        WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
+		DWORD i;
+		WORD *src = (WORD *) src_d->lpSurface, *dst = surface;
+		
+		for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) {
+		    *dst++ = (((*src & 0xFFF0) >>  4) |
+			      ((*src & 0x000F) << 12));
+		    src++;
+		}
+		
+		if (init_upload)
+		    glTexImage2D(GL_TEXTURE_2D,
+				 glThis->mipmap_level,
+				 GL_RGBA,
+				 src_d->dwWidth, src_d->dwHeight,
+				 0,
+				 GL_RGBA,
+				 GL_UNSIGNED_SHORT_4_4_4_4,
+				 surface);
+		else
+		    glTexSubImage2D(GL_TEXTURE_2D,
+				    glThis->mipmap_level,
+				    0, 0,
+				    src_d->dwWidth, src_d->dwHeight,
+				    GL_RGBA,
+				    GL_UNSIGNED_SHORT_4_4_4_4,
+				    surface);
+		
+		HeapFree(GetProcessHeap(), 0, surface);
 	    } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) {
 	        /* Converting the 1555 format in 5551 packed */
 	        WORD *surface = (WORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(WORD));
@@ -779,17 +810,6 @@
     XCAST(Load) GL_IDirect3DTextureImpl_2_1T_Load,
 };
 
-ICOM_VTABLE(IDirect3DTexture2) STUB_VTABLE_IDirect3DTexture2 =
-{
-    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
-    XCAST(QueryInterface) Thunk_IDirect3DTextureImpl_2_QueryInterface,
-    XCAST(AddRef) Thunk_IDirect3DTextureImpl_2_AddRef,
-    XCAST(Release) Thunk_IDirect3DTextureImpl_2_Release,
-    XCAST(GetHandle) Main_IDirect3DTextureImpl_2_1T_GetHandle,
-    XCAST(PaletteChanged) Main_IDirect3DTextureImpl_2_1T_PaletteChanged,
-    XCAST(Load) Main_IDirect3DTextureImpl_2_1T_Load,
-};
-
 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
 #undef XCAST
 #endif
@@ -823,14 +843,6 @@
 {
     IDirect3DTextureGLImpl *private;
 
-    if ((surf->surface_desc.ddsCaps.dwCaps & (DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY)) != 0) {
-        /* If it is an offscreen texture, only create stub implementations.
-	   Only the IUnknown interfaces should be used anyway. */
-        ICOM_INIT_INTERFACE(surf, IDirect3DTexture,  VTABLE_IDirect3DTexture); /* No special STUB one here as all functions are stubs */
-	ICOM_INIT_INTERFACE(surf, IDirect3DTexture2, STUB_VTABLE_IDirect3DTexture2);
-        return DD_OK;
-    }
-    
     private = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DTextureGLImpl));
     if (private == NULL) return DDERR_OUTOFMEMORY;
 
--- ../wine_base/dlls/ddraw/mesa.c	Sun Dec 15 18:47:58 2002
+++ dlls/ddraw/mesa.c	Sun Dec 15 21:45:38 2002
@@ -83,6 +83,7 @@
 		}
 	    } break;
 
+	      
 	    case D3DRENDERSTATE_TEXTUREADDRESSU:  /* 44 */
 	    case D3DRENDERSTATE_TEXTUREADDRESSV:  /* 45 */
 	    case D3DRENDERSTATE_TEXTUREADDRESS: { /*  3 */
@@ -268,7 +269,34 @@
 		else
 		    glDisable(GL_BLEND);
 	        break;
+	      
+	    case D3DRENDERSTATE_FOGENABLE: /* 28 */
+	        if (dwRenderState)
+		    glEnable(GL_FOG);
+		else
+		    glDisable(GL_FOG);
+	        break;
+
+	    case D3DRENDERSTATE_SPECULARENABLE: /* 29 */
+	        if (dwRenderState)
+		    ERR(" Specular Lighting not supported yet.\n");
+	        break;
+	      
+	    case D3DRENDERSTATE_SUBPIXEL:  /* 31 */
+	    case D3DRENDERSTATE_SUBPIXELX: /* 32 */
+	        /* We do not support this anyway, so why protest :-) */
+	        break;
+
+	    case D3DRENDERSTATE_FOGCOLOR: { /* 34 */
+	        GLint color[4];
+		color[0] = (dwRenderState >> 16) & 0xFF;
+		color[1] = (dwRenderState >>  8) & 0xFF;
+		color[2] = (dwRenderState >>  0) & 0xFF;
+		color[3] = (dwRenderState >> 24) & 0xFF;
+		glFogiv(GL_FOG_COLOR, color);
+	    } break;
 
+	      
 	    case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
 	        if (dwRenderState)
 		    glEnable(GL_BLEND);
@@ -276,6 +304,20 @@
 		    glDisable(GL_BLEND);
 	        break;
 
+	    case D3DRENDERSTATE_ZBIAS: /* 47 */
+	        /* This is a tad bit hacky.. But well, no idea how to do it better in OpenGL :-/ */
+	        if (dwRenderState == 0) {
+		    glDisable(GL_POLYGON_OFFSET_FILL);
+		    glDisable(GL_POLYGON_OFFSET_LINE);
+		    glDisable(GL_POLYGON_OFFSET_POINT);
+		} else {
+		    glEnable(GL_POLYGON_OFFSET_FILL);
+		    glEnable(GL_POLYGON_OFFSET_LINE);
+		    glEnable(GL_POLYGON_OFFSET_POINT);
+		    glPolygonOffset(1.0, dwRenderState * 1.0);
+		}
+	        break;
+	      
 	    case D3DRENDERSTATE_FLUSHBATCH:         /* 50 */
 	        break;
 
--- ../wine_base/dlls/ddraw/d3ddevice/mesa.c	Sun Dec 15 19:25:19 2002
+++ dlls/ddraw/d3ddevice/mesa.c	Sun Dec 15 21:45:07 2002
@@ -733,23 +733,24 @@
 	        D3DLVERTEX *vx = ((D3DLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
 		DWORD col = vx->u4.color;
 
-		glColor3f(((col >> 16) & 0xFF) / 255.0,
-			  ((col >>  8) & 0xFF) / 255.0,
-			  ((col >>  0) & 0xFF) / 255.0);
+		glColor4ub((col >> 16) & 0xFF,
+			   (col >>  8) & 0xFF,
+			   (col >>  0) & 0xFF,
+			   (col >> 24) & 0xFF);
 		glVertex3f(vx->u1.x, vx->u2.y, vx->u3.z);
-		TRACE("  LV: %f %f %f (%02lx %02lx %02lx)\n",
+		TRACE("  LV: %f %f %f (%02lx %02lx %02lx %02lx)\n",
 		      vx->u1.x, vx->u2.y, vx->u3.z,
-		      ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF));
+		      ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF), ((col >> 24) & 0xFF));
 	    } break;
 
 	    case D3DVT_TLVERTEX: {
 	        D3DTLVERTEX *vx = ((D3DTLVERTEX *) lpvertex) + (index == 0 ? vx_index : index[vx_index]);
 		DWORD col = vx->u5.color;
 
-		glColor4ub((col >> 24) & 0xFF,
-			   (col >> 16) & 0xFF,
+		glColor4ub((col >> 16) & 0xFF,
 			   (col >>  8) & 0xFF,
-			   (col >>  0) & 0xFF);
+			   (col >>  0) & 0xFF,
+			   (col >> 24) & 0xFF);
 		glTexCoord2f(vx->u7.tu, vx->u8.tv);
 		if (vx->u4.rhw < 0.01)
 		    glVertex3f(vx->u1.sx,
@@ -760,9 +761,9 @@
 			       vx->u2.sy / vx->u4.rhw,
 			       vx->u3.sz / vx->u4.rhw,
 			       1.0 / vx->u4.rhw);
-		TRACE(" TLV: %f %f %f (%02lx %02lx %02lx) (%f %f) (%f)\n",
+		TRACE(" TLV: %f %f %f (%02lx %02lx %02lx %02lx) (%f %f) (%f)\n",
 		      vx->u1.sx, vx->u2.sy, vx->u3.sz,
-		      ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF),
+		      ((col >> 16) & 0xFF), ((col >>  8) & 0xFF), ((col >>  0) & 0xFF), ((col >> 24) & 0xFF),
 		      vx->u7.tu, vx->u8.tv, vx->u4.rhw);
 	    } break;
 
@@ -926,10 +927,10 @@
 }
 static void handle_diffuse(char *vertex, int offset, int extra) {
     DWORD color = *((DWORD *) (vertex + offset));
-    glColor4ub((color >> 24) & 0xFF,
-	       (color >> 16) & 0xFF,
+    glColor4ub((color >> 16) & 0xFF,
 	       (color >>  8) & 0xFF,
-	       (color >>  0) & 0xFF);
+	       (color >>  0) & 0xFF,
+	       (color >> 24) & 0xFF);
 }
 static void handle_texture(char *vertex, int offset, int extra) {
     if (extra == 0xFF) {
@@ -983,10 +984,10 @@
 	for (index = 0; index < dwIndexCount; index++) {
 	    int i = (dwIndices == NULL) ? index : dwIndices[index];
 	    
-	    glColor4ub((vertices[i].diffuse >> 24) & 0xFF,
-		       (vertices[i].diffuse >> 16) & 0xFF,
+	    glColor4ub((vertices[i].diffuse >> 16) & 0xFF,
 		       (vertices[i].diffuse >>  8) & 0xFF,
-		       (vertices[i].diffuse >>  0) & 0xFF);
+		       (vertices[i].diffuse >>  0) & 0xFF,
+		       (vertices[i].diffuse >> 24) & 0xFF);
 	    /* Todo : handle specular... */
 	    glTexCoord2fv(&(vertices[i].tu1));
 	    if (vertices[i].rhw < 0.00001)
@@ -998,14 +999,14 @@
 			   1.0 / vertices[i].rhw);
 	    TRACE(" %f %f %f %f / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
 		  vertices[i].x, vertices[i].y, vertices[i].z, vertices[i].rhw,
-		  (vertices[i].diffuse >> 24) & 0xFF,
 		  (vertices[i].diffuse >> 16) & 0xFF,
 		  (vertices[i].diffuse >>  8) & 0xFF,
 		  (vertices[i].diffuse >>  0) & 0xFF,
-		  (vertices[i].specular >> 24) & 0xFF,
+		  (vertices[i].diffuse >> 24) & 0xFF,
 		  (vertices[i].specular >> 16) & 0xFF,
 		  (vertices[i].specular >>  8) & 0xFF,
 		  (vertices[i].specular >>  0) & 0xFF,
+		  (vertices[i].specular >> 24) & 0xFF,
 		  vertices[i].tu1, vertices[i].tv1);
 	} 
     } else if (((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) ||
@@ -1144,23 +1145,23 @@
 	for (index = 0; index < dwIndexCount; index++) {
 	    int i = (dwIndices == NULL) ? index : dwIndices[index];
 	    
-	    glColor4ub((CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF,
-		       (CPNT(diffuse,i,0,DWORD) >> 16) & 0xFF,
+	    glColor4ub((CPNT(diffuse,i,0,DWORD) >> 16) & 0xFF,
 		       (CPNT(diffuse,i,0,DWORD) >>  8) & 0xFF,
-		       (CPNT(diffuse,i,0,DWORD) >>  0) & 0xFF);
+		       (CPNT(diffuse,i,0,DWORD) >>  0) & 0xFF,
+		       (CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF);
 	    /* Todo : handle specular... */
 	    glTexCoord2f(CPNT(textureCoords[1],i,0,D3DVALUE),CPNT(textureCoords[1],i,1,D3DVALUE));
 	    glVertex3f(CPNT(position,i,0,D3DVALUE),CPNT(position,i,1,D3DVALUE),CPNT(position,i,2,D3DVALUE));
 	    TRACE(" %f %f %f  / %02lx %02lx %02lx %02lx - %02lx %02lx %02lx %02lx (%f %f)\n",
 		  CPNT(position,i,0,D3DVALUE),CPNT(position,i,1,D3DVALUE),CPNT(position,i,2,D3DVALUE),
-		  (CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF,
 		  (CPNT(diffuse,i,0,DWORD) >> 16) & 0xFF,
 		  (CPNT(diffuse,i,0,DWORD) >>  8) & 0xFF,
 		  (CPNT(diffuse,i,0,DWORD) >>  0) & 0xFF,
-		  (CPNT(specular,i,0,DWORD) >> 24) & 0xFF,
+		  (CPNT(diffuse,i,0,DWORD) >> 24) & 0xFF,
 		  (CPNT(specular,i,0,DWORD) >> 16) & 0xFF,
 		  (CPNT(specular,i,0,DWORD) >>  8) & 0xFF,
 		  (CPNT(specular,i,0,DWORD) >>  0) & 0xFF,
+		  (CPNT(specular,i,0,DWORD) >> 24) & 0xFF,
 		  CPNT(textureCoords[0],i,0,D3DVALUE),CPNT(textureCoords[0],i,1,D3DVALUE));
 	} 
     }
--- ../wine_base/dlls/ddraw/ddraw/main.c	Sun Dec 15 12:15:49 2002
+++ dlls/ddraw/ddraw/main.c	Sun Dec 15 20:10:22 2002
@@ -557,6 +557,11 @@
        /* create backbuffer surface */
        hr = This->create_backbuffer(This, pDDSD, ppSurf, pUnkOuter, NULL);
     }
+    else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
+    {
+	/* create texture */
+	hr = create_texture(This, pDDSD, ppSurf, pUnkOuter);
+    }
     else if ((pDDSD->ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) ||
 	     (pDDSD->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) /* No difference in Wine right now */
     {
@@ -567,11 +572,6 @@
     {
 	/* create z-buffer */
 	hr = This->create_zbuffer(This, pDDSD, ppSurf, pUnkOuter);
-    }
-    else if (pDDSD->ddsCaps.dwCaps & DDSCAPS_TEXTURE)
-    {
-	/* create texture */
-	hr = create_texture(This, pDDSD, ppSurf, pUnkOuter);
     }
     else
     {


More information about the wine-patches mailing list