D3D自学笔记(山峰)

承接上次的渲染方体。我们用同样步骤来实现一个山峰,和上次方体的一点不同的就是,再新建了一个类,封装了常用的几何体(网格,方体,球体等)的新建顶点、索引操作。

(一)  定义结构点:

//Vertex.h

namespace Vertex
{
	struct mountainVertex
	{...
	};
}
 

构成点的元素(位置 颜色 纹理等)进行描述

//vertex.cpp

const D3D11_INPUT_ELEMENT_DESC InputLayoutDec::MountainVertexs[] =
{...
};

Effect是一样的

建立inputlayout

//Vertex.h

ID3D11InputLayout* InputLayouts::Mountain = 0;

void InputLayouts::CreateInputLayouts(ID3D11Device* device)
{       ...
	HR(device->CreateInputLayout(InputLayoutDec::MountainVertexs, 2, passDesc.pIAInputSignature, 
	passDesc.IAInputSignatureSize, &Mountain));

}

(二)

//GeometryHelper.h

class GeoGen
{
public:
	struct Vertex
	{
		Vertex(){}
		Vertex(const XMFLOAT3& pos,const XMFLOAT3& nor,const XMFLOAT3& tex, const XMFLOAT2& uv)
			:Position(pos),Normal(nor),TangentU(tex),TexC(uv){}
		Vertex(
			float px, float py, float pz,
			float nx, float ny, float nz,
			float tx, float ty, float tz,
			float u, float v)
			: Position(px,py,pz), Normal(nx,ny,nz),
			  TangentU(tx, ty, tz), TexC(u,v){}
		XMFLOAT3 Position;
		XMFLOAT3 Normal;
		XMFLOAT3 TangentU;
		XMFLOAT2 TexC;
	}; //类里面的VERTEX定义,主要是服务于类里面的顶点定义,通过观察vertex的构造函数,可以看出position,normal,texture的内容。
	//用于返回到cpp,方便管理?
	struct MeshData
	{
		std::vector<Vertex> Vertices;
		std::vector<UINT> Indices;
	};

	//建立正方体
	void CreateBox(float width, float height, float depth, MeshData& meshData);
	//建立圆球
	void CreateSphere(float radius, UINT sliceCount, UINT stackCount, MeshData& meshData);
	//另一种方式建立圆球
	void CreateGeosphere(float radius,UINT numSubdivisions, MeshData& meshData);
	//建立圆柱
	void CreateCylinder(float bottomRadius, float topRadius, float height, UINT sliceCount, UINT stackCount, MeshData& meshData);
	//建立方格
	void CreateGrid(float width, float depth, UINT m, UINT n, MeshData& meshData);
	//建立满屏四边形?
	void CreateFullscreenQuad(MeshData& meshData);

	private:
	void Subdivide(MeshData& meshData);
	//建立圆柱顶盖,底盖
	void BuildCylinderTopCap(float bottomRadius, float topRadius, float height, UINT sliceCount, UINT stackCount, MeshData& meshData);
	void BuildCylinderBottomCap(float bottomRadius, float topRadius, float height, UINT sliceCount, UINT stackCount, MeshData& meshData);
};

//GeometryHelper.cpp

void GeoGen::CreateGrid(float width, float depth, UINT m, UINT n, MeshData& meshData)
{
	UINT vertexCount = m*n;
	UINT faceCount   = (m-1)*(n-1)*2;

	// 建立点

	float halfWidth = 0.5f*width;
	float halfDepth = 0.5f*depth;

	float dx = width / (n-1);
	float dz = depth / (m-1);

	float du = 1.0f / (n-1);
	float dv = 1.0f / (m-1);

	meshData.Vertices.resize(vertexCount);
	for(UINT i = 0; i < m; ++i)
	{
		float z = halfDepth - i*dz;
		for(UINT j = 0; j < n; ++j)
		{
			float x = -halfWidth + j*dx;

			meshData.Vertices[i*n+j].Position = XMFLOAT3(x, 0.0f, z);
			meshData.Vertices[i*n+j].Normal   = XMFLOAT3(0.0f, 1.0f, 0.0f);
			meshData.Vertices[i*n+j].TangentU = XMFLOAT3(1.0f, 0.0f, 0.0f);

			// Stretch texture over grid.
			meshData.Vertices[i*n+j].TexC.x = j*du;
			meshData.Vertices[i*n+j].TexC.y = i*dv;
		}
	}
 

	// 建立索引.

	meshData.Indices.resize(faceCount*3); // 3 indices per face

	// Iterate over each quad and compute indices.
	UINT k = 0;
	for(UINT i = 0; i < m-1; ++i)
	{
		for(UINT j = 0; j < n-1; ++j)
		{
			meshData.Indices[k]   = i*n+j;
			meshData.Indices[k+1] = i*n+j+1;
			meshData.Indices[k+2] = (i+1)*n+j;

			meshData.Indices[k+3] = (i+1)*n+j;
			meshData.Indices[k+4] = i*n+j+1;
			meshData.Indices[k+5] = (i+1)*n+j+1;

			k += 6; 
		}
	}
}

