Stefan Dösinger : ddraw: Implement IDirect3DDevice7:: DrawIndexedPrimitiveStrided.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Aug 8 08:59:17 CDT 2007


Module: wine
Branch: master
Commit: 89dccc7c7c73c8497d6370a16c4a251de797f114
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=89dccc7c7c73c8497d6370a16c4a251de797f114

Author: Stefan Dösinger <stefan at codeweavers.com>
Date:   Fri Jul 27 14:39:55 2007 +0200

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 d0cfcdf..56e5cf3 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 65c5382..5f894bd 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 3823515..35430b9 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)




More information about the wine-cvs mailing list