Files
Vibe-HD-2D/engine/include/hd2d/Terrain.h
Gabrieal Jimmy 2c99305fb0 init
2026-10-02 12:42:00 -05:00

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