Files
2026-10-25 03:29:04 -03:00

80 lines
2.8 KiB
C++

// Renderer: one shader + one draw path for both BSP (brush) batches and mesh-object batches.
#pragma once
#include <hmap/hmap.h>
#include <string>
#include <unordered_map>
#include <vector>
#include "raylib.h"
#include "rlgl.h"
namespace hpp {
inline Vector3 toRl(const hmap::Vec3& v) { return {v.x, v.y, v.z}; }
// hmap::Mat34 uses column vectors (p' = M p + t); raylib's Matrix is laid out so that
// MatrixToFloat() yields the same column-major OpenGL matrix.
inline Matrix toRlMatrix(const hmap::Mat34& a) {
Matrix m;
m.m0 = a.m[0][0]; m.m4 = a.m[0][1]; m.m8 = a.m[0][2]; m.m12 = a.m[0][3];
m.m1 = a.m[1][0]; m.m5 = a.m[1][1]; m.m9 = a.m[1][2]; m.m13 = a.m[1][3];
m.m2 = a.m[2][0]; m.m6 = a.m[2][1]; m.m10 = a.m[2][2]; m.m14 = a.m[2][3];
m.m3 = 0; m.m7 = 0; m.m11 = 0; m.m15 = 1;
return m;
}
// Batches immediate-mode lines so a huge wireframe never overflows rlgl's vertex buffer.
struct LineBatch {
int n = 0;
void begin() { rlBegin(RL_LINES); n = 0; }
void line(const hmap::Vec3& a, const hmap::Vec3& b, Color c) {
rlColor4ub(c.r, c.g, c.b, c.a);
rlVertex3f(a.x, a.y, a.z);
rlVertex3f(b.x, b.y, b.z);
if (++n >= 2048) { rlEnd(); rlBegin(RL_LINES); n = 0; }
}
void end() { rlEnd(); }
};
struct ModelEntry {
Model model = {};
bool ok = false;
BoundingBox box = {};
std::vector<Color> baseColors;
};
class Renderer {
public:
void init();
void shutdown();
void setEditBatches(const std::vector<hmap::Batch>& b); // raw per-object geometry (no CSG)
void setCompiledBatches(const std::vector<hmap::Batch>& b); // CSG'd + baked geometry
void setLights(const std::vector<hmap::Light>& lights, const hmap::Vec3& ambient);
// mode: 0 = flat, 1 = dynamic lights, 2 = baked vertex colours
void drawBatches(bool compiled, const std::vector<hmap::Material>& mats, const std::string& assetRoot, int mode);
void drawModel(ModelEntry& me, const hmap::Mat34& xf, Color tint, int mode);
ModelEntry& model(const std::string& relPath, const std::string& assetRoot);
Texture2D texture(const hmap::Material& m, const std::string& assetRoot);
void clearCaches();
size_t editTriangles = 0, compiledTriangles = 0;
private:
struct Gpu { Mesh mesh; int material; };
void upload(const std::vector<hmap::Batch>& in, std::vector<Gpu>& out, size_t& tris);
void freeGpu(std::vector<Gpu>& v);
void setMode(int m);
Shader shader_ = {};
Material mat_ = {};
int locMode_ = -1, locAmbient_ = -1, locSunDir_ = -1, locSunColor_ = -1, locCount_ = -1, locPos_ = -1, locCol_ = -1;
std::vector<Gpu> edit_, compiled_;
std::unordered_map<std::string, Texture2D> textures_;
std::unordered_map<std::string, ModelEntry> models_;
};
} // namespace hpp