#52 - C++ Terrain Class
Data: 2019-03-16 12:00 - C++
C++ class to create a terrain mesh. This generates meshes without a third dimension. The third dimension should be added in a shader with a heightmap texture.
// Terrain.h
#pragma once
#include <memory>
#define TERRAIN_POSITIONS 0
#define TERRAIN_TEXTURE_COORDS 1
class Terrain {
static std::shared_ptr<Mesh> createPatch(float size, float resolution);
private:
int _sizeX;
int _sizeY;
float _patchSize;
float _patchResolution;
std::shared_ptr<Meshes::Mesh> _terrainPatch;
public:
Terrain(int sizeX, int sizeY, float patchSize, float patchResolution);
void render();
};
// Terrain.cpp
#include "Terrain.h"
#include "Mesh.h"
#include "MeshBuilder.h"
std::shared_ptr<Mesh> Terrain::createPatch(float size, float resolution) {
const int numVerticesPerAxis = (int)(size * resolution) + 1;
const float ds = 1.0f / numVerticesPerAxis;
const float dx = 1.0f / resolution;
const int numVertices = numVerticesPerAxis * numVerticesPerAxis;
float* vertices = new float[numVertices * 2];
float* texCoords = new float[numVertices * 2];
const int numEdgesAxis = numVerticesPerAxis - 1;
const int numIndices = numEdgesAxis * numEdgesAxis * 3 * 2;
unsigned int* indices = new unsigned int[numIndices];
for (int i = 0, x = 0; x < numVerticesPerAxis; x++) {
for (int z = 0; z < numVerticesPerAxis; z++) {
vertices[i] = x * dx;
vertices[i + 1] = z * dx;
texCoords[i] = x * ds;
texCoords[i + 1] = z * ds;
i += 2;
}
}
for (int i = 0, index = 0, x = 0; x < numEdgesAxis; x++) {
for (int z = 0; z < numEdgesAxis; z++) {
indices[i] = index;
indices[i + 1] = index + 1;
indices[i + 2] = index + numVerticesPerAxis + 1;
indices[i + 3] = index + numVerticesPerAxis + 1;
indices[i + 4] = index + numVerticesPerAxis;
indices[i + 5] = index;
i += 6;
index++;
}
index++;
}
MeshBuilder builder;
builder.generateVBO(GL_ARRAY_BUFFER, numVertices * 2 * sizeof(float), vertices, GL_STATIC_DRAW);
builder.attribPointer(TERRAIN_POSITIONS, 2, GL_FLOAT, 0, 0);
builder.generateVBO(GL_ARRAY_BUFFER, numVertices * 2 * sizeof(float), texCoords, GL_STATIC_DRAW);
builder.attribPointer(TERRAIN_TEXTURE_COORDS, 2, GL_FLOAT, 0, 0);
builder.generateVBO(GL_ELEMENT_ARRAY_BUFFER, numIndices * sizeof(unsigned int), indices, GL_STATIC_DRAW);
delete[] vertices;
delete[] texCoords;
delete[] indices;
return builder.build(numIndices);
}
Terrain::Terrain(int sizeX, int sizeY, float patchSize, float patchResolution) : _sizeX(sizeX), _sizeY(sizeY), _patchSize(patchSize), _patchResolution(patchResolution) {
_terrainPatch = Terrain::createPatch(patchSize, patchResolution);
}
void Terrain::render() {
_terrainPatch->render();
}