[D3D 12] Some new vertex type supported in the D3D3/7 DrawPrimitive method

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

 



Hi all,

This patch adds the Transformed / Lit case for the DrawPrimitive API in D3D
3 / 7. It also shares some more code between D3D 1/2 and 3/7.

Changelog:
 - some more code sharing between D3DDevice versions
 - implementation of D3DFVF_TLVERTEX format fast path

              Lionel

PS: still 35 patches to go to unthrone Dimi as the patch series king :-)

-- 
		 Lionel Ulmer - http://www.bbrox.org/
--- ../wine_work_base/dlls/ddraw/mesa_private.h	Sat Nov 30 00:06:53 2002
+++ dlls/ddraw/mesa_private.h	Sat Nov 30 12:33:19 2002
@@ -101,7 +101,8 @@
     RenderState render_state;
 
     /* The last type of vertex drawn */
-    D3DVERTEXTYPE vertex_type;
+    BOOLEAN last_vertices_transformed;
+    BOOLEAN last_vertices_lit;
 
     D3DMATRIX *world_mat;
     D3DMATRIX *view_mat;
--- ../wine_work_base/dlls/ddraw/d3ddevice/mesa.c	Sat Nov 30 00:06:53 2002
+++ dlls/ddraw/d3ddevice/mesa.c	Sat Nov 30 12:52:48 2002
@@ -610,7 +610,7 @@
     return DD_OK;
 }
 
-inline static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
+static void draw_primitive_start_GL(D3DPRIMITIVETYPE d3dpt)
 {
     switch (d3dpt) {
         case D3DPT_POINTLIST:
@@ -649,83 +649,68 @@
     }
 }
 
