d3dx9: Apply current transform in ID3DXSprite_Draw instead of ID3DXSprite_Flush.
[wine/d3dx9TW.git] / dlls / d3dx9_36 / mesh.c
blobe70cdbd7c3a0365d91feefa982569384c2f5d6f4
1 /*
2 * Mesh operations specific to D3DX9.
4 * Copyright (C) 2009 David Adam
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "wine/debug.h"
22 #include "d3dx9_36_private.h"
24 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
26 /*************************************************************************
27 * D3DXBoxBoundProbe
29 BOOL WINAPI D3DXBoxBoundProbe(CONST D3DXVECTOR3 *pmin, CONST D3DXVECTOR3 *pmax, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
31 /* Algorithm taken from the article: An Efficient and Robust Ray-Box Intersection Algoritm
32 Amy Williams University of Utah
33 Steve Barrus University of Utah
34 R. Keith Morley University of Utah
35 Peter Shirley University of Utah
37 International Conference on Computer Graphics and Interactive Techniques archive
38 ACM SIGGRAPH 2005 Courses
39 Los Angeles, California
41 This algorithm is free of patents or of copyrights, as confirmed by Peter Shirley himself.
43 Algorithm: Consider the box as the intersection of three slabs. Clip the ray
44 against each slab, if there's anything left of the ray after we're
45 done we've got an intersection of the ray with the box.
49 FLOAT div, tmin, tmax, tymin, tymax, tzmin, tzmax;
51 div = 1.0f / praydirection->x;
52 if ( div >= 0.0f )
54 tmin = ( pmin->x - prayposition->x ) * div;
55 tmax = ( pmax->x - prayposition->x ) * div;
57 else
59 tmin = ( pmax->x - prayposition->x ) * div;
60 tmax = ( pmin->x - prayposition->x ) * div;
63 if ( tmax < 0.0f ) return FALSE;
65 div = 1.0f / praydirection->y;
66 if ( div >= 0.0f )
68 tymin = ( pmin->y - prayposition->y ) * div;
69 tymax = ( pmax->y - prayposition->y ) * div;
71 else
73 tymin = ( pmax->y - prayposition->y ) * div;
74 tymax = ( pmin->y - prayposition->y ) * div;
77 if ( ( tymax < 0.0f ) || ( tmin > tymax ) || ( tymin > tmax ) ) return FALSE;
79 if ( tymin > tmin ) tmin = tymin;
80 if ( tymax < tmax ) tmax = tymax;
82 div = 1.0f / praydirection->z;
83 if ( div >= 0.0f )
85 tzmin = ( pmin->z - prayposition->z ) * div;
86 tzmax = ( pmax->z - prayposition->z ) * div;
88 else
90 tzmin = ( pmax->z - prayposition->z ) * div;
91 tzmax = ( pmin->z - prayposition->z ) * div;
94 if ( (tzmax < 0.0f ) || ( tmin > tzmax ) || ( tzmin > tmax ) ) return FALSE;
96 return TRUE;
99 /*************************************************************************
100 * D3DXComputeBoundingBox
102 HRESULT WINAPI D3DXComputeBoundingBox(CONST D3DXVECTOR3 *pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pmin, D3DXVECTOR3 *pmax)
104 D3DXVECTOR3 vec;
105 unsigned int i;
107 if( !pfirstposition || !pmin || !pmax ) return D3DERR_INVALIDCALL;
109 *pmin = *pfirstposition;
110 *pmax = *pmin;
112 for(i=0; i<numvertices; i++)
114 vec = *( (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i) );
116 if ( vec.x < pmin->x ) pmin->x = vec.x;
117 if ( vec.x > pmax->x ) pmax->x = vec.x;
119 if ( vec.y < pmin->y ) pmin->y = vec.y;
120 if ( vec.y > pmax->y ) pmax->y = vec.y;
122 if ( vec.z < pmin->z ) pmin->z = vec.z;
123 if ( vec.z > pmax->z ) pmax->z = vec.z;
126 return D3D_OK;
129 /*************************************************************************
130 * D3DXComputeBoundingSphere
132 HRESULT WINAPI D3DXComputeBoundingSphere(CONST D3DXVECTOR3* pfirstposition, DWORD numvertices, DWORD dwstride, D3DXVECTOR3 *pcenter, FLOAT *pradius)
134 D3DXVECTOR3 temp, temp1;
135 FLOAT d;
136 unsigned int i;
138 if( !pfirstposition || !pcenter || !pradius ) return D3DERR_INVALIDCALL;
140 temp.x = 0.0f;
141 temp.y = 0.0f;
142 temp.z = 0.0f;
143 temp1 = temp;
144 d = 0.0f;
145 *pradius = 0.0f;
147 for(i=0; i<numvertices; i++)
149 D3DXVec3Add(&temp1, &temp, (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i));
150 temp = temp1;
153 D3DXVec3Scale(pcenter, &temp, 1.0f/((FLOAT)numvertices));
155 for(i=0; i<numvertices; i++)
157 d = D3DXVec3Length(D3DXVec3Subtract(&temp, (D3DXVECTOR3*)((char*)pfirstposition + dwstride * i), pcenter));
158 if ( d > *pradius ) *pradius = d;
160 return D3D_OK;
163 /*************************************************************************
164 * D3DXGetFVFVertexSize
166 static UINT Get_TexCoord_Size_From_FVF(DWORD FVF, int tex_num)
168 return (((((FVF) >> (16 + (2 * (tex_num)))) + 1) & 0x03) + 1);
171 UINT WINAPI D3DXGetFVFVertexSize(DWORD FVF)
173 DWORD size = 0;
174 UINT i;
175 UINT numTextures = (FVF & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
177 if (FVF & D3DFVF_NORMAL) size += sizeof(D3DXVECTOR3);
178 if (FVF & D3DFVF_DIFFUSE) size += sizeof(DWORD);
179 if (FVF & D3DFVF_SPECULAR) size += sizeof(DWORD);
180 if (FVF & D3DFVF_PSIZE) size += sizeof(DWORD);
182 switch (FVF & D3DFVF_POSITION_MASK)
184 case D3DFVF_XYZ: size += sizeof(D3DXVECTOR3); break;
185 case D3DFVF_XYZRHW: size += 4 * sizeof(FLOAT); break;
186 case D3DFVF_XYZB1: size += 4 * sizeof(FLOAT); break;
187 case D3DFVF_XYZB2: size += 5 * sizeof(FLOAT); break;
188 case D3DFVF_XYZB3: size += 6 * sizeof(FLOAT); break;
189 case D3DFVF_XYZB4: size += 7 * sizeof(FLOAT); break;
190 case D3DFVF_XYZB5: size += 8 * sizeof(FLOAT); break;
191 case D3DFVF_XYZW: size += 4 * sizeof(FLOAT); break;
194 for (i = 0; i < numTextures; i++)
196 size += Get_TexCoord_Size_From_FVF(FVF, i) * sizeof(FLOAT);
199 return size;
202 /*************************************************************************
203 * D3DXGetDeclVertexSize
205 UINT WINAPI D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9 *decl, DWORD stream_idx)
207 const D3DVERTEXELEMENT9 *element;
208 UINT size = 0;
210 TRACE("decl %p, stream_idx %u\n", decl, stream_idx);
212 if (!decl) return 0;
214 for (element = decl; element->Stream != 0xff; ++element)
216 UINT type_size;
218 if (element->Stream != stream_idx) continue;
220 type_size = vertex_element_size(element->Type);
221 if (element->Offset + type_size > size) size = element->Offset + type_size;
223 return size;
226 /*************************************************************************
227 * D3DXDeclaratorFromFVF
229 HRESULT WINAPI D3DXDeclaratorFromFVF(DWORD fvf, D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE])
231 unsigned int idx, idx2;
232 unsigned int offset;
233 BOOL has_pos = (fvf & D3DFVF_POSITION_MASK) != 0;
234 BOOL has_blend = (fvf & D3DFVF_XYZB5) > D3DFVF_XYZRHW;
235 BOOL has_blend_idx = has_blend &&
236 (((fvf & D3DFVF_XYZB5) == D3DFVF_XYZB5) ||
237 (fvf & D3DFVF_LASTBETA_D3DCOLOR) ||
238 (fvf & D3DFVF_LASTBETA_UBYTE4));
239 BOOL has_normal = (fvf & D3DFVF_NORMAL) != 0;
240 BOOL has_psize = (fvf & D3DFVF_PSIZE) != 0;
242 BOOL has_diffuse = (fvf & D3DFVF_DIFFUSE) != 0;
243 BOOL has_specular = (fvf & D3DFVF_SPECULAR) !=0;
245 DWORD num_textures = (fvf & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT;
246 DWORD texcoords = (fvf & 0xFFFF0000) >> 16;
248 D3DVERTEXELEMENT9 end_element = D3DDECL_END();
250 unsigned int size;
251 DWORD num_blends = 1 + (((fvf & D3DFVF_XYZB5) - D3DFVF_XYZB1) >> 1);
252 if (has_blend_idx) num_blends--;
254 TRACE("fvf %u, Declaration %p\n", fvf, Declaration);
256 if(fvf == D3DFVF_XYZB5) return D3DERR_INVALIDCALL;
258 /* compute declaration size */
259 size = has_pos + (has_blend && num_blends > 0) + has_blend_idx + has_normal +
260 has_psize + has_diffuse + has_specular + num_textures + 1;
262 /* convert the declaration */
263 Declaration[size-1] = end_element;
264 idx = 0;
265 if (has_pos) {
266 if (!has_blend && (fvf & D3DFVF_XYZRHW)) {
267 Declaration[idx].Type = D3DDECLTYPE_FLOAT4;
268 Declaration[idx].Usage = D3DDECLUSAGE_POSITIONT;
270 else if (!has_blend && (fvf & D3DFVF_XYZW) == D3DFVF_XYZW) {
271 Declaration[idx].Type = D3DDECLTYPE_FLOAT4;
272 Declaration[idx].Usage = D3DDECLUSAGE_POSITION;
274 else {
275 Declaration[idx].Type = D3DDECLTYPE_FLOAT3;
276 Declaration[idx].Usage = D3DDECLUSAGE_POSITION;
278 Declaration[idx].UsageIndex = 0;
279 idx++;
281 if (has_blend && (num_blends > 0)) {
282 if (((fvf & D3DFVF_XYZB5) == D3DFVF_XYZB2) && (fvf & D3DFVF_LASTBETA_D3DCOLOR))
283 Declaration[idx].Type = D3DDECLTYPE_D3DCOLOR;
284 else {
285 switch(num_blends) {
286 case 1: Declaration[idx].Type = D3DDECLTYPE_FLOAT1; break;
287 case 2: Declaration[idx].Type = D3DDECLTYPE_FLOAT2; break;
288 case 3: Declaration[idx].Type = D3DDECLTYPE_FLOAT3; break;
289 case 4: Declaration[idx].Type = D3DDECLTYPE_FLOAT4; break;
290 default:
291 ERR("Unexpected amount of blend values: %u\n", num_blends);
294 Declaration[idx].Usage = D3DDECLUSAGE_BLENDWEIGHT;
295 Declaration[idx].UsageIndex = 0;
296 idx++;
298 if (has_blend_idx) {
299 if (fvf & D3DFVF_LASTBETA_UBYTE4 ||
300 (((fvf & D3DFVF_XYZB5) == D3DFVF_XYZB2) && (fvf & D3DFVF_LASTBETA_D3DCOLOR)))
301 Declaration[idx].Type = D3DDECLTYPE_UBYTE4;
302 else if (fvf & D3DFVF_LASTBETA_D3DCOLOR)
303 Declaration[idx].Type = D3DDECLTYPE_D3DCOLOR;
304 else
305 Declaration[idx].Type = D3DDECLTYPE_FLOAT1;
306 Declaration[idx].Usage = D3DDECLUSAGE_BLENDINDICES;
307 Declaration[idx].UsageIndex = 0;
308 idx++;
310 if (has_normal) {
311 Declaration[idx].Type = D3DDECLTYPE_FLOAT3;
312 Declaration[idx].Usage = D3DDECLUSAGE_NORMAL;
313 Declaration[idx].UsageIndex = 0;
314 idx++;
316 if (has_psize) {
317 Declaration[idx].Type = D3DDECLTYPE_FLOAT1;
318 Declaration[idx].Usage = D3DDECLUSAGE_PSIZE;
319 Declaration[idx].UsageIndex = 0;
320 idx++;
322 if (has_diffuse) {
323 Declaration[idx].Type = D3DDECLTYPE_D3DCOLOR;
324 Declaration[idx].Usage = D3DDECLUSAGE_COLOR;
325 Declaration[idx].UsageIndex = 0;
326 idx++;
328 if (has_specular) {
329 Declaration[idx].Type = D3DDECLTYPE_D3DCOLOR;
330 Declaration[idx].Usage = D3DDECLUSAGE_COLOR;
331 Declaration[idx].UsageIndex = 1;
332 idx++;
334 for (idx2 = 0; idx2 < num_textures; idx2++) {
335 unsigned int numcoords = (texcoords >> (idx2*2)) & 0x03;
336 switch (numcoords) {
337 case D3DFVF_TEXTUREFORMAT1:
338 Declaration[idx].Type = D3DDECLTYPE_FLOAT1;
339 break;
340 case D3DFVF_TEXTUREFORMAT2:
341 Declaration[idx].Type = D3DDECLTYPE_FLOAT2;
342 break;
343 case D3DFVF_TEXTUREFORMAT3:
344 Declaration[idx].Type = D3DDECLTYPE_FLOAT3;
345 break;
346 case D3DFVF_TEXTUREFORMAT4:
347 Declaration[idx].Type = D3DDECLTYPE_FLOAT4;
348 break;
350 Declaration[idx].Usage = D3DDECLUSAGE_TEXCOORD;
351 Declaration[idx].UsageIndex = idx2;
352 idx++;
355 /* compute offsets and initialize the rest of the fields */
356 for (idx = 0, offset = 0; idx < size-1; idx++) {
357 Declaration[idx].Stream = 0;
358 Declaration[idx].Method = D3DDECLMETHOD_DEFAULT;
359 Declaration[idx].Offset = offset;
360 offset += vertex_element_size(Declaration[idx].Type);
362 return D3D_OK;
365 /*************************************************************************
366 * D3DXFVFFromDeclarator
368 * segfaults if pDeclaration of pFVF are NULL
370 HRESULT WINAPI D3DXFVFFromDeclarator(CONST D3DVERTEXELEMENT9 *pDeclaration, DWORD *pFVF)
372 D3DVERTEXELEMENT9 cmpdecl[MAX_FVF_DECL_SIZE];
373 unsigned int i, numtextures = 0;
374 TRACE("(void)\n");
376 *pFVF = 0;
378 for(i = 0;pDeclaration[i].Stream != 0xFF;i++) {
379 if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT3 && pDeclaration[i].Usage == D3DDECLUSAGE_POSITION && pDeclaration[i].UsageIndex == 0) *pFVF |= D3DFVF_XYZ;
380 else if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT4 && pDeclaration[i].Usage == D3DDECLUSAGE_POSITIONT && pDeclaration[i].UsageIndex == 0) *pFVF |= D3DFVF_XYZRHW;
381 else if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT1 && pDeclaration[i].Usage == D3DDECLUSAGE_BLENDWEIGHT && pDeclaration[i].UsageIndex == 0) *pFVF |= D3DFVF_XYZB1;
382 else if(pDeclaration[i].Usage == D3DDECLUSAGE_BLENDWEIGHT && pDeclaration[i].UsageIndex == 0) {
383 if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT2) *pFVF |= D3DFVF_XYZB2;
384 else if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT3) *pFVF |= D3DFVF_XYZB3;
385 else if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT4) *pFVF |= D3DFVF_XYZB4;
386 /* TODO: if((pDeclaration)[i].Type == D3DDECLTYPE_UBYTE4) ; */
388 else if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT3 && pDeclaration[i].Usage == D3DDECLUSAGE_NORMAL && pDeclaration[i].UsageIndex == 0) *pFVF |= D3DFVF_NORMAL;
389 else if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT1 && pDeclaration[i].Usage == D3DDECLUSAGE_PSIZE && pDeclaration[i].UsageIndex == 0) *pFVF |= D3DFVF_PSIZE;
390 else if((pDeclaration)[i].Type == D3DDECLTYPE_D3DCOLOR && pDeclaration[i].Usage == D3DDECLUSAGE_COLOR && pDeclaration[i].UsageIndex == 0) *pFVF |= D3DFVF_DIFFUSE;
391 else if((pDeclaration)[i].Type == D3DDECLTYPE_D3DCOLOR && pDeclaration[i].Usage == D3DDECLUSAGE_COLOR && pDeclaration[i].UsageIndex == 1) *pFVF |= D3DFVF_SPECULAR;
392 else if(pDeclaration[i].Usage == D3DDECLUSAGE_TEXCOORD) {
393 numtextures++;
394 if(pDeclaration[i].Type == D3DDECLTYPE_FLOAT1) *pFVF |= D3DFVF_TEXCOORDSIZE1(pDeclaration[i].UsageIndex);
395 else if(pDeclaration[i].Type == D3DDECLTYPE_FLOAT2) *pFVF |= D3DFVF_TEXCOORDSIZE2(pDeclaration[i].UsageIndex);
396 else if(pDeclaration[i].Type == D3DDECLTYPE_FLOAT3) *pFVF |= D3DFVF_TEXCOORDSIZE3(pDeclaration[i].UsageIndex);
397 else if(pDeclaration[i].Type == D3DDECLTYPE_FLOAT4) *pFVF |= D3DFVF_TEXCOORDSIZE4(pDeclaration[i].UsageIndex);
399 else if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT3 && pDeclaration[i].Usage == D3DDECLUSAGE_POSITION && pDeclaration[i].UsageIndex == 1) return D3DERR_INVALIDCALL;
400 else if((pDeclaration)[i].Type == D3DDECLTYPE_FLOAT3 && pDeclaration[i].Usage == D3DDECLUSAGE_NORMAL && pDeclaration[i].UsageIndex == 1) return D3DERR_INVALIDCALL;
402 *pFVF |= numtextures << 8;
403 D3DXDeclaratorFromFVF(*pFVF, cmpdecl);
405 if(memcmp(cmpdecl, pDeclaration, i * sizeof(D3DVERTEXELEMENT9)) != 0) return D3DERR_INVALIDCALL;
407 return D3D_OK;
410 /*************************************************************************
411 * D3DXIntersectTri
413 BOOL WINAPI D3DXIntersectTri(CONST D3DXVECTOR3 *p0, CONST D3DXVECTOR3 *p1, CONST D3DXVECTOR3 *p2, CONST D3DXVECTOR3 *praypos, CONST D3DXVECTOR3 *praydir, FLOAT *pu, FLOAT *pv, FLOAT *pdist)
415 D3DXMATRIX m;
416 D3DXVECTOR4 vec;
418 m.m[0][0] = p1->x - p0->x;
419 m.m[1][0] = p2->x - p0->x;
420 m.m[2][0] = -praydir->x;
421 m.m[3][0] = 0.0f;
422 m.m[0][1] = p1->y - p0->z;
423 m.m[1][1] = p2->y - p0->z;
424 m.m[2][1] = -praydir->y;
425 m.m[3][1] = 0.0f;
426 m.m[0][2] = p1->z - p0->z;
427 m.m[1][2] = p2->z - p0->z;
428 m.m[2][2] = -praydir->z;
429 m.m[3][2] = 0.0f;
430 m.m[0][3] = 0.0f;
431 m.m[1][3] = 0.0f;
432 m.m[2][3] = 0.0f;
433 m.m[3][3] = 1.0f;
435 vec.x = praypos->x - p0->x;
436 vec.y = praypos->y - p0->y;
437 vec.z = praypos->z - p0->z;
438 vec.w = 0.0f;
440 if ( D3DXMatrixInverse(&m, NULL, &m) )
442 D3DXVec4Transform(&vec, &vec, &m);
443 if ( (vec.x >= 0.0f) && (vec.y >= 0.0f) && (vec.x + vec.y <= 1.0f) && (vec.z >= 0.0f) )
445 *pu = vec.x;
446 *pv = vec.y;
447 *pdist = fabs( vec.z );
448 return TRUE;
452 return FALSE;
455 /*************************************************************************
456 * D3DXSphereBoundProbe
458 BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *pcenter, FLOAT radius, CONST D3DXVECTOR3 *prayposition, CONST D3DXVECTOR3 *praydirection)
460 D3DXVECTOR3 difference;
461 FLOAT a, b, c, d;
463 a = D3DXVec3LengthSq(praydirection);
464 if (!D3DXVec3Subtract(&difference, prayposition, pcenter)) return FALSE;
465 b = D3DXVec3Dot(&difference, praydirection);
466 c = D3DXVec3LengthSq(&difference) - radius * radius;
467 d = b * b - a * c;
469 if ( ( d <= 0.0f ) || ( sqrt(d) <= b ) ) return FALSE;
470 return TRUE;
473 /*************************************************************************
474 * D3DXCreateBox
476 HRESULT WINAPI D3DXCreateBox(LPDIRECT3DDEVICE9 pDevice,
477 FLOAT fWidth,
478 FLOAT fHeight,
479 FLOAT fDepth,
480 LPD3DXMESH *ppMesh,
481 LPD3DXBUFFER *ppAdjacency)
483 float vertices[6 * 24] = {
484 /* Pos XYZ - Normal XYZ */
485 -0.50, -0.50, -0.50, -1.00, 0.00, 0.00,
486 -0.50, -0.50, 0.50, -1.00, 0.00, 0.00,
487 -0.50, 0.50, 0.50, -1.00, 0.00, 0.00,
488 -0.50, 0.50, -0.50, -1.00, 0.00, 0.00,
489 -0.50, 0.50, -0.50, 0.00, 1.00, 0.00,
490 -0.50, 0.50, 0.50, 0.00, 1.00, 0.00,
491 0.50, 0.50, 0.50, 0.00, 1.00, 0.00,
492 0.50, 0.50, -0.50, 0.00, 1.00, 0.00,
493 0.50, 0.50, -0.50, 1.00, 0.00, 0.00,
494 0.50, 0.50, 0.50, 1.00, 0.00, 0.00,
495 0.50, -0.50, 0.50, 1.00, 0.00, 0.00,
496 0.50, -0.50, -0.50, 1.00, 0.00, 0.00,
497 -0.50, -0.50, 0.50, 0.00, -1.00, 0.00,
498 -0.50, -0.50, -0.50, 0.00, -1.00, 0.00,
499 0.50, -0.50, -0.50, 0.00, -1.00, 0.00,
500 0.50, -0.50, 0.50, 0.00, -1.00, 0.00,
501 -0.50, -0.50, 0.50, 0.00, 0.00, 1.00,
502 0.50, -0.50, 0.50, 0.00, 0.00, 1.00,
503 0.50, 0.50, 0.50, 0.00, 0.00, 1.00,
504 -0.50, 0.50, 0.50, 0.00, 0.00, 1.00,
505 -0.50, -0.50, -0.50, 0.00, 0.00, -1.00,
506 -0.50, 0.50, -0.50, 0.00, 0.00, -1.00,
507 0.50, 0.50, -0.50, 0.00, 0.00, -1.00,
508 0.50, -0.50, -0.50, 0.00, 0.00, -1.00,
510 WORD indices[36] = {
511 0, 1, 2, 2, 3, 0,
512 4, 5, 6, 6, 7, 4,
513 8, 9, 10, 10, 11, 8,
514 12, 13, 14, 14, 15, 12,
515 16, 17, 18, 18, 19, 16,
516 20, 21, 22, 22, 23, 20,
518 LPVOID pData;
519 HRESULT hr;
520 int i;
521 TRACE("(void)\n");
523 if( !pDevice || !ppMesh ) return D3DERR_INVALIDCALL;
524 if(fWidth < 0.f || fHeight < 0.f || fDepth < 0.f) return D3DERR_INVALIDCALL;
526 hr = D3DXCreateMeshFVF(12, 24, D3DXMESH_MANAGED, D3DFVF_XYZ | D3DFVF_NORMAL, pDevice, ppMesh);
527 if(FAILED(hr)) return hr;
529 for(i = 0;i < 24; i++) {
530 vertices[6 * i ] *= fWidth;
531 vertices[6 * i + 1] *= fHeight;
532 vertices[6 * i + 2] *= fDepth;
535 ID3DXMesh_LockVertexBuffer(*ppMesh, D3DLOCK_NOSYSLOCK, &pData);
536 memcpy(pData, vertices, sizeof(float) * 6 * 24);
537 ID3DXMesh_UnlockVertexBuffer(*ppMesh);
539 ID3DXMesh_LockIndexBuffer(*ppMesh, D3DLOCK_NOSYSLOCK, &pData);
540 memcpy(pData, indices, sizeof(WORD) * 36);
541 ID3DXMesh_UnlockIndexBuffer(*ppMesh);
543 if(ppAdjacency) {
544 D3DXCreateBuffer(sizeof(DWORD) * 3 * 12, ppAdjacency);
545 ID3DXMesh_GenerateAdjacency(*ppMesh, 0.f, ID3DXBuffer_GetBufferPointer(*ppAdjacency));
547 return D3D_OK;