Files
inferno-hart/src/raytracing/renderer.cpp
Ben Kyd 0cc5570098
Some checks failed
C/C++ CI / build (push) Has been cancelled
tracing
2024-01-28 23:20:39 +00:00

167 lines
5.4 KiB
C++

#include "renderer.hpp"
#include <graphics.hpp>
#include <graphics/rendertarget.hpp>
#include <graphics/vkrenderer.hpp>
#include <raytracing/hit.hpp>
#include <raytracing/object_tracer.hpp>
#include <raytracing/ray.hpp>
#include <scene/camera.hpp>
#include <scene/mesh.hpp>
#include <scene/scene.hpp>
// #include "preview/debug.hpp"
#include "ray_source.hpp"
#include <yolo/yolo.hpp>
#include <scene/camera.hpp>
#include <cstring>
#include <iostream>
namespace inferno::graphics {
RayRenderer* rayr_create(VulkanRenderer* renderer, scene::Scene* scene)
{
RayRenderer* ray = new RayRenderer;
ray->Scene = scene;
ray->Renderer = renderer;
auto camera = scene::scene_get_camera(scene);
ray->Viewport.offset.x = 0;
ray->Viewport.offset.y = 0;
ray->Viewport.extent.width = camera_ray_get_viewport(camera).x;
ray->Viewport.extent.height = camera_ray_get_viewport(camera).y;
ray->HasViewportChanged = true;
ray->RenderData
= new glm::fvec4[ray->Viewport.extent.width * ray->Viewport.extent.height];
memset(ray->RenderData, 0,
ray->Viewport.extent.width * ray->Viewport.extent.height * sizeof(glm::fvec4));
ray->RayRenderTarget = graphics::dynamic_rendertarget_create(
renderer->Device, ray->Viewport.extent, VK_FORMAT_R32G32B32A32_SFLOAT);
rayr_set_viewport(ray, camera);
return ray;
}
void rayr_cleanup(RayRenderer* renderer) { delete[] renderer->RenderData; }
void rayr_draw_ui(RayRenderer* renderer) { }
void rayr_set_viewport(RayRenderer* renderer, Camera* camera)
{
auto viewport = camera_ray_get_viewport(camera);
renderer->Viewport.offset.x = 0;
renderer->Viewport.offset.y = 0;
renderer->Viewport.extent.width = viewport.x;
renderer->Viewport.extent.height = viewport.y;
renderer->HasViewportChanged = true;
delete[] renderer->RenderData;
renderer->RenderData
= new glm::fvec4[renderer->Viewport.extent.width * renderer->Viewport.extent.height];
memset(renderer->RenderData, 1,
renderer->Viewport.extent.width * renderer->Viewport.extent.height * sizeof(glm::fvec4));
// Now resize the rendertarget
graphics::dynamic_rendertarget_recreate(
renderer->RayRenderTarget, renderer->Viewport.extent);
}
DynamicCPUTarget* rayr_get_target(RayRenderer* renderer)
{
return renderer->RayRenderTarget;
}
glm::fvec4* rayr_get_render_data(RayRenderer* renderer) { return renderer->RenderData; }
void rayr_prepare(RayRenderer* renderer)
{
// TODO: This is TEMP
memset(renderer->RenderData, 1,
renderer->Viewport.extent.width * renderer->Viewport.extent.height
* sizeof(glm::fvec4));
assert(renderer->Scene != nullptr);
if (scene::scene_did_update(renderer->Scene)) {
yolo::debug("Scene updated, rebuilding acceleration structure");
// renderer->AccelerationInterface->newScene(renderer->CurrentScene);
}
}
void rayr_draw(RayRenderer* renderer)
{
rayr_prepare(renderer);
scene::scene_frame_tick(renderer->Scene);
// TODO: Rays should definately be bump allocated if possible, this is KBs of
// ray data and nothing else being reallocated every frame for no reason
rays::ReferencedRayField startRays
= rays::generate_initial_rays(scene::scene_get_camera(renderer->Scene), true);
#pragma omp parallel for
for (int x = 0; x < renderer->Viewport.extent.width; x++) {
for (int y = 0; y < renderer->Viewport.extent.height; y++) {
// renderer->RenderData[y * renderer->Viewport.extent.width + x]
// = { 1.0, 1.0, 1.0, 1.0 };
rays::Ray* ray = startRays.Field[x * renderer->Viewport.extent.height + y];
rays::HitInfo* closest_hit = nullptr;
for (auto& obj : scene::scene_get_renderables(renderer->Scene)) {
rays::HitInfo* hit = rays::object_ray_collide(obj, ray);
if (hit->Did) {
if (closest_hit == nullptr) {
closest_hit = hit;
} else {
bool is_closer = hit->Distance < closest_hit->Distance;
if (is_closer) {
delete closest_hit;
closest_hit = hit;
} else {
delete hit;
}
}
}
if (hit->Did) {
glm::vec3 hit_distance = glm::vec3 { hit->Distance };
hit_distance /= 10;
renderer->RenderData[y * renderer->Viewport.extent.width + x]
= { hit_distance, 1.0 };
}
delete hit;
}
}
}
graphics::dynamic_rendertarget_update(renderer->RayRenderTarget,
(void*)renderer->RenderData, renderer->Viewport.extent);
}
//
// void RayRenderer::computeHit(HitInfo* info)
// {
// static float mind = 100000.0f;
// static float maxd = 0.0f;
// // TODO: Make sure signal is started
// if (!(*mCurrentRefTable).count(info->Caller->Reference)) {
// yolo::warn("Why is the ray not in the map?!");
// return;
// }
// glm::ivec2 pos = (*mCurrentRefTable)[info->Caller->Reference];
// float d = info->Distance;
// if (d < mind)
// mind = d;
// if (d > maxd)
// maxd = d;
// float n = (d - mind) / (maxd - mind);
// mTarget[pos.y * mRenderTargetSize.x + pos.x] = { n, n, n, 1.0f };
// }
}