Added support for vertex declarations to wined3d, it's the last patch

to give wined3d basic functionality.
This commit is contained in:
Oliver Stieber 2005-07-07 20:45:39 +00:00 committed by Alexandre Julliard
parent 8a6799d47d
commit 3b0b430824
5 changed files with 445 additions and 569 deletions

View file

@ -22,7 +22,7 @@
#include "config.h"
#include "d3d9_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
/* IDirect3DVertexDeclaration9 IUnknown parts follow: */
HRESULT WINAPI IDirect3DVertexDeclaration9Impl_QueryInterface(LPDIRECT3DVERTEXDECLARATION9 iface, REFIID riid, LPVOID* ppobj) {
@ -30,7 +30,7 @@ HRESULT WINAPI IDirect3DVertexDeclaration9Impl_QueryInterface(LPDIRECT3DVERTEXDE
if (IsEqualGUID(riid, &IID_IUnknown)
|| IsEqualGUID(riid, &IID_IDirect3DVertexDeclaration9)) {
IDirect3DVertexDeclaration9Impl_AddRef(iface);
IUnknown_AddRef(iface);
*ppobj = This;
return D3D_OK;
}
@ -65,23 +65,36 @@ ULONG WINAPI IDirect3DVertexDeclaration9Impl_Release(LPDIRECT3DVERTEXDECLARATION
HRESULT WINAPI IDirect3DVertexDeclaration9Impl_GetDevice(LPDIRECT3DVERTEXDECLARATION9 iface, IDirect3DDevice9** ppDevice) {
IDirect3DVertexDeclaration9Impl *This = (IDirect3DVertexDeclaration9Impl *)iface;
IWineD3DDevice *myDevice = NULL;
IWineD3DVertexDeclaration_GetDevice(This->wineD3DVertexDeclaration, &myDevice);
IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
IWineD3DDevice_Release(myDevice);
return D3D_OK;
HRESULT hr = D3D_OK;
TRACE("(%p) : Relay\n", iface);
hr = IWineD3DVertexDeclaration_GetDevice(This->wineD3DVertexDeclaration, &myDevice);
if (hr == D3D_OK && myDevice != NULL) {
hr = IWineD3DDevice_GetParent(myDevice, (IUnknown **)ppDevice);
IWineD3DDevice_Release(myDevice);
}
return hr;
}
HRESULT WINAPI IDirect3DVertexDeclaration9Impl_GetDeclaration(LPDIRECT3DVERTEXDECLARATION9 iface, D3DVERTEXELEMENT9* pDecl, UINT* pNumElements) {
IDirect3DVertexDeclaration9Impl *This = (IDirect3DVertexDeclaration9Impl *)iface;
return IWineD3DVertexDeclaration_GetDeclaration(This->wineD3DVertexDeclaration, 9, pDecl, (DWORD*) pNumElements);
}
DWORD NumElements;
HRESULT hr;
TRACE("(%p) : Relay\n", iface);
hr = IWineD3DVertexDeclaration_GetDeclaration(This->wineD3DVertexDeclaration, pDecl, &NumElements);
*pNumElements = NumElements;
return hr;
}
const IDirect3DVertexDeclaration9Vtbl Direct3DVertexDeclaration9_Vtbl =
{
/* IUnknown */
IDirect3DVertexDeclaration9Impl_QueryInterface,
IDirect3DVertexDeclaration9Impl_AddRef,
IDirect3DVertexDeclaration9Impl_Release,
/* IDirect3DVertexDeclaration9 */
IDirect3DVertexDeclaration9Impl_GetDevice,
IDirect3DVertexDeclaration9Impl_GetDeclaration
};
@ -93,7 +106,8 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
IDirect3DVertexDeclaration9Impl *object = NULL;
HRESULT hr = D3D_OK;
TRACE("(%p) : Relay\n", iface);
if (NULL == ppDecl) {
return D3DERR_INVALIDCALL;
}
@ -123,30 +137,34 @@ HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(LPDIRECT3DDEVICE9
HRESULT WINAPI IDirect3DDevice9Impl_SetVertexDeclaration(LPDIRECT3DDEVICE9 iface, IDirect3DVertexDeclaration9* pDecl) {
IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
IDirect3DVertexDeclaration9Impl *pDeclImpl = (IDirect3DVertexDeclaration9Impl *)pDecl;
HRESULT hr = S_OK;
/* TODO: implement stateblocks */
FIXME("Disabled\n");
return D3DERR_INVALIDCALL;
if (NULL != pDecl) {
hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, pDeclImpl->wineD3DVertexDeclaration);
}
HRESULT hr = D3D_OK;
TRACE("(%p) : Relay\n", iface);
hr = IWineD3DDevice_SetVertexDeclaration(This->WineD3DDevice, pDeclImpl == NULL ? NULL : pDeclImpl->wineD3DVertexDeclaration);
return hr;
}
HRESULT WINAPI IDirect3DDevice9Impl_GetVertexDeclaration(LPDIRECT3DDEVICE9 iface, IDirect3DVertexDeclaration9** ppDecl) {
IDirect3DDevice9Impl* This = (IDirect3DDevice9Impl*) iface;
IWineD3DVertexDeclaration* pTest = NULL;
HRESULT hr = S_OK;
FIXME("Disabled\n");
return D3DERR_INVALIDCALL;
HRESULT hr = D3D_OK;
TRACE("(%p) : Relay+\n", iface);
if (NULL == ppDecl) {
return D3DERR_INVALIDCALL;
}
*ppDecl = NULL;
hr = IWineD3DDevice_GetVertexDeclaration(This->WineD3DDevice, &pTest);
if (SUCCEEDED(hr)) {
*ppDecl = NULL;
if (hr == D3D_OK && NULL != pTest) {
IWineD3DResource_GetParent(pTest, (IUnknown **)ppDecl);
IWineD3DResource_Release(pTest);
} else {
*ppDecl = NULL;
}
TRACE("(%p) : returning %p\n", This, *ppDecl);
return hr;
}

View file

@ -1342,62 +1342,19 @@ HRESULT WINAPI IWineD3DDeviceImpl_Reset(IWineD3DDevice* iface, WINED3DPRESENT_PA
/*****
* Vertex Declaration
*****/
/* TODO: Get ridd of thease and put the functions in the IWineD3DVertexDeclaration interface */
#if 1
extern HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration8(IWineD3DDeviceImpl * This, const DWORD* pDecl, IWineD3DVertexDeclarationImpl * object);
extern HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration9(IWineD3DDeviceImpl * This, const D3DVERTEXELEMENT9* pDecl, IWineD3DVertexDeclarationImpl * object);
HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration(IWineD3DDevice* iface, CONST VOID* pDeclaration, IWineD3DVertexDeclaration** ppVertexDeclaration, IUnknown *parent) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVertexDeclarationImpl *object = NULL;
HRESULT hr = D3D_OK;
TRACE("(%p) : directXVersion=%u, pFunction=%p, ppDecl=%p\n", This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, pDeclaration, ppVertexDeclaration);
TRACE("(%p) : directXVersion=%u, pFunction=%p, ppDecl=%p\n", This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, pDeclaration, ppVertexDeclaration);
D3DCREATEOBJECTINSTANCE(object, VertexDeclaration)
object->allFVF = 0;
if (8 == ((IWineD3DImpl *)This->wineD3D)->dxVersion) {
/** @TODO */
hr = IWineD3DVertexDeclarationImpl_ParseDeclaration8(This, (const DWORD*) pDeclaration, object);
} else {
hr = IWineD3DVertexDeclarationImpl_ParseDeclaration9(This, (const D3DVERTEXELEMENT9*) pDeclaration, object);
}
hr = IWineD3DVertexDeclaration_SetDeclaration((IWineD3DVertexDeclaration *)object, (void *)pDeclaration);
return hr;
}
#else
HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration8(IWineD3DDevice* iface, const DWORD* pDeclaration, IWineD3DVertexDeclaration** ppVertexDeclaration, IUnknown *parent){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVertexDeclarationImpl *object = NULL; /* NOTE: impl allowed, this is a create */
HRESULT hr = D3D_OK;
/* TODO: replace impl usage with a call to Version*/
TRACE("(%p) : directXVersion=%u, pFunction=%p, ppDecl=%p\n", This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, pDeclaration, ppVertexDeclaration);
D3DCREATEOBJECTINSTANCE(object, VertexDeclaration)
object->allFVF = 0;
/* TODO: get ridd of the impl usage, we should only be using interfaces */
hr = IWineD3DVertexDeclarationImpl_ParseDeclaration8(This, pDeclaration, object);
return hr;
}
HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexDeclaration9(IWineD3DDevice* iface, const D3DVERTEXELEMENT9* pDeclaration, IWineD3DVertexDeclaration** ppVertexDeclaration, IUnknown *parent){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVertexDeclarationImpl *object = NULL; /* NOTE: impl allowed, this is a create */
HRESULT hr = D3D_OK;
/* TODO: replace impl usage with a call to Version*/
TRACE("(%p) : directXVersion=%u, pFunction=%p, ppDecl=%p\n", This, ((IWineD3DImpl *)This->wineD3D)->dxVersion, pDeclaration, ppVertexDeclaration);
D3DCREATEOBJECTINSTANCE(object, VertexDeclaration)
object->allFVF = 0;
/* TODO: get ridd of the impl usage, we should only be using interfaces */
hr = IWineD3DVertexDeclarationImpl_ParseDeclaration9(This, pDeclaration, object);
return hr;
}
#endif
/* http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/directx9_c/directx/graphics/programmingguide/programmable/vertexshaders/vscreate.asp */
HRESULT WINAPI IWineD3DDeviceImpl_CreateVertexShader(IWineD3DDevice* iface, CONST DWORD* pFunction, IWineD3DVertexShader** ppVertexShader, IUnknown *parent){
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
@ -1443,10 +1400,16 @@ HRESULT WINAPI IWineD3DDeviceImpl_SetFVF(IWineD3DDevice *iface, DWORD fvf) {
This->updateStateBlock->set.fvf = TRUE;
TRACE("(%p) : FVF Shader FVF set to %lx\n", This, fvf);
/* clear down the vertex declaration
NOTE: Axis and Allies doesn't work properly otherwise
(may be a stateblock problem though!)
*/
/* No difference if recording or not */
return D3D_OK;
return IWineD3DDevice_SetVertexDeclaration(iface, NULL);
}
HRESULT WINAPI IWineD3DDeviceImpl_GetFVF(IWineD3DDevice *iface, DWORD *pfvf) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
TRACE("(%p) : GetFVF returning %lx\n", This, This->stateBlock->fvf);
@ -3554,10 +3517,11 @@ HRESULT WINAPI IWineD3DDeviceImpl_GetScissorRect(IWineD3DDevice *iface, RECT* pR
}
HRESULT WINAPI IWineD3DDeviceImpl_SetVertexDeclaration(IWineD3DDevice* iface, IWineD3DVertexDeclaration* pDecl) {
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *) iface;
TRACE("(%p) : pDecl=%p\n", This, pDecl);
/* TODO: what about recording stateblocks? */
IWineD3DVertexDeclaration_AddRef(pDecl);
if (NULL != This->updateStateBlock->vertexDecl) {
IWineD3DVertexDeclaration_Release(This->updateStateBlock->vertexDecl);

View file

@ -23,7 +23,7 @@
#include "config.h"
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DEFAULT_DEBUG_CHANNEL(d3d_draw);
WINE_DECLARE_DEBUG_CHANNEL(d3d_shader);
#define GLINFO_LOCATION ((IWineD3DImpl *)(This->wineD3D))->gl_info
@ -346,6 +346,192 @@ BOOL primitiveInitState(IWineD3DDevice *iface, BOOL vtx_transformed, BOOL vtx_li
return isLightingOn;
}
void primitiveDeclarationConvertToStridedData(IWineD3DDevice *iface, Direct3DVertexStridedData *strided, LONG BaseVertexIndex, DWORD *fvf) {
/* We need to deal with frequency data!*/
int textureNo =0;
BYTE *data = NULL;
IWineD3DDeviceImpl *This = (IWineD3DDeviceImpl *)iface;
IWineD3DVertexDeclarationImpl* vertexDeclaration = (IWineD3DVertexDeclarationImpl*)This->stateBlock->vertexDecl;
int i;
D3DVERTEXELEMENT9 *element;
DWORD stride;
for(i = 0 ; i < vertexDeclaration->declaration9NumElements -1; i++){
element = vertexDeclaration->pDeclaration9 + i;
TRACE("%p Elements %p %d or %d\n", vertexDeclaration->pDeclaration9, element, i, vertexDeclaration->declaration9NumElements);
if (This->stateBlock->streamIsUP) {
TRACE("Stream is up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
data = (BYTE *)This->stateBlock->streamSource[element->Stream];
} else {
TRACE("Stream isn't up %d, %p\n", element->Stream, This->stateBlock->streamSource[element->Stream]);
data = ((IWineD3DVertexBufferImpl *)This->stateBlock->streamSource[element->Stream])->resource.allocatedMemory;
}
stride = This->stateBlock->streamSource[element->Stream];
data += (BaseVertexIndex * stride);
data += element->Offset;
/* Why can't I just use a lookup table instead of a switch statment? */
switch(element->Usage){
case D3DDECLUSAGE_POSITION:
switch(element->UsageIndex){
case 0: /* N-patch */
strided->u.s.position.lpData = data;
strided->u.s.position.dwType = element->Type;
strided->u.s.position.dwStride = stride;
break;
case 1: /* tweened see http://www.gamedev.net/reference/articles/article2017.asp */
FIXME("Tweened positions\n");
break;
}
break;
case D3DDECLUSAGE_NORMAL:
switch(element->UsageIndex){
case 0: /* N-patch */
strided->u.s.normal.lpData = data;
strided->u.s.normal.dwType = element->Type;
strided->u.s.normal.dwStride = stride;
break;
case 1: /* skinning */
FIXME("Skinning normals\n");
break;
}
*fvf |= D3DFVF_NORMAL;
break;
case D3DDECLUSAGE_BLENDINDICES:
/* demo @http://www.ati.com/developer/vertexblend.html
and http://www.flipcode.com/articles/article_dx8shaders.shtml
*/
strided->u.s.blendMatrixIndices.lpData = data;
strided->u.s.blendMatrixIndices.dwType = element->Type;
strided->u.s.blendMatrixIndices.dwStride= stride;
break;
case D3DDECLUSAGE_BLENDWEIGHT:
strided->u.s.blendWeights.lpData = data;
strided->u.s.blendWeights.dwType = element->Type;
strided->u.s.blendWeights.dwStride = stride;
break;
case D3DDECLUSAGE_PSIZE:
strided->u.s.pSize.lpData = data;
strided->u.s.pSize.dwType = element->Type;
strided->u.s.pSize.dwStride = stride;
break;
case D3DDECLUSAGE_COLOR:
switch(element->UsageIndex){
case 0:/* diffuse */
strided->u.s.diffuse.lpData = data;
strided->u.s.diffuse.dwType = element->Type;
strided->u.s.diffuse.dwStride = stride;
break;
case 1: /* specular */
strided->u.s.specular.lpData = data;
strided->u.s.specular.dwType = element->Type;
strided->u.s.specular.dwStride = stride;
}
break;
case D3DDECLUSAGE_TEXCOORD:
/* For some odd reason Microsoft desided to sum usage accross all the streams,
which means we need to do a count and not just use the usage number */
strided->u.s.texCoords[textureNo].lpData = data;
strided->u.s.texCoords[textureNo].dwType = element->Type;
strided->u.s.texCoords[textureNo].dwStride = stride;
textureNo++;
break;
case D3DDECLUSAGE_TANGENT:
/* Implement tangents and binormals using http://oss.sgi.com/projects/ogl-sample/registry/EXT/coordinate_frame.txt
this is easy so long as the OpenGL implementation supports it, otherwise drop back to calculating the
normal using tangents where no normal data has been provided */
#if 0
strided->u.s.tangent.lpData = data;
strided->u.s.tangent.dwType = element->type;
strided->u.s.tangent.dsString = stride;
#endif
TRACE("Tangents\n");
break;
case D3DDECLUSAGE_BINORMAL:
/* Binormals are really bitangents perpendicular to the normal but s-aligned to the tangent, basicly they are the vectors of any two lines on the plain at right angles to the normal and at right angles to each other, like the x,y,z axis.
tangent data makes it easier to perform some calcualtions (a bit like using 2d graph paper instead of the normal of the piece of paper)
The only thing they are usefull for in fixed function would be working out normals when none are give.
*/
#if 0
strided->u.s.binormal.lpData = data;
strided->u.s.binormal.dwType = element->type;
strided->u.s.binormal.dsString = stride;
#endif
/* Don't bother showing fixme's tangents aren't that interesting */
TRACE("BI-Normal\n");
break;
case D3DDECLUSAGE_TESSFACTOR:
/* a google for D3DDECLUSAGE_TESSFACTOR turns up a wopping 36 entries, 7 of which are from MSDN.
*/
#if 0
strided->u.s.tessFacrot.lpData = data;
strided->u.s.tessFactor.dwType = element->type;
strided->u.s.tessFactor.dsString = stride;
#else
FIXME("Tess Factor\n");
#endif
break;
case D3DDECLUSAGE_POSITIONT:
switch(element->UsageIndex){
case 0: /* N-patch */
strided->u.s.position.lpData = data;
strided->u.s.position.dwType = element->Type;
strided->u.s.position.dwStride = stride;
break;
case 1: /* skinning */
/* see http://rsn.gamedev.net/tutorials/ms3danim.asp
http://xface.blogspot.com/2004_08_01_xface_archive.html
*/
FIXME("Skinning positionsT\n");
break;
}
/* TODO: change fvf usage to a plain boolean flag */
*fvf |= D3DFVF_XYZRHW;
/* FIXME: were faking this flag so that we don't transform the data again */
break;
case D3DDECLUSAGE_FOG:
/* maybe GL_EXT_fog_coord ?
* http://oss.sgi.com/projects/ogl-sample/registry/EXT/fog_coord.txt
* This extension allows specifying an explicit per-vertex fog
* coordinate to be used in fog computations, rather than using a
* fragment depth-based fog equation.
*
* */
#if 0
strided->u.s.fog.lpData = data;
strided->u.s.fog.dwType = element->type;
strided->u.s.fog.dsString = stride;
#else
FIXME("Fog\n");
#endif
break;
case D3DDECLUSAGE_DEPTH:
FIXME("depth\n");
#if 0
strided->u.s.depth.lpData = data;
strided->u.s.depth.dwType = element->type;
strided->u.s.depth.dsString = stride;
#endif
break;
case D3DDECLUSAGE_SAMPLE: /* VertexShader textures */
#if 0
strided->u.s.sample.lpData = data;
strided->u.s.sample.dwType = element->type;
strided->u.s.sample.dsString = stride;
#endif
FIXME("depth\n");
break;
};
};
}
void primitiveConvertToStridedData(IWineD3DDevice *iface, Direct3DVertexStridedData *strided, LONG BaseVertexIndex) {
short LoopThroughTo = 0;
@ -1405,6 +1591,29 @@ void drawStridedHardwareVS(IWineD3DDevice *iface, Direct3DVertexStridedData *sd,
}
#endif
void inline drawPrimitiveTraceDataLocations(Direct3DVertexStridedData *dataLocations,DWORD fvf){
/* Dump out what parts we have supplied */
TRACE("Strided Data (from FVF/VS): %lx\n", fvf);
TRACE_STRIDED((dataLocations), position);
TRACE_STRIDED((dataLocations), blendWeights);
TRACE_STRIDED((dataLocations), blendMatrixIndices);
TRACE_STRIDED((dataLocations), normal);
TRACE_STRIDED((dataLocations), pSize);
TRACE_STRIDED((dataLocations), diffuse);
TRACE_STRIDED((dataLocations), specular);
TRACE_STRIDED((dataLocations), texCoords[0]);
TRACE_STRIDED((dataLocations), texCoords[1]);
TRACE_STRIDED((dataLocations), texCoords[2]);
TRACE_STRIDED((dataLocations), texCoords[3]);
TRACE_STRIDED((dataLocations), texCoords[4]);
TRACE_STRIDED((dataLocations), texCoords[5]);
TRACE_STRIDED((dataLocations), texCoords[6]);
TRACE_STRIDED((dataLocations), texCoords[7]);
return;
}
/* Routine common to the draw primitive and draw indexed primitive routines */
void drawPrimitive(IWineD3DDevice *iface,
int PrimitiveType, long NumPrimitives,
@ -1429,10 +1638,14 @@ void drawPrimitive(IWineD3DDevice *iface,
Direct3DVertexStridedData dataLocations;
int useHW = FALSE;
/* Work out what the FVF should look like */
rc = initializeFVF(iface, &fvf, &useVertexShaderFunction);
if (rc) return;
if (This->stateBlock->vertexDecl == NULL) {
/* Work out what the FVF should look like */
rc = initializeFVF(iface, &fvf, &useVertexShaderFunction);
if (rc) return;
} else {
TRACE("(%p) : using vertex declaration %p \n", iface, This->stateBlock->vertexDecl);
}
/* If we will be using a vertex shader, do some initialization for it */
if (useVertexShaderFunction) {
#if 0 /* TODO: vertex and pixel shaders */
@ -1479,6 +1692,25 @@ void drawPrimitive(IWineD3DDevice *iface,
}
#endif /* TODO: vertex and pixel shaders */
/* Initialize all values to null */
if (useVertexShaderFunction == FALSE) {
memset(&dataLocations, 0x00, sizeof(dataLocations));
/* Convert to strided data */
if(This->stateBlock->vertexDecl != NULL){
TRACE("================ Vertex Declaration ===================\n");
primitiveDeclarationConvertToStridedData(iface, &dataLocations, StartVertexIndex, &fvf);
}else{
TRACE("================ FVF ===================\n");
primitiveConvertToStridedData(iface, &dataLocations, StartVertexIndex);
}
/* write out some debug information*/
drawPrimitiveTraceDataLocations(&dataLocations, fvf);
} else {
FIXME("line %d, drawing using vertex shaders\n", __LINE__);
}
/* Setup transform matrices and sort out */
if (useHW) {
/* Lighting is not completely bypassed with ATI drivers although it should be. Mesa is ok from this respect...
@ -1487,36 +1719,11 @@ void drawPrimitive(IWineD3DDevice *iface,
glDisable(GL_LIGHTING);
checkGLcall("glDisable(GL_LIGHTING);");
TRACE("Disabled lighting as no normals supplied, old state = %d\n", isLightingOn);
} else
} else {
isLightingOn = primitiveInitState(iface,
fvf & D3DFVF_XYZRHW,
!(fvf & D3DFVF_NORMAL),
useVertexShaderFunction);
/* Initialize all values to null */
if (useVertexShaderFunction == FALSE) {
memset(&dataLocations, 0x00, sizeof(dataLocations));
/* Convert to strided data */
primitiveConvertToStridedData(iface, &dataLocations, StartVertexIndex);
/* Dump out what parts we have supplied */
TRACE("Strided Data (from FVF/VS): %lx\n", fvf);
TRACE_STRIDED((&dataLocations), position);
TRACE_STRIDED((&dataLocations), blendWeights);
TRACE_STRIDED((&dataLocations), blendMatrixIndices);
TRACE_STRIDED((&dataLocations), normal);
TRACE_STRIDED((&dataLocations), pSize);
TRACE_STRIDED((&dataLocations), diffuse);
TRACE_STRIDED((&dataLocations), specular);
TRACE_STRIDED((&dataLocations), texCoords[0]);
TRACE_STRIDED((&dataLocations), texCoords[1]);
TRACE_STRIDED((&dataLocations), texCoords[2]);
TRACE_STRIDED((&dataLocations), texCoords[3]);
TRACE_STRIDED((&dataLocations), texCoords[4]);
TRACE_STRIDED((&dataLocations), texCoords[5]);
TRACE_STRIDED((&dataLocations), texCoords[6]);
TRACE_STRIDED((&dataLocations), texCoords[7]);
}
/* Now initialize the materials state */
@ -1525,13 +1732,12 @@ void drawPrimitive(IWineD3DDevice *iface,
/* And re-upload any dirty textures */
for (i=0; i<GL_LIMITS(textures); i++) {
if ((This->stateBlock->textures[i] != NULL) &&
(IWineD3DBaseTexture_GetDirty(This->stateBlock->textures[i])))
{
/* Load up the texture now */
IWineD3DTexture_PreLoad((IWineD3DTexture *) This->stateBlock->textures[i]);
/* TODO: Is this right, as its cast all texture types to texture8... checkme */
IWineD3DBaseTexture_PreLoad((IWineD3DBaseTexture *) This->stateBlock->textures[i]);
}
}

View file

@ -4,6 +4,7 @@
* Copyright 2002-2005 Raphael Junqueira
* Copyright 2004 Jason Edmeades
* Copyright 2004 Christian Costa
* Copyright 2005 Oliver Stieber
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -122,7 +123,8 @@ typedef enum _D3DVSDE_REGISTER {
D3DVSDE_TEXCOORD6 = 13,
D3DVSDE_TEXCOORD7 = 14,
D3DVSDE_POSITION2 = 15,
D3DVSDE_NORMAL2 = 16
D3DVSDE_NORMAL2 = 16,
MAX_D3DVSDE = 17
} D3DVSDE_REGISTER;
typedef enum _D3DVSDT_TYPE {
@ -168,7 +170,7 @@ typedef enum _D3DVSDT_TYPE {
#define D3DVSD_END() 0xFFFFFFFF
#define D3DVSD_NOP() 0x00000000
DWORD IWineD3DVertexDeclarationImpl_ParseToken8(const DWORD* pToken) {
static DWORD IWineD3DVertexDeclarationImpl_ParseToken8(const DWORD* pToken) {
const DWORD token = *pToken;
DWORD tokenlen = 1;
@ -251,492 +253,124 @@ DWORD IWineD3DVertexDeclarationImpl_ParseToken8(const DWORD* pToken) {
return tokenlen;
}
DWORD IWineD3DVertexDeclarationImpl_ParseToken9(const D3DVERTEXELEMENT9* pToken);
/* structure used by the d3d8 to d3d9 conversion lookup table */
typedef struct _Decl8to9Lookup {
int usage;
int usageIndex;
} Decl8to9Lookup;
HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration8(IWineD3DDeviceImpl* This, const DWORD* pDecl, IWineD3DVertexDeclarationImpl* object) {
const DWORD* pToken = pDecl;
DWORD fvf = 0;
BOOL invalid_fvf = FALSE;
DWORD tex = D3DFVF_TEX0;
DWORD len = 0;
DWORD stream = 0;
DWORD token;
DWORD tokenlen;
DWORD tokentype;
DWORD nTokens = 0;
D3DVERTEXELEMENT9 convTo9[128];
static HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration8(IWineD3DVertexDeclaration *iface, const DWORD *pDecl) {
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
#define MAKE_LOOKUP(_reg,_usage,_usageindex) decl8to9Lookup[_reg].usage = _usage; \
decl8to9Lookup[_reg].usageIndex = _usageindex;
const DWORD* pToken = pDecl;
DWORD len = 0;
DWORD stream = 0;
DWORD token;
DWORD tokenlen;
DWORD tokentype;
DWORD nTokens = 0;
D3DVERTEXELEMENT9 convTo9[128];
/* TODO: find out where rhw (or positionT) is for declaration8 */
Decl8to9Lookup decl8to9Lookup[MAX_D3DVSDE];
MAKE_LOOKUP(D3DVSDE_POSITION, D3DDECLUSAGE_POSITION, 0);
MAKE_LOOKUP(D3DVSDE_POSITION2, D3DDECLUSAGE_POSITION, 1);
MAKE_LOOKUP(D3DVSDE_BLENDWEIGHT, D3DDECLUSAGE_BLENDWEIGHT, 0);
MAKE_LOOKUP(D3DVSDE_BLENDINDICES, D3DDECLUSAGE_BLENDWEIGHT, 0);
MAKE_LOOKUP(D3DVSDE_NORMAL, D3DDECLUSAGE_NORMAL, 0);
MAKE_LOOKUP(D3DVSDE_NORMAL2, D3DDECLUSAGE_NORMAL, 1);
MAKE_LOOKUP(D3DVSDE_DIFFUSE, D3DDECLUSAGE_COLOR, 0);
MAKE_LOOKUP(D3DVSDE_SPECULAR, D3DDECLUSAGE_COLOR, 1);
MAKE_LOOKUP(D3DVSDE_TEXCOORD0, D3DDECLUSAGE_BLENDWEIGHT, 0);
MAKE_LOOKUP(D3DVSDE_TEXCOORD1, D3DDECLUSAGE_BLENDWEIGHT, 1);
MAKE_LOOKUP(D3DVSDE_TEXCOORD2, D3DDECLUSAGE_BLENDWEIGHT, 2);
MAKE_LOOKUP(D3DVSDE_TEXCOORD3, D3DDECLUSAGE_BLENDWEIGHT, 3);
MAKE_LOOKUP(D3DVSDE_TEXCOORD4, D3DDECLUSAGE_BLENDWEIGHT, 4);
MAKE_LOOKUP(D3DVSDE_TEXCOORD5, D3DDECLUSAGE_BLENDWEIGHT, 5);
MAKE_LOOKUP(D3DVSDE_TEXCOORD6, D3DDECLUSAGE_BLENDWEIGHT, 6);
MAKE_LOOKUP(D3DVSDE_TEXCOORD7, D3DDECLUSAGE_BLENDWEIGHT, 7);
TRACE("(%p) : pDecl(%p)\n", This, pDecl);
#undef MAKE_LOOKUP
TRACE("(%p) : pDecl(%p)\n", This, pDecl);
/* Convert from a directx* declaration into a directx9 one, so we only have to deal with one type of declaration everywhere else */
while (D3DVSD_END() != *pToken) {
token = *pToken;
tokenlen = IWineD3DVertexDeclarationImpl_ParseToken8(pToken);
tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
while (D3DVSD_END() != *pToken) {
token = *pToken;
tokenlen = IWineD3DVertexDeclarationImpl_ParseToken8(pToken);
tokentype = ((token & D3DVSD_TOKENTYPEMASK) >> D3DVSD_TOKENTYPESHIFT);
if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) {
/**
* how really works streams,
* in DolphinVS dx8 dsk sample they seems to decal reg numbers !!!
*/
stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
/** FVF generation block */
if (D3DVSD_TOKEN_STREAM == tokentype && 0 == (D3DVSD_STREAMTESSMASK & token)) {
/**
* how really works streams,
* in DolphinVS dx8 dsk sample they seems to decal reg numbers !!!
*/
DWORD oldStream = stream;
stream = ((token & D3DVSD_STREAMNUMBERMASK) >> D3DVSD_STREAMNUMBERSHIFT);
} else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) {
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
/* copy fvf if valid */
if (FALSE == invalid_fvf) {
fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
tex = 0;
object->fvf[oldStream] = fvf;
object->allFVF |= fvf;
} else {
object->fvf[oldStream] = 0;
tex = 0;
}
/* reset valid/invalid fvf */
fvf = 0;
invalid_fvf = FALSE;
} else if (D3DVSD_TOKEN_STREAMDATA == tokentype && 0 == (0x10000000 & tokentype)) {
DWORD type = ((token & D3DVSD_DATATYPEMASK) >> D3DVSD_DATATYPESHIFT);
DWORD reg = ((token & D3DVSD_VERTEXREGMASK) >> D3DVSD_VERTEXREGSHIFT);
convTo9[nTokens].Stream = stream;
convTo9[nTokens].Method = D3DDECLMETHOD_DEFAULT;
convTo9[nTokens].UsageIndex = 0;
convTo9[nTokens].Type = D3DDECLTYPE_UNUSED;
switch (reg) {
case D3DVSDE_POSITION:
convTo9[nTokens].Usage = D3DDECLUSAGE_POSITION;
convTo9[nTokens].Type = type;
switch (type) {
case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZ; break;
case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZRHW; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
if (type >= MAX_VSHADER_DECL_TYPES) {
TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported and unrecognized type %08lx\n", type);
} else {
TRACE("Mismatched use in VertexShader declaration of D3DVSDE_POSITION register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
}
}
break;
case D3DVSDE_BLENDWEIGHT:
convTo9[nTokens].Usage = D3DDECLUSAGE_BLENDWEIGHT;
convTo9[nTokens].Type = type;
switch (type) {
case D3DVSDT_FLOAT1: fvf |= D3DFVF_XYZB1; break;
case D3DVSDT_FLOAT2: fvf |= D3DFVF_XYZB2; break;
case D3DVSDT_FLOAT3: fvf |= D3DFVF_XYZB3; break;
case D3DVSDT_FLOAT4: fvf |= D3DFVF_XYZB4; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDWEIGHT register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
}
break;
case D3DVSDE_BLENDINDICES: /* seem to be B5 as said in MSDN Dx9SDK ?? */
convTo9[nTokens].Usage = D3DDECLUSAGE_BLENDINDICES;
convTo9[nTokens].Type = type;
switch (type) {
case D3DVSDT_UBYTE4: fvf |= D3DFVF_LASTBETA_UBYTE4; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexShader declaration of D3DVSDE_BLENDINDINCES register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
}
break;
case D3DVSDE_NORMAL: /* TODO: only FLOAT3 supported ... another choice possible ? */
convTo9[nTokens].Usage = D3DDECLUSAGE_NORMAL;
convTo9[nTokens].Type = type;
switch (type) {
case D3DVSDT_FLOAT3: fvf |= D3DFVF_NORMAL; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexShader declaration of D3DVSDE_NORMAL register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
}
break;
case D3DVSDE_PSIZE: /* TODO: only FLOAT1 supported ... another choice possible ? */
convTo9[nTokens].Usage = D3DDECLUSAGE_PSIZE;
convTo9[nTokens].Type = type;
switch (type) {
case D3DVSDT_FLOAT1: fvf |= D3DFVF_PSIZE; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexShader declaration of D3DVSDE_PSIZE register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
}
break;
case D3DVSDE_DIFFUSE: /* TODO: only D3DCOLOR supported */
convTo9[nTokens].Usage = D3DDECLUSAGE_COLOR;
convTo9[nTokens].UsageIndex = 0;
convTo9[nTokens].Type = type;
switch (type) {
case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_DIFFUSE; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexShader declaration of D3DVSDE_DIFFUSE register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
}
break;
case D3DVSDE_SPECULAR: /* TODO: only D3DCOLOR supported */
convTo9[nTokens].Usage = D3DDECLUSAGE_COLOR;
convTo9[nTokens].UsageIndex = 1;
convTo9[nTokens].Type = type;
switch (type) {
case D3DVSDT_D3DCOLOR: fvf |= D3DFVF_SPECULAR; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexShader declaration of D3DVSDE_SPECULAR register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
}
break;
case D3DVSDE_TEXCOORD0:
case D3DVSDE_TEXCOORD1:
case D3DVSDE_TEXCOORD2:
case D3DVSDE_TEXCOORD3:
case D3DVSDE_TEXCOORD4:
case D3DVSDE_TEXCOORD5:
case D3DVSDE_TEXCOORD6:
case D3DVSDE_TEXCOORD7:
/* Fixme? - assume all tex coords in same stream */
{
int texNo = 1 + (reg - D3DVSDE_TEXCOORD0);
convTo9[nTokens].Usage = D3DDECLUSAGE_TEXCOORD;
convTo9[nTokens].UsageIndex = texNo;
convTo9[nTokens].Type = type;
tex = max(tex, texNo);
switch (type) {
case D3DVSDT_FLOAT1: fvf |= D3DFVF_TEXCOORDSIZE1(texNo); break;
case D3DVSDT_FLOAT2: fvf |= D3DFVF_TEXCOORDSIZE2(texNo); break;
case D3DVSDT_FLOAT3: fvf |= D3DFVF_TEXCOORDSIZE3(texNo); break;
case D3DVSDT_FLOAT4: fvf |= D3DFVF_TEXCOORDSIZE4(texNo); break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexShader declaration of D3DVSDE_TEXCOORD? register: unsupported type %s\n", VertexDecl8_DataTypes[type]);
}
}
break;
case D3DVSDE_POSITION2: /* maybe D3DFVF_XYZRHW instead D3DFVF_XYZ (of D3DVDE_POSITION) ... to see */
case D3DVSDE_NORMAL2: /* FIXME i don't know what to do here ;( */
FIXME("[%lu] registers in VertexShader declaration not supported yet (token:0x%08lx)\n", reg, token);
break;
}
TRACE("VertexShader declaration define %lx as current FVF\n", fvf);
convTo9[nTokens].Stream = stream;
convTo9[nTokens].Method = D3DDECLMETHOD_DEFAULT;
convTo9[nTokens].Usage = decl8to9Lookup[reg].usage;
convTo9[nTokens].UsageIndex = decl8to9Lookup[reg].usageIndex;
convTo9[nTokens].Type = type;
++nTokens;
}/* TODO: Constants. */
len += tokenlen;
pToken += tokenlen;
}
++nTokens;
len += tokenlen;
pToken += tokenlen;
}
/* here D3DVSD_END() */
len += IWineD3DVertexDeclarationImpl_ParseToken8(pToken);
convTo9[nTokens].Stream = 0xFF;
convTo9[nTokens].Type = D3DDECLTYPE_UNUSED;
/* copy fvf if valid */
if (FALSE == invalid_fvf) {
fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
object->fvf[stream] = fvf;
object->allFVF |= fvf;
} else {
object->fvf[stream] = 0;
}
TRACE("Completed, allFVF = %lx\n", object->allFVF);
/* compute size */
object->declaration8Length = len * sizeof(DWORD);
This->declaration8Length = len * sizeof(DWORD);
/* copy the declaration */
object->pDeclaration8 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->declaration8Length);
memcpy(object->pDeclaration8, pDecl, object->declaration8Length);
This->pDeclaration8 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->declaration8Length);
memcpy(This->pDeclaration8, pDecl, This->declaration8Length);
/* compute convTo9 size */
object->declaration9NumElements = nTokens;
This->declaration9NumElements = nTokens;
/* copy the convTo9 declaration */
object->pDeclaration9 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nTokens * sizeof(D3DVERTEXELEMENT9));
memcpy(object->pDeclaration9, convTo9, nTokens * sizeof(D3DVERTEXELEMENT9));
This->pDeclaration9 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nTokens * sizeof(D3DVERTEXELEMENT9));
memcpy(This->pDeclaration9, convTo9, nTokens * sizeof(D3DVERTEXELEMENT9));
#if 0 /* TODO: This looks like overkill so I've removed it. */
{
D3DVERTEXELEMENT9* pIt = object->pDeclaration9;
TRACE("dumping of D3D9 Conversion:\n");
D3DVERTEXELEMENT9* pIt = This->pDeclaration9;
TRACE("dumping of D3D9 Convertion:\n");
while (0xFF != pIt->Stream) {
IWineD3DVertexDeclarationImpl_ParseToken9(pIt);
++pIt;
}
}
IWineD3DVertexDeclarationImpl_ParseToken9(pIt);
}
#endif
/* returns */
return D3D_OK;
}
static CONST char* VertexDecl9_DeclUsages[] = {
"D3DDECLUSAGE_POSITION",
"D3DDECLUSAGE_BLENDWEIGHT",
"D3DDECLUSAGE_BLENDINDICES",
"D3DDECLUSAGE_NORMAL",
"D3DDECLUSAGE_PSIZE",
"D3DDECLUSAGE_TEXCOORD",
"D3DDECLUSAGE_TANGENT",
"D3DDECLUSAGE_BINORMAL",
"D3DDECLUSAGE_TESSFACTOR",
"D3DDECLUSAGE_POSITIONT",
"D3DDECLUSAGE_COLOR",
"D3DDECLUSAGE_FOG",
"D3DDECLUSAGE_DEPTH",
"D3DDECLUSAGE_SAMPLE",
NULL
};
static HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration9(IWineD3DVertexDeclaration* iface, const D3DVERTEXELEMENT9* pDecl) {
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
const D3DVERTEXELEMENT9* pToken = pDecl;
static CONST char* VertexDecl9_DeclMethods[] = {
"D3DDECLMETHOD_DEFAULT",
"D3DDECLMETHOD_PARTIALU",
"D3DDECLMETHOD_PARTIALV",
"D3DDECLMETHOD_CROSSUV",
"D3DDECLMETHOD_UV",
"D3DDECLMETHOD_LOOKUP",
"D3DDECLMETHOD_LOOKUPPRESAMPLED",
NULL
};
TRACE("(%p) : pDecl(%p)\n", This, pDecl);
static CONST char* VertexDecl9_DeclTypes[] = {
"D3DDECLTYPE_FLOAT1",
"D3DDECLTYPE_FLOAT2",
"D3DDECLTYPE_FLOAT3",
"D3DDECLTYPE_FLOAT4",
"D3DDECLTYPE_D3DCOLOR",
"D3DDECLTYPE_UBYTE4",
"D3DDECLTYPE_SHORT2",
"D3DDECLTYPE_SHORT4",
/* VS 2.0 */
"D3DDECLTYPE_UBYTE4N",
"D3DDECLTYPE_SHORT2N",
"D3DDECLTYPE_SHORT4N",
"D3DDECLTYPE_USHORT2N",
"D3DDECLTYPE_USHORT4N",
"D3DDECLTYPE_UDEC3",
"D3DDECLTYPE_DEC3N",
"D3DDECLTYPE_FLOAT16_2",
"D3DDECLTYPE_FLOAT16_4",
"D3DDECLTYPE_UNUSED",
NULL
};
This->declaration9NumElements = 1;
for(pToken = pDecl;0xFF != pToken->Stream && This->declaration9NumElements < 128 ; pToken++) This->declaration9NumElements++;
DWORD IWineD3DVertexDeclarationImpl_ParseToken9(const D3DVERTEXELEMENT9* pToken) {
DWORD tokenlen = 1;
if (0xFF != pToken->Stream) {
TRACE(" D3DDECL(%u, %u, %s, %s, %s, %u)\n",
pToken->Stream,
pToken->Offset,
VertexDecl9_DeclTypes[pToken->Type],
VertexDecl9_DeclMethods[pToken->Method],
VertexDecl9_DeclUsages[pToken->Usage],
pToken->UsageIndex
);
} else {
TRACE(" D3DDECL_END()\n" );
}
return tokenlen;
}
HRESULT IWineD3DVertexDeclarationImpl_ParseDeclaration9(IWineD3DDeviceImpl* This, const D3DVERTEXELEMENT9* pDecl, IWineD3DVertexDeclarationImpl* object) {
const D3DVERTEXELEMENT9* pToken = pDecl;
DWORD fvf = 0;
BOOL invalid_fvf = FALSE;
DWORD tex = D3DFVF_TEX0;
DWORD len = 0;
DWORD stream = 0;
TRACE("(%p) : pDecl(%p)\n", This, pDecl);
while (0xFF != pToken->Stream) {
DWORD type = pToken->Type;
DWORD oldStream = stream;
stream = pToken->Stream;
IWineD3DVertexDeclarationImpl_ParseToken9(pToken);
if (D3DDECLMETHOD_DEFAULT != pToken->Method) {
WARN(
"%s register: Unsupported Method of %s (only D3DDECLMETHOD_DEFAULT for now) for VertexDeclaration (type %s)\n",
VertexDecl9_DeclUsages[pToken->Usage],
VertexDecl9_DeclMethods[pToken->Method],
VertexDecl9_DeclTypes[pToken->Type]
);
if (This->declaration9NumElements == 128) {
FIXME("?(%p) Error parsing vertex declaration\n", This);
return D3DERR_INVALIDCALL;
}
if (oldStream != stream) {
if (FALSE == invalid_fvf) {
fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
tex = 0;
object->fvf[oldStream] = fvf;
object->allFVF |= fvf;
} else {
object->fvf[oldStream] = 0;
tex = 0;
}
/* reset valid/invalid fvf */
fvf = 0;
invalid_fvf = FALSE;
}
/* copy the declaration */
This->pDeclaration9 = HeapAlloc(GetProcessHeap(), 0, This->declaration9NumElements * sizeof(D3DVERTEXELEMENT9));
memcpy(This->pDeclaration9, pDecl, This->declaration9NumElements * sizeof(D3DVERTEXELEMENT9));
switch (pToken->Usage) {
case D3DDECLUSAGE_POSITION:
if (0 < pToken->UsageIndex) {
invalid_fvf = TRUE;
TRACE("Mismatched UsageIndex (%u) in VertexDeclaration for D3DDECLUSAGE_POSITION register: unsupported type %s\n",
pToken->UsageIndex, VertexDecl9_DeclTypes[type]);
break;
}
switch (type) {
case D3DDECLTYPE_FLOAT3: fvf |= D3DFVF_XYZ; break;
case D3DDECLTYPE_FLOAT4: fvf |= D3DFVF_XYZRHW; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_POSITION register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
}
break;
case D3DDECLUSAGE_BLENDWEIGHT:
switch (type) {
case D3DDECLTYPE_FLOAT1: fvf |= D3DFVF_XYZB1; break;
case D3DDECLTYPE_FLOAT2: fvf |= D3DFVF_XYZB2; break;
case D3DDECLTYPE_FLOAT3: fvf |= D3DFVF_XYZB3; break;
case D3DDECLTYPE_FLOAT4: fvf |= D3DFVF_XYZB4; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_BLENDWEIGHT register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
}
break;
case D3DDECLUSAGE_BLENDINDICES:
switch (type) {
case D3DDECLTYPE_UBYTE4: fvf |= D3DFVF_LASTBETA_UBYTE4; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_BLENDINDINCES register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
}
break;
case D3DDECLUSAGE_NORMAL:
if (0 < pToken->UsageIndex) {
invalid_fvf = TRUE;
TRACE("Mismatched UsageIndex (%u) in VertexDeclaration for D3DDECLUSAGE_NORMAL register: unsupported type %s\n",
pToken->UsageIndex, VertexDecl9_DeclTypes[type]);
break;
}
switch (type) {
case D3DDECLTYPE_FLOAT3: fvf |= D3DFVF_NORMAL; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_NORMAL register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
}
break;
case D3DDECLUSAGE_PSIZE:
switch (type) {
case D3DDECLTYPE_FLOAT1: fvf |= D3DFVF_PSIZE; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_PSIZE register: unsupported type %s\n", VertexDecl9_DeclTypes[type]);
}
break;
case D3DDECLUSAGE_TEXCOORD:
{
DWORD texNo = pToken->UsageIndex;
tex = max(tex, texNo);
switch (type) {
case D3DDECLTYPE_FLOAT1: fvf |= D3DFVF_TEXCOORDSIZE1(texNo); break;
case D3DDECLTYPE_FLOAT2: fvf |= D3DFVF_TEXCOORDSIZE2(texNo); break;
case D3DDECLTYPE_FLOAT3: fvf |= D3DFVF_TEXCOORDSIZE3(texNo); break;
case D3DDECLTYPE_FLOAT4: fvf |= D3DFVF_TEXCOORDSIZE4(texNo); break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_TEXCOORD[%lu] register: unsupported type %s\n", texNo, VertexDecl9_DeclTypes[type]);
}
}
break;
case D3DDECLUSAGE_COLOR:
{
DWORD colorNo = pToken->UsageIndex;
switch (type) {
case D3DDECLTYPE_D3DCOLOR:
switch (pToken->UsageIndex) {
case 0: fvf |= D3DFVF_DIFFUSE; break;
case 1: fvf |= D3DFVF_SPECULAR; break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_COLOR[%lu] unsupported COLOR register\n", colorNo);
}
break;
default:
/** Mismatched use of a register, invalid for fixed function fvf computing (ok for VS) */
invalid_fvf = TRUE;
TRACE("Mismatched use in VertexDeclaration of D3DDECLUSAGE_COLOR[%lu] register: unsupported type %s\n", colorNo, VertexDecl9_DeclTypes[type]);
}
}
break;
case D3DDECLUSAGE_TANGENT:
case D3DDECLUSAGE_BINORMAL:
case D3DDECLUSAGE_TESSFACTOR:
case D3DDECLUSAGE_POSITIONT:
case D3DDECLUSAGE_FOG:
case D3DDECLUSAGE_DEPTH:
case D3DDECLUSAGE_SAMPLE:
FIXME("%s Usage not supported yet by VertexDeclaration (type is %s)\n", VertexDecl9_DeclUsages[pToken->Usage], VertexDecl9_DeclTypes[type]);
break;
}
++len;
++pToken;
}
++len; /* D3DDECL_END() */
/* copy fvf if valid */
if (FALSE == invalid_fvf) {
fvf |= tex << D3DFVF_TEXCOUNT_SHIFT;
object->fvf[stream] = fvf;
object->allFVF |= fvf;
} else {
object->fvf[stream] = 0;
}
TRACE("Completed, allFVF = %lx\n", object->allFVF);
/* compute size */
object->declaration9NumElements = len;
/* copy the declaration */
object->pDeclaration9 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len * sizeof(D3DVERTEXELEMENT9));
memcpy(object->pDeclaration9, pDecl, len * sizeof(D3DVERTEXELEMENT9));
/* returns */
TRACE("Returns allFVF = %lx\n", object->allFVF);
return D3D_OK;
}
@ -780,6 +414,15 @@ ULONG WINAPI IWineD3DVertexDeclarationImpl_Release(IWineD3DVertexDeclaration *if
IWineD3DVertexDeclaration parts follow
******************************************* */
HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetParent(IWineD3DVertexDeclaration *iface, IUnknown** parent){
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
*parent= (IUnknown*) parent;
IUnknown_AddRef(*parent);
TRACE("(%p) : returning %p\n", This, *parent);
return D3D_OK;
}
HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDevice(IWineD3DVertexDeclaration *iface, IWineD3DDevice** ppDevice) {
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
TRACE("(%p) : returning %p\n", This, This->wineD3DDevice);
@ -809,29 +452,70 @@ HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration9(IWineD3DVertexDecla
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
if (NULL == pData) {
*pNumElements = This->declaration9NumElements;
TRACE("(%p) : Returning numElements %ld\n", iface, *pNumElements);
return D3D_OK;
}
if (*pNumElements < This->declaration9NumElements) {
*pNumElements = This->declaration9NumElements;
memcpy(pData, This->pDeclaration9, *pNumElements * sizeof(*pData));
FIXME("(%p) : Returning D3DERR_MOREDATA numElements %ld expected %u\n", iface, *pNumElements, This->declaration9NumElements);
return D3DERR_MOREDATA;
}
TRACE("(%p) : GetVertexDeclaration9 copying to %p\n", This, pData);
memcpy(pData, This->pDeclaration9, This->declaration9NumElements);
memcpy(pData, This->pDeclaration9, This->declaration9NumElements * sizeof(*pData));
return D3D_OK;
}
HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVertexDeclaration* iface, UINT iDeclVersion, VOID* pData, DWORD* pSize) {
if (8 == iDeclVersion) {
return IWineD3DVertexDeclarationImpl_GetDeclaration8(iface, (DWORD*) pData, pSize);
}
return IWineD3DVertexDeclarationImpl_GetDeclaration9(iface, (D3DVERTEXELEMENT9*) pData, pSize);
HRESULT WINAPI IWineD3DVertexDeclarationImpl_GetDeclaration(IWineD3DVertexDeclaration *iface, VOID *pData, DWORD *pSize) {
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
HRESULT hr = D3D_OK;
TRACE("(%p) : d3d version %d r\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
switch (((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion) {
case 8:
hr = IWineD3DVertexDeclarationImpl_GetDeclaration8(iface, (DWORD *)pData, pSize);
break;
case 9:
hr = IWineD3DVertexDeclarationImpl_GetDeclaration9(iface, (D3DVERTEXELEMENT9 *)pData, pSize);
break;
default:
FIXME("(%p) : Unsupport DirectX version %u\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
break;
}
return hr;
}
HRESULT WINAPI IWineD3DVertexDeclarationImpl_SetDeclaration(IWineD3DVertexDeclaration *iface, VOID *pDecl) {
IWineD3DVertexDeclarationImpl *This = (IWineD3DVertexDeclarationImpl *)iface;
HRESULT hr = D3D_OK;
TRACE("(%p) : d3d version %d\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
switch (((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion) {
case 8:
TRACE("Parsing declatation 8\n");
hr = IWineD3DVertexDeclarationImpl_ParseDeclaration8(iface, (CONST DWORD *)pDecl);
break;
case 9:
FIXME("Parsing declatation 9\n");
hr = IWineD3DVertexDeclarationImpl_ParseDeclaration9(iface, (CONST D3DVERTEXELEMENT9 *)pDecl);
break;
default:
FIXME("(%p) : Unsupport DirectX version %u\n", This, ((IWineD3DImpl *)This->wineD3DDevice->wineD3D)->dxVersion);
break;
}
TRACE("Returning\n");
return hr;
}
const IWineD3DVertexDeclarationVtbl IWineD3DVertexDeclaration_Vtbl =
{
/* IUnknown */
IWineD3DVertexDeclarationImpl_QueryInterface,
IWineD3DVertexDeclarationImpl_AddRef,
IWineD3DVertexDeclarationImpl_Release,
/* IWineD3DVertexDeclaration */
IWineD3DVertexDeclarationImpl_GetParent,
IWineD3DVertexDeclarationImpl_GetDevice,
IWineD3DVertexDeclarationImpl_GetDeclaration,
IWineD3DVertexDeclarationImpl_SetDeclaration
};

View file

@ -1083,12 +1083,14 @@ DECLARE_INTERFACE_(IWineD3DVolume,IWineD3DResource)
DECLARE_INTERFACE_(IWineD3DVertexDeclaration,IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void** ppvObject) PURE;
STDMETHOD_(HRESULT,QueryInterface)(THIS_ REFIID riid, void **ppvObject) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
/*** IWineD3DVertexDeclaration methods ***/
STDMETHOD(GetDevice)(THIS_ IWineD3DDevice ** ppDevice) PURE;
STDMETHOD(GetDeclaration)(THIS_ UINT iDeclVersion, VOID*, DWORD* pSize) PURE;
STDMETHOD(GetParent)(THIS_ IUnknown **pParent) PURE;
STDMETHOD(GetDevice)(THIS_ IWineD3DDevice **ppDevice) PURE;
STDMETHOD(GetDeclaration)(THIS_ VOID *pDecl, DWORD *pSize) PURE;
STDMETHOD(SetDeclaration)(THIS_ VOID *pDecl) PURE;
};
#undef INTERFACE
@ -1098,8 +1100,10 @@ DECLARE_INTERFACE_(IWineD3DVertexDeclaration,IUnknown)
#define IWineD3DVertexDeclaration_AddRef(p) (p)->lpVtbl->AddRef(p)
#define IWineD3DVertexDeclaration_Release(p) (p)->lpVtbl->Release(p)
/*** IWineD3DVertexDeclaration methods ***/
#define IWineD3DVertexDeclaration_GetParent(p,a) (p)->lpVtbl->GetParent(p,a)
#define IWineD3DVertexDeclaration_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a)
#define IWineD3DVertexDeclaration_GetDeclaration(p,a,b,c) (p)->lpVtbl->GetDeclaration(p,a,b,c)
#define IWineD3DVertexDeclaration_GetDeclaration(p,a,b) (p)->lpVtbl->GetDeclaration(p,a,b)
#define IWineD3DVertexDeclaration_SetDeclaration(p,b) (p)->lpVtbl->SetDeclaration(p,b)
#endif
/*****************************************************************************