//----------------------------------------------------------------------------- // Name: XBUtil_DeclaratorFromFVF() // Desc: Create a vertex declaration from an FVF. Registers are assigned as // follows: // v0 = Vertex position // v1 = Vertex blend weights // v2 = Vertex normal // v3 = Vertex diffuse color // v4 = Vertex specular color // // v5 = Vertex fog (no FVF code) // // v6 = Vertex pointsize (no FVF code) // // v7 = Vertex back diffuse color (no FVF code) // // v8 = Vertex back specular color (no FVF code) // v9-v12 = Vertex texture coords //----------------------------------------------------------------------------- HRESULT XBUtil_DeclaratorFromFVF( DWORD dwFVF, DWORD Declaration[MAX_FVF_DECL_SIZE] ) { // Start the declaration DWORD decl = 0; Declaration[decl++] = D3DVSD_STREAM(0); // Handle position DWORD dwPositionFVF = ( dwFVF & D3DFVF_POSITION_MASK ); if( dwPositionFVF == D3DFVF_XYZRHW ) Declaration[decl++] = D3DVSD_REG( 0, D3DVSDT_FLOAT4 ); else Declaration[decl++] = D3DVSD_REG( 0, D3DVSDT_FLOAT3 ); // Handle blend weights if( dwPositionFVF == D3DFVF_XYZB1 ) Declaration[decl++] = D3DVSD_REG( 1, D3DVSDT_FLOAT1 ); if( dwPositionFVF == D3DFVF_XYZB2 ) Declaration[decl++] = D3DVSD_REG( 1, D3DVSDT_FLOAT2 ); if( dwPositionFVF == D3DFVF_XYZB3 ) Declaration[decl++] = D3DVSD_REG( 1, D3DVSDT_FLOAT3 ); if( dwPositionFVF == D3DFVF_XYZB4 ) Declaration[decl++] = D3DVSD_REG( 1, D3DVSDT_FLOAT4 ); // Handle normal, diffuse, and specular if( dwFVF & D3DFVF_NORMAL ) Declaration[decl++] = D3DVSD_REG( 2, D3DVSDT_FLOAT3 ); if( dwFVF & D3DFVF_DIFFUSE ) Declaration[decl++] = D3DVSD_REG( 3, D3DVSDT_D3DCOLOR ); if( dwFVF & D3DFVF_SPECULAR ) Declaration[decl++] = D3DVSD_REG( 4, D3DVSDT_D3DCOLOR ); // Handle texture coordinates DWORD dwNumTextures = (dwFVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT; for( DWORD i=0; i<dwNumTextures; i++ ) { DWORD dwTexCoordSize = ( dwFVF & (0x00030000<<(i*2)) ); DWORD dwNumTexCoords = 0; if( dwTexCoordSize == D3DFVF_TEXCOORDSIZE1(i) ) dwNumTexCoords = D3DVSDT_FLOAT1; if( dwTexCoordSize == D3DFVF_TEXCOORDSIZE2(i) ) dwNumTexCoords = D3DVSDT_FLOAT2; if( dwTexCoordSize == D3DFVF_TEXCOORDSIZE3(i) ) dwNumTexCoords = D3DVSDT_FLOAT3; if( dwTexCoordSize == D3DFVF_TEXCOORDSIZE4(i) ) dwNumTexCoords = D3DVSDT_FLOAT4; Declaration[decl++] = D3DVSD_REG( 9 + i, dwNumTexCoords ); } // End the declarator Declaration[decl++] = D3DVSD_END(); return S_OK; }
/* Explanation of texture copying via drawShadedTexQuad and drawShadedTexSubQuad: From MSDN: "When rendering 2D output using pre-transformed vertices, care must be taken to ensure that each texel area correctly corresponds to a single pixel area, otherwise texture distortion can occur." => We need to subtract 0.5 from the vertex positions to properly map texels to pixels. HOWEVER, the MSDN article talks about D3DFVF_XYZRHW vertices, which bypass the programmable pipeline. Since we're using D3DFVF_XYZW and the programmable pipeline though, the vertex positions are normalized to [-1;+1], i.e. we need to scale the -0.5 offset by the texture dimensions. For example see a texture with a width of 640 pixels: "Expected" coordinate range when using D3DFVF_XYZRHW: [0;640] Normalizing this coordinate range for D3DFVF_XYZW: [0;640]->[-320;320]->[-1;1] i.e. we're subtracting width/2 and dividing by width/2 BUT: The actual range when using D3DFVF_XYZRHW needs to be [-0.5;639.5] because of the need for exact texel->pixel mapping. We can still apply the same normalizing procedure though: [-0.5;639.5]->[-320-0.5;320-0.5]->[-1-0.5/320;1-0.5/320] So generally speaking the correct coordinate range is [-1-0.5/(w/2);1-0.5/(w/2)] which can be simplified to [-1-1/w;1-1/w]. Note that while for D3DFVF_XYZRHW the y coordinate of the bottom of the screen is positive, it's negative for D3DFVF_XYZW. This is why we need to _add_ 1/h for the second position component instead of subtracting it. For a detailed explanation of this read the MSDN article "Directly Mapping Texels to Pixels (Direct3D 9)". */ void drawShadedTexQuad(IDirect3DTexture9 *texture, const RECT *rSource, int SourceWidth, int SourceHeight, int DestWidth, int DestHeight, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader, float Gamma) { float sw = 1.0f / (float)SourceWidth; float sh = 1.0f / (float)SourceHeight; float dw = 1.0f / (float)DestWidth; float dh = 1.0f / (float)DestHeight; float u1 = 0.0f; float u2 = 1.0f; float v1 = 0.0f; float v2 = 1.0f; if (rSource != nullptr) { u1 = ((float)rSource->left) * sw; u2 = ((float)rSource->right) * sw; v1 = ((float)rSource->top) * sh; v2 = ((float)rSource->bottom) * sh; } float g = 1.0f / Gamma; const struct Q2DVertex { float x, y, z, rhw, u, v, w, h, G; } coords[4] = { {-1.0f - dw,-1.0f + dh, 0.0f,1.0f, u1, v2, dw, dh, g}, {-1.0f - dw, 1.0f + dh, 0.0f,1.0f, u1, v1, dw, dh, g}, { 1.0f - dw,-1.0f + dh, 0.0f,1.0f, u2, v2, dw, dh, g}, { 1.0f - dw, 1.0f + dh, 0.0f,1.0f, u2, v1, dw, dh, g} }; D3D::ChangeVertexShader(Vshader); D3D::ChangePixelShader(PShader); D3D::SetTexture(0, texture); D3D::ChangeVertexDeclaration(0); dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2)); dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); RestoreShaders(); }
void drawShadedTexSubQuad(IDirect3DTexture9 *texture, const MathUtil::Rectangle<float> *rSource, int SourceWidth, int SourceHeight, const MathUtil::Rectangle<float> *rDest, int DestWidth, int DestHeight, IDirect3DPixelShader9 *PShader, IDirect3DVertexShader9 *Vshader, float Gamma) { float sw = 1.0f / (float)SourceWidth; float sh = 1.0f / (float)SourceHeight; float dw = 1.0f / (float)DestWidth; float dh = 1.0f / (float)DestHeight; float u1 = rSource->left * sw; float u2 = rSource->right * sw; float v1 = rSource->top * sh; float v2 = rSource->bottom * sh; float g = 1.0f / Gamma; struct Q2DVertex { float x, y, z, rhw, u, v, w, h, G; } coords[4] = { { rDest->left - dw , rDest->top + dh, 1.0f,1.0f, u1, v2, dw, dh, g}, { rDest->left - dw , rDest->bottom + dh, 1.0f,1.0f, u1, v1, dw, dh, g}, { rDest->right - dw , rDest->top + dh, 1.0f,1.0f, u2, v2, dw, dh, g}, { rDest->right - dw , rDest->bottom + dh, 1.0f,1.0f, u2, v1, dw, dh, g} }; D3D::ChangeVertexShader(Vshader); D3D::ChangePixelShader(PShader); D3D::SetTexture(0, texture); D3D::ChangeVertexDeclaration(0); dev->SetFVF(D3DFVF_XYZW | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE1(2)); dev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, coords, sizeof(Q2DVertex)); RestoreShaders(); }
static void D3DXGetFVFVertexSizeTest(void) { UINT got; compare_vertex_sizes (D3DFVF_XYZ, 12); compare_vertex_sizes (D3DFVF_XYZB3, 24); compare_vertex_sizes (D3DFVF_XYZB5, 32); compare_vertex_sizes (D3DFVF_XYZ | D3DFVF_NORMAL, 24); compare_vertex_sizes (D3DFVF_XYZ | D3DFVF_DIFFUSE, 16); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0), 16); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE1(1), 20); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0), 20); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1), 28); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX6 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1) | D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE2(4) | D3DFVF_TEXCOORDSIZE2(5), 60); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX8 | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1) | D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE2(3) | D3DFVF_TEXCOORDSIZE2(4) | D3DFVF_TEXCOORDSIZE2(5) | D3DFVF_TEXCOORDSIZE2(6) | D3DFVF_TEXCOORDSIZE2(7), 76); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0), 24); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX4 | D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE3(2) | D3DFVF_TEXCOORDSIZE3(3), 60); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0), 28); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX2 | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEXCOORDSIZE4(1), 44); compare_vertex_sizes ( D3DFVF_XYZ | D3DFVF_TEX3 | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEXCOORDSIZE4(1) | D3DFVF_TEXCOORDSIZE4(2), 60); compare_vertex_sizes ( D3DFVF_XYZB5 | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX8 | D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEXCOORDSIZE4(1) | D3DFVF_TEXCOORDSIZE4(2) | D3DFVF_TEXCOORDSIZE4(3) | D3DFVF_TEXCOORDSIZE4(4) | D3DFVF_TEXCOORDSIZE4(5) | D3DFVF_TEXCOORDSIZE4(6) | D3DFVF_TEXCOORDSIZE4(7), 180); }
void DX9Buffer::setNbTexCoords(size_t nb) { if (nbTexCoords != nb) { nbTexCoords = nb; SAFE_RELEASE( texCoordBuffer ); if (nbTexCoords > 0) DX9Info::getDevice()->CreateVertexBuffer(nbVertices*nbTexCoords*sizeof(float), D3DUSAGE_DYNAMIC, D3DFVF_TEX1|D3DFVF_TEXCOORDSIZE1(nbTexCoords), D3DPOOL_DEFAULT, &texCoordBuffer, NULL); currentTexCoordIndex = 0; } }
DX9Buffer::DX9Buffer(BufferInfo &info) : nbVertices(info.nbVertices), nbIndices(info.nbIndices), nbTexCoords(info.nbTexCoords), currentVertexIndex(0), currentColorIndex(0), currentTexCoordIndex(0), currentLock(NO_LOCK), vertexBuffer(NULL), colorBuffer(NULL), texCoordBuffer(NULL), indexBuffer(NULL), ptrVertexBuffer(NULL), ptrColorBuffer(NULL), ptrTexCoordBuffer(NULL), ptrIndexBuffer(NULL) { SPK_ASSERT(nbVertices > 0,"DX9Buffer::DX9Buffer(BufferInfo) - The number of vertices cannot be 0"); DX9Info::getDevice()->CreateVertexBuffer(nbVertices*sizeof(D3DXVECTOR3), D3DUSAGE_DYNAMIC, D3DFVF_XYZ, D3DPOOL_DEFAULT, &vertexBuffer, NULL); DX9Info::getDevice()->CreateVertexBuffer(nbVertices*sizeof(D3DCOLOR), D3DUSAGE_DYNAMIC, D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &colorBuffer, NULL); // TODO : gérer les indices 32bit if( nbIndices > 0 ) { DX9Info::getDevice()->CreateIndexBuffer(nbIndices*sizeof(short), 0, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &indexBuffer, 0); unsigned int offsetIndex = 0; lock(INDEX_LOCK); // initialisation de l'index buffer for(size_t i = 0; i < nbIndices/6; i++) { //#ifdef _DX9QUADRENDERER_CLOCKWISE_ *(ptrIndexBuffer++) = 0 + offsetIndex; *(ptrIndexBuffer++) = 1 + offsetIndex; *(ptrIndexBuffer++) = 2 + offsetIndex; *(ptrIndexBuffer++) = 0 + offsetIndex; *(ptrIndexBuffer++) = 2 + offsetIndex; *(ptrIndexBuffer++) = 3 + offsetIndex; // TODO handle counter clockwise //#else // *(ptrIndexBuffer++) = 0 + offsetIndex; // *(ptrIndexBuffer++) = 2 + offsetIndex; // *(ptrIndexBuffer++) = 1 + offsetIndex; // *(ptrIndexBuffer++) = 0 + offsetIndex; // *(ptrIndexBuffer++) = 3 + offsetIndex; // *(ptrIndexBuffer++) = 2 + offsetIndex; //#endif offsetIndex += 4; } unlock(); } // TODO : gérer autre chose que les textures 2D if(nbTexCoords > 0) DX9Info::getDevice()->CreateVertexBuffer(nbVertices*sizeof(D3DXVECTOR2), D3DUSAGE_DYNAMIC, D3DFVF_TEX1|D3DFVF_TEXCOORDSIZE1(nbTexCoords), D3DPOOL_DEFAULT, &texCoordBuffer, NULL); }
static void test_fvf_decl_conversion(IDirect3DDevice9 *pDevice) { HRESULT hr; unsigned int i; IDirect3DVertexDeclaration9* default_decl = NULL; DWORD default_fvf = D3DFVF_SPECULAR | D3DFVF_DIFFUSE; D3DVERTEXELEMENT9 default_elements[] = { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 }, { 0, 4, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 }, D3DDECL_END() }; /* Create a default declaration and FVF that does not match any of the tests */ hr = IDirect3DDevice9_CreateVertexDeclaration( pDevice, default_elements, &default_decl ); ok(SUCCEEDED(hr), "CreateVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK); if (FAILED(hr)) goto cleanup; /* Test conversions from vertex declaration to an FVF. * For some reason those seem to occur only for POSITION/POSITIONT, * Otherwise the FVF is forced to 0 - maybe this is configuration specific */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, D3DFVF_XYZ, TRUE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, D3DFVF_XYZRHW, TRUE)); } for (i = 0; i < 4; i++) { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT1+i, 0, D3DDECLUSAGE_BLENDWEIGHT, 0}, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0}, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } /* Make sure textures of different sizes work */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } /* Make sure the TEXCOORD index works correctly - try several textures */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1 }, { 0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2 }, { 0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } /* No FVF mapping available */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 1 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 1 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } /* Try empty declaration */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } /* Now try a combination test */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITIONT, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 }, { 0, 24, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0 }, { 0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 }, { 0, 32, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 44, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 1 }, D3DDECL_END() }; VDECL_CHECK(test_decl_to_fvf(pDevice, default_fvf, test_buffer, 0, FALSE)); } /* Test conversions from FVF to a vertex declaration * These seem to always occur internally. A new declaration object is created if necessary */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZ, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITION, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZW, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZRHW, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 28, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB5 | D3DFVF_LASTBETA_D3DCOLOR, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 28, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB5, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB1, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB1 | D3DFVF_LASTBETA_UBYTE4, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB1 | D3DFVF_LASTBETA_D3DCOLOR, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB2, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 16, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB2 | D3DFVF_LASTBETA_D3DCOLOR, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB3, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 20, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 20, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB3 | D3DFVF_LASTBETA_D3DCOLOR, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB4, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 24, D3DDECLTYPE_UBYTE4, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 24, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_BLENDINDICES, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB4 | D3DFVF_LASTBETA_D3DCOLOR, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_NORMAL, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_PSIZE, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_PSIZE, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_DIFFUSE, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_SPECULAR, test_buffer, 1)); } /* Make sure textures of different sizes work */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEX1, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEX1, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_TEXCOORDSIZE3(0) | D3DFVF_TEX1, test_buffer, 1)); } { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_TEXCOORDSIZE4(0) | D3DFVF_TEX1, test_buffer, 1)); } /* Make sure the TEXCOORD index works correctly - try several textures */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT1, 0, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 4, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1 }, { 0, 16, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 2 }, { 0, 24, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_TEXCOORD, 3 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_TEXCOORDSIZE1(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEXCOORDSIZE2(2) | D3DFVF_TEXCOORDSIZE4(3) | D3DFVF_TEX4, test_buffer, 1)); } /* Now try a combination test */ { CONST D3DVERTEXELEMENT9 test_buffer[] = { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_BLENDWEIGHT, 0 }, { 0, 28, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 0 }, { 0, 32, D3DDECLTYPE_D3DCOLOR, 0, D3DDECLUSAGE_COLOR, 1 }, { 0, 36, D3DDECLTYPE_FLOAT2, 0, D3DDECLUSAGE_TEXCOORD, 0 }, { 0, 44, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_TEXCOORD, 1 }, D3DDECL_END() }; VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, D3DFVF_XYZB4 | D3DFVF_SPECULAR | D3DFVF_DIFFUSE | D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE3(1) | D3DFVF_TEX2, test_buffer, 1)); } /* Setting the FVF to 0 should result in no change to the default decl */ VDECL_CHECK(test_fvf_to_decl(pDevice, default_decl, 0, default_elements, 0)); cleanup: IDirect3DDevice9_SetVertexDeclaration ( pDevice, NULL ); if ( default_decl ) IUnknown_Release (default_decl); }