80 lines
2.7 KiB
C++
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
|