62 lines
2.1 KiB
C++
62 lines
2.1 KiB
C++
#pragma once
|
|
#include "hd2d/GL.h"
|
|
#include "hd2d/Texture.h"
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <glm/glm.hpp>
|
|
#include <vector>
|
|
|
|
namespace hd2d {
|
|
|
|
// How a material id maps onto layers of the terrain texture array.
|
|
struct TerrainMaterial {
|
|
int topFirst = 0, topCount = 1; // layers picked per tile for top faces
|
|
int accentFirst = 0, accentCount = 0; // occasional variation layers
|
|
float accentChance = 0.0f; // probability a tile uses an accent layer
|
|
int sideFirst = 0, sideCount = 1; // layers for cliff faces below this tile
|
|
int lipLayer = -1; // layer for an overhang strip atop cliff faces (-1 = none)
|
|
};
|
|
|
|
// Tile-based diorama terrain: every tile has an integer height level and a
|
|
// material. Top faces are drawn with organically jittered material borders
|
|
// at pixel granularity; height differences produce textured cliff faces.
|
|
class Terrain {
|
|
public:
|
|
static constexpr int kMaxMaterials = 8;
|
|
|
|
void init(int width, int depth, float levelHeight = 0.5f);
|
|
int width() const { return w_; }
|
|
int depth() const { return d_; }
|
|
float levelHeight() const { return levelHeight_; }
|
|
|
|
bool inBounds(int x, int z) const { return x >= 0 && z >= 0 && x < w_ && z < d_; }
|
|
int level(int x, int z) const;
|
|
uint8_t material(int x, int z) const;
|
|
void setLevel(int x, int z, int level);
|
|
void setMaterial(int x, int z, uint8_t mat);
|
|
float heightAt(float x, float z) const; // top surface height of tile under (x, z)
|
|
|
|
// Cliff faces at the map border extend down to this level (diorama base).
|
|
int baseLevel = -6;
|
|
std::array<TerrainMaterial, kMaxMaterials> materials{};
|
|
|
|
// (Re)builds GPU mesh + material map after edits.
|
|
void build();
|
|
void draw() const;
|
|
void bindMaterialMap(GLuint unit) const { glBindTextureUnit(unit, matTex_); }
|
|
|
|
TextureArray textures; // pixel-art material layers, all same size
|
|
|
|
private:
|
|
int w_ = 0, d_ = 0;
|
|
float levelHeight_ = 0.5f;
|
|
std::vector<int> levels_;
|
|
std::vector<uint8_t> mats_;
|
|
|
|
GLuint vao_ = 0, vbo_ = 0, ibo_ = 0, matTex_ = 0;
|
|
GLsizei indexCount_ = 0;
|
|
};
|
|
|
|
} // namespace hd2d
|