I'm trying to make a grid of triangles for a terrain generation project in DirectX 11, but when it gets drawn to the screen it draws in all three axis, instead of just the x and z.
I do get the correct amount of vertices and indices, but in the vector of indices it has a size of 972, the first 486 of them are set to 0 instead of the actual values.
I was wondering if I could get some clarification on whether I was setting the vertex/index buffers correctly.
Below is an example for a 10 by 10 grid.
GenerateTerrain method
void Application::GenerateTerrain(int vertRows, int vertCols)
{
HRESULT hr;
// ------------------------------------- Create Vertex Buffer --------------------------------------
totalCellRows = vertRows - 1;
totalCellCols = vertCols - 1;
// Width and Total Width
float dx = 1.0f;
float totalWidth = totalCellCols * dx;
// Depth and Total Depth
float dz = 1.0f;
float totalDepth = totalCellRows * dz;
// X and Z Offsets
float xOffset = -totalWidth * 0.5f;
float zOffset = totalDepth * 0.5f;
totalVertices = vertRows * vertCols;
totalTriangles = (totalCellRows * totalCellCols) * 2;
totalIndices = totalTriangles * 3;
terrainVertices = new SimpleVertex[totalVertices];
// Array Version
int k = 0;
for (int i = 0; i < vertRows; i++)
{
for (int j = 0; j < vertCols; j++)
{
SimpleVertex newVertex;
terrainVertices[k].PosL = XMFLOAT3(j * dx + xOffset, 0.0f, -(i * dz) + zOffset);
terrainVertices[k].NormL = XMFLOAT3(0.0f, 1.0f, 0.0f);
terrainVertices[k].Tex = XMFLOAT2(0.0f, 0.0f);
k++;
}
}
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(SimpleVertex) * totalVertices;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = &terrainVertices;
hr = _pd3dDevice->CreateBuffer(&bd, &InitData, &_pGridVertexBuffer);
// ------------------------------------- Create Index Buffer --------------------------------------
// Vector Version
indices.resize(totalIndices);
for (WORD i = 0; i < (WORD)vertRows - 1; i++)
{
for (WORD j = 0; j < (WORD)vertCols - 1; j++)
{
indices.push_back(i * vertCols + j);
indices.push_back(i * vertCols + (j + 1));
indices.push_back((i + 1) * vertCols + j);
indices.push_back((i + 1) * vertCols + j);
indices.push_back((i * vertCols + (j + 1)));
indices.push_back((i + 1) * vertCols + (j + 1));
}
}
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(WORD) * totalIndices;
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
ZeroMemory(&InitData, sizeof(InitData));
InitData.pSysMem = &indices;
hr = _pd3dDevice->CreateBuffer(&bd, &InitData, &_pGridIndexBuffer);
}
indices.resize(totalIndices); <----- !!!!!!ERROR!!!! u mean reserve
for (WORD i = 0; i < (WORD)vertRows - 1; i++)
{
for (WORD j = 0; j < (WORD)vertCols - 1; j++)
{
indices.push_back(i * vertCols + j);
indices.push_back(i * vertCols + (j + 1));
indices.push_back((i + 1) * vertCols + j);
indices.push_back((i + 1) * vertCols + j);
indices.push_back((i * vertCols + (j + 1)));
indices.push_back((i + 1) * vertCols + (j + 1));
}
}
You write resize, so the vector is resized, and then you add more indices with pushback. I think you want to reserve memory "reserve" and add them with pushback.
Also i would recommend to use a pointer to the first value, instead of a pointer to the vector
you:
InitData.pSysMem = &indices;
better:
InitData.pSysMem = &indices[0];
Buffer initialization seems to be ok.
Good luck
Related
I have had a terrain generation algorithm for a while and have had a lot of success with it. However when I decided to start work on Level of Detail (Has not been implemented), I started to notice that my terrain would begin to draw underneath itself as it got larger (when it gets to around 257 by 257). I'm not too sure why it starts to do this however I have a feeling its either due to me converting the 2d vector into a 1d or when i generate my indices but i am not 100 percent. If someone could have a look that would be amazing
Terrain at 100 by 100
Terrain at 1000 by 1000
Code used to Generate Vertices
void TerrainObject::LoadFlatTerrain()
{
float F_terrainDimentions = terrainDimentions; //used to stop integer division
m_vertexCount = terrainDimentions * terrainDimentions; //terrainDimentions = the width and depth of the terrain
float halfWidth = 0.5f * F_terrainDimentions;
float halfDepth = 0.5f * F_terrainDimentions;
// project the grid into xz plane
float dx = F_terrainDimentions / (F_terrainDimentions - 1);
float dz = F_terrainDimentions / (F_terrainDimentions - 1);
float du = 1.0f / (F_terrainDimentions - 1); // texture co-ordinates
float dv = 1.0f / (F_terrainDimentions - 1);
//Resizes Vectors for Vertices
vertices.resize(m_vertexCount);
verts2d.resize(terrainDimentions);
for (int i = 0; i < verts2d.size(); i++)
{
verts2d[i].resize(terrainDimentions);
}
//Generates Vertices for 2d array
for (int i = 0; i < terrainDimentions; i++)
{
float z = halfDepth - i * dz;
for (int j = 0; j < terrainDimentions; j++)
{
float x = -halfWidth + j * dx;
float y = 0;
verts2d[i][j].Position.x = x;
verts2d[i][j].Position.y = y;
verts2d[i][j].Position.z = z;
verts2d[i][j].Normal = XMFLOAT3(0.0f, 1.0f, 0.0f);
verts2d[i][j].Tangent = XMFLOAT3(1.0f, 0.0f, 0.0f);
verts2d[i][j].TexCoord.x = j * du;
verts2d[i][j].TexCoord.y = i * dv;
}
}
//Converts to 1d array
for (int i = 0; i < terrainDimentions; i++)
{
for (int j = 0; j < terrainDimentions; j++)
{
vertices[i * terrainDimentions + j].Position = verts2d[i][j].Position;
vertices[i * terrainDimentions + j].TexCoord = verts2d[i][j].TexCoord;
vertices[i * terrainDimentions + j].Normal = verts2d[i][j].Normal;
vertices[i * terrainDimentions + j].Tangent = verts2d[i][j].Tangent;
}
}
// Create vertex buffer
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(ComplexVertex) * m_vertexCount;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = &(vertices[0]);
m_pd3dDevice->CreateBuffer(&vbd, &vinitData, &m_pVertexBuffer);
CreateIndices();
//Sets terrains Current position in the world to be the top corner
m_position = verts2d[terrainDimentions - 1][terrainDimentions - 1].Position;
}
Code to Generate Indices
HRESULT TerrainObject::CreateIndices()
{
UINT faceCount = (terrainDimentions - 1) * (terrainDimentions - 1) * 2; // each quad consists of two triangles
int index = 0;
indices.resize(faceCount * 3);
for (UINT i = 0; i < terrainDimentions - 1; ++i)
{
for (UINT j = 0; j < terrainDimentions - 1; ++j)
{
indices[index] = i * terrainDimentions + j;
indices[index + 1] = i * terrainDimentions + j + 1;
indices[index + 2] = (i + 1) * terrainDimentions + j;
indices[index + 3] = (i + 1) * terrainDimentions + j;
indices[index + 4] = i * terrainDimentions + j + 1;
indices[index + 5] = (i + 1) * terrainDimentions + j + 1;
index += 6; // next quad
}
}
m_indexCount = indices.size();
// Creates index buffer
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_DEFAULT;
ibd.ByteWidth = sizeof(WORD) * m_indexCount;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = &indices[0];
return m_pd3dDevice->CreateBuffer(&ibd, &iinitData, &m_pIndexBuffer);
}
I am trying to draw a 3D cylinder by LWJGL,
and i am trying to generate the vertices, indices and textCoordinate
and storing them in arrays
, but i am stuck how to calculate the size of the vertices, indices and textCoordinate arrays...etc.
anyone knows how i can do it please:
Here the snippet of the code:
// generate vertices for a cylinder
void buildVerticesSmooth() {
//=====> vertices = new float[]; <========
//=====> normals = new float[]; <========
//=====> texcoords = new float[]; <========
int texCoordsIndex = -1;
int verticesIndex = -1;
int normalsIndex = -1;
int indicesIndex = -1; // get unit circle vectors on XY-plane
float[] unitVertices = getUnitCircleVertices();
// put side vertices to arrays
for (int i = 0; i < 2; ++i) {
float h = -height / 2.0f + i * height; // z value; -h/2 to h/2
float t = 1.0f - i; // vertical tex coord; 1 to 0
for (int j = 0, k = 0; j <= sectors; ++j, k += 3) {
float ux = unitVertices[k];
float uy = unitVertices[k + 1];
float uz = unitVertices[k + 2];
// position vector
vertices[++verticesIndex] = (ux * radius); // vx
vertices[++verticesIndex] = (uy * radius); // vy
vertices[++verticesIndex] = (h); // vz
// normal vector
normals[++normalsIndex] = (ux); // nx
normals[++normalsIndex] = (uy); // ny
normals[++normalsIndex] = (uz); // nz
// texture coordinate
texcoords[++texCoordsIndex] = ((float) j / sectors); // s
texcoords[++texCoordsIndex] = (t); // t
}
}
// the starting index for the base/top surface
//NOTE: it is used for generating indices later
int baseCenterIndex = vertices.length / 3;
int topCenterIndex = baseCenterIndex + sectors + 1; // include center vertex
// put base and top vertices to arrays
for (int i = 0; i < 2; ++i) {
float h = -height / 2.0f + i * height; // z value; -h/2 to h/2
float nz = -1 + i * 2; // z value of normal; -1 to 1
// center point
vertices[++verticesIndex] = 0;
vertices[++verticesIndex] = 0;
vertices[++verticesIndex] = h;
normals[++normalsIndex] = 0;
normals[++normalsIndex] = 0;
normals[++normalsIndex] = nz;
texcoords[++texCoordsIndex] = 0.5f;
texcoords[++texCoordsIndex] = 0.5f;
for (int j = 0, k = 0; j < sectors; ++j, k += 3) {
float ux = unitVertices[k];
float uy = unitVertices[k + 1];
// position vector
vertices[++verticesIndex] = (ux * radius); // vx
vertices[++verticesIndex] = (uy * radius); // vy
vertices[++verticesIndex] = (h); // vz
// normal vector
normals[++normalsIndex] = (0); // nx
normals[++normalsIndex] = (0); // ny
normals[++normalsIndex] = (nz); // nz
// texture coordinate
texcoords[++texCoordsIndex] = (-ux * 0.5f + 0.5f); // s
texcoords[++texCoordsIndex] = (-uy * 0.5f + 0.5f); // t
}
}
int[] indices;
int k1 = 0; // 1st vertex index at base
int k2 = sectors + 1; // 1st vertex index at top
// indices for the side surface
for(int i = 0; i < sectors; ++i, ++k1, ++k2)
{
// 2 triangles per sector
// k1 => k1+1 => k2
indices[++indicesIndex] = (k1);
indices[++indicesIndex] = (k1 + 1);
indices[++indicesIndex] = (k2);
// k2 => k1+1 => k2+1
indices[++indicesIndex] = (k2);
indices[++indicesIndex] = (k1 + 1);
indices[++indicesIndex] = (k2 + 1);
}
// indices for the base surface
// NOTE: baseCenterIndex and topCenterIndices are pre-computed during vertex generation
// please see the previous code snippet
for(int i = 0, k = baseCenterIndex + 1; i < sectors; ++i, ++k)
{
if(i < sectors - 1)
{
indices[++indicesIndex] = (baseCenterIndex);
indices[++indicesIndex] = (k + 1);
indices[++indicesIndex] = (k);
}
else // last triangle
{
indices[++indicesIndex] = (baseCenterIndex);
indices[++indicesIndex] = (baseCenterIndex + 1);
indices[++indicesIndex] = (k);
}
}
// indices for the top surface
for(int i = 0, k = topCenterIndex + 1; i < sectors; ++i, ++k)
{
if(i < sectors - 1)
{
indices[++indicesIndex] = (topCenterIndex);
indices[++indicesIndex] = (k);
indices[++indicesIndex] = (k + 1);
}
else // last triangle
{
indices[++indicesIndex] = (topCenterIndex);
indices[++indicesIndex] = (k);
indices[++indicesIndex] = (topCenterIndex + 1);
}
}
}
As httpdigest said:
you know how many iterations every loop performs and you know how
many increments/additions you do per each array. Should be very simple
math now.
I'm new to DirectX programming...
I wrote a code to draw grid (following Frank D. Luna). The code works almost correctly - grid is drawn but not all the vertices. Here is the image of the Grid:
I'm drawing a 4x4 grid.
As seen in the image, the bottom-most vertices are not drawn, and in each row an extra triangle is drawn, stretching from 1st quad to last quad in each row
Code:
void Model::CreateGrid(const Vector3& centerPos,float width,float depth,int verticesX,int verticesZ
{
assert(verticesX > 1 || verticesZ >1);
gridVertexCount = verticesX*verticesZ;
gridIndexCount = (verticesX - 1)*(verticesZ - 1)*6;
v.resize(gridVertexCount);
vIndex.resize(gridIndexCount);
float dx = width / (verticesX - 1);
float dz = depth / (verticesZ - 1);
float halfWidth = width / 2.0f;
float halfDepth = depth / 2.0f;
//Compute The Grid Vertex
for (size_t rows = 0; rows < verticesZ; rows++)
{
float z = halfDepth - rows*dz;
for (size_t col = 0; col < verticesX; col++)
{
float x = -halfWidth + col*dx;
v[col + rows*verticesX].pos = XMFLOAT3(x+centerPos.x, 0.0f, z + centerPos.z);
v[col + rows*verticesX].color = Colors::White;
}
}
//Compute the Grid Indices
UINT k = 0;
for (size_t row = 0; row < verticesZ - 1; row++)
{
for (size_t col = 0; col < verticesX - 1; col++)
{
//Index of One Quad
vIndex[k] = row*verticesX + col;
vIndex[k + 1] = row*verticesX+col+1;
vIndex[k + 2] = (row + 1)*verticesX + col;
vIndex[k + 3] = (row + 1)*verticesX + col;
vIndex[k + 4] = row*verticesX + col + 1;
vIndex[k + 5] = (row + 1)*verticesX + (col+1);
//Move to Next Quad
k +=6;
}
}
gridVertexSize = v.size();
gridIndexSize = vIndex.size();
//Add Vertex Data to Global Mesh Data
globalMesh.VertexData.insert(globalMesh.VertexData.end(), v.begin(),v.end());
v.clear();
//Add Index Data to Global Mesh Data
globalMesh.IndexData.insert(globalMesh.IndexData.end(), vIndex.begin(), vIndex.end());
vIndex.clear();
this->BuildGeometryBuffers();
this->BuildFX();
this->BuildVertexLayout(nullptr);
}
//Then I Set the Buffers
void Model::BuildGeometryBuffers()
{
//Set Vertex Buffer Description
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = (UINT)sizeof(Vertex)*globalMesh.VertexData.size();
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA vintData;
vintData.pSysMem = &globalMesh.VertexData[0];
device->CreateBuffer(&vbd, &vintData, &m_vB);
//Set Index Buffer Description
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = (UINT)sizeof(UINT)*globalMesh.IndexData.size();
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = &globalMesh.IndexData[0];
device->CreateBuffer(&ibd, &iinitData, &m_iB);
}
What is wrong with my code?
Solved it :
Changed this :
vIndex[k] = row*verticesX + col;
vIndex[k + 1] = row*verticesX+col+1;
vIndex[k + 2] = (row + 1)*verticesX + col;
vIndex[k + 3] = (row + 1)*verticesX + col;
vIndex[k + 4] = row*verticesX + col + 1;
vIndex[k + 5] = (row + 1)*verticesX + (col+1);
To:
vIndex[k] = row*verticesX + col;
vIndex[k + 1] = row*verticesX+col+1;
vIndex[k + 2] = (row + 1)*verticesX + col;
vIndex[k + 3] = row*verticesX + col + 1;
vIndex[k + 4] = (row + 1)*verticesX + (col + 1);
vIndex[k + 5] = (row + 1)*verticesX + col;
I'm trying to render a terrain using directx 11 and applying a heightmap to it.
I load the heightmap then I copy it to a integer vector, then for each vertex position I assign the Y position of that vertex to the heightmap value, but the terrain is completely destroyed and distorted. When I remove the calculation on the Y axis, I get a flat grid and no problem.
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;
}
here is a video of the problem
https://www.youtube.com/watch?v=lnlIz3DjebM&feature=youtu.be
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;
}
I would use unsigned char instead of BYTE when defining std::vector<BYTE> in(m*n) since it isn't a part of the C standard library so it is system dependent.
Also use a cast on this line
in.size());// number of bytes to read into buffer
to the actual parameter type of ifstream::read which is std::streamsize.
Like this:
(std::streamsize)in.size());// number of bytes to read into buffer
Since you're working with an 8-bit height map you should perhaps not just copy the value from the RAW file into your height map like this:
for (int i = 0; i < in.size(); i++)
m_heightmap[i] = in[i];
Since each height map value is represented by an 8-bit integer you could try dividing the height map value as well as multiply it with some scale modifier. This would make it more convenient if you want to test your way to some good values. Purely for visual purposes...
for (int i = 0; i < in.size(); i++)
m_heightmap[i] = (float)( in[i] / 255.0f ) * scaleModifier;
When I draw terrain like this - it works normal
void Terrain::RenderLandscape()
{
int x, y;
int Index = 0;
for (int i = 0; i < MapSize-1; i++)
{
Index = 0;
for (int j = 0;j < MapSize-1; j++)
{
x = j * Zoom;
y = i * Zoom;
TextureMap[Index+0][0]= j * TextureBit;
TextureMap[Index+0][1]= i * TextureBit;
TextureMap[Index+1][0]= j * TextureBit;
TextureMap[Index+1][1]= (i+1) * TextureBit;
VertexMap[Index+0][2] = HeightMap[j][i];
VertexMap[Index+1][2] = HeightMap[j][i+1];
VertexMap[Index+0][0] = x;
VertexMap[Index+0][1] = y;
VertexMap[Index+1][0] = x;
VertexMap[Index+1][1] = y+Zoom;
Index += 2;
}
glDrawElements(GL_TRIANGLE_STRIP, Index, GL_UNSIGNED_INT, Indices);
}
}
But when I move loops to another method and leave in RenderLandscape
void Terrain::RenderLandscape()
{
glDrawElements(GL_TRIANGLE_STRIP, 512, GL_UNSIGNED_INT, Indices);
}
Where 512 - size of Indices array - It shows only black screen without terrain.
What is the problem?
I move loops to method which is called before renderLandscape. There I initialize vertex, normals, texture arrays. Method init.
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, VertexMap);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, TextureMap);
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT,0, NormalMap);
for (int Row = 0; Row < MapSize*2; Row++)
{
Indices[Row] = Row;
}
int x, y;
int Index = 0;
for (int i = 0; i < MapSize-1; i++)
{
Index = 0;
for (int j = 0;j < MapSize-1; j++)
{
x = j * Zoom;
y = i * Zoom;
TextureMap[Index+0][0]= j * TextureBit;
TextureMap[Index+0][1]= i * TextureBit;
TextureMap[Index+1][0]= j * TextureBit;
TextureMap[Index+1][1]= (i+1) * TextureBit;
VertexMap[Index+0][2] = HeightMap[j][i];
VertexMap[Index+1][2] = HeightMap[j][i+1];
VertexMap[Index+0][0] = x;
VertexMap[Index+0][1] = y;
VertexMap[Index+1][0] = x;
VertexMap[Index+1][1] = y+Zoom;
Index += 2;
}
}
Index = 0;
for(int i = 0; i < MapSize - 1; i++)
{
Index = 0;
for (int j = 0;j < MapSize-1; j++)
{
CVector3 vTriangle[] = { CVector3(VertexMap[Index + 0]),
CVector3(VertexMap[Index + 1]),
CVector3(VertexMap[Index + 2]) };
CVector3 normal = Normal(vTriangle);
NormalMap[Index + 0][0] = normal.x;
NormalMap[Index + 0][1] = normal.y;
NormalMap[Index + 0][2] = normal.z;
NormalMap[Index + 1][0] = normal.x;
NormalMap[Index + 1][1] = normal.y;
NormalMap[Index + 1][2] = normal.z;
NormalMap[Index + 2][0] = normal.x;
NormalMap[Index + 2][1] = normal.y;
NormalMap[Index + 2][2] = normal.z;
Index += 3;
}
}
So it works like this
1) I initialize opengl and create terrain object.
........
landscape.Init();
glutPassiveMotionFunc(MousePassive);
glutIdleFunc(draw)
........
2) in method draw I call renderLandscape method
glPushMatrix();
glTranslatef(-20, 0, 0);
glScalef(0.01, 0.01, 0.01);
glRotatef(90, 1, 0, 0);
landscape.RenderLandscape();
glPopMatrix();