📄 dxutshapes.cpp
字号:
//--------------------------------------------------------------------------------------
// File: DXUTShapes.cpp
//
// Shape creation functions for DXUT
//
// Copyright (c) Microsoft Corporation. All rights reserved
//--------------------------------------------------------------------------------------
#include "DXUT.h"
#include "DXUTShapes.h"
//--------------------------------------------------------------------------------------
// VERTEX is the vertex layout for all DXUT created shapes
//--------------------------------------------------------------------------------------
struct VERTEX
{
D3DXVECTOR3 pos;
D3DXVECTOR3 norm;
};
static const D3D10_INPUT_ELEMENT_DESC s_ShapeLayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D10_INPUT_PER_VERTEX_DATA, 0 },
};
//--------------------------------------------------------------------------------------
static inline void sincosf(float angle, float *psin, float *pcos)
{
*psin = sinf(angle);
*pcos = cosf(angle);
}
//--------------------------------------------------------------------------------------
// Create D3DX10Mesh from the input vertex and index data
//--------------------------------------------------------------------------------------
HRESULT CreateShapeMesh( ID3D10Device* pDev10, ID3DX10Mesh** ppMesh, VERTEX* pVertices, UINT NumVertices, WORD* pIndices, UINT NumIndices )
{
HRESULT hr = S_OK;
// Create the mesh
hr = D3DX10CreateMesh( pDev10,
s_ShapeLayout,
sizeof(s_ShapeLayout)/sizeof(s_ShapeLayout[0]),
s_ShapeLayout[0].SemanticName,
NumVertices,
NumIndices/3,
0,
ppMesh );
if(FAILED(hr))
return hr;
// Set the Vertex Data
(*ppMesh)->SetVertexData( 0, pVertices );
// Set the Index Data
(*ppMesh)->SetIndexData( pIndices, NumIndices );
// Set attributes
DWORD dwNumAttr = 1;
D3DX10_ATTRIBUTE_RANGE* pAttr = new D3DX10_ATTRIBUTE_RANGE[dwNumAttr];
if(!pAttr)
return E_OUTOFMEMORY;
pAttr[0].AttribId = 0;
pAttr[0].FaceStart = 0;
pAttr[0].FaceCount = NumIndices/3;
pAttr[0].VertexStart = 0;
pAttr[0].VertexCount = NumVertices;
(*ppMesh)->SetAttributeTable( pAttr, dwNumAttr );
SAFE_DELETE_ARRAY( pAttr );
// Create the internal mesh VBs and IBs
(*ppMesh)->CommitToDevice();
return hr;
}
//----------------------------------------------------------------------------
// Box
//----------------------------------------------------------------------------
static float cubeN[6][3] =
{
{-1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
{0.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}, {0.0f, 0.0f, -1.0f}
};
static WORD cubeF[6][4] =
{
{ 0, 1, 5, 4 }, { 4, 5, 6, 7 }, { 7, 6, 2, 3 },
{ 1, 0, 3, 2 }, { 1, 2, 6, 5 }, { 0, 4, 7, 3 }
};
static float cubeV[8][3] =
{
// Lower tier (lower in y)
{-.5f, -.5f, -.5f},
{-.5f, -.5f, .5f},
{ .5f, -.5f, .5f},
{ .5f, -.5f, -.5f},
// Upper tier
{-.5f, .5f, -.5f},
{-.5f, .5f, .5f},
{ .5f, .5f, .5f},
{ .5f, .5f, -.5f},
};
static float cubeT[4][2] =
{
// Lower tier (lower in y)
{0.0f, 0.0f},
{0.0f, 1.0f},
{1.0f, 1.0f},
{1.0f, 0.0f}
};
static WORD cubeFT[6][4] =
{
{ 3, 0, 1, 2 }, { 0, 1, 2, 3 }, { 1, 2, 3, 0 },
{ 0, 1, 2, 3 }, { 3, 0, 1, 2 }, { 0, 1, 2, 3 }
};
//--------------------------------------------------------------------------------------
// MakeBox helper
//--------------------------------------------------------------------------------------
static void
MakeBox(
VERTEX* pVertices,
DWORD* pPointRep,
WORD* pwIndices,
float fWidth,
float fHeight,
float fDepth)
{
// Fill in the data
VERTEX *pVertex = pVertices;
WORD *pwFace = pwIndices;
UINT iVertex = 0;
// i iterates over the faces, 2 triangles per face
for (int i=0; i<6; i++)
{
for (int j=0; j<4; j++)
{
pVertex->pos.x = cubeV[cubeF[i][j]][0] * fWidth;
pVertex->pos.y = cubeV[cubeF[i][j]][1] * fHeight;
pVertex->pos.z = cubeV[cubeF[i][j]][2] * fDepth;
pVertex->norm.x = cubeN[i][0];
pVertex->norm.y = cubeN[i][1];
pVertex->norm.z = cubeN[i][2];
if (pPointRep != NULL)
{
*pPointRep = cubeF[i][j];
pPointRep++;
}
pVertex++;
}
pwFace[0] = (WORD) (iVertex);
pwFace[1] = (WORD) (iVertex + 1);
pwFace[2] = (WORD) (iVertex + 2);
pwFace += 3;
pwFace[0] = (WORD) (iVertex + 2);
pwFace[1] = (WORD) (iVertex + 3);
pwFace[2] = (WORD) (iVertex);
pwFace += 3;
iVertex += 4;
}
}
//--------------------------------------------------------------------------------------
// DXUTCreateBox - create a box mesh
//--------------------------------------------------------------------------------------
HRESULT WINAPI DXUTCreateBox( ID3D10Device* pDevice, float fWidth, float fHeight, float fDepth, ID3DX10Mesh** ppMesh )
{
HRESULT hr = S_OK;
WORD *pwIndices = NULL;
VERTEX *pVertices = NULL;
// Set up the defaults
if(D3DX_DEFAULT_FLOAT == fWidth)
fWidth = 1.0f;
if(D3DX_DEFAULT_FLOAT == fHeight)
fHeight = 1.0f;
if(D3DX_DEFAULT_FLOAT == fDepth)
fDepth = 1.0f;
// Validate parameters
if(!pDevice)
return D3DERR_INVALIDCALL;
if(!ppMesh)
return D3DERR_INVALIDCALL;
if(fWidth < 0.0f)
return D3DERR_INVALIDCALL;
if(fHeight < 0.0f)
return D3DERR_INVALIDCALL;
if(fDepth < 0.0f)
return D3DERR_INVALIDCALL;
// Create the mesh
UINT cFaces = 12;
UINT cVertices = 24;
// Create enough memory for the vertices and indices
pVertices = new VERTEX[ cVertices ];
if(!pVertices)
return E_OUTOFMEMORY;
pwIndices = new WORD[ cFaces*3 ];
if(!pwIndices)
return E_OUTOFMEMORY;
// Create a box
MakeBox(pVertices, NULL, pwIndices, fWidth, fHeight, fDepth);
// Create a mesh
hr = CreateShapeMesh( pDevice, ppMesh, pVertices, cVertices, pwIndices, cFaces*3 );
// Free up the memory
SAFE_DELETE_ARRAY( pVertices );
SAFE_DELETE_ARRAY( pwIndices );
return hr;
}
#define CACHE_SIZE 240
//----------------------------------------------------------------------------
// MakeCylinder helper
//----------------------------------------------------------------------------
static void
MakeCylinder(
VERTEX* pVertices,
DWORD* pPointReps,
WORD* pwIndices,
float fRadius1,
float fRadius2,
float fLength,
UINT uSlices,
UINT uStacks)
{
UINT i, j;
// Sin/Cos caches
float sinI[CACHE_SIZE], cosI[CACHE_SIZE];
for(i = 0; i < uSlices; i++)
sincosf(2.0f * D3DX_PI * i / uSlices, sinI + i, cosI + i);
// Compute side normal angle
float fDeltaRadius = fRadius2 - fRadius1;
float fSideLength = sqrtf(fDeltaRadius * fDeltaRadius + fLength * fLength);
float fNormalXY = (fSideLength > 0.00001f) ? (fLength / fSideLength) : 1.0f;
float fNormalZ = (fSideLength > 0.00001f) ? (-fDeltaRadius / fSideLength) : 0.0f;
// Generate vertices
VERTEX *pVertex = pVertices;
float fZ, fRadius;
DWORD iVertex;
// Base cap (uSlices + 1)
fZ = fLength * -0.5f;
fRadius = fRadius1;
iVertex = 0;
pVertex->pos = D3DXVECTOR3(0.0f, 0.0f, fZ);
pVertex->norm = D3DXVECTOR3(0.0f, 0.0f, -1.0f);
pVertex++;
if (pPointReps != NULL)
pPointReps[iVertex] = iVertex;
iVertex++;
for(i = 0; i < uSlices; i++)
{
pVertex->pos = D3DXVECTOR3(fRadius * sinI[i], fRadius * cosI[i], fZ);
pVertex->norm = D3DXVECTOR3(0.0f, 0.0f, -1.0f);
pVertex++;
// link into stack vertices, which follow
if (pPointReps != NULL)
pPointReps[iVertex] = iVertex + uSlices;
iVertex++;
}
// Stacks ((uStacks + 1)*uSlices)
for(j = 0; j <= uStacks; j++)
{
float f = (float) j / (float) uStacks;
fZ = fLength * (f - 0.5f);
fRadius = fRadius1 + f * fDeltaRadius;
for(i = 0; i < uSlices; i++)
{
pVertex->pos = D3DXVECTOR3(fRadius * sinI[i], fRadius * cosI[i], fZ);
pVertex->norm = D3DXVECTOR3(fNormalXY * sinI[i], fNormalXY * cosI[i], fNormalZ);
pVertex++;
if (pPointReps != NULL)
pPointReps[iVertex] = iVertex;
iVertex++;
}
}
// Top cap (uSlices + 1)
fZ = fLength * 0.5f;
fRadius = fRadius2;
for(i = 0; i < uSlices; i++)
{
pVertex->pos = D3DXVECTOR3(fRadius * sinI[i], fRadius * cosI[i], fZ);
pVertex->norm = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
pVertex++;
// link into stack vertices, which precede
if (pPointReps != NULL)
pPointReps[iVertex] = iVertex - uSlices;
iVertex++;
}
pVertex->pos = D3DXVECTOR3(0.0f, 0.0f, fZ);
pVertex->norm = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
pVertex++;
if (pPointReps != NULL)
pPointReps[iVertex] = iVertex;
iVertex++;
// Generate indices
WORD *pwFace = pwIndices;
UINT uRowA, uRowB;
// Z+ pole (uSlices)
uRowA = 0;
uRowB = 1;
for(i = 0; i < uSlices - 1; i++)
{
pwFace[0] = (WORD) (uRowA);
pwFace[1] = (WORD) (uRowB + i);
pwFace[2] = (WORD) (uRowB + i + 1);
pwFace += 3;
}
pwFace[0] = (WORD) (uRowA);
pwFace[1] = (WORD) (uRowB + i);
pwFace[2] = (WORD) (uRowB);
pwFace += 3;
// Interior stacks (uStacks * uSlices * 2)
for(j = 0; j < uStacks; j++)
{
uRowA = 1 + (j + 1) * uSlices;
uRowB = uRowA + uSlices;
for(i = 0; i < uSlices - 1; i++)
{
pwFace[0] = (WORD) (uRowA + i);
pwFace[1] = (WORD) (uRowB + i);
pwFace[2] = (WORD) (uRowA + i + 1);
pwFace += 3;
pwFace[0] = (WORD) (uRowA + i + 1);
pwFace[1] = (WORD) (uRowB + i);
pwFace[2] = (WORD) (uRowB + i + 1);
pwFace += 3;
}
pwFace[0] = (WORD) (uRowA + i);
pwFace[1] = (WORD) (uRowB + i);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -