278 lines
9.3 KiB
C++
278 lines
9.3 KiB
C++
#include "logging.hpp"
|
|
#include "scene/scene_camera.hpp"
|
|
#include <pch.hpp>
|
|
|
|
#include <renderer/render_command.hpp>
|
|
#include <renderer/uniform_buffer.hpp>
|
|
#include <renderer/editor_camera.hpp>
|
|
#include <renderer/vertex_array.hpp>
|
|
#include <renderer/renderer3d.hpp>
|
|
#include <renderer/shader.hpp>
|
|
#include <renderer/buffer.hpp>
|
|
#include <instrumentor.hpp>
|
|
#include <ref_scope.hpp>
|
|
|
|
#include <glm/ext/quaternion_common.hpp>
|
|
#include <glm/ext/matrix_transform.hpp>
|
|
#include <glm/trigonometric.hpp>
|
|
#include <glm/fwd.hpp>
|
|
#include <cstdint>
|
|
|
|
#include <glad/glad.h>
|
|
|
|
namespace OpenEngine {
|
|
|
|
// SHOULD BE MOVED ==================================
|
|
|
|
Ref<Mesh> CreateQuad(uint32_t id, bool back_face)
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
OE_CORE_DEBUG("Creating quad with id {}.", id);
|
|
|
|
std::vector<MeshVertex> vertices;
|
|
std::vector<uint32_t> indices;
|
|
if (back_face) {
|
|
vertices = {
|
|
// Front face (normal 0, 0, 1)
|
|
{{-0.5f, -0.5f, 0.0f}, {0,0,1}, {0,0}},
|
|
{{-0.5f, 0.5f, 0.0f}, {0,0,1}, {0,1}},
|
|
{{ 0.5f, 0.5f, 0.0f}, {0,0,1}, {1,1}},
|
|
{{ 0.5f, -0.5f, 0.0f}, {0,0,1}, {1,0}},
|
|
|
|
// Back face (normal 0, 0, -1)
|
|
{{-0.5f, -0.5f, -0.0f}, {0,0,-1}, {0,0}},
|
|
{{-0.5f, 0.5f, -0.0f}, {0,0,-1}, {0,1}},
|
|
{{ 0.5f, 0.5f, -0.0f}, {0,0,-1}, {1,1}},
|
|
{{ 0.5f, -0.5f, -0.0f}, {0,0,-1}, {1,0}}
|
|
};
|
|
|
|
indices = {
|
|
// Front face (z=0.5)
|
|
0, 2, 1, 0, 3, 2,
|
|
// Back face (z=-0.5)
|
|
4, 5, 6, 4, 6, 7
|
|
};
|
|
} else {
|
|
vertices = {
|
|
// Front face (normal 0, 0, 1)
|
|
{{-0.5f, -0.5f, 0.0f}, {0,0,1}, {0,0}},
|
|
{{-0.5f, 0.5f, 0.0f}, {0,0,1}, {0,1}},
|
|
{{ 0.5f, 0.5f, 0.0f}, {0,0,1}, {1,1}},
|
|
{{ 0.5f, -0.5f, 0.0f}, {0,0,1}, {1,0}}
|
|
};
|
|
|
|
indices = {
|
|
// Front face (z=0.5)
|
|
0, 2, 1, 0, 3, 2
|
|
};
|
|
}
|
|
|
|
return CreateMesh(vertices, indices);
|
|
}
|
|
|
|
Ref<Mesh> CreateCube(uint32_t id)
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
OE_CORE_DEBUG("Creating cube with id {}.", id);
|
|
std::vector<MeshVertex> vertices = {
|
|
// Front face (normal 0, 0, 1)
|
|
{{-0.5f, -0.5f, 0.5f}, {0,0,1}, {0,0}},
|
|
{{-0.5f, 0.5f, 0.5f}, {0,0,1}, {0,1}},
|
|
{{ 0.5f, 0.5f, 0.5f}, {0,0,1}, {1,1}},
|
|
{{ 0.5f, -0.5f, 0.5f}, {0,0,1}, {1,0}},
|
|
|
|
// Back face (normal 0, 0, -1)
|
|
{{-0.5f, -0.5f, -0.5f}, {0,0,-1}, {0,0}},
|
|
{{-0.5f, 0.5f, -0.5f}, {0,0,-1}, {0,1}},
|
|
{{ 0.5f, 0.5f, -0.5f}, {0,0,-1}, {1,1}},
|
|
{{ 0.5f, -0.5f, -0.5f}, {0,0,-1}, {1,0}},
|
|
|
|
// Left face (normal -1, 0, 0)
|
|
{{-0.5f, -0.5f, -0.5f}, {-1,0,0}, {0,0}},
|
|
{{-0.5f, 0.5f, -0.5f}, {-1,0,0}, {0,1}},
|
|
{{-0.5f, 0.5f, 0.5f}, {-1,0,0}, {1,1}},
|
|
{{-0.5f, -0.5f, 0.5f}, {-1,0,0}, {1,0}},
|
|
|
|
// Right face (normal 1, 0, 0)
|
|
{{ 0.5f, -0.5f, -0.5f}, {1,0,0}, {0,0}},
|
|
{{ 0.5f, 0.5f, -0.5f}, {1,0,0}, {0,1}},
|
|
{{ 0.5f, 0.5f, 0.5f}, {1,0,0}, {1,1}},
|
|
{{ 0.5f, -0.5f, 0.5f}, {1,0,0}, {1,0}},
|
|
|
|
// Top face (normal 0, 1, 0)
|
|
{{-0.5f, 0.5f, -0.5f}, {0,1,0}, {0,0}},
|
|
{{-0.5f, 0.5f, 0.5f}, {0,1,0}, {0,1}},
|
|
{{ 0.5f, 0.5f, 0.5f}, {0,1,0}, {1,1}},
|
|
{{ 0.5f, 0.5f, -0.5f}, {0,1,0}, {1,0}},
|
|
|
|
// Bottom face (normal 0, -1, 0)
|
|
{{-0.5f, -0.5f, -0.5f}, {0,-1,0}, {0,0}},
|
|
{{-0.5f, -0.5f, 0.5f}, {0,-1,0}, {0,1}},
|
|
{{ 0.5f, -0.5f, 0.5f}, {0,-1,0}, {1,1}},
|
|
{{ 0.5f, -0.5f, -0.5f}, {0,-1,0}, {1,0}},
|
|
};
|
|
|
|
std::vector<uint32_t> indices = {
|
|
// Front face (z=-0.5)
|
|
0, 2, 1, 0, 3, 2,
|
|
// Back face (z=0.5)
|
|
4, 5, 6, 4, 6, 7,
|
|
// Right face
|
|
12, 13, 14, 12, 14, 15,
|
|
// Left face
|
|
8, 10, 9, 8, 11, 10,
|
|
// Top face
|
|
18, 16, 17, 18, 19, 16,
|
|
// Bottom face
|
|
20, 22, 21, 20, 23, 22
|
|
};
|
|
|
|
return CreateMesh(vertices, indices);
|
|
}
|
|
|
|
// ==================================================
|
|
struct Renderer3DData
|
|
{
|
|
Ref<Shader> color_shader_3d;
|
|
|
|
struct CameraData
|
|
{
|
|
glm::mat4 view_projection;
|
|
glm::vec3 view_position;
|
|
};
|
|
CameraData camera_buffer;
|
|
Ref<UniformBuffer> camera_uniform_buffer;
|
|
|
|
struct TransformData
|
|
{
|
|
glm::mat4 transform;
|
|
};
|
|
TransformData transform_buffer;
|
|
Ref<UniformBuffer> transform_uniform_buffer;
|
|
|
|
Material material_buffer;
|
|
Ref<UniformBuffer> material_uniform_buffer;
|
|
|
|
Ref<UniformBuffer> id_uniform_buffer;
|
|
};
|
|
|
|
static Renderer3DData renderer_data;
|
|
|
|
void Renderer3D::Init()
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
glCullFace(GL_BACK);
|
|
|
|
renderer_data.color_shader_3d = Shader::Create("assets/shaders/color3d.glsl");
|
|
renderer_data.camera_uniform_buffer = UniformBuffer::Create(sizeof(Renderer3DData::CameraData), 0);
|
|
renderer_data.transform_uniform_buffer = UniformBuffer::Create(sizeof(Renderer3DData::TransformData), 1);
|
|
renderer_data.material_uniform_buffer = UniformBuffer::Create(sizeof(Material), 2);
|
|
renderer_data.id_uniform_buffer = UniformBuffer::Create(sizeof(uint32_t), 3);
|
|
|
|
glEnable(GL_DEBUG_OUTPUT);
|
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
|
glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity,
|
|
GLsizei length, const GLchar* message, const void* userParam) {
|
|
OE_CORE_ERROR("GL: {0}", message);
|
|
}, nullptr);
|
|
}
|
|
|
|
void Renderer3D::Shutdown()
|
|
{
|
|
renderer_data.color_shader_3d.reset();
|
|
renderer_data.camera_uniform_buffer.reset();
|
|
renderer_data.transform_uniform_buffer.reset();
|
|
renderer_data.material_uniform_buffer.reset();
|
|
renderer_data.id_uniform_buffer.reset();
|
|
}
|
|
|
|
void Renderer3D::BeginScene(const SceneCamera& camera, const glm::mat4& transform)
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
|
|
renderer_data.camera_buffer.view_projection = camera.GetProjection() * glm::inverse(transform);
|
|
renderer_data.camera_buffer.view_position = transform[3];
|
|
|
|
renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer3DData::CameraData));
|
|
}
|
|
|
|
void Renderer3D::BeginScene(const EditorCamera& camera)
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
|
|
renderer_data.camera_buffer.view_projection = camera.GetViewProjection();
|
|
renderer_data.camera_buffer.view_position = camera.GetPosition();
|
|
|
|
renderer_data.camera_uniform_buffer->SetData(&renderer_data.camera_buffer, sizeof(Renderer3DData::CameraData));
|
|
}
|
|
|
|
void Renderer3D::EndScene()
|
|
{
|
|
|
|
}
|
|
|
|
void Renderer3D::DrawMesh(const Ref<Mesh>& mesh, Material& material,
|
|
const glm::mat4& transform)
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
|
|
renderer_data.color_shader_3d->Bind();
|
|
|
|
renderer_data.transform_buffer.transform = transform;
|
|
renderer_data.transform_uniform_buffer->SetData(&renderer_data.transform_buffer, sizeof(Renderer3DData::TransformData));
|
|
|
|
renderer_data.material_buffer = material;
|
|
renderer_data.material_uniform_buffer->SetData(&renderer_data.material_buffer, sizeof(Material));
|
|
|
|
mesh->vertex_array->Bind();
|
|
|
|
RenderCommand::DrawIndexed(mesh->vertex_array, mesh->indices.size());
|
|
}
|
|
|
|
void Renderer3D::DrawMesh(const Ref<Mesh>& mesh, Material& material,
|
|
const glm::mat4& transform,
|
|
uint32_t entity_id)
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
|
|
renderer_data.color_shader_3d->Bind();
|
|
|
|
renderer_data.transform_buffer.transform = transform;
|
|
renderer_data.transform_uniform_buffer->SetData(&renderer_data.transform_buffer, sizeof(Renderer3DData::TransformData));
|
|
|
|
renderer_data.material_buffer = material;
|
|
renderer_data.material_uniform_buffer->SetData(&renderer_data.material_buffer, sizeof(Material));
|
|
|
|
renderer_data.id_uniform_buffer->SetData(&entity_id, sizeof(uint32_t));
|
|
|
|
mesh->vertex_array->Bind();
|
|
|
|
RenderCommand::DrawIndexed(mesh->vertex_array, mesh->indices.size());
|
|
}
|
|
|
|
void Renderer3D::DrawModel(const Ref<Model3D>& model,
|
|
const glm::mat4& transform,
|
|
uint32_t entity_id)
|
|
{
|
|
OE_PROFILE_FUNCTION();
|
|
|
|
renderer_data.color_shader_3d->Bind();
|
|
|
|
renderer_data.transform_buffer.transform = transform;
|
|
renderer_data.transform_uniform_buffer->SetData(&renderer_data.transform_buffer, sizeof(Renderer3DData::TransformData));
|
|
|
|
for (auto& mesh : *model) {
|
|
renderer_data.material_buffer = mesh.material;
|
|
renderer_data.material_uniform_buffer->SetData(&renderer_data.material_buffer, sizeof(Material));
|
|
|
|
renderer_data.id_uniform_buffer->SetData(&entity_id, sizeof(uint32_t));
|
|
|
|
mesh.vertex_array->Bind();
|
|
|
|
RenderCommand::DrawIndexed(mesh.vertex_array, mesh.indices.size());
|
|
}
|
|
}
|
|
}
|