From 89dccc7c7c73c8497d6370a16c4a251de797f114 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Fri, 27 Jul 2007 14:39:55 +0200 Subject: [PATCH] ddraw: Implement IDirect3DDevice7::DrawIndexedPrimitiveStrided. --- dlls/ddraw/device.c | 106 +++++++++++++++++++++++++++++++++++++-- dlls/wined3d/device.c | 23 ++++++++- include/wine/wined3d_interface.h | 2 + 3 files changed, 126 insertions(+), 5 deletions(-) diff --git a/dlls/ddraw/device.c b/dlls/ddraw/device.c index d0cfcdf33e6..56e5cf32d3e 100644 --- a/dlls/ddraw/device.c +++ b/dlls/ddraw/device.c @@ -3621,12 +3621,110 @@ IDirect3DDeviceImpl_7_DrawIndexedPrimitiveStrided(IDirect3DDevice7 *iface, DWORD Flags) { ICOM_THIS_FROM(IDirect3DDeviceImpl, IDirect3DDevice7, iface); - FIXME("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x): stub!\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); + WineDirect3DVertexStridedData WineD3DStrided; + int i; + UINT PrimitiveCount; + HRESULT hr; + + TRACE("(%p)->(%08x,%08x,%p,%08x,%p,%08x,%08x)\n", This, PrimitiveType, VertexType, D3DDrawPrimStrideData, VertexCount, Indices, IndexCount, Flags); - /* I'll implement it as soon as I find a app to test it. - * This needs an additional method in IWineD3DDevice. + memset(&WineD3DStrided, 0, sizeof(WineD3DStrided)); + /* Get the strided data right. the wined3d structure is a bit bigger + * Watch out: The contents of the strided data are determined by the fvf, + * not by the members set in D3DDrawPrimStrideData. So it's valid + * to have diffuse.lpvData set to 0xdeadbeef if the diffuse flag is + * not set in the fvf. */ - return D3D_OK; + if(VertexType & D3DFVF_POSITION_MASK) + { + WineD3DStrided.u.s.position.lpData = D3DDrawPrimStrideData->position.lpvData; + WineD3DStrided.u.s.position.dwStride = D3DDrawPrimStrideData->position.dwStride; + WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT3; + if (VertexType & D3DFVF_XYZRHW) + { + WineD3DStrided.u.s.position.dwType = WINED3DDECLTYPE_FLOAT4; + WineD3DStrided.u.s.position_transformed = TRUE; + } else + WineD3DStrided.u.s.position_transformed = FALSE; + } + + if(VertexType & D3DFVF_NORMAL) + { + WineD3DStrided.u.s.normal.lpData = D3DDrawPrimStrideData->normal.lpvData; + WineD3DStrided.u.s.normal.dwStride = D3DDrawPrimStrideData->normal.dwStride; + WineD3DStrided.u.s.normal.dwType = WINED3DDECLTYPE_FLOAT3; + } + + if(VertexType & D3DFVF_DIFFUSE) + { + WineD3DStrided.u.s.diffuse.lpData = D3DDrawPrimStrideData->diffuse.lpvData; + WineD3DStrided.u.s.diffuse.dwStride = D3DDrawPrimStrideData->diffuse.dwStride; + WineD3DStrided.u.s.diffuse.dwType = WINED3DDECLTYPE_SHORT4; + } + + if(VertexType & D3DFVF_SPECULAR) + { + WineD3DStrided.u.s.specular.lpData = D3DDrawPrimStrideData->specular.lpvData; + WineD3DStrided.u.s.specular.dwStride = D3DDrawPrimStrideData->specular.dwStride; + WineD3DStrided.u.s.specular.dwType = WINED3DDECLTYPE_SHORT4; + } + + for( i = 0; i < GET_TEXCOUNT_FROM_FVF(VertexType); i++) + { + WineD3DStrided.u.s.texCoords[i].lpData = D3DDrawPrimStrideData->textureCoords[i].lpvData; + WineD3DStrided.u.s.texCoords[i].dwStride = D3DDrawPrimStrideData->textureCoords[i].dwStride; + switch(GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)) + { + case 1: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT1; break; + case 2: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT2; break; + case 3: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT3; break; + case 4: WineD3DStrided.u.s.texCoords[i].dwType = WINED3DDECLTYPE_FLOAT4; break; + default: ERR("Unexpected texture coordinate size %d\n", + GET_TEXCOORD_SIZE_FROM_FVF(VertexType, i)); + } + } + + /* Get the primitive count */ + switch(PrimitiveType) + { + case D3DPT_POINTLIST: + PrimitiveCount = IndexCount; + break; + + case D3DPT_LINELIST: + PrimitiveCount = IndexCount / 2; + break; + + case D3DPT_LINESTRIP: + PrimitiveCount = IndexCount - 1; + break; + + case D3DPT_TRIANGLELIST: + PrimitiveCount = IndexCount / 3; + break; + + case D3DPT_TRIANGLESTRIP: + PrimitiveCount = IndexCount - 2; + break; + + case D3DPT_TRIANGLEFAN: + PrimitiveCount = IndexCount - 2; + break; + + default: return DDERR_INVALIDPARAMS; + } + + /* WineD3D doesn't need the FVF here */ + EnterCriticalSection(&ddraw_cs); + hr = IWineD3DDevice_DrawIndexedPrimitiveStrided(This->wineD3DDevice, + PrimitiveType, + PrimitiveCount, + &WineD3DStrided, + VertexCount, + Indices, + WINED3DFMT_INDEX16); + LeaveCriticalSection(&ddraw_cs); + return hr; } static HRESULT WINAPI diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c index 65c5382c461..5f894bd9bf6 100644 --- a/dlls/wined3d/device.c +++ b/dlls/wined3d/device.c @@ -4755,7 +4755,27 @@ static HRESULT WINAPI IWineD3DDeviceImpl_DrawPrimitiveStrided (IWineD3DDevice *i This->up_strided = NULL; return WINED3D_OK; } - /* Yet another way to update a texture, some apps use this to load default textures instead of using surface/texture lock/unlock */ + +static HRESULT WINAPI IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided(IWineD3DDevice *iface, WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, WineDirect3DVertexStridedData *DrawPrimStrideData, UINT NumVertices, CONST void *pIndexData, WINED3DFORMAT IndexDataFormat) { + IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface; + DWORD idxSize = (IndexDataFormat == WINED3DFMT_INDEX32 ? 4 : 2); + + /* Mark the state dirty until we have nicer tracking + * its fine to change baseVertexIndex because that call is only called by ddraw which does not need + * that value. + */ + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_VDECL); + IWineD3DDeviceImpl_MarkStateDirty(This, STATE_INDEXBUFFER); + This->stateBlock->streamIsUP = TRUE; + This->stateBlock->baseVertexIndex = 0; + This->up_strided = DrawPrimStrideData; + drawPrimitive(iface, PrimitiveType, PrimitiveCount, 0 /* startvertexidx */, 0 /* numindices */, 0 /* startidx */, idxSize, pIndexData, 0 /* minindex */); + This->up_strided = NULL; + return WINED3D_OK; +} + + +/* Yet another way to update a texture, some apps use this to load default textures instead of using surface/texture lock/unlock */ static HRESULT WINAPI IWineD3DDeviceImpl_UpdateTexture (IWineD3DDevice *iface, IWineD3DBaseTexture *pSourceTexture, IWineD3DBaseTexture *pDestinationTexture){ IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface; HRESULT hr = WINED3D_OK; @@ -6667,6 +6687,7 @@ const IWineD3DDeviceVtbl IWineD3DDevice_Vtbl = IWineD3DDeviceImpl_DrawPrimitiveUP, IWineD3DDeviceImpl_DrawIndexedPrimitiveUP, IWineD3DDeviceImpl_DrawPrimitiveStrided, + IWineD3DDeviceImpl_DrawIndexedPrimitiveStrided, IWineD3DDeviceImpl_DrawRectPatch, IWineD3DDeviceImpl_DrawTriPatch, IWineD3DDeviceImpl_DeletePatch, diff --git a/include/wine/wined3d_interface.h b/include/wine/wined3d_interface.h index 38235152901..35430b97ef6 100644 --- a/include/wine/wined3d_interface.h +++ b/include/wine/wined3d_interface.h @@ -472,6 +472,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) STDMETHOD(DrawPrimitiveUP)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE; STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices, UINT PrimitiveCount, CONST void * pIndexData, WINED3DFORMAT IndexDataFormat, CONST void * pVertexStreamZeroData, UINT VertexStreamZeroStride) PURE; STDMETHOD(DrawPrimitiveStrided)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, WineDirect3DVertexStridedData *DrawPrimStrideData) PURE; + STDMETHOD(DrawIndexedPrimitiveStrided)(THIS_ WINED3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, WineDirect3DVertexStridedData *DrawPrimStrideData, UINT NumVertices, CONST void *pIndexData, WINED3DFORMAT IndexDataFormat) PURE; STDMETHOD(DrawRectPatch)(THIS_ UINT Handle, CONST float* pNumSegs, CONST WINED3DRECTPATCH_INFO* pRectPatchInfo) PURE; STDMETHOD(DrawTriPatch)(THIS_ UINT Handle, CONST float* pNumSegs, CONST WINED3DTRIPATCH_INFO* pTriPatchInfo) PURE; STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE; @@ -611,6 +612,7 @@ DECLARE_INTERFACE_(IWineD3DDevice,IWineD3DBase) #define IWineD3DDevice_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d) #define IWineD3DDevice_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) #define IWineD3DDevice_DrawPrimitiveStrided(p,a,b,c) (p)->lpVtbl->DrawPrimitiveStrided(p,a,b,c) +#define IWineD3DDevice_DrawIndexedPrimitiveStrided(p,a,b,c,d,e,f) (p)->lpVtbl->DrawIndexedPrimitiveStrided(p,a,b,c,d,e,f) #define IWineD3DDevice_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c) #define IWineD3DDevice_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c) #define IWineD3DDevice_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a) -- 2.11.4.GIT