1d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens//
3d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Licensed under the Apache License, Version 2.0 (the "License");
4d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// you may not use this file except in compliance with the License.
5d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// You may obtain a copy of the License at
6ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens//
7d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens//    http://www.apache.org/licenses/LICENSE-2.0
8ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens//
9d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Unless required by applicable law or agreed to in writing, software
10d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// distributed under the License is distributed on an "AS IS" BASIS,
11d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// See the License for the specific language governing permissions and
13d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// limitations under the License.
14ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
15ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Direct3DVertexDeclaration9.hpp"
16ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
17ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Direct3DDevice9.hpp"
18ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include "Debug.hpp"
19ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
20ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include <d3d9types.h>
21ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include <stdio.h>
22ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens#include <assert.h>
23ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
24ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capensnamespace D3D9
25ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens{
26ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	Direct3DVertexDeclaration9::Direct3DVertexDeclaration9(Direct3DDevice9 *device, const D3DVERTEXELEMENT9 *vertexElement) : device(device)
27ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
28ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		int size = sizeof(D3DVERTEXELEMENT9);
29ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		const D3DVERTEXELEMENT9 *element = vertexElement;
30ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		preTransformed = false;
31ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
32ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		while(element->Stream != 0xFF)
33ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
34ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			if(element->Usage == D3DDECLUSAGE_POSITIONT)
35ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			{
36ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				preTransformed = true;
37ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			}
38ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
39ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			size += sizeof(D3DVERTEXELEMENT9);
40ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			element++;
41ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
42ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
43ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		numElements = size / sizeof(D3DVERTEXELEMENT9);
44ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		this->vertexElement = new D3DVERTEXELEMENT9[numElements];
45ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		memcpy(this->vertexElement, vertexElement, size);
46ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
47ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		FVF = computeFVF();
48ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
49ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
50ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	Direct3DVertexDeclaration9::Direct3DVertexDeclaration9(Direct3DDevice9 *device, unsigned long FVF) : device(device)
51ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
52ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		this->FVF = FVF;
53ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
54502836a8df8985544667325ad0fb44d3ac0f40e3Nicolas Capens		vertexElement = new D3DVERTEXELEMENT9[MAX_VERTEX_INPUTS];
55ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
56ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		numElements = 0;
57ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		int offset = 0;
58ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		preTransformed = false;
59ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
60ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		switch(FVF & D3DFVF_POSITION_MASK)
61ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
62ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case 0:
63ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			// No position stream
64ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			break;
65ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFVF_XYZ:
66ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
67ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
68ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
69ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
70ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
71ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
72ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
73ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 3;
74ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			break;
75ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFVF_XYZRHW:
76ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			preTransformed = true;
77ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
78ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
79ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT4;
80ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
81ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_POSITIONT;
82ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
83ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
84ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 4;
85ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			break;
86ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFVF_XYZB1:
87ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
88ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
89ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
90ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
91ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
92ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
93ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
94ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 3;
95ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
96ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
97ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
98ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT1;
99ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
100ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
101ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
102ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
103ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 1;
104ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			break;
105ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFVF_XYZB2:
106ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
107ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
108ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
109ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
110ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
111ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
112ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
113ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 3;
114ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
115ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
116ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
117ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT2;
118ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
119ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
120ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
121ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
122ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 2;
123ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			break;
124ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFVF_XYZB3:
125ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
126ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
127ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
128ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
129ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
130ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
131ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
132ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 3;
133ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
134ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
135ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
136ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
137ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
138ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
139ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
140ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
141ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 3;
142ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			break;
143ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFVF_XYZB4:
144ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
145ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
146ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
147ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
148ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
149ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
150ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
151ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 3;
152ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
153ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
154ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
155ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT4;
156ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
157ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
158ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
159ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
160ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 4;
161ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			break;
162ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFVF_XYZB5:
163ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
164ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
165ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
166ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
167ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
168ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
169ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
170ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 3;
171ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
172ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
173ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
174ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT4;
175ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
176ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
177ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
178ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
179ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 5;
180ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			break;
181ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		case D3DFVF_XYZW:
182ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
183ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
184ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT4;
185ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
186ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_POSITION;
187ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
188ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
189ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 4;
190ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			break;
191ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		default:
192ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			ASSERT(false);
193ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
194ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
195ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(FVF & D3DFVF_NORMAL)
196ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
197ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
198ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
199ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT3;
200ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
201ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_NORMAL;
202ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
203ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
204ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4 * 3;
205ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
206ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
207ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(FVF & D3DFVF_PSIZE)
208ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
209ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
210ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
211ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_FLOAT1;
212ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
213ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_PSIZE;
214ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
215ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
216ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4;
217ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
218ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
219ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(FVF & D3DFVF_DIFFUSE)
220ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
221d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens			vertexElement[numElements].Stream = 0;
222ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
223ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_D3DCOLOR;
224ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
225ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_COLOR;
226ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 0;
227ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
228ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4;
229ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
230ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
231ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(FVF & D3DFVF_SPECULAR)
232ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
233ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
234ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
235ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = D3DDECLTYPE_D3DCOLOR;
236ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
237ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_COLOR;
238ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = 1;
239ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
240ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += 4;
241ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
242ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
243ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		int numTexCoord = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
244ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		int textureFormats = (FVF >> 16) & 0xFFFF;
245d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
246ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		static const int textureSize[4] =
247ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
248ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			2 * 4,   // D3DFVF_TEXTUREFORMAT2
249ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			3 * 4,   // D3DFVF_TEXTUREFORMAT3
250ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			4 * 4,   // D3DFVF_TEXTUREFORMAT4
251ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			1 * 4    // D3DFVF_TEXTUREFORMAT1
252ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		};
253d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
254ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		static const D3DDECLTYPE textureType[4] =
255ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
256ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			D3DDECLTYPE_FLOAT2,   // D3DFVF_TEXTUREFORMAT2
257ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			D3DDECLTYPE_FLOAT3,   // D3DFVF_TEXTUREFORMAT3
258ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			D3DDECLTYPE_FLOAT4,   // D3DFVF_TEXTUREFORMAT4
259ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			D3DDECLTYPE_FLOAT1    // D3DFVF_TEXTUREFORMAT1
260ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		};
261ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
262ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		for(int i = 0; i < numTexCoord; i++)
263ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
264ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Stream = 0;
265ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Offset = offset;
266ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Type = textureType[textureFormats & 0x3];
267ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Method = D3DDECLMETHOD_DEFAULT;
268ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].Usage = D3DDECLUSAGE_TEXCOORD;
269ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			vertexElement[numElements].UsageIndex = i;
270ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numElements++;
271ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			offset += textureSize[textureFormats & 0x3];
272ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			textureFormats >>= 2;
273ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
274ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
275ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		// D3DDECL_END()
276ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		vertexElement[numElements].Stream = 0xFF;
277ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		vertexElement[numElements].Offset = 0;
278ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		vertexElement[numElements].Type = D3DDECLTYPE_UNUSED;
279ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		vertexElement[numElements].Method = 0;
280ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		vertexElement[numElements].Usage = 0;
281ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		vertexElement[numElements].UsageIndex = 0;
282ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		numElements++;
283ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
284ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
285ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	Direct3DVertexDeclaration9::~Direct3DVertexDeclaration9()
286ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
287ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		delete[] vertexElement;
288ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		vertexElement = 0;
289ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
290ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
291ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DVertexDeclaration9::QueryInterface(const IID &iid, void **object)
292ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
293ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
294ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
295ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
296ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
297ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(iid == IID_IDirect3DVertexDeclaration9 ||
298ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		   iid == IID_IUnknown)
299ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
300ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			AddRef();
301ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			*object = this;
302ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
303ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return S_OK;
304ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
305ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
306ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		*object = 0;
307ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
308ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return NOINTERFACE(iid);
309ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
310ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
311ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	unsigned long Direct3DVertexDeclaration9::AddRef()
312ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
313ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
314ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
315ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Unknown::AddRef();
316ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
317d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
318ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	unsigned long Direct3DVertexDeclaration9::Release()
319ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
320ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
321ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
322ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return Unknown::Release();
323ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
324ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
325ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DVertexDeclaration9::GetDevice(IDirect3DDevice9 **device)
326ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
327ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(this->device);
328ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
329ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
330ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
331ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(!device)
332ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
333ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return INVALIDCALL();
334ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
335ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
336ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		this->device->AddRef();
337ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		*device = this->device;
338ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
339ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return D3D_OK;
340ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
341ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
342ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	long Direct3DVertexDeclaration9::GetDeclaration(D3DVERTEXELEMENT9 *declaration, unsigned int *numElements)
343ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
344ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		CriticalSection cs(device);
345ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
346ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		TRACE("");
347ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
348ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(!declaration || !numElements)
349ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
350ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return INVALIDCALL();
351ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
352ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
353ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		*numElements = this->numElements;
354ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
355ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		for(int i = 0; i < this->numElements; i++)
356ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
357ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			declaration[i] = vertexElement[i];
358ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
359ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
360ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return D3D_OK;
361ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
362ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
363ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	unsigned long Direct3DVertexDeclaration9::getFVF() const
364ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
365ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return FVF;
366ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
367ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
368ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	bool Direct3DVertexDeclaration9::isPreTransformed() const
369ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
370ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return preTransformed;
371ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
372ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
373ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	unsigned long Direct3DVertexDeclaration9::computeFVF()
374ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	{
375ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		unsigned long FVF = 0;
376ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
377ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		int textureBits = 0;
378ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		int numBlendWeights = 0;
379d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
380ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		for(int i = 0; i < numElements - 1; i++)
381ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
382ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			D3DVERTEXELEMENT9 &element = vertexElement[i];
383ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
384ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			if(element.Stream != 0)
385ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			{
386ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				return 0;
387ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			}
388ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
389ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			switch(element.Usage)
390ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			{
391ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case D3DDECLUSAGE_POSITION:
392ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				if(element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0)
393ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
394ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					FVF |= D3DFVF_XYZ;
395ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
396ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				else
397ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
398ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					return 0;
399ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
400ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				break;
401ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case D3DDECLUSAGE_POSITIONT:
402ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				if(element.Type == D3DDECLTYPE_FLOAT4 && element.UsageIndex == 0)
403ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
404ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					FVF |= D3DFVF_XYZRHW;
405ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
406ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				else
407ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
408ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					return 0;
409ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
410ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				break;
411ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case D3DDECLUSAGE_BLENDWEIGHT:
412ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				if(element.Type <= D3DDECLTYPE_FLOAT4 && element.UsageIndex == 0)
413ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
414ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					numBlendWeights += element.Type + 1;
415ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
416ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				else
417ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
418ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					return 0;
419ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
420ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				break;
421ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case D3DDECLUSAGE_BLENDINDICES:
422ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				return 0;
423ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				break;
424ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case D3DDECLUSAGE_NORMAL:
425ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				if(element.Type == D3DDECLTYPE_FLOAT3 && element.UsageIndex == 0)
426ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
427ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					FVF |= D3DFVF_NORMAL;
428ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
429ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				else
430ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
431ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					return 0;
432ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
433ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				break;
434ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case D3DDECLUSAGE_PSIZE:
435ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				if(element.Type == D3DDECLTYPE_FLOAT1 && element.UsageIndex == 0)
436ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
437ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					FVF |= D3DFVF_PSIZE;
438ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
439ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				else
440ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
441ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					return 0;
442ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
443ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				break;
444ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case D3DDECLUSAGE_COLOR:
445ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				if(element.Type == D3DDECLTYPE_D3DCOLOR && element.UsageIndex < 2)
446ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
447ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					if(element.UsageIndex == 0)
448ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					{
449ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens						FVF |= D3DFVF_DIFFUSE;
450ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					}
451ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					else   // element.UsageIndex == 1
452ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					{
453ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens						FVF |= D3DFVF_SPECULAR;
454ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					}
455ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
456ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				else
457ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
458ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					return 0;
459ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
460ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				break;
461ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			case D3DDECLUSAGE_TEXCOORD:
462ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				if((element.Type > D3DDECLTYPE_FLOAT4) || (element.UsageIndex > 7))
463ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
464ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					return 0;
465ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
466d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
467ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				int bit = 1 << element.UsageIndex;
468d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
469ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				if(textureBits & bit)
470ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
471ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					return 0;
472ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
473ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
474ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				textureBits |= bit;
475d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
476ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				switch(element.Type)
477ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				{
478ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				case D3DDECLTYPE_FLOAT1:
479ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					FVF |= D3DFVF_TEXCOORDSIZE1(element.UsageIndex);
480ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					break;
481ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				case D3DDECLTYPE_FLOAT2:
482ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					FVF |= D3DFVF_TEXCOORDSIZE2(element.UsageIndex);
483ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					break;
484ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				case D3DDECLTYPE_FLOAT3:
485ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					FVF |= D3DFVF_TEXCOORDSIZE3(element.UsageIndex);
486ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					break;
487ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				case D3DDECLTYPE_FLOAT4:
488ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					FVF |= D3DFVF_TEXCOORDSIZE4(element.UsageIndex);
489ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens					break;
490ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				}
491ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			}
492ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
493ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
494ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		bool isTransformed = (FVF & D3DFVF_XYZRHW) != 0;
495ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
496ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(isTransformed)
497ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
498ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			if(numBlendWeights != 0)
499ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			{
500ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens				return 0;
501ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			}
502ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
503ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		else if((FVF & D3DFVF_XYZ) == 0)
504ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
505ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return 0;
506ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
507d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
508ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		int positionMask = isTransformed ? 0x2 : 0x1;
509ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
510ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(numBlendWeights)
511ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
512ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			positionMask += numBlendWeights + 1;
513ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
514d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens
515ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		int numTexCoord = 0;
516ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
517ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		while(textureBits & 1)
518ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
519ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			textureBits >>= 1;
520ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
521ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			numTexCoord++;
522ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
523ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
524ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		if(textureBits)   // FVF does not allow
525ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		{
526ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens			return 0;
527ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		}
528ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
529ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		FVF |= D3DFVF_POSITION_MASK & (positionMask << 1);
530ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		FVF |= numTexCoord << D3DFVF_TEXCOUNT_SHIFT;
531ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens
532ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens		return FVF;
533ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens	}
534ee16f0de07d4b02a81c1c9ac716d631e67f487fcNicolas Capens}
535