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

承接上一次的渲染山峰,这次要使用动态缓冲(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


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值