obj loading and proper raytracing

This commit is contained in:
Ben Kyd
2019-08-05 03:28:01 +01:00
parent 8ee9e71a0a
commit dcb4ff99cf
5 changed files with 2742 additions and 15 deletions

View File

@@ -1,10 +1,14 @@
#include "progressiverenderer.hpp"
#define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cpp
#include "../util/tiny_obj_loader.hpp"
#include "../common.hpp"
#include "../pixel.hpp"
#include "../display/displayinterface.hpp"
#include "../definitions/primatives/primative.hpp"
#include "../definitions/primatives/triangle.hpp"
#include "../definitions/camera.hpp"
#include "../definitions/scene.hpp"
#include "../definitions/ray.hpp"
@@ -18,7 +22,98 @@ void ProgressiveRenderer::Init(DisplayInterface* interface, Scene* scene) {
m_scene = scene;
}
glm::vec3 getNormal(glm::vec3 p0, glm::vec3 p1, glm::vec3 p2) {
glm::vec3 u = p1 - p0;
glm::vec3 v = p2 - p0;
glm::vec3 normal;
normal.x = u.y * v.z - u.z * v.y;
normal.y = u.z * v.x - u.x * v.z;
normal.z = u.x * v.y - u.y - v.x;
return normal;
}
std::vector<Primative*> loadTriangles(std::string path) {
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
std::string warn, err;
bool canLoad = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, path.c_str());
if (!err.empty() || !canLoad) {
std::cerr << "Cannot load obj '" << path << "': " << err << std::endl;
exit(0);
}
if (!warn.empty()) {
std::cerr << "Warning from obj loader while loading obj '" << path << "': " << warn << std::endl;
}
std::vector<Triangle*> triangles;
for (size_t s = 0; s < shapes.size(); s++) {
size_t index_offset = 0;
for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
int fv = shapes[s].mesh.num_face_vertices[f];
if (fv == 3) {
tinyobj::real_t avx[3];
tinyobj::real_t avy[3];
tinyobj::real_t avz[3];
tinyobj::real_t anx[3];
tinyobj::real_t any[3];
tinyobj::real_t anz[3];
for (size_t v = 0; v < fv; v++) {
tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
avx[v] = attrib.vertices[3 * idx.vertex_index + 0];
avy[v] = attrib.vertices[3 * idx.vertex_index + 1];
avz[v] = attrib.vertices[3 * idx.vertex_index + 2];
anx[v] = attrib.normals[3 * idx.normal_index + 0];
any[v] = attrib.normals[3 * idx.normal_index + 1];
anz[v] = attrib.normals[3 * idx.normal_index + 2];
}
tinyobj::material_t material = materials[shapes[s].mesh.material_ids[f]];
// glm::vec3 normal = getNormal({avx[0], avy[0], avz[0]},
// {avx[1], avy[1], avz[1]},
// {avx[2], avy[2], avz[2]});
Triangle* tmp = new Triangle {
{avx[0], avy[0], avz[0]},
{avx[1], avy[1], avz[1]},
{avx[2], avy[2], avz[2]},
{anx[0], any[0], anz[0]},
{anx[1], any[1], anz[1]},
{anx[2], any[2], anz[2]},
};
triangles.push_back(tmp);
}
index_offset += fv;
}
}
std::vector<Primative*> objects;
for (const auto& triangle : triangles)
objects.push_back(triangle);
return objects;
}
void ProgressiveRenderer::Render() {
while (m_interface->Active) {
// Take input
@@ -31,22 +126,20 @@ void ProgressiveRenderer::Render() {
for (int y = 0; y < m_scene->h; y++) {
Ray ray = m_scene->camera->CastRay(x, y);
for (int i = 0; i < m_scene->objects.size(); i++) {
Primative* smh = m_scene->objects[i];
float t = 0;
if (smh->DoesIntersect(ray, t)) {
if (smh->type == TYPE_SPHERE) {
m_interface->SetPixelSafe(x, y, 0x00FF00);
} else if (smh->type == TYPE_PLANE) {
m_interface->SetPixelSafe(x, y, 0x00FFFF);
} else {
m_interface->SetPixelSafe(x, y, 0xFF00FF);
}
}
float t, i;
bool didhit = TraceRay(ray, m_scene, t, i);
if (!didhit) {
m_interface->SetPixelSafe(x, y, 0xFFFFFF);
continue;
}
}
Primative* hit = m_scene->objects[i];
m_scene->objects[1]->center.y += 0.01f;
if (hit->type == TYPE_SPHERE) {
m_interface->SetPixelSafe(x, y, 0xFFFF00);
}
}
// Swap framebuffers
m_interface->Update();