您的位置:首页 > 其它

D3D自学笔记(山峰与水波)

2015-10-20 23:57 549 查看
承接上一次的渲染山峰,这次要使用动态缓冲(dynamic buffer),实现更新水波顶点高度,制造水波效果。

我暂时忽略水波模拟算法上,直接运用龙书中的Waves.h,Waves.cpp。

与之前的两次渲染相同,总共分两步,但在上一次基础上,其实第一步已经完成,下面是第二步。

描述具体点

MountainAndWaves.cpp
//mWaves.Init(160, 160, 1.0f, 0.03f, 3.25f, 0.4f);

描述索引,建立缓冲(注意在建立顶点缓冲的时候,并没有定义指向顶点数据的指针,而是赋0。

MountainAndWaves.cpp
void BuildWavesVerInBuffers();
…
void moutainApp::BuildWavesVerInBuffers()
{
D3D11_BUFFER_DESCvbd;
vbd.Usage =D3D11_USAGE_DYNAMIC;
vbd.ByteWidth= sizeof(Vertex::mountainVertex) *mWaves.VertexCount();
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;      //要更新资源,设为写入cpu
vbd.MiscFlags = 0;

HR(md3dDevice->CreateBuffer(&vbd, 0, &mWavesVB));

// Create the index buffer. The index buffer is fixed, so we only
// need to create and set once.

std::vector<UINT>indices(3*mWaves.TriangleCount()); // 3 indices perface

// Iterate over each quad.
UINT m =mWaves.RowCount();
UINT n =mWaves.ColumnCount();
int k = 0;
for(UINT i = 0; i < m-1; ++i)
{
for(DWORD j = 0; j < n-1; ++j)
{
indices[k]   = i*n+j;
indices[k+1]= i*n+j+1;
indices[k+2]= (i+1)*n+j;

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

k +=6; // next quad
}
}

D3D11_BUFFER_DESCibd;
ibd.Usage =D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth= sizeof(UINT) * indices.size();
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;                         //index不用更新
ibd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = &indices[0];
HR(md3dDevice->CreateBuffer(&ibd, &iinitData, &mWavesIB));
};

其实是在更新函数的时候才定义指向顶点数据(资源)的指针:

void moutainApp::Update(float dt)
{
...
static float t_base =0.0f;
if( (mTimer.TotalTime() - t_base) >= 0.25f )
{
t_base+= 0.25f;

DWORD i= 5 + rand() % (mWaves.RowCount()-10);
DWORD j= 5 + rand() % (mWaves.ColumnCount()-10);

float r = MathHelper<float>::RandF(1.0f,2.0f);

mWaves.Disturb(i,j, r);
}

mWaves.Update(dt);

D3D11_MAPPED_SUBRESOURCEmappedData;
HR(md3dContext->Map(mWavesVB,0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData));
Vertex::mountainVertex* v = reinterpret_cast<Vertex::mountainVertex*>(mappedData.pData);
for(UINT i = 0; i < mWaves.VertexCount(); ++i)
{
v[i].pos    = mWaves[i];
v[i].Color  = reinterpret_cast<const float*>(&Colors::Black);
}
md3dContext->Unmap(mWavesVB,0);
}

绑定到装配输入阶段并且渲染,注意这里描述了一个光栅化状态,使水波呈线框状,且没有背面消隐:

<pre name="code" class="cpp">void moutainApp::Draw()
{
...
D3D11_RASTERIZER_DESCrsDesc;
ZeroMemory(&rsDesc,sizeof(D3D11_RASTERIZER_DESC));
rsDesc.FillMode= D3D11_FILL_WIREFRAME;
rsDesc.CullMode= D3D11_CULL_NONE;
rsDesc.FrontCounterClockwise= false;
rsDesc.DepthClipEnable= true;

HR(md3dDevice->CreateRasterizerState(&rsDesc,&mWireFrameRS));//描述光栅化状态
...
md3dContext->IASetVertexBuffers(0, 1, &mMountainVB, &stride,&offset);
md3dContext->IASetIndexBuffer(mMountainIB, DXGI_FORMAT_R32_UINT, 0);

// Set constants
XMMATRIXworld = XMLoadFloat4x4(&mMountainWorld);
//
XMMATRIXview  = XMLoadFloat4x4(&mView);
XMMATRIXproj  = XMLoadFloat4x4(&mProj);
XMMATRIXViewProj = view*proj;

D3DX11_TECHNIQUE_DESC techDesc;
Effects::BasicFX->Tech->GetDesc(&techDesc );
for(UINT p = 0; p < techDesc.Passes; ++p)
{
//
// Draw the hills.
//
md3dContext->IASetVertexBuffers(0,1, &mMountainVB, &stride, &offset);
md3dContext->IASetIndexBuffer(mMountainIB,DXGI_FORMAT_R32_UINT, 0);

// Set per object constants.
XMMATRIXworld = XMLoadFloat4x4(&mMountainWorld);
XMMATRIXworldViewProj = world*view*proj;

Effects::BasicFX->WorldViewProj->SetMatrix(reinterpret_cast<float*>(&worldViewProj));

Effects::BasicFX->Tech->GetPassByIndex(p)->Apply(0,md3dContext);
md3dContext->DrawIndexed(mLandIndexCount,0, 0);

//
// Draw the waves.
//

md3dContext->RSSetState(mWireFrameRS);//运用线框,而且没有背面消隐

md3dContext->IASetVertexBuffers(0,1, &mWavesVB, &stride, &offset);
md3dContext->IASetIndexBuffer(mWavesIB,DXGI_FORMAT_R32_UINT, 0);

// Set per object constants.
world =XMLoadFloat4x4(&mWavesWorld);
worldViewProj= world*view*proj;

Effects::BasicFX->WorldViewProj->SetMatrix(reinterpret_cast<float*>(&worldViewProj));

Effects::BasicFX->Tech->GetPassByIndex(p)->Apply(0,md3dContext);
md3dContext->DrawIndexed(3*mWaves.TriangleCount(),0, 0);

md3dContext->RSSetState(0 ); //重新初始化光栅状态,以免渲染山峰时候运用了这个状态
}
HR(mSwapChain->Present(0, 0));
}



还有一些细节可参考代码,空注释//为对比上次山峰文件所新添加的
配套代码: http://download.csdn.net/detail/vwwyohann/9215157
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: