Files

80 lines
2.7 KiB
C++

#pragma once
#include <array>
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
namespace boundard {
// 渲染组件:描述 Actor 的几何形状、颜色和可选 PNG 纹理。
class Mesh {
public:
struct Vertex {
std::array<float, 2> position;
std::array<float, 4> color;
std::array<float, 2> uv;
};
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
std::string texture; // PNG 纹理路径;为空时使用白色纹理。
std::array<float, 4> color() const {
std::lock_guard<std::mutex> lock(*color_mutex_);
return color_;
}
void set_color(std::array<float, 4> color) {
std::lock_guard<std::mutex> lock(*color_mutex_);
color_ = color;
}
static Mesh quad() {
Mesh mesh;
mesh.vertices = {
{{-1.0F, -1.0F}, {1.0F, 1.0F, 1.0F, 1.0F}, {0.0F, 0.0F}},
{{1.0F, -1.0F}, {1.0F, 1.0F, 1.0F, 1.0F}, {1.0F, 0.0F}},
{{1.0F, 1.0F}, {1.0F, 1.0F, 1.0F, 1.0F}, {1.0F, 1.0F}},
{{-1.0F, 1.0F}, {1.0F, 1.0F, 1.0F, 1.0F}, {0.0F, 1.0F}},
};
mesh.indices = {0, 1, 2, 2, 3, 0};
return mesh;
}
static Mesh grid(int half_cells = 12) {
Mesh mesh;
const float world_to_local = 1.0F / 0.35F;
const float half_extent = static_cast<float>(half_cells) * world_to_local;
const float line_half_width = 0.012F * world_to_local;
const std::array<float, 4> line_color{1.0F, 1.0F, 1.0F, 1.0F};
auto add_rect = [&](float left, float bottom, float right, float top) {
const uint32_t base = static_cast<uint32_t>(mesh.vertices.size());
mesh.vertices.insert(mesh.vertices.end(), {
{{left, bottom}, line_color, {0.0F, 0.0F}},
{{right, bottom}, line_color, {1.0F, 0.0F}},
{{right, top}, line_color, {1.0F, 1.0F}},
{{left, top}, line_color, {0.0F, 1.0F}},
});
mesh.indices.insert(mesh.indices.end(),
{base, base + 1, base + 2, base + 2, base + 3, base});
};
for (int cell = -half_cells; cell <= half_cells; ++cell) {
const float coordinate = static_cast<float>(cell) * world_to_local;
add_rect(coordinate - line_half_width, -half_extent, coordinate + line_half_width,
half_extent);
add_rect(-half_extent, coordinate - line_half_width, half_extent,
coordinate + line_half_width);
}
return mesh;
}
private:
std::unique_ptr<std::mutex> color_mutex_ = std::make_unique<std::mutex>();
std::array<float, 4> color_{1.0F, 1.0F, 1.0F, 1.0F};
};
} // namespace boundard