2026-10-25 23:27:19 +01:00

130 lines
3.9 KiB
C++

#include <deerith/client/graphics/primitive_internals.h>
#include <deerith/client/graphics/primitive.h>
#include <deerith/client/graphics/shader.h>
#include <deerith/client/graphics/mesh.h>
#include <deerith/engine.h>
#include "glm/glm.hpp"
#include "glm/mat4x4.hpp"
#include "glm/ext/matrix_clip_space.hpp"
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glad/gl.h>
#include <vector>
namespace deerith
{
std::unique_ptr<shader_t> primitive_shader;
std::unique_ptr<mesh_2d_t> primitive_rectangle_mesh;
std::unique_ptr<shader_t> lit_shader;
std::unique_ptr<mesh_3d_t> cube_mesh;
std::unique_ptr<mesh_3d_t> grid_mesh;
void create_grid_mesh();
}
void deerith::create_grid_mesh()
{
const size_t vertex_count = GRID_SIZE * 4;
std::vector<glm::vec3> grid_vertices; // size will GRID_SIZE * 4
for (int i = 0; i < GRID_SIZE; i++)
{
float relative_position = static_cast<float>(i) / static_cast<float>(GRID_SIZE - 1);
float absolute_position = (relative_position * 2.0f - 1.0f) * static_cast<float>(GRID_SIZE);
grid_vertices.push_back(glm::vec3(absolute_position, 0, -GRID_SIZE));
grid_vertices.push_back(glm::vec3(absolute_position, 0, GRID_SIZE));
grid_vertices.push_back(glm::vec3(-GRID_SIZE, 0, absolute_position));
grid_vertices.push_back(glm::vec3(GRID_SIZE, 0, absolute_position));
}
grid_mesh = std::make_unique<mesh_3d_t>(&grid_vertices[0], vertex_count, nullptr, 0);
}
void deerith::init_primitives()
{
primitive_shader = std::make_unique<shader_t>(
"../deerith_engine_client/shaders/primitive.vert.glsl",
"../deerith_engine_client/shaders/primitive.frag.glsl");
primitive_rectangle_mesh = std::make_unique<mesh_2d_t>(rectangle_vertices, 4, rectangle_indices, 6);
lit_shader = std::make_unique<shader_t>(
"../deerith_engine_client/shaders/lit.vert.glsl",
"../deerith_engine_client/shaders/lit.frag.glsl");
cube_mesh = std::make_unique<mesh_3d_t>(cube_vertices, 8, cube_indices, 36); // 6 faces * 2 * 3
create_grid_mesh();
}
void deerith::shutdown_primitives()
{
primitive_shader.release();
primitive_shader.reset();
primitive_rectangle_mesh.release();
primitive_rectangle_mesh.reset();
lit_shader.release();
lit_shader.reset();
cube_mesh.release();
cube_mesh.reset();
grid_mesh.release();
grid_mesh.reset();
}
void deerith::set_primitive_viewspace(glm::vec2 start_viewspace, glm::vec2 end_viewspace)
{
float width = end_viewspace.x - start_viewspace.x;
float height = end_viewspace.y - start_viewspace.y;
deerith_assert(width > 0, "set_primitive_viewspace width must be > 0");
deerith_assert(height > 0, "set_primitive_viewspace height must be > 0");
glm::mat4 m_projection = glm::ortho(
start_viewspace.x,
end_viewspace.x,
start_viewspace.y,
end_viewspace.y,
-1.0f,
1.0f);
primitive_shader->set_matrix("uViewProjection", m_projection);
}
void deerith::set_primitive_color(glm::vec4 color)
{
primitive_shader->set_vec4("uColor", color);
}
void deerith::draw_primitive_rectangle(glm::vec2 start, glm::vec2 end)
{
float width = end.x - start.x;
float height = end.y - start.y;
deerith_assert(width > 0, "draw_primitive_rectangle width must be > 0");
deerith_assert(height > 0, "draw_primitive_rectangle height must be > 0");
glm::mat4 model = glm::translate(glm::mat4(1), glm::vec3(start.x, start.y, 0.0f));
model = glm::scale(model, glm::vec3(width, height, 1.0f));
primitive_shader->use();
primitive_shader->set_matrix("uTransform", model);
primitive_rectangle_mesh->draw();
}
deerith::shader_t *deerith::get_lit_shader()
{
return lit_shader.get();
}
deerith::mesh_3d_t *deerith::get_cube_mesh()
{
return cube_mesh.get();
}
deerith::mesh_3d_t *deerith::get_grid_mesh()
{
return grid_mesh.get();
}