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 /*************************************************************************
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
;
54 tmin
= ( pmin
->x
- prayposition
->x
) * div
;
55 tmax
= ( pmax
->x
- prayposition
->x
) * div
;
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
;
68 tymin
= ( pmin
->y
- prayposition
->y
) * div
;
69 tymax
= ( pmax
->y
- prayposition
->y
) * div
;
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
;
85 tzmin
= ( pmin
->z
- prayposition
->z
) * div
;
86 tzmax
= ( pmax
->z
- prayposition
->z
) * div
;
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
;
99 /*************************************************************************
100 * D3DXComputeBoundingBox
102 HRESULT WINAPI
D3DXComputeBoundingBox(CONST D3DXVECTOR3
*pfirstposition
, DWORD numvertices
, DWORD dwstride
, D3DXVECTOR3
*pmin
, D3DXVECTOR3
*pmax
)
107 if( !pfirstposition
|| !pmin
|| !pmax
) return D3DERR_INVALIDCALL
;
109 *pmin
= *pfirstposition
;
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
;
129 /*************************************************************************
130 * D3DXComputeBoundingSphere
132 HRESULT WINAPI
D3DXComputeBoundingSphere(CONST D3DXVECTOR3
* pfirstposition
, DWORD numvertices
, DWORD dwstride
, D3DXVECTOR3
*pcenter
, FLOAT
*pradius
)
134 D3DXVECTOR3 temp
, temp1
;
138 if( !pfirstposition
|| !pcenter
|| !pradius
) return D3DERR_INVALIDCALL
;
147 for(i
=0; i
<numvertices
; i
++)
149 D3DXVec3Add(&temp1
, &temp
, (D3DXVECTOR3
*)((char*)pfirstposition
+ dwstride
* i
));
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
;
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
)
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
);
202 /*************************************************************************
203 * D3DXGetDeclVertexSize
205 UINT WINAPI
D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9
*decl
, DWORD stream_idx
)
207 const D3DVERTEXELEMENT9
*element
;
210 TRACE("decl %p, stream_idx %u\n", decl
, stream_idx
);
214 for (element
= decl
; element
->Stream
!= 0xff; ++element
)
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
;
226 /*************************************************************************
227 * D3DXDeclaratorFromFVF
229 HRESULT WINAPI
D3DXDeclaratorFromFVF(DWORD fvf
, D3DVERTEXELEMENT9 Declaration
[MAX_FVF_DECL_SIZE
])
231 unsigned int idx
, idx2
;
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();
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
;
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
;
275 Declaration
[idx
].Type
= D3DDECLTYPE_FLOAT3
;
276 Declaration
[idx
].Usage
= D3DDECLUSAGE_POSITION
;
278 Declaration
[idx
].UsageIndex
= 0;
281 if (has_blend
&& (num_blends
> 0)) {
282 if (((fvf
& D3DFVF_XYZB5
) == D3DFVF_XYZB2
) && (fvf
& D3DFVF_LASTBETA_D3DCOLOR
))
283 Declaration
[idx
].Type
= D3DDECLTYPE_D3DCOLOR
;
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;
291 ERR("Unexpected amount of blend values: %u\n", num_blends
);
294 Declaration
[idx
].Usage
= D3DDECLUSAGE_BLENDWEIGHT
;
295 Declaration
[idx
].UsageIndex
= 0;
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
;
305 Declaration
[idx
].Type
= D3DDECLTYPE_FLOAT1
;
306 Declaration
[idx
].Usage
= D3DDECLUSAGE_BLENDINDICES
;
307 Declaration
[idx
].UsageIndex
= 0;
311 Declaration
[idx
].Type
= D3DDECLTYPE_FLOAT3
;
312 Declaration
[idx
].Usage
= D3DDECLUSAGE_NORMAL
;
313 Declaration
[idx
].UsageIndex
= 0;
317 Declaration
[idx
].Type
= D3DDECLTYPE_FLOAT1
;
318 Declaration
[idx
].Usage
= D3DDECLUSAGE_PSIZE
;
319 Declaration
[idx
].UsageIndex
= 0;
323 Declaration
[idx
].Type
= D3DDECLTYPE_D3DCOLOR
;
324 Declaration
[idx
].Usage
= D3DDECLUSAGE_COLOR
;
325 Declaration
[idx
].UsageIndex
= 0;
329 Declaration
[idx
].Type
= D3DDECLTYPE_D3DCOLOR
;
330 Declaration
[idx
].Usage
= D3DDECLUSAGE_COLOR
;
331 Declaration
[idx
].UsageIndex
= 1;
334 for (idx2
= 0; idx2
< num_textures
; idx2
++) {
335 unsigned int numcoords
= (texcoords
>> (idx2
*2)) & 0x03;
337 case D3DFVF_TEXTUREFORMAT1
:
338 Declaration
[idx
].Type
= D3DDECLTYPE_FLOAT1
;
340 case D3DFVF_TEXTUREFORMAT2
:
341 Declaration
[idx
].Type
= D3DDECLTYPE_FLOAT2
;
343 case D3DFVF_TEXTUREFORMAT3
:
344 Declaration
[idx
].Type
= D3DDECLTYPE_FLOAT3
;
346 case D3DFVF_TEXTUREFORMAT4
:
347 Declaration
[idx
].Type
= D3DDECLTYPE_FLOAT4
;
350 Declaration
[idx
].Usage
= D3DDECLUSAGE_TEXCOORD
;
351 Declaration
[idx
].UsageIndex
= idx2
;
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
);
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;
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
) {
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
;
410 /*************************************************************************
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
)
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
;
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
;
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
;
435 vec
.x
= praypos
->x
- p0
->x
;
436 vec
.y
= praypos
->y
- p0
->y
;
437 vec
.z
= praypos
->z
- p0
->z
;
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
) )
447 *pdist
= fabs( vec
.z
);
455 /*************************************************************************
456 * D3DXSphereBoundProbe
458 BOOL WINAPI
D3DXSphereBoundProbe(CONST D3DXVECTOR3
*pcenter
, FLOAT radius
, CONST D3DXVECTOR3
*prayposition
, CONST D3DXVECTOR3
*praydirection
)
460 D3DXVECTOR3 difference
;
463 a
= D3DXVec3LengthSq(praydirection
);
464 if (!D3DXVec3Subtract(&difference
, prayposition
, pcenter
)) return FALSE
;
465 b
= D3DXVec3Dot(&difference
, praydirection
);
466 c
= D3DXVec3LengthSq(&difference
) - radius
* radius
;
469 if ( ( d
<= 0.0f
) || ( sqrt(d
) <= b
) ) return FALSE
;
473 /*************************************************************************
476 HRESULT WINAPI
D3DXCreateBox(LPDIRECT3DDEVICE9 pDevice
,
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,
514 12, 13, 14, 14, 15, 12,
515 16, 17, 18, 18, 19, 16,
516 20, 21, 22, 22, 23, 20,
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
);
544 D3DXCreateBuffer(sizeof(DWORD
) * 3 * 12, ppAdjacency
);
545 ID3DXMesh_GenerateAdjacency(*ppMesh
, 0.f
, ID3DXBuffer_GetBufferPointer(*ppAdjacency
));