zoukankan      html  css  js  c++  java
  • Directx11教程(19) 画一个简单的地形

          通常我们在xz平面定义一个二维的网格,然后y的值根据一定的函数计算得到,比如正弦、余弦函数的组合等等,可以得到一个看似不错的地形或者水面的效果。 在本教程中我们修改ModelClass.h和ModelClass.cpp,得到一个近似的地形。

       

        在本章代码中,我们定义300*300=90000个顶点,共(300-1)(300-1)*2个三角形,每个网格的大小都为1.

        我们得到y值的函数为:

    float ModelClass::getHeight(float x, float z) const
        {
        return 0.3f*( z*sinf(0.1f*x) + x*cosf(0.1f*z) );
        }

        

        

    ModelClass.h主要代码如下:

    #pragma once

    #include <d3d11.h>
    #include <d3dx10math.h>
    #include "common.h"

    class ModelClass
        {

            int GetIndexCount();
           //根据顶点的x值和z值,计算出y值
            float getHeight(float x, float z)const;

        private:
            bool InitializeBuffers(ID3D11Device*, int, int, float);
            void ShutdownBuffers();
            void RenderBuffers(ID3D11DeviceContext*);
            //顶点缓冲和顶点索引缓冲
            ID3D11Buffer *m_vertexBuffer, *m_indexBuffer;
            int m_vertexCount, m_indexCount;

        };

        ModelClass.cpp主要代码如下:

    bool ModelClass::Initialize(ID3D11Device* device, int m, int n, float dx)
        {
        bool result;


        // 初始化顶点缓冲和顶点索引缓冲.
        result = InitializeBuffers(device, m, n, dx);
        if(!result)
            {
            return false;
            }

        return true;
        }

    void ModelClass::Shutdown()
        {
        // 释放顶点和索引缓冲.
        ShutdownBuffers();

        return;
        }

    float ModelClass::getHeight(float x, float z) const
        {
        return 0.3f*( z*sinf(0.1f*x) + x*cosf(0.1f*z) );
        }

    void ModelClass::Render(ID3D11DeviceContext* deviceContext)
        {
        // 把顶点和索引缓冲放入图形管线,准备渲染.
        RenderBuffers(deviceContext);

        return;
        }

    int ModelClass::GetIndexCount()
        {
       //返回索引顶点计数
        return m_indexCount;
        }

    bool ModelClass::InitializeBuffers(ID3D11Device* device, int m, int n, float dx)
        {
        VertexType* vertices;
        unsigned long* indices;
        D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc;
        D3D11_SUBRESOURCE_DATA vertexData, indexData;
        HRESULT result;


        //计算得到顶点和索引顶点数目
        //首先得到三角形的数目,然后乘以3就是顶点索引数目

        m_vertexCount = m*n;
        m_indexCount    = (m-1)*(n-1)*2*3;

        // 创建顶点临时缓冲.
        vertices = new VertexType[m_vertexCount];
        if(!vertices)
            {
            return false;
            }

        float halfWidth = (n-1)*dx*0.5f;
        float halfDepth = (m-1)*dx*0.5f;

        for(int i = 0; i < m; ++i)
            {
            float z = halfDepth - i*dx;
            for(int j = 0; j < n; ++j)
                {
                float x = -halfWidth + j*dx;

                // 计算得到z值.
                float y = getHeight(x,z);

                vertices[i*n+j].position = D3DXVECTOR3(x, y, z);

                // 根据高度来定义颜色
                if( y < -10.0f )
                    vertices[i*n+j].color = BEACH_SAND;
                else if( y < 5.0f )
                    vertices[i*n+j].color = LIGHT_YELLOW_GREEN;
                else if( y < 12.0f )
                    vertices[i*n+j].color = DARK_YELLOW_GREEN;
                else if( y < 20.0f )
                    vertices[i*n+j].color = DARKBROWN;
                else
                    vertices[i*n+j].color = WHITE;
                }
            }

        // 创建索引缓冲.
        indices = new unsigned long[m_indexCount];
        if(!indices)
            {
            return false;
            }

       // 迭代每个grid,计算得出索引.
        int k = 0;
        for(int i = 0; i < m-1; ++i)
            {
            for(int 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; //下一个grid
                }
            }

        // 设置顶点缓冲描述

        return true;
        }

    还要修改一下GraphicsClass.cpp中初始化ModelClass的代码:

    // 初始化模型对象.
    result = m_Model->Initialize(m_D3D->GetDevice(), 300, 300, 1.0f);
    if(!result)
        {
        MessageBox(hwnd, L"Could not initialize the model object.", L"Error", MB_OK);
        return false;
        }

    运行程序后,效果如下,我们还可以用a/s/d/w键来移动摄像机看看地形的效果。

    image

    我们还可以修改D3DClass.cpp中,渲染状态Fillmode设置,修改为线框模式后的效果如下:

    image

    D3DClass.cpp中修改代码如下:

    // 设置光栅化描述,指定多边形如何被渲染.
    rasterDesc.AntialiasedLineEnable = false;
    rasterDesc.CullMode = D3D11_CULL_BACK;
    rasterDesc.DepthBias = 0;
    rasterDesc.DepthBiasClamp = 0.0f;
    rasterDesc.DepthClipEnable = true;
    rasterDesc.FillMode = D3D11_FILL_WIREFRAME;
    rasterDesc.FrontCounterClockwise = false;
    rasterDesc.MultisampleEnable = false;
    rasterDesc.ScissorEnable = false;
    rasterDesc.SlopeScaledDepthBias = 0.0f;

     

    完整的代码请参考:

    工程文件myTutorialD3D11_13

    代码下载:

    https://files.cnblogs.com/mikewolf2002/myTutorialD3D11.zip

  • 相关阅读:
    onkeyup事件
    asp.net学习视频资料地址链接
    企业站新闻信息的后台功能开发心得(1)
    js实现切换导航
    jquery实现上拉加载更多
    css设置input框没有边框,选中时取消背景色
    使用js修改url地址参数
    ubantu 修改hosts文件
    git的使用
    ubantu 16.04 菜单栏的位置变换
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/2416405.html
Copyright © 2011-2022 走看看