Merge pull request #1 from benkyd/rewrite

Rewrite complete
This commit is contained in:
Benjamin Kyd
2023-10-16 11:51:00 +01:00
committed by GitHub
32 changed files with 662 additions and 1011 deletions

View File

@@ -25,7 +25,8 @@ elseif (APPLE)
target_compile_options(inferno PRIVATE -O1)
endif()
else()
target_compile_options(inferno PRIVATE -std=c++17)
target_compile_options(inferno PRIVATE -std=c++20)
target_compile_options(inferno PRIVATE -m64)
if (CMAKE_BUILD_TYPE MATCHES "Debug")
target_compile_options(inferno PRIVATE -O1)
target_compile_options(inferno PRIVATE -Wall)

View File

@@ -8,7 +8,10 @@
namespace inferno::graphics {
struct _CameraImpl;
typedef struct _CameraImpl {
bool DidUpdate;
std::mutex CamMutex;
} _CameraImpl;
typedef struct Viewport {
glm::ivec2 Raster;
@@ -20,7 +23,7 @@ typedef struct Camera {
glm::mat4 ProjectionMatrix;
glm::mat4 LookMatrix;
std::shared_ptr<Viewport> Views;
Viewport Views;
float MouseSensitivity = 0.4f;
float Speed = 0.1f;
@@ -30,33 +33,35 @@ typedef struct Camera {
glm::vec3 Position = {};
glm::vec3 LookDirection = {};
std::unique_ptr<_CameraImpl> _impl;
_CameraImpl* _impl;
} Camera;
std::unique_ptr<Camera> camera_create();
void camera_cleanup(std::unique_ptr<Camera>& camera);
Camera* camera_create();
void camera_cleanup(Camera* camera);
void camera_update(std::unique_ptr<Camera>& camera);
bool camera_did_update(std::unique_ptr<Camera>& camera);
void camera_new_frame(std::unique_ptr<Camera>& camera);
void camera_update(Camera* camera);
bool camera_did_update(Camera* camera);
void camera_new_frame(Camera* camera);
glm::mat4 camera_get_view(std::unique_ptr<Camera>& camera);
glm::mat4 camera_get_projection(std::unique_ptr<Camera>& camera);
glm::mat4 camera_get_look(std::unique_ptr<Camera>& camera);
glm::mat4 camera_get_view(Camera* camera);
glm::mat4 camera_get_projection(Camera* camera);
glm::mat4 camera_get_look(Camera* camera);
void raster_set_viewport(std::unique_ptr<Camera>& camera, glm::ivec2 viewport);
glm::ivec2 raster_get_viewport(std::unique_ptr<Camera>& camera);
void raster_set_viewport(Camera* camera, glm::ivec2 viewport);
glm::ivec2 raster_get_viewport(Camera* camera);
void ray_set_viewport(std::unique_ptr<Camera>& camera, glm::ivec2 viewport);
glm::ivec2 ray_get_viewport(std::unique_ptr<Camera>& camera);
void ray_set_viewport(Camera* camera, glm::ivec2 viewport);
glm::ivec2 ray_get_viewport(Camera* camera);
void camera_move(std::unique_ptr<Camera>& camera, uint8_t movement_delta);
void camera_mouse_move(std::unique_ptr<Camera>& camera, glm::vec2 mouse_delta);
void camera_move(Camera* camera, uint8_t movement_delta);
void camera_mouse_move(Camera* camera, glm::vec2 mouse_delta);
void camera_set_position(std::unique_ptr<Camera>& camera, glm::vec3 position);
void camera_set_euler_look(std::unique_ptr<Camera>& camera, float roll,
void camera_set_position(Camera* camera, glm::vec3 position);
void camera_set_euler_look(Camera* camera, float roll,
float pitch, float yaw);
void camera_set_look(std::unique_ptr<Camera>& camera,
void camera_set_look(Camera* camera,
glm::vec3 look_direction);
glm::vec3 camera_get_position(Camera* camera);
} // namespace inferno::graphics

View File

@@ -1,185 +0,0 @@
#include "hart_directory.hpp"
#include "inferno_hart.hpp"
#include <yolo/yolo.hpp>
#include <iostream>
using namespace inferno;
HARTModuleDirectory::HARTModuleDirectory()
{
}
HARTModuleDirectory::~HARTModuleDirectory()
{
}
std::vector<HARTModuleDirectory::discoveryEntry> HARTModuleDirectory::discoverModules(std::filesystem::path folder, bool recurse)
{
if (!std::filesystem::exists(folder)) return { };
if (!std::filesystem::is_directory(folder))
{
return { this->registerModule(folder) };
}
std::error_code err;
if (recurse)
{
for (const auto& file : std::filesystem::recursive_directory_iterator(folder, err))
{
if (file.path().extension() == HART_EXTENSION)
{
this->registerModule(file);
}
}
} else
{
for (const auto& file : std::filesystem::directory_iterator(folder, err))
{
if (file.path().extension() == HART_EXTENSION)
{
this->registerModule(file);
}
}
}
return { };
}
HARTModuleDirectory::discoveryEntry HARTModuleDirectory::registerModule(std::filesystem::path file)
{
yolo::info("Registering module at {}", file.c_str());
discoveryEntry entry;
entry.Location = file;
#ifdef _WIN32
entry.Handle = LoadLibraryA(file.c_str());
if (entry.Handle == NULL)
{
yolo::error("Cannot load module at {}.", file.c_str());
entry.Handle = NULL; entry.DidLink = false;
return entry;
}
HART_CREDIT_F credit = (HART_CREDIT_F)GetProcAddress(entry.Handle, "_CREDIT");
entry.InitCallback = (HART_INIT_F)GetProcAddress(entry.Handle, "_GET");
entry.DestroyCallback = (HART_DESTROY_F)GetProcAddress(entry.Handle, "_DESTROY");
#else // UNIX-Like
entry.Handle = dlopen(file.c_str(), RTLD_NOW | RTLD_LOCAL);
if (entry.Handle == NULL)
{
yolo::error("Cannot load module at ", dlerror());
entry.Handle = NULL; entry.DidLink = false;
return entry;
}
HART_CREDIT_F credit = (HART_CREDIT_F)dlsym(entry.Handle, "_CREDIT");
entry.InitCallback = (HART_INIT_F)dlsym(entry.Handle, "_GET");
entry.DestroyCallback = (HART_DESTROY_F)dlsym(entry.Handle, "_DESTROY");
#endif
if (credit == NULL)
{
yolo::error("Cannot load module at {}... No credit...", file.c_str());
entry.Handle = NULL; entry.DidLink = false;
return entry;
}
if (entry.InitCallback == NULL)
{
yolo::error("Cannot load module at {}... No get...", file.c_str());
entry.Handle = NULL; entry.DidLink = false;
return entry;
}
if (entry.DestroyCallback == NULL)
{
yolo::error("Cannot load module at {}... No destroy...", file.c_str());
entry.Handle = NULL; entry.DidLink = false;
return entry;
}
entry.Credit = (ModuleCredit*)credit();
yolo::info("Module {} v{}.{}.{} by {}", entry.Credit->ModuleName,
entry.Credit->VersionMajor,
entry.Credit->VersionMinor,
entry.Credit->VersionBuild,
entry.Credit->AuthorName);
entry.DidLink = true;
mEntries[entry.Credit->ModuleName] = { entry, nullptr };
if (mEntries.size() == 1)
{
// this is the first, make it active - or else
mActiveModule = entry.Credit->ModuleName;
this->load(mActiveModule);
}
return entry;
}
std::vector<std::string> HARTModuleDirectory::getModules()
{
std::vector<std::string> keys;
for(auto kv : mEntries)
{
keys.push_back(kv.first);
}
return keys;
}
void HARTModuleDirectory::setActive(std::string moduleName)
{
if (moduleName == mActiveModule) return;
this->destroy(mActiveModule);
mActiveModule = moduleName;
this->load(mActiveModule);
}
void HARTModuleDirectory::setActiveIndex(int index)
{
std::vector<std::string> keys = this->getModules();
this->setActive(keys[index]);
}
HARTModule* HARTModuleDirectory::getActiveModule()
{
return mEntries[mActiveModule].Module;
}
std::string HARTModuleDirectory::getActive()
{
return mActiveModule;
}
int HARTModuleDirectory::getActiveIndex()
{
std::vector<std::string> keys = this->getModules();
for (int i = 0; i < keys.size(); i++)
{
if (keys[i] == mActiveModule) return i;
}
return -1; // this should never happen
}
ModuleCredit* HARTModuleDirectory::getActiveCredit()
{
return mEntries[mActiveModule].Discovery.Credit;
}
void HARTModuleDirectory::load(std::string moduleName)
{
HARTModule* mod = (HARTModule*)mEntries[moduleName].Discovery.InitCallback();
mEntries[moduleName].Module = mod;
mEntries[moduleName].Active = true;
}
void HARTModuleDirectory::destroy(std::string moduleName)
{
mEntries[moduleName].Discovery.DestroyCallback(mEntries[moduleName].Module);
mEntries[moduleName].Module = nullptr;
mEntries[moduleName].Active = false;
}

View File

@@ -1,71 +0,0 @@
#pragma once
// INFERNO-HART Modules
// _GET returns derived HARTModule
// _DESTROY returns void but takes derived HARTModule
// _CREDIT returns ModuleCredit
// THIS IS SHARED DO __NOT__ REINCLUDE libhart/thirdparty
#include <inferno_hart.hpp>
#include <filesystem>
#include <string>
#include <vector>
#include <unordered_map>
namespace inferno {
class HARTModule;
struct ModuleCredit;
class HARTModuleDirectory
{
public:
HARTModuleDirectory();
~HARTModuleDirectory();
struct discoveryEntry
{
std::filesystem::path Location;
bool DidLink = false;
#ifdef _WIN32
HMODULE Handle;
#else // UNIX-Like
void* Handle;
#endif
ModuleCredit* Credit;
HART_INIT_F InitCallback;
HART_DESTROY_F DestroyCallback;
};
struct moduleEntry
{
discoveryEntry Discovery;
HARTModule* Module;
bool Active;
};
// This can take a file or a directory, and inside the directory discover recursively or not
std::vector<discoveryEntry> discoverModules(std::filesystem::path path, bool recurse = false);
discoveryEntry registerModule(std::filesystem::path file);
std::vector<std::string> getModules();
void setActive(std::string moduleName);
void setActiveIndex(int index);
HARTModule* getActiveModule();
std::string getActive();
int getActiveIndex();
ModuleCredit* getActiveCredit();
void load(std::string moduleName);
void destroy(std::string moduleName);
private:
std::string mActiveModule;
std::unordered_map<std::string, moduleEntry> mEntries;
};
}

View File

@@ -1,83 +0,0 @@
#include "hart_module.hpp"
#include <renderer/ray_source.hpp>
#include <renderer/renderer.hpp>
#include <scene/scene.hpp>
#include <scene/mesh.hpp>
#include <yolo/yolo.hpp>
#include <vector>
using namespace inferno;
HHM::HHM()
: mDirectory()
{
mDirectory.discoverModules("./hart/", true);
}
HHM::~HHM()
{
}
HARTModuleDirectory* HHM::getModuleDirectory()
{
return &mDirectory;
}
HARTModule::EModuleState HHM::getModuleState()
{
HARTModule* mod = mDirectory.getActiveModule();
return mod->getState();
}
void HHM::newScene(Scene* scene)
{
HARTModule* mod = mDirectory.getActiveModule();
std::vector<Mesh*> meshs = scene->getRenderables();
// TODO: This may not be the way i want to approach it
// as submitTris should take maybe a mesh ID and then the mesh data
// as it is now, submitTris assumes it's getting the whole scene
// which would involve a lot of mesh copying (avoid!) if i were to chain them
for (auto* mesh : meshs) {
void* verticies; void* normals; void* indicies;
int vertexCount = mesh->getVerticies(&verticies, &normals);
int indexCount = mesh->getIndicies(&indicies);
yolo::debug("Mesh for module ready... {} {}", verticies, normals);
mod->submitTris(verticies, normals, vertexCount, indicies, indexCount);
}
}
void HHM::notifySceneUpdate()
{
HARTModule* mod = mDirectory.getActiveModule();
mod->updateTris();
}
void rayHitCallback(void* hhm, HitInfo* hit)
{
((HHM*)hhm)->rayReturn(hit);
}
void HHM::rayReturn(HitInfo* hit)
{
Renderer->computeHit(hit);
}
void HHM::bounce(Ray* newRay)
{
}
void HHM::startTrace(RayField sourceScatter)
{
// TODO: Signal start
HARTModule* mod = mDirectory.getActiveModule();
mod->passContext((void*)this, &rayHitCallback);
yolo::debug("SubmitQueue {}", sourceScatter.size());
mod->submitQueue(sourceScatter);
mod->start();
}

View File

@@ -1,42 +0,0 @@
#pragma once
// the HHM (Hamlin Hamlin McGill) aka the Head HART Module keeps track of the module
// and gives the renderer a cleaner interface to talk to a HART Module
#include <vector>
#include <graphics.hpp>
#include "hart_directory.hpp"
namespace inferno {
class Scene;
class Ray;
class HitInfo;
class HARTModule;
class RayRenderer;
class HHM
{
public:
HHM();
~HHM();
HARTModuleDirectory* getModuleDirectory();
HARTModule::EModuleState getModuleState();
void newScene(Scene* scene);
void notifySceneUpdate();
void rayReturn(HitInfo* hit);
void bounce(Ray* newRay);
void startTrace(RayField sourceScatter);
RayRenderer* Renderer;
private:
HARTModuleDirectory mDirectory;
};
}

View File

@@ -2,19 +2,16 @@
#include <version.hpp>
// #include "gui/layout.hpp"
#include "imgui/imgui.h"
#include "scene/scene.hpp"
#include "window.hpp"
// #include "hart_module.hpp"
// #include "hart_directory.hpp"
// #include "preview_renderer/renderer.hpp"
// #include "preview_renderer/shader.hpp"
// #include "renderer/dispatcher.hpp"
// #include "renderer/renderer.hpp"
#include "preview_renderer/renderer.hpp"
#include "preview_renderer/shader.hpp"
#include "scene/camera.hpp"
// #include "scene/scene.hpp"
// #include "scene/material.hpp"
// #include "scene/mesh.hpp"
#include "scene/material.hpp"
#include "scene/mesh.hpp"
#include "scene/scene.hpp"
#include <yolo/yolo.hpp>
@@ -25,24 +22,45 @@
namespace inferno {
std::unique_ptr<InfernoApp> inferno_create()
InfernoApp* inferno_create()
{
// MOTD
yolo::info("INFERNO HART v" INFERNO_VERSION);
std::unique_ptr<InfernoApp> app = std::make_unique<InfernoApp>();
app->Input = std::make_unique<InfernoInput>();
InfernoApp* app = new InfernoApp;
app->Input = new InfernoInput;
app->Scene = scene::scene_create();
// Create window
graphics::window_create("Inferno v" INFERNO_VERSION, 1280, 720);
// setup the scene
scene::Material* basicMaterial = new scene::Material("basic");
graphics::Shader* basicShader = graphics::shader_create();
graphics::shader_load(basicShader, "res/shaders/basic.glsl");
graphics::shader_link(basicShader);
basicMaterial->setGlShader(basicShader);
scene::Mesh* mesh = new scene::Mesh;
// mesh->loadOBJ("res/cornell-box.obj");
mesh->loadOBJ("res/sponza.obj");
mesh->ready();
mesh->setMaterial(basicMaterial);
scene::SceneObject* object = scene::scene_object_create();
scene::scene_object_add_mesh(object, mesh);
scene::scene_add_object(app->Scene, object);
app->PreviewRenderer = graphics::preview_create();
return app;
}
void inferno_cleanup(std::unique_ptr<InfernoApp>& app)
void inferno_cleanup(InfernoApp* app)
{
graphics::window_cleanup();
app.reset();
delete app;
}
static void inferno_gui_help_marker(const char* desc)
@@ -57,7 +75,7 @@ static void inferno_gui_help_marker(const char* desc)
}
}
void inferno_preset_gui(std::unique_ptr<InfernoApp>& app)
void inferno_preset_gui(InfernoApp* app)
{
ImGuiID dockspace_id = ImGui::GetID("main");
@@ -65,7 +83,7 @@ void inferno_preset_gui(std::unique_ptr<InfernoApp>& app)
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace); // Add empty node
ImGui::DockBuilderSetNodeSize(dockspace_id, { 1000, 1000 });
ImGuiID dock_main_id = dockspace_id; // This variable will track the document node, however we are not using it here as we aren't docking anything into it.
ImGuiID dock_main_id = dockspace_id;
ImGuiID dock_left = ImGui::DockBuilderSplitNode(dock_main_id, ImGuiDir_Left, 0.5f, NULL, &dock_main_id);
ImGui::DockBuilderDockWindow("Preview", dock_left);
ImGui::DockBuilderDockWindow("Render", dock_main_id);
@@ -74,7 +92,7 @@ void inferno_preset_gui(std::unique_ptr<InfernoApp>& app)
yolo::info("LAYOUT SET TO DEFAULT");
}
void inferno_move_input(std::unique_ptr<InfernoApp>& app)
void inferno_move_input(InfernoApp* app)
{
static GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
glfwSetCursor(graphics::window_get_glfw_window(), cursor);
@@ -113,15 +131,14 @@ void inferno_move_input(std::unique_ptr<InfernoApp>& app)
app->Input->MovementDelta |= 0b00000100;
}
void inferno_stop_move_input(std::unique_ptr<InfernoApp>& app)
void inferno_stop_move_input(InfernoApp* app)
{
app->Input->MovementDelta = 0x0;
app->Input->MouseDelta = { 0.0f, 0.0f };
}
int inferno_run(std::unique_ptr<InfernoApp>& app)
int inferno_run(InfernoApp* app)
{
while (true) {
if (!graphics::window_new_frame())
break;
@@ -134,6 +151,11 @@ int inferno_run(std::unique_ptr<InfernoApp>& app)
}
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
if (glm::length(app->Input->MouseDelta) > 0.0f)
graphics::camera_mouse_move(app->Scene->Camera, app->Input->MouseDelta);
if (app->Input->MovementDelta != 0b00000000)
graphics::camera_move(app->Scene->Camera, app->Input->MovementDelta);
// Menu Bar
static bool showPreview = true;
static bool showRenderSettings = true;
@@ -162,22 +184,78 @@ int inferno_run(std::unique_ptr<InfernoApp>& app)
} else {
inferno_stop_move_input(app);
}
if (glm::length(app->Input->MouseDelta) > 0.0f)
graphics::camera_mouse_move(app->Camera, app->Input->MouseDelta);
if (app->Input->MovementDelta != 0b00000000)
graphics::camera_move(app->Camera, app->Input->MovementDelta);
graphics::raster_set_viewport(app->Camera, { ImGui::GetWindowSize().x, ImGui::GetWindowSize().y });
mRasterRenderer->setTargetSize({ ImGui::GetWindowSize().x, ImGui::GetWindowSize().y });
mRasterRenderer->prepare();
mRasterRenderer->draw();
graphics::raster_set_viewport(scene::scene_get_camera(app->Scene),
{ ImGui::GetWindowSize().x, ImGui::GetWindowSize().y });
graphics::preview_draw(app->PreviewRenderer, app->Scene);
ImGui::Image((ImTextureID)mRasterRenderer->getRenderedTexture(), inderno { mRasterRenderer->getTargetSize().x, mRasterRenderer->getTargetSize().y },
ImTextureID texture = (ImTextureID)graphics::preview_get_rendered_texture(app->PreviewRenderer);
ImGui::Image(
texture,
{ ImGui::GetWindowSize().x, ImGui::GetWindowSize().y },
ImVec2(0, 1), ImVec2(1, 0));
glBindFramebuffer(GL_FRAMEBUFFER, 0);
ImGui::End();
}
if (showRenderSettings && ImGui::Begin("Inferno HART")) {
if (ImGui::TreeNode("Camera")) {
ImGui::PushItemWidth(100);
ImGui::Text("Camera Position X,Y,Z");
graphics::Camera* camera = scene::scene_get_camera(app->Scene);
bool positionUpdated = false;
ImGui::DragFloat("X", &camera->Position.x, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
ImGui::SameLine();
if (ImGui::IsItemEdited())
positionUpdated = true;
ImGui::DragFloat("Y", &camera->Position.y, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
ImGui::SameLine();
if (ImGui::IsItemEdited())
positionUpdated = true;
ImGui::DragFloat("Z", &camera->Position.z, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
if (ImGui::IsItemEdited())
positionUpdated = true;
if (positionUpdated)
graphics::camera_set_position(camera, graphics::camera_get_position(camera));
bool viewUpdated = false;
ImGui::Text("Camera Look Yaw, Pitch, Roll");
ImGui::DragFloat("Yaw", &camera->Yaw, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
ImGui::SameLine();
if (ImGui::IsItemEdited())
viewUpdated = true;
ImGui::DragFloat("Pitch", &camera->Pitch, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
ImGui::SameLine();
if (ImGui::IsItemEdited())
viewUpdated = true;
ImGui::DragFloat("Roll", &camera->Roll, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
if (ImGui::IsItemEdited())
viewUpdated = true;
ImGui::PopItemWidth();
ImGui::PushItemWidth(300);
ImGui::Text("Camera Zoom");
ImGui::DragFloat("Zoom", &camera->FOV, -0.1f, 0.01f, 180.0f, "%.2f", ImGuiSliderFlags_None);
ImGui::SameLine();
if (ImGui::IsItemEdited())
viewUpdated = true;
if (viewUpdated)
graphics::camera_update(camera);
ImGui::PopItemWidth();
ImGui::TreePop();
}
ImGui::End();
}
if (showDemoWindow) {
ImGui::ShowDemoWindow();
}
// clang-format off
GLenum err;
while((err = glGetError()) != GL_NO_ERROR) {

View File

@@ -1,6 +1,10 @@
#pragma once
#include "graphics.hpp"
#include "scene/scene.hpp"
#include "scene/camera.hpp"
// #include "renderer/renderer.hpp"
#include "preview_renderer/renderer.hpp"
#include <memory>
@@ -10,21 +14,27 @@ namespace graphics {
struct Camera;
}
namespace scene {
struct Scene;
}
typedef struct InfernoInput {
glm::vec2 MouseDelta;
uint8_t MovementDelta;
glm::vec2 MouseDelta = {0.0f, 0.0f};
uint8_t MovementDelta = 0;
} InfernoInput;
typedef struct InfernoApp {
std::unique_ptr<InfernoInput> Input;
std::unique_ptr<graphics::Camera> Camera;
InfernoInput* Input;
scene::Scene* Scene;
graphics::PreviewRenderer* PreviewRenderer;
// graphics::RayRenderer* RayRenderer;
} InfernoApp;
std::unique_ptr<InfernoApp> inferno_create();
void inferno_cleanup(std::unique_ptr<InfernoApp>& app);
void inferno_preset_gui(std::unique_ptr<InfernoApp>& app);
void inferno_move_input(std::unique_ptr<InfernoApp>& app);
void inferno_stop_move_input(std::unique_ptr<InfernoApp>& app);
int inferno_run(std::unique_ptr<InfernoApp>& app);
InfernoApp* inferno_create();
void inferno_cleanup(InfernoApp* app);
void inferno_preset_gui(InfernoApp* app);
void inferno_move_input(InfernoApp* app);
void inferno_stop_move_input(InfernoApp* app);
int inferno_run(InfernoApp* app);
}
} // namespace inferno

View File

@@ -5,6 +5,6 @@
int main(int argc, char** argv)
{
std::unique_ptr<inferno::InfernoApp> inferno = inferno::inferno_create();
auto inferno = inferno::inferno_create();
return inferno::inferno_run(inferno);
}

View File

@@ -1,19 +1,24 @@
#include "renderer.hpp"
#include "scene/object.hpp"
#include "shader.hpp"
#include <yolo/yolo.hpp>
#include <algorithm>
#include <scene/camera.hpp>
#include <scene/material.hpp>
#include <scene/mesh.hpp>
#include <scene/object.hpp>
#include <scene/scene.hpp>
#include <iostream>
namespace inferno::graphics {
std::unique_ptr<PreviewRenderer> preview_create()
PreviewRenderer* preview_create()
{
std::unique_ptr<PreviewRenderer> renderer = std::make_unique<PreviewRenderer>();
PreviewRenderer* renderer = new PreviewRenderer;
glGenFramebuffers(1, &renderer->RenderTarget);
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
@@ -44,18 +49,23 @@ std::unique_ptr<PreviewRenderer> preview_create()
return renderer;
}
void preview_cleanup(std::unique_ptr<PreviewRenderer>& renderer)
void preview_cleanup(PreviewRenderer* renderer)
{
}
void preview_set_scene(std::unique_ptr<PreviewRenderer>& renderer, std::shared_ptr<Scene> scene)
void preview_set_viewport(PreviewRenderer* renderer, Viewport* viewport)
{
renderer->CurrentScene = scene;
}
void preview_set_viewport(std::unique_ptr<PreviewRenderer>& renderer, std::shared_ptr<const Viewport> viewport)
GLuint preview_get_rendered_texture(PreviewRenderer* renderer)
{
renderer->RenderTargetSize = viewport;
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
return renderer->RenderTargetTexture;
}
void preview_draw(PreviewRenderer* renderer, scene::Scene* scene)
{
const glm::ivec2& viewport = graphics::raster_get_viewport(scene::scene_get_camera(scene));
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
@@ -63,8 +73,8 @@ void preview_set_viewport(std::unique_ptr<PreviewRenderer>& renderer, std::share
GL_TEXTURE_2D,
0,
GL_RGB,
viewport->Raster.x,
viewport->Raster.y,
viewport.x,
viewport.y,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
@@ -74,61 +84,55 @@ void preview_set_viewport(std::unique_ptr<PreviewRenderer>& renderer, std::share
glTexImage2D(GL_TEXTURE_2D,
0,
GL_DEPTH24_STENCIL8,
viewport->Raster.x,
viewport->Raster.y,
viewport.x,
viewport.y,
0,
GL_DEPTH_COMPONENT,
GL_FLOAT,
NULL);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
const glm::ivec2& preview_get_viewport(std::unique_ptr<PreviewRenderer>& renderer)
{
return renderer->RenderTargetSize->Raster;
}
// clear
GLuint preview_get_rendered_texture(std::unique_ptr<PreviewRenderer>& renderer)
{
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
return renderer->RenderTargetTexture;
}
void preview_prepare(std::unique_ptr<PreviewRenderer>& renderer)
{
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
glClearColor(0.1, 0.1, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
void preview_draw(std::unique_ptr<PreviewRenderer>& renderer)
{
// draw
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
glViewport(0,
0,
renderer->RenderTargetSize->Raster.x,
renderer->RenderTargetSize->Raster.y);
renderer->Viewport.x,
renderer->Viewport.y);
glEnable(GL_DEPTH_TEST);
for (Mesh* m : renderer->CurrentScene->getRenderables()) {
// m->getMaterial()->getGlShader()->use();
// GLint uniTrans = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "model");
// glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f)));
for (scene::SceneObject* o : scene::scene_get_renderables(scene)) {
for (scene::Mesh* m : scene::scene_object_get_meshs(o)) {
graphics::Shader* shader = m->getMaterial()->getGlShader();
graphics::shader_use(shader);
// GLint uniView = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "view");
// glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(renderer->CurrentScene->getCamera()->getViewMatrix()));
auto viewMatrix = graphics::camera_get_view(scene::scene_get_camera(scene));
auto projMatrix = graphics::camera_get_projection(scene::scene_get_camera(scene));
// GLint uniProj = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "proj");
// glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(renderer->CurrentScene->getCamera()->getProjectionMatrix()));
GLint uniTrans = glGetUniformLocation(graphics::shader_get_program(shader), "model");
glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f)));
GLint uniView = glGetUniformLocation(graphics::shader_get_program(shader), "view");
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(viewMatrix));
GLint uniProj = glGetUniformLocation(graphics::shader_get_program(shader), "proj");
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(projMatrix));
glBindVertexArray(m->getVAO());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->getEBO());
glDrawElements(GL_TRIANGLES, m->getIndexCount() * sizeof(uint32_t), GL_UNSIGNED_INT, 0);
}
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

View File

@@ -13,22 +13,18 @@ namespace inferno::graphics {
struct Viewport;
typedef struct PreviewRenderer {
glm::ivec2 Viewport;
GLuint RenderTarget = 0;
GLuint RenderTargetTexture = 0;
GLuint RenderTargetDepthTexture = 0;
std::shared_ptr<scene::Scene> CurrentScene;
std::shared_ptr<const Viewport> RenderTargetSize;
} PreviewRenderer;
std::unique_ptr<PreviewRenderer> preview_create();
void preview_cleanup(std::unique_ptr<PreviewRenderer>& renderer);
PreviewRenderer* preview_create();
void preview_cleanup(PreviewRenderer* renderer);
void preview_set_scene(std::unique_ptr<PreviewRenderer>& renderer, std::shared_ptr<scene::Scene> scene);
void preview_set_viewport(std::unique_ptr<PreviewRenderer>& renderer, std::shared_ptr<const Viewport> viewports);
const glm::ivec2& preview_get_viewport(std::unique_ptr<PreviewRenderer>& renderer);
GLuint preview_get_rendered_texture(std::unique_ptr<PreviewRenderer>& renderer);
GLuint preview_get_rendered_texture(PreviewRenderer* renderer);
void preview_prepare(std::unique_ptr<PreviewRenderer>& renderer);
void preview_draw(std::unique_ptr<PreviewRenderer>& renderer);
void preview_draw(PreviewRenderer* renderer, scene::Scene* scene);
} // namespace inferno::graphics

View File

@@ -3,7 +3,7 @@
#include <fstream>
#include <iostream>
using namespace inferno::graphics;
namespace inferno::graphics {
static std::unordered_map<GLuint, int> shader2Index = {
{ GL_VERTEX_SHADER, 0 },
@@ -25,7 +25,7 @@ std::string textFromFile(const std::filesystem::path& path)
std::istreambuf_iterator<char>());
}
std::vector<const ShaderPreprocessorDefinition*> getKeys(std::unique_ptr<Shader>& shader, std::string key)
std::vector<const ShaderPreprocessorDefinition*> getKeys(Shader* shader, std::string key)
{
std::vector<const ShaderPreprocessorDefinition*> ret;
for (const auto& p : shader->PreprocessorDefinitions)
@@ -56,9 +56,9 @@ bool checkShader(GLuint uid)
return true;
}
std::unique_ptr<Shader> shader_create()
Shader* shader_create()
{
std::unique_ptr<Shader> shader = std::make_unique<Shader>();
Shader* shader = new Shader;
shader->Program = 0;
shader->Shaders[0] = GL_NONE;
@@ -68,7 +68,7 @@ std::unique_ptr<Shader> shader_create()
return shader;
}
void shader_cleanup(std::unique_ptr<Shader>& shader)
void shader_cleanup(Shader* shader)
{
for (int i = 0; i < 3; i++) {
if (shader->Shaders[i] == GL_NONE)
@@ -79,7 +79,7 @@ void shader_cleanup(std::unique_ptr<Shader>& shader)
glDeleteProgram(shader->Program);
}
void shader_load(std::unique_ptr<Shader>& shader, std::filesystem::path path)
void shader_load(Shader* shader, std::filesystem::path path)
{
assert(std::filesystem::exists(path));
@@ -132,7 +132,7 @@ void shader_load(std::unique_ptr<Shader>& shader, std::filesystem::path path)
}
}
void shader_link(std::unique_ptr<Shader>& shader)
void shader_link(Shader* shader)
{
shader->Program = glCreateProgram();
@@ -150,32 +150,39 @@ void shader_link(std::unique_ptr<Shader>& shader)
glLinkProgram(shader->Program);
}
void shader_add_attribute(std::unique_ptr<Shader>& shader, const std::string& attribute)
GLuint shader_get_program(Shader* shader)
{
return shader->Program;
}
void shader_add_attribute(Shader* shader, const std::string& attribute)
{
shader->Attributes[attribute] = glGetAttribLocation(shader->Program, attribute.c_str());
}
void shader_add_uniform(std::unique_ptr<Shader>& shader, const std::string& uniform)
void shader_add_uniform(Shader* shader, const std::string& uniform)
{
shader->Uniforms[uniform] = glGetUniformLocation(shader->Program, uniform.c_str());
}
GLuint shader_get_attribute(std::unique_ptr<Shader>& shader, const std::string& attribute)
GLuint shader_get_attribute(Shader* shader, const std::string& attribute)
{
return shader->Attributes[attribute];
}
GLuint shader_get_uniform(std::unique_ptr<Shader>& shader, const std::string& uniform)
GLuint shader_get_uniform(Shader* shader, const std::string& uniform)
{
return shader->Uniforms[uniform];
}
void shader_use(std::unique_ptr<Shader>& shader)
void shader_use(Shader* shader)
{
glUseProgram(shader->Program);
}
void shader_unuse(std::unique_ptr<Shader>& shader)
void shader_unuse(Shader* shader)
{
glUseProgram(0);
}
}

View File

@@ -24,18 +24,21 @@ typedef struct Shader {
std::vector<ShaderPreprocessorDefinition> PreprocessorDefinitions;
} Shader;
std::unique_ptr<Shader> shader_create();
void shader_cleanup(std::unique_ptr<Shader>& shader);
Shader* shader_create();
void shader_cleanup(Shader* shader);
void shader_load(Shader* shader, std::filesystem::path path);
void shader_link(Shader* shader);
GLuint shader_get_program(Shader* shader);
void shader_load(std::unique_ptr<Shader>& shader, std::filesystem::path path);
void shader_link(std::unique_ptr<Shader>& shader);
// TODO: Implement shader_reload
void shader_add_attribute(std::unique_ptr<Shader>& shader, const std::string& attribute);
void shader_add_uniform(std::unique_ptr<Shader>& shader, const std::string& uniform);
GLuint shader_get_attribute(std::unique_ptr<Shader>& shader, const std::string& attribute);
GLuint shader_get_uniform(std::unique_ptr<Shader>& shader, const std::string& uniform);
void shader_add_attribute(Shader* shader, const std::string& attribute);
void shader_add_uniform(Shader* shader, const std::string& uniform);
GLuint shader_get_attribute(Shader* shader, const std::string& attribute);
GLuint shader_get_uniform(Shader* shader, const std::string& uniform);
void shader_use(std::unique_ptr<Shader>& shader);
void shader_unuse(std::unique_ptr<Shader>& shader);
void shader_use(Shader* shader);
void shader_unuse(Shader* shader);
}

View File

@@ -1,75 +0,0 @@
#include "dispatcher.hpp"
#include "hart_module.hpp"
#include "renderer.hpp"
#include <mutex>
#include <chrono>
using namespace inferno;
RenderDispatcher::RenderDispatcher()
: mRenderWorker{}
{
mHHM = new HHM();
mRenderer = new RayRenderer(mHHM);
mHHM->Renderer = mRenderer;
}
RenderDispatcher::~RenderDispatcher()
{
mDoWork = false;
mJoin = true;
mRenderWorker.join();
}
RayRenderer* RenderDispatcher::getRenderer()
{
return mRenderer;
}
HHM* RenderDispatcher::getTopModule()
{
return mHHM;
}
void renderWorker(RayRenderer* renderer, std::atomic<bool>* doWork, std::atomic<bool>* join)
{
while (!*join)
{
if (!*doWork) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue; // stall
}
renderer->prepare();
renderer->draw();
}
}
void RenderDispatcher::startProgression()
{
if (!mRenderWorker.joinable())
{
mRenderWorker = std::thread{ &renderWorker, this->mRenderer, &mDoWork, &mJoin };
}
mDoWork = true;
}
void RenderDispatcher::stopProgression()
{
mDoWork = false;
}
bool RenderDispatcher::progressionStatus()
{
return mDoWork;
}
GLuint RenderDispatcher::getLatestTexture()
{
std::lock_guard<std::mutex> lock(mRenderer->_RenderData);
glBindTexture(GL_TEXTURE_2D, mRenderer->mRenderTargetTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mRenderer->mRenderTargetSize.x, mRenderer->mRenderTargetSize.y, 0, GL_RGBA, GL_FLOAT, mRenderer->mTarget);
glBindTexture(GL_TEXTURE_2D, 0);
return mRenderer->mRenderTargetTexture;
}

View File

@@ -1,42 +0,0 @@
#pragma once
#include <graphics.hpp>
#include <thread>
#include <mutex>
#include <atomic>
namespace inferno {
// Thread dispatcher keeps track of the thread that calls the
// copy function because OpenGL is a nightmare
class HHM;
class Scene;
class RayRenderer;
class RenderDispatcher
{
public:
RenderDispatcher();
~RenderDispatcher();
RayRenderer* getRenderer();
HHM* getTopModule();
void startProgression();
void stopProgression();
bool progressionStatus();
GLuint getLatestTexture();
private:
HHM* mHHM;
RayRenderer* mRenderer;
private:
std::thread mRenderWorker;
std::atomic<bool> mDoWork = false;
std::atomic<bool> mJoin = false;
};
}

View File

@@ -1,70 +1,70 @@
#include "ray_source.hpp"
#include <iostream>
#include <maths.hpp>
#include <scene/camera.hpp>
#include <tracing/ray.hpp>
using namespace inferno;
RaySource::RaySource(Camera* camera)
: mReferenceCamera(camera)
{
this->generate();
}
RaySource::~RaySource()
{
}
void RaySource::generate()
{
// #include "ray_source.hpp"
//
// #include <iostream>
//
// #include <maths.hpp>
//
// #include <scene/camera.hpp>
//
// #include <tracing/ray.hpp>
//
// using namespace inferno;
//
// RaySource::RaySource(Camera* camera)
// : mReferenceCamera(camera)
// {
// this->generate();
// }
//
// RaySource::~RaySource()
// {
//
// }
//
// void RaySource::generate()
// {
// // const float aspect = mReferenceCamera->getRayViewport().x / mReferenceCamera->getRayViewport().y;
// // float scale = tan(mReferenceCamera->FOV / 2.0f * helpers::PI / 180.0f);
// }
//
// ReferencedRayField RaySource::getInitialRays(bool MSAA)
// {
// if (mReferenceCamera->didUpdate())
// {
// this->generate();
// }
//
// RayField field;
// field.reserve(mReferenceCamera->getRayViewport().x * mReferenceCamera->getRayViewport().y);
//
// const float aspect = mReferenceCamera->getRayViewport().x / mReferenceCamera->getRayViewport().y;
// float scale = tan(mReferenceCamera->FOV / 2.0f * helpers::PI / 180.0f);
}
ReferencedRayField RaySource::getInitialRays(bool MSAA)
{
if (mReferenceCamera->didUpdate())
{
this->generate();
}
RayField field;
field.reserve(mReferenceCamera->getRayViewport().x * mReferenceCamera->getRayViewport().y);
const float aspect = mReferenceCamera->getRayViewport().x / mReferenceCamera->getRayViewport().y;
float scale = tan(mReferenceCamera->FOV / 2.0f * helpers::PI / 180.0f);
glm::mat4 cameraToWorld = mReferenceCamera->getCameraLook();
glm::vec3 origin = mReferenceCamera->Position;
std::unordered_map<uint32_t, glm::ivec2> reference;
uint32_t i = 0;
for (int x = 0; x < mReferenceCamera->getRayViewport().x; x++)
for (int y = 0; y < mReferenceCamera->getRayViewport().y; y++)
{
float Px = (2.0f * ((x + 0.5f) / mReferenceCamera->getRayViewport().x) - 1.0f) * scale * aspect;
float Py = (2.0f * ((y + 0.5f) / mReferenceCamera->getRayViewport().y) - 1.0f) * scale;
Ray* ray = new Ray{};
glm::vec4 dir4 = glm::vec4(Px, Py, -1.0f, 1.0f) * cameraToWorld;
glm::vec3 dir3 = glm::vec3(dir4) / dir4.w;
ray->Direction = glm::normalize(dir3);
ray->Origin = origin;
ray->Reference = i;
reference[i] = {x, y};
field.push_back(ray);
i++;
}
return { field, reference };
}
//
// glm::mat4 cameraToWorld = mReferenceCamera->getCameraLook();
// glm::vec3 origin = mReferenceCamera->Position;
//
// std::unordered_map<uint32_t, glm::ivec2> reference;
//
// uint32_t i = 0;
// for (int x = 0; x < mReferenceCamera->getRayViewport().x; x++)
// for (int y = 0; y < mReferenceCamera->getRayViewport().y; y++)
// {
// float Px = (2.0f * ((x + 0.5f) / mReferenceCamera->getRayViewport().x) - 1.0f) * scale * aspect;
// float Py = (2.0f * ((y + 0.5f) / mReferenceCamera->getRayViewport().y) - 1.0f) * scale;
//
// Ray* ray = new Ray{};
//
// glm::vec4 dir4 = glm::vec4(Px, Py, -1.0f, 1.0f) * cameraToWorld;
// glm::vec3 dir3 = glm::vec3(dir4) / dir4.w;
// ray->Direction = glm::normalize(dir3);
//
// ray->Origin = origin;
// ray->Reference = i;
// reference[i] = {x, y};
//
// field.push_back(ray);
// i++;
// }
//
// return { field, reference };
// }

View File

@@ -1,33 +1,33 @@
#pragma once
#include <vector>
#include <unordered_map>
#include <graphics.hpp>
#include <tracing/ray.hpp>
namespace inferno {
class Camera;
struct ReferencedRayField {
RayField Field;
std::unordered_map<uint32_t, glm::ivec2> Reference;
};
class RaySource
{
public:
RaySource(Camera* camera);
~RaySource();
void generate();
ReferencedRayField getInitialRays(bool MSAA);
private:
Camera* mReferenceCamera;
};
}
// #pragma once
//
// #include <vector>
// #include <unordered_map>
//
// #include <graphics.hpp>
//
// #include <tracing/ray.hpp>
//
// namespace inferno {
//
// class Camera;
//
// struct ReferencedRayField {
// RayField Field;
// std::unordered_map<uint32_t, glm::ivec2> Reference;
// };
//
//
// class RaySource
// {
// public:
// RaySource(Camera* camera);
// ~RaySource();
//
// void generate();
// ReferencedRayField getInitialRays(bool MSAA);
//
// private:
// Camera* mReferenceCamera;
// };
//
// }

View File

@@ -1,144 +1,143 @@
#include "renderer.hpp"
#include <graphics.hpp>
#include <scene/camera.hpp>
#include <scene/scene.hpp>
#include <scene/mesh.hpp>
#include <tracing/ray.hpp>
#include <tracing/hit.hpp>
#include "hart_module.hpp"
#include "ray_source.hpp"
#include <yolo/yolo.hpp>
#include <iostream>
namespace inferno::graphics {
std::unique_ptr<RayRenderer> rayr_create(glm::ivec2 viewport, HHM* accelIface)
{
std::unique_ptr<RayRenderer> renderer = std::make_unique<RayRenderer>();
renderer->RenderTargetSize = viewport;
renderer->RenderData = new glm::fvec4[renderer->RenderTargetSize.x * renderer->RenderTargetSize.y];
glGenTextures(1, &renderer->RenderTargetTexture);
glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderer->RenderTargetSize.x, renderer->RenderTargetSize.y, 0, GL_RGBA, GL_FLOAT, renderer->RenderData);
glBindTexture(GL_TEXTURE_2D, 0);
return renderer;
}
void rayr_cleanup(std::unique_ptr<RayRenderer>& renderer)
{
delete[] renderer->RenderData;
}
void rayr_set_scene(std::unique_ptr<RayRenderer>& renderer, std::shared_ptr<scene::Scene> scene)
{
renderer->CurrentScene = scene;
if (renderer->RaySource != nullptr)
{
delete renderer->RaySource;
}
// renderer->RaySource = new RaySource(scene->getCamera());
// the scene will be sent to the module on prepare
// as it did update during initialisation
// mIface->newScene(scene);
}
void rayr_set_viewport(std::unique_ptr<RayRenderer> &renderer, glm::ivec2 size)
{
renderer->RenderTargetSize = size;
}
glm::ivec2 rayr_get_viewport(std::unique_ptr<RayRenderer> &renderer)
{
return renderer->RenderTargetSize;
}
GLuint rayr_get_rendered_texture(std::unique_ptr<RayRenderer> &renderer)
{
std::lock_guard<std::mutex> lock(renderer->RenderDataMutex);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
return renderer->RenderTargetTexture;
}
glm::fvec4* rayr_get_render_data(std::unique_ptr<RayRenderer> &renderer)
{
std::lock_guard<std::mutex> lock(renderer->RenderDataMutex);
return renderer->RenderData;
}
void rayr_prepare(std::unique_ptr<RayRenderer> &renderer)
{
assert(renderer->CurrentScene != nullptr);
// here, scene_did_update takes a unique_ptr, but we have a shared_ptr
// so we need to call unique() to get the unique_ptr but that will error
// with non-const ltype so we need to const_cast it
if (scene::scene_did_update(renderer->CurrentScene))
{
yolo::debug("New Scene!");
// renderer->AccelerationInterface->newScene(renderer->CurrentScene);
}
}
void rayr_draw(std::unique_ptr<RayRenderer> &renderer)
{
scene::scene_frame_tick(renderer->CurrentScene);
// 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
ReferencedRayField startRays = mRaySource->getInitialRays(true);
for (int x = 0; x < mRenderTargetSize.x; x++)
for (int y = 0; y < mRenderTargetSize.y; y++)
{
mTarget[y * mRenderTargetSize.x + x] = { 0.1f, 0.1f, 0.1f, 1.0f };
}
mCurrentRefTable = &startRays.Reference;
// before we start we now want to check that it hasn't been force-stopped
mIface->startTrace(startRays.Field);
yolo::info("Sample complete");
for (auto* ray : startRays.Field)
{
delete ray;
}
}
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};
}
void mHaultWait();
std::unordered_map<uint32_t, glm::ivec2>* mCurrentRefTable;
}
// #include "renderer.hpp"
//
// #include <graphics.hpp>
//
// #include <scene/camera.hpp>
// #include <scene/scene.hpp>
// #include <scene/mesh.hpp>
// #include <tracing/ray.hpp>
// #include <tracing/hit.hpp>
//
// #include "ray_source.hpp"
//
// #include <yolo/yolo.hpp>
//
// #include <iostream>
//
// namespace inferno::graphics {
//
// RayRenderer* rayr_create(glm::ivec2 viewport, HHM* accelIface)
// {
// RayRenderer* renderer = new RayRenderer;
// renderer->RenderTargetSize = viewport;
// renderer->RenderData = new glm::fvec4[renderer->RenderTargetSize.x * renderer->RenderTargetSize.y];
//
// glGenTextures(1, &renderer->RenderTargetTexture);
// glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
//
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//
// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderer->RenderTargetSize.x, renderer->RenderTargetSize.y, 0, GL_RGBA, GL_FLOAT, renderer->RenderData);
//
// glBindTexture(GL_TEXTURE_2D, 0);
//
// return renderer;
// }
//
// void rayr_cleanup(RayRenderer* renderer)
// {
// delete[] renderer->RenderData;
// }
//
// void rayr_set_scene(RayRenderer* renderer, std::shared_ptr<scene::Scene> scene)
// {
// renderer->CurrentScene = scene;
// if (renderer->RaySource != nullptr)
// {
// delete renderer->RaySource;
// }
// // renderer->RaySource = new RaySource(scene->getCamera());
// // the scene will be sent to the module on prepare
// // as it did update during initialisation
//
// // mIface->newScene(scene);
// }
//
// void rayr_set_viewport(RayRenderer* &renderer, glm::ivec2 size)
// {
// renderer->RenderTargetSize = size;
// }
//
// glm::ivec2 rayr_get_viewport(RayRenderer* &renderer)
// {
// return renderer->RenderTargetSize;
// }
//
// GLuint rayr_get_rendered_texture(RayRenderer* &renderer)
// {
// std::lock_guard<std::mutex> lock(renderer->RenderDataMutex);
// glBindFramebuffer(GL_FRAMEBUFFER, 0);
// glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
// return renderer->RenderTargetTexture;
// }
//
// glm::fvec4* rayr_get_render_data(RayRenderer* &renderer)
// {
// std::lock_guard<std::mutex> lock(renderer->RenderDataMutex);
// return renderer->RenderData;
// }
//
// void rayr_prepare(RayRenderer* &renderer)
// {
// assert(renderer->CurrentScene != nullptr);
// // here, scene_did_update takes a unique_ptr, but we have a shared_ptr
// // so we need to call unique() to get the unique_ptr but that will error
// // with non-const ltype so we need to const_cast it
// if (scene::scene_did_update(renderer->CurrentScene))
// {
// yolo::debug("New Scene!");
// // renderer->AccelerationInterface->newScene(renderer->CurrentScene);
// }
// }
//
// void rayr_draw(RayRenderer* &renderer)
// {
// scene::scene_frame_tick(renderer->CurrentScene);
// // 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
// ReferencedRayField startRays = mRaySource->getInitialRays(true);
//
// for (int x = 0; x < mRenderTargetSize.x; x++)
// for (int y = 0; y < mRenderTargetSize.y; y++)
// {
// mTarget[y * mRenderTargetSize.x + x] = { 0.1f, 0.1f, 0.1f, 1.0f };
// }
// mCurrentRefTable = &startRays.Reference;
//
// // before we start we now want to check that it hasn't been force-stopped
// mIface->startTrace(startRays.Field);
//
// yolo::info("Sample complete");
//
// for (auto* ray : startRays.Field)
// {
// delete ray;
// }
// }
//
// 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};
// }
// void mHaultWait();
// std::unordered_map<uint32_t, glm::ivec2>* mCurrentRefTable;
//
//
// }

View File

@@ -20,33 +20,26 @@ class RaySource;
class RenderDispatcher;
typedef struct RayRenderer {
glm::ivec2* Viewport;
// TODO: Can this be direct 2 GPU?
glm::fvec4* RenderData = nullptr;
GLuint RenderTargetTexture = 0;
// TODO: Put this inside an internal struct
std::mutex RenderDataMutex;
std::condition_variable RenderPause;
// TODO: End
std::unique_ptr<scene::Scene> CurrentScene;
// std::shared_ptr<const Viewport> RenderTargetSize;
glm::ivec2 RenderTargetSize;
HHM* AccelerationInterface = nullptr;
RenderDispatcher* Dispatcher = nullptr;
// Internal stuffs
RaySource* RaySource = nullptr;
} RayRenderer;
std::unique_ptr<RayRenderer> rayr_create(glm::ivec2 viewport, HHM* accelIface);
void rayr_cleanup(std::unique_ptr<RayRenderer>& renderer);
void rayr_set_scene(std::unique_ptr<RayRenderer>& renderer, std::unique_ptr<scene::Scene> scene);
void rayr_set_viewport(std::unique_ptr<RayRenderer>& renderer, glm::ivec2 size);
glm::ivec2 rayr_get_viewport(std::unique_ptr<RayRenderer>& renderer);
GLuint rayr_get_rendered_texture(std::unique_ptr<RayRenderer>& renderer);
glm::fvec4* rayr_get_render_data(std::unique_ptr<RayRenderer>& renderer);
void rayr_prepare(std::unique_ptr<RayRenderer>& renderer);
void rayr_draw(std::unique_ptr<RayRenderer>& renderer);
RayRenderer* rayr_create(glm::ivec2 viewport, HHM* accelIface);
void rayr_cleanup(RayRenderer* renderer);
void rayr_set_viewport(RayRenderer* renderer, glm::ivec2 size);
GLuint rayr_get_rendered_texture(RayRenderer* renderer);
glm::fvec4* rayr_get_render_data(RayRenderer* renderer);
void rayr_draw(RayRenderer* renderer, scene::Scene* scene);
void raryr_compute_hit(HitInfo* info);
}
} // namespace inferno::graphics

View File

@@ -2,19 +2,14 @@
namespace inferno::graphics {
typedef struct _CameraImpl {
bool DidUpdate;
std::mutex CamMutex;
} _CameraImpl;
std::unique_ptr<Camera> camera_create()
Camera* camera_create()
{
std::unique_ptr<Camera> camera = std::make_unique<Camera>();
camera->_impl = std::make_unique<_CameraImpl>();
camera->Views = std::make_shared<Viewports>();
camera->Views->Raster = glm::ivec2(800, 600);
camera->Views->Ray = glm::ivec2(800, 600);
Camera* camera = new Camera;
camera->_impl = new _CameraImpl;
camera->Views = Viewports();
camera->Views.Raster = glm::ivec2(800, 600);
camera->Views.Ray = glm::ivec2(800, 600);
camera->ProjectionMatrix = glm::perspective(
glm::radians(camera->FOV),
@@ -34,13 +29,13 @@ std::unique_ptr<Camera> camera_create()
return camera;
}
void camera_cleanup(std::unique_ptr<Camera>& camera)
void camera_cleanup(Camera* camera)
{
camera->_impl.reset();
camera.reset();
delete camera->_impl;
delete camera;
}
void camera_update(std::unique_ptr<Camera>& camera)
void camera_update(Camera* camera)
{
glm::mat4 matRoll = glm::mat4(1.0f);
glm::mat4 matPitch = glm::mat4(1.0f);
@@ -61,7 +56,7 @@ void camera_update(std::unique_ptr<Camera>& camera)
camera->ViewMatrix = rotate * translate;
camera->ProjectionMatrix = glm::perspective(
glm::radians(camera->FOV),
static_cast<float>(camera->Views->Raster.x) / static_cast<float>(camera->Views->Raster.y),
static_cast<float>(camera->Views.Raster.x) / static_cast<float>(camera->Views.Raster.y),
0.1f,
1000.0f);
@@ -75,40 +70,40 @@ void camera_update(std::unique_ptr<Camera>& camera)
camera->_impl->DidUpdate = true;
}
bool camera_did_update(std::unique_ptr<Camera>& camera)
bool camera_did_update(Camera* camera)
{
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->_impl->DidUpdate;
}
void camera_new_frame(std::unique_ptr<Camera>& camera)
void camera_new_frame(Camera* camera)
{
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
camera->_impl->DidUpdate = false;
}
glm::mat4 camera_get_view(std::unique_ptr<Camera>& camera)
glm::mat4 camera_get_view(Camera* camera)
{
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->ViewMatrix;
}
glm::mat4 camera_get_projection(std::unique_ptr<Camera>& camera)
glm::mat4 camera_get_projection(Camera* camera)
{
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->ProjectionMatrix;
}
glm::mat4 camera_get_look(std::unique_ptr<Camera>& camera)
glm::mat4 camera_get_look(Camera* camera)
{
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->LookMatrix;
}
void raster_set_viewport(std::unique_ptr<Camera>& camera, glm::ivec2 viewport)
void raster_set_viewport(Camera* camera, glm::ivec2 viewport)
{
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
camera->Views->Raster = viewport;
camera->Views.Raster = viewport;
camera->ProjectionMatrix = glm::perspective(
glm::radians(camera->FOV),
static_cast<float>(viewport.x) / static_cast<float>(viewport.y),
@@ -116,25 +111,25 @@ void raster_set_viewport(std::unique_ptr<Camera>& camera, glm::ivec2 viewport)
1000.0f);
}
glm::ivec2 raster_get_viewport(std::unique_ptr<Camera>& camera)
glm::ivec2 raster_get_viewport(Camera* camera)
{
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->Views->Raster;
return camera->Views.Raster;
}
void ray_set_viewport(std::unique_ptr<Camera>& camera, glm::ivec2 viewport)
void ray_set_viewport(Camera* camera, glm::ivec2 viewport)
{
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
camera->Views->Ray = viewport;
camera->Views.Ray = viewport;
}
glm::ivec2 ray_get_viewport(std::unique_ptr<Camera>& camera)
glm::ivec2 ray_get_viewport(Camera* camera)
{
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->Views->Ray;
return camera->Views.Ray;
}
void camera_move(std::unique_ptr<Camera>& camera, uint8_t movement_delta)
void camera_move(Camera* camera, uint8_t movement_delta)
{
if (movement_delta == 0)
return;
@@ -186,7 +181,7 @@ void camera_move(std::unique_ptr<Camera>& camera, uint8_t movement_delta)
camera_update(camera);
}
void camera_mouse_move(std::unique_ptr<Camera>& camera, glm::vec2 mouse_delta)
void camera_mouse_move(Camera* camera, glm::vec2 mouse_delta)
{
if (glm::length(mouse_delta) == 0)
return;
@@ -199,13 +194,13 @@ void camera_mouse_move(std::unique_ptr<Camera>& camera, glm::vec2 mouse_delta)
camera_update(camera);
}
void camera_set_position(std::unique_ptr<Camera>& camera, glm::vec3 position)
void camera_set_position(Camera* camera, glm::vec3 position)
{
camera->Position = position;
camera_update(camera);
}
void camera_set_euler_look(std::unique_ptr<Camera>& camera, float roll, float pitch, float yaw)
void camera_set_euler_look(Camera* camera, float roll, float pitch, float yaw)
{
camera->Roll = roll;
camera->Pitch = pitch;
@@ -217,7 +212,7 @@ void camera_set_euler_look(std::unique_ptr<Camera>& camera, float roll, float pi
camera_update(camera);
}
void camera_set_look(std::unique_ptr<Camera>& camera, glm::vec3 look_direction)
void camera_set_look(Camera* camera, glm::vec3 look_direction)
{
camera->LookDirection = look_direction;
camera->Pitch = asin(-look_direction.y);
@@ -226,4 +221,9 @@ void camera_set_look(std::unique_ptr<Camera>& camera, glm::vec3 look_direction)
camera_update(camera);
}
glm::vec3 camera_get_position(Camera* camera)
{
return camera->Position;
}
}

View File

@@ -2,7 +2,7 @@
#include "preview_renderer/shader.hpp"
using namespace inferno;
namespace inferno::scene {
Material::Material(std::string name)
: mName(name)
@@ -15,12 +15,13 @@ Material::~Material()
}
//void Material::setGlShader(Shader* shader)
//{
//mGlShader = shader;
//}
void Material::setGlShader(graphics::Shader* shader)
{
mGlShader = shader;
}
//Shader* Material::getGlShader()
//{
//return mGlShader;
//}
graphics::Shader* Material::getGlShader()
{
return mGlShader;
}
}

View File

@@ -4,9 +4,12 @@
#include <hart_graphics.hpp>
namespace inferno {
namespace inferno::graphics {
class Shader;
};
namespace inferno::scene {
//class Shader;
class HitInfo;
class Material {
@@ -15,14 +18,14 @@ public:
~Material();
std::string getName();
//void setGlShader(Shader* shader);
//Shader* getGlShader();
void setGlShader(graphics::Shader* shader);
graphics::Shader* getGlShader();
glm::vec3 sample(HitInfo* hit);
private:
std::string mName;
//Shader* mGlShader;
graphics::Shader* mGlShader;
};
}

View File

@@ -6,7 +6,7 @@
#include <iostream>
using namespace inferno;
namespace inferno::scene {
Mesh::Mesh()
{
@@ -116,3 +116,5 @@ GLuint Mesh::getEBO()
{
return mEBO;
}
}

View File

@@ -1,15 +1,15 @@
#pragma once
#include <vector>
#include <filesystem>
#include <hart_graphics.hpp>
namespace inferno {
namespace inferno::scene {
class ObjLoader;
class Material;
// TODO: This should be procedural like everything else
struct Vert
{
glm::vec3 Position;

View File

@@ -0,0 +1,29 @@
#include "object.hpp"
#include "mesh.hpp"
namespace inferno::scene {
SceneObject* scene_object_create()
{
SceneObject* object = new SceneObject;
return object;
}
void scene_object_cleanup(SceneObject* object)
{
}
void scene_object_add_mesh(SceneObject* object, Mesh* mesh)
{
object->Meshs.push_back(mesh);
}
std::vector<Mesh*>& scene_object_get_meshs(SceneObject* object)
{
return object->Meshs;
}
}

View File

@@ -1,19 +1,20 @@
#pragma once
#include <memory>
#include <vector>
namespace inferno {
namespace inferno::scene {
class Mesh;
class Object
{
public:
Object();
~Object();
typedef struct SceneObject {
std::vector<Mesh*> Meshs;
} SceneObject;
private:
std::vector<Mesh*> mMeshs;
};
SceneObject* scene_object_create();
void scene_object_cleanup(SceneObject* object);
}
void scene_object_add_mesh(SceneObject* object, Mesh* mesh);
std::vector<Mesh*>& scene_object_get_meshs(SceneObject* object);
} // namespace inferno::scene

View File

@@ -10,7 +10,7 @@
#include <assert.h>
#include <map>
using namespace inferno;
namespace inferno::scene {
struct FaceVert
{
@@ -263,3 +263,5 @@ const float* ObjLoader::getTexCoords(int multiTexCoordLayer)
assert(multiTexCoordLayer < mTexCoordLayers);
return (const float*)&mTexCoords[0];
}
}

View File

@@ -5,7 +5,7 @@
#include <hart_graphics.hpp>
namespace inferno {
namespace inferno::scene {
struct Face
{

View File

@@ -1,55 +1,61 @@
#include "scene.hpp"
#include <yolo/yolo.hpp>
#include <memory>
#include <scene/camera.hpp>
#include <scene/mesh.hpp>
#include <scene/object.hpp>
namespace inferno::scene {
std::unique_ptr<Scene> scene_create()
Scene* scene_create()
{
std::unique_ptr<Scene> scene = std::make_unique<Scene>();
scene->Camera = std::make_shared<graphics::Camera>();
Scene* scene = new Scene;
scene->Objects = std::vector<SceneObject*>();
scene->Camera = graphics::camera_create();
yolo::debug("Created scene {} and camera {}", scene, scene->Camera);
return scene;
}
void scene_cleanup(std::unique_ptr<Scene>& scene)
void scene_cleanup(Scene* scene)
{
}
void scene_set_camera(std::unique_ptr<Scene>& scene, std::shared_ptr<graphics::Camera> camera)
void scene_add_object(Scene* scene, SceneObject* object)
{
scene->Camera = camera;
yolo::debug("Using scene {}", scene);
yolo::debug("Adding object to scene, no Objects: {}, adding to pool of: {}", object->Meshs.size(), scene->Objects.size());
yolo::debug("Object Mesh 0 is {}", object->Meshs[0]);
scene->Objects.push_back(object);
scene->DidUpdate = true;
}
void scene_add_object(std::unique_ptr<Scene>& scene, std::unique_ptr<SceneObject> object)
graphics::Camera* scene_get_camera(Scene* scene)
{
scene->Objects.push_back(std::move(object));
scene->DidUpdate = true;
return scene->Camera;
}
std::vector<std::unique_ptr<SceneObject>>& scene_get_renderables(std::unique_ptr<Scene>& scene)
std::vector<SceneObject*>& scene_get_renderables(Scene* scene)
{
return scene->Objects;
}
bool scene_did_update(std::unique_ptr<Scene>& scene)
bool scene_did_update(Scene* scene)
{
return scene->DidUpdate;
}
void scene_frame_tick(std::unique_ptr<Scene>& scene)
void scene_frame_tick(Scene* scene)
{
scene->DidUpdate = false;
}
void scene_tick(std::unique_ptr<Scene>& scene)
void scene_tick(Scene* scene)
{
for (auto& object : scene->Objects) {
// object->tick();
// Shit here like animation idk
}
}
}

View File

@@ -1,5 +1,7 @@
#pragma once
#include "scene/object.hpp"
#include <memory>
#include <vector>
@@ -13,19 +15,22 @@ class SceneObject;
class Mesh;
typedef struct Scene {
std::shared_ptr<graphics::Camera> Camera;
std::vector<std::unique_ptr<SceneObject>> Objects;
std::vector<SceneObject*> Objects;
graphics::Camera* Camera;
bool DidUpdate = false;
} Scene;
std::unique_ptr<Scene> scene_create();
void scene_cleanup(std::unique_ptr<Scene>& scene);
void scene_set_camera(std::unique_ptr<Scene>& scene, std::shared_ptr<graphics::Camera> camera);
void scene_add_object(std::unique_ptr<Scene>& scene, std::unique_ptr<SceneObject> object);
std::unique_ptr<graphics::Camera>& scene_get_camera(std::unique_ptr<Scene>& scene);
std::vector<std::unique_ptr<SceneObject>>& scene_get_renderables(std::unique_ptr<Scene>& scene);
bool scene_did_update(std::unique_ptr<Scene>& scene);
void scene_frame_tick(std::unique_ptr<Scene>& scene);
void scene_tick(std::unique_ptr<Scene>& scene);
Scene* scene_create();
void scene_cleanup(Scene* scene);
}
void scene_add_object(Scene* scene, SceneObject* object);
graphics::Camera* scene_get_camera(Scene* scene);
std::vector<SceneObject*>& scene_get_renderables(Scene* scene);
bool scene_did_update(Scene* scene);
void scene_frame_tick(Scene* scene);
void scene_tick(Scene* scene);
} // namespace inferno::scene

View File

@@ -1,3 +1,3 @@
#pragma once
#define INFERNO_VERSION "3.0.1_alpha"
#define INFERNO_VERSION "3.0.13_alpha"

View File

@@ -60,6 +60,10 @@ void setupGLFW(std::string title)
glfwMakeContextCurrent(Window);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
glfwSwapInterval(1); // Enable vsync
yolo::info("GLFW {} initialized", glfwGetVersionString());
yolo::info("OpenGL {} initialized", glGetString(GL_VERSION));
yolo::info("GLSL {} initialized", glGetString(GL_SHADING_LANGUAGE_VERSION));
yolo::info("INFERNO HART Running on ", glGetString(GL_RENDERER));
}
void setupImGui()