[D3D 12] Some new vertex type supported in the D3D3/7 DrawPrimitive method
Lionel Ulmer
lionel.ulmer at free.fr
Sat Nov 30 06:03:19 CST 2002
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/
-------------- next part --------------
--- ../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();
More information about the wine-patches
mailing list