[D3D 57] Some paletted textures improvements

Lionel Ulmer lionel.ulmer at free.fr
Fri Dec 27 12:26:51 CST 2002


Changelog
 - allow application to load palette-less textures
 - handle palette change of loaded textures
 - some changes in the ExecuteBuffer

-- 
		 Lionel Ulmer - http://www.bbrox.org/
-------------- next part --------------
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3dexecutebuffer.c	2002-12-27 17:30:31.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3dexecutebuffer.c	2002-12-27 13:03:17.000000000 +0100
@@ -217,12 +217,12 @@
 	
 	switch (current->bOpcode) {
 	    case D3DOP_POINT: {
-	        TRACE("POINT-s          (%d)\n", count);
+	        WARN("POINT-s          (%d)\n", count);
 		instr += count * size;
 	    } break;
 
 	    case D3DOP_LINE: {
-	        TRACE("LINE-s           (%d)\n", count);
+	        WARN("LINE-s           (%d)\n", count);
 		instr += count * size;
 	    } break;
 
@@ -278,37 +278,31 @@
 			break;
 
 		    case D3DVT_TLVERTEX: {
-		        GLdouble height, width, minZ, maxZ;
+		        GLdouble height, width;
+			GLfloat trans_mat[16];
 			
 			/* First, disable lighting */
 			glDisable(GL_LIGHTING);
 			
-			/* Then do not put any transformation matrixes */
+			width = lpDevice->surface->surface_desc.dwWidth;
+			height = lpDevice->surface->surface_desc.dwHeight;
+
+			/* The X axis is straighforward.. For the Y axis, we need to convert 'D3D' screen coordinates
+			   to OpenGL screen coordinates (ie the upper left corner is not the same).
+			   For Z, the mystery is what should it be mapped to ? Ie should the resulting range be between
+			   -1.0 and 1.0 (as the X and Y coordinates) or between 0.0 and 1.0 ? */
+			trans_mat[ 0] = 2.0 / width;  trans_mat[ 4] = 0.0;  trans_mat[ 8] = 0.0; trans_mat[12] = -1.0;
+			trans_mat[ 1] = 0.0; trans_mat[ 5] = -2.0 / height; trans_mat[ 9] = 0.0; trans_mat[13] =  1.0;
+			trans_mat[ 2] = 0.0; trans_mat[ 6] = 0.0; trans_mat[10] = 1.0;           trans_mat[14] = -1.0;
+			trans_mat[ 3] = 0.0; trans_mat[ 7] = 0.0; trans_mat[11] = 0.0;           trans_mat[15] =  1.0;
+
 			glMatrixMode(GL_MODELVIEW);
 			glLoadIdentity();
 			glMatrixMode(GL_PROJECTION);
-			glLoadIdentity();
-			
-			if (lpViewport == NULL) {
-			    ERR("No current viewport !\n");
-			    /* Using standard values */
-			    height = 640.0;
-			    width = 480.0;
-			    minZ = -10.0;
-			    maxZ = 10.0;
-			} else {
-			    height = (GLdouble) lpViewport->viewports.vp1.dwHeight;
-			    width  = (GLdouble) lpViewport->viewports.vp1.dwWidth;
-			    minZ   = (GLdouble) lpViewport->viewports.vp1.dvMinZ;
-			    maxZ   = (GLdouble) lpViewport->viewports.vp1.dvMaxZ;
-			    
-			    if (minZ == maxZ) {
-			        /* I do not know why, but many Dx 3.0 games have minZ = maxZ = 0.0 */
-			        minZ = 0.0;
-				maxZ = 1.0;
-			    }
-			}
-			glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
+			glLoadMatrixf(trans_mat);
+
+			/* Remove also fogging... */
+			glDisable(GL_FOG);
 		    } break;
 
 		    default:
@@ -335,7 +329,7 @@
 	    } break;
 
 	    case D3DOP_MATRIXLOAD:
-	        TRACE("MATRIXLOAD-s     (%d)\n", count);
+	        WARN("MATRIXLOAD-s     (%d)\n", count);
 	        instr += count * size;
 	        break;
 
