2016-05-08 3 views
0

Я пытаюсь сделать ландшафт с помощью directx 11 и применить к нему карту высот. Я загружаю карту высот, а затем копирую ее в целочисленный вектор, а затем для каждой позиции вершины присваиваю Y-позицию этой вершины значению heightmap, но ландшафт полностью разрушен и искажен. Когда я удаляю вычисление по оси Y, я получаю плоскую сетку и никаких проблем.Рендеринг ландшафта в directx 11

bool cGrid::readRawFile(std::string fileName, int m, int n) 
{ 
    // A height for each vertex 
    std::vector<BYTE> in(m*n); 
    std::ifstream inFile(fileName.c_str(), std::ios_base::binary); 
    if (!inFile) 
     return false; 
    inFile.read(
     (char*)&in[0], // buffer 
     in.size());// number of bytes to read into buffer 
    inFile.close(); 
    // copy BYTE vector to int vector 
    m_heightmap.resize(n*m); 
    for (int i = 0; i < in.size(); i++) 
     m_heightmap[i] = in[i]; 
    return true; 
} 

for (size_t i = 0; i<m_Mesh.m_Vertices.size(); ++i) 
    { 
     XMFLOAT3 p = m_Mesh.m_Vertices[i].Position; 
     p.y = (float)m_heightmap[i]*0.5f; 
     m_Mesh.m_Vertices[i].Position = p; 
    } 

вот видео проблемы

https://www.youtube.com/watch?v=lnlIz3DjebM&feature=youtu.beenter image description here

enter image description here

HRESULT cGrid::CreateGrid(float width, float depth, UINT n, UINT m) 
{ 
    HRESULT hr; 
    int vertexCount = m*n; 
    UINT faceCount = (m - 1)*(n - 1) * 2; // each quad consists of two triangles 

    float halfWidth = 0.5f*width; 
    float halfDepth = 0.5f*depth; 

    // project the grid into xz plane 
    float dx = width/(n - 1); 
    float dz = depth/(m - 1); 

    float du = 1.0f/(n - 1); // texture co-ordinates 
    float dv = 1.0f/(m - 1); 


    m_Mesh.m_Vertices.resize(vertexCount); 

    // build the vertices of the grid, including the normals and the tangent, 
    //you can build then the bitanget by cross product for normal maps -_- 

    for (UINT i = 0; i < m; ++i) 
    { 
     float z = halfDepth - i*dz; // reset for the next cell 
     for (UINT j = 0; j < n; ++j) 
     { 
      float x = -halfWidth + j*dx; 
      float y = (float)m_heightmap[j + i*m]; 
      m_Mesh.m_Vertices[i*n + j].Position = XMFLOAT3(x, y, z); 
//   m_Mesh.m_Vertices[i*n + j].Normal = XMFLOAT3(0.0f, 1.0f, 0.0f); 
//   m_Mesh.m_Vertices[i*n + j].TangentU = XMFLOAT3(1.0f, 0.0f, 0.0f); 

      // Stretch texture over grid. 
      m_Mesh.m_Vertices[i*n + j].TextureCords.x = j*du; 
      m_Mesh.m_Vertices[i*n + j].TextureCords.y = i*dv; 
     } 
    } 

    m_Mesh.m_Indices.resize(faceCount * 3); // 3 indices per face 

    // Iterate over each quad and compute indices. 
    UINT k = 0; 
    for (UINT i = 0; i < m - 1; ++i) 
    { 
     for (UINT j = 0; j < n - 1; ++j) 
     { 
      m_Mesh.m_Indices[k] = i*n + j; 
      m_Mesh.m_Indices[k + 1] = i*n + j + 1; 
      m_Mesh.m_Indices[k + 2] = (i + 1)*n + j; 

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

      k += 6; // next quad 
     } 
    } 

    m_IndicesSize = m_Mesh.m_Indices.size(); 


    // Pack all the vertices into vertex buffer 
    D3D11_BUFFER_DESC vbd; 
    vbd.Usage = D3D11_USAGE_IMMUTABLE; 
    vbd.ByteWidth = sizeof(MeshVertex)* vertexCount; 
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER; 
    vbd.CPUAccessFlags = 0; 
    vbd.MiscFlags = 0; 
    D3D11_SUBRESOURCE_DATA vinitData; 
    vinitData.pSysMem = &(m_Mesh.m_Vertices[0]); 
    m_pGraphics->getDevice()->CreateBuffer(&vbd, &vinitData, &mVB); 

    // Pack the indices of all the meshes into one index buffer. 
    D3D11_BUFFER_DESC ibd; 
    ibd.Usage = D3D11_USAGE_DEFAULT; 
    ibd.ByteWidth = sizeof(UINT)* m_IndicesSize; 
    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER; 
    ibd.CPUAccessFlags = 0; 
    ibd.MiscFlags = 0; 
    D3D11_SUBRESOURCE_DATA iinitData; 
    iinitData.pSysMem = &m_Mesh.m_Indices[0]; 
    m_pGraphics->getDevice()->CreateBuffer(&ibd, &iinitData, &mIB); 

    // Create the constant buffer 
    ibd.Usage = D3D11_USAGE_DEFAULT; 
    ibd.ByteWidth = sizeof(ConstantBuffer); 
    ibd.BindFlags = D3D11_BIND_CONSTANT_BUFFER; 
    ibd.CPUAccessFlags = 0; 
    hr = m_pGraphics->getDevice()->CreateBuffer(&ibd, nullptr, &m_pConstantBuffer); 
    if (FAILED(hr)) 
     return hr; 

    return hr; 
} 
+0

Как внушения одно вы можете посмотреть на хорошие ссылки являются местность разрывая уроки, которые могут быть найдены в http://www.rastertek.com под DirectX 10 и DirectX 11 уроков местности в разделе «Исторические уроки». –

+0

(продолжение ...) Я также хотел бы добавить, что под серией 2 есть полная версия для учебника по ландшафту для DirectX 11. –

ответ

1

Я хотел бы использовать unsigned char вместо BYTE при определении std::vector<BYTE> in(m*n), поскольку она не является частью стандартная библиотека C, поэтому она зависит от системы.

использовать также бросание на этой линии

in.size());// number of bytes to read into buffer 

к фактическому типу параметра ifstream::read, который std::streamsize.

Как это:

(std::streamsize)in.size());// number of bytes to read into buffer 

Поскольку вы работаете с 8-битовой карты высот вы, возможно, следует не просто скопировать значение из RAW файла в карте высоты, как это:

for (int i = 0; i < in.size(); i++) 
    m_heightmap[i] = in[i]; 

Поскольку каждое значение высоты карты представлено 8-битовым целым, вы можете попробовать делить значение карты высоты, а также умножить ее на некоторый модификатор масштаба. Это сделает его более удобным, если вы хотите проверить свой путь к некоторым хорошим значениям. Чисто для визуальных целей ...

for (int i = 0; i < in.size(); i++) 
    m_heightmap[i] = (float)(in[i]/255.0f) * scaleModifier; 
+0

после применения ваших комментариев я просто получаю плоскую грань. Никакой ландшафт вообще –

+0

смотрите прикрепленную картинку в вышеуказанном сообщении. теперь я получаю такой поезд. просто несколько шипов –

+0

Я приложил карту высот –