//mountainDemo.cpp

void moutainApp::BuildVerInBuffers()
{
	GeoGen::MeshData grid;

	GeoGen geoGen;

	geoGen.CreateGrid(160.0f, 160.0f, 50, 50, grid);

	mLandIndexCount = grid.Indices.size(); //Vertex的自带函数
	//vertices要改变一下
	std::vector<Vertex::mountainVertex> vertices(grid.Vertices.size());
for(size_t i = 0; i < grid.Vertices.size(); ++i)
    {
        XMFLOAT3 p = grid.Vertices[i].Position;
 
        p.y = GetHillHeight(p.x, p.z);
 
        vertices[i].pos   = p;
         
        // 根据顶点高度设置颜色
        if( p.y < -10.0f )
        {
            // 沙滩色
            vertices[i].Color = XMFLOAT4(1.0f, 0.96f, 0.62f, 1.0f);
        }
        else if( p.y < 5.0f )
        {
            // 淡绿色
            vertices[i].Color = XMFLOAT4(0.48f, 0.77f, 0.46f, 1.0f);
        }
        else if( p.y < 12.0f )
        {
            // 深绿色
            vertices[i].Color = XMFLOAT4(0.1f, 0.48f, 0.19f, 1.0f);
        }
        else if( p.y < 20.0f )
        {
            // 棕色
            vertices[i].Color = XMFLOAT4(0.45f, 0.39f, 0.34f, 1.0f);
        }
        else
        {
            // 白色
            vertices[i].Color = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
        }
    }

	D3D11_BUFFER_DESC vbd;
	vbd.Usage = D3D11_USAGE_IMMUTABLE;
	vbd.ByteWidth = sizeof(Vertex::mountainVertex) * grid.Vertices.size();
	vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
	vbd.CPUAccessFlags = 0;
	vbd.MiscFlags = 0;
	vbd.StructureByteStride = 0;
	D3D11_SUBRESOURCE_DATA vinitData;
	vinitData.pSysMem = &vertices[0];
 
	HR(md3dDevice->CreateBuffer(&vbd, &vinitData, &mVB));


	// 要创建的索引的描述
	D3D11_BUFFER_DESC ibd;
	ibd.Usage = D3D11_USAGE_IMMUTABLE;
	ibd.ByteWidth = sizeof(UINT) * mLandIndexCount;
	ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
	ibd.CPUAccessFlags = 0;
	ibd.MiscFlags = 0;
	ibd.StructureByteStride = 0;
 
	// 设定用于初始化索引缓冲的数据
	D3D11_SUBRESOURCE_DATA iinitData;
	iinitData.pSysMem = &grid.Indices[0];
 
	// 创建索引缓冲
	HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mIB));

};
<pre name="code" class="cpp">float moutainApp::GetHillHeight(float x, float z)const
{
	return 0.3f*( z*sinf(0.1f*x) + x*cosf(0.1f*z) );
}
 
void moutainApp::Draw()
{
	...
    for(UINT p = 0; p < techDesc.Passes; ++p)
    {
        Effects::BasicFX->Tech->GetPassByIndex(p)->Apply(0, md3dContext);
        md3dContext->DrawIndexed(mLandIndexCount, 0, 0);
    }
 
    HR(mSwapChain->Present(0, 0));
}
 

配套代码:

http://download.csdn.net/detail/vwwyohann/9215151






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值