@@ -440,23 +434,23 @@
 			} break ;
 			  
 			case D3DLIGHTSTATE_COLORMODEL: {
-			    TRACE("  COLORMODEL\n");
+			    WARN("  COLORMODEL\n");
 			} break ;
 
 			case D3DLIGHTSTATE_FOGMODE: {
-			    TRACE("  FOGMODE\n");
+			    WARN("  FOGMODE\n");
 			} break ;
 
 			case D3DLIGHTSTATE_FOGSTART: {
-			    TRACE("  FOGSTART\n");
+			    WARN("  FOGSTART\n");
 			} break ;
 
 			case D3DLIGHTSTATE_FOGEND: {
-			    TRACE("  FOGEND\n");
+			    WARN("  FOGEND\n");
 			} break ;
 
 			case D3DLIGHTSTATE_FOGDENSITY: {
-			    TRACE("  FOGDENSITY\n");
+			    WARN("  FOGDENSITY\n");
 			} break ;
 
 			default:
@@ -605,7 +599,7 @@
 	    } break;
 
 	    case D3DOP_TEXTURELOAD: {
-	        TRACE("TEXTURELOAD-s    (%d)\n", count);
+	        WARN("TEXTURELOAD-s    (%d)\n", count);
 
 		instr += count * size;
 	    } break;
@@ -640,7 +634,7 @@
 	    } break;
 
 	    case D3DOP_SPAN: {
-	        TRACE("SPAN-s           (%d)\n", count);
+	        WARN("SPAN-s           (%d)\n", count);
 
 		instr += count * size;
 	    } break;
