[D3D 87] Implement vertex and pixel fog

Tue Jan 21 15:54:21 CST 2003

```Changelog :
Implement vertex and pixel fog.
Fix fog color initialization.

-------------- next part --------------
diff -u -r ../../winebase/wine/dlls/ddraw/d3ddevice/mesa.c dlls/ddraw/d3ddevice/mesa.c
--- ../../winebase/wine/dlls/ddraw/d3ddevice/mesa.c	Tue Jan 21 20:53:12 2003
+++ dlls/ddraw/d3ddevice/mesa.c	Tue Jan 21 21:04:12 2003
@@ -673,6 +673,22 @@
}
}

+/* This function calculate the Z coordinate from Zproj */
+static float ZfromZproj(IDirect3DDeviceImpl *This, D3DVALUE Zproj)
+{
+    float a,b,c,d;
+    /* Assume that X = Y = 0 and W = 1 */
+    a = This->proj_mat->_33;
+    b = This->proj_mat->_34;
+    c = This->proj_mat->_43;
+    d = This->proj_mat->_44;
+    /* We have in homogenous coordinates Z' = a * Z + c and W' = b * Z + d
+     * So in non homogenous coordinates we have Zproj = (a * Z + b) / (c * Z + d)
+     * And finally Z = (d * Zproj - c) / (a - b * Zproj)
+     */
+    return (d*Zproj - c) / (a - b*Zproj);
+}
+
static void draw_primitive_handle_GL_state(IDirect3DDeviceImpl *This,
BOOLEAN vertex_transformed,
BOOLEAN vertex_lit) {
@@ -688,17 +704,34 @@
This->world_mat, This->view_mat, This->proj_mat);
glThis->transform_state = GL_TRANSFORM_NORMAL;

-	if (This->state_block.render_state[D3DRENDERSTATE_FOGENABLE - 1] == TRUE)
-	    glEnable(GL_FOG);
} else if ((vertex_transformed == TRUE) &&
(glThis->transform_state != GL_TRANSFORM_ORTHO)) {
/* Set our orthographic projection */
glThis->transform_state = GL_TRANSFORM_ORTHO;
d3ddevice_set_ortho(This);
-
-	/* Remove also fogging... */
-	glDisable(GL_FOG);
}
+    if (This->state_block.render_state[D3DRENDERSTATE_FOGENABLE - 1] == TRUE) {glHint(GL_FOG_HINT,GL_NICEST);
+        if (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1] != D3DFOG_NONE) {
+            switch (This->state_block.render_state[D3DRENDERSTATE_FOGTABLEMODE - 1]) {
+                case D3DFOG_LINEAR: glFogi(GL_FOG_MODE,GL_LINEAR); break;
+                case D3DFOG_EXP:    glFogi(GL_FOG_MODE,GL_EXP); break;
+                case D3DFOG_EXP2:   glFogi(GL_FOG_MODE,GL_EXP2); break;
+            }
+            glFogf(GL_FOG_START,ZfromZproj(This,*(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1]));
+            glFogf(GL_FOG_END,ZfromZproj(This,*(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1]));
+  	    glEnable(GL_FOG);
+        } else if ( (This->state_block.render_state[D3DRENDERSTATE_FOGVERTEXMODE - 1] != D3DFOG_NONE) &&
+                    (vertex_lit == FALSE) && (vertex_transformed == FALSE) ) {
+            /* D3DFOG_EXP and D3DFOG_EXP2 are treated as D3DFOG_LINEAR */
+            glFogi(GL_FOG_MODE,GL_LINEAR);
+            glFogf(GL_FOG_START,*(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGSTART - 1]);
+            glFogf(GL_FOG_END,*(float*)&This->state_block.render_state[D3DRENDERSTATE_FOGEND - 1]);
+  	    glEnable(GL_FOG);
+        } else
+            glDisable(GL_FOG);
+    }
+    else
+	glDisable(GL_FOG);

/* Handle the 'no-normal' case */
if (vertex_lit == TRUE)
diff -u -r ../../winebase/wine/dlls/ddraw/mesa.c dlls/ddraw/mesa.c
--- ../../winebase/wine/dlls/ddraw/mesa.c	Wed Jan  8 20:31:50 2003
+++ dlls/ddraw/mesa.c	Tue Jan 21 20:54:32 2003
@@ -304,12 +304,7 @@
break;

case D3DRENDERSTATE_FOGENABLE: /* 28 */
-	        if ((dwRenderState == TRUE) &&
-		    (glThis->transform_state != GL_TRANSFORM_ORTHO)) {
-		    glEnable(GL_FOG);
-		} else {
-		    glDisable(GL_FOG);
-		}
+	        /* Nothing to do here. Only the storage matters :-) */
break;

case D3DRENDERSTATE_SPECULARENABLE: /* 29 */
@@ -320,7 +315,7 @@
case D3DRENDERSTATE_SUBPIXEL:  /* 31 */
case D3DRENDERSTATE_SUBPIXELX: /* 32 */
/* We do not support this anyway, so why protest :-) */
-	        break;
+	        break;

case D3DRENDERSTATE_STIPPLEDALPHA: /* 33 */
if (dwRenderState)
@@ -328,15 +323,26 @@
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);
+	        GLfloat color[4];
+		color[0] = ((dwRenderState >> 16) & 0xFF)/255.0f;
+		color[1] = ((dwRenderState >>  8) & 0xFF)/255.0f;
+		color[2] = ((dwRenderState >>  0) & 0xFF)/255.0f;
+		color[3] = ((dwRenderState >> 24) & 0xFF)/255.0f;
+		glFogfv(GL_FOG_COLOR,color);
+		/* Note: glFogiv does not seem to work */
} break;

-
+ 	    case D3DRENDERSTATE_FOGTABLEMODE:  /* 35 */
+ 	    case D3DRENDERSTATE_FOGVERTEXMODE: /* 140 */
+ 	    case D3DRENDERSTATE_FOGSTART:      /* 36 */
+	    case D3DRENDERSTATE_FOGEND:        /* 37 */
+	        /* Nothing to do here. Only the storage matters :-) */
+		break;
+
+	    case D3DRENDERSTATE_FOGDENSITY:    /* 38 */
+		glFogi(GL_FOG_DENSITY,*(float*)&dwRenderState);
+		break;
+
case D3DRENDERSTATE_COLORKEYENABLE:     /* 41 */
/* This needs to be fixed. */
if (dwRenderState)

```