+static void draw_primitive_handle_GL_state(IDirect3DDeviceGLImpl *glThis,
+					   BOOLEAN vertex_transformed,
+					   BOOLEAN vertex_lit) {
+    /* Puts GL in the correct lighting / transformation mode */
+    if ((glThis->last_vertices_transformed == TRUE) && (vertex_transformed == FALSE)) {
+        /* Need to put the correct transformation again if we go from Transformed
+	   vertices to non-transformed ones.
+	*/
+        glMatrixMode(GL_MODELVIEW);
+	glLoadMatrixf((float *) glThis->view_mat);
+	glMultMatrixf((float *) glThis->world_mat);
+	glMatrixMode(GL_PROJECTION);
+	glLoadMatrixf((float *) glThis->proj_mat);
+    } else if ((glThis->last_vertices_transformed == FALSE) && (vertex_transformed == TRUE)) {
+        GLdouble height, width, minZ, maxZ;
+      
+        glMatrixMode(GL_MODELVIEW);
+	glLoadIdentity();
+	glMatrixMode(GL_PROJECTION);
+	glLoadIdentity();
+	
+	if (glThis->parent.current_viewport == NULL) {
+	    ERR("No current viewport !\n");
+	    /* Using standard values */
+	    height = 640.0;
+	    width = 480.0;
+	    minZ = -10.0;
+	    maxZ = 10.0;
+	} else {
+	    if (glThis->parent.current_viewport->use_vp2 == 1) {
+	        height = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwHeight;
+		width  = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwWidth;
+		minZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMinZ;
+		maxZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMaxZ;
+	    } else {
+	        height = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwHeight;
+		width  = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwWidth;
+		minZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMinZ;
+		maxZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMaxZ;
+	    }
+	}
+	glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
+    }
+    
+    if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == FALSE)) {
+        glEnable(GL_LIGHTING);
+    } else if ((glThis->last_vertices_lit == TRUE) && (vertex_lit == TRUE)) {
+        glDisable(GL_LIGHTING);
+    }
+
+    /* And save the current state */
+    glThis->last_vertices_transformed = vertex_transformed;
+    glThis->last_vertices_lit = vertex_lit;
+}
+
+
 inline static void draw_primitive(IDirect3DDeviceGLImpl *glThis, DWORD maxvert, WORD *index,
 				  D3DVERTEXTYPE d3dvt, D3DPRIMITIVETYPE d3dpt, void *lpvertex)
 {
     DWORD vx_index;
   
-    /* Puts GL in the correct lighting mode */
-    if (glThis->vertex_type != d3dvt) {
-        if ((glThis->vertex_type == D3DVT_TLVERTEX) &&
-	     (d3dvt != D3DVT_TLVERTEX)) {
-	    /* Need to put the correct transformation again if we go from Transformed / Lighted
-	       vertices to non-transformed ones.
-	    */
-	    glMatrixMode(GL_MODELVIEW);
-	    glLoadMatrixf((float *) glThis->view_mat);
-	    glMultMatrixf((float *) glThis->world_mat);
-	    glMatrixMode(GL_PROJECTION);
-	    glLoadMatrixf((float *) glThis->proj_mat);
-	}
-
-	switch (d3dvt) {
-	    case D3DVT_VERTEX:
-	        TRACE("Standard Vertex\n");
-		glEnable(GL_LIGHTING);
-		break;
-
-	    case D3DVT_LVERTEX:
-		TRACE("Lighted Vertex\n");
-		glDisable(GL_LIGHTING);
-		break;
-
-	    case D3DVT_TLVERTEX: {
-	        GLdouble height, width, minZ, maxZ;
-
-		TRACE("Transformed - Lighted Vertex\n");
-		if (glThis->vertex_type != D3DVT_TLVERTEX) {
-		    /* First, disable lighting */
-		    glDisable(GL_LIGHTING);
-
-		    /* Then do not put any transformation matrixes */
-		    glMatrixMode(GL_MODELVIEW);
-		    glLoadIdentity();
-		    glMatrixMode(GL_PROJECTION);
-		    glLoadIdentity();
-		}
-
-		if (glThis->parent.current_viewport == NULL) {
-		    ERR("No current viewport !\n");
-		    /* Using standard values */
-		    height = 640.0;
-		    width = 480.0;
-		    minZ = -10.0;
-		    maxZ = 10.0;
-		} else {
-		    if (glThis->parent.current_viewport->use_vp2 == 1) {
-		        height = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwHeight;
-			width  = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dwWidth;
-			minZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMinZ;
-			maxZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp2.dvMaxZ;
-		    } else {
-		        height = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwHeight;
-			width  = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dwWidth;
-			minZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMinZ;
-			maxZ   = (GLdouble) glThis->parent.current_viewport->viewports.vp1.dvMaxZ;
-		    }
-		}
-
-		glOrtho(0.0, width, height, 0.0, -minZ, -maxZ);
-	    } break;
-
-	    default:
-		ERR("Unhandled vertex type\n");
-		break;
-	}
-
-	glThis->vertex_type = d3dvt;
-    }
-
+    draw_primitive_handle_GL_state(glThis, d3dvt == D3DVT_TLVERTEX, d3dvt != D3DVT_VERTEX);
     draw_primitive_start_GL(d3dpt);
     
     /* Draw the primitives */
@@ -886,6 +871,13 @@
     float tu1, tv1;
 } D3DFVF_VERTEX_1;
 
