Compare commits
5 Commits
ec7ef40aea
...
063b228b97
| Author | SHA1 | Date | |
|---|---|---|---|
| 063b228b97 | |||
| 1440fd847c | |||
| 337da2b3b7 | |||
| 3574634c4c | |||
| 32873d14ae |
@ -7,6 +7,8 @@ set(SOURCES
|
||||
|
||||
src/input/input.cpp
|
||||
|
||||
src/opengl/buffers.cpp
|
||||
|
||||
src/scene/scene.cpp
|
||||
src/window/window.cpp
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ namespace Core {
|
||||
struct ENGINE_API batch {
|
||||
friend class Renderer;
|
||||
public:
|
||||
// requires transform component
|
||||
// requires Transform component
|
||||
struct item {
|
||||
unsigned int batchId;
|
||||
};
|
||||
|
||||
@ -5,11 +5,13 @@
|
||||
#include "engine/export.h"
|
||||
|
||||
namespace Core {
|
||||
struct ENGINE_API transform {
|
||||
|
||||
struct ENGINE_API Transform {
|
||||
glm::vec3 position;
|
||||
glm::vec3 rotation;
|
||||
glm::vec3 scale;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // COMPONENTS_TRANSFORM_H_
|
||||
43
engine/include/engine/opengl/buffers.h
Normal file
43
engine/include/engine/opengl/buffers.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef OPENGL_BUFFERS_H_
|
||||
#define OPENGL_BUFFERS_H_
|
||||
|
||||
#include <GL/glew.h>
|
||||
|
||||
#include "engine/export.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
namespace OpenGL {
|
||||
using BufferTarget = GLenum;
|
||||
using BufferUsage = GLenum;
|
||||
using BufferID = unsigned int;
|
||||
|
||||
class ENGINE_API Buffer {
|
||||
public:
|
||||
Buffer(BufferTarget target, BufferUsage usage);
|
||||
|
||||
void Data(void* data, size_t size);
|
||||
void SubData(void *data, size_t size, size_t offset);
|
||||
|
||||
void BindBuffer(unsigned int index);
|
||||
void BindBufferRanged(unsigned int index, size_t offset, size_t size);
|
||||
protected:
|
||||
void Bind();
|
||||
void Unbind();
|
||||
private:
|
||||
BufferID m_buffer;
|
||||
BufferTarget m_target;
|
||||
BufferUsage m_usage;
|
||||
};
|
||||
|
||||
class ENGINE_API UniformBuffer : public Buffer {
|
||||
public:
|
||||
UniformBuffer(size_t size, unsigned int index);
|
||||
public:
|
||||
|
||||
};
|
||||
} // namespace OpenGL
|
||||
|
||||
} // namespace Core
|
||||
|
||||
#endif // OPENGL_BUFFERS_H_
|
||||
@ -8,6 +8,8 @@
|
||||
#include "engine/export.h"
|
||||
#include "engine/components/light.h"
|
||||
|
||||
#include "engine/opengl/buffers.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
// TODO: make static or singleton
|
||||
@ -26,6 +28,8 @@ private:
|
||||
void GenerateShadowMaps();
|
||||
void EnsureShadowResources(light& l);
|
||||
private:
|
||||
OpenGL::UniformBuffer m_uniform_matrices;
|
||||
|
||||
Shader m_shader;
|
||||
Shader m_depthShader;
|
||||
|
||||
|
||||
58
engine/src/opengl/buffers.cpp
Normal file
58
engine/src/opengl/buffers.cpp
Normal file
@ -0,0 +1,58 @@
|
||||
#include "engine/opengl/buffers.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
namespace OpenGL {
|
||||
|
||||
Buffer::Buffer(BufferTarget target, BufferUsage usage)
|
||||
: m_target(target), m_usage(usage)
|
||||
{
|
||||
glGenBuffers(1, &m_buffer);
|
||||
Bind();
|
||||
Data(nullptr, 0);
|
||||
Unbind();
|
||||
}
|
||||
|
||||
void Buffer::Bind() {
|
||||
glBindBuffer(m_target, m_buffer);
|
||||
}
|
||||
|
||||
void Buffer::Unbind() {
|
||||
glBindBuffer(m_target, 0);
|
||||
}
|
||||
|
||||
void Buffer::Data(void *data, size_t size) {
|
||||
Bind();
|
||||
glBufferData(m_target, size, data, m_usage);
|
||||
Unbind();
|
||||
}
|
||||
|
||||
void Buffer::SubData(void *data, size_t size, size_t offset) {
|
||||
Bind();
|
||||
glBufferSubData(m_target, offset, size, data);
|
||||
Unbind();
|
||||
}
|
||||
|
||||
void Buffer::BindBuffer(unsigned int index) {
|
||||
Bind();
|
||||
glBindBufferBase(m_target, index, m_buffer);
|
||||
Unbind();
|
||||
}
|
||||
|
||||
void Buffer::BindBufferRanged(unsigned int index, size_t offset, size_t size) {
|
||||
Bind();
|
||||
glBindBufferRange(m_target, index, m_buffer, offset, size);
|
||||
Unbind();
|
||||
}
|
||||
|
||||
UniformBuffer::UniformBuffer(size_t size, unsigned int index)
|
||||
: Buffer(GL_UNIFORM_BUFFER, GL_STATIC_DRAW)
|
||||
{
|
||||
Data(nullptr, size);
|
||||
|
||||
BindBuffer(index);
|
||||
}
|
||||
|
||||
} // namespace OpenGL
|
||||
|
||||
} // namespace Core
|
||||
@ -9,6 +9,7 @@
|
||||
#include <glm/gtx/euler_angles.hpp>
|
||||
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "engine/renderer/renderer.h"
|
||||
#include "engine/window/window.h"
|
||||
@ -22,15 +23,9 @@
|
||||
|
||||
namespace Core {
|
||||
|
||||
Renderer::Renderer(std::shared_ptr<Scene> scene) : m_scene(scene)
|
||||
Renderer::Renderer(std::shared_ptr<Scene> scene)
|
||||
: m_scene(scene), m_uniform_matrices(2 * sizeof(glm::mat4), 1)
|
||||
{
|
||||
m_proj = glm::perspective(
|
||||
static_cast<float>(M_PI_2),
|
||||
static_cast<float>(Window::GetWidth()) / static_cast<float>(Window::GetHeight()),
|
||||
0.01f,
|
||||
100.0f
|
||||
);
|
||||
|
||||
m_shader.init(
|
||||
FileManager::read("./engine/src/shaders/main.vs"),
|
||||
FileManager::read("./engine/src/shaders/pbr.fs")
|
||||
@ -41,6 +36,18 @@ Renderer::Renderer(std::shared_ptr<Scene> scene) : m_scene(scene)
|
||||
FileManager::read("./engine/src/shaders/depth.fs")
|
||||
);
|
||||
|
||||
glUniformBlockBinding(m_shader.m_id, glGetUniformBlockIndex(m_shader.m_id, "Matrices"), 1);
|
||||
// glUniformBlockBinding(m_depthShader.m_id, glGetUniformBlockIndex(m_depthShader.m_id, "Matrices"), 1);
|
||||
|
||||
m_proj = glm::perspective(
|
||||
static_cast<float>(M_PI_2),
|
||||
static_cast<float>(Window::GetWidth()) / static_cast<float>(Window::GetHeight()),
|
||||
0.01f,
|
||||
100.0f
|
||||
);
|
||||
|
||||
m_uniform_matrices.SubData(glm::value_ptr(m_proj), sizeof(glm::mat4), 0);
|
||||
|
||||
m_model = glm::mat4(1.f);
|
||||
|
||||
m_shader.use();
|
||||
@ -58,6 +65,7 @@ void Renderer::OnWindowResized(int w, int h) {
|
||||
0.01f,
|
||||
100.0f
|
||||
);
|
||||
m_uniform_matrices.SubData(glm::value_ptr(m_proj), sizeof(glm::mat4), 0);
|
||||
}
|
||||
|
||||
void Renderer::ApplyLights(Shader &shader) {
|
||||
@ -67,7 +75,7 @@ void Renderer::ApplyLights(Shader &shader) {
|
||||
size_t lightIndex = 0;
|
||||
for (auto entity : lights) {
|
||||
auto &l = m_scene->m_registry.get<light>(entity);
|
||||
auto &transf = m_scene->m_registry.get<transform>(entity);
|
||||
auto &transf = m_scene->m_registry.get<Transform>(entity);
|
||||
|
||||
shader.setInt("lights[" + std::to_string(lightIndex) + "].type", static_cast<int>(l.type));
|
||||
shader.setVec3("lights[" + std::to_string(lightIndex) + "].position", transf.position);
|
||||
@ -111,14 +119,16 @@ void Renderer::EnsureShadowResources(light& l) {
|
||||
void Renderer::UpdateView() {
|
||||
auto camView = m_scene->m_registry.view<camera>();
|
||||
auto camTransform = camView.size() > 0 ?
|
||||
m_scene->m_registry.get<transform>(camView.back()) :
|
||||
transform {glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f)};
|
||||
m_scene->m_registry.get<Transform>(camView.back()) :
|
||||
Transform {glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 0.f), glm::vec3(1.f, 1.f, 1.f)};
|
||||
|
||||
m_view = glm::lookAt(
|
||||
camTransform.position,
|
||||
camTransform.position + camTransform.rotation,
|
||||
glm::vec3(0.f, 1.f, 0.f)
|
||||
);
|
||||
|
||||
m_uniform_matrices.SubData(glm::value_ptr(m_view), sizeof(glm::mat4), sizeof(glm::mat4));
|
||||
|
||||
m_shader.setVec3("viewPos", camTransform.position);
|
||||
|
||||
@ -149,7 +159,7 @@ void Renderer::RenderScene(Shader &shader) {
|
||||
models.reserve(batchItems.size());
|
||||
|
||||
for (auto item : batchItems) {
|
||||
auto &t = m_scene->m_registry.get<transform>(item);
|
||||
auto &t = m_scene->m_registry.get<Transform>(item);
|
||||
glm::mat4 rotation = glm::yawPitchRoll(t.rotation.y, t.rotation.x, t.rotation.z);
|
||||
auto itemModel = glm::translate(glm::mat4(1.f), t.position) * rotation;
|
||||
models.push_back(itemModel);
|
||||
@ -165,7 +175,7 @@ void Renderer::RenderScene(Shader &shader) {
|
||||
}
|
||||
shader.setBool("u_isInstanced", false);
|
||||
|
||||
for (auto [entity, transf, mesh] : m_scene->m_registry.view<transform, mesh>(entt::exclude<batch, batch::item>).each()) {
|
||||
for (auto [entity, transf, mesh] : m_scene->m_registry.view<Transform, mesh>(entt::exclude<batch, batch::item>).each()) {
|
||||
if (mesh.object == nullptr) {
|
||||
std::cerr << "WARN: Entity doesn't have a mesh to render" << std::endl;
|
||||
return;
|
||||
@ -206,7 +216,7 @@ void Renderer::Render() {
|
||||
|
||||
glCullFace(GL_FRONT);
|
||||
|
||||
const auto lights = m_scene->m_registry.view<light, transform>();
|
||||
const auto lights = m_scene->m_registry.view<light, Transform>();
|
||||
|
||||
for (auto [_, l, t] : lights.each()) {
|
||||
// TODO: support other light types when ready
|
||||
|
||||
@ -1,13 +1,23 @@
|
||||
#version 410 core
|
||||
#version 460 core
|
||||
|
||||
// Input vertex attributes
|
||||
layout (location = 0) in vec3 position; // Vertex position in local space (model space)
|
||||
layout (location = 3) in mat4 instanceModel; // Vertex texture uv
|
||||
|
||||
// layout (std140, binding = 1) uniform Matrices
|
||||
// {
|
||||
// mat4 projection;
|
||||
// mat4 view;
|
||||
// };
|
||||
|
||||
// Uniforms for transformation matrices
|
||||
uniform mat4 u_model; // Model matrix: transforms from local space to world space
|
||||
uniform mat4 u_lightSpace;
|
||||
uniform bool u_isInstanced;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_lightSpace * u_model * vec4(position, 1.0);
|
||||
mat4 model = u_isInstanced ? instanceModel : u_model;
|
||||
|
||||
gl_Position = u_lightSpace * model * vec4(position, 1.0);
|
||||
}
|
||||
@ -6,6 +6,12 @@ layout (location = 1) in vec3 normal; // vertex normal
|
||||
layout (location = 2) in vec2 texCoord; // Vertex texture uv
|
||||
layout (location = 3) in mat4 instanceModel; // Vertex texture uv
|
||||
|
||||
layout (std140, binding = 1) uniform Matrices
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 view;
|
||||
};
|
||||
|
||||
// Output to fragment shader
|
||||
out vec3 vertexPos;
|
||||
out vec3 vertexNormal;
|
||||
@ -14,8 +20,8 @@ out vec4 fragPosLightSpace;
|
||||
|
||||
// Uniforms for transformation matrices
|
||||
uniform mat4 u_model; // Model matrix: transforms from local space to world space
|
||||
uniform mat4 u_view; // View matrix: transforms from world space to camera space (view space)
|
||||
uniform mat4 u_projection; // Projection matrix: transforms from camera space to clip space
|
||||
// uniform mat4 u_view;
|
||||
// uniform mat4 u_projection;
|
||||
uniform bool u_isInstanced;
|
||||
|
||||
void main()
|
||||
@ -32,5 +38,5 @@ void main()
|
||||
|
||||
// fragPosLightSpace = u_lightSpace * vec4(vertexPos, 1.0);
|
||||
|
||||
gl_Position = u_projection * u_view * vec4(vertexPos, 1.0);
|
||||
gl_Position = projection * view * vec4(vertexPos, 1.0);
|
||||
}
|
||||
@ -36,20 +36,20 @@ public:
|
||||
|
||||
Object* lightObj = Object::LoadFile("./assets/common/sphere/sphere.obj");
|
||||
lightEntity = scene->CreateEntity();
|
||||
lightEntity.AddComponent<transform>(glm::vec3(5.f, 5.f, 5.f), glm::vec3(0.f));
|
||||
lightEntity.AddComponent<Transform>(glm::vec3(5.f, 5.f, 5.f), glm::vec3(0.f));
|
||||
lightEntity.AddComponent<light>(light::LightType::DIRECTIONAL, glm::vec3(1.f, 1.f, 1.f), 1.5f);
|
||||
lightEntity.AddComponent<mesh>(std::shared_ptr<Object>(lightObj));
|
||||
assert(lightEntity.HasComponent<mesh>() && "light doesn't have any mesh!");
|
||||
|
||||
cameraEntity = scene->CreateEntity();
|
||||
cameraEntity.AddComponent<camera>();
|
||||
cameraEntity.AddComponent<transform>(glm::vec3(0.f, 2.f, 2.f));
|
||||
cameraEntity.AddComponent<Transform>(glm::vec3(0.f, 2.f, 2.f));
|
||||
assert(cameraEntity.HasComponent<camera>() && "Camera doesn't have required 'camera' component");
|
||||
assert(cameraEntity.HasComponent<transform>() && "Camera doesn't have 'transform' component");
|
||||
assert(cameraEntity.HasComponent<Transform>() && "Camera doesn't have 'transform' component");
|
||||
|
||||
Object* targetObj = Object::LoadFile("./assets/wizard/wizard.obj");
|
||||
modelEntity = scene->CreateEntity();
|
||||
modelEntity.AddComponent<transform>(glm::vec3(0.f, 0.0f, 0.f));
|
||||
modelEntity.AddComponent<Transform>(glm::vec3(0.f, 0.0f, 0.f));
|
||||
modelEntity.AddComponent<mesh>(std::shared_ptr<Object>(targetObj));
|
||||
modelEntity.AddComponent<rotate>();
|
||||
assert(modelEntity.HasComponent<mesh>() && "model doesn't have any mesh!");
|
||||
@ -70,14 +70,14 @@ public:
|
||||
float y = static_cast<float>(rand()) / RAND_MAX * 10.f; // range [0, 10]
|
||||
float z = static_cast<float>(rand()) / RAND_MAX * 200.f - 100.f; // range [-100, 100]
|
||||
|
||||
cubeEntity.AddComponent<transform>(glm::vec3(x, y, z));
|
||||
cubeEntity.AddComponent<Transform>(glm::vec3(x, y, z));
|
||||
cubeEntity.AddComponent<rotate>();
|
||||
cubeEntity.AddComponent<batch::item>(cubeBatch.id());
|
||||
}
|
||||
|
||||
Object* floorObj = Object::LoadFile("./assets/common/plane/plane.obj");
|
||||
auto floorEntt = scene->CreateEntity();
|
||||
floorEntt.AddComponent<transform>(glm::vec3(0.f));
|
||||
floorEntt.AddComponent<Transform>(glm::vec3(0.f));
|
||||
floorEntt.AddComponent<mesh>(std::shared_ptr<Object>(floorObj));
|
||||
assert(floorEntt.HasComponent<mesh>() && "floor doesn't have any mesh component!");
|
||||
|
||||
@ -120,7 +120,7 @@ public:
|
||||
if (Input::IsKeyPressed(SDL_SCANCODE_SPACE)) velocity.y += 1.f;
|
||||
if (Input::IsKeyPressed(SDL_SCANCODE_LSHIFT)) velocity.y -= 1.f;
|
||||
|
||||
auto& camTransform = cameraEntity.GetComponent<transform>();
|
||||
auto& camTransform = cameraEntity.GetComponent<Transform>();
|
||||
camTransform.position += velocity * (float)dt * 2.5f; // speed is e.g. 2.5f
|
||||
camTransform.rotation = cameraViewDirection;
|
||||
|
||||
@ -154,7 +154,7 @@ public:
|
||||
|
||||
// Update the directional light in the registry
|
||||
auto& l = lightEntity.GetComponent<light>();
|
||||
auto& t = lightEntity.GetComponent<transform>();
|
||||
auto& t = lightEntity.GetComponent<Transform>();
|
||||
if (l.type == light::LightType::DIRECTIONAL) {
|
||||
// "position" for directional light often stores direction vector
|
||||
// If your system instead uses transform.rotation, adjust accordingly
|
||||
|
||||
Reference in New Issue
Block a user