Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2014
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.18 KB | None | 0 0
  1. #include "Terrain.h"
  2.  
  3. Terrain::Terrain()
  4. {
  5.     m_device         = nullptr;
  6.     m_deviceContext  = nullptr;
  7.     m_VertexBuffer   = nullptr;
  8.     m_IndexBuffer    = nullptr;
  9. }
  10.  
  11. Terrain::Terrain( ID3D11Device* device, ID3D11DeviceContext* deviceContext )
  12. {
  13.     m_device            = device;
  14.     m_deviceContext     = deviceContext;
  15.     m_VertexBuffer   = nullptr;
  16.     m_IndexBuffer    = nullptr;
  17.  
  18.     LoadHeightMap();
  19.     Smooth();
  20.     BuildTerrainBuffers();
  21. }
  22.  
  23. Terrain::~Terrain()
  24. {
  25.     SAFE_RELEASE( m_VertexBuffer );
  26.     SAFE_RELEASE( m_IndexBuffer );
  27. }
  28.  
  29. void Terrain::LoadHeightMap()
  30. {
  31.  
  32.     m_MapInfo.Filename          = L"Map/map.raw";
  33.     m_MapInfo.HeightScale       = 25.0f;
  34.     m_MapInfo.HeightMapWidth    = 257; //640;
  35.     m_MapInfo.HeightMapHeight   = 257; //480;
  36.  
  37.     // A height for each vertex
  38.     std::vector<unsigned char> in ( m_MapInfo.HeightMapWidth * m_MapInfo.HeightMapHeight );
  39.  
  40.     // Open the file
  41.     std::ifstream inFile;
  42.     inFile.open( m_MapInfo.Filename.c_str(), std::ios_base::binary );
  43.  
  44.     if( inFile )
  45.     {
  46.         // Read the RAW bytes
  47.         inFile.read((char*)&in[0], (std::streamsize)in.size() );
  48.         inFile.close();
  49.     }
  50.  
  51.     // Copy data to a float array and scale it
  52.     m_HeightMap.resize(m_MapInfo.HeightMapHeight * m_MapInfo.HeightMapWidth, 0 );
  53.     for( UINT i = 0; i < m_MapInfo.HeightMapHeight * m_MapInfo.HeightMapWidth; ++i )
  54.     {
  55.         m_HeightMap[i] = (in[i] / 255.0f) * m_MapInfo.HeightScale;
  56.     }
  57. }
  58.  
  59. void Terrain::CreateGrid( float width, float depth, UINT m, UINT n, MeshData& meshData )
  60. {
  61.     UINT vertexCount = m*n;
  62.     UINT faceCount   = (m-1)*(n-1)*2;
  63.  
  64.  
  65.     //////////////////
  66.     // Create vertices
  67.     //////////////////
  68.  
  69.     float halfWidth = 0.5f * width;
  70.     float halfDepth = 0.5f * depth;
  71.  
  72.     float dx = width / (n-1);
  73.     float dz = depth / (m-1);
  74.  
  75.     float du = 1.0f / (n-1);
  76.     float dv = 1.0f / (m-1);
  77.  
  78.     meshData.Vertices.resize( vertexCount );
  79.     for( UINT i = 0; i < m; ++i )
  80.     {
  81.         float z = halfDepth - i*dz;
  82.         for( UINT j = 0; j < n; ++j )
  83.         {
  84.             float x = -halfWidth + j*dx;
  85.  
  86.             // Position
  87.             meshData.Vertices[i*n+j].pos[0] = x;
  88.             meshData.Vertices[i*n+j].pos[1] = m_HeightMap[i*n+j];
  89.             meshData.Vertices[i*n+j].pos[2] = z;
  90.  
  91.             // Normal (stämmer inte efter heightmapning)
  92.             meshData.Vertices[i*n+j].norm[0] = 0.0f;
  93.             meshData.Vertices[i*n+j].norm[1] = 1.0f;
  94.             meshData.Vertices[i*n+j].norm[2] = 0.0f;
  95.  
  96.             // UV
  97.             //meshData.Vertices[i*n+j].uv[0] = j*du;
  98.             //meshData.Vertices[i*n+j].uv[1] = i*dv;
  99.             meshData.Vertices[i*n+j].uv[0] = j*du; //0.0f;
  100.             meshData.Vertices[i*n+j].uv[1] = i*dv; //0.0f;
  101.         }
  102.     }
  103.  
  104.     /////////////////
  105.     // Create indices
  106.     /////////////////
  107.  
  108.     meshData.Indices.resize( faceCount * 3 ); // 3 indicies per face
  109.  
  110.     // Iterate over each quad and compute indices
  111.     UINT k = 0;
  112.     for( UINT i = 0; i < m-1; ++i )
  113.     {
  114.         for( UINT j = 0; j < n-1; ++j )
  115.         {
  116.             meshData.Indices[k] = i*n+j;
  117.             meshData.Indices[k+1] = i*n+j+1;
  118.             meshData.Indices[k+2] = (i+1)*n+j;
  119.             meshData.Indices[k+3] = (i+1)*n+j;
  120.             meshData.Indices[k+4] = i*n+j+1;
  121.             meshData.Indices[k+5] = (i+1)*n+j+1;
  122.  
  123.             k += 6; // next quad
  124.         }
  125.     }
  126.  
  127.     m_MeshData = meshData;
  128. }
  129.  
  130. void Terrain::BuildTerrainBuffers()
  131. {
  132.     MeshData grid;
  133.  
  134.     CreateGrid( (float)m_MapInfo.HeightMapWidth, (float)m_MapInfo.HeightMapHeight, 257, 257, grid );
  135.  
  136.     m_GridIndexCount = grid.Indices.size();
  137.  
  138.     D3D11_BUFFER_DESC vbd;
  139.     vbd.Usage           = D3D11_USAGE_IMMUTABLE;
  140.     vbd.ByteWidth       = sizeof(Vertex) * grid.Vertices.size();
  141.     vbd.BindFlags       = D3D11_BIND_VERTEX_BUFFER;
  142.     vbd.CPUAccessFlags  = 0;
  143.     vbd.MiscFlags       = 0;
  144.          
  145.     D3D11_SUBRESOURCE_DATA vinitData;
  146.     vinitData.pSysMem = &grid.Vertices[0];
  147.     m_device->CreateBuffer( &vbd, &vinitData, &m_VertexBuffer );
  148.  
  149.     // Pack the indices of all the meshes into one index buffer
  150.  
  151.     D3D11_BUFFER_DESC ibd;
  152.     ibd.Usage           = D3D11_USAGE_IMMUTABLE;
  153.     ibd.ByteWidth       = sizeof(UINT) * m_GridIndexCount;
  154.     ibd.BindFlags       = D3D11_BIND_INDEX_BUFFER;
  155.     ibd.CPUAccessFlags  = 0;
  156.     ibd.MiscFlags       = 0;
  157.  
  158.     D3D11_SUBRESOURCE_DATA iinitData;
  159.     iinitData.pSysMem = &grid.Indices[0];
  160.     m_device->CreateBuffer( &ibd, &iinitData, &m_IndexBuffer );
  161. }
  162.  
  163.  
  164.  
  165. bool Terrain::InBounds( int i, int j )
  166. {
  167.     return  i >= 0 && i < (int)m_MapInfo.HeightMapHeight &&
  168.             j >= 0 && j < (int)m_MapInfo.HeightMapWidth;
  169. }
  170.  
  171. float Terrain::Average( int i, int j )
  172. {
  173.     float avg = 0.0f;
  174.     float num = 0.0f;
  175.  
  176.     for( int m = i-1; m <= i+1; m++ )
  177.     {
  178.         for( int n = j-1; n <= j+1; n++ )
  179.         {
  180.             if( InBounds( m, n ) )
  181.             {
  182.                 avg += m_HeightMap[ m * m_MapInfo.HeightMapWidth + n ];
  183.                 num += 1.0f;
  184.             }
  185.         }
  186.     }
  187.  
  188.     return avg / num;
  189. }
  190.  
  191. void Terrain::Smooth()
  192. {
  193.     std::vector<float> dest( m_HeightMap.size() );
  194.  
  195.     for( UINT i = 0; i < m_MapInfo.HeightMapHeight; i++ )
  196.     {
  197.         for( UINT j = 0; j < m_MapInfo.HeightMapWidth; j++ )
  198.         {
  199.             dest[ i * m_MapInfo.HeightMapWidth + j ] = Average( i, j );
  200.         }
  201.     }
  202.  
  203.     m_HeightMap = dest;
  204. }
  205.  
  206.  
  207.  
  208. float Terrain::GetHeight( float x, float z )
  209. {
  210.     //Test1
  211.     //return m_HeightMap[ z * m_MapInfo.HeightMapHeight + x];
  212.     //return Average( m_HeightMap[z], m_HeightMap[x] ) + 10;
  213.    
  214.     //// Test 2
  215.     //float test =  0.0;
  216.     //if( InBounds( x, z ) )
  217.     //{
  218.     //  int iter =  (int)( x * 257 + z );
  219.     //  test = m_HeightMap[iter];
  220.     //}
  221.     //return test;
  222.  
  223.     // test 3
  224.     float y = 100.0f;
  225.     for( int i = 0; i < m_MeshData.Vertices.size(); i++ )
  226.     {
  227.         if( ((int)m_MeshData.Vertices[i].pos[0] == (int)x) && ((int)m_MeshData.Vertices[i].pos[2] == (int)z))
  228.         {
  229.             y = m_MeshData.Vertices[i].pos[1];
  230.             break;
  231.         }
  232.     }
  233.     return y;
  234. }
  235.  
  236. HRESULT Terrain::Draw()
  237. {
  238.     // Set topology
  239.     m_deviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
  240.  
  241.     // Set vertices
  242.     UINT32 vertexSize = sizeof( Vertex );
  243.     UINT32 offset = 0;
  244.     ID3D11Buffer* buffersToSet[] = { m_VertexBuffer };
  245.     m_deviceContext->IASetVertexBuffers( 0, 1, buffersToSet, &vertexSize, &offset );
  246.     m_deviceContext->IASetIndexBuffer( m_IndexBuffer, DXGI_FORMAT_R32_UINT, 0 );
  247.  
  248.  
  249.     m_deviceContext->DrawIndexed( m_GridIndexCount, 0, 0 );
  250.  
  251.     return S_OK;
  252. }
  253.  
  254. void Terrain::GetVertexBuffer( ID3D11Buffer*& buffer )
  255. {
  256.     buffer = m_VertexBuffer;
  257. }
  258.  
  259. void Terrain::GetIndexBuffer( ID3D11Buffer*& buffer )
  260. {
  261.     buffer = m_IndexBuffer;
  262. }
  263.  
  264. void Terrain::GetVertexAndIndexBuffer( ID3D11Buffer*& vertexBuffer, ID3D11Buffer*& indexBuffer )
  265. {
  266.     vertexBuffer = m_VertexBuffer;
  267.     indexBuffer  = m_IndexBuffer;
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement