Merge pull request #2 from benkyd/refactor

Refactor -> Master
This commit is contained in:
Benjamin Kyd
2023-10-16 11:52:06 +01:00
committed by GitHub
35 changed files with 1455 additions and 1725 deletions

192
.clang-format Normal file
View File

@@ -0,0 +1,192 @@
---
Language: Cpp
# BasedOnStyle: WebKit
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignArrayOfStructures: None
AlignConsecutiveMacros: None
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignEscapedNewlines: Right
AlignOperands: DontAlign
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: All
BreakBeforeConceptDeclarations: true
BreakBeforeBraces: WebKit
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: BinPack
BasedOnStyle: ''
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: None
IndentExternBlock: AfterExternBlock
IndentRequires: false
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Left
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...

View File

@@ -10,7 +10,7 @@ target_include_directories(inferno PRIVATE "src/")
target_include_directories(inferno PRIVATE "src/thirdparty")
# Hardware Acceleration Modules (HART)
add_subdirectory("hart/inferno-hart-cpu")
#add_subdirectory("hart/inferno-hart-cpu")
#add_subdirectory("hart/inferno-hart-opencl")
# Compiler arguments
@@ -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)
@@ -66,3 +67,4 @@ else()
OpenGL::GL
)
endif()

View File

@@ -3,56 +3,65 @@
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <memory>
#include <mutex>
namespace inferno {
namespace inferno::graphics {
class Camera {
public:
Camera();
Camera(int w, int h);
typedef struct _CameraImpl {
bool DidUpdate;
std::mutex CamMutex;
} _CameraImpl;
void update();
bool didUpdate();
void newFrame();
typedef struct Viewport {
glm::ivec2 Raster;
glm::ivec2 Ray;
} Viewports;
glm::mat4 getViewMatrix();
glm::mat4 getProjectionMatrix();
glm::mat4 getCameraLook();
typedef struct Camera {
glm::mat4 ViewMatrix;
glm::mat4 ProjectionMatrix;
glm::mat4 LookMatrix;
void setRasterViewport(glm::vec2 viewport);
Viewport Views;
// Keyboard
void moveCamera(uint8_t posDelta);
// Mouse Delta
void mouseMoved(glm::vec2 mouseDelta);
float MouseSensitivity = 0.4f;
float Speed = 0.1f;
float Roll, Pitch, Yaw;
float FOV = 45.0f;
void setPosition(glm::vec3 position);
void setEulerLook(float roll, float pitch, float yaw);
void setLook(glm::vec3 lookDirection);
glm::vec3 Position = {};
glm::vec3 LookDirection = {};
public:
void setRayViewport(glm::vec2 viewport);
glm::vec2 getRayViewport();
_CameraImpl* _impl;
} Camera;
public:
// necessary evil
float MouseSensitivity = 0.4f;
float CameraSpeed = 0.1f;
float Roll, Pitch, Yaw;
float FOV = 45.0f;
glm::vec3 Position = {};
glm::vec3 LookDirection = {};
Camera* camera_create();
void camera_cleanup(Camera* camera);
private:
glm::vec2 mViewport = { 100.0f, 100.0f };
glm::vec2 mRayViewport = { 200.0f, 200.0f };
glm::mat4 mViewMatrix = {};
glm::mat4 mProjMatrix = {};
glm::mat4 mCameraLook = {};
bool mDidUpdate;
void camera_update(Camera* camera);
bool camera_did_update(Camera* camera);
void camera_new_frame(Camera* camera);
std::mutex _mCam;
};
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(Camera* camera, glm::ivec2 viewport);
glm::ivec2 raster_get_viewport(Camera* camera);
void ray_set_viewport(Camera* camera, glm::ivec2 viewport);
glm::ivec2 ray_get_viewport(Camera* camera);
void camera_move(Camera* camera, uint8_t movement_delta);
void camera_mouse_move(Camera* camera, glm::vec2 mouse_delta);
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(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

@@ -1,54 +1,72 @@
#include "inferno.hpp"
#include <version.hpp>
#include "gui/layout.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 "scene/camera.hpp"
#include "scene/scene.hpp"
#include "scene/material.hpp"
#include "scene/mesh.hpp"
#include "scene/scene.hpp"
#include <yolo/yolo.hpp>
#include <chrono>
#include <iostream>
#include <memory>
#include <chrono>
#include <numeric>
using namespace inferno;
namespace inferno {
Inferno::Inferno()
InfernoApp* inferno_create()
{
// MOTD
yolo::info("INFERNO HART v" INFERNO_VERSION);
InfernoApp* app = new InfernoApp;
app->Input = new InfernoInput;
app->Scene = scene::scene_create();
// Create window
mWin = &Window::GetInstance();
mWin->init("Inferno v" INFERNO_VERSION, 1280, 720);
graphics::window_create("Inferno v" INFERNO_VERSION, 1280, 720);
mRasterRenderer = new RasterizeRenderer();
mRayRenderer = new RenderDispatcher();
mScene = new Scene();
// 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;
}
Inferno::~Inferno()
void inferno_cleanup(InfernoApp* app)
{
graphics::window_cleanup();
delete app;
}
static void HelpMarker(const char* desc)
static void inferno_gui_help_marker(const char* desc)
{
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort))
{
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) {
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
ImGui::TextUnformatted(desc);
@@ -57,15 +75,15 @@ static void HelpMarker(const char* desc)
}
}
void Inferno::uiPreset()
void inferno_preset_gui(InfernoApp* app)
{
ImGuiID dockspace_id = ImGui::GetID("main");
ImGui::DockBuilderRemoveNode(dockspace_id); // Clear out existing layout
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace); // Add empty node
ImGui::DockBuilderSetNodeSize(dockspace_id, {1000, 1000});
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,107 +92,85 @@ void Inferno::uiPreset()
yolo::info("LAYOUT SET TO DEFAULT");
}
void Inferno::moveInput()
void inferno_move_input(InfernoApp* app)
{
static GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
glfwSetCursor(mWin->getGLFWWindow(), cursor);
glfwSetCursor(graphics::window_get_glfw_window(), cursor);
// KBD & MOUSE
// pan only get on hold
static glm::dvec2 lastMousePos;
static int firstClick = 0;
if (glfwGetMouseButton(mWin->getGLFWWindow(), GLFW_MOUSE_BUTTON_1) == GLFW_PRESS)
{
if (glfwGetMouseButton(graphics::window_get_glfw_window(), GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) {
firstClick++;
if (firstClick == 1)
{
glfwGetCursorPos(mWin->getGLFWWindow(), &lastMousePos.x, &lastMousePos.y);
if (firstClick == 1) {
glfwGetCursorPos(graphics::window_get_glfw_window(), &lastMousePos.x, &lastMousePos.y);
}
glm::dvec2 tempMousePos = { 0.0f, 0.0f };
glfwGetCursorPos(mWin->getGLFWWindow(), &tempMousePos.x, &tempMousePos.y);
mouseDelta = lastMousePos - tempMousePos;
glfwGetCursorPos(graphics::window_get_glfw_window(), &tempMousePos.x, &tempMousePos.y);
app->Input->MouseDelta = lastMousePos - tempMousePos;
lastMousePos = tempMousePos;
} else
{
} else {
firstClick = 0;
mouseDelta = { 0.0f, 0.0f };
app->Input->MouseDelta = { 0.0f, 0.0f };
lastMousePos = { 0.0f, 0.0f };
}
movementDelta = 0b00000000;
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_W) == GLFW_PRESS)
movementDelta |= 0b10000000;
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_A) == GLFW_PRESS)
movementDelta |= 0b01000000;
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_S) == GLFW_PRESS)
movementDelta |= 0b00100000;
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_D) == GLFW_PRESS)
movementDelta |= 0b00010000;
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_SPACE) == GLFW_PRESS)
movementDelta |= 0b00001000;
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
movementDelta |= 0b00000100;
app->Input->MovementDelta = 0b00000000;
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_W) == GLFW_PRESS)
app->Input->MovementDelta |= 0b10000000;
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_A) == GLFW_PRESS)
app->Input->MovementDelta |= 0b01000000;
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_S) == GLFW_PRESS)
app->Input->MovementDelta |= 0b00100000;
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_D) == GLFW_PRESS)
app->Input->MovementDelta |= 0b00010000;
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_SPACE) == GLFW_PRESS)
app->Input->MovementDelta |= 0b00001000;
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
app->Input->MovementDelta |= 0b00000100;
}
void Inferno::stopMoveInput()
void inferno_stop_move_input(InfernoApp* app)
{
movementDelta = 0x0;
mouseDelta = { 0.0f, 0.0f };
app->Input->MovementDelta = 0x0;
app->Input->MouseDelta = { 0.0f, 0.0f };
}
int Inferno::run()
int inferno_run(InfernoApp* app)
{
Material basicMaterial("basic");
Shader basicShader;
basicShader.load("res/shaders/basic.glsl")->link();
basicMaterial.setGlShader(&basicShader);
Mesh cornell;
cornell.loadOBJ("res/cornell-box.obj");
//cornell.loadOBJ("res/sponza.obj");
cornell.ready();
cornell.setMaterial(&basicMaterial);
mScene->addMesh(&cornell);
// Mesh dragon;
// dragon.loadOBJ("res/dragon-cornell-size.obj");
// dragon.ready();
// dragon.setMaterial(&basicMaterial);
// mScene->addMesh(&dragon);
Camera camera;
mScene->setCamera(&camera);
mRasterRenderer->setScene(mScene);
mRayRenderer->getRenderer()->setScene(mScene);
while (true)
{
if (!mWin->newFrame()) { break; }
camera.newFrame();
while (true) {
if (!graphics::window_new_frame())
break;
// set the main window to the dockspace and then on the first launch set the preset
ImGuiID dockspace_id = ImGui::GetID("main");
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
if (ImGui::DockBuilderGetNode(dockspace_id) == NULL) { this->uiPreset(); }
if (ImGui::DockBuilderGetNode(dockspace_id) == NULL) {
inferno_preset_gui(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;
static bool showDemoWindow = false;
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("Menu"))
{
if (ImGui::BeginMenuBar()) {
if (ImGui::BeginMenu("Menu")) {
ImGui::EndMenu();
}
if (ImGui::BeginMenu("View"))
{
if (ImGui::BeginMenu("View")) {
ImGui::Checkbox("Show Preview", &showPreview);
ImGui::SameLine(); HelpMarker("Show the preview window");
ImGui::SameLine();
inferno_gui_help_marker("Show the preview window");
ImGui::Checkbox("Show Settings", &showRenderSettings);
ImGui::SameLine(); HelpMarker("Show the Inferno HART settings window");
ImGui::SameLine();
inferno_gui_help_marker("Show the Inferno HART settings window");
ImGui::Checkbox("Show Demo", &showDemoWindow);
ImGui::EndMenu();
@@ -182,118 +178,73 @@ int Inferno::run()
ImGui::EndMenuBar();
}
if (showPreview && ImGui::Begin("Preview", nullptr, ImGuiWindowFlags_NoScrollbar))
{
if (ImGui::IsWindowHovered())
{
this->moveInput();
} else
{
this->stopMoveInput();
if (showPreview && ImGui::Begin("Preview", nullptr, ImGuiWindowFlags_NoScrollbar)) {
if (ImGui::IsWindowHovered()) {
inferno_move_input(app);
} else {
inferno_stop_move_input(app);
}
if (glm::length(mouseDelta) > 0.0f) camera.mouseMoved(mouseDelta);
if (movementDelta != 0b00000000) camera.moveCamera(movementDelta);
camera.setRasterViewport({ImGui::GetWindowSize().x, ImGui::GetWindowSize().y});
mRasterRenderer->setTargetSize({ImGui::GetWindowSize().x, ImGui::GetWindowSize().y});
mRasterRenderer->prepare();
mRasterRenderer->draw();
ImGui::Image((ImTextureID)mRasterRenderer->getRenderedTexture(),
{ mRasterRenderer->getTargetSize().x, mRasterRenderer->getTargetSize().y },
ImVec2(0,1), ImVec2(1,0));
graphics::raster_set_viewport(scene::scene_get_camera(app->Scene),
{ ImGui::GetWindowSize().x, ImGui::GetWindowSize().y });
graphics::preview_draw(app->PreviewRenderer, app->Scene);
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 (ImGui::Begin("Render", nullptr, ImGuiWindowFlags_NoScrollbar))
{
ImGui::Image((ImTextureID)mRayRenderer->getLatestTexture(),
{ mRayRenderer->getRenderer()->getTargetSize().x,
mRayRenderer->getRenderer()->getTargetSize().y },
ImVec2(0,1), ImVec2(1,0));
glBindTexture(GL_TEXTURE_2D, 0);
ImGui::End();
}
if (showRenderSettings && ImGui::Begin("Inferno HART"))
{
// start/stop
bool isRenderRunning = mRayRenderer->progressionStatus();
if (isRenderRunning)
{
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
ImGui::Button("Start Render"); ImGui::SameLine();
ImGui::PopItemFlag(); ImGui::PopStyleVar();
if (ImGui::Button("Stop Render"))
mRayRenderer->stopProgression();
} else {
if (ImGui::Button("Start Render"))
mRayRenderer->startProgression();
ImGui::SameLine();
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
ImGui::Button("Stop Render");
ImGui::PopItemFlag(); ImGui::PopStyleVar();
}
if (ImGui::TreeNode("Render"))
{
// modules
HHM* hhm = mRayRenderer->getTopModule();
if (ImGui::TreeNode("Accelerator"))
{
ImGui::Button("Find Accelerator...");
ImGui::Text("Select Accelerator:");
if (ImGui::BeginListBox("", ImVec2(-FLT_MIN, 3 * ImGui::GetTextLineHeightWithSpacing())))
{
std::vector<std::string> moduleNames = hhm->getModuleDirectory()->getModules();
int active = hhm->getModuleDirectory()->getActiveIndex();
for (int n = 0; n < moduleNames.size(); n++)
{
const bool isSelected = (active == n);
if (ImGui::Selectable(moduleNames[n].c_str(), isSelected))
hhm->getModuleDirectory()->setActiveIndex(n);
if (isSelected)
ImGui::SetItemDefaultFocus();
}
ImGui::EndListBox();
}
auto* activeCredit = hhm->getModuleDirectory()->getActiveCredit();
ImGui::Text(activeCredit->ModuleName.c_str());
ImGui::SameLine();
ImGui::Text("v%i.%i.%i", activeCredit->VersionMajor,
activeCredit->VersionMinor,
activeCredit->VersionBuild);
ImGui::BulletText(activeCredit->ModuleDesc.c_str());
ImGui::BulletText("Authored by %s", activeCredit->AuthorName.c_str());
ImGui::TreePop();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Camera"))
{
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) camera.setPosition(camera.Position);
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::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) camera.update();
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();
@@ -301,11 +252,11 @@ int Inferno::run()
ImGui::End();
}
if (showDemoWindow)
{
if (showDemoWindow) {
ImGui::ShowDemoWindow();
}
// clang-format off
GLenum err;
while((err = glGetError()) != GL_NO_ERROR) {
std::string error;
@@ -322,8 +273,10 @@ int Inferno::run()
yolo::error("[GL]: {} {}", err, error);
}
mWin->render();
graphics::window_render();
}
return 0;
return 1;
}
} // namespace inferno

View File

@@ -1,45 +1,40 @@
#pragma once
#include "graphics.hpp"
#include "scene/scene.hpp"
#include "scene/camera.hpp"
// #include "renderer/renderer.hpp"
#include "preview_renderer/renderer.hpp"
#include <singleton.hpp>
#include <memory>
namespace inferno {
class Window;
class HHM;
class RasterizeRenderer;
class RenderDispatcher;
class Scene;
class Inferno : public helpers::Singleton<Inferno>
{
public:
Inferno();
~Inferno();
void uiPreset();
void moveInput();
void stopMoveInput();
int run();
public:
glm::vec2 mouseDelta;
// 0b00000000
// 0bFLBRUDxx
uint8_t movementDelta;
private:
// need deffered init as they need an OpenGL context
// could and should be fixed with a static window
RasterizeRenderer* mRasterRenderer;
RenderDispatcher* mRayRenderer;
Scene* mScene;
private:
Window* mWin;
};
namespace graphics {
struct Camera;
}
namespace scene {
struct Scene;
}
typedef struct InfernoInput {
glm::vec2 MouseDelta = {0.0f, 0.0f};
uint8_t MovementDelta = 0;
} InfernoInput;
typedef struct InfernoApp {
InfernoInput* Input;
scene::Scene* Scene;
graphics::PreviewRenderer* PreviewRenderer;
// graphics::RayRenderer* RayRenderer;
} InfernoApp;
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,13 +5,6 @@
int main(int argc, char** argv)
{
try
{
return inferno::Inferno::GetInstance().run();
}
catch (std::exception e)
{
yolo::error(e.what());
return -1;
}
auto inferno = inferno::inferno_create();
return inferno::inferno_run(inferno);
}

View File

@@ -1,114 +1,140 @@
#include "renderer.hpp"
#include "scene/object.hpp"
#include "shader.hpp"
#include <yolo/yolo.hpp>
#include <algorithm>
#include <scene/camera.hpp>
#include <scene/scene.hpp>
#include <scene/material.hpp>
#include <scene/mesh.hpp>
#include <scene/object.hpp>
#include <scene/scene.hpp>
#include <iostream>
using namespace inferno;
namespace inferno::graphics {
RasterizeRenderer::RasterizeRenderer()
PreviewRenderer* preview_create()
{
glGenFramebuffers(1, &mRenderTarget);
glBindFramebuffer(GL_FRAMEBUFFER, mRenderTarget);
PreviewRenderer* renderer = new PreviewRenderer;
glGenFramebuffers(1, &renderer->RenderTarget);
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
glGenTextures(1, &mRenderTargetTexture);
glBindTexture(GL_TEXTURE_2D, mRenderTargetTexture);
glGenTextures(1, &renderer->RenderTargetTexture);
glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glGenTextures(1, &mRenderTargetDepthTexture );
glBindTexture(GL_TEXTURE_2D, mRenderTargetDepthTexture );
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 800, 600, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glGenTextures(1, &renderer->RenderTargetDepthTexture);
glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetDepthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 800, 600, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Attach the texture to the framebuffer.
glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, mRenderTargetDepthTexture, 0 );
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mRenderTargetTexture, 0);
// Attach the texture to the framebuffer.
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, renderer->RenderTargetDepthTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderer->RenderTargetTexture, 0);
assert(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return renderer;
}
RasterizeRenderer::~RasterizeRenderer()
void preview_cleanup(PreviewRenderer* renderer)
{
}
void RasterizeRenderer::setScene(Scene* scene)
void preview_set_viewport(PreviewRenderer* renderer, Viewport* viewport)
{
mCurrentScene = scene;
}
void RasterizeRenderer::setTargetSize(glm::ivec2 size)
GLuint preview_get_rendered_texture(PreviewRenderer* renderer)
{
glBindFramebuffer(GL_FRAMEBUFFER, mRenderTarget);
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
return renderer->RenderTargetTexture;
}
glBindTexture(GL_TEXTURE_2D, mRenderTargetTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.x, size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
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, mRenderTargetDepthTexture);
glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, size.x, size.y, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL );
glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
glTexImage2D(
GL_TEXTURE_2D,
0,
GL_RGB,
viewport.x,
viewport.y,
0,
GL_RGB,
GL_UNSIGNED_BYTE,
NULL);
glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetDepthTexture);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_DEPTH24_STENCIL8,
viewport.x,
viewport.y,
0,
GL_DEPTH_COMPONENT,
GL_FLOAT,
NULL);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
mRenderTargetSize = size;
}
GLuint RasterizeRenderer::getRenderedTexture()
{
glBindFramebuffer(GL_FRAMEBUFFER, mRenderTarget);
return mRenderTargetTexture;
}
// clear
glm::ivec2 RasterizeRenderer::getTargetSize()
{
return mRenderTargetSize;
}
void RasterizeRenderer::prepare()
{
glBindFramebuffer(GL_FRAMEBUFFER, mRenderTarget);
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 RasterizeRenderer::draw()
{
glBindFramebuffer(GL_FRAMEBUFFER, mRenderTarget);
glViewport(0, 0, mRenderTargetSize.x, mRenderTargetSize.y);
// draw
glEnable(GL_DEPTH_TEST);
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
glViewport(0,
0,
renderer->Viewport.x,
renderer->Viewport.y);
for (Mesh* m : mCurrentScene->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)));
glEnable(GL_DEPTH_TEST);
GLint uniView = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "view");
glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(mCurrentScene->getCamera()->getViewMatrix()));
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 uniProj = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "proj");
glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(mCurrentScene->getCamera()->getProjectionMatrix()));
auto viewMatrix = graphics::camera_get_view(scene::scene_get_camera(scene));
auto projMatrix = graphics::camera_get_projection(scene::scene_get_camera(scene));
glBindVertexArray(m->getVAO());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->getEBO());
GLint uniTrans = glGetUniformLocation(graphics::shader_get_program(shader), "model");
glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f)));
glDrawElements(GL_TRIANGLES, m->getIndexCount() * sizeof(uint32_t), GL_UNSIGNED_INT, 0);
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

@@ -2,32 +2,29 @@
#include <graphics.hpp>
namespace inferno {
class Scene;
class RasterizeRenderer
{
public:
RasterizeRenderer();
~RasterizeRenderer();
void setScene(Scene* scene);
void setTargetSize(glm::ivec2 size);
glm::ivec2 getTargetSize();
GLuint getRenderedTexture();
void prepare();
void draw();
private:
GLuint mRenderTarget = 0;
GLuint mRenderTargetTexture = 0;
GLuint mRenderTargetDepthTexture = 0;
glm::ivec2 mRenderTargetSize = {1920, 1080};
Scene* mCurrentScene;
};
#include <memory>
namespace inferno::scene {
struct Scene;
}
namespace inferno::graphics {
struct Viewport;
typedef struct PreviewRenderer {
glm::ivec2 Viewport;
GLuint RenderTarget = 0;
GLuint RenderTargetTexture = 0;
GLuint RenderTargetDepthTexture = 0;
} PreviewRenderer;
PreviewRenderer* preview_create();
void preview_cleanup(PreviewRenderer* renderer);
GLuint preview_get_rendered_texture(PreviewRenderer* renderer);
void preview_draw(PreviewRenderer* renderer, scene::Scene* scene);
} // namespace inferno::graphics

View File

@@ -1,158 +1,188 @@
#include "shader.hpp"
#include <iostream>
#include <fstream>
#include <iostream>
namespace inferno::graphics {
static std::unordered_map<GLuint, int> shader2Index = {
{ GL_VERTEX_SHADER, 0 },
{ GL_GEOMETRY_SHADER, 1 },
{ GL_FRAGMENT_SHADER, 2 }
};
inline std::string trim(std::string& str)
{
str.erase(str.find_last_not_of(' ')+1); //suffixing spaces
str.erase(0, str.find_first_not_of(' ')); //prefixing spaces
str.erase(str.find_last_not_of(' ') + 1); // suffixing spaces
str.erase(0, str.find_first_not_of(' ')); // prefixing spaces
return str;
}
static std::unordered_map<GLuint, int> Shader2Index = {
{GL_VERTEX_SHADER, 0},
{GL_GEOMETRY_SHADER, 1},
{GL_FRAGMENT_SHADER, 2}
};
using namespace inferno;
std::string textFromFile(const std::filesystem::path& path) {
std::string textFromFile(const std::filesystem::path& path)
{
std::ifstream input(path);
return std::string((std::istreambuf_iterator<char>(input)),
std::istreambuf_iterator<char>());
std::istreambuf_iterator<char>());
}
Shader::Shader()
: mShaders({ GL_NONE, GL_NONE, GL_NONE})
, mProgram(0) {
}
Shader::~Shader() {
for (int i = 0; i < 3; i++) {
if (mShaders[i] == GL_NONE) continue;
glDeleteShader(mShaders[i]);
}
}
Shader* Shader::load(std::filesystem::path path) {
assert(std::filesystem::exists(path));
std::string loadedShaderSource = textFromFile(path);
for (int i = 0; i < loadedShaderSource.length(); i++) {
const char& c = loadedShaderSource[i];
if (c == '#') {
mPreprocessorDefinition def = { .start = i };
int j;
for (j = ++i; loadedShaderSource[j] != ' '; j++) {
def.key += loadedShaderSource[j];
}
for (j++; loadedShaderSource[j] != '\n'; j++) {
def.def += loadedShaderSource[j];
}
def.end = j; i = j; // advance i
def.def = trim(def.def);
def.key = trim(def.key);
mDefinitions.push_back(def);
}
}
// now we have all of the key/value definitions
// we can extract the relavent ones, for example
// "type"
auto types = mGetKeys("type");
int i = 0;
for (const mPreprocessorDefinition* type : types) {
GLuint glType = GL_NONE;
if (type->def == "vertex") glType = GL_VERTEX_SHADER;
if (type->def == "geometry") glType = GL_GEOMETRY_SHADER;
if (type->def == "fragment") glType = GL_FRAGMENT_SHADER;
assert(glType != GL_NONE);
mShaders[Shader2Index[glType]] = glCreateShader(glType);
const char* source = loadedShaderSource.c_str() + type->end;
int end = types.size() - 1 == i ? types.size(): types[i + 1]->start;
int length = end - type->end;
glShaderSource(mShaders[Shader2Index[glType]], 1, &source, &length);
i++;
}
return this;
}
Shader* Shader::link() {
mProgram = glCreateProgram();
for (int i = 0; i < 3; i++) {
if (mShaders[i] == GL_NONE) continue;
glCompileShader(mShaders[i]);
if (!mCheckShader(mShaders[i])) continue;
glAttachShader(mProgram, mShaders[i]);
}
glLinkProgram(mProgram);
return this;
}
Shader* Shader::use() {
glUseProgram(mProgram);
return this;
}
Shader* Shader::unUse() {
glUseProgram(0);
return this;
}
GLuint Shader::getProgram()
std::vector<const ShaderPreprocessorDefinition*> getKeys(Shader* shader, std::string key)
{
return mProgram;
std::vector<const ShaderPreprocessorDefinition*> ret;
for (const auto& p : shader->PreprocessorDefinitions)
if (p.key == key)
ret.push_back(&p);
return ret;
}
bool checkShader(GLuint uid)
{
GLint isCompiled = 0;
glGetShaderiv(uid, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE) {
GLint maxLength = 0;
glGetShaderiv(uid, GL_INFO_LOG_LENGTH, &maxLength);
void Shader::addAttribute(const std::string& attribute) {
mAttributes[attribute] = glGetAttribLocation(mProgram, attribute.c_str());
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(uid, maxLength, &maxLength, &errorLog[0]);
for (int i = 0; i < errorLog.size(); i++) {
std::cout << errorLog[i];
}
glDeleteShader(uid);
return false;
}
return true;
}
void Shader::addUniform(const std::string& uniform) {
mUniformLocations[uniform] = glGetUniformLocation(mProgram, uniform.c_str());
Shader* shader_create()
{
Shader* shader = new Shader;
shader->Program = 0;
shader->Shaders[0] = GL_NONE;
shader->Shaders[1] = GL_NONE;
shader->Shaders[2] = GL_NONE;
return shader;
}
bool Shader::mCheckShader(GLuint uid) {
GLint isCompiled = 0;
glGetShaderiv(uid, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(uid, GL_INFO_LOG_LENGTH, &maxLength);
void shader_cleanup(Shader* shader)
{
for (int i = 0; i < 3; i++) {
if (shader->Shaders[i] == GL_NONE)
continue;
glDeleteShader(shader->Shaders[i]);
}
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(uid, maxLength, &maxLength, &errorLog[0]);
for (int i = 0; i < errorLog.size(); i++) {
std::cout << errorLog[i];
}
glDeleteShader(uid);
return false;
}
return true;
glDeleteProgram(shader->Program);
}
void shader_load(Shader* shader, std::filesystem::path path)
{
assert(std::filesystem::exists(path));
std::string loadedShaderSource = textFromFile(path);
for (int i = 0; i < loadedShaderSource.length(); i++) {
const char& c = loadedShaderSource[i];
if (c == '#') {
ShaderPreprocessorDefinition def = { .start = i };
int j;
for (j = ++i; loadedShaderSource[j] != ' '; j++) {
def.key += loadedShaderSource[j];
}
for (j++; loadedShaderSource[j] != '\n'; j++) {
def.def += loadedShaderSource[j];
}
def.end = j;
i = j; // advance i
def.def = trim(def.def);
def.key = trim(def.key);
shader->PreprocessorDefinitions.push_back(def);
}
}
// now we have all of the key/value definitions
// we can extract the relavent ones, for example
// "type"
std::vector<const ShaderPreprocessorDefinition*> types = getKeys(shader, "type");
int i = 0;
for (const ShaderPreprocessorDefinition* type : types) {
GLuint glType = GL_NONE;
if (type->def == "vertex")
glType = GL_VERTEX_SHADER;
if (type->def == "geometry")
glType = GL_GEOMETRY_SHADER;
if (type->def == "fragment")
glType = GL_FRAGMENT_SHADER;
assert(glType != GL_NONE);
shader->Shaders[shader2Index[glType]] = glCreateShader(glType);
const char* source = loadedShaderSource.c_str() + type->end;
int end = types.size() - 1 == i ? types.size() : types[i + 1]->start;
int length = end - type->end;
glShaderSource(shader->Shaders[shader2Index[glType]], 1, &source, &length);
i++;
}
}
void shader_link(Shader* shader)
{
shader->Program = glCreateProgram();
for (int i = 0; i < 3; i++) {
if (shader->Shaders[i] == GL_NONE)
continue;
glCompileShader(shader->Shaders[i]);
if (!checkShader(shader->Shaders[i]))
continue;
glAttachShader(shader->Program, shader->Shaders[i]);
}
glLinkProgram(shader->Program);
}
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(Shader* shader, const std::string& uniform)
{
shader->Uniforms[uniform] = glGetUniformLocation(shader->Program, uniform.c_str());
}
GLuint shader_get_attribute(Shader* shader, const std::string& attribute)
{
return shader->Attributes[attribute];
}
GLuint shader_get_uniform(Shader* shader, const std::string& uniform)
{
return shader->Uniforms[uniform];
}
void shader_use(Shader* shader)
{
glUseProgram(shader->Program);
}
void shader_unuse(Shader* shader)
{
glUseProgram(0);
}
std::vector<const Shader::mPreprocessorDefinition*> Shader::mGetKeys(std::string key) {
std::vector<const Shader::mPreprocessorDefinition*> ret;
for (const auto& p : mDefinitions) if (p.key == key) ret.push_back(&p);
return ret;
}

View File

@@ -2,58 +2,43 @@
#include "../graphics.hpp"
#include <string>
#include <memory>
#include <vector>
#include <filesystem>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
namespace inferno {
namespace inferno::graphics {
class Shader {
public:
Shader();
~Shader();
typedef struct ShaderPreprocessorDefinition {
int start, end;
std::string key;
std::string def;
} shaderpreprocessordefinition;
Shader* preprocessorDefine(std::string statement);
typedef struct Shader {
GLuint Shaders[3];
GLuint Program;
std::unordered_map<std::string, GLuint> Attributes;
std::unordered_map<std::string, GLuint> Uniforms;
std::vector<ShaderPreprocessorDefinition> PreprocessorDefinitions;
} Shader;
Shader* load(std::filesystem::path path);
Shader* link();
Shader* shader_create();
void shader_cleanup(Shader* shader);
Shader* use();
Shader* unUse();
void shader_load(Shader* shader, std::filesystem::path path);
void shader_link(Shader* shader);
GLuint getProgram();
GLuint shader_get_program(Shader* shader);
void addAttribute(const std::string& attribute);
void addUniform(const std::string& uniform);
GLuint operator[](const std::string& attribute) {
return mAttributes[attribute];
}
GLuint operator()(const std::string& uniform) {
return mUniformLocations[uniform];
}
// TODO: Implement shader_reload
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);
private:
GLuint mShaders[3];
GLuint mProgram;
std::unordered_map<std::string, GLuint> mAttributes;
std::unordered_map<std::string, GLuint> mUniformLocations;
bool mCheckShader(GLuint uid);
private:
// preprocessor definitions can be defined by their
// start/end index, this is so that text can either be inserted
// in their place or for the "type" definition, the program
// can count until the next "type" definition per shader
struct mPreprocessorDefinition {
int start, end;
std::string key;
std::string def;
};
std::vector<mPreprocessorDefinition> mDefinitions;
std::vector<const Shader::mPreprocessorDefinition*> mGetKeys(std::string key);
};
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()
{
// 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 };
}
// #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);
//
// 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,132 +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>
using namespace inferno;
RayRenderer::RayRenderer(HHM* accelIface)
: mIface(accelIface)
{
mTarget = new glm::fvec4[mRenderTargetSize.x * mRenderTargetSize.y];
glGenTextures(1, &mRenderTargetTexture);
glBindTexture(GL_TEXTURE_2D, mRenderTargetTexture);
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, mRenderTargetSize.x, mRenderTargetSize.y, 0, GL_RGBA, GL_FLOAT, mTarget);
glBindTexture(GL_TEXTURE_2D, 0);
}
RayRenderer::~RayRenderer()
{
delete[] mTarget;
}
void RayRenderer::setScene(Scene* scene)
{
mCurrentScene = scene;
if (mRaySource != nullptr)
{
delete mRaySource;
}
mRaySource = new RaySource(scene->getCamera());
// the scene will be sent to the module on prepare
// as it did update during initialisation
// mIface->newScene(scene);
}
void RayRenderer::setTargetSize(glm::ivec2 size)
{
mRenderTargetSize = size;
}
glm::ivec2 RayRenderer::getTargetSize()
{
return mRenderTargetSize;
}
GLuint RayRenderer::getRenderedTexture()
{
std::lock_guard<std::mutex> lock(this->_RenderData);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, mRenderTargetTexture);
return mRenderTargetTexture;
}
glm::fvec4* RayRenderer::getRenderData()
{
return mTarget;
}
void RayRenderer::prepare()
{
assert(mCurrentScene != nullptr);
if (mCurrentScene->didUpdate())
{
yolo::debug("New Scene!");
mIface->newScene(mCurrentScene);
}
}
void RayRenderer::draw()
{
mCurrentScene->newFrame();
// 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};
}
// #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

@@ -2,58 +2,44 @@
#include <graphics.hpp>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <unordered_map>
#include <condition_variable>
namespace inferno {
namespace inferno::scene {
struct Scene;
}
namespace inferno::graphics {
class HHM;
class Scene;
class HitInfo;
class RaySource;
class RenderDispatcher;
class RayRenderer
{
public:
RayRenderer(HHM* accelIface);
~RayRenderer();
typedef struct RayRenderer {
glm::ivec2* Viewport;
void setScene(Scene* scene);
// TODO: Can this be direct 2 GPU?
glm::fvec4* RenderData = nullptr;
GLuint RenderTargetTexture = 0;
void setTargetSize(glm::ivec2 size);
glm::ivec2 getTargetSize();
GLuint getRenderedTexture();
glm::fvec4* getRenderData();
// Internal stuffs
RaySource* RaySource = nullptr;
} RayRenderer;
void prepare();
void draw();
RayRenderer* rayr_create(glm::ivec2 viewport, HHM* accelIface);
void rayr_cleanup(RayRenderer* renderer);
public:
void computeHit(HitInfo* info);
void rayr_set_viewport(RayRenderer* renderer, glm::ivec2 size);
private:
void mHaultWait();
GLuint rayr_get_rendered_texture(RayRenderer* renderer);
glm::fvec4* rayr_get_render_data(RayRenderer* renderer);
std::unordered_map<uint32_t, glm::ivec2>* mCurrentRefTable;
void rayr_draw(RayRenderer* renderer, scene::Scene* scene);
private:
GLuint mRenderTargetTexture = 0;
glm::fvec4* mTarget;
void raryr_compute_hit(HitInfo* info);
std::mutex _RenderData;
std::condition_variable _RenderPause;
glm::ivec2 mRenderTargetSize = {200, 200};
Scene* mCurrentScene = nullptr;
RaySource* mRaySource = nullptr;
friend class RenderDispatcher;
private:
HHM* mIface;
};
}
} // namespace inferno::graphics

View File

@@ -1,205 +1,229 @@
#include <scene/camera.hpp>
using namespace inferno;
namespace inferno::graphics {
Camera::Camera()
Camera* camera_create()
{
mProjMatrix = glm::perspective( glm::radians(FOV), 1.0f, 0.1f, 1000.0f );
Camera* camera = new Camera;
camera->_impl = new _CameraImpl;
Roll = 0.0f;
Pitch = 0.0f;
Yaw = 0.0f;
camera->Views = Viewports();
camera->Views.Raster = glm::ivec2(800, 600);
camera->Views.Ray = glm::ivec2(800, 600);
Position = {};
LookDirection = {};
camera->ProjectionMatrix = glm::perspective(
glm::radians(camera->FOV),
1.0f,
0.1f,
1000.0f);
camera->ViewMatrix = {};
mViewMatrix = {};
camera->Roll = 0.0f;
camera->Pitch = 0.0f;
camera->Yaw = 0.0f;
update();
camera->Position = {};
camera->LookDirection = {};
camera_update(camera);
return camera;
}
Camera::Camera(int w, int h)
void camera_cleanup(Camera* camera)
{
mProjMatrix = glm::perspective(glm::radians(FOV), (float)w / (float)h, 0.1f, 1000.0f);
Roll = 0.0f;
Pitch = 0.0f;
Yaw = 0.0f;
Position = {};
LookDirection = {};
mViewMatrix = {};
update();
delete camera->_impl;
delete camera;
}
void Camera::update()
void camera_update(Camera* camera)
{
glm::mat4 matRoll = glm::mat4(1.0f);
glm::mat4 matPitch = glm::mat4(1.0f);
glm::mat4 matYaw = glm::mat4(1.0f);
glm::mat4 matRoll = glm::mat4(1.0f);
glm::mat4 matPitch = glm::mat4(1.0f);
glm::mat4 matYaw = glm::mat4(1.0f);
matRoll = glm::rotate(matRoll, Roll, glm::vec3(0.0f, 0.0f, 1.0f));
matPitch = glm::rotate(matPitch, Pitch, glm::vec3(1.0f, 0.0f, 0.0f));
matYaw = glm::rotate(matYaw, Yaw, glm::vec3( 0.0f, 1.0f, 0.0f));
matRoll = glm::rotate(matRoll, camera->Roll, glm::vec3(0.0f, 0.0f, 1.0f));
matPitch = glm::rotate(matPitch, camera->Pitch, glm::vec3(1.0f, 0.0f, 0.0f));
matYaw = glm::rotate(matYaw, camera->Yaw, glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 rotate = matRoll * matPitch * matYaw;
mCameraLook = rotate;
glm::mat4 rotate = matRoll * matPitch * matYaw;
camera->LookMatrix = rotate;
glm::mat4 translate = glm::mat4(1.0f);
translate = glm::translate(translate, -Position);
glm::mat4 translate = glm::mat4(1.0f);
translate = glm::translate(translate, -camera->Position);
std::lock_guard<std::mutex> lock(this->_mCam);
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
mViewMatrix = rotate * translate;
mProjMatrix = glm::perspective(glm::radians(FOV), mViewport.x / mViewport.y, 0.1f, 1000.0f);
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),
0.1f,
1000.0f);
// Work out Look Vector
glm::mat4 inverseView = glm::inverse(mViewMatrix);
// Work out Look Vector
glm::mat4 inverseView = glm::inverse(camera->ViewMatrix);
LookDirection.x = inverseView[2][0];
LookDirection.y = inverseView[2][1];
LookDirection.z = inverseView[2][2];
camera->LookDirection.x = inverseView[2][0];
camera->LookDirection.y = inverseView[2][1];
camera->LookDirection.z = inverseView[2][2];
mDidUpdate = true;
camera->_impl->DidUpdate = true;
}
bool Camera::didUpdate()
bool camera_did_update(Camera* camera)
{
std::lock_guard<std::mutex> lock(this->_mCam);
return mDidUpdate;
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->_impl->DidUpdate;
}
void Camera::newFrame()
void camera_new_frame(Camera* camera)
{
std::lock_guard<std::mutex> lock(this->_mCam);
mDidUpdate = false;
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
camera->_impl->DidUpdate = false;
}
glm::mat4 Camera::getViewMatrix()
glm::mat4 camera_get_view(Camera* camera)
{
std::lock_guard<std::mutex> lock(this->_mCam);
return mViewMatrix;
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->ViewMatrix;
}
glm::mat4 Camera::getProjectionMatrix()
glm::mat4 camera_get_projection(Camera* camera)
{
std::lock_guard<std::mutex> lock(this->_mCam);
return mProjMatrix;
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->ProjectionMatrix;
}
glm::mat4 Camera::getCameraLook()
glm::mat4 camera_get_look(Camera* camera)
{
std::lock_guard<std::mutex> lock(this->_mCam);
return mCameraLook;
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->LookMatrix;
}
void Camera::setRasterViewport(glm::vec2 viewport)
void raster_set_viewport(Camera* camera, glm::ivec2 viewport)
{
std::lock_guard<std::mutex> lock(this->_mCam);
mViewport = viewport;
mProjMatrix = glm::perspective(glm::radians(FOV), (float)viewport.x / (float)viewport.y, 0.1f, 1000.0f);
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
camera->Views.Raster = viewport;
camera->ProjectionMatrix = glm::perspective(
glm::radians(camera->FOV),
static_cast<float>(viewport.x) / static_cast<float>(viewport.y),
0.1f,
1000.0f);
}
void Camera::moveCamera(uint8_t posDelta)
glm::ivec2 raster_get_viewport(Camera* camera)
{
if (posDelta == 0) return;
// Rotate by camera direction
glm::vec3 delta(0.0f);
glm::mat2 rotate {
cos(Yaw), -sin(Yaw),
sin(Yaw), cos(Yaw)
};
glm::vec2 f(0.0, 1.0);
f = f * rotate;
if (posDelta & 0x80) {
delta.z -= f.y;
delta.x -= f.x;
}
if (posDelta & 0x20) {
delta.z += f.y;
delta.x += f.x;
}
if (posDelta & 0x40) {
delta.z += f.x;
delta.x += -f.y;
}
if (posDelta & 0x10) {
delta.z -= f.x;
delta.x -= -f.y;
}
if (posDelta & 0x8) {
delta.y += 1;
}
if (posDelta & 0x4) {
delta.y -= 1;
}
// get current view matrix
glm::mat4 mat = getViewMatrix();
glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]);
glm::vec3 strafe(mat[0][0], mat[1][0], mat[2][0]);
// forward vector must be negative to look forward.
// read :http://in2gpu.com/2015/05/17/view-matrix/
Position += delta * CameraSpeed;
// update the view matrix
update();
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->Views.Raster;
}
void Camera::mouseMoved(glm::vec2 mouseDelta)
void ray_set_viewport(Camera* camera, glm::ivec2 viewport)
{
if (glm::length(mouseDelta) == 0) return;
// note that yaw and pitch must be converted to radians.
// this is done in update() by glm::rotate
Yaw += MouseSensitivity * (mouseDelta.x / 100);
Pitch += MouseSensitivity * (mouseDelta.y / 100);
Pitch = glm::clamp<float>(Pitch, -M_PI / 2, M_PI / 2);
update();
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
camera->Views.Ray = viewport;
}
void Camera::setPosition(glm::vec3 position)
glm::ivec2 ray_get_viewport(Camera* camera)
{
Position = position;
update();
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
return camera->Views.Ray;
}
void Camera::setEulerLook(float roll, float pitch, float yaw)
void camera_move(Camera* camera, uint8_t movement_delta)
{
Roll = roll; Pitch = pitch; Yaw = yaw;
LookDirection.x = cos(Yaw) * cos(Pitch);
LookDirection.y = sin(Yaw) * cos(Pitch);
LookDirection.z = sin(Pitch);
if (movement_delta == 0)
return;
update();
// Rotate by camera direction
glm::vec3 delta(0.0f);
glm::mat2 rotate {
cos(camera->Yaw), -sin(camera->Yaw),
sin(camera->Yaw), cos(camera->Yaw)
};
glm::vec2 f(0.0, 1.0);
f = f * rotate;
if (movement_delta & 0x80) {
delta.z -= f.y;
delta.x -= f.x;
}
if (movement_delta & 0x20) {
delta.z += f.y;
delta.x += f.x;
}
if (movement_delta & 0x40) {
delta.z += f.x;
delta.x += -f.y;
}
if (movement_delta & 0x10) {
delta.z -= f.x;
delta.x -= -f.y;
}
if (movement_delta & 0x8) {
delta.y += 1;
}
if (movement_delta & 0x4) {
delta.y -= 1;
}
// get current view matrix
glm::mat4 mat = camera_get_view(camera);
glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]);
glm::vec3 strafe(mat[0][0], mat[1][0], mat[2][0]);
// forward vector must be negative to look forward.
// read :http://in2gpu.com/2015/05/17/view-matrix/
camera->Position += delta * camera->Speed;
// update the view matrix
camera_update(camera);
}
void Camera::setLook(glm::vec3 lookDirection)
void camera_mouse_move(Camera* camera, glm::vec2 mouse_delta)
{
LookDirection = lookDirection;
Pitch = asin(-lookDirection.y);
Yaw = atan2(lookDirection.x, lookDirection.z);
if (glm::length(mouse_delta) == 0)
return;
// note that yaw and pitch must be converted to radians.
// this is done in update() by glm::rotate
camera->Yaw += camera->MouseSensitivity * (mouse_delta.x / 100);
camera->Pitch += camera->MouseSensitivity * (mouse_delta.y / 100);
camera->Pitch = glm::clamp<float>(camera->Pitch, -M_PI / 2, M_PI / 2);
update();
camera_update(camera);
}
void Camera::setRayViewport(glm::vec2 viewport)
void camera_set_position(Camera* camera, glm::vec3 position)
{
std::lock_guard<std::mutex> lock(this->_mCam);
mRayViewport = viewport;
camera->Position = position;
camera_update(camera);
}
glm::vec2 Camera::getRayViewport()
void camera_set_euler_look(Camera* camera, float roll, float pitch, float yaw)
{
std::lock_guard<std::mutex> lock(this->_mCam);
return mRayViewport;
camera->Roll = roll;
camera->Pitch = pitch;
camera->Yaw = yaw;
camera->LookDirection.x = cos(camera->Yaw) * cos(camera->Pitch);
camera->LookDirection.y = sin(camera->Yaw) * cos(camera->Pitch);
camera->LookDirection.z = sin(camera->Pitch);
camera_update(camera);
}
void camera_set_look(Camera* camera, glm::vec3 look_direction)
{
camera->LookDirection = look_direction;
camera->Pitch = asin(-look_direction.y);
camera->Yaw = atan2(look_direction.x, look_direction.z);
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)
void Material::setGlShader(graphics::Shader* shader)
{
mGlShader = shader;
}
Shader* Material::getGlShader()
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,49 +1,61 @@
#include "scene.hpp"
#include <scene/object.hpp>
#include <yolo/yolo.hpp>
#include <memory>
#include <scene/camera.hpp>
#include <scene/mesh.hpp>
#include <scene/object.hpp>
using namespace inferno;
namespace inferno::scene {
Scene::Scene()
Scene* scene_create()
{
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;
}
Scene::~Scene()
void scene_cleanup(Scene* scene)
{
}
void Scene::setCamera(Camera* camera)
void scene_add_object(Scene* scene, SceneObject* object)
{
mCurrentCamera = camera;
mDidUpdate = true;
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;
}
Camera* Scene::getCamera()
graphics::Camera* scene_get_camera(Scene* scene)
{
return mCurrentCamera;
return scene->Camera;
}
void Scene::addMesh(Mesh* mesh)
std::vector<SceneObject*>& scene_get_renderables(Scene* scene)
{
mMeshs.push_back(mesh);
mDidUpdate = true;
return scene->Objects;
}
bool Scene::didUpdate()
bool scene_did_update(Scene* scene)
{
return mDidUpdate;
return scene->DidUpdate;
}
void Scene::newFrame()
void scene_frame_tick(Scene* scene)
{
mDidUpdate = false;
scene->DidUpdate = false;
}
const std::vector<Mesh*>& Scene::getRenderables()
void scene_tick(Scene* scene)
{
return mMeshs;
for (auto& object : scene->Objects) {
// Shit here like animation idk
}
}
}

View File

@@ -1,37 +1,36 @@
#pragma once
#include "scene/object.hpp"
#include <memory>
#include <vector>
namespace inferno {
namespace inferno::graphics {
class Camera;
}
namespace inferno::scene {
class SceneObject;
class Camera;
class Mesh;
class Sky;
class Scene
{
public:
Scene();
~Scene();
typedef struct Scene {
std::vector<SceneObject*> Objects;
graphics::Camera* Camera;
bool DidUpdate = false;
} Scene;
void setCamera(Camera* camera);
Camera* getCamera();
void addMesh(Mesh* mesh);
Scene* scene_create();
void scene_cleanup(Scene* scene);
bool didUpdate();
void newFrame();
void scene_add_object(Scene* scene, SceneObject* object);
const std::vector<Mesh*>& getRenderables();
graphics::Camera* scene_get_camera(Scene* scene);
std::vector<SceneObject*>& scene_get_renderables(Scene* scene);
private:
std::vector<Mesh*> mMeshs;
bool scene_did_update(Scene* scene);
Camera* mCurrentCamera;
Sky* mCurrentSky;
void scene_frame_tick(Scene* scene);
void scene_tick(Scene* scene);
private:
bool mDidUpdate = false;
};
}
} // namespace inferno::scene

View File

@@ -1,21 +0,0 @@
#pragma once
namespace inferno::helpers {
template <class T>
class Singleton
{
public:
static T& GetInstance()
{
static T instance;
return instance;
}
Singleton( Singleton const& ) = delete;
void operator=( Singleton const& ) = delete;
protected:
Singleton() = default;
};
}

View File

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

View File

@@ -1,63 +1,169 @@
#include "window.hpp"
#include "gui/style.hpp"
#include "yolo/yolo.hpp"
using namespace inferno;
namespace inferno::graphics {
Window::Window() {}
static WINDOW_MODE WinMode = WINDOW_MODE::WIN_MODE_DEFAULT;
static KeyCallback UserKeyCallback = nullptr;
static int Width, Height;
static const char* GlslVersion;
static GLFWwindow* Window;
Window::~Window() {
void glfwKeyCallback(GLFWwindow* window, int key, int scancode,
int action, int mods)
{
if (UserKeyCallback != nullptr) {
UserKeyCallback(key, scancode, action, mods);
}
}
void glfwErrorCallback(int error, const char* description)
{
yolo::error("[GLFW {}] {}", error, description);
}
void setupGLFW(std::string title)
{
glfwSetErrorCallback(glfwErrorCallback);
if (!glfwInit())
throw std::runtime_error("Failed to initialize GLFW");
// Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2)
// GL ES 2.0 + GLSL 100
GlslVersion = "#version 100";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
#elif defined(__APPLE__)
// GL 3.2 + GLSL 150
GlslVersion = "#version 150";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
#else
// GL 4.5 + GLSL 450
GlslVersion = "#version 450";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only
#endif
// Create window with graphics context
Window = glfwCreateWindow(1280, 720, title.c_str(), NULL, NULL);
if (Window == NULL)
throw std::runtime_error("Could not create window");
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()
{
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
// Setup Dear ImGui style
ImGui::StyleColorsDark();
ImGuiIO& io = ImGui::GetIO();
(void)io;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleFonts; // FIXME-DPI: THIS CURRENTLY DOESN'T
// WORK AS EXPECTED. DON'T USE IN
// USER APP!
io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleViewports; // FIXME-DPI
// io.ConfigDockingWithShift
// = true;
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(Window, true);
ImGui_ImplOpenGL3_Init(GlslVersion);
inferno::SetupImGuiStyle2();
}
void shutdownImGui()
{
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void shutdownGLFW()
{
glfwDestroyWindow(Window);
glfwTerminate();
}
void window_create(std::string title, int width, int height)
{
Width = width;
Height = height;
setupGLFW(title);
glfwSetKeyCallback(Window, glfwKeyCallback);
setupImGui();
}
void window_cleanup()
{
shutdownImGui();
shutdownGLFW();
}
void Window::init(std::string title, int width, int height) {
this->width = width;
this->height = height;
setupGLFW(title);
glfwSetKeyCallback(getGLFWWindow(), glfwKeyCallback);
setupImGui();
void window_set_title(std::string title)
{
glfwSetWindowTitle(Window, title.c_str());
}
void Window::setTitle(std::string title) {
glfwSetWindowTitle(window, title.c_str());
void window_set_size(int w, int h)
{
Width = w;
Height = h;
glfwSetWindowSize(Window, Width, Height);
}
void Window::setSize(int w, int h) {
width = w;
height = h;
glfwSetWindowSize(window, width, height);
}
void window_set_pos(int x, int y) { glfwSetWindowPos(Window, x, y); }
void Window::setPos(int x, int y) { glfwSetWindowPos(window, x, y); }
glm::vec2 window_get_size() { return { Width, Height }; }
glm::vec2 Window::getSize() { return {width, height}; }
void window_get_pos(int& x, int& y) { glfwGetWindowPos(Window, &x, &y); }
void Window::getPos(int &x, int &y) { glfwGetWindowPos(window, &x, &y); }
GLFWwindow* window_get_glfw_window() { return Window; }
void Window::setFPSMode() {
mWinMode = WIN_MODE_FPS;
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
}
void Window::setKeyCallback(KeyCallback callback) { mKeyCallback = callback; }
KeyCallback Window::getKeyCallback() { return mKeyCallback; }
bool Window::newFrame() {
glfwPollEvents();
if (mWinMode == WIN_MODE_FPS) {
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
glfwSetCursorPos(window, (double)width / 2, (double)height / 2);
void window_set_mode(WINDOW_MODE mode)
{
WinMode = mode;
if (mode == WINDOW_MODE::WIN_MODE_FPS) {
glfwSetInputMode(Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
}
if (glfwWindowShouldClose(window)) {
}
void window_set_key_callback(KeyCallback callback) { UserKeyCallback = callback; }
KeyCallback window_get_key_callback() { return UserKeyCallback; }
bool window_new_frame()
{
glfwPollEvents();
if (WinMode == WIN_MODE_FPS) {
glfwSetInputMode(Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
glfwSetCursorPos(Window, (double)Width / 2, (double)Height / 2);
}
if (glfwWindowShouldClose(Window)) {
return false;
}
glfwGetWindowSize(window, &width, &height);
glfwGetWindowSize(Window, &Width, &Height);
glClearColor(0.1, 0.1, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -68,102 +174,20 @@ bool Window::newFrame() {
ImGui::Begin("main", nullptr, WINDOW_FLAGS);
ImGui::SetWindowPos(ImVec2(0, 0));
ImGui::SetWindowSize(ImVec2(width, height));
ImGui::SetWindowSize(ImVec2(Width, Height));
return true;
}
void Window::render() {
void window_render()
{
ImGui::End();
ImGui::Render();
auto io = ImGui::GetIO();
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(window);
glfwSwapBuffers(Window);
ImGui::UpdatePlatformWindows();
}
void Window::setupGLFW(std::string title) {
glfwSetErrorCallback(glfwErrorCallback);
if (!glfwInit())
throw std::runtime_error("Failed to initialize GLFW");
// Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2)
// GL ES 2.0 + GLSL 100
glslVersion = "#version 100";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
#elif defined(__APPLE__)
// GL 3.2 + GLSL 150
glslVersion = "#version 150";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
#else
// GL 4.5 + GLSL 450
glslVersion = "#version 450";
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only
#endif
// Create window with graphics context
window = glfwCreateWindow(1280, 720, title.c_str(), NULL, NULL);
if (window == NULL)
throw std::runtime_error("Could not create window");
glfwMakeContextCurrent(window);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
glfwSwapInterval(1); // Enable vsync
}
void Window::setupImGui() {
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
// Setup Dear ImGui style
ImGui::StyleColorsDark();
ImGuiIO &io = ImGui::GetIO();
(void)io;
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
io.ConfigFlags |=
ImGuiConfigFlags_DpiEnableScaleFonts; // FIXME-DPI: THIS CURRENTLY DOESN'T
// WORK AS EXPECTED. DON'T USE IN
// USER APP!
io.ConfigFlags |= ImGuiConfigFlags_DpiEnableScaleViewports; // FIXME-DPI
// io.ConfigDockingWithShift
// = true;
// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplOpenGL3_Init(glslVersion);
SetupImGuiStyle2();
}
void Window::shutdownImGui() {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
}
void Window::shutdownGLFW() {
glfwDestroyWindow(window);
glfwTerminate();
}
void Window::glfwKeyCallback(GLFWwindow *window, int key, int scancode,
int action, int mods) {
if (Window::GetInstance().getKeyCallback() != nullptr) {
Window::GetInstance().getKeyCallback()(key, scancode, action, mods);
}
}
void Window::glfwErrorCallback(int error, const char *description) {
yolo::error("[GLFW {}] {}", error, description);
}

View File

@@ -2,64 +2,37 @@
#include <string>
#include "singleton.hpp"
#include "graphics.hpp"
#define WINDOW_FLAGS ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoCollapse
namespace inferno {
namespace inferno::graphics {
typedef void (*KeyCallback)(int key, int scan, int action, int mod);
typedef void (*MouseCallback)(double x, double y);
enum WINDOW_MODE
{
enum WINDOW_MODE {
WIN_MODE_DEFAULT,
WIN_MODE_FPS,
};
class Window : public helpers::Singleton<Window>
{
public:
Window();
~Window();
void window_create(std::string title, int width, int height);
void window_cleanup();
void init(std::string title, int width, int height);
void window_set_title(std::string title);
bool newFrame();
void render();
void window_set_size(int w, int h);
void window_set_pos(int x, int y);
glm::vec2 window_get_size();
void window_get_pos(int& x, int& y);
void setTitle(std::string title);
void setSize(int w, int h);
void setPos(int x, int y);
GLFWwindow* window_get_glfw_window();
void window_set_mode(WINDOW_MODE mode);
glm::vec2 getSize();
void getPos(int& x, int& y);
GLFWwindow* getGLFWWindow() { return window; }
void window_set_key_callback(KeyCallback callback);
KeyCallback window_get_key_callback();
void setFPSMode();
void setKeyCallback(KeyCallback callback);
KeyCallback getKeyCallback();
private:
WINDOW_MODE mWinMode = WIN_MODE_DEFAULT;
private:
void setupGLFW(std::string title);
void setupImGui();
void shutdownImGui();
void shutdownGLFW();
static void glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
KeyCallback mKeyCallback = nullptr;
private:
static void glfwErrorCallback(int error, const char* description);
int width, height;
const char* glslVersion;
GLFWwindow* window;
};
bool window_new_frame();
void window_render();
}