@@ -737,7 +731,7 @@
 {
     ICOM_THIS_FROM(IDirect3DExecuteBufferImpl, IDirect3DExecuteBuffer, iface);
     DWORD dwSize;
-    TRACE("(%p/%p)->(%p): stub!\n", This, iface, lpDesc);
+    TRACE("(%p/%p)->(%p)\n", This, iface, lpDesc);
 
     dwSize = lpDesc->dwSize;
     memset(lpDesc, 0, dwSize);
--- /home/ulmer/Wine/wine_base//dlls/ddraw/d3dtexture.c	2002-12-27 17:30:31.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/d3dtexture.c	2002-12-27 17:28:51.000000000 +0100
@@ -177,21 +177,22 @@
 #endif
 	
 	if (pal == NULL) {
-	    ERR("Palettized texture Loading with a NULL palette !\n");
-	    glBindTexture(GL_TEXTURE_2D, current_texture);
-	    return D3DERR_INVALIDPALETTE;
-	}
-	/* Get the surface's palette */
-	for (i = 0; i < 256; i++) {
-	    table[i][0] = pal->palents[i].peRed;
-	    table[i][1] = pal->palents[i].peGreen;
-	    table[i][2] = pal->palents[i].peBlue;
-	    if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
-		(i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
-		(i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
-	        table[i][3] = 0x00;
-	    else
-	        table[i][3] = 0xFF;
+	    /* Upload a black texture. The real one will be uploaded on palette change */
+	    WARN("Palettized texture Loading with a NULL palette !\n");
+	    memset(table, 0, 256 * 4);
+	} else {
+	    /* Get the surface's palette */
+	    for (i = 0; i < 256; i++) {
+	        table[i][0] = pal->palents[i].peRed;
+		table[i][1] = pal->palents[i].peGreen;
+		table[i][2] = pal->palents[i].peBlue;
+		if ((src_d->dwFlags & DDSD_CKSRCBLT) &&
+		    (i >= src_d->ddckCKSrcBlt.dwColorSpaceLowValue) &&
+		    (i <= src_d->ddckCKSrcBlt.dwColorSpaceHighValue))
+		    table[i][3] = 0x00;
+		else
+		    table[i][3] = 0xFF;
+	    }
 	}
 
 	if (ptr_ColorTableEXT != NULL) {
@@ -373,6 +374,19 @@
     return DD_OK;
 }
 
+static void gltex_set_palette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal)
+{
+    IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
+    
+    /* First call the previous set_palette function */
+    glThis->set_palette(This, pal);
+
+    /* Then re-upload the texture to OpenGL */
+    ENTER_GL();
+    gltex_upload_texture(This, glThis->first_unlock);
+    LEAVE_GL();
+}
+
 static void
 gltex_final_release(IDirectDrawSurfaceImpl *This)
 {
@@ -415,12 +429,12 @@
 {
     IDirect3DTextureGLImpl *glThis = (IDirect3DTextureGLImpl *) This->tex_private;
 
+    glThis->unlock_update(This, pRect);
+    
     ENTER_GL();
     gltex_upload_texture(This, glThis->first_unlock);
     LEAVE_GL();
     glThis->first_unlock = FALSE;
-
-    glThis->unlock_update(This, pRect);
 }
 
 HRESULT WINAPI
@@ -490,7 +504,22 @@
 
     /* Suppress the ALLOCONLOAD flag */
     This->surface_desc.ddsCaps.dwCaps &= ~DDSCAPS_ALLOCONLOAD;
-    This->palette = lpD3DTextureImpl->palette;
+    
+    /* After seeing some logs, not sure at all about this... */
+    if (This->palette == NULL) {
+        This->palette = lpD3DTextureImpl->palette;
+	if (lpD3DTextureImpl->palette != NULL) IDirectDrawPalette_AddRef(ICOM_INTERFACE(lpD3DTextureImpl->palette,
+										IDirectDrawPalette));
+    } else {
+        if (lpD3DTextureImpl->palette != NULL) {
+	    PALETTEENTRY palent[256];
+	    IDirectDrawPalette *pal_int = ICOM_INTERFACE(lpD3DTextureImpl->palette, IDirectDrawPalette);
+	    IDirectDrawPalette_AddRef(pal_int);
+	    IDirectDrawPalette_GetEntries(pal_int, 0, 0, 256, palent);
+	    IDirectDrawPalette_SetEntries(ICOM_INTERFACE(This->palette, IDirectDrawPalette),
+					  0, 0, 256, palent);
+	}
+    }
     
     /* Copy one surface on the other */
     dst_d = (DDSURFACEDESC *)&(This->surface_desc);
@@ -676,6 +705,7 @@
 	private->final_release = surf->final_release;
 	private->lock_update = surf->lock_update;
 	private->unlock_update = surf->unlock_update;
+	private->set_palette = surf->set_palette;
 	
 	/* If at creation, we can optimize stuff and wait the first 'unlock' to upload a valid stuff to OpenGL.
 	   Otherwise, it will be uploaded here (and may be invalid). */
@@ -688,7 +718,8 @@
 	surf->unlock_update = gltex_unlock_update;
 	surf->tex_private = private;
 	surf->aux_setcolorkey_cb = gltex_setcolorkey_cb;
-	
+	surf->set_palette = gltex_set_palette;
+
 	ENTER_GL();
 	if (surf->mipmap_level == 0) {
 	    glGenTextures(1, &(private->tex_name));
--- /home/ulmer/Wine/wine_base//dlls/ddraw/mesa_private.h	2002-12-27 17:30:31.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/mesa_private.h	2002-12-27 17:04:51.000000000 +0100
@@ -100,6 +100,7 @@
     void (*final_release)(struct IDirectDrawSurfaceImpl *This);
     void (*lock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags);
     void (*unlock_update)(IDirectDrawSurfaceImpl* This, LPCRECT pRect);
+    void (*set_palette)(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* pal);
 } IDirect3DTextureGLImpl;
 
 typedef struct IDirect3DDeviceGLImpl
--- /home/ulmer/Wine/wine_base//dlls/ddraw/dsurface/main.c	2002-12-27 17:30:31.000000000 +0100
+++ /home/ulmer/Wine/wine_work//dlls/ddraw/dsurface/main.c	2002-12-27 17:22:38.000000000 +0100
@@ -100,6 +100,10 @@
 
 static void Main_DirectDrawSurface_Destroy(IDirectDrawSurfaceImpl* This)
 {
+    if (This->palette) {
+        IDirectDrawPalette_Release(ICOM_INTERFACE(This->palette, IDirectDrawPalette));
+	This->palette = NULL;
+    }
     This->final_release(This);
     if (This->private != This+1) HeapFree(GetProcessHeap(), 0, This->private);
     if (This->tex_private) HeapFree(GetProcessHeap(), 0, This->tex_private);


More information about the wine-patches mailing list