hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/engine.cpp317
-rw-r--r--src/engine/engine.h87
-rw-r--r--src/engine/object.cpp46
-rw-r--r--src/engine/object.h43
-rw-r--r--src/engine/scene.cpp57
-rw-r--r--src/engine/scene.h55
6 files changed, 249 insertions, 356 deletions
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
index 29fa65a..c2a84a8 100644
--- a/src/engine/engine.cpp
+++ b/src/engine/engine.cpp
@@ -1,251 +1,144 @@
-#include "engine.h"
-#include <GLFW/glfw3.h>
-#include <glad/glad.h>
#include <iostream>
#include <fstream>
#include <sstream>
-#include <limits>
+
+#include <GLFW/glfw3.h>
+
+#include "engine.h"
#include "rendering/vertex_buffer.h"
#include "rendering/index_buffer.h"
namespace Donut
{
- Engine::Engine()
- : m_sag_a(glm::vec3(0.0f, 0.0f, 0.0f),
- static_cast<float>(8.54e36))
+ Engine::Engine()
+ : m_sag_a(glm::vec3(0.0f, 0.0f, 0.0f), 8.54e36f)
{
GLFWwindow* window = static_cast<GLFWwindow*>(Application::get().get_window().get_native_window());
glfwGetFramebufferSize(window, &m_width, &m_height);
- m_compute_height = 420;
- m_compute_width = (m_width * 420) / m_height;
- m_camera.set_orbital_mode(true);
- m_camera.set_radius(6.34194e10);
- m_camera.set_min_radius(1e10);
- m_camera.set_max_radius(1e12);
- m_camera.set_orbit_speed(0.01f);
+ m_camera.set_camera_mode(CameraMode::Orbital);
+ m_camera.set_orbital_radius(6.34194e10);
+ m_camera.set_orbital_limits(1e10, 1e12);
+ m_camera.set_orbital_speed(0.01f);
m_camera.set_zoom_speed(25e9f);
m_objects =
{
- { glm::vec4(4e11f, 0.0f, 0.0f, 4e10f), glm::vec4(1,1,0,1), static_cast<float>(1.98892e30) },
- { glm::vec4(0.0f, 0.0f, 4e11f, 4e10f), glm::vec4(1,0,0,1), static_cast<float>(1.98892e30) },
- { glm::vec4(0.0f, 0.0f, 0.0f, m_sag_a.m_rs), glm::vec4(0,0,0,1), static_cast<float>(m_sag_a.m_mass) }
+ { glm::vec4(4e11f, 0.00f, 0.00f, 4e10f), glm::vec4(1, 1, 0, 1), static_cast<float>(1.98892e30) },
+ { glm::vec4(0.00f, 0.00f, 4e11f, 4e10f), glm::vec4(1, 0, 0, 1), static_cast<float>(1.98892e30) },
+ { glm::vec4(0.00f, 0.00f, 0.00f, m_sag_a.m_rs), glm::vec4(0, 0, 0, 1), static_cast<float>(m_sag_a.m_mass) }
};
- m_quad_shader = Shader::create("assets/shaders/quad.glsl");
- m_grid_shader = Shader::create("assets/shaders/grid.glsl");
- m_compute_shader = Shader::create_compute("Geodesic", load_compute_shader("assets/shaders/geodesic.glsl"));
+ m_shader_program = Ref<Shader>(Shader::create("assets/shaders/compute_texture_quad.glsl"));
+ m_compute_program = create_compute_program("assets/shaders/geodesic.glsl");
m_camera_ubo = UniformBuffer::create(128, 1);
- m_disk_ubo = UniformBuffer::create(sizeof(float) * 4, 2);
+ m_disk_ubo = UniformBuffer::create(sizeof(float) * 4, 2);
uint32_t obj_ubo_size = sizeof(int) + 3 * sizeof(float)
+ 16 * (sizeof(glm::vec4) + sizeof(glm::vec4))
+ 16 * sizeof(float);
m_objects_ubo = UniformBuffer::create(obj_ubo_size, 3);
- float quad_vertices[] =
- {
- -1.0f, 1.0f, 0.0f, 1.0f,
- -1.0f, -1.0f, 0.0f, 0.0f,
- 1.0f, -1.0f, 1.0f, 0.0f,
-
- -1.0f, 1.0f, 0.0f, 1.0f,
- 1.0f, -1.0f, 1.0f, 0.0f,
- 1.0f, 1.0f, 1.0f, 1.0f
- };
-
- m_quad_vao = VertexArray::create();
-
- auto vertex_buffer = VertexBuffer::create(quad_vertices, static_cast<uint32_t>(sizeof(quad_vertices)));
- VertexBufferLayout layout;
- layout.push<float>(2);
- layout.push<float>(2);
- vertex_buffer->set_layout(layout);
- m_quad_vao->add_vertex_buffer(vertex_buffer);
-
- m_texture = Texture2D::create(m_width, m_height);
+ auto result = quad_vao();
+ m_quad_vao = result.first;
+ m_texture = result.second;
}
- void Engine::generate_grid(const std::vector<ObjectData>& objects)
+ void Engine::update_window_dimensions()
{
- const int grid_size = 25;
- const float spacing = 1e10f;
-
- std::vector<glm::vec3> vertices;
- std::vector<uint32_t> indices;
-
- for (int z = 0; z <= grid_size; ++z)
- {
- for (int x = 0; x <= grid_size; ++x)
- {
- float world_x = (x - grid_size / 2) * spacing;
- float world_z = (z - grid_size / 2) * spacing;
- float y = 0.0f;
-
- for (const auto& obj : objects)
- {
- glm::vec3 obj_pos = glm::vec3(obj.m_pos_radius);
- double mass = obj.m_mass;
- double radius = obj.m_pos_radius.w;
-
- double r_s = 2.0 * G * mass / (c * c);
- double dx = world_x - obj_pos.x;
- double dz = world_z - obj_pos.z;
- double dist = sqrt(dx * dx + dz * dz);
-
- if (dist > r_s)
- {
- double delta_y = 2.0 * sqrt(r_s * (dist - r_s));
- y += static_cast<float>(delta_y) - 3e10f;
- }
- else
- {
- y += 2.0f * static_cast<float>(sqrt(r_s * r_s)) - 3e10f;
- }
- }
-
- vertices.emplace_back(world_x, y, world_z);
- }
- }
-
- for (int z = 0; z < grid_size; ++z)
- {
- for (int x = 0; x < grid_size; ++x)
- {
- int i = z * (grid_size + 1) + x;
- indices.push_back(i);
- indices.push_back(i + 1);
- indices.push_back(i);
- indices.push_back(i + grid_size + 1);
- }
- }
-
- if (!m_grid_vao)
- {
- m_grid_vao = Ref<VertexArray>(VertexArray::create());
-
- auto vertex_buffer = Ref<VertexBuffer>(VertexBuffer::create(vertices.data(), static_cast<uint32_t>(vertices.size() * sizeof(glm::vec3))));
- VertexBufferLayout layout;
- layout.push<float>(3);
- vertex_buffer->set_layout(layout);
- m_grid_vao->add_vertex_buffer(vertex_buffer);
-
- auto index_buffer = Ref<IndexBuffer>(IndexBuffer::create(indices.data(), static_cast<uint32_t>(indices.size())));
- m_grid_vao->set_index_buffer(index_buffer);
- }
- else
- {
- auto vertex_buffer = m_grid_vao->get_vertex_buffers()[0];
- vertex_buffer->set_data(vertices.data(), static_cast<uint32_t>(vertices.size() * sizeof(glm::vec3)));
- }
-
- m_grid_index_count = static_cast<int>(indices.size());
+ GLFWwindow* window = static_cast<GLFWwindow*>(Application::get().get_window().get_native_window());
+ int old_width = m_width;
+ int old_height = m_height;
+ int old_compute_height = m_compute_height;
+
+ glfwGetFramebufferSize(window, &m_width, &m_height);
+
+ if (old_width != m_width ||
+ old_height != m_height ||
+ old_compute_height != m_compute_height)
+ update_compute_dimensions();
}
- void Engine::draw_grid(const glm::mat4& view_proj)
+ void Engine::update_performance(float delta_time)
{
- if (!m_grid_shader || !m_grid_vao)
- return;
-
- m_grid_shader->bind();
- m_grid_shader->set_mat4("viewProj", view_proj);
-
- RenderCommand::disable_depth_test();
- RenderCommand::enable_blending();
-
- m_grid_vao->bind();
- glDrawElements(GL_LINES, m_grid_index_count, GL_UNSIGNED_INT, nullptr);
-
- RenderCommand::enable_depth_test();
+ if (delta_time > 0.0f)
+ m_current_fps = 1.0f / delta_time;
}
- void Engine::update_window_dimensions()
+ void Engine::update_compute_dimensions()
{
- GLFWwindow* window = static_cast<GLFWwindow*>(Application::get().get_window().get_native_window());
- int old_width = m_width;
- int old_height = m_height;
- glfwGetFramebufferSize(window, &m_width, &m_height);
- m_compute_height = 420;
- m_compute_width = (m_width * 420) / m_height;
-
- if (old_width != m_width || old_height != m_height)
- m_texture = Texture2D::create(m_width, m_height);
+ m_texture = Texture2D::create(get_compute_width(), m_compute_height);
}
- void Engine::draw_full_screen_quad()
+ void Engine::draw_full_screen_quad()
{
RenderCommand::set_viewport(0, 0, m_width, m_height);
- m_quad_shader->bind();
- std::cout << "Texture ID: " << m_texture->get_renderer_id() << ", Size: " << m_texture->get_width() << "x" << m_texture->get_height() << std::endl;
+ m_shader_program->bind();
+ m_quad_vao->bind();
+
m_texture->bind(0);
- m_quad_shader->set_int("screenTexture", 0);
- std::cout << "Set screenTexture uniform to slot 0\n";
+ m_shader_program->set_int("u_ScreenTexture", 0);
RenderCommand::disable_depth_test();
- RenderCommand::draw_indexed(m_quad_vao, 6);
+ RenderCommand::draw_arrays(6);
RenderCommand::enable_depth_test();
}
- void Engine::dispatch_compute(const Camera& cam)
+ void Engine::dispatch_compute(const Camera& cam)
{
- int cw = m_compute_width;
+ int cw = get_compute_width();
int ch = m_compute_height;
- if (m_texture->get_width() != cw || m_texture->get_height() != ch)
- m_texture = Texture2D::create(cw, ch);
+ m_texture->set_data(nullptr, cw * ch * 4);
- m_compute_shader->bind();
+ m_compute_program->bind();
upload_camera_ubo(cam);
upload_disk_ubo();
upload_objects_ubo(m_objects);
-
m_texture->bind_as_image(0, false);
- uint32_t groups_x = (uint32_t)std::ceil(cw / 16.0f);
- uint32_t groups_y = (uint32_t)std::ceil(ch / 16.0f);
- m_compute_shader->dispatch(groups_x, groups_y, 1);
- m_compute_shader->memory_barrier(IMAGE_ACCESS_BARRIER_BIT);
-
- glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
- glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT);
+ uint32_t groups_x = static_cast<uint32_t>(std::ceil(cw / 16.0f));
+ uint32_t groups_y = static_cast<uint32_t>(std::ceil(ch / 16.0f));
+ m_compute_program->dispatch(groups_x, groups_y, 1);
+ m_compute_program->memory_barrier(IMAGE_ACCESS_BARRIER_BIT);
}
- void Engine::upload_camera_ubo(const Camera& cam)
+ void Engine::upload_camera_ubo(const Camera& cam)
{
- struct UBOData
+ struct UBOData
{
- glm::vec3 pos; float _pad0;
- glm::vec3 right; float _pad1;
- glm::vec3 up; float _pad2;
+ glm::vec3 pos; float _pad0;
+ glm::vec3 right; float _pad1;
+ glm::vec3 up; float _pad2;
glm::vec3 forward; float _pad3;
float tan_half_fov;
float aspect;
- bool moving;
- int _pad4;
+ bool moving;
+ int _pad4;
} data;
- glm::vec3 fwd = glm::normalize(cam.get_target() - cam.get_orbital_position());
- glm::vec3 up = glm::vec3(0, 1, 0);
+ glm::vec3 fwd = glm::normalize(cam.get_orbital_target() - cam.get_orbital_position());
+ glm::vec3 up = glm::vec3(0, 1, 0);
glm::vec3 right = glm::normalize(glm::cross(fwd, up));
up = glm::cross(right, fwd);
- data.pos = cam.get_orbital_position();
- data.right = right;
- data.up = up;
- data.forward = fwd;
+ data.pos = cam.get_orbital_position();
+ data.right = right;
+ data.up = up;
+ data.forward = fwd;
data.tan_half_fov = static_cast<float>(tan(glm::radians(60.0f * 0.5f)));
- data.aspect = static_cast<float>(m_width) / static_cast<float>(m_height);
- data.moving = cam.is_dragging() || cam.is_panning();
+ data.aspect = static_cast<float>(get_compute_width()) / static_cast<float>(m_compute_height);
+ data.moving = cam.is_dragging() || cam.is_panning();
m_camera_ubo->set_data(&data, sizeof(UBOData));
+ m_camera_ubo->bind(1);
}
- void Engine::upload_objects_ubo(const std::vector<ObjectData>& objs)
+ void Engine::upload_objects_ubo(const std::vector<ObjectData>& objs)
{
- struct UBOData
+ struct UBOData
{
int num_objects;
float _pad0, _pad1, _pad2;
@@ -257,7 +150,7 @@ namespace Donut
size_t count = std::min(objs.size(), size_t(16));
data.num_objects = static_cast<int>(count);
- for (size_t i = 0; i < count; ++i)
+ for (size_t i = 0; i < count; ++i)
{
data.pos_radius[i] = objs[i].m_pos_radius;
data.color[i] = objs[i].m_color;
@@ -265,9 +158,10 @@ namespace Donut
}
m_objects_ubo->set_data(&data, sizeof(data));
+ m_objects_ubo->bind(3);
}
- void Engine::upload_disk_ubo()
+ void Engine::upload_disk_ubo()
{
float r1 = static_cast<float>(m_sag_a.m_rs * 2.2);
float r2 = static_cast<float>(m_sag_a.m_rs * 5.2);
@@ -276,28 +170,28 @@ namespace Donut
float disk_data[4] = { r1, r2, num, thickness };
m_disk_ubo->set_data(disk_data, sizeof(disk_data));
+ m_disk_ubo->bind(2);
}
- void Engine::update_physics(float delta_time)
+ void Engine::update_physics(float delta_time)
{
- for (auto& obj : m_objects)
+ for (auto& obj : m_objects)
{
- for (auto& obj2 : m_objects)
+ for (auto& obj2 : m_objects)
{
if (&obj == &obj2) continue;
float dx = obj2.m_pos_radius.x - obj.m_pos_radius.x;
float dy = obj2.m_pos_radius.y - obj.m_pos_radius.y;
float dz = obj2.m_pos_radius.z - obj.m_pos_radius.z;
float distance = sqrt(dx * dx + dy * dy + dz * dz);
-
- if (distance > 0)
+ if (distance > 0)
{
std::vector<double> direction = {dx / distance, dy / distance, dz / distance};
double Gforce = (G * obj.m_mass * obj2.m_mass) / (distance * distance);
double acc1 = Gforce / obj.m_mass;
std::vector<double> acc = {direction[0] * acc1, direction[1] * acc1, direction[2] * acc1};
-
- if (m_gravity)
+
+ if (m_gravity)
{
obj.m_velocity.x += static_cast<float>(acc[0]);
obj.m_velocity.y += static_cast<float>(acc[1]);
@@ -314,34 +208,49 @@ namespace Donut
void Engine::render_scene()
{
- glm::mat4 view = glm::lookAt(m_camera.get_orbital_position(), m_camera.get_target(), glm::vec3(0,1,0));
- glm::mat4 proj = glm::perspective(glm::radians(60.0f), float(m_width)/m_height, 1e9f, 1e14f);
- glm::mat4 view_proj = proj * view;
-
- generate_grid(m_objects);
- draw_grid(view_proj);
-
- RenderCommand::set_viewport(0, 0, m_width, m_height);
- dispatch_compute(m_camera);
- draw_full_screen_quad();
+ RenderCommand::clear();
+ m_shader_program->bind();
+ m_quad_vao->bind();
+ m_texture->bind(0);
+ RenderCommand::draw_arrays(6);
}
- std::string Engine::load_compute_shader(const std::string& path)
+ Ref<Shader> Engine::create_compute_program(const char* path)
{
std::ifstream in(path);
- if(!in.is_open())
+ if(!in.is_open())
{
std::cerr << "Failed to open compute shader: " << path << "\n";
- return "";
+ return nullptr;
}
-
std::stringstream ss;
ss << in.rdbuf();
- std::string result = ss.str();
- if (result.empty())
- std::cerr << "Warning: Compute shader file is empty: " << path << "\n";
- else
- std::cout << "Successfully loaded compute shader: " << path << " (size: " << result.size() << " bytes)\n";
- return result;
+ std::string src_str = ss.str();
+ return Ref<Shader>(Shader::create_compute("ComputeShader", src_str));
+ }
+
+ std::pair<Ref<VertexArray>, Ref<Texture2D>> Engine::quad_vao()
+ {
+ float quad_vertices[] =
+ {
+ -1.0f, 1.0f, 0.0f, 1.0f,
+ -1.0f, -1.0f, 0.0f, 0.0f,
+ 1.0f, -1.0f, 1.0f, 0.0f,
+ -1.0f, 1.0f, 0.0f, 1.0f,
+ 1.0f, -1.0f, 1.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f, 1.0f
+ };
+
+ auto vertex_buffer = Ref<VertexBuffer>(VertexBuffer::create(quad_vertices, static_cast<uint32_t>(sizeof(quad_vertices))));
+ VertexBufferLayout layout;
+ layout.push<float>(2);
+ layout.push<float>(2);
+ vertex_buffer->set_layout(layout);
+
+ auto vertex_array = Ref<VertexArray>(VertexArray::create());
+ vertex_array->add_vertex_buffer(vertex_buffer);
+ auto texture = Texture2D::create(get_compute_width(), m_compute_height);
+
+ return { vertex_array, texture };
}
}
diff --git a/src/engine/engine.h b/src/engine/engine.h
index 6f90efb..39791c1 100644
--- a/src/engine/engine.h
+++ b/src/engine/engine.h
@@ -2,10 +2,6 @@
#include <vector>
#include <iostream>
-#include <GLFW/glfw3.h>
-#include <glm/glm.hpp>
-#include <glm/gtc/matrix_transform.hpp>
-#include <glm/gtc/type_ptr.hpp>
#include <fstream>
#include <sstream>
#include <chrono>
@@ -15,16 +11,27 @@
#include "core/camera.h"
#include "rendering/renderer.h"
#include "rendering/shader.h"
-#include "rendering/texture.h"
#include "rendering/vertex_array.h"
+#include "rendering/texture.h"
#include "rendering/uniform_buffer.h"
+#include "rendering/texture_manager.h"
+
+#include <GLFW/glfw3.h>
+#include <glm/glm.hpp>
+#include <glm/gtc/matrix_transform.hpp>
+#include <glm/gtc/type_ptr.hpp>
+
+#define _USE_MATH_DEFINES
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
namespace Donut
{
const double c = 299792458.0;
const double G = 6.67430e-11;
- struct BlackHole
+ struct BlackHole
{
glm::vec3 m_position;
double m_mass;
@@ -32,13 +39,12 @@ namespace Donut
double m_rs;
BlackHole(glm::vec3 pos, float mass)
- : m_position(pos),
- m_mass(mass)
+ : m_position(pos), m_mass(mass)
{
m_rs = 2.0 * G * m_mass / (c * c);
}
- bool intercept(float px, float py, float pz) const
+ bool intercept(float px, float py, float pz) const
{
double dx = double(px) - double(m_position.x);
double dy = double(py) - double(m_position.y);
@@ -48,11 +54,11 @@ namespace Donut
}
};
- struct ObjectData
+ struct ObjectData
{
glm::vec4 m_pos_radius;
glm::vec4 m_color;
- float m_mass;
+ float m_mass;
glm::vec3 m_velocity = glm::vec3(0.0f, 0.0f, 0.0f);
};
@@ -62,8 +68,6 @@ namespace Donut
Engine();
~Engine() = default;
- void generate_grid(const std::vector<ObjectData>& objects);
- void draw_grid(const glm::mat4& view_proj);
void draw_full_screen_quad();
void dispatch_compute(const Camera& cam);
void upload_camera_ubo(const Camera& cam);
@@ -73,46 +77,47 @@ namespace Donut
void update_physics(float delta_time);
void update_window_dimensions();
- Camera& get_camera() { return m_camera; }
- const Camera& get_camera() const { return m_camera; }
-
- const std::vector<ObjectData>& get_objects() const { return m_objects; }
- std::vector<ObjectData>& get_objects() { return m_objects; }
-
- bool get_gravity() const { return m_gravity; }
- void set_gravity(bool gravity) { m_gravity = gravity; }
-
- int get_width() const { return m_width; }
- int get_height() const { return m_height; }
- int get_compute_width() const { return m_compute_width; }
- int get_compute_height() const { return m_compute_height; }
+ int get_width() const { return m_width; }
+ int get_height() const { return m_height; }
+
+ std::vector<ObjectData>& get_objects() { return m_objects; }
+ BlackHole& get_sag_a() { return m_sag_a; }
+ Camera& get_camera() { return m_camera; }
+ bool& get_gravity() { return m_gravity; }
+ void update_performance(float delta_time);
+ void set_target_fps(int fps) { m_target_fps = fps; }
+ int get_target_fps() const { return m_target_fps; }
+ float get_current_fps() const { return m_current_fps; }
+ void set_compute_height(int height) { m_compute_height = height; }
+ int get_compute_height() const { return m_compute_height; }
+ int get_compute_width() const { return (m_width * m_compute_height) / m_height; }
+ void update_compute_dimensions();
private:
- std::string create_basic_vertex_shader();
- std::string create_basic_fragment_shader();
- std::string load_compute_shader(const std::string& path);
+ Ref<Shader> create_compute_program(const char* path);
+ std::pair<Ref<VertexArray>, Ref<Texture2D>> quad_vao();
private:
- Ref<Shader> m_grid_shader;
- Ref<Shader> m_quad_shader;
- Ref<Shader> m_compute_shader;
- Ref<Texture2D> m_texture;
Ref<VertexArray> m_quad_vao;
- Ref<VertexArray> m_grid_vao;
+ Ref<Texture2D> m_texture;
+ Ref<Shader> m_shader_program;
+ Ref<Shader> m_compute_program;
Ref<UniformBuffer> m_camera_ubo;
Ref<UniformBuffer> m_disk_ubo;
Ref<UniformBuffer> m_objects_ubo;
-
- int m_grid_index_count = 0;
+
int m_width;
int m_height;
- int m_compute_width;
- int m_compute_height;
- float m_width_scale = 100000000000.0f;
- float m_height_scale = 75000000000.0f;
+ float m_width_f = 100*10e10f;
+ float m_height_f = 75*10e10f;
+
+ int m_target_fps = 60;
+ float m_current_fps = 60.0f;
+ float m_last_frame_time = 0.0f;
+ int m_compute_height = 320;
std::vector<ObjectData> m_objects;
BlackHole m_sag_a;
Camera m_camera;
bool m_gravity = false;
};
-}
+};
diff --git a/src/engine/object.cpp b/src/engine/object.cpp
deleted file mode 100644
index 2e76b16..0000000
--- a/src/engine/object.cpp
+++ /dev/null
@@ -1,46 +0,0 @@
-#include "object.h"
-
-namespace Donut
-{
- Ray::Ray(glm::vec3 o, glm::vec3 d)
- : m_origin(o),
- m_direction(glm::normalize(d)) { }
-
- Material::Material(glm::vec3 c, float s, float e)
- : m_color(c),
- m_specular(s),
- m_emission(e) { }
-
- Object::Object(glm::vec3 c, float r, Material m)
- : m_centre(c),
- m_radius(r),
- m_material(m) { }
-
- bool Object::intersect(Ray &ray, float &t)
- {
- glm::vec3 oc = ray.m_origin - m_centre;
- float a = glm::dot(ray.m_direction, ray.m_direction);
- float b = 2.0f * glm::dot(oc, ray.m_direction);
- float c = glm::dot(oc, oc) - m_radius * m_radius;
- double discriminant = b*b - 4*a*c;
-
- if(discriminant < 0)
- return false;
-
- float intercept = (-b - sqrt(discriminant)) / (2.0f*a);
- if(intercept < 0)
- {
- intercept = (-b + sqrt(discriminant)) / (2.0f*a);
- if(intercept<0)
- return false;
- }
-
- t = intercept;
- return true;
- }
-
- glm::vec3 Object::get_normal(glm::vec3 &point) const
- {
- return glm::normalize(point - m_centre);
- }
-}
diff --git a/src/engine/object.h b/src/engine/object.h
index 5f5d86f..c45815b 100644
--- a/src/engine/object.h
+++ b/src/engine/object.h
@@ -10,7 +10,9 @@ namespace Donut
glm::vec3 m_direction;
glm::vec3 m_origin;
- Ray(glm::vec3 o, glm::vec3 d);
+ Ray(glm::vec3 o, glm::vec3 d)
+ : m_origin(o),
+ m_direction(glm::normalize(d)) { }
};
class Material
@@ -20,7 +22,10 @@ namespace Donut
float m_specular;
float m_emission;
- Material(glm::vec3 c, float s, float e);
+ Material(glm::vec3 c, float s, float e)
+ : m_color(c),
+ m_specular(s),
+ m_emission(e) { }
};
class Object
@@ -30,9 +35,37 @@ namespace Donut
float m_radius;
Material m_material;
- Object(glm::vec3 c, float r, Material m);
+ Object(glm::vec3 c, float r, Material m)
+ : m_centre(c),
+ m_radius(r),
+ m_material(m) { }
- bool intersect(Ray &ray, float &t);
- glm::vec3 get_normal(glm::vec3 &point) const;
+ bool intersect(Ray &ray, float &t)
+ {
+ glm::vec3 oc = ray.m_origin - m_centre;
+ float a = glm::dot(ray.m_direction, ray.m_direction);
+ float b = 2.0f * glm::dot(oc, ray.m_direction);
+ float c = glm::dot(oc, oc) - m_radius * m_radius;
+ double discriminant = b*b - 4*a*c;
+
+ if(discriminant < 0)
+ return false;
+
+ float intercept = (-b - sqrt(discriminant)) / (2.0f*a);
+ if(intercept < 0)
+ {
+ intercept = (-b + sqrt(discriminant)) / (2.0f*a);
+ if(intercept<0)
+ return false;
+ }
+
+ t = intercept;
+ return true;
+ }
+
+ glm::vec3 get_normal(glm::vec3 &point) const
+ {
+ return glm::normalize(point - m_centre);
+ }
};
};
diff --git a/src/engine/scene.cpp b/src/engine/scene.cpp
deleted file mode 100644
index bfac1aa..0000000
--- a/src/engine/scene.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-#include "scene.h"
-
-namespace Donut
-{
- Scene::Scene()
- : m_light_pos(5.0f, 5.0f, 5.0f) { }
-
- glm::vec3 Scene::trace(Ray &ray)
- {
- float closest = std::numeric_limits<float>::infinity();
- const Object* hit_obj = nullptr;
-
- for(auto& obj : objs)
- {
- float t;
-
- if(obj.intersect(ray, t))
- if(t < closest)
- {
- closest = t;
- hit_obj = &obj;
- }
- }
-
- if(hit_obj)
- {
- glm::vec3 hit_point = ray.m_origin + ray.m_direction * closest;
- glm::vec3 normal = hit_obj->get_normal(hit_point);
- glm::vec3 light_dir = glm::normalize(m_light_pos - hit_point);
-
- float diff = std::max(glm::dot(normal, light_dir), 0.0f);
-
- Ray shadow_ray(hit_point + normal * 0.001f, light_dir);
- bool in_shadow = false;
-
- for(auto& obj : objs)
- {
- float t;
-
- if(obj.intersect(shadow_ray, t))
- {
- in_shadow = true;
- break;
- }
- }
-
- glm::vec3 color = hit_obj->m_material.m_color;
- float ambient = 0.1f;
-
- if (in_shadow)
- return color * ambient;
- return color * (ambient + diff * 0.9f);
- }
-
- return glm::vec3(0.0f, 0.0f, 0.1f);
- }
-}
diff --git a/src/engine/scene.h b/src/engine/scene.h
index abe582e..2ac9cd8 100644
--- a/src/engine/scene.h
+++ b/src/engine/scene.h
@@ -2,7 +2,6 @@
#include <vector>
#include <limits>
-#include <glm/glm.hpp>
#include "object.h"
@@ -14,7 +13,57 @@ namespace Donut
std::vector<Object> objs;
glm::vec3 m_light_pos;
- Scene();
- glm::vec3 trace(Ray &ray);
+ Scene()
+ : m_light_pos(5.0f, 5.0f, 5.0f) { }
+
+ glm::vec3 trace(Ray &ray)
+ {
+ float closest = std::numeric_limits<float>::infinity();
+ const Object* hit_obj = nullptr;
+
+ for(auto& obj : objs)
+ {
+ float t;
+
+ if(obj.intersect(ray, t))
+ if(t < closest)
+ {
+ closest = t;
+ hit_obj = &obj;
+ }
+ }
+
+ if(hit_obj)
+ {
+ glm::vec3 hit_point = ray.m_origin + ray.m_direction * closest;
+ glm::vec3 normal = hit_obj->get_normal(hit_point);
+ glm::vec3 light_dir = glm::normalize(m_light_pos - hit_point);
+
+ float diff = std::max(glm::dot(normal, light_dir), 0.0f);
+
+ Ray shadow_ray(hit_point + normal * 0.001f, light_dir);
+ bool in_shadow = false;
+
+ for(auto& obj : objs)
+ {
+ float t;
+
+ if(obj.intersect(shadow_ray, t))
+ {
+ in_shadow = true;
+ break;
+ }
+ }
+
+ glm::vec3 color = hit_obj->m_material.m_color;
+ float ambient = 0.1f;
+
+ if (in_shadow)
+ return color * ambient;
+ return color * (ambient + diff * 0.9f);
+ }
+
+ return glm::vec3(0.0f, 0.0f, 0.1f);
+ }
};
};