From c064dcf50c1685032c0a6e7c78129defa3c20083 Mon Sep 17 00:00:00 2001 From: Lionel Ulmer Date: Fri, 3 Jan 2003 21:07:22 +0000 Subject: [PATCH] - hack for one case of the ProcessVertices case - some changes in the execute buffer to reuse the new Matrix code - always reinitialize the enumeration structures in case some games modify them - added support for the (unused) Reserved1 field in the FVF formats - fix 32 bit texturing and added more checks - remove some useless and annoying fixme --- dlls/ddraw/d3d_private.h | 9 +- dlls/ddraw/d3dcommon.c | 78 +++++++++++-- dlls/ddraw/d3ddevice/main.c | 2 +- dlls/ddraw/d3ddevice/mesa.c | 178 +++++++++++++---------------- dlls/ddraw/d3dexecutebuffer.c | 51 ++++----- dlls/ddraw/d3dtexture.c | 80 +++++++++++--- dlls/ddraw/d3dvertexbuffer.c | 203 +++++++++++++++++++++++++++++++++- dlls/ddraw/mesa_private.h | 9 ++ 8 files changed, 451 insertions(+), 159 deletions(-) diff --git a/dlls/ddraw/d3d_private.h b/dlls/ddraw/d3d_private.h index 427c76f8e1..f166482de7 100644 --- a/dlls/ddraw/d3d_private.h +++ b/dlls/ddraw/d3d_private.h @@ -226,6 +226,8 @@ struct IDirect3DVertexBufferImpl D3DVERTEXBUFFERDESC desc; LPVOID *vertices; DWORD vertex_buffer_size; + + BOOLEAN processed; }; /* Various dump and helper functions */ @@ -237,6 +239,11 @@ extern void dump_DPFLAGS(DWORD dwFlags); extern void dump_D3DMATRIX(D3DMATRIX *mat); extern void dump_D3DVECTOR(D3DVECTOR *lpVec); extern void dump_flexible_vertex(DWORD d3dvtVertexType); -extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements); +extern DWORD get_flexible_vertex_size(DWORD d3dvtVertexType); +extern void convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided); +extern void dump_D3DVOP(DWORD dwVertexOp); +extern void dump_D3DPV(DWORD dwFlags); + +extern const float id_mat[16]; #endif /* __GRAPHICS_WINE_D3D_PRIVATE_H */ diff --git a/dlls/ddraw/d3dcommon.c b/dlls/ddraw/d3dcommon.c index 34c07bd6c4..64fe11c4c5 100644 --- a/dlls/ddraw/d3dcommon.c +++ b/dlls/ddraw/d3dcommon.c @@ -230,23 +230,20 @@ dump_D3DMATRIX(D3DMATRIX *mat) } -DWORD get_flexible_vertex_size(DWORD d3dvtVertexType, DWORD *elements) +DWORD get_flexible_vertex_size(DWORD d3dvtVertexType) { DWORD size = 0; - DWORD elts = 0; - if (d3dvtVertexType & D3DFVF_NORMAL) { size += 3 * sizeof(D3DVALUE); elts += 1; } - if (d3dvtVertexType & D3DFVF_DIFFUSE) { size += sizeof(DWORD); elts += 1; } - if (d3dvtVertexType & D3DFVF_SPECULAR) { size += sizeof(DWORD); elts += 1; } + if (d3dvtVertexType & D3DFVF_NORMAL) size += 3 * sizeof(D3DVALUE); + if (d3dvtVertexType & D3DFVF_DIFFUSE) size += sizeof(DWORD); + if (d3dvtVertexType & D3DFVF_SPECULAR) size += sizeof(DWORD); + if (d3dvtVertexType & D3DFVF_RESERVED1) size += sizeof(DWORD); switch (d3dvtVertexType & D3DFVF_POSITION_MASK) { - case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); elts += 1; break; - case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); elts += 1; break; + case D3DFVF_XYZ: size += 3 * sizeof(D3DVALUE); break; + case D3DFVF_XYZRHW: size += 4 * sizeof(D3DVALUE); break; default: TRACE(" matrix weighting not handled yet...\n"); } size += 2 * sizeof(D3DVALUE) * ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); - elts += (d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; - - if (elements) *elements = elts; return size; } @@ -290,3 +287,64 @@ void dump_flexible_vertex(DWORD d3dvtVertexType) } DPRINTF("\n"); } + +void +convert_FVF_to_strided_data(DWORD d3dvtVertexType, LPVOID lpvVertices, D3DDRAWPRIMITIVESTRIDEDDATA *strided) +{ + int current_offset = 0; + int tex_index; + + if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { + strided->position.lpvData = lpvVertices; + current_offset += 3 * sizeof(D3DVALUE); + } else { + strided->position.lpvData = lpvVertices; + current_offset += 4 * sizeof(D3DVALUE); + } + if (d3dvtVertexType & D3DFVF_RESERVED1) { + current_offset += sizeof(DWORD); + } + if (d3dvtVertexType & D3DFVF_NORMAL) { + strided->normal.lpvData = ((char *) lpvVertices) + current_offset; + current_offset += 3 * sizeof(D3DVALUE); + } + if (d3dvtVertexType & D3DFVF_DIFFUSE) { + strided->diffuse.lpvData = ((char *) lpvVertices) + current_offset; + current_offset += sizeof(DWORD); + } + if (d3dvtVertexType & D3DFVF_SPECULAR) { + strided->specular.lpvData = ((char *) lpvVertices) + current_offset; + current_offset += sizeof(DWORD); + } + for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { + strided->textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset; + current_offset += 2 * sizeof(D3DVALUE); + } + strided->position.dwStride = current_offset; + strided->normal.dwStride = current_offset; + strided->diffuse.dwStride = current_offset; + strided->specular.dwStride = current_offset; + for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) + strided->textureCoords[tex_index].dwStride = current_offset; +} + +void +dump_D3DVOP(DWORD dwVertexOp) +{ + static const flag_info flags[] = + { + FE(D3DVOP_LIGHT), + FE(D3DVOP_CLIP), + FE(D3DVOP_EXTENTS), + FE(D3DVOP_TRANSFORM) + }; + DDRAW_dump_flags(dwVertexOp, flags, sizeof(flags)/sizeof(flags[0])); +} + +void +dump_D3DPV(DWORD dwFlags) +{ + if (dwFlags == D3DPV_DONOTCOPYDATA) DPRINTF("D3DPV_DONOTCOPYDATA\n"); + else if (dwFlags != 0) DPRINTF("Unknown !!!\n"); + else DPRINTF("\n"); +} diff --git a/dlls/ddraw/d3ddevice/main.c b/dlls/ddraw/d3ddevice/main.c index 40e7ee18f8..3a8b1285e1 100644 --- a/dlls/ddraw/d3ddevice/main.c +++ b/dlls/ddraw/d3ddevice/main.c @@ -724,7 +724,7 @@ Main_IDirect3DDeviceImpl_7_GetInfo(LPDIRECT3DDEVICE7 iface, DWORD dwSize) { ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p/%p)->(%08lx,%p,%08lx): stub!\n", This, iface, dwDevInfoID, pDevInfoStruct, dwSize); + TRACE("(%p/%p)->(%08lx,%p,%08lx)\n", This, iface, dwDevInfoID, pDevInfoStruct, dwSize); if (TRACE_ON(ddraw)) { TRACE(" info requested : "); diff --git a/dlls/ddraw/d3ddevice/mesa.c b/dlls/ddraw/d3ddevice/mesa.c index bc5176d5ea..f638fb27a5 100644 --- a/dlls/ddraw/d3ddevice/mesa.c +++ b/dlls/ddraw/d3ddevice/mesa.c @@ -52,22 +52,22 @@ typedef void (* PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, const GLvoid *table); #endif -static const float id_mat[16] = { +const float id_mat[16] = { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 }; -static void draw_primitive_strided_7(IDirect3DDeviceImpl *This, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwStartVertex, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) ; +static void draw_primitive_strided(IDirect3DDeviceImpl *This, + D3DPRIMITIVETYPE d3dptPrimitiveType, + DWORD d3dvtVertexType, + LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, + DWORD dwStartVertex, + DWORD dwVertexCount, + LPWORD dwIndices, + DWORD dwIndexCount, + DWORD dwFlags) ; /* retrieve the X display to use on a given DC */ inline static Display *get_display( HDC hdc ) @@ -271,22 +271,25 @@ static void fill_device_capabilities(IDirectDrawImpl* ddraw) HRESULT d3ddevice_enumerate(LPD3DENUMDEVICESCALLBACK cb, LPVOID context) { - D3DDEVICEDESC d1, d2; + D3DDEVICEDESC dref, d1, d2; HRESULT ret_value; - fill_opengl_caps(&d1); - d2 = d1; + fill_opengl_caps(&dref); TRACE(" enumerating OpenGL D3DDevice interface using reference IID (IID %s).\n", debugstr_guid(&IID_IDirect3DRefDevice)); + d1 = dref; + d2 = dref; ret_value = cb((LPIID) &IID_IDirect3DRefDevice, "WINE Reference Direct3DX using OpenGL", "direct3d", &d1, &d2, context); if (ret_value != D3DENUMRET_OK) return ret_value; TRACE(" enumerating OpenGL D3DDevice interface (IID %s).\n", debugstr_guid(&IID_D3DDEVICE_OpenGL)); + d1 = dref; + d2 = dref; ret_value = cb((LPIID) &IID_D3DDEVICE_OpenGL, "WINE Direct3DX using OpenGL", "direct3d", &d1, &d2, context); if (ret_value != D3DENUMRET_OK) return ret_value; - + return D3DENUMRET_OK; } @@ -410,6 +413,16 @@ static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1, if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; + TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (ARGB) (16)\n"); + pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; + pformat->u1.dwRGBBitCount = 16; + pformat->u2.dwRBitMask = 0x00007C00; + pformat->u3.dwGBitMask = 0x000003E0; + pformat->u4.dwBBitMask = 0x0000001F; + pformat->u5.dwRGBAlphaBitMask = 0x00008000; + if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; + if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; + TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (16)\n"); pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; pformat->u1.dwRGBBitCount = 16; @@ -420,16 +433,6 @@ static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1, if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_1_5_5_5 (16)\n"); - pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - pformat->u1.dwRGBBitCount = 16; - pformat->u2.dwRBitMask = 0x00007C00; - pformat->u3.dwGBitMask = 0x000003E0; - pformat->u4.dwBBitMask = 0x0000001F; - pformat->u5.dwRGBAlphaBitMask = 0x00008000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - TRACE("Enumerating GL_RGBA packed GL_UNSIGNED_SHORT_4_4_4_4 (ARGB) (16)\n"); pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; pformat->u1.dwRGBBitCount = 16; @@ -450,16 +453,6 @@ static HRESULT enum_texture_format_OpenGL(LPD3DENUMTEXTUREFORMATSCALLBACK cb_1, if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - TRACE("Enumerating GL_ARGB (no direct OpenGL equivalent - conversion needed)\n"); - pformat->dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS; - pformat->u1.dwRGBBitCount = 16; - pformat->u2.dwRBitMask = 0x00007C00; - pformat->u3.dwGBitMask = 0x000003E0; - pformat->u4.dwBBitMask = 0x0000001F; - pformat->u5.dwRGBAlphaBitMask = 0x00008000; - if (cb_1) if (cb_1(&sdesc , context) == 0) return DD_OK; - if (cb_2) if (cb_2(pformat, context) == 0) return DD_OK; - TRACE("Enumerating Paletted (8)\n"); pformat->dwFlags = DDPF_PALETTEINDEXED8; pformat->u1.dwRGBBitCount = 8; @@ -705,7 +698,7 @@ inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD strided.normal.dwStride = sizeof(D3DVERTEX); strided.textureCoords[0].lpvData = &((D3DVERTEX *) lpvertex)->u7.tu; strided.textureCoords[0].dwStride = sizeof(D3DVERTEX); - draw_primitive_strided_7(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */); + draw_primitive_strided(This, d3dpt, D3DFVF_VERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */); } break; case D3DVT_LVERTEX: { @@ -717,7 +710,7 @@ inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD strided.specular.dwStride = sizeof(D3DLVERTEX); strided.textureCoords[0].lpvData = &((D3DLVERTEX *) lpvertex)->u6.tu; strided.textureCoords[0].dwStride = sizeof(D3DLVERTEX); - draw_primitive_strided_7(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */); + draw_primitive_strided(This, d3dpt, D3DFVF_LVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */); } break; case D3DVT_TLVERTEX: { @@ -729,7 +722,7 @@ inline static void draw_primitive(IDirect3DDeviceImpl *This, DWORD maxvert, WORD strided.specular.dwStride = sizeof(D3DTLVERTEX); strided.textureCoords[0].lpvData = &((D3DTLVERTEX *) lpvertex)->u7.tu; strided.textureCoords[0].dwStride = sizeof(D3DTLVERTEX); - draw_primitive_strided_7(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */); + draw_primitive_strided(This, d3dpt, D3DFVF_TLVERTEX, &strided, 0, 0 /* Unused */, index, maxvert, 0 /* Unused */); } break; default: @@ -912,15 +905,15 @@ inline static void handle_textures(D3DVALUE *coords, int tex_index) { if (tex_index == 0) glTexCoord2fv(coords); } -static void draw_primitive_strided_7(IDirect3DDeviceImpl *This, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, - DWORD dwStartVertex, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) +static void draw_primitive_strided(IDirect3DDeviceImpl *This, + D3DPRIMITIVETYPE d3dptPrimitiveType, + DWORD d3dvtVertexType, + LPD3DDRAWPRIMITIVESTRIDEDDATA lpD3DDrawPrimStrideData, + DWORD dwStartVertex, + DWORD dwVertexCount, + LPWORD dwIndices, + DWORD dwIndexCount, + DWORD dwFlags) { IDirect3DDeviceGLImpl* glThis = (IDirect3DDeviceGLImpl*) This; if (TRACE_ON(ddraw)) { @@ -1098,53 +1091,6 @@ static void draw_primitive_strided_7(IDirect3DDeviceImpl *This, TRACE("End\n"); } -static void draw_primitive_7(IDirect3DDeviceImpl *This, - D3DPRIMITIVETYPE d3dptPrimitiveType, - DWORD d3dvtVertexType, - LPVOID lpvVertices, - DWORD dwStartVertex, - DWORD dwVertexCount, - LPWORD dwIndices, - DWORD dwIndexCount, - DWORD dwFlags) -{ - D3DDRAWPRIMITIVESTRIDEDDATA strided; - int current_offset = 0; - int tex_index; - - if ((d3dvtVertexType & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { - strided.position.lpvData = lpvVertices; - current_offset += 3 * sizeof(D3DVALUE); - } else { - strided.position.lpvData = lpvVertices; - current_offset += 4 * sizeof(D3DVALUE); - } - if (d3dvtVertexType & D3DFVF_NORMAL) { - strided.normal.lpvData = ((char *) lpvVertices) + current_offset; - current_offset += 3 * sizeof(D3DVALUE); - } - if (d3dvtVertexType & D3DFVF_DIFFUSE) { - strided.diffuse.lpvData = ((char *) lpvVertices) + current_offset; - current_offset += sizeof(DWORD); - } - if (d3dvtVertexType & D3DFVF_SPECULAR) { - strided.specular.lpvData = ((char *) lpvVertices) + current_offset; - current_offset += sizeof(DWORD); - } - for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { - strided.textureCoords[tex_index].lpvData = ((char *) lpvVertices) + current_offset; - current_offset += 2 * sizeof(D3DVALUE); - } - strided.position.dwStride = current_offset; - strided.normal.dwStride = current_offset; - strided.diffuse.dwStride = current_offset; - strided.specular.dwStride = current_offset; - for (tex_index = 0; tex_index < ((d3dvtVertexType & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) - strided.textureCoords[tex_index].dwStride = current_offset; - - draw_primitive_strided_7(This, d3dptPrimitiveType, d3dvtVertexType, &strided, dwStartVertex, dwVertexCount, dwIndices, dwIndexCount, dwFlags); -} - HRESULT WINAPI GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface, D3DPRIMITIVETYPE d3dptPrimitiveType, @@ -1154,13 +1100,15 @@ GL_IDirect3DDeviceImpl_7_3T_DrawPrimitive(LPDIRECT3DDEVICE7 iface, DWORD dwFlags) { ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + D3DDRAWPRIMITIVESTRIDEDDATA strided; TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwFlags); if (TRACE_ON(ddraw)) { TRACE(" - flags : "); dump_DPFLAGS(dwFlags); } - draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, NULL, dwVertexCount, dwFlags); + convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided); + draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, NULL, dwVertexCount, dwFlags); return DD_OK; } @@ -1176,13 +1124,15 @@ GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitive(LPDIRECT3DDEVICE7 iface, DWORD dwFlags) { ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); + D3DDRAWPRIMITIVESTRIDEDDATA strided; TRACE("(%p/%p)->(%08x,%08lx,%p,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, dwVertexCount, dwIndices, dwIndexCount, dwFlags); if (TRACE_ON(ddraw)) { TRACE(" - flags : "); dump_DPFLAGS(dwFlags); } - draw_primitive_7(This, d3dptPrimitiveType, d3dvtVertexType, lpvVertices, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags); + convert_FVF_to_strided_data(d3dvtVertexType, lpvVertices, &strided); + draw_primitive_strided(This, d3dptPrimitiveType, d3dvtVertexType, &strided, 0, dwVertexCount, dwIndices, dwIndexCount, dwFlags); return DD_OK; } @@ -1201,7 +1151,7 @@ GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveStrided(LPDIRECT3DDEVICE7 iface, if (TRACE_ON(ddraw)) { TRACE(" - flags : "); dump_DPFLAGS(dwFlags); } - draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags); + draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, NULL, dwVertexCount, dwFlags); return DD_OK; } @@ -1223,7 +1173,7 @@ GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveStrided(LPDIRECT3DDEVICE7 iface, TRACE(" - flags : "); dump_DPFLAGS(dwFlags); } - draw_primitive_strided_7(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags); + draw_primitive_strided(This, d3dptPrimitiveType, dwVertexType, lpD3DDrawPrimStrideData, 0, dwVertexCount, lpIndex, dwIndexCount, dwFlags); return DD_OK; } @@ -1238,13 +1188,28 @@ GL_IDirect3DDeviceImpl_7_3T_DrawPrimitiveVB(LPDIRECT3DDEVICE7 iface, { ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf); + D3DDRAWPRIMITIVESTRIDEDDATA strided; TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, dwFlags); if (TRACE_ON(ddraw)) { TRACE(" - flags : "); dump_DPFLAGS(dwFlags); } - draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags); + if (vb_impl->processed == TRUE) { + IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl; + IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; + + glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER; + This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED, + &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat)); + + convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided); + draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags); + + } else { + convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided); + draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, NULL, dwNumVertices, dwFlags); + } return DD_OK; } @@ -1261,13 +1226,28 @@ GL_IDirect3DDeviceImpl_7_3T_DrawIndexedPrimitiveVB(LPDIRECT3DDEVICE7 iface, { ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); IDirect3DVertexBufferImpl *vb_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpD3DVertexBuf); + D3DDRAWPRIMITIVESTRIDEDDATA strided; TRACE("(%p/%p)->(%08x,%p,%08lx,%08lx,%p,%08lx,%08lx)\n", This, iface, d3dptPrimitiveType, lpD3DVertexBuf, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags); if (TRACE_ON(ddraw)) { TRACE(" - flags : "); dump_DPFLAGS(dwFlags); } - draw_primitive_7(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, vb_impl->vertices, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags); + if (vb_impl->processed == TRUE) { + IDirect3DVertexBufferGLImpl *vb_glimp = (IDirect3DVertexBufferGLImpl *) vb_impl; + IDirect3DDeviceGLImpl *glThis = (IDirect3DDeviceGLImpl *) This; + + glThis->transform_state = GL_TRANSFORM_VERTEXBUFFER; + This->set_matrices(This, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED, + &(vb_glimp->world_mat), &(vb_glimp->view_mat), &(vb_glimp->proj_mat)); + + convert_FVF_to_strided_data(vb_glimp->dwVertexTypeDesc, vb_glimp->vertices, &strided); + draw_primitive_strided(This, d3dptPrimitiveType, vb_glimp->dwVertexTypeDesc, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags); + + } else { + convert_FVF_to_strided_data(vb_impl->desc.dwFVF, vb_impl->vertices, &strided); + draw_primitive_strided(This, d3dptPrimitiveType, vb_impl->desc.dwFVF, &strided, dwStartVertex, dwNumVertices, lpwIndices, dwIndexCount, dwFlags); + } return DD_OK; } diff --git a/dlls/ddraw/d3dexecutebuffer.c b/dlls/ddraw/d3dexecutebuffer.c index b33a1c6e7a..f552c16711 100644 --- a/dlls/ddraw/d3dexecutebuffer.c +++ b/dlls/ddraw/d3dexecutebuffer.c @@ -238,43 +238,34 @@ static void execute(IDirect3DExecuteBufferImpl *This, /* This time, there is lighting */ glEnable(GL_LIGHTING); - /* Use given matrixes */ - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); /* The model transformation was done during the - transformation phase */ - glMatrixMode(GL_PROJECTION); - TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat); - dump_D3DMATRIX(lpDevice->proj_mat); - TRACE(" View Matrix : (%p)\n", lpDevice->view_mat); - dump_D3DMATRIX(lpDevice->view_mat); + if (TRACE_ON(ddraw)) { + TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat); + dump_D3DMATRIX(lpDevice->proj_mat); + TRACE(" View Matrix : (%p)\n", lpDevice->view_mat); + dump_D3DMATRIX(lpDevice->view_mat); + } - /* Although z axis is inverted between OpenGL and Direct3D, the z projected coordinates - are always 0.0 at the front viewing volume and 1.0 at the back with Direct 3D and with - the default behaviour of OpenGL. So, no additional transformation is required. */ - glLoadMatrixf((float *) lpDevice->proj_mat); - glMultMatrixf((float *) lpDevice->view_mat); + /* Using the identity matrix as the world matrix as the world transformation was + already done. */ + lpDevice->set_matrices(lpDevice, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED, + (D3DMATRIX *) id_mat, lpDevice->view_mat, lpDevice->proj_mat); break; case D3DVT_LVERTEX: /* No lighting */ glDisable(GL_LIGHTING); - /* Use given matrixes */ - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); /* The model transformation was done during the - transformation phase */ - glMatrixMode(GL_PROJECTION); - - TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat); - dump_D3DMATRIX(lpDevice->proj_mat); - TRACE(" View Matrix : (%p)\n", lpDevice->view_mat); - dump_D3DMATRIX(lpDevice->view_mat); - - /* Although z axis is inverted between OpenGL and Direct3D, the z projected coordinates - are always 0 at the front viewing volume and 1 at the back with Direct 3D and with - the default behaviour of OpenGL. So, no additional transformation is required. */ - glLoadMatrixf((float *) lpDevice->proj_mat); - glMultMatrixf((float *) lpDevice->view_mat); + if (TRACE_ON(ddraw)) { + TRACE(" Projection Matrix : (%p)\n", lpDevice->proj_mat); + dump_D3DMATRIX(lpDevice->proj_mat); + TRACE(" View Matrix : (%p)\n", lpDevice->view_mat); + dump_D3DMATRIX(lpDevice->view_mat); + } + + /* Using the identity matrix as the world matrix as the world transformation was + already done. */ + lpDevice->set_matrices(lpDevice, VIEWMAT_CHANGED|WORLDMAT_CHANGED|PROJMAT_CHANGED, + (D3DMATRIX *) id_mat, lpDevice->view_mat, lpDevice->proj_mat); break; case D3DVT_TLVERTEX: { diff --git a/dlls/ddraw/d3dtexture.c b/dlls/ddraw/d3dtexture.c index 5283747c4e..ed803bbef6 100644 --- a/dlls/ddraw/d3dtexture.c +++ b/dlls/ddraw/d3dtexture.c @@ -237,22 +237,40 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) { RGB Textures ************ */ if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 8) { + if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xE0) && + (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x1C) && + (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x03)) { /* ********************** GL_UNSIGNED_BYTE_3_3_2 ********************** */ - format = GL_RGB; - pixel_format = GL_UNSIGNED_BYTE_3_3_2; + format = GL_RGB; + pixel_format = GL_UNSIGNED_BYTE_3_3_2; + } else { + error = TRUE; + } } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 16) { - if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000) { + if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF800) && + (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x07E0) && + (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) && + (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000)) { format = GL_RGB; pixel_format = GL_UNSIGNED_SHORT_5_6_5; - } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000001) { + } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF800) && + (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x07C0) && + (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x003E) && + (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0001)) { format = GL_RGBA; pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; - } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000000F) { + } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xF000) && + (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0F00) && + (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x00F0) && + (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000F)) { format = GL_RGBA; pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; - } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x0000F000) { + } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x0F00) && + (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x00F0) && + (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000F) && + (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0xF000)) { /* Move the four Alpha bits... */ DWORD i; WORD *src = (WORD *) src_d->lpSurface, *dst; @@ -268,7 +286,10 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) { format = GL_RGBA; pixel_format = GL_UNSIGNED_SHORT_4_4_4_4; - } else if (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00008000) { + } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x7C00) && + (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x03E0) && + (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x001F) && + (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x8000)) { /* Converting the 1555 format in 5551 packed */ DWORD i; WORD *src = (WORD *) src_d->lpSurface, *dst; @@ -284,21 +305,47 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) { format = GL_RGBA; pixel_format = GL_UNSIGNED_SHORT_5_5_5_1; } else { - ERR("Unhandled texture format (bad Aplha channel for a 16 bit texture)\n"); error = TRUE; } } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 24) { - format = GL_RGB; - pixel_format = GL_UNSIGNED_BYTE; + if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) && + (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) && + (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) && + (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) { + format = GL_BGR; + pixel_format = GL_UNSIGNED_BYTE; + } else { + error = TRUE; + } } else if (src_d->ddpfPixelFormat.u1.dwRGBBitCount == 32) { - format = GL_RGBA; - pixel_format = GL_UNSIGNED_BYTE; + if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0xFF000000) && + (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x00FF0000) && + (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x0000FF00) && + (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x000000FF)) { + format = GL_RGBA; + pixel_format = GL_UNSIGNED_INT_8_8_8_8; + } else if ((src_d->ddpfPixelFormat.u2.dwRBitMask == 0x00FF0000) && + (src_d->ddpfPixelFormat.u3.dwGBitMask == 0x0000FF00) && + (src_d->ddpfPixelFormat.u4.dwBBitMask == 0x000000FF) && + (src_d->ddpfPixelFormat.u5.dwRGBAlphaBitMask == 0x00000000)) { + /* Just add an alpha component... */ + DWORD i; + DWORD *src = (DWORD *) src_d->lpSurface, *dst; + + surface = (DWORD *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, src_d->dwWidth * src_d->dwHeight * sizeof(DWORD)); + dst = (DWORD *) surface; + for (i = 0; i < src_d->dwHeight * src_d->dwWidth; i++) { + *dst++ = (*src++ << 8) | 0xFF; + } + format = GL_RGBA; + pixel_format = GL_UNSIGNED_INT_8_8_8_8; + } else { + error = TRUE; + } } else { - ERR("Unhandled texture format (bad RGB count)\n"); error = TRUE; } } else { - ERR("Unhandled texture format (neither RGB nor INDEX)\n"); error = TRUE; } @@ -321,6 +368,11 @@ gltex_upload_texture(IDirectDrawSurfaceImpl *This, BOOLEAN init_upload) { pixel_format, surface == NULL ? src_d->lpSurface : surface); if (surface) HeapFree(GetProcessHeap(), 0, surface); + } else if (error == TRUE) { + if (ERR_ON(ddraw)) { + ERR("Unsupported pixel format for textures : \n"); + DDRAW_dump_pixelformat(&src_d->ddpfPixelFormat); + } } glBindTexture(GL_TEXTURE_2D, current_texture); diff --git a/dlls/ddraw/d3dvertexbuffer.c b/dlls/ddraw/d3dvertexbuffer.c index 7047c6316f..354df4b7b4 100644 --- a/dlls/ddraw/d3dvertexbuffer.c +++ b/dlls/ddraw/d3dvertexbuffer.c @@ -99,6 +99,10 @@ Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface, DDRAW_dump_lockflag(dwFlags); } + if (This->processed == TRUE) { + WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n"); + } + if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED; if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size; @@ -263,6 +267,197 @@ Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER ifa lpD3DVertexBufferDesc); } +#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size) + +static HRESULT +process_vertices_strided(IDirect3DVertexBufferImpl *This, + DWORD dwVertexOp, + DWORD dwDestIndex, + DWORD dwCount, + LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData, + DWORD dwVertexTypeDesc, + IDirect3DDeviceImpl *device_impl, + DWORD dwFlags) +{ + IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This; + DWORD size = get_flexible_vertex_size(dwVertexTypeDesc); + char *dest_ptr; + int i; + + This->processed = TRUE; + + /* For the moment, the trick is to save the transform and lighting state at process + time to restore them at drawing time. + + The BIG problem with this method is nothing prevents D3D to do dirty tricks like + processing two different sets of vertices with two different rendering parameters + and then to display them using the same DrawPrimitive call. + + It would be nice to check for such code here (but well, even this is not trivial + to do). + + This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff + in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when + implementing this mostly useless (IMHO) API. + */ + glThis->dwVertexTypeDesc = dwVertexTypeDesc; + + if (dwVertexTypeDesc & D3DFVF_NORMAL) { + WARN(" lighting state not saved yet... Some strange stuff may happen !\n"); + } + + if (glThis->vertices == NULL) { + glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices); + } + dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size; + + memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX)); + memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX)); + memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX)); + + for (i = 0; i < dwCount; i++) { + int tex_index; + + if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { + D3DVALUE *position = + (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride); + copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE)); + } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) { + D3DVALUE *position = + (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride); + copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE)); + } + if (dwVertexTypeDesc & D3DFVF_RESERVED1) { + dest_ptr += sizeof(DWORD); + } + if (dwVertexTypeDesc & D3DFVF_NORMAL) { + D3DVALUE *normal = + (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride); + copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE)); + } + if (dwVertexTypeDesc & D3DFVF_DIFFUSE) { + DWORD *color_d = + (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride); + copy_and_next(dest_ptr, color_d, sizeof(DWORD)); + } + if (dwVertexTypeDesc & D3DFVF_SPECULAR) { + DWORD *color_s = + (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride); + copy_and_next(dest_ptr, color_s, sizeof(DWORD)); + } + for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { + D3DVALUE *tex_coord = + (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + + i * lpStrideData->textureCoords[tex_index].dwStride); + copy_and_next(dest_ptr, tex_coord, 2 * sizeof(D3DVALUE)); + } + + if (TRACE_ON(ddraw)) { + if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) { + D3DVALUE *position = + (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride); + TRACE(" %f %f %f", position[0], position[1], position[2]); + } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) { + D3DVALUE *position = + (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride); + TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]); + } + if (dwVertexTypeDesc & D3DFVF_NORMAL) { + D3DVALUE *normal = + (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride); + DPRINTF(" / %f %f %f", normal[0], normal[1], normal[2]); + } + if (dwVertexTypeDesc & D3DFVF_DIFFUSE) { + DWORD *color_d = + (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride); + DPRINTF(" / %02lx %02lx %02lx %02lx", + (*color_d >> 16) & 0xFF, + (*color_d >> 8) & 0xFF, + (*color_d >> 0) & 0xFF, + (*color_d >> 24) & 0xFF); + } + if (dwVertexTypeDesc & D3DFVF_SPECULAR) { + DWORD *color_s = + (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride); + DPRINTF(" / %02lx %02lx %02lx %02lx", + (*color_s >> 16) & 0xFF, + (*color_s >> 8) & 0xFF, + (*color_s >> 0) & 0xFF, + (*color_s >> 24) & 0xFF); + } + for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) { + D3DVALUE *tex_coord = + (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + + i * lpStrideData->textureCoords[tex_index].dwStride); + DPRINTF(" / %f %f", tex_coord[0], tex_coord[1]); + } + DPRINTF("\n"); + } + } + + return DD_OK; +} + +#undef copy_and_next + +HRESULT WINAPI +GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface, + DWORD dwVertexOp, + DWORD dwDestIndex, + DWORD dwCount, + LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer, + DWORD dwSrcIndex, + LPDIRECT3DDEVICE7 lpD3DDevice, + DWORD dwFlags) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); + IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer); + IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice); + D3DDRAWPRIMITIVESTRIDEDDATA strided; + DWORD size; + + TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags); + + if (TRACE_ON(ddraw)) { + DPRINTF(" - vertex operations : "); dump_D3DVOP(dwVertexOp); + DPRINTF(" - flags : "); dump_D3DPV(dwFlags); + } + + if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS; + + size = get_flexible_vertex_size(src_impl->desc.dwFVF); + convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided); + + return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags); +} + +HRESULT WINAPI +GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface, + DWORD dwVertexOp, + DWORD dwDestIndex, + DWORD dwCount, + LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData, + DWORD dwVertexTypeDesc, + LPDIRECT3DDEVICE7 lpD3DDevice, + DWORD dwFlags) +{ + ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface); + IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice); + + TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags); + if (TRACE_ON(ddraw)) { + DPRINTF(" - vertex operations : "); dump_D3DVOP(dwVertexOp); + DPRINTF(" - flags : "); dump_D3DPV(dwFlags); + DPRINTF(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc); + } + + if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS; + + return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags); +} + + + #if !defined(__STRICT_ANSI__) && defined(__GNUC__) # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun)) #else @@ -277,10 +472,10 @@ ICOM_VTABLE(IDirect3DVertexBuffer7) VTABLE_IDirect3DVertexBuffer7 = XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release, XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock, XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock, - XCAST(ProcessVertices) Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices, + XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices, XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc, XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize, - XCAST(ProcessVerticesStrided) Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided + XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided }; #if !defined(__STRICT_ANSI__) && defined(__GNUC__) @@ -321,13 +516,13 @@ HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirect3DImpl *d FE(D3DVBCAPS_WRITEONLY) }; - object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferImpl)); + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl)); if (object == NULL) return DDERR_OUTOFMEMORY; object->ref = 1; object->d3d = d3d; object->desc = *lpD3DVertBufDesc; - object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF, NULL) * lpD3DVertBufDesc->dwNumVertices; + object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices; object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size); ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer); diff --git a/dlls/ddraw/mesa_private.h b/dlls/ddraw/mesa_private.h index 4ec142c0d1..c5bb249a51 100644 --- a/dlls/ddraw/mesa_private.h +++ b/dlls/ddraw/mesa_private.h @@ -137,6 +137,15 @@ typedef struct IDirect3DDeviceGLImpl Drawable drawable; } IDirect3DDeviceGLImpl; +/* This is for the OpenGL additions... */ +typedef struct { + struct IDirect3DVertexBufferImpl parent; + + DWORD dwVertexTypeDesc; + D3DMATRIX world_mat, view_mat, proj_mat; + LPVOID vertices; +} IDirect3DVertexBufferGLImpl; + /* All non-static functions 'exported' by various sub-objects */ extern HRESULT direct3d_create(IDirect3DImpl **obj, IDirectDrawImpl *ddraw); extern HRESULT d3dtexture_create(IDirect3DImpl *d3d, IDirectDrawSurfaceImpl *surf, BOOLEAN at_creation, IDirectDrawSurfaceImpl *main_surf);