zoukankan      html  css  js  c++  java
  • Directx11学习笔记【二十二】 用高度图实现地形

    本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html

      在前面我们曾经实现过简单的地形(Directx11学习笔记【十三】 实现一个简单地形),只不过原来使用一个固定的函数获得地形高度,这样跟真实的地形差距比较大。接下来让我们学习使用高度图来进行三维地形模拟。

    1.高度图

      高度图其实就是一组连续的数组,这个数组中的元素与地形网格中的顶点一一对应,且每一个元素都指定了地形网格的某个顶点的高度值。高度图最常用的使用灰度图实现,灰度图中亮度越大对应的地形高度越高。下面就是一幅灰度图:

      

      灰度图格式通常为.raw,google一下高度图保存图片改为raw格式就可以了。高度图每个元素通常只分配一个字节,即数值在0~255之间。但在实际使用的时候经常要对高度进行比例变换,因此需要将byte转为float,然后通过一个缩放系数进行缩放,这样就不必拘泥于0~255这么一个范围了。

    2.读取高度图

      读取高度图很简单,用二进制读取文件就好了。

     1 //读取高度图信息
     2 bool TerrainDemo::ReadRawFile(std::string filePath)
     3 {
     4     std::ifstream inFile;
     5     //二进制方式打开文件
     6     inFile.open(filePath.c_str(), std::ios::binary);
     7     //文件指针移动到末尾
     8     inFile.seekg(0, std::ios::end);
     9     //大小为当前缓冲区大小
    10     std::vector<BYTE> inData(inFile.tellg());
    11     //文件指针移动到开头
    12     inFile.seekg(std::ios::beg);
    13     //读取高度信息
    14     inFile.read((char*)&inData[0], inData.size());
    15     inFile.close();
    16 
    17     m_heightInfos.resize(inData.size());
    18     for (int i = 0; i < inData.size(); ++i)
    19     {
    20         m_heightInfos[i] = inData[i];
    21     }
    22 
    23     return true;
    24 }

    3.顶点和索引的计算

      顶点和索引的计算同Directx11学习笔记【十三】 实现一个简单地形类似,这里就不再详细说明了。不一样的由于采用了纹理光照渲染,所以需要得到法线,在计算索引的同时需要把顶点法线计算出来:

     1 //计算法线
     2 void TerrainDemo::ComputeNomal(Vertex& v1, Vertex& v2, Vertex& v3, XMFLOAT3& normal)
     3 {
     4     XMFLOAT3 f1(v2.pos.x - v1.pos.x, v2.pos.y - v1.pos.y, v2.pos.z - v1.pos.z);
     5     XMFLOAT3 f2(v3.pos.x - v1.pos.x, v3.pos.y - v1.pos.y, v3.pos.z - v1.pos.z);
     6     XMVECTOR vec1 = XMLoadFloat3(&f1);
     7     XMVECTOR vec2 = XMLoadFloat3(&f2);
     8     XMVECTOR temp = XMVector3Normalize(XMVector3Cross(vec1, vec2));
     9     XMStoreFloat3(&normal, temp);
    10 }

      计算顶点和索引:

     1 bool TerrainDemo::InitTerrain(float width, float height, UINT m, UINT n,float scale)
     2 {
     3     m_cellsPerRow = m;
     4     m_cellsPerCol = n;
     5     m_verticesPerRow = m + 1;
     6     m_verticesPerCol = n + 1;
     7     m_numsVertices = m_verticesPerRow*m_verticesPerCol;
     8     m_width = width;
     9     m_height = height;
    10     m_heightScale = scale;
    11 
    12     //得到缩放后的高度
    13     for (auto& item : m_heightInfos)
    14     {
    15         item *= m_heightScale;
    16     }
    17 
    18     //起始x z坐标
    19     float oX = -width * 0.5f;
    20     float oZ = height * 0.5f;
    21     //每一格坐标变化
    22     float dx = width / m;
    23     float dz = height / n;
    24 
    25     m_vertices.resize(m_numsVertices);
    26     //计算顶点
    27     for (UINT i = 0; i < m_verticesPerCol; ++i)
    28     {
    29         float tempZ = oZ - dz * i;
    30         for (UINT j = 0; j < m_verticesPerRow; ++j)
    31         {
    32             UINT index = m_verticesPerRow * i + j;
    33             m_vertices[index].pos.x = oX + dx * j;
    34             m_vertices[index].pos.y = m_heightInfos[index];
    35             m_vertices[index].pos.z = tempZ;
    36 
    37             m_vertices[index].tex = XMFLOAT2(dx*i, dx*j);
    38         }
    39     }
    40 
    41     //计算索引和法线
    42     //总格子数量:m * n
    43     //因此总索引数量: 6 * m * n
    44     UINT nIndices = m * n * 6;
    45     m_indices.resize(nIndices);
    46     UINT tmp = 0;
    47     for (UINT i = 0; i < n; ++i)
    48     {
    49         for (UINT j = 0; j < m; ++j)
    50         {
    51             m_indices[tmp] = i * m_verticesPerRow + j;
    52             m_indices[tmp + 1] = i * m_verticesPerRow + j + 1;
    53             m_indices[tmp + 2] = (i + 1) * m_verticesPerRow + j;
    54 
    55             //计算法线
    56             XMFLOAT3 temp;
    57             ComputeNomal(m_vertices[m_indices[tmp]], m_vertices[m_indices[tmp + 1]], 
    58                 m_vertices[m_indices[tmp + 2]], temp);
    59             m_vertices[m_indices[tmp]].normal = temp;
    60             m_vertices[m_indices[tmp + 1]].normal = temp;
    61             m_vertices[m_indices[tmp + 2]].normal = temp;
    62 
    63             m_indices[tmp + 3] = i * m_verticesPerRow + j + 1;
    64             m_indices[tmp + 4] = (i + 1) * m_verticesPerRow + j + 1;
    65             m_indices[tmp + 5] = (i + 1) * m_verticesPerRow + j;
    66 
    67             ComputeNomal(m_vertices[m_indices[tmp + 3]], m_vertices[m_indices[tmp + 4]],
    68                 m_vertices[m_indices[tmp + 5]], temp);
    69             m_vertices[m_indices[tmp + 3]].normal = temp;
    70             m_vertices[m_indices[tmp + 4]].normal = temp;
    71             m_vertices[m_indices[tmp + 5]].normal = temp;
    72 
    73             tmp += 6;
    74         }
    75     }
    76 
    77     return true;
    78 }

    4.效果截图

    5.详细源码

    TerrainDemo.h

     1 #pragma once
     2 #include <string>
     3 #include <vector>
     4 #include "Dx11Base.h"
     5 #include "Camera.h"
     6 #include "Input.h"
     7 #include "Utility.h"
     8 #include "LightHelper.h"
     9 
    10 class TerrainDemo : public Dx11Base
    11 {
    12 public:
    13     TerrainDemo(HINSTANCE hInst, std::wstring title = L"TerrainDemo", int width = 800, int height = 640);
    14     ~TerrainDemo();
    15 
    16     //顶点结构 位置、法线、uv坐标
    17     struct Vertex
    18     {
    19         Vertex() {}
    20         Vertex(const XMFLOAT3 _pos, XMFLOAT3 _normal,  XMFLOAT2 _tex) :
    21             pos(_pos), normal(_normal),  tex(_tex) {}
    22 
    23         XMFLOAT3        pos;
    24         XMFLOAT3        normal;
    25         XMFLOAT2        tex;
    26     };
    27 
    28     bool Init() override;
    29     void Update(float dt);
    30     void Render();
    31 
    32     bool OnResize() override;
    33 private:
    34     bool BuildBuffers();
    35     bool BuildSRVs();
    36     bool BuildInputLayouts();
    37     void UpdateCamera(float dt);
    38 private:
    39     bool ReadRawFile(std::string filePath);                                        //从高度图读取高度信息
    40     bool InitTerrain(float width, float height, UINT m, UINT n, float scale);    //初始化地形
    41     void ComputeNomal(Vertex& v1, Vertex& v2, Vertex& v3, XMFLOAT3& normal);        //计算法线
    42 private:
    43     std::vector<float>    m_heightInfos;        //高度图高度信息
    44     int        m_cellsPerRow;                    //每行单元格数
    45     int        m_cellsPerCol;                    //每列单元格数
    46     int        m_verticesPerRow;                //每行顶点数
    47     int        m_verticesPerCol;                //每列顶点数
    48     int        m_numsVertices;                    //顶点总数
    49     float    m_width;                        //地形宽度
    50     float    m_height;                        //地形高度
    51     float    m_heightScale;                    //高度缩放系数
    52 
    53     std::vector<Vertex>        m_vertices;        //顶点集合
    54     std::vector<UINT>          m_indices;        //索引集合
    55 
    56 private:
    57     ID3D11Buffer*                m_pVertexBuffer;
    58     ID3D11Buffer*                m_pIndexBuffer;
    59     ID3D11InputLayout*           m_pInputLayout;
    60     ID3D11ShaderResourceView*    m_pSRVTerrain;
    61 
    62     Lights::DirectionalLight     m_dirLights[3];            //3个平行光源
    63     Lights::Material             m_materialTerrain;        //材质
    64 
    65     Camera                        m_camera;
    66 
    67     XMFLOAT4X4                    m_world;                    //世界变换矩阵
    68     XMFLOAT4X4                    m_worldViewProj;            //世界视角投影矩阵
    69     XMFLOAT4X4                    m_worldInvTranspose;        //世界逆矩阵的转置,用于法线变换
    70     XMFLOAT4X4                    m_texTrans;                //纹理坐标变换矩阵    
    71 
    72     POINT                m_lastMousePos;        
    73 };

    TerrainDemo.cpp

      1 #include <fstream>
      2 #include <memory>
      3 #include "TerrainDemo.h"
      4 #include "Utility.h"
      5 #include "WICTextureLoader.h"
      6 #include "d3dx11effect.h"
      7 #include "Effects.h"
      8 
      9 TerrainDemo::TerrainDemo(HINSTANCE hInst, std::wstring title, int width, int height)
     10     :Dx11Base(hInst, title, width, height)
     11 {
     12     //"三点式"照明
     13     //主光源
     14     m_dirLights[0].ambient = XMFLOAT4(0.3f, 0.3f, 0.3f, 1.0f);
     15     m_dirLights[0].diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
     16     m_dirLights[0].specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
     17     m_dirLights[0].direction = XMFLOAT3(0.57735f, -0.57735f, 0.57735f);
     18     //侧光源
     19     m_dirLights[1].ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
     20     m_dirLights[1].diffuse = XMFLOAT4(0.20f, 0.20f, 0.20f, 1.0f);
     21     m_dirLights[1].specular = XMFLOAT4(0.25f, 0.25f, 0.25f, 1.0f);
     22     m_dirLights[1].direction = XMFLOAT3(-0.57735f, -0.57735f, 0.57735f);
     23     //背光源
     24     m_dirLights[2].ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
     25     m_dirLights[2].diffuse = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
     26     m_dirLights[2].specular = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
     27     m_dirLights[2].direction = XMFLOAT3(0.0f, -0.707f, -0.707f);
     28 
     29     //材质
     30     m_materialTerrain.ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
     31     m_materialTerrain.diffuse = XMFLOAT4(1.f, 1.f, 1.f, 1.0f);
     32     m_materialTerrain.specular = XMFLOAT4(0.3f, 0.3f, 0.3f, 16.0f);
     33 
     34     //设置相机
     35     m_lastMousePos = { 0,0 };
     36     XMVECTOR Eye = XMVectorSet(0.0f, 50.0f, 0.1f, 0.0f);
     37     XMVECTOR At = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
     38     XMVECTOR Up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
     39     m_camera.LookAtXM(Eye, At, Up);
     40     //设置投影矩阵
     41     m_camera.SetLens(XM_PIDIV4, AspectRatio(), 0.1f, 1000.f);
     42 
     43     //初始化世界矩阵 逆转置矩阵 及纹理坐标矩阵
     44     //这些每一帧不改变
     45     XMMATRIX I = XMMatrixIdentity();
     46     XMStoreFloat4x4(&m_world, I);
     47     XMVECTOR det = XMMatrixDeterminant(I);
     48     XMMATRIX worldInvTranspose = XMMatrixTranspose(XMMatrixInverse(&det,I));
     49     XMStoreFloat4x4(&m_worldInvTranspose, worldInvTranspose);
     50     XMStoreFloat4x4(&m_texTrans, I);
     51 }
     52 
     53 TerrainDemo::~TerrainDemo()
     54 {
     55     SafeRelease(m_pVertexBuffer);
     56     SafeRelease(m_pIndexBuffer);
     57     SafeRelease(m_pInputLayout);
     58     SafeRelease(m_pSRVTerrain);
     59     Effects::ReleaseAll();
     60 }
     61 
     62 bool TerrainDemo::Init()
     63 {
     64     if (!Dx11Base::Init())
     65         return false;
     66     if (!Effects::InitAll(m_pd3dDevice))
     67         return false;
     68     if (!ReadRawFile("Texture\heightmap.raw"))
     69     return false;
     70     if (!InitTerrain(500, 500, 255, 255, 0.2f))
     71         return false;
     72     if (!BuildBuffers())
     73         return false;
     74     if (!BuildSRVs())
     75         return false;
     76     if (!BuildInputLayouts())
     77         return false;
     78 }
     79 
     80 void TerrainDemo::Update(float dt)
     81 {
     82     UpdateCamera(dt);
     83     XMMATRIX world = XMLoadFloat4x4(&m_world);
     84     XMMATRIX worldViewProj = world * m_camera.GetViewProj();
     85     XMStoreFloat4x4(&m_worldViewProj, worldViewProj);
     86 
     87     //设置灯光
     88     Effects::ms_pBasicEffect->m_pFxDirLights->SetRawValue(&m_dirLights, 0,
     89         3 * sizeof(Lights::DirectionalLight));
     90     Effects::ms_pBasicEffect->m_pFxEyePos->SetRawValue(&m_camera.GetPosition(), 0, 
     91         sizeof(m_camera.GetPosition()));
     92 }
     93 
     94 void TerrainDemo::Render()
     95 {
     96     m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, Colors::Silver);
     97     m_pImmediateContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
     98     m_pImmediateContext->IASetInputLayout(m_pInputLayout);
     99 
    100     UINT stride = sizeof(Vertex);
    101     UINT offset = 0;
    102     m_pImmediateContext->IASetVertexBuffers(0, 1, &m_pVertexBuffer, &stride, &offset);
    103     m_pImmediateContext->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R32_UINT, offset);
    104     m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    105 
    106     D3DX11_TECHNIQUE_DESC desc;
    107     ID3DX11EffectTechnique* tech = Effects::ms_pBasicEffect->m_pFxLight3TexTech;
    108     tech->GetDesc(&desc);
    109 
    110     for (UINT i = 0; i < desc.Passes; ++i)
    111     {
    112         //设置着色器变量
    113         Effects::ms_pBasicEffect->m_pFxWorld->SetMatrix(reinterpret_cast<const float*>(&m_world));
    114         Effects::ms_pBasicEffect->m_pFxWorldViewProj->SetMatrix(reinterpret_cast<const float*>(
    115             &m_worldViewProj));
    116         Effects::ms_pBasicEffect->m_pFxWorldInvTranspose->SetMatrix(reinterpret_cast<const float*>(
    117             &m_worldInvTranspose));
    118         Effects::ms_pBasicEffect->m_pFxTexTrans->SetMatrix(reinterpret_cast<const float*>(
    119             &m_texTrans));
    120         Effects::ms_pBasicEffect->m_pFxMaterial->SetRawValue(&m_materialTerrain, 0, sizeof(m_materialTerrain));
    121         Effects::ms_pBasicEffect->m_pFxSR->SetResource(m_pSRVTerrain);
    122         tech->GetPassByIndex(i)->Apply(0, m_pImmediateContext);
    123         m_pImmediateContext->DrawIndexed(m_indices.size(), 0, 0);
    124     }
    125 
    126     m_pSwapChain->Present(0, 0);
    127 }
    128 
    129 bool TerrainDemo::OnResize()
    130 {
    131     if (!Dx11Base::OnResize())
    132         return false;
    133     //更新camera参数
    134     m_camera.SetLens(XM_PIDIV4, AspectRatio(), 1.f, 1000.f);
    135 
    136     return true;
    137 }
    138 
    139 bool TerrainDemo::BuildBuffers()
    140 {
    141     //创建顶点缓冲区
    142     D3D11_BUFFER_DESC vertexDesc;
    143     ZeroMemory(&vertexDesc, sizeof(vertexDesc));
    144     vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    145     vertexDesc.ByteWidth = sizeof(Vertex) * m_numsVertices;
    146     vertexDesc.Usage = D3D11_USAGE_IMMUTABLE;
    147 
    148     D3D11_SUBRESOURCE_DATA vertexData;
    149     vertexData.pSysMem = &m_vertices[0];
    150     vertexData.SysMemPitch = 0;
    151     vertexData.SysMemSlicePitch = 0;
    152     if (FAILED(m_pd3dDevice->CreateBuffer(&vertexDesc, &vertexData, &m_pVertexBuffer)))
    153     {
    154         MessageBox(nullptr, L"Create Vertex Buffer failed!", L"Error", MB_OK);
    155         return false;
    156     }
    157 
    158     //创建索引缓冲区
    159     D3D11_BUFFER_DESC indexDesc;
    160     ZeroMemory(&indexDesc, sizeof(indexDesc));
    161     indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    162     indexDesc.ByteWidth = sizeof(UINT) * m_indices.size();
    163     indexDesc.Usage = D3D11_USAGE_IMMUTABLE;
    164 
    165     D3D11_SUBRESOURCE_DATA indexData;
    166     indexData.pSysMem = &m_indices[0];
    167     indexData.SysMemPitch = 0;
    168     indexData.SysMemSlicePitch = 0;
    169     if (FAILED(m_pd3dDevice->CreateBuffer(&indexDesc, &indexData, &m_pIndexBuffer)))
    170     {
    171         MessageBox(nullptr, L"Create Index Buffer failed!", L"Error", MB_OK);
    172         return false;
    173     }
    174 
    175     return true;
    176 }
    177 
    178 bool TerrainDemo::BuildSRVs()
    179 {
    180     if (FAILED(CreateWICTextureFromFile(m_pd3dDevice, L"Texture\desert.bmp", nullptr, &m_pSRVTerrain)))
    181     {
    182         MessageBox(nullptr, L"create texture failed!", L"error", MB_OK);
    183         return false;
    184     }
    185     return true;
    186 }
    187 
    188 bool TerrainDemo::BuildInputLayouts()
    189 {
    190     D3D11_INPUT_ELEMENT_DESC layout[] = 
    191     {
    192         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    193         { "NORMAL",   0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12,D3D11_INPUT_PER_VERTEX_DATA, 0 },
    194         { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT,     0, 24,D3D11_INPUT_PER_VERTEX_DATA, 0 }
    195     };
    196 
    197     UINT numLayoutElements = ARRAYSIZE(layout);
    198     D3DX11_PASS_DESC passDesc;
    199     Effects::ms_pBasicEffect->m_pFxLight3TexTech->GetPassByIndex(0)->GetDesc(&passDesc);
    200     if (FAILED(m_pd3dDevice->CreateInputLayout(layout, numLayoutElements, passDesc.pIAInputSignature,
    201         passDesc.IAInputSignatureSize, &m_pInputLayout)))
    202     {
    203         MessageBox(nullptr, L"create inputLayout failed!", L"error", MB_OK);
    204         return false;
    205     }
    206     return true;
    207 }
    208 
    209 void TerrainDemo::UpdateCamera(float dt)
    210 {
    211     //前后左右行走
    212     if (Input::GetInstance()->IsKeyDown('A'))
    213     {
    214         m_camera.Strafe(-60.f*dt);
    215     }
    216     else if (Input::GetInstance()->IsKeyDown('D'))
    217     {
    218         m_camera.Strafe(60.f*dt);
    219     }
    220     if (Input::GetInstance()->IsKeyDown('W'))
    221     {
    222         m_camera.Walk(60.f*dt);
    223     }
    224     else if (Input::GetInstance()->IsKeyDown('S'))
    225     {
    226         m_camera.Walk(-60.f*dt);
    227     }
    228 
    229 
    230     if (Input::GetInstance()->IsMouseMove())
    231     {
    232         float mouseX = Input::GetInstance()->GetMouseX();
    233         float mouseY = Input::GetInstance()->GetMouseY();
    234         if (Input::GetInstance()->IsLMouseDown())
    235         {
    236             float dx = XMConvertToRadians(0.25f*(mouseX - m_lastMousePos.x));
    237             float dy = XMConvertToRadians(0.25f*(mouseY - m_lastMousePos.y));
    238 
    239             OutputDebugString(L"left btn click");
    240             m_camera.Pitch(dy);
    241             m_camera.RotateY(dx);
    242         }
    243         m_lastMousePos.x = mouseX;
    244         m_lastMousePos.y = mouseY;
    245     }
    246 
    247     m_camera.UpdateViewMatrix();
    248 }
    249 
    250 //读取高度图信息
    251 bool TerrainDemo::ReadRawFile(std::string filePath)
    252 {
    253     std::ifstream inFile;
    254     //二进制方式打开文件
    255     inFile.open(filePath.c_str(), std::ios::binary);
    256     //文件指针移动到末尾
    257     inFile.seekg(0, std::ios::end);
    258     //大小为当前缓冲区大小
    259     std::vector<BYTE> inData(inFile.tellg());
    260     //文件指针移动到开头
    261     inFile.seekg(std::ios::beg);
    262     //读取高度信息
    263     inFile.read((char*)&inData[0], inData.size());
    264     inFile.close();
    265 
    266     m_heightInfos.resize(inData.size());
    267     for (int i = 0; i < inData.size(); ++i)
    268     {
    269         m_heightInfos[i] = inData[i];
    270     }
    271 
    272     return true;
    273 }
    274 
    275 bool TerrainDemo::InitTerrain(float width, float height, UINT m, UINT n,float scale)
    276 {
    277     m_cellsPerRow = m;
    278     m_cellsPerCol = n;
    279     m_verticesPerRow = m + 1;
    280     m_verticesPerCol = n + 1;
    281     m_numsVertices = m_verticesPerRow*m_verticesPerCol;
    282     m_width = width;
    283     m_height = height;
    284     m_heightScale = scale;
    285 
    286     //得到缩放后的高度
    287     for (auto& item : m_heightInfos)
    288     {
    289         item *= m_heightScale;
    290     }
    291 
    292     //起始x z坐标
    293     float oX = -width * 0.5f;
    294     float oZ = height * 0.5f;
    295     //每一格坐标变化
    296     float dx = width / m;
    297     float dz = height / n;
    298 
    299     m_vertices.resize(m_numsVertices);
    300     //计算顶点
    301     for (UINT i = 0; i < m_verticesPerCol; ++i)
    302     {
    303         float tempZ = oZ - dz * i;
    304         for (UINT j = 0; j < m_verticesPerRow; ++j)
    305         {
    306             UINT index = m_verticesPerRow * i + j;
    307             m_vertices[index].pos.x = oX + dx * j;
    308             m_vertices[index].pos.y = m_heightInfos[index];
    309             m_vertices[index].pos.z = tempZ;
    310 
    311             m_vertices[index].tex = XMFLOAT2(dx*i, dx*j);
    312         }
    313     }
    314 
    315     //计算索引和法线
    316     //总格子数量:m * n
    317     //因此总索引数量: 6 * m * n
    318     UINT nIndices = m * n * 6;
    319     m_indices.resize(nIndices);
    320     UINT tmp = 0;
    321     for (UINT i = 0; i < n; ++i)
    322     {
    323         for (UINT j = 0; j < m; ++j)
    324         {
    325             m_indices[tmp] = i * m_verticesPerRow + j;
    326             m_indices[tmp + 1] = i * m_verticesPerRow + j + 1;
    327             m_indices[tmp + 2] = (i + 1) * m_verticesPerRow + j;
    328 
    329             //计算法线
    330             XMFLOAT3 temp;
    331             ComputeNomal(m_vertices[m_indices[tmp]], m_vertices[m_indices[tmp + 1]], 
    332                 m_vertices[m_indices[tmp + 2]], temp);
    333             m_vertices[m_indices[tmp]].normal = temp;
    334             m_vertices[m_indices[tmp + 1]].normal = temp;
    335             m_vertices[m_indices[tmp + 2]].normal = temp;
    336 
    337             m_indices[tmp + 3] = i * m_verticesPerRow + j + 1;
    338             m_indices[tmp + 4] = (i + 1) * m_verticesPerRow + j + 1;
    339             m_indices[tmp + 5] = (i + 1) * m_verticesPerRow + j;
    340 
    341             ComputeNomal(m_vertices[m_indices[tmp + 3]], m_vertices[m_indices[tmp + 4]],
    342                 m_vertices[m_indices[tmp + 5]], temp);
    343             m_vertices[m_indices[tmp + 3]].normal = temp;
    344             m_vertices[m_indices[tmp + 4]].normal = temp;
    345             m_vertices[m_indices[tmp + 5]].normal = temp;
    346 
    347             tmp += 6;
    348         }
    349     }
    350 
    351     return true;
    352 }
    353 
    354 //计算法线
    355 void TerrainDemo::ComputeNomal(Vertex& v1, Vertex& v2, Vertex& v3, XMFLOAT3& normal)
    356 {
    357     XMFLOAT3 f1(v2.pos.x - v1.pos.x, v2.pos.y - v1.pos.y, v2.pos.z - v1.pos.z);
    358     XMFLOAT3 f2(v3.pos.x - v1.pos.x, v3.pos.y - v1.pos.y, v3.pos.z - v1.pos.z);
    359     XMVECTOR vec1 = XMLoadFloat3(&f1);
    360     XMVECTOR vec2 = XMLoadFloat3(&f2);
    361     XMVECTOR temp = XMVector3Normalize(XMVector3Cross(vec1, vec2));
    362     XMStoreFloat3(&normal, temp);
    363 }
    364 
    365 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow)
    366 {
    367     std::shared_ptr<Dx11Base> bd(new TerrainDemo(hInstance));
    368     if (!bd->Init())
    369         return -1;
    370     return bd->Run();
    371 }
  • 相关阅读:
    Microsoft SQL Server 自定义函数整理大全 [转]
    eclipse将android项目生成apk并且给apk签名
    Android实现对图片的缩放、剪切、旋转、存储
    Android 之 ProgressDialog用法介绍
    Android中Path类的lineTo方法和quadTo方法画线的区别
    Android仿微信二维码扫描
    Android中Bitmap,byte[],Drawable相互转化
    hibernate基础之无法自动创建表总结
    Android获取短信验证码
    Android之常见问题集锦Ⅰ
  • 原文地址:https://www.cnblogs.com/zhangbaochong/p/5827714.html
Copyright © 2011-2022 走看看