diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..c8e7b33 --- /dev/null +++ b/.clang-format @@ -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 +... + diff --git a/CMakeLists.txt b/CMakeLists.txt index 897b76d..33edf86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() + diff --git a/libhart/scene/camera.hpp b/libhart/scene/camera.hpp index 77213a0..83e3267 100644 --- a/libhart/scene/camera.hpp +++ b/libhart/scene/camera.hpp @@ -3,56 +3,65 @@ #include #include +#include #include -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 diff --git a/src/hart_directory.cpp b/src/hart_directory.cpp deleted file mode 100644 index 571a7f7..0000000 --- a/src/hart_directory.cpp +++ /dev/null @@ -1,185 +0,0 @@ -#include "hart_directory.hpp" - -#include "inferno_hart.hpp" - -#include - -#include - -using namespace inferno; - -HARTModuleDirectory::HARTModuleDirectory() -{ - -} - -HARTModuleDirectory::~HARTModuleDirectory() -{ - -} - -std::vector 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 HARTModuleDirectory::getModules() -{ - std::vector 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 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 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; -} diff --git a/src/hart_directory.hpp b/src/hart_directory.hpp deleted file mode 100644 index 6ddf462..0000000 --- a/src/hart_directory.hpp +++ /dev/null @@ -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 - -#include -#include -#include -#include - -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 discoverModules(std::filesystem::path path, bool recurse = false); - discoveryEntry registerModule(std::filesystem::path file); - - std::vector 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 mEntries; -}; - -} - diff --git a/src/hart_module.cpp b/src/hart_module.cpp deleted file mode 100644 index 3b14733..0000000 --- a/src/hart_module.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "hart_module.hpp" - -#include -#include - -#include -#include - -#include - -#include - -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 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(); -} diff --git a/src/hart_module.hpp b/src/hart_module.hpp deleted file mode 100644 index 9317c8d..0000000 --- a/src/hart_module.hpp +++ /dev/null @@ -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 - -#include -#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; -}; - -} diff --git a/src/inferno.cpp b/src/inferno.cpp index 4f0bce9..e16e0e3 100644 --- a/src/inferno.cpp +++ b/src/inferno.cpp @@ -1,54 +1,72 @@ #include "inferno.hpp" #include -#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 +#include #include #include -#include #include -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 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 diff --git a/src/inferno.hpp b/src/inferno.hpp index 0eeb685..5d895bf 100644 --- a/src/inferno.hpp +++ b/src/inferno.hpp @@ -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 +#include namespace inferno { -class Window; -class HHM; - -class RasterizeRenderer; -class RenderDispatcher; -class Scene; - -class Inferno : public helpers::Singleton -{ -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 diff --git a/src/main.cpp b/src/main.cpp index 2d7a693..0ffa398 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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); } diff --git a/src/preview_renderer/renderer.cpp b/src/preview_renderer/renderer.cpp index 4fdacdc..0036a97 100644 --- a/src/preview_renderer/renderer.cpp +++ b/src/preview_renderer/renderer.cpp @@ -1,114 +1,140 @@ #include "renderer.hpp" +#include "scene/object.hpp" #include "shader.hpp" +#include + +#include #include -#include #include #include +#include +#include #include -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); + 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); + 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); - - 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))); + glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget); + glViewport(0, + 0, + renderer->Viewport.x, + renderer->Viewport.y); - GLint uniView = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "view"); - glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(mCurrentScene->getCamera()->getViewMatrix())); + glEnable(GL_DEPTH_TEST); - GLint uniProj = glGetUniformLocation(m->getMaterial()->getGlShader()->getProgram(), "proj"); - glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(mCurrentScene->getCamera()->getProjectionMatrix())); - - glBindVertexArray(m->getVAO()); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->getEBO()); + 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); - glDrawElements(GL_TRIANGLES, m->getIndexCount() * sizeof(uint32_t), GL_UNSIGNED_INT, 0); + auto viewMatrix = graphics::camera_get_view(scene::scene_get_camera(scene)); + auto projMatrix = graphics::camera_get_projection(scene::scene_get_camera(scene)); + + GLint uniTrans = glGetUniformLocation(graphics::shader_get_program(shader), "model"); + glUniformMatrix4fv(uniTrans, 1, GL_FALSE, glm::value_ptr(glm::mat4(1.0f))); + + GLint uniView = glGetUniformLocation(graphics::shader_get_program(shader), "view"); + glUniformMatrix4fv(uniView, 1, GL_FALSE, glm::value_ptr(viewMatrix)); + + GLint uniProj = glGetUniformLocation(graphics::shader_get_program(shader), "proj"); + glUniformMatrix4fv(uniProj, 1, GL_FALSE, glm::value_ptr(projMatrix)); + + glBindVertexArray(m->getVAO()); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->getEBO()); + + glDrawElements(GL_TRIANGLES, m->getIndexCount() * sizeof(uint32_t), GL_UNSIGNED_INT, 0); + } } - + glBindFramebuffer(GL_FRAMEBUFFER, 0); } + +} diff --git a/src/preview_renderer/renderer.hpp b/src/preview_renderer/renderer.hpp index 4d0c059..4120d8b 100644 --- a/src/preview_renderer/renderer.hpp +++ b/src/preview_renderer/renderer.hpp @@ -2,32 +2,29 @@ #include -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 +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 diff --git a/src/preview_renderer/shader.cpp b/src/preview_renderer/shader.cpp index 34f005f..e085ff2 100644 --- a/src/preview_renderer/shader.cpp +++ b/src/preview_renderer/shader.cpp @@ -1,158 +1,188 @@ #include "shader.hpp" -#include #include +#include + +namespace inferno::graphics { + +static std::unordered_map 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 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::ifstream input(path); - return std::string((std::istreambuf_iterator(input)), - std::istreambuf_iterator()); - -} - -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::string textFromFile(const std::filesystem::path& path) { - return mProgram; + std::ifstream input(path); + return std::string((std::istreambuf_iterator(input)), + std::istreambuf_iterator()); } - -void Shader::addAttribute(const std::string& attribute) { - mAttributes[attribute] = glGetAttribLocation(mProgram, attribute.c_str()); +std::vector getKeys(Shader* shader, std::string key) +{ + std::vector ret; + for (const auto& p : shader->PreprocessorDefinitions) + if (p.key == key) + ret.push_back(&p); + return ret; } -void Shader::addUniform(const std::string& uniform) { - mUniformLocations[uniform] = glGetUniformLocation(mProgram, uniform.c_str()); +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); + + std::vector 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; } -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); +Shader* shader_create() +{ + Shader* shader = new Shader; - std::vector errorLog(maxLength); - glGetShaderInfoLog(uid, maxLength, &maxLength, &errorLog[0]); + shader->Program = 0; + shader->Shaders[0] = GL_NONE; + shader->Shaders[1] = GL_NONE; + shader->Shaders[2] = GL_NONE; - for (int i = 0; i < errorLog.size(); i++) { - std::cout << errorLog[i]; - } - - glDeleteShader(uid); - return false; - } - - return true; + return shader; +} + +void shader_cleanup(Shader* shader) +{ + for (int i = 0; i < 3; i++) { + if (shader->Shaders[i] == GL_NONE) + continue; + glDeleteShader(shader->Shaders[i]); + } + + 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 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 Shader::mGetKeys(std::string key) { - std::vector ret; - for (const auto& p : mDefinitions) if (p.key == key) ret.push_back(&p); - return ret; } diff --git a/src/preview_renderer/shader.hpp b/src/preview_renderer/shader.hpp index f2661e3..ae8a56f 100644 --- a/src/preview_renderer/shader.hpp +++ b/src/preview_renderer/shader.hpp @@ -2,58 +2,43 @@ #include "../graphics.hpp" -#include -#include -#include #include +#include +#include #include +#include -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 Attributes; + std::unordered_map Uniforms; + std::vector 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 mAttributes; - std::unordered_map 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 mDefinitions; - std::vector mGetKeys(std::string key); -}; +void shader_use(Shader* shader); +void shader_unuse(Shader* shader); } diff --git a/src/renderer/dispatcher.cpp b/src/renderer/dispatcher.cpp deleted file mode 100644 index bc1515e..0000000 --- a/src/renderer/dispatcher.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "dispatcher.hpp" - -#include "hart_module.hpp" -#include "renderer.hpp" - -#include -#include - -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* doWork, std::atomic* 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 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; -} diff --git a/src/renderer/dispatcher.hpp b/src/renderer/dispatcher.hpp deleted file mode 100644 index fd18921..0000000 --- a/src/renderer/dispatcher.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include - -#include -#include -#include - -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 mDoWork = false; - std::atomic mJoin = false; -}; - -} diff --git a/src/renderer/ray_source.cpp b/src/renderer/ray_source.cpp index f5e376e..62393e2 100644 --- a/src/renderer/ray_source.cpp +++ b/src/renderer/ray_source.cpp @@ -1,70 +1,70 @@ -#include "ray_source.hpp" - -#include - -#include - -#include - -#include - -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 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 +// +// #include +// +// #include +// +// #include +// +// 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 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 }; +// } diff --git a/src/renderer/ray_source.hpp b/src/renderer/ray_source.hpp index 0b3ae52..9ccce94 100644 --- a/src/renderer/ray_source.hpp +++ b/src/renderer/ray_source.hpp @@ -1,33 +1,33 @@ -#pragma once - -#include -#include - -#include - -#include - -namespace inferno { - -class Camera; - -struct ReferencedRayField -{ - RayField Field; - std::unordered_map Reference; -}; - -class RaySource -{ -public: - RaySource(Camera* camera); - ~RaySource(); - - void generate(); - ReferencedRayField getInitialRays(bool MSAA); - -private: - Camera* mReferenceCamera; -}; - -} +// #pragma once +// +// #include +// #include +// +// #include +// +// #include +// +// namespace inferno { +// +// class Camera; +// +// struct ReferencedRayField { +// RayField Field; +// std::unordered_map Reference; +// }; +// +// +// class RaySource +// { +// public: +// RaySource(Camera* camera); +// ~RaySource(); +// +// void generate(); +// ReferencedRayField getInitialRays(bool MSAA); +// +// private: +// Camera* mReferenceCamera; +// }; +// +// } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 0cd3230..628aeae 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -1,132 +1,143 @@ -#include "renderer.hpp" - -#include - -#include -#include -#include -#include -#include - -#include "hart_module.hpp" -#include "ray_source.hpp" - -#include - -#include - -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 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 +// +// #include +// #include +// #include +// #include +// #include +// +// #include "ray_source.hpp" +// +// #include +// +// #include +// +// 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) +// { +// 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 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 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* mCurrentRefTable; +// +// +// } diff --git a/src/renderer/renderer.hpp b/src/renderer/renderer.hpp index ca3ad45..d3ac31d 100644 --- a/src/renderer/renderer.hpp +++ b/src/renderer/renderer.hpp @@ -2,58 +2,44 @@ #include +#include +#include #include #include -#include -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* 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 diff --git a/src/scene/camera.cpp b/src/scene/camera.cpp index 2d37c2a..90c30b3 100644 --- a/src/scene/camera.cpp +++ b/src/scene/camera.cpp @@ -1,205 +1,229 @@ #include -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 lock(this->_mCam); + std::lock_guard 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(camera->Views.Raster.x) / static_cast(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 lock(this->_mCam); - return mDidUpdate; + std::lock_guard lock(camera->_impl->CamMutex); + return camera->_impl->DidUpdate; } -void Camera::newFrame() +void camera_new_frame(Camera* camera) { - std::lock_guard lock(this->_mCam); - mDidUpdate = false; + std::lock_guard lock(camera->_impl->CamMutex); + camera->_impl->DidUpdate = false; } -glm::mat4 Camera::getViewMatrix() +glm::mat4 camera_get_view(Camera* camera) { - std::lock_guard lock(this->_mCam); - return mViewMatrix; + std::lock_guard lock(camera->_impl->CamMutex); + return camera->ViewMatrix; } -glm::mat4 Camera::getProjectionMatrix() +glm::mat4 camera_get_projection(Camera* camera) { - std::lock_guard lock(this->_mCam); - return mProjMatrix; + std::lock_guard lock(camera->_impl->CamMutex); + return camera->ProjectionMatrix; } -glm::mat4 Camera::getCameraLook() +glm::mat4 camera_get_look(Camera* camera) { - std::lock_guard lock(this->_mCam); - return mCameraLook; + std::lock_guard 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 lock(this->_mCam); - mViewport = viewport; - mProjMatrix = glm::perspective(glm::radians(FOV), (float)viewport.x / (float)viewport.y, 0.1f, 1000.0f); + std::lock_guard lock(camera->_impl->CamMutex); + camera->Views.Raster = viewport; + camera->ProjectionMatrix = glm::perspective( + glm::radians(camera->FOV), + static_cast(viewport.x) / static_cast(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 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(Pitch, -M_PI / 2, M_PI / 2); - - update(); + std::lock_guard 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 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(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 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 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; +} + +} diff --git a/src/scene/material.cpp b/src/scene/material.cpp index 95918fc..6d21036 100644 --- a/src/scene/material.cpp +++ b/src/scene/material.cpp @@ -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; } +} diff --git a/src/scene/material.hpp b/src/scene/material.hpp index 482a48e..ed70756 100644 --- a/src/scene/material.hpp +++ b/src/scene/material.hpp @@ -4,9 +4,12 @@ #include -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; }; } diff --git a/src/scene/mesh.cpp b/src/scene/mesh.cpp index 03f4bca..b81da20 100644 --- a/src/scene/mesh.cpp +++ b/src/scene/mesh.cpp @@ -6,7 +6,7 @@ #include -using namespace inferno; +namespace inferno::scene { Mesh::Mesh() { @@ -27,7 +27,7 @@ void Mesh::loadOBJ(std::filesystem::path file) for (int i = 0; i < vertCount * 3; i += 3) { Vert vert; - vert.Position = { + vert.Position = { mObjLoader->getPositions()[i], mObjLoader->getPositions()[i+1], mObjLoader->getPositions()[i+2], @@ -53,17 +53,17 @@ void Mesh::ready() // load data into vertex buffers glBindBuffer(GL_ARRAY_BUFFER, mVBO); - glBufferData(GL_ARRAY_BUFFER, mVerticies.size() * sizeof(Vert), &mVerticies[0], GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, mVerticies.size() * sizeof(Vert), &mVerticies[0], GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mEBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, mObjLoader->getIndexCount() * sizeof(uint32_t), &mObjLoader->getFaces()[0], GL_STATIC_DRAW); // set the vertex attribute pointers // vertex Positions - glEnableVertexAttribArray(0); + glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)0); // vertex normals - glEnableVertexAttribArray(1); + glEnableVertexAttribArray(1); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vert), (void*)offsetof(Vert, Normal)); // vertex UV glEnableVertexAttribArray(2); @@ -116,3 +116,5 @@ GLuint Mesh::getEBO() { return mEBO; } + +} diff --git a/src/scene/mesh.hpp b/src/scene/mesh.hpp index 05fc01c..fc585b2 100644 --- a/src/scene/mesh.hpp +++ b/src/scene/mesh.hpp @@ -1,15 +1,15 @@ #pragma once - #include #include #include -namespace inferno { +namespace inferno::scene { class ObjLoader; class Material; +// TODO: This should be procedural like everything else struct Vert { glm::vec3 Position; @@ -17,7 +17,7 @@ struct Vert glm::vec2 UV; }; -class Mesh +class Mesh { public: Mesh(); @@ -49,7 +49,7 @@ private: private: ObjLoader* mObjLoader; Material* mMaterial; - + std::vector mVerticies; }; diff --git a/src/scene/object.cpp b/src/scene/object.cpp index e69de29..25e8981 100644 --- a/src/scene/object.cpp +++ b/src/scene/object.cpp @@ -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& scene_object_get_meshs(SceneObject* object) +{ + return object->Meshs; +} + +} + diff --git a/src/scene/object.hpp b/src/scene/object.hpp index 2c82f5e..973b868 100644 --- a/src/scene/object.hpp +++ b/src/scene/object.hpp @@ -1,19 +1,20 @@ #pragma once +#include #include -namespace inferno { +namespace inferno::scene { class Mesh; -class Object -{ -public: - Object(); - ~Object(); +typedef struct SceneObject { + std::vector Meshs; +} SceneObject; -private: - std::vector mMeshs; -}; +SceneObject* scene_object_create(); +void scene_object_cleanup(SceneObject* object); -} +void scene_object_add_mesh(SceneObject* object, Mesh* mesh); +std::vector& scene_object_get_meshs(SceneObject* object); + +} // namespace inferno::scene diff --git a/src/scene/objloader.cpp b/src/scene/objloader.cpp index 8a0367a..7f0cec5 100644 --- a/src/scene/objloader.cpp +++ b/src/scene/objloader.cpp @@ -10,7 +10,7 @@ #include #include -using namespace inferno; +namespace inferno::scene { struct FaceVert { @@ -60,7 +60,7 @@ void ObjLoader::load(std::filesystem::path file) std::ifstream inf; inf.open(file.c_str(), std::ios_base::in); - if (!inf.is_open()) + if (!inf.is_open()) { yolo::error("Failed to open OBJ file ", file.string()); return; @@ -82,7 +82,7 @@ void ObjLoader::load(std::filesystem::path file) std::map uniqueverts; unsigned int vert_count = 0; - while (inf.good()) + while (inf.good()) { memset( (void*)line, 0, CHARACTER_COUNT); inf.getline(line, CHARACTER_COUNT); @@ -94,7 +94,7 @@ void ObjLoader::load(std::filesystem::path file) // verts look like: // v float float float - if (strcmp(token, "v") == 0) + if (strcmp(token, "v") == 0) { float x=0, y=0, z=0, w=1; sscanf(line+2, "%f %f %f %f", &x, &y, &z, &w); @@ -110,7 +110,7 @@ void ObjLoader::load(std::filesystem::path file) } // texcoords: // vt float float - else if (strcmp(token, "vt") == 0) + else if (strcmp(token, "vt") == 0) { float x=0, y=0, z=0; sscanf(line+3, "%f %f %f", &x, &y, &z); @@ -119,14 +119,14 @@ void ObjLoader::load(std::filesystem::path file) // keep track of smoothing groups // s [number|off] - else if (strcmp(token, "s") == 0) + else if (strcmp(token, "s") == 0) { } // faces start with: // f - else if (strcmp(token, "f") == 0) + else if (strcmp(token, "f") == 0) { std::vector vindices; @@ -164,7 +164,7 @@ void ObjLoader::load(std::filesystem::path file) // being that some exporters can export either 3 or 4 sided polygon's // convert what ever was exported into triangles - for (size_t i=1; i::iterator iter; - for (iter = uniqueverts.begin(); iter != uniqueverts.end(); ++iter) + for (iter = uniqueverts.begin(); iter != uniqueverts.end(); ++iter) { mPositions[iter->second] = verts[iter->first.vert]; - if ( norms.size() > 0 ) + if ( norms.size() > 0 ) { mNormals[iter->second] = norms[iter->first.norm]; } - if ( texcoords.size() > 0) + if ( texcoords.size() > 0) { mTexCoords[iter->second] = texcoords[iter->first.coord]; } - } + } } int ObjLoader::getIndexCount() @@ -263,3 +263,5 @@ const float* ObjLoader::getTexCoords(int multiTexCoordLayer) assert(multiTexCoordLayer < mTexCoordLayers); return (const float*)&mTexCoords[0]; } + +} diff --git a/src/scene/objloader.hpp b/src/scene/objloader.hpp index ce7b008..4141544 100644 --- a/src/scene/objloader.hpp +++ b/src/scene/objloader.hpp @@ -5,7 +5,7 @@ #include -namespace inferno { +namespace inferno::scene { struct Face { diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 75e451a..d518bd1 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -1,49 +1,61 @@ #include "scene.hpp" -#include +#include + +#include #include #include +#include -using namespace inferno; +namespace inferno::scene { -Scene::Scene() +Scene* scene_create() { - + Scene* scene = new Scene; + scene->Objects = std::vector(); + 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& 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& Scene::getRenderables() +void scene_tick(Scene* scene) { - return mMeshs; + for (auto& object : scene->Objects) { + // Shit here like animation idk + } +} + } diff --git a/src/scene/scene.hpp b/src/scene/scene.hpp index 0935348..6004da2 100644 --- a/src/scene/scene.hpp +++ b/src/scene/scene.hpp @@ -1,37 +1,36 @@ #pragma once +#include "scene/object.hpp" + +#include #include -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 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& getRenderables(); +graphics::Camera* scene_get_camera(Scene* scene); +std::vector& scene_get_renderables(Scene* scene); -private: - std::vector 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 diff --git a/src/singleton.hpp b/src/singleton.hpp deleted file mode 100644 index 4f63e80..0000000 --- a/src/singleton.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -namespace inferno::helpers { - -template -class Singleton -{ -public: - static T& GetInstance() - { - static T instance; - return instance; - } - - Singleton( Singleton const& ) = delete; - void operator=( Singleton const& ) = delete; -protected: - Singleton() = default; -}; - -} diff --git a/src/version.hpp b/src/version.hpp index 9e5aad7..d9a5fcc 100644 --- a/src/version.hpp +++ b/src/version.hpp @@ -1,3 +1,3 @@ #pragma once -#define INFERNO_VERSION "3.0.1_alpha" +#define INFERNO_VERSION "3.0.13_alpha" diff --git a/src/window.cpp b/src/window.cpp index 121a470..fd99e83 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -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); } diff --git a/src/window.hpp b/src/window.hpp index 6063da9..aee839f 100644 --- a/src/window.hpp +++ b/src/window.hpp @@ -2,64 +2,37 @@ #include -#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 -{ -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(); }