+typedef struct {
+    float x, y, z, rhw;
+    DWORD diffuse;
+    DWORD specular;
+    float tu1, tv1;
+} D3DFVF_TLVERTEX_1;
+
 static void draw_primitive_7(IDirect3DDeviceImpl *This,
 			     D3DPRIMITIVETYPE d3dptPrimitiveType,
 			     DWORD d3dvtVertexType,
@@ -895,19 +887,21 @@
 			     DWORD dwIndexCount,
 			     DWORD dwFlags)
 {
+    IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This;
     if (TRACE_ON(ddraw)) {
         TRACE(" Vertex format : "); dump_flexible_vertex(d3dvtVertexType);
     }
 
     ENTER_GL();
+    draw_primitive_handle_GL_state(glThis,
+				   (d3dvtVertexType & D3DFVF_POSITION_MASK) != D3DFVF_XYZ,
+				   (d3dvtVertexType & D3DFVF_NORMAL) == 0);
     draw_primitive_start_GL(d3dptPrimitiveType);
 
     /* Some fast paths first before the generic case.... */
     if (d3dvtVertexType == D3DFVF_VERTEX) {
         D3DFVF_VERTEX_1 *vertices = (D3DFVF_VERTEX_1 *) lpvVertices;
 	int index;
-
-	glEnable(GL_LIGHTING);
 	
 	for (index = 0; index < dwIndexCount; index++) {
 	    int i = (dwIndices == NULL) ? index : dwIndices[index];
@@ -920,6 +914,38 @@
 		  vertices[i].nx, vertices[i].ny, vertices[i].nz,
 		  vertices[i].tu1, vertices[i].tv1);
 	}
+    } else if (d3dvtVertexType == D3DFVF_TLVERTEX) {
+        D3DFVF_TLVERTEX_1 *vertices = (D3DFVF_TLVERTEX_1 *) lpvVertices;
+	int index;
+	
+	for (index = 0; index < dwIndexCount; index++) {
+	    int i = (dwIndices == NULL) ? index : dwIndices[index];
+	    
+	    glColor4ub((vertices[i].diffuse >> 24) & 0xFF,
+		       (vertices[i].diffuse >> 16) & 0xFF,
+		       (vertices[i].diffuse >>  8) & 0xFF,
+		       (vertices[i].diffuse >>  0) & 0xFF);
+	    /* Todo : handle specular... */
+	    glTexCoord2f(vertices[i].tu1, vertices[i].tv1);
+	    if (vertices[i].rhw < 0.00001)
+	        glVertex3f(vertices[i].x, vertices[i].y, vertices[i].z);
+	    else
+	        glVertex4f(vertices[i].x / vertices[i].rhw,
+			   vertices[i].y / vertices[i].rhw,
+			   vertices[i].z / vertices[i].rhw,
+			   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].specular >> 16) & 0xFF,
+		  (vertices[i].specular >>  8) & 0xFF,
+		  (vertices[i].specular >>  0) & 0xFF,
+		  vertices[i].tu1, vertices[i].tv1);
+	} 
     }
     
     glEnd();
@@ -1176,6 +1202,7 @@
       by other OpenGL code in D3D
     - handle the case where no 'Begin / EndScene' was done between two locks
     - handle the rectangles in the unlock too
+    - handle pitch correctly...
 */
 static void d3ddevice_lock_update(IDirectDrawSurfaceImpl* This, LPCRECT pRect, DWORD dwFlags)
 {
@@ -1255,6 +1282,7 @@
 	    return;
 	}
 
+	glRasterPos2f(0.0, 0.0);
 	glDrawPixels(This->surface_desc.dwWidth, This->surface_desc.dwHeight, 
 		     GL_RGB, buffer_type, This->surface_desc.lpSurface);
 	glDrawBuffer(prev_draw);
@@ -1350,7 +1378,6 @@
     gl_object->render_state.dst = GL_ZERO;
     gl_object->render_state.mag = GL_NEAREST;
     gl_object->render_state.min = GL_NEAREST;
-    gl_object->vertex_type = 0;
 
     /* Allocate memory for the matrices */
     gl_object->world_mat = (D3DMATRIX *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16 * sizeof(float));
@@ -1371,6 +1398,7 @@
     glColor3f(1.0, 1.0, 1.0);
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
     glDrawBuffer(buffer);
+    glReadBuffer(buffer);
     /* glDisable(GL_DEPTH_TEST); Need here to check for the presence of a ZBuffer and to reenable it when the ZBuffer is attached */
     LEAVE_GL();
 

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

  Powered by Linux