192
.clang-format
Normal file
192
.clang-format
Normal file
@@ -0,0 +1,192 @@
|
||||
---
|
||||
Language: Cpp
|
||||
# BasedOnStyle: WebKit
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignArrayOfStructures: None
|
||||
AlignConsecutiveMacros: None
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: None
|
||||
AlignConsecutiveDeclarations: None
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: DontAlign
|
||||
AlignTrailingComments: false
|
||||
AllowAllArgumentsOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortEnumsOnASingleLine: true
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: MultiLine
|
||||
AttributeMacros:
|
||||
- __capability
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: true
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
BeforeLambdaBody: false
|
||||
BeforeWhile: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: All
|
||||
BreakBeforeConceptDeclarations: true
|
||||
BreakBeforeBraces: WebKit
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 0
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
QualifierAlignment: Leave
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: false
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
PackConstructorInitializers: BinPack
|
||||
BasedOnStyle: ''
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
FixNamespaceComments: false
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IfMacros:
|
||||
- KJ_IF_MAYBE
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
CaseSensitive: false
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseLabels: false
|
||||
IndentCaseBlocks: false
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentExternBlock: AfterExternBlock
|
||||
IndentRequires: false
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: None
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
LambdaBodyIndentation: Signature
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: Inner
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 4
|
||||
ObjCBreakBeforeNestedBlockParam: true
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakOpenParenthesis: 0
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PenaltyIndentedWhitespace: 0
|
||||
PointerAlignment: Left
|
||||
PPIndentWidth: -1
|
||||
ReferenceAlignment: Pointer
|
||||
ReflowComments: true
|
||||
RemoveBracesLLVM: false
|
||||
SeparateDefinitionBlocks: Leave
|
||||
ShortNamespaceLines: 1
|
||||
SortIncludes: CaseSensitive
|
||||
SortJavaStaticImport: Before
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCaseColon: false
|
||||
SpaceBeforeCpp11BracedList: true
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeParensOptions:
|
||||
AfterControlStatements: true
|
||||
AfterForeachMacros: true
|
||||
AfterFunctionDefinitionName: false
|
||||
AfterFunctionDeclarationName: false
|
||||
AfterIfMacros: true
|
||||
AfterOverloadedOperator: false
|
||||
BeforeNonEmptyParentheses: false
|
||||
SpaceAroundPointerQualifiers: Default
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: Never
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInLineCommentPrefix:
|
||||
Minimum: 1
|
||||
Maximum: -1
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
BitFieldColonSpacing: Both
|
||||
Standard: Latest
|
||||
StatementAttributeLikeMacros:
|
||||
- Q_EMIT
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
WhitespaceSensitiveMacros:
|
||||
- STRINGIZE
|
||||
- PP_STRINGIZE
|
||||
- BOOST_PP_STRINGIZE
|
||||
- NS_SWIFT_NAME
|
||||
- CF_SWIFT_NAME
|
||||
...
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -3,56 +3,65 @@
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace inferno {
|
||||
namespace inferno::graphics {
|
||||
|
||||
class Camera {
|
||||
public:
|
||||
Camera();
|
||||
Camera(int w, int h);
|
||||
typedef struct _CameraImpl {
|
||||
bool DidUpdate;
|
||||
std::mutex CamMutex;
|
||||
} _CameraImpl;
|
||||
|
||||
void update();
|
||||
bool didUpdate();
|
||||
void newFrame();
|
||||
typedef struct Viewport {
|
||||
glm::ivec2 Raster;
|
||||
glm::ivec2 Ray;
|
||||
} Viewports;
|
||||
|
||||
glm::mat4 getViewMatrix();
|
||||
glm::mat4 getProjectionMatrix();
|
||||
glm::mat4 getCameraLook();
|
||||
typedef struct Camera {
|
||||
glm::mat4 ViewMatrix;
|
||||
glm::mat4 ProjectionMatrix;
|
||||
glm::mat4 LookMatrix;
|
||||
|
||||
void setRasterViewport(glm::vec2 viewport);
|
||||
Viewport Views;
|
||||
|
||||
// Keyboard
|
||||
void moveCamera(uint8_t posDelta);
|
||||
// Mouse Delta
|
||||
void mouseMoved(glm::vec2 mouseDelta);
|
||||
float MouseSensitivity = 0.4f;
|
||||
float Speed = 0.1f;
|
||||
float Roll, Pitch, Yaw;
|
||||
float FOV = 45.0f;
|
||||
|
||||
void setPosition(glm::vec3 position);
|
||||
void setEulerLook(float roll, float pitch, float yaw);
|
||||
void setLook(glm::vec3 lookDirection);
|
||||
glm::vec3 Position = {};
|
||||
glm::vec3 LookDirection = {};
|
||||
|
||||
public:
|
||||
void setRayViewport(glm::vec2 viewport);
|
||||
glm::vec2 getRayViewport();
|
||||
_CameraImpl* _impl;
|
||||
} Camera;
|
||||
|
||||
public:
|
||||
// necessary evil
|
||||
float MouseSensitivity = 0.4f;
|
||||
float CameraSpeed = 0.1f;
|
||||
float Roll, Pitch, Yaw;
|
||||
float FOV = 45.0f;
|
||||
glm::vec3 Position = {};
|
||||
glm::vec3 LookDirection = {};
|
||||
Camera* camera_create();
|
||||
void camera_cleanup(Camera* camera);
|
||||
|
||||
private:
|
||||
glm::vec2 mViewport = { 100.0f, 100.0f };
|
||||
glm::vec2 mRayViewport = { 200.0f, 200.0f };
|
||||
glm::mat4 mViewMatrix = {};
|
||||
glm::mat4 mProjMatrix = {};
|
||||
glm::mat4 mCameraLook = {};
|
||||
bool mDidUpdate;
|
||||
void camera_update(Camera* camera);
|
||||
bool camera_did_update(Camera* camera);
|
||||
void camera_new_frame(Camera* camera);
|
||||
|
||||
std::mutex _mCam;
|
||||
};
|
||||
glm::mat4 camera_get_view(Camera* camera);
|
||||
glm::mat4 camera_get_projection(Camera* camera);
|
||||
glm::mat4 camera_get_look(Camera* camera);
|
||||
|
||||
}
|
||||
void raster_set_viewport(Camera* camera, glm::ivec2 viewport);
|
||||
glm::ivec2 raster_get_viewport(Camera* camera);
|
||||
|
||||
void ray_set_viewport(Camera* camera, glm::ivec2 viewport);
|
||||
glm::ivec2 ray_get_viewport(Camera* camera);
|
||||
|
||||
void camera_move(Camera* camera, uint8_t movement_delta);
|
||||
void camera_mouse_move(Camera* camera, glm::vec2 mouse_delta);
|
||||
|
||||
void camera_set_position(Camera* camera, glm::vec3 position);
|
||||
void camera_set_euler_look(Camera* camera, float roll,
|
||||
float pitch, float yaw);
|
||||
void camera_set_look(Camera* camera,
|
||||
glm::vec3 look_direction);
|
||||
|
||||
glm::vec3 camera_get_position(Camera* camera);
|
||||
|
||||
} // namespace inferno::graphics
|
||||
|
||||
@@ -1,185 +0,0 @@
|
||||
#include "hart_directory.hpp"
|
||||
|
||||
#include "inferno_hart.hpp"
|
||||
|
||||
#include <yolo/yolo.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace inferno;
|
||||
|
||||
HARTModuleDirectory::HARTModuleDirectory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HARTModuleDirectory::~HARTModuleDirectory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::vector<HARTModuleDirectory::discoveryEntry> HARTModuleDirectory::discoverModules(std::filesystem::path folder, bool recurse)
|
||||
{
|
||||
if (!std::filesystem::exists(folder)) return { };
|
||||
if (!std::filesystem::is_directory(folder))
|
||||
{
|
||||
return { this->registerModule(folder) };
|
||||
}
|
||||
|
||||
std::error_code err;
|
||||
if (recurse)
|
||||
{
|
||||
for (const auto& file : std::filesystem::recursive_directory_iterator(folder, err))
|
||||
{
|
||||
if (file.path().extension() == HART_EXTENSION)
|
||||
{
|
||||
this->registerModule(file);
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
for (const auto& file : std::filesystem::directory_iterator(folder, err))
|
||||
{
|
||||
if (file.path().extension() == HART_EXTENSION)
|
||||
{
|
||||
this->registerModule(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { };
|
||||
}
|
||||
|
||||
HARTModuleDirectory::discoveryEntry HARTModuleDirectory::registerModule(std::filesystem::path file)
|
||||
{
|
||||
yolo::info("Registering module at {}", file.c_str());
|
||||
|
||||
discoveryEntry entry;
|
||||
entry.Location = file;
|
||||
|
||||
#ifdef _WIN32
|
||||
entry.Handle = LoadLibraryA(file.c_str());
|
||||
if (entry.Handle == NULL)
|
||||
{
|
||||
yolo::error("Cannot load module at {}.", file.c_str());
|
||||
entry.Handle = NULL; entry.DidLink = false;
|
||||
return entry;
|
||||
}
|
||||
HART_CREDIT_F credit = (HART_CREDIT_F)GetProcAddress(entry.Handle, "_CREDIT");
|
||||
entry.InitCallback = (HART_INIT_F)GetProcAddress(entry.Handle, "_GET");
|
||||
entry.DestroyCallback = (HART_DESTROY_F)GetProcAddress(entry.Handle, "_DESTROY");
|
||||
#else // UNIX-Like
|
||||
entry.Handle = dlopen(file.c_str(), RTLD_NOW | RTLD_LOCAL);
|
||||
if (entry.Handle == NULL)
|
||||
{
|
||||
yolo::error("Cannot load module at ", dlerror());
|
||||
entry.Handle = NULL; entry.DidLink = false;
|
||||
return entry;
|
||||
}
|
||||
HART_CREDIT_F credit = (HART_CREDIT_F)dlsym(entry.Handle, "_CREDIT");
|
||||
entry.InitCallback = (HART_INIT_F)dlsym(entry.Handle, "_GET");
|
||||
entry.DestroyCallback = (HART_DESTROY_F)dlsym(entry.Handle, "_DESTROY");
|
||||
#endif
|
||||
|
||||
if (credit == NULL)
|
||||
{
|
||||
yolo::error("Cannot load module at {}... No credit...", file.c_str());
|
||||
entry.Handle = NULL; entry.DidLink = false;
|
||||
return entry;
|
||||
}
|
||||
if (entry.InitCallback == NULL)
|
||||
{
|
||||
yolo::error("Cannot load module at {}... No get...", file.c_str());
|
||||
entry.Handle = NULL; entry.DidLink = false;
|
||||
return entry;
|
||||
}
|
||||
if (entry.DestroyCallback == NULL)
|
||||
{
|
||||
yolo::error("Cannot load module at {}... No destroy...", file.c_str());
|
||||
entry.Handle = NULL; entry.DidLink = false;
|
||||
return entry;
|
||||
}
|
||||
|
||||
entry.Credit = (ModuleCredit*)credit();
|
||||
|
||||
yolo::info("Module {} v{}.{}.{} by {}", entry.Credit->ModuleName,
|
||||
entry.Credit->VersionMajor,
|
||||
entry.Credit->VersionMinor,
|
||||
entry.Credit->VersionBuild,
|
||||
entry.Credit->AuthorName);
|
||||
|
||||
entry.DidLink = true;
|
||||
mEntries[entry.Credit->ModuleName] = { entry, nullptr };
|
||||
|
||||
if (mEntries.size() == 1)
|
||||
{
|
||||
// this is the first, make it active - or else
|
||||
mActiveModule = entry.Credit->ModuleName;
|
||||
this->load(mActiveModule);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
std::vector<std::string> HARTModuleDirectory::getModules()
|
||||
{
|
||||
std::vector<std::string> keys;
|
||||
for(auto kv : mEntries)
|
||||
{
|
||||
keys.push_back(kv.first);
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
void HARTModuleDirectory::setActive(std::string moduleName)
|
||||
{
|
||||
if (moduleName == mActiveModule) return;
|
||||
this->destroy(mActiveModule);
|
||||
mActiveModule = moduleName;
|
||||
this->load(mActiveModule);
|
||||
}
|
||||
|
||||
void HARTModuleDirectory::setActiveIndex(int index)
|
||||
{
|
||||
std::vector<std::string> keys = this->getModules();
|
||||
this->setActive(keys[index]);
|
||||
}
|
||||
|
||||
HARTModule* HARTModuleDirectory::getActiveModule()
|
||||
{
|
||||
return mEntries[mActiveModule].Module;
|
||||
}
|
||||
|
||||
std::string HARTModuleDirectory::getActive()
|
||||
{
|
||||
return mActiveModule;
|
||||
}
|
||||
|
||||
int HARTModuleDirectory::getActiveIndex()
|
||||
{
|
||||
std::vector<std::string> keys = this->getModules();
|
||||
for (int i = 0; i < keys.size(); i++)
|
||||
{
|
||||
if (keys[i] == mActiveModule) return i;
|
||||
}
|
||||
return -1; // this should never happen
|
||||
}
|
||||
|
||||
ModuleCredit* HARTModuleDirectory::getActiveCredit()
|
||||
{
|
||||
return mEntries[mActiveModule].Discovery.Credit;
|
||||
}
|
||||
|
||||
void HARTModuleDirectory::load(std::string moduleName)
|
||||
{
|
||||
HARTModule* mod = (HARTModule*)mEntries[moduleName].Discovery.InitCallback();
|
||||
mEntries[moduleName].Module = mod;
|
||||
mEntries[moduleName].Active = true;
|
||||
}
|
||||
|
||||
void HARTModuleDirectory::destroy(std::string moduleName)
|
||||
{
|
||||
mEntries[moduleName].Discovery.DestroyCallback(mEntries[moduleName].Module);
|
||||
mEntries[moduleName].Module = nullptr;
|
||||
mEntries[moduleName].Active = false;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// INFERNO-HART Modules
|
||||
// _GET returns derived HARTModule
|
||||
// _DESTROY returns void but takes derived HARTModule
|
||||
// _CREDIT returns ModuleCredit
|
||||
|
||||
// THIS IS SHARED DO __NOT__ REINCLUDE libhart/thirdparty
|
||||
#include <inferno_hart.hpp>
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace inferno {
|
||||
|
||||
class HARTModule;
|
||||
struct ModuleCredit;
|
||||
|
||||
class HARTModuleDirectory
|
||||
{
|
||||
public:
|
||||
HARTModuleDirectory();
|
||||
~HARTModuleDirectory();
|
||||
|
||||
struct discoveryEntry
|
||||
{
|
||||
std::filesystem::path Location;
|
||||
bool DidLink = false;
|
||||
#ifdef _WIN32
|
||||
HMODULE Handle;
|
||||
#else // UNIX-Like
|
||||
void* Handle;
|
||||
#endif
|
||||
ModuleCredit* Credit;
|
||||
HART_INIT_F InitCallback;
|
||||
HART_DESTROY_F DestroyCallback;
|
||||
};
|
||||
|
||||
struct moduleEntry
|
||||
{
|
||||
discoveryEntry Discovery;
|
||||
HARTModule* Module;
|
||||
bool Active;
|
||||
};
|
||||
|
||||
// This can take a file or a directory, and inside the directory discover recursively or not
|
||||
std::vector<discoveryEntry> discoverModules(std::filesystem::path path, bool recurse = false);
|
||||
discoveryEntry registerModule(std::filesystem::path file);
|
||||
|
||||
std::vector<std::string> getModules();
|
||||
|
||||
void setActive(std::string moduleName);
|
||||
void setActiveIndex(int index);
|
||||
|
||||
HARTModule* getActiveModule();
|
||||
std::string getActive();
|
||||
int getActiveIndex();
|
||||
ModuleCredit* getActiveCredit();
|
||||
|
||||
void load(std::string moduleName);
|
||||
void destroy(std::string moduleName);
|
||||
|
||||
private:
|
||||
std::string mActiveModule;
|
||||
std::unordered_map<std::string, moduleEntry> mEntries;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
#include "hart_module.hpp"
|
||||
|
||||
#include <renderer/ray_source.hpp>
|
||||
#include <renderer/renderer.hpp>
|
||||
|
||||
#include <scene/scene.hpp>
|
||||
#include <scene/mesh.hpp>
|
||||
|
||||
#include <yolo/yolo.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace inferno;
|
||||
|
||||
HHM::HHM()
|
||||
: mDirectory()
|
||||
{
|
||||
mDirectory.discoverModules("./hart/", true);
|
||||
}
|
||||
|
||||
HHM::~HHM()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HARTModuleDirectory* HHM::getModuleDirectory()
|
||||
{
|
||||
return &mDirectory;
|
||||
}
|
||||
|
||||
HARTModule::EModuleState HHM::getModuleState()
|
||||
{
|
||||
HARTModule* mod = mDirectory.getActiveModule();
|
||||
return mod->getState();
|
||||
}
|
||||
|
||||
void HHM::newScene(Scene* scene)
|
||||
{
|
||||
HARTModule* mod = mDirectory.getActiveModule();
|
||||
std::vector<Mesh*> meshs = scene->getRenderables();
|
||||
// TODO: This may not be the way i want to approach it
|
||||
// as submitTris should take maybe a mesh ID and then the mesh data
|
||||
// as it is now, submitTris assumes it's getting the whole scene
|
||||
// which would involve a lot of mesh copying (avoid!) if i were to chain them
|
||||
for (auto* mesh : meshs) {
|
||||
void* verticies; void* normals; void* indicies;
|
||||
int vertexCount = mesh->getVerticies(&verticies, &normals);
|
||||
int indexCount = mesh->getIndicies(&indicies);
|
||||
yolo::debug("Mesh for module ready... {} {}", verticies, normals);
|
||||
mod->submitTris(verticies, normals, vertexCount, indicies, indexCount);
|
||||
}
|
||||
}
|
||||
|
||||
void HHM::notifySceneUpdate()
|
||||
{
|
||||
HARTModule* mod = mDirectory.getActiveModule();
|
||||
mod->updateTris();
|
||||
}
|
||||
|
||||
void rayHitCallback(void* hhm, HitInfo* hit)
|
||||
{
|
||||
((HHM*)hhm)->rayReturn(hit);
|
||||
}
|
||||
|
||||
void HHM::rayReturn(HitInfo* hit)
|
||||
{
|
||||
Renderer->computeHit(hit);
|
||||
}
|
||||
|
||||
void HHM::bounce(Ray* newRay)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void HHM::startTrace(RayField sourceScatter)
|
||||
{
|
||||
// TODO: Signal start
|
||||
HARTModule* mod = mDirectory.getActiveModule();
|
||||
mod->passContext((void*)this, &rayHitCallback);
|
||||
yolo::debug("SubmitQueue {}", sourceScatter.size());
|
||||
mod->submitQueue(sourceScatter);
|
||||
mod->start();
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
// the HHM (Hamlin Hamlin McGill) aka the Head HART Module keeps track of the module
|
||||
// and gives the renderer a cleaner interface to talk to a HART Module
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <graphics.hpp>
|
||||
#include "hart_directory.hpp"
|
||||
|
||||
namespace inferno {
|
||||
|
||||
class Scene;
|
||||
class Ray;
|
||||
class HitInfo;
|
||||
class HARTModule;
|
||||
class RayRenderer;
|
||||
|
||||
class HHM
|
||||
{
|
||||
public:
|
||||
HHM();
|
||||
~HHM();
|
||||
|
||||
HARTModuleDirectory* getModuleDirectory();
|
||||
HARTModule::EModuleState getModuleState();
|
||||
|
||||
void newScene(Scene* scene);
|
||||
void notifySceneUpdate();
|
||||
|
||||
void rayReturn(HitInfo* hit);
|
||||
void bounce(Ray* newRay);
|
||||
|
||||
void startTrace(RayField sourceScatter);
|
||||
|
||||
RayRenderer* Renderer;
|
||||
|
||||
private:
|
||||
HARTModuleDirectory mDirectory;
|
||||
};
|
||||
|
||||
}
|
||||
327
src/inferno.cpp
327
src/inferno.cpp
@@ -1,54 +1,72 @@
|
||||
#include "inferno.hpp"
|
||||
|
||||
#include <version.hpp>
|
||||
#include "gui/layout.hpp"
|
||||
// #include "gui/layout.hpp"
|
||||
#include "imgui/imgui.h"
|
||||
#include "scene/scene.hpp"
|
||||
#include "window.hpp"
|
||||
|
||||
#include "hart_module.hpp"
|
||||
#include "hart_directory.hpp"
|
||||
|
||||
#include "preview_renderer/renderer.hpp"
|
||||
#include "preview_renderer/shader.hpp"
|
||||
#include "renderer/dispatcher.hpp"
|
||||
#include "renderer/renderer.hpp"
|
||||
#include "scene/camera.hpp"
|
||||
#include "scene/scene.hpp"
|
||||
#include "scene/material.hpp"
|
||||
#include "scene/mesh.hpp"
|
||||
#include "scene/scene.hpp"
|
||||
|
||||
#include <yolo/yolo.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <chrono>
|
||||
#include <numeric>
|
||||
|
||||
using namespace inferno;
|
||||
namespace inferno {
|
||||
|
||||
Inferno::Inferno()
|
||||
InfernoApp* inferno_create()
|
||||
{
|
||||
// MOTD
|
||||
yolo::info("INFERNO HART v" INFERNO_VERSION);
|
||||
|
||||
InfernoApp* app = new InfernoApp;
|
||||
app->Input = new InfernoInput;
|
||||
app->Scene = scene::scene_create();
|
||||
|
||||
// Create window
|
||||
mWin = &Window::GetInstance();
|
||||
mWin->init("Inferno v" INFERNO_VERSION, 1280, 720);
|
||||
graphics::window_create("Inferno v" INFERNO_VERSION, 1280, 720);
|
||||
|
||||
mRasterRenderer = new RasterizeRenderer();
|
||||
mRayRenderer = new RenderDispatcher();
|
||||
mScene = new Scene();
|
||||
// setup the scene
|
||||
scene::Material* basicMaterial = new scene::Material("basic");
|
||||
graphics::Shader* basicShader = graphics::shader_create();
|
||||
graphics::shader_load(basicShader, "res/shaders/basic.glsl");
|
||||
graphics::shader_link(basicShader);
|
||||
basicMaterial->setGlShader(basicShader);
|
||||
|
||||
scene::Mesh* mesh = new scene::Mesh;
|
||||
// mesh->loadOBJ("res/cornell-box.obj");
|
||||
mesh->loadOBJ("res/sponza.obj");
|
||||
mesh->ready();
|
||||
mesh->setMaterial(basicMaterial);
|
||||
|
||||
scene::SceneObject* object = scene::scene_object_create();
|
||||
scene::scene_object_add_mesh(object, mesh);
|
||||
|
||||
scene::scene_add_object(app->Scene, object);
|
||||
|
||||
app->PreviewRenderer = graphics::preview_create();
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
Inferno::~Inferno()
|
||||
void inferno_cleanup(InfernoApp* app)
|
||||
{
|
||||
|
||||
graphics::window_cleanup();
|
||||
delete app;
|
||||
}
|
||||
|
||||
static void HelpMarker(const char* desc)
|
||||
static void inferno_gui_help_marker(const char* desc)
|
||||
{
|
||||
ImGui::TextDisabled("(?)");
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort))
|
||||
{
|
||||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) {
|
||||
ImGui::BeginTooltip();
|
||||
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f);
|
||||
ImGui::TextUnformatted(desc);
|
||||
@@ -57,15 +75,15 @@ static void HelpMarker(const char* desc)
|
||||
}
|
||||
}
|
||||
|
||||
void Inferno::uiPreset()
|
||||
void inferno_preset_gui(InfernoApp* app)
|
||||
{
|
||||
ImGuiID dockspace_id = ImGui::GetID("main");
|
||||
|
||||
ImGui::DockBuilderRemoveNode(dockspace_id); // Clear out existing layout
|
||||
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace); // Add empty node
|
||||
ImGui::DockBuilderSetNodeSize(dockspace_id, {1000, 1000});
|
||||
ImGui::DockBuilderSetNodeSize(dockspace_id, { 1000, 1000 });
|
||||
|
||||
ImGuiID dock_main_id = dockspace_id; // This variable will track the document node, however we are not using it here as we aren't docking anything into it.
|
||||
ImGuiID dock_main_id = dockspace_id;
|
||||
ImGuiID dock_left = ImGui::DockBuilderSplitNode(dock_main_id, ImGuiDir_Left, 0.5f, NULL, &dock_main_id);
|
||||
ImGui::DockBuilderDockWindow("Preview", dock_left);
|
||||
ImGui::DockBuilderDockWindow("Render", dock_main_id);
|
||||
@@ -74,107 +92,85 @@ void Inferno::uiPreset()
|
||||
yolo::info("LAYOUT SET TO DEFAULT");
|
||||
}
|
||||
|
||||
void Inferno::moveInput()
|
||||
void inferno_move_input(InfernoApp* app)
|
||||
{
|
||||
static GLFWcursor* cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
|
||||
glfwSetCursor(mWin->getGLFWWindow(), cursor);
|
||||
glfwSetCursor(graphics::window_get_glfw_window(), cursor);
|
||||
|
||||
// KBD & MOUSE
|
||||
// pan only get on hold
|
||||
static glm::dvec2 lastMousePos;
|
||||
static int firstClick = 0;
|
||||
if (glfwGetMouseButton(mWin->getGLFWWindow(), GLFW_MOUSE_BUTTON_1) == GLFW_PRESS)
|
||||
{
|
||||
if (glfwGetMouseButton(graphics::window_get_glfw_window(), GLFW_MOUSE_BUTTON_1) == GLFW_PRESS) {
|
||||
firstClick++;
|
||||
if (firstClick == 1)
|
||||
{
|
||||
glfwGetCursorPos(mWin->getGLFWWindow(), &lastMousePos.x, &lastMousePos.y);
|
||||
if (firstClick == 1) {
|
||||
glfwGetCursorPos(graphics::window_get_glfw_window(), &lastMousePos.x, &lastMousePos.y);
|
||||
}
|
||||
glm::dvec2 tempMousePos = { 0.0f, 0.0f };
|
||||
glfwGetCursorPos(mWin->getGLFWWindow(), &tempMousePos.x, &tempMousePos.y);
|
||||
mouseDelta = lastMousePos - tempMousePos;
|
||||
glfwGetCursorPos(graphics::window_get_glfw_window(), &tempMousePos.x, &tempMousePos.y);
|
||||
app->Input->MouseDelta = lastMousePos - tempMousePos;
|
||||
lastMousePos = tempMousePos;
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
firstClick = 0;
|
||||
mouseDelta = { 0.0f, 0.0f };
|
||||
app->Input->MouseDelta = { 0.0f, 0.0f };
|
||||
lastMousePos = { 0.0f, 0.0f };
|
||||
}
|
||||
|
||||
movementDelta = 0b00000000;
|
||||
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_W) == GLFW_PRESS)
|
||||
movementDelta |= 0b10000000;
|
||||
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_A) == GLFW_PRESS)
|
||||
movementDelta |= 0b01000000;
|
||||
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_S) == GLFW_PRESS)
|
||||
movementDelta |= 0b00100000;
|
||||
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_D) == GLFW_PRESS)
|
||||
movementDelta |= 0b00010000;
|
||||
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_SPACE) == GLFW_PRESS)
|
||||
movementDelta |= 0b00001000;
|
||||
if (glfwGetKey(mWin->getGLFWWindow(), GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
||||
movementDelta |= 0b00000100;
|
||||
app->Input->MovementDelta = 0b00000000;
|
||||
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_W) == GLFW_PRESS)
|
||||
app->Input->MovementDelta |= 0b10000000;
|
||||
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_A) == GLFW_PRESS)
|
||||
app->Input->MovementDelta |= 0b01000000;
|
||||
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_S) == GLFW_PRESS)
|
||||
app->Input->MovementDelta |= 0b00100000;
|
||||
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_D) == GLFW_PRESS)
|
||||
app->Input->MovementDelta |= 0b00010000;
|
||||
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_SPACE) == GLFW_PRESS)
|
||||
app->Input->MovementDelta |= 0b00001000;
|
||||
if (glfwGetKey(graphics::window_get_glfw_window(), GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
||||
app->Input->MovementDelta |= 0b00000100;
|
||||
}
|
||||
|
||||
void Inferno::stopMoveInput()
|
||||
void inferno_stop_move_input(InfernoApp* app)
|
||||
{
|
||||
movementDelta = 0x0;
|
||||
mouseDelta = { 0.0f, 0.0f };
|
||||
app->Input->MovementDelta = 0x0;
|
||||
app->Input->MouseDelta = { 0.0f, 0.0f };
|
||||
}
|
||||
|
||||
int Inferno::run()
|
||||
int inferno_run(InfernoApp* app)
|
||||
{
|
||||
Material basicMaterial("basic");
|
||||
Shader basicShader;
|
||||
basicShader.load("res/shaders/basic.glsl")->link();
|
||||
basicMaterial.setGlShader(&basicShader);
|
||||
|
||||
Mesh cornell;
|
||||
cornell.loadOBJ("res/cornell-box.obj");
|
||||
//cornell.loadOBJ("res/sponza.obj");
|
||||
cornell.ready();
|
||||
cornell.setMaterial(&basicMaterial);
|
||||
mScene->addMesh(&cornell);
|
||||
|
||||
// Mesh dragon;
|
||||
// dragon.loadOBJ("res/dragon-cornell-size.obj");
|
||||
// dragon.ready();
|
||||
// dragon.setMaterial(&basicMaterial);
|
||||
// mScene->addMesh(&dragon);
|
||||
|
||||
Camera camera;
|
||||
mScene->setCamera(&camera);
|
||||
|
||||
mRasterRenderer->setScene(mScene);
|
||||
mRayRenderer->getRenderer()->setScene(mScene);
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!mWin->newFrame()) { break; }
|
||||
camera.newFrame();
|
||||
while (true) {
|
||||
if (!graphics::window_new_frame())
|
||||
break;
|
||||
|
||||
// set the main window to the dockspace and then on the first launch set the preset
|
||||
ImGuiID dockspace_id = ImGui::GetID("main");
|
||||
static ImGuiDockNodeFlags dockspace_flags = ImGuiDockNodeFlags_PassthruCentralNode;
|
||||
if (ImGui::DockBuilderGetNode(dockspace_id) == NULL) { this->uiPreset(); }
|
||||
if (ImGui::DockBuilderGetNode(dockspace_id) == NULL) {
|
||||
inferno_preset_gui(app);
|
||||
}
|
||||
ImGui::DockSpace(dockspace_id, ImVec2(0.0f, 0.0f), dockspace_flags);
|
||||
|
||||
if (glm::length(app->Input->MouseDelta) > 0.0f)
|
||||
graphics::camera_mouse_move(app->Scene->Camera, app->Input->MouseDelta);
|
||||
if (app->Input->MovementDelta != 0b00000000)
|
||||
graphics::camera_move(app->Scene->Camera, app->Input->MovementDelta);
|
||||
|
||||
// Menu Bar
|
||||
static bool showPreview = true;
|
||||
static bool showRenderSettings = true;
|
||||
static bool showDemoWindow = false;
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Menu"))
|
||||
{
|
||||
if (ImGui::BeginMenuBar()) {
|
||||
if (ImGui::BeginMenu("Menu")) {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (ImGui::BeginMenu("View"))
|
||||
{
|
||||
if (ImGui::BeginMenu("View")) {
|
||||
ImGui::Checkbox("Show Preview", &showPreview);
|
||||
ImGui::SameLine(); HelpMarker("Show the preview window");
|
||||
ImGui::SameLine();
|
||||
inferno_gui_help_marker("Show the preview window");
|
||||
ImGui::Checkbox("Show Settings", &showRenderSettings);
|
||||
ImGui::SameLine(); HelpMarker("Show the Inferno HART settings window");
|
||||
ImGui::SameLine();
|
||||
inferno_gui_help_marker("Show the Inferno HART settings window");
|
||||
ImGui::Checkbox("Show Demo", &showDemoWindow);
|
||||
|
||||
ImGui::EndMenu();
|
||||
@@ -182,118 +178,73 @@ int Inferno::run()
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
if (showPreview && ImGui::Begin("Preview", nullptr, ImGuiWindowFlags_NoScrollbar))
|
||||
{
|
||||
if (ImGui::IsWindowHovered())
|
||||
{
|
||||
this->moveInput();
|
||||
} else
|
||||
{
|
||||
this->stopMoveInput();
|
||||
if (showPreview && ImGui::Begin("Preview", nullptr, ImGuiWindowFlags_NoScrollbar)) {
|
||||
if (ImGui::IsWindowHovered()) {
|
||||
inferno_move_input(app);
|
||||
} else {
|
||||
inferno_stop_move_input(app);
|
||||
}
|
||||
if (glm::length(mouseDelta) > 0.0f) camera.mouseMoved(mouseDelta);
|
||||
if (movementDelta != 0b00000000) camera.moveCamera(movementDelta);
|
||||
|
||||
camera.setRasterViewport({ImGui::GetWindowSize().x, ImGui::GetWindowSize().y});
|
||||
mRasterRenderer->setTargetSize({ImGui::GetWindowSize().x, ImGui::GetWindowSize().y});
|
||||
mRasterRenderer->prepare();
|
||||
mRasterRenderer->draw();
|
||||
ImGui::Image((ImTextureID)mRasterRenderer->getRenderedTexture(),
|
||||
{ mRasterRenderer->getTargetSize().x, mRasterRenderer->getTargetSize().y },
|
||||
ImVec2(0,1), ImVec2(1,0));
|
||||
graphics::raster_set_viewport(scene::scene_get_camera(app->Scene),
|
||||
{ ImGui::GetWindowSize().x, ImGui::GetWindowSize().y });
|
||||
graphics::preview_draw(app->PreviewRenderer, app->Scene);
|
||||
|
||||
ImTextureID texture = (ImTextureID)graphics::preview_get_rendered_texture(app->PreviewRenderer);
|
||||
ImGui::Image(
|
||||
texture,
|
||||
{ ImGui::GetWindowSize().x, ImGui::GetWindowSize().y },
|
||||
ImVec2(0, 1), ImVec2(1, 0));
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (ImGui::Begin("Render", nullptr, ImGuiWindowFlags_NoScrollbar))
|
||||
{
|
||||
ImGui::Image((ImTextureID)mRayRenderer->getLatestTexture(),
|
||||
{ mRayRenderer->getRenderer()->getTargetSize().x,
|
||||
mRayRenderer->getRenderer()->getTargetSize().y },
|
||||
ImVec2(0,1), ImVec2(1,0));
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (showRenderSettings && ImGui::Begin("Inferno HART"))
|
||||
{
|
||||
// start/stop
|
||||
bool isRenderRunning = mRayRenderer->progressionStatus();
|
||||
if (isRenderRunning)
|
||||
{
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
||||
ImGui::Button("Start Render"); ImGui::SameLine();
|
||||
ImGui::PopItemFlag(); ImGui::PopStyleVar();
|
||||
if (ImGui::Button("Stop Render"))
|
||||
mRayRenderer->stopProgression();
|
||||
} else {
|
||||
if (ImGui::Button("Start Render"))
|
||||
mRayRenderer->startProgression();
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_Disabled, true); ImGui::PushStyleVar(ImGuiStyleVar_Alpha, ImGui::GetStyle().Alpha * 0.5f);
|
||||
ImGui::Button("Stop Render");
|
||||
ImGui::PopItemFlag(); ImGui::PopStyleVar();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("Render"))
|
||||
{
|
||||
// modules
|
||||
HHM* hhm = mRayRenderer->getTopModule();
|
||||
if (ImGui::TreeNode("Accelerator"))
|
||||
{
|
||||
ImGui::Button("Find Accelerator...");
|
||||
ImGui::Text("Select Accelerator:");
|
||||
if (ImGui::BeginListBox("", ImVec2(-FLT_MIN, 3 * ImGui::GetTextLineHeightWithSpacing())))
|
||||
{
|
||||
std::vector<std::string> moduleNames = hhm->getModuleDirectory()->getModules();
|
||||
int active = hhm->getModuleDirectory()->getActiveIndex();
|
||||
for (int n = 0; n < moduleNames.size(); n++)
|
||||
{
|
||||
const bool isSelected = (active == n);
|
||||
if (ImGui::Selectable(moduleNames[n].c_str(), isSelected))
|
||||
hhm->getModuleDirectory()->setActiveIndex(n);
|
||||
if (isSelected)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
ImGui::EndListBox();
|
||||
}
|
||||
auto* activeCredit = hhm->getModuleDirectory()->getActiveCredit();
|
||||
ImGui::Text(activeCredit->ModuleName.c_str());
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("v%i.%i.%i", activeCredit->VersionMajor,
|
||||
activeCredit->VersionMinor,
|
||||
activeCredit->VersionBuild);
|
||||
ImGui::BulletText(activeCredit->ModuleDesc.c_str());
|
||||
ImGui::BulletText("Authored by %s", activeCredit->AuthorName.c_str());
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
if (ImGui::TreeNode("Camera"))
|
||||
{
|
||||
if (showRenderSettings && ImGui::Begin("Inferno HART")) {
|
||||
if (ImGui::TreeNode("Camera")) {
|
||||
ImGui::PushItemWidth(100);
|
||||
ImGui::Text("Camera Position X,Y,Z");
|
||||
|
||||
graphics::Camera* camera = scene::scene_get_camera(app->Scene);
|
||||
|
||||
bool positionUpdated = false;
|
||||
ImGui::DragFloat("X", &camera.Position.x, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); ImGui::SameLine(); if (ImGui::IsItemEdited()) positionUpdated = true;
|
||||
ImGui::DragFloat("Y", &camera.Position.y, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); ImGui::SameLine(); if (ImGui::IsItemEdited()) positionUpdated = true;
|
||||
ImGui::DragFloat("Z", &camera.Position.z, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); if (ImGui::IsItemEdited()) positionUpdated = true;
|
||||
if (positionUpdated) camera.setPosition(camera.Position);
|
||||
ImGui::DragFloat("X", &camera->Position.x, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::IsItemEdited())
|
||||
positionUpdated = true;
|
||||
ImGui::DragFloat("Y", &camera->Position.y, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::IsItemEdited())
|
||||
positionUpdated = true;
|
||||
ImGui::DragFloat("Z", &camera->Position.z, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
|
||||
if (ImGui::IsItemEdited())
|
||||
positionUpdated = true;
|
||||
if (positionUpdated)
|
||||
graphics::camera_set_position(camera, graphics::camera_get_position(camera));
|
||||
|
||||
bool viewUpdated = false;
|
||||
ImGui::Text("Camera Look Yaw, Pitch, Roll");
|
||||
ImGui::DragFloat("Yaw", &camera.Yaw, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); ImGui::SameLine(); if (ImGui::IsItemEdited()) viewUpdated = true;
|
||||
ImGui::DragFloat("Pitch", &camera.Pitch, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); ImGui::SameLine(); if (ImGui::IsItemEdited()) viewUpdated = true;
|
||||
ImGui::DragFloat("Roll", &camera.Roll, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None); if (ImGui::IsItemEdited()) viewUpdated = true;
|
||||
ImGui::DragFloat("Yaw", &camera->Yaw, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::IsItemEdited())
|
||||
viewUpdated = true;
|
||||
ImGui::DragFloat("Pitch", &camera->Pitch, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::IsItemEdited())
|
||||
viewUpdated = true;
|
||||
ImGui::DragFloat("Roll", &camera->Roll, 0.01f, -FLT_MAX, FLT_MAX, "%.2f", ImGuiSliderFlags_None);
|
||||
if (ImGui::IsItemEdited())
|
||||
viewUpdated = true;
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::PushItemWidth(300);
|
||||
|
||||
ImGui::Text("Camera Zoom");
|
||||
ImGui::DragFloat("Zoom", &camera.FOV, -0.1f, 0.01f, 180.0f, "%.2f", ImGuiSliderFlags_None); ImGui::SameLine(); if (ImGui::IsItemEdited()) viewUpdated = true;
|
||||
if (viewUpdated) camera.update();
|
||||
ImGui::DragFloat("Zoom", &camera->FOV, -0.1f, 0.01f, 180.0f, "%.2f", ImGuiSliderFlags_None);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::IsItemEdited())
|
||||
viewUpdated = true;
|
||||
if (viewUpdated)
|
||||
graphics::camera_update(camera);
|
||||
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::TreePop();
|
||||
@@ -301,11 +252,11 @@ int Inferno::run()
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
if (showDemoWindow)
|
||||
{
|
||||
if (showDemoWindow) {
|
||||
ImGui::ShowDemoWindow();
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
GLenum err;
|
||||
while((err = glGetError()) != GL_NO_ERROR) {
|
||||
std::string error;
|
||||
@@ -322,8 +273,10 @@ int Inferno::run()
|
||||
yolo::error("[GL]: {} {}", err, error);
|
||||
}
|
||||
|
||||
mWin->render();
|
||||
graphics::window_render();
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace inferno
|
||||
|
||||
@@ -1,45 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "graphics.hpp"
|
||||
#include "scene/scene.hpp"
|
||||
#include "scene/camera.hpp"
|
||||
// #include "renderer/renderer.hpp"
|
||||
#include "preview_renderer/renderer.hpp"
|
||||
|
||||
#include <singleton.hpp>
|
||||
#include <memory>
|
||||
|
||||
namespace inferno {
|
||||
|
||||
class Window;
|
||||
class HHM;
|
||||
|
||||
class RasterizeRenderer;
|
||||
class RenderDispatcher;
|
||||
class Scene;
|
||||
|
||||
class Inferno : public helpers::Singleton<Inferno>
|
||||
{
|
||||
public:
|
||||
Inferno();
|
||||
~Inferno();
|
||||
|
||||
void uiPreset();
|
||||
|
||||
void moveInput();
|
||||
void stopMoveInput();
|
||||
int run();
|
||||
|
||||
public:
|
||||
glm::vec2 mouseDelta;
|
||||
// 0b00000000
|
||||
// 0bFLBRUDxx
|
||||
uint8_t movementDelta;
|
||||
|
||||
private:
|
||||
// need deffered init as they need an OpenGL context
|
||||
// could and should be fixed with a static window
|
||||
RasterizeRenderer* mRasterRenderer;
|
||||
RenderDispatcher* mRayRenderer;
|
||||
Scene* mScene;
|
||||
|
||||
private:
|
||||
Window* mWin;
|
||||
};
|
||||
|
||||
namespace graphics {
|
||||
struct Camera;
|
||||
}
|
||||
|
||||
namespace scene {
|
||||
struct Scene;
|
||||
}
|
||||
|
||||
typedef struct InfernoInput {
|
||||
glm::vec2 MouseDelta = {0.0f, 0.0f};
|
||||
uint8_t MovementDelta = 0;
|
||||
} InfernoInput;
|
||||
|
||||
typedef struct InfernoApp {
|
||||
InfernoInput* Input;
|
||||
scene::Scene* Scene;
|
||||
graphics::PreviewRenderer* PreviewRenderer;
|
||||
// graphics::RayRenderer* RayRenderer;
|
||||
} InfernoApp;
|
||||
|
||||
InfernoApp* inferno_create();
|
||||
void inferno_cleanup(InfernoApp* app);
|
||||
void inferno_preset_gui(InfernoApp* app);
|
||||
void inferno_move_input(InfernoApp* app);
|
||||
void inferno_stop_move_input(InfernoApp* app);
|
||||
int inferno_run(InfernoApp* app);
|
||||
|
||||
} // namespace inferno
|
||||
|
||||
11
src/main.cpp
11
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);
|
||||
}
|
||||
|
||||
@@ -1,114 +1,140 @@
|
||||
#include "renderer.hpp"
|
||||
|
||||
#include "scene/object.hpp"
|
||||
#include "shader.hpp"
|
||||
|
||||
#include <yolo/yolo.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <scene/camera.hpp>
|
||||
#include <scene/scene.hpp>
|
||||
#include <scene/material.hpp>
|
||||
#include <scene/mesh.hpp>
|
||||
#include <scene/object.hpp>
|
||||
#include <scene/scene.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace inferno;
|
||||
namespace inferno::graphics {
|
||||
|
||||
RasterizeRenderer::RasterizeRenderer()
|
||||
PreviewRenderer* preview_create()
|
||||
{
|
||||
glGenFramebuffers(1, &mRenderTarget);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mRenderTarget);
|
||||
PreviewRenderer* renderer = new PreviewRenderer;
|
||||
|
||||
glGenFramebuffers(1, &renderer->RenderTarget);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, renderer->RenderTarget);
|
||||
|
||||
glGenTextures(1, &mRenderTargetTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderTargetTexture);
|
||||
glGenTextures(1, &renderer->RenderTargetTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,32 +2,29 @@
|
||||
|
||||
#include <graphics.hpp>
|
||||
|
||||
namespace inferno {
|
||||
|
||||
class Scene;
|
||||
|
||||
class RasterizeRenderer
|
||||
{
|
||||
public:
|
||||
RasterizeRenderer();
|
||||
~RasterizeRenderer();
|
||||
|
||||
void setScene(Scene* scene);
|
||||
|
||||
void setTargetSize(glm::ivec2 size);
|
||||
glm::ivec2 getTargetSize();
|
||||
GLuint getRenderedTexture();
|
||||
|
||||
void prepare();
|
||||
void draw();
|
||||
|
||||
private:
|
||||
GLuint mRenderTarget = 0;
|
||||
GLuint mRenderTargetTexture = 0;
|
||||
GLuint mRenderTargetDepthTexture = 0;
|
||||
glm::ivec2 mRenderTargetSize = {1920, 1080};
|
||||
|
||||
Scene* mCurrentScene;
|
||||
};
|
||||
#include <memory>
|
||||
|
||||
namespace inferno::scene {
|
||||
struct Scene;
|
||||
}
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
struct Viewport;
|
||||
|
||||
typedef struct PreviewRenderer {
|
||||
glm::ivec2 Viewport;
|
||||
|
||||
GLuint RenderTarget = 0;
|
||||
GLuint RenderTargetTexture = 0;
|
||||
GLuint RenderTargetDepthTexture = 0;
|
||||
} PreviewRenderer;
|
||||
|
||||
PreviewRenderer* preview_create();
|
||||
void preview_cleanup(PreviewRenderer* renderer);
|
||||
|
||||
GLuint preview_get_rendered_texture(PreviewRenderer* renderer);
|
||||
|
||||
void preview_draw(PreviewRenderer* renderer, scene::Scene* scene);
|
||||
|
||||
} // namespace inferno::graphics
|
||||
|
||||
@@ -1,158 +1,188 @@
|
||||
#include "shader.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
static std::unordered_map<GLuint, int> shader2Index = {
|
||||
{ GL_VERTEX_SHADER, 0 },
|
||||
{ GL_GEOMETRY_SHADER, 1 },
|
||||
{ GL_FRAGMENT_SHADER, 2 }
|
||||
};
|
||||
|
||||
inline std::string trim(std::string& str)
|
||||
{
|
||||
str.erase(str.find_last_not_of(' ')+1); //suffixing spaces
|
||||
str.erase(0, str.find_first_not_of(' ')); //prefixing spaces
|
||||
str.erase(str.find_last_not_of(' ') + 1); // suffixing spaces
|
||||
str.erase(0, str.find_first_not_of(' ')); // prefixing spaces
|
||||
return str;
|
||||
}
|
||||
|
||||
static std::unordered_map<GLuint, int> Shader2Index = {
|
||||
{GL_VERTEX_SHADER, 0},
|
||||
{GL_GEOMETRY_SHADER, 1},
|
||||
{GL_FRAGMENT_SHADER, 2}
|
||||
};
|
||||
|
||||
using namespace inferno;
|
||||
|
||||
std::string textFromFile(const std::filesystem::path& path) {
|
||||
std::ifstream input(path);
|
||||
return std::string((std::istreambuf_iterator<char>(input)),
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
}
|
||||
|
||||
Shader::Shader()
|
||||
: mShaders({ GL_NONE, GL_NONE, GL_NONE})
|
||||
, mProgram(0) {
|
||||
}
|
||||
|
||||
|
||||
Shader::~Shader() {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (mShaders[i] == GL_NONE) continue;
|
||||
glDeleteShader(mShaders[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Shader* Shader::load(std::filesystem::path path) {
|
||||
|
||||
assert(std::filesystem::exists(path));
|
||||
|
||||
std::string loadedShaderSource = textFromFile(path);
|
||||
|
||||
for (int i = 0; i < loadedShaderSource.length(); i++) {
|
||||
const char& c = loadedShaderSource[i];
|
||||
if (c == '#') {
|
||||
mPreprocessorDefinition def = { .start = i };
|
||||
int j;
|
||||
for (j = ++i; loadedShaderSource[j] != ' '; j++) {
|
||||
def.key += loadedShaderSource[j];
|
||||
}
|
||||
for (j++; loadedShaderSource[j] != '\n'; j++) {
|
||||
def.def += loadedShaderSource[j];
|
||||
}
|
||||
def.end = j; i = j; // advance i
|
||||
def.def = trim(def.def);
|
||||
def.key = trim(def.key);
|
||||
mDefinitions.push_back(def);
|
||||
}
|
||||
}
|
||||
|
||||
// now we have all of the key/value definitions
|
||||
// we can extract the relavent ones, for example
|
||||
// "type"
|
||||
auto types = mGetKeys("type");
|
||||
int i = 0;
|
||||
for (const mPreprocessorDefinition* type : types) {
|
||||
GLuint glType = GL_NONE;
|
||||
if (type->def == "vertex") glType = GL_VERTEX_SHADER;
|
||||
if (type->def == "geometry") glType = GL_GEOMETRY_SHADER;
|
||||
if (type->def == "fragment") glType = GL_FRAGMENT_SHADER;
|
||||
|
||||
assert(glType != GL_NONE);
|
||||
|
||||
mShaders[Shader2Index[glType]] = glCreateShader(glType);
|
||||
|
||||
const char* source = loadedShaderSource.c_str() + type->end;
|
||||
int end = types.size() - 1 == i ? types.size(): types[i + 1]->start;
|
||||
int length = end - type->end;
|
||||
|
||||
glShaderSource(mShaders[Shader2Index[glType]], 1, &source, &length);
|
||||
i++;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Shader* Shader::link() {
|
||||
|
||||
mProgram = glCreateProgram();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (mShaders[i] == GL_NONE) continue;
|
||||
|
||||
glCompileShader(mShaders[i]);
|
||||
if (!mCheckShader(mShaders[i])) continue;
|
||||
|
||||
glAttachShader(mProgram, mShaders[i]);
|
||||
}
|
||||
|
||||
glLinkProgram(mProgram);
|
||||
return this;
|
||||
}
|
||||
|
||||
Shader* Shader::use() {
|
||||
glUseProgram(mProgram);
|
||||
return this;
|
||||
}
|
||||
|
||||
Shader* Shader::unUse() {
|
||||
glUseProgram(0);
|
||||
return this;
|
||||
}
|
||||
|
||||
GLuint Shader::getProgram()
|
||||
std::string textFromFile(const std::filesystem::path& path)
|
||||
{
|
||||
return mProgram;
|
||||
std::ifstream input(path);
|
||||
return std::string((std::istreambuf_iterator<char>(input)),
|
||||
std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
|
||||
void Shader::addAttribute(const std::string& attribute) {
|
||||
mAttributes[attribute] = glGetAttribLocation(mProgram, attribute.c_str());
|
||||
std::vector<const ShaderPreprocessorDefinition*> getKeys(Shader* shader, std::string key)
|
||||
{
|
||||
std::vector<const ShaderPreprocessorDefinition*> 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<GLchar> errorLog(maxLength);
|
||||
glGetShaderInfoLog(uid, maxLength, &maxLength, &errorLog[0]);
|
||||
|
||||
for (int i = 0; i < errorLog.size(); i++) {
|
||||
std::cout << errorLog[i];
|
||||
}
|
||||
|
||||
glDeleteShader(uid);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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<GLchar> 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<const ShaderPreprocessorDefinition*> types = getKeys(shader, "type");
|
||||
int i = 0;
|
||||
for (const ShaderPreprocessorDefinition* type : types) {
|
||||
GLuint glType = GL_NONE;
|
||||
if (type->def == "vertex")
|
||||
glType = GL_VERTEX_SHADER;
|
||||
if (type->def == "geometry")
|
||||
glType = GL_GEOMETRY_SHADER;
|
||||
if (type->def == "fragment")
|
||||
glType = GL_FRAGMENT_SHADER;
|
||||
|
||||
assert(glType != GL_NONE);
|
||||
|
||||
shader->Shaders[shader2Index[glType]] = glCreateShader(glType);
|
||||
|
||||
const char* source = loadedShaderSource.c_str() + type->end;
|
||||
int end = types.size() - 1 == i ? types.size() : types[i + 1]->start;
|
||||
int length = end - type->end;
|
||||
|
||||
glShaderSource(shader->Shaders[shader2Index[glType]], 1, &source, &length);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void shader_link(Shader* shader)
|
||||
{
|
||||
shader->Program = glCreateProgram();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (shader->Shaders[i] == GL_NONE)
|
||||
continue;
|
||||
|
||||
glCompileShader(shader->Shaders[i]);
|
||||
if (!checkShader(shader->Shaders[i]))
|
||||
continue;
|
||||
|
||||
glAttachShader(shader->Program, shader->Shaders[i]);
|
||||
}
|
||||
|
||||
glLinkProgram(shader->Program);
|
||||
}
|
||||
|
||||
GLuint shader_get_program(Shader* shader)
|
||||
{
|
||||
return shader->Program;
|
||||
}
|
||||
|
||||
void shader_add_attribute(Shader* shader, const std::string& attribute)
|
||||
{
|
||||
shader->Attributes[attribute] = glGetAttribLocation(shader->Program, attribute.c_str());
|
||||
}
|
||||
|
||||
void shader_add_uniform(Shader* shader, const std::string& uniform)
|
||||
{
|
||||
shader->Uniforms[uniform] = glGetUniformLocation(shader->Program, uniform.c_str());
|
||||
}
|
||||
|
||||
GLuint shader_get_attribute(Shader* shader, const std::string& attribute)
|
||||
{
|
||||
return shader->Attributes[attribute];
|
||||
}
|
||||
|
||||
GLuint shader_get_uniform(Shader* shader, const std::string& uniform)
|
||||
{
|
||||
return shader->Uniforms[uniform];
|
||||
}
|
||||
|
||||
void shader_use(Shader* shader)
|
||||
{
|
||||
glUseProgram(shader->Program);
|
||||
}
|
||||
|
||||
void shader_unuse(Shader* shader)
|
||||
{
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
std::vector<const Shader::mPreprocessorDefinition*> Shader::mGetKeys(std::string key) {
|
||||
std::vector<const Shader::mPreprocessorDefinition*> ret;
|
||||
for (const auto& p : mDefinitions) if (p.key == key) ret.push_back(&p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2,58 +2,43 @@
|
||||
|
||||
#include "../graphics.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace inferno {
|
||||
namespace inferno::graphics {
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
Shader();
|
||||
~Shader();
|
||||
typedef struct ShaderPreprocessorDefinition {
|
||||
int start, end;
|
||||
std::string key;
|
||||
std::string def;
|
||||
} shaderpreprocessordefinition;
|
||||
|
||||
Shader* preprocessorDefine(std::string statement);
|
||||
typedef struct Shader {
|
||||
GLuint Shaders[3];
|
||||
GLuint Program;
|
||||
std::unordered_map<std::string, GLuint> Attributes;
|
||||
std::unordered_map<std::string, GLuint> Uniforms;
|
||||
std::vector<ShaderPreprocessorDefinition> PreprocessorDefinitions;
|
||||
} Shader;
|
||||
|
||||
Shader* load(std::filesystem::path path);
|
||||
Shader* link();
|
||||
Shader* shader_create();
|
||||
void shader_cleanup(Shader* shader);
|
||||
|
||||
Shader* use();
|
||||
Shader* unUse();
|
||||
void shader_load(Shader* shader, std::filesystem::path path);
|
||||
void shader_link(Shader* shader);
|
||||
|
||||
GLuint getProgram();
|
||||
GLuint shader_get_program(Shader* shader);
|
||||
|
||||
void addAttribute(const std::string& attribute);
|
||||
void addUniform(const std::string& uniform);
|
||||
GLuint operator[](const std::string& attribute) {
|
||||
return mAttributes[attribute];
|
||||
}
|
||||
GLuint operator()(const std::string& uniform) {
|
||||
return mUniformLocations[uniform];
|
||||
}
|
||||
// TODO: Implement shader_reload
|
||||
void shader_add_attribute(Shader* shader, const std::string& attribute);
|
||||
void shader_add_uniform(Shader* shader, const std::string& uniform);
|
||||
GLuint shader_get_attribute(Shader* shader, const std::string& attribute);
|
||||
GLuint shader_get_uniform(Shader* shader, const std::string& uniform);
|
||||
|
||||
private:
|
||||
GLuint mShaders[3];
|
||||
GLuint mProgram;
|
||||
|
||||
std::unordered_map<std::string, GLuint> mAttributes;
|
||||
std::unordered_map<std::string, GLuint> mUniformLocations;
|
||||
bool mCheckShader(GLuint uid);
|
||||
|
||||
private:
|
||||
// preprocessor definitions can be defined by their
|
||||
// start/end index, this is so that text can either be inserted
|
||||
// in their place or for the "type" definition, the program
|
||||
// can count until the next "type" definition per shader
|
||||
struct mPreprocessorDefinition {
|
||||
int start, end;
|
||||
std::string key;
|
||||
std::string def;
|
||||
};
|
||||
std::vector<mPreprocessorDefinition> mDefinitions;
|
||||
std::vector<const Shader::mPreprocessorDefinition*> mGetKeys(std::string key);
|
||||
};
|
||||
void shader_use(Shader* shader);
|
||||
void shader_unuse(Shader* shader);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
#include "dispatcher.hpp"
|
||||
|
||||
#include "hart_module.hpp"
|
||||
#include "renderer.hpp"
|
||||
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
|
||||
using namespace inferno;
|
||||
|
||||
RenderDispatcher::RenderDispatcher()
|
||||
: mRenderWorker{}
|
||||
{
|
||||
mHHM = new HHM();
|
||||
mRenderer = new RayRenderer(mHHM);
|
||||
mHHM->Renderer = mRenderer;
|
||||
}
|
||||
|
||||
RenderDispatcher::~RenderDispatcher()
|
||||
{
|
||||
mDoWork = false;
|
||||
mJoin = true;
|
||||
mRenderWorker.join();
|
||||
}
|
||||
|
||||
RayRenderer* RenderDispatcher::getRenderer()
|
||||
{
|
||||
return mRenderer;
|
||||
}
|
||||
|
||||
HHM* RenderDispatcher::getTopModule()
|
||||
{
|
||||
return mHHM;
|
||||
}
|
||||
|
||||
void renderWorker(RayRenderer* renderer, std::atomic<bool>* doWork, std::atomic<bool>* join)
|
||||
{
|
||||
while (!*join)
|
||||
{
|
||||
if (!*doWork) {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
continue; // stall
|
||||
}
|
||||
renderer->prepare();
|
||||
renderer->draw();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDispatcher::startProgression()
|
||||
{
|
||||
if (!mRenderWorker.joinable())
|
||||
{
|
||||
mRenderWorker = std::thread{ &renderWorker, this->mRenderer, &mDoWork, &mJoin };
|
||||
}
|
||||
mDoWork = true;
|
||||
}
|
||||
|
||||
void RenderDispatcher::stopProgression()
|
||||
{
|
||||
mDoWork = false;
|
||||
}
|
||||
|
||||
bool RenderDispatcher::progressionStatus()
|
||||
{
|
||||
return mDoWork;
|
||||
}
|
||||
|
||||
GLuint RenderDispatcher::getLatestTexture()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRenderer->_RenderData);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderer->mRenderTargetTexture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mRenderer->mRenderTargetSize.x, mRenderer->mRenderTargetSize.y, 0, GL_RGBA, GL_FLOAT, mRenderer->mTarget);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
return mRenderer->mRenderTargetTexture;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <graphics.hpp>
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
|
||||
namespace inferno {
|
||||
|
||||
// Thread dispatcher keeps track of the thread that calls the
|
||||
// copy function because OpenGL is a nightmare
|
||||
|
||||
class HHM;
|
||||
class Scene;
|
||||
class RayRenderer;
|
||||
|
||||
class RenderDispatcher
|
||||
{
|
||||
public:
|
||||
RenderDispatcher();
|
||||
~RenderDispatcher();
|
||||
|
||||
RayRenderer* getRenderer();
|
||||
HHM* getTopModule();
|
||||
|
||||
void startProgression();
|
||||
void stopProgression();
|
||||
bool progressionStatus();
|
||||
GLuint getLatestTexture();
|
||||
|
||||
private:
|
||||
HHM* mHHM;
|
||||
RayRenderer* mRenderer;
|
||||
|
||||
private:
|
||||
std::thread mRenderWorker;
|
||||
std::atomic<bool> mDoWork = false;
|
||||
std::atomic<bool> mJoin = false;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,70 +1,70 @@
|
||||
#include "ray_source.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <maths.hpp>
|
||||
|
||||
#include <scene/camera.hpp>
|
||||
|
||||
#include <tracing/ray.hpp>
|
||||
|
||||
using namespace inferno;
|
||||
|
||||
RaySource::RaySource(Camera* camera)
|
||||
: mReferenceCamera(camera)
|
||||
{
|
||||
this->generate();
|
||||
}
|
||||
|
||||
RaySource::~RaySource()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void RaySource::generate()
|
||||
{
|
||||
// const float aspect = mReferenceCamera->getRayViewport().x / mReferenceCamera->getRayViewport().y;
|
||||
// float scale = tan(mReferenceCamera->FOV / 2.0f * helpers::PI / 180.0f);
|
||||
}
|
||||
|
||||
ReferencedRayField RaySource::getInitialRays(bool MSAA)
|
||||
{
|
||||
if (mReferenceCamera->didUpdate())
|
||||
{
|
||||
this->generate();
|
||||
}
|
||||
|
||||
RayField field;
|
||||
field.reserve(mReferenceCamera->getRayViewport().x * mReferenceCamera->getRayViewport().y);
|
||||
|
||||
const float aspect = mReferenceCamera->getRayViewport().x / mReferenceCamera->getRayViewport().y;
|
||||
float scale = tan(mReferenceCamera->FOV / 2.0f * helpers::PI / 180.0f);
|
||||
|
||||
glm::mat4 cameraToWorld = mReferenceCamera->getCameraLook();
|
||||
glm::vec3 origin = mReferenceCamera->Position;
|
||||
|
||||
std::unordered_map<uint32_t, glm::ivec2> reference;
|
||||
|
||||
uint32_t i = 0;
|
||||
for (int x = 0; x < mReferenceCamera->getRayViewport().x; x++)
|
||||
for (int y = 0; y < mReferenceCamera->getRayViewport().y; y++)
|
||||
{
|
||||
float Px = (2.0f * ((x + 0.5f) / mReferenceCamera->getRayViewport().x) - 1.0f) * scale * aspect;
|
||||
float Py = (2.0f * ((y + 0.5f) / mReferenceCamera->getRayViewport().y) - 1.0f) * scale;
|
||||
|
||||
Ray* ray = new Ray{};
|
||||
|
||||
glm::vec4 dir4 = glm::vec4(Px, Py, -1.0f, 1.0f) * cameraToWorld;
|
||||
glm::vec3 dir3 = glm::vec3(dir4) / dir4.w;
|
||||
ray->Direction = glm::normalize(dir3);
|
||||
|
||||
ray->Origin = origin;
|
||||
ray->Reference = i;
|
||||
reference[i] = {x, y};
|
||||
|
||||
field.push_back(ray);
|
||||
i++;
|
||||
}
|
||||
|
||||
return { field, reference };
|
||||
}
|
||||
// #include "ray_source.hpp"
|
||||
//
|
||||
// #include <iostream>
|
||||
//
|
||||
// #include <maths.hpp>
|
||||
//
|
||||
// #include <scene/camera.hpp>
|
||||
//
|
||||
// #include <tracing/ray.hpp>
|
||||
//
|
||||
// using namespace inferno;
|
||||
//
|
||||
// RaySource::RaySource(Camera* camera)
|
||||
// : mReferenceCamera(camera)
|
||||
// {
|
||||
// this->generate();
|
||||
// }
|
||||
//
|
||||
// RaySource::~RaySource()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// void RaySource::generate()
|
||||
// {
|
||||
// // const float aspect = mReferenceCamera->getRayViewport().x / mReferenceCamera->getRayViewport().y;
|
||||
// // float scale = tan(mReferenceCamera->FOV / 2.0f * helpers::PI / 180.0f);
|
||||
// }
|
||||
//
|
||||
// ReferencedRayField RaySource::getInitialRays(bool MSAA)
|
||||
// {
|
||||
// if (mReferenceCamera->didUpdate())
|
||||
// {
|
||||
// this->generate();
|
||||
// }
|
||||
//
|
||||
// RayField field;
|
||||
// field.reserve(mReferenceCamera->getRayViewport().x * mReferenceCamera->getRayViewport().y);
|
||||
//
|
||||
// const float aspect = mReferenceCamera->getRayViewport().x / mReferenceCamera->getRayViewport().y;
|
||||
// float scale = tan(mReferenceCamera->FOV / 2.0f * helpers::PI / 180.0f);
|
||||
//
|
||||
// glm::mat4 cameraToWorld = mReferenceCamera->getCameraLook();
|
||||
// glm::vec3 origin = mReferenceCamera->Position;
|
||||
//
|
||||
// std::unordered_map<uint32_t, glm::ivec2> reference;
|
||||
//
|
||||
// uint32_t i = 0;
|
||||
// for (int x = 0; x < mReferenceCamera->getRayViewport().x; x++)
|
||||
// for (int y = 0; y < mReferenceCamera->getRayViewport().y; y++)
|
||||
// {
|
||||
// float Px = (2.0f * ((x + 0.5f) / mReferenceCamera->getRayViewport().x) - 1.0f) * scale * aspect;
|
||||
// float Py = (2.0f * ((y + 0.5f) / mReferenceCamera->getRayViewport().y) - 1.0f) * scale;
|
||||
//
|
||||
// Ray* ray = new Ray{};
|
||||
//
|
||||
// glm::vec4 dir4 = glm::vec4(Px, Py, -1.0f, 1.0f) * cameraToWorld;
|
||||
// glm::vec3 dir3 = glm::vec3(dir4) / dir4.w;
|
||||
// ray->Direction = glm::normalize(dir3);
|
||||
//
|
||||
// ray->Origin = origin;
|
||||
// ray->Reference = i;
|
||||
// reference[i] = {x, y};
|
||||
//
|
||||
// field.push_back(ray);
|
||||
// i++;
|
||||
// }
|
||||
//
|
||||
// return { field, reference };
|
||||
// }
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <graphics.hpp>
|
||||
|
||||
#include <tracing/ray.hpp>
|
||||
|
||||
namespace inferno {
|
||||
|
||||
class Camera;
|
||||
|
||||
struct ReferencedRayField
|
||||
{
|
||||
RayField Field;
|
||||
std::unordered_map<uint32_t, glm::ivec2> Reference;
|
||||
};
|
||||
|
||||
class RaySource
|
||||
{
|
||||
public:
|
||||
RaySource(Camera* camera);
|
||||
~RaySource();
|
||||
|
||||
void generate();
|
||||
ReferencedRayField getInitialRays(bool MSAA);
|
||||
|
||||
private:
|
||||
Camera* mReferenceCamera;
|
||||
};
|
||||
|
||||
}
|
||||
// #pragma once
|
||||
//
|
||||
// #include <vector>
|
||||
// #include <unordered_map>
|
||||
//
|
||||
// #include <graphics.hpp>
|
||||
//
|
||||
// #include <tracing/ray.hpp>
|
||||
//
|
||||
// namespace inferno {
|
||||
//
|
||||
// class Camera;
|
||||
//
|
||||
// struct ReferencedRayField {
|
||||
// RayField Field;
|
||||
// std::unordered_map<uint32_t, glm::ivec2> Reference;
|
||||
// };
|
||||
//
|
||||
//
|
||||
// class RaySource
|
||||
// {
|
||||
// public:
|
||||
// RaySource(Camera* camera);
|
||||
// ~RaySource();
|
||||
//
|
||||
// void generate();
|
||||
// ReferencedRayField getInitialRays(bool MSAA);
|
||||
//
|
||||
// private:
|
||||
// Camera* mReferenceCamera;
|
||||
// };
|
||||
//
|
||||
// }
|
||||
|
||||
@@ -1,132 +1,143 @@
|
||||
#include "renderer.hpp"
|
||||
|
||||
#include <graphics.hpp>
|
||||
|
||||
#include <scene/camera.hpp>
|
||||
#include <scene/scene.hpp>
|
||||
#include <scene/mesh.hpp>
|
||||
#include <tracing/ray.hpp>
|
||||
#include <tracing/hit.hpp>
|
||||
|
||||
#include "hart_module.hpp"
|
||||
#include "ray_source.hpp"
|
||||
|
||||
#include <yolo/yolo.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using namespace inferno;
|
||||
|
||||
RayRenderer::RayRenderer(HHM* accelIface)
|
||||
: mIface(accelIface)
|
||||
{
|
||||
mTarget = new glm::fvec4[mRenderTargetSize.x * mRenderTargetSize.y];
|
||||
|
||||
glGenTextures(1, &mRenderTargetTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderTargetTexture);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mRenderTargetSize.x, mRenderTargetSize.y, 0, GL_RGBA, GL_FLOAT, mTarget);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
RayRenderer::~RayRenderer()
|
||||
{
|
||||
delete[] mTarget;
|
||||
}
|
||||
|
||||
void RayRenderer::setScene(Scene* scene)
|
||||
{
|
||||
mCurrentScene = scene;
|
||||
if (mRaySource != nullptr)
|
||||
{
|
||||
delete mRaySource;
|
||||
}
|
||||
mRaySource = new RaySource(scene->getCamera());
|
||||
// the scene will be sent to the module on prepare
|
||||
// as it did update during initialisation
|
||||
|
||||
// mIface->newScene(scene);
|
||||
}
|
||||
|
||||
void RayRenderer::setTargetSize(glm::ivec2 size)
|
||||
{
|
||||
mRenderTargetSize = size;
|
||||
}
|
||||
|
||||
glm::ivec2 RayRenderer::getTargetSize()
|
||||
{
|
||||
return mRenderTargetSize;
|
||||
}
|
||||
|
||||
GLuint RayRenderer::getRenderedTexture()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->_RenderData);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderTargetTexture);
|
||||
return mRenderTargetTexture;
|
||||
}
|
||||
|
||||
glm::fvec4* RayRenderer::getRenderData()
|
||||
{
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
void RayRenderer::prepare()
|
||||
{
|
||||
assert(mCurrentScene != nullptr);
|
||||
if (mCurrentScene->didUpdate())
|
||||
{
|
||||
yolo::debug("New Scene!");
|
||||
mIface->newScene(mCurrentScene);
|
||||
}
|
||||
}
|
||||
|
||||
void RayRenderer::draw()
|
||||
{
|
||||
mCurrentScene->newFrame();
|
||||
// TODO: Rays should definately be bump allocated if possible, this is KBs of
|
||||
// ray data and nothing else being reallocated every frame for no reason
|
||||
ReferencedRayField startRays = mRaySource->getInitialRays(true);
|
||||
|
||||
for (int x = 0; x < mRenderTargetSize.x; x++)
|
||||
for (int y = 0; y < mRenderTargetSize.y; y++)
|
||||
{
|
||||
mTarget[y * mRenderTargetSize.x + x] = { 0.1f, 0.1f, 0.1f, 1.0f };
|
||||
}
|
||||
mCurrentRefTable = &startRays.Reference;
|
||||
|
||||
// before we start we now want to check that it hasn't been force-stopped
|
||||
mIface->startTrace(startRays.Field);
|
||||
|
||||
yolo::info("Sample complete");
|
||||
|
||||
for (auto* ray : startRays.Field)
|
||||
{
|
||||
delete ray;
|
||||
}
|
||||
}
|
||||
|
||||
void RayRenderer::computeHit(HitInfo* info)
|
||||
{
|
||||
static float mind = 100000.0f;
|
||||
static float maxd = 0.0f;
|
||||
// TODO: Make sure signal is started
|
||||
if (!(*mCurrentRefTable).count(info->Caller->Reference))
|
||||
{
|
||||
yolo::warn("Why is the ray not in the map?!");
|
||||
return;
|
||||
}
|
||||
glm::ivec2 pos = (*mCurrentRefTable)[info->Caller->Reference];
|
||||
float d = info->Distance;
|
||||
if (d < mind) mind = d;
|
||||
if (d > maxd) maxd = d;
|
||||
float n = (d - mind) / (maxd - mind);
|
||||
mTarget[pos.y * mRenderTargetSize.x + pos.x] = { n, n, n, 1.0f};
|
||||
}
|
||||
// #include "renderer.hpp"
|
||||
//
|
||||
// #include <graphics.hpp>
|
||||
//
|
||||
// #include <scene/camera.hpp>
|
||||
// #include <scene/scene.hpp>
|
||||
// #include <scene/mesh.hpp>
|
||||
// #include <tracing/ray.hpp>
|
||||
// #include <tracing/hit.hpp>
|
||||
//
|
||||
// #include "ray_source.hpp"
|
||||
//
|
||||
// #include <yolo/yolo.hpp>
|
||||
//
|
||||
// #include <iostream>
|
||||
//
|
||||
// namespace inferno::graphics {
|
||||
//
|
||||
// RayRenderer* rayr_create(glm::ivec2 viewport, HHM* accelIface)
|
||||
// {
|
||||
// RayRenderer* renderer = new RayRenderer;
|
||||
// renderer->RenderTargetSize = viewport;
|
||||
// renderer->RenderData = new glm::fvec4[renderer->RenderTargetSize.x * renderer->RenderTargetSize.y];
|
||||
//
|
||||
// glGenTextures(1, &renderer->RenderTargetTexture);
|
||||
// glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
|
||||
//
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
//
|
||||
// glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, renderer->RenderTargetSize.x, renderer->RenderTargetSize.y, 0, GL_RGBA, GL_FLOAT, renderer->RenderData);
|
||||
//
|
||||
// glBindTexture(GL_TEXTURE_2D, 0);
|
||||
//
|
||||
// return renderer;
|
||||
// }
|
||||
//
|
||||
// void rayr_cleanup(RayRenderer* renderer)
|
||||
// {
|
||||
// delete[] renderer->RenderData;
|
||||
// }
|
||||
//
|
||||
// void rayr_set_scene(RayRenderer* renderer, std::shared_ptr<scene::Scene> scene)
|
||||
// {
|
||||
// renderer->CurrentScene = scene;
|
||||
// if (renderer->RaySource != nullptr)
|
||||
// {
|
||||
// delete renderer->RaySource;
|
||||
// }
|
||||
// // renderer->RaySource = new RaySource(scene->getCamera());
|
||||
// // the scene will be sent to the module on prepare
|
||||
// // as it did update during initialisation
|
||||
//
|
||||
// // mIface->newScene(scene);
|
||||
// }
|
||||
//
|
||||
// void rayr_set_viewport(RayRenderer* &renderer, glm::ivec2 size)
|
||||
// {
|
||||
// renderer->RenderTargetSize = size;
|
||||
// }
|
||||
//
|
||||
// glm::ivec2 rayr_get_viewport(RayRenderer* &renderer)
|
||||
// {
|
||||
// return renderer->RenderTargetSize;
|
||||
// }
|
||||
//
|
||||
// GLuint rayr_get_rendered_texture(RayRenderer* &renderer)
|
||||
// {
|
||||
// std::lock_guard<std::mutex> lock(renderer->RenderDataMutex);
|
||||
// glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
// glBindTexture(GL_TEXTURE_2D, renderer->RenderTargetTexture);
|
||||
// return renderer->RenderTargetTexture;
|
||||
// }
|
||||
//
|
||||
// glm::fvec4* rayr_get_render_data(RayRenderer* &renderer)
|
||||
// {
|
||||
// std::lock_guard<std::mutex> lock(renderer->RenderDataMutex);
|
||||
// return renderer->RenderData;
|
||||
// }
|
||||
//
|
||||
// void rayr_prepare(RayRenderer* &renderer)
|
||||
// {
|
||||
// assert(renderer->CurrentScene != nullptr);
|
||||
// // here, scene_did_update takes a unique_ptr, but we have a shared_ptr
|
||||
// // so we need to call unique() to get the unique_ptr but that will error
|
||||
// // with non-const ltype so we need to const_cast it
|
||||
// if (scene::scene_did_update(renderer->CurrentScene))
|
||||
// {
|
||||
// yolo::debug("New Scene!");
|
||||
// // renderer->AccelerationInterface->newScene(renderer->CurrentScene);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// void rayr_draw(RayRenderer* &renderer)
|
||||
// {
|
||||
// scene::scene_frame_tick(renderer->CurrentScene);
|
||||
// // TODO: Rays should definately be bump allocated if possible, this is KBs of
|
||||
// // ray data and nothing else being reallocated every frame for no reason
|
||||
// ReferencedRayField startRays = mRaySource->getInitialRays(true);
|
||||
//
|
||||
// for (int x = 0; x < mRenderTargetSize.x; x++)
|
||||
// for (int y = 0; y < mRenderTargetSize.y; y++)
|
||||
// {
|
||||
// mTarget[y * mRenderTargetSize.x + x] = { 0.1f, 0.1f, 0.1f, 1.0f };
|
||||
// }
|
||||
// mCurrentRefTable = &startRays.Reference;
|
||||
//
|
||||
// // before we start we now want to check that it hasn't been force-stopped
|
||||
// mIface->startTrace(startRays.Field);
|
||||
//
|
||||
// yolo::info("Sample complete");
|
||||
//
|
||||
// for (auto* ray : startRays.Field)
|
||||
// {
|
||||
// delete ray;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// void RayRenderer::computeHit(HitInfo* info)
|
||||
// {
|
||||
// static float mind = 100000.0f;
|
||||
// static float maxd = 0.0f;
|
||||
// // TODO: Make sure signal is started
|
||||
// if (!(*mCurrentRefTable).count(info->Caller->Reference))
|
||||
// {
|
||||
// yolo::warn("Why is the ray not in the map?!");
|
||||
// return;
|
||||
// }
|
||||
// glm::ivec2 pos = (*mCurrentRefTable)[info->Caller->Reference];
|
||||
// float d = info->Distance;
|
||||
// if (d < mind) mind = d;
|
||||
// if (d > maxd) maxd = d;
|
||||
// float n = (d - mind) / (maxd - mind);
|
||||
// mTarget[pos.y * mRenderTargetSize.x + pos.x] = { n, n, n, 1.0f};
|
||||
// }
|
||||
// void mHaultWait();
|
||||
// std::unordered_map<uint32_t, glm::ivec2>* mCurrentRefTable;
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
@@ -2,58 +2,44 @@
|
||||
|
||||
#include <graphics.hpp>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
#include <condition_variable>
|
||||
|
||||
namespace inferno {
|
||||
namespace inferno::scene {
|
||||
struct Scene;
|
||||
}
|
||||
|
||||
namespace inferno::graphics {
|
||||
|
||||
class HHM;
|
||||
|
||||
class Scene;
|
||||
class HitInfo;
|
||||
class RaySource;
|
||||
class RenderDispatcher;
|
||||
|
||||
class RayRenderer
|
||||
{
|
||||
public:
|
||||
RayRenderer(HHM* accelIface);
|
||||
~RayRenderer();
|
||||
typedef struct RayRenderer {
|
||||
glm::ivec2* Viewport;
|
||||
|
||||
void setScene(Scene* scene);
|
||||
// TODO: Can this be direct 2 GPU?
|
||||
glm::fvec4* RenderData = nullptr;
|
||||
GLuint RenderTargetTexture = 0;
|
||||
|
||||
void setTargetSize(glm::ivec2 size);
|
||||
glm::ivec2 getTargetSize();
|
||||
GLuint getRenderedTexture();
|
||||
glm::fvec4* getRenderData();
|
||||
// Internal stuffs
|
||||
RaySource* RaySource = nullptr;
|
||||
} RayRenderer;
|
||||
|
||||
void prepare();
|
||||
void draw();
|
||||
RayRenderer* rayr_create(glm::ivec2 viewport, HHM* accelIface);
|
||||
void rayr_cleanup(RayRenderer* renderer);
|
||||
|
||||
public:
|
||||
void computeHit(HitInfo* info);
|
||||
void rayr_set_viewport(RayRenderer* renderer, glm::ivec2 size);
|
||||
|
||||
private:
|
||||
void mHaultWait();
|
||||
GLuint rayr_get_rendered_texture(RayRenderer* renderer);
|
||||
glm::fvec4* rayr_get_render_data(RayRenderer* renderer);
|
||||
|
||||
std::unordered_map<uint32_t, glm::ivec2>* mCurrentRefTable;
|
||||
void rayr_draw(RayRenderer* renderer, scene::Scene* scene);
|
||||
|
||||
private:
|
||||
GLuint mRenderTargetTexture = 0;
|
||||
glm::fvec4* mTarget;
|
||||
void raryr_compute_hit(HitInfo* info);
|
||||
|
||||
std::mutex _RenderData;
|
||||
std::condition_variable _RenderPause;
|
||||
|
||||
glm::ivec2 mRenderTargetSize = {200, 200};
|
||||
|
||||
Scene* mCurrentScene = nullptr;
|
||||
RaySource* mRaySource = nullptr;
|
||||
|
||||
friend class RenderDispatcher;
|
||||
private:
|
||||
HHM* mIface;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace inferno::graphics
|
||||
|
||||
@@ -1,205 +1,229 @@
|
||||
#include <scene/camera.hpp>
|
||||
|
||||
using namespace inferno;
|
||||
namespace inferno::graphics {
|
||||
|
||||
Camera::Camera()
|
||||
Camera* camera_create()
|
||||
{
|
||||
mProjMatrix = glm::perspective( glm::radians(FOV), 1.0f, 0.1f, 1000.0f );
|
||||
Camera* camera = new Camera;
|
||||
camera->_impl = new _CameraImpl;
|
||||
|
||||
Roll = 0.0f;
|
||||
Pitch = 0.0f;
|
||||
Yaw = 0.0f;
|
||||
camera->Views = Viewports();
|
||||
camera->Views.Raster = glm::ivec2(800, 600);
|
||||
camera->Views.Ray = glm::ivec2(800, 600);
|
||||
|
||||
Position = {};
|
||||
LookDirection = {};
|
||||
camera->ProjectionMatrix = glm::perspective(
|
||||
glm::radians(camera->FOV),
|
||||
1.0f,
|
||||
0.1f,
|
||||
1000.0f);
|
||||
camera->ViewMatrix = {};
|
||||
|
||||
mViewMatrix = {};
|
||||
camera->Roll = 0.0f;
|
||||
camera->Pitch = 0.0f;
|
||||
camera->Yaw = 0.0f;
|
||||
|
||||
update();
|
||||
camera->Position = {};
|
||||
camera->LookDirection = {};
|
||||
|
||||
camera_update(camera);
|
||||
return camera;
|
||||
}
|
||||
|
||||
Camera::Camera(int w, int h)
|
||||
void camera_cleanup(Camera* camera)
|
||||
{
|
||||
mProjMatrix = glm::perspective(glm::radians(FOV), (float)w / (float)h, 0.1f, 1000.0f);
|
||||
|
||||
Roll = 0.0f;
|
||||
Pitch = 0.0f;
|
||||
Yaw = 0.0f;
|
||||
|
||||
Position = {};
|
||||
LookDirection = {};
|
||||
|
||||
mViewMatrix = {};
|
||||
|
||||
update();
|
||||
delete camera->_impl;
|
||||
delete camera;
|
||||
}
|
||||
|
||||
void Camera::update()
|
||||
void camera_update(Camera* camera)
|
||||
{
|
||||
glm::mat4 matRoll = glm::mat4(1.0f);
|
||||
glm::mat4 matPitch = glm::mat4(1.0f);
|
||||
glm::mat4 matYaw = glm::mat4(1.0f);
|
||||
glm::mat4 matRoll = glm::mat4(1.0f);
|
||||
glm::mat4 matPitch = glm::mat4(1.0f);
|
||||
glm::mat4 matYaw = glm::mat4(1.0f);
|
||||
|
||||
matRoll = glm::rotate(matRoll, Roll, glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
matPitch = glm::rotate(matPitch, Pitch, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
matYaw = glm::rotate(matYaw, Yaw, glm::vec3( 0.0f, 1.0f, 0.0f));
|
||||
matRoll = glm::rotate(matRoll, camera->Roll, glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
matPitch = glm::rotate(matPitch, camera->Pitch, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
matYaw = glm::rotate(matYaw, camera->Yaw, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
glm::mat4 rotate = matRoll * matPitch * matYaw;
|
||||
mCameraLook = rotate;
|
||||
glm::mat4 rotate = matRoll * matPitch * matYaw;
|
||||
camera->LookMatrix = rotate;
|
||||
|
||||
glm::mat4 translate = glm::mat4(1.0f);
|
||||
translate = glm::translate(translate, -Position);
|
||||
glm::mat4 translate = glm::mat4(1.0f);
|
||||
translate = glm::translate(translate, -camera->Position);
|
||||
|
||||
std::lock_guard<std::mutex> lock(this->_mCam);
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
|
||||
mViewMatrix = rotate * translate;
|
||||
mProjMatrix = glm::perspective(glm::radians(FOV), mViewport.x / mViewport.y, 0.1f, 1000.0f);
|
||||
camera->ViewMatrix = rotate * translate;
|
||||
camera->ProjectionMatrix = glm::perspective(
|
||||
glm::radians(camera->FOV),
|
||||
static_cast<float>(camera->Views.Raster.x) / static_cast<float>(camera->Views.Raster.y),
|
||||
0.1f,
|
||||
1000.0f);
|
||||
|
||||
// Work out Look Vector
|
||||
glm::mat4 inverseView = glm::inverse(mViewMatrix);
|
||||
// Work out Look Vector
|
||||
glm::mat4 inverseView = glm::inverse(camera->ViewMatrix);
|
||||
|
||||
LookDirection.x = inverseView[2][0];
|
||||
LookDirection.y = inverseView[2][1];
|
||||
LookDirection.z = inverseView[2][2];
|
||||
camera->LookDirection.x = inverseView[2][0];
|
||||
camera->LookDirection.y = inverseView[2][1];
|
||||
camera->LookDirection.z = inverseView[2][2];
|
||||
|
||||
mDidUpdate = true;
|
||||
camera->_impl->DidUpdate = true;
|
||||
}
|
||||
|
||||
bool Camera::didUpdate()
|
||||
bool camera_did_update(Camera* camera)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->_mCam);
|
||||
return mDidUpdate;
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
return camera->_impl->DidUpdate;
|
||||
}
|
||||
|
||||
void Camera::newFrame()
|
||||
void camera_new_frame(Camera* camera)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->_mCam);
|
||||
mDidUpdate = false;
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
camera->_impl->DidUpdate = false;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::getViewMatrix()
|
||||
glm::mat4 camera_get_view(Camera* camera)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->_mCam);
|
||||
return mViewMatrix;
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
return camera->ViewMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::getProjectionMatrix()
|
||||
glm::mat4 camera_get_projection(Camera* camera)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->_mCam);
|
||||
return mProjMatrix;
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
return camera->ProjectionMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 Camera::getCameraLook()
|
||||
glm::mat4 camera_get_look(Camera* camera)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->_mCam);
|
||||
return mCameraLook;
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
return camera->LookMatrix;
|
||||
}
|
||||
|
||||
void Camera::setRasterViewport(glm::vec2 viewport)
|
||||
void raster_set_viewport(Camera* camera, glm::ivec2 viewport)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->_mCam);
|
||||
mViewport = viewport;
|
||||
mProjMatrix = glm::perspective(glm::radians(FOV), (float)viewport.x / (float)viewport.y, 0.1f, 1000.0f);
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
camera->Views.Raster = viewport;
|
||||
camera->ProjectionMatrix = glm::perspective(
|
||||
glm::radians(camera->FOV),
|
||||
static_cast<float>(viewport.x) / static_cast<float>(viewport.y),
|
||||
0.1f,
|
||||
1000.0f);
|
||||
}
|
||||
|
||||
void Camera::moveCamera(uint8_t posDelta)
|
||||
glm::ivec2 raster_get_viewport(Camera* camera)
|
||||
{
|
||||
if (posDelta == 0) return;
|
||||
|
||||
// Rotate by camera direction
|
||||
glm::vec3 delta(0.0f);
|
||||
|
||||
glm::mat2 rotate {
|
||||
cos(Yaw), -sin(Yaw),
|
||||
sin(Yaw), cos(Yaw)
|
||||
};
|
||||
|
||||
glm::vec2 f(0.0, 1.0);
|
||||
f = f * rotate;
|
||||
|
||||
if (posDelta & 0x80) {
|
||||
delta.z -= f.y;
|
||||
delta.x -= f.x;
|
||||
}
|
||||
if (posDelta & 0x20) {
|
||||
delta.z += f.y;
|
||||
delta.x += f.x;
|
||||
}
|
||||
if (posDelta & 0x40) {
|
||||
delta.z += f.x;
|
||||
delta.x += -f.y;
|
||||
}
|
||||
if (posDelta & 0x10) {
|
||||
delta.z -= f.x;
|
||||
delta.x -= -f.y;
|
||||
}
|
||||
if (posDelta & 0x8) {
|
||||
delta.y += 1;
|
||||
}
|
||||
if (posDelta & 0x4) {
|
||||
delta.y -= 1;
|
||||
}
|
||||
|
||||
// get current view matrix
|
||||
glm::mat4 mat = getViewMatrix();
|
||||
glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]);
|
||||
glm::vec3 strafe(mat[0][0], mat[1][0], mat[2][0]);
|
||||
|
||||
// forward vector must be negative to look forward.
|
||||
// read :http://in2gpu.com/2015/05/17/view-matrix/
|
||||
Position += delta * CameraSpeed;
|
||||
|
||||
// update the view matrix
|
||||
update();
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
return camera->Views.Raster;
|
||||
}
|
||||
|
||||
void Camera::mouseMoved(glm::vec2 mouseDelta)
|
||||
void ray_set_viewport(Camera* camera, glm::ivec2 viewport)
|
||||
{
|
||||
if (glm::length(mouseDelta) == 0) return;
|
||||
// note that yaw and pitch must be converted to radians.
|
||||
// this is done in update() by glm::rotate
|
||||
Yaw += MouseSensitivity * (mouseDelta.x / 100);
|
||||
Pitch += MouseSensitivity * (mouseDelta.y / 100);
|
||||
Pitch = glm::clamp<float>(Pitch, -M_PI / 2, M_PI / 2);
|
||||
|
||||
update();
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
camera->Views.Ray = viewport;
|
||||
}
|
||||
|
||||
void Camera::setPosition(glm::vec3 position)
|
||||
glm::ivec2 ray_get_viewport(Camera* camera)
|
||||
{
|
||||
Position = position;
|
||||
|
||||
update();
|
||||
std::lock_guard<std::mutex> lock(camera->_impl->CamMutex);
|
||||
return camera->Views.Ray;
|
||||
}
|
||||
|
||||
void Camera::setEulerLook(float roll, float pitch, float yaw)
|
||||
void camera_move(Camera* camera, uint8_t movement_delta)
|
||||
{
|
||||
Roll = roll; Pitch = pitch; Yaw = yaw;
|
||||
LookDirection.x = cos(Yaw) * cos(Pitch);
|
||||
LookDirection.y = sin(Yaw) * cos(Pitch);
|
||||
LookDirection.z = sin(Pitch);
|
||||
if (movement_delta == 0)
|
||||
return;
|
||||
|
||||
update();
|
||||
// Rotate by camera direction
|
||||
glm::vec3 delta(0.0f);
|
||||
|
||||
glm::mat2 rotate {
|
||||
cos(camera->Yaw), -sin(camera->Yaw),
|
||||
sin(camera->Yaw), cos(camera->Yaw)
|
||||
};
|
||||
|
||||
glm::vec2 f(0.0, 1.0);
|
||||
f = f * rotate;
|
||||
|
||||
if (movement_delta & 0x80) {
|
||||
delta.z -= f.y;
|
||||
delta.x -= f.x;
|
||||
}
|
||||
if (movement_delta & 0x20) {
|
||||
delta.z += f.y;
|
||||
delta.x += f.x;
|
||||
}
|
||||
if (movement_delta & 0x40) {
|
||||
delta.z += f.x;
|
||||
delta.x += -f.y;
|
||||
}
|
||||
if (movement_delta & 0x10) {
|
||||
delta.z -= f.x;
|
||||
delta.x -= -f.y;
|
||||
}
|
||||
if (movement_delta & 0x8) {
|
||||
delta.y += 1;
|
||||
}
|
||||
if (movement_delta & 0x4) {
|
||||
delta.y -= 1;
|
||||
}
|
||||
|
||||
// get current view matrix
|
||||
glm::mat4 mat = camera_get_view(camera);
|
||||
glm::vec3 forward(mat[0][2], mat[1][2], mat[2][2]);
|
||||
glm::vec3 strafe(mat[0][0], mat[1][0], mat[2][0]);
|
||||
|
||||
// forward vector must be negative to look forward.
|
||||
// read :http://in2gpu.com/2015/05/17/view-matrix/
|
||||
camera->Position += delta * camera->Speed;
|
||||
|
||||
// update the view matrix
|
||||
camera_update(camera);
|
||||
}
|
||||
|
||||
void Camera::setLook(glm::vec3 lookDirection)
|
||||
void camera_mouse_move(Camera* camera, glm::vec2 mouse_delta)
|
||||
{
|
||||
LookDirection = lookDirection;
|
||||
Pitch = asin(-lookDirection.y);
|
||||
Yaw = atan2(lookDirection.x, lookDirection.z);
|
||||
if (glm::length(mouse_delta) == 0)
|
||||
return;
|
||||
// note that yaw and pitch must be converted to radians.
|
||||
// this is done in update() by glm::rotate
|
||||
camera->Yaw += camera->MouseSensitivity * (mouse_delta.x / 100);
|
||||
camera->Pitch += camera->MouseSensitivity * (mouse_delta.y / 100);
|
||||
camera->Pitch = glm::clamp<float>(camera->Pitch, -M_PI / 2, M_PI / 2);
|
||||
|
||||
update();
|
||||
camera_update(camera);
|
||||
}
|
||||
|
||||
void Camera::setRayViewport(glm::vec2 viewport)
|
||||
void camera_set_position(Camera* camera, glm::vec3 position)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->_mCam);
|
||||
mRayViewport = viewport;
|
||||
camera->Position = position;
|
||||
camera_update(camera);
|
||||
}
|
||||
|
||||
glm::vec2 Camera::getRayViewport()
|
||||
void camera_set_euler_look(Camera* camera, float roll, float pitch, float yaw)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(this->_mCam);
|
||||
return mRayViewport;
|
||||
camera->Roll = roll;
|
||||
camera->Pitch = pitch;
|
||||
camera->Yaw = yaw;
|
||||
camera->LookDirection.x = cos(camera->Yaw) * cos(camera->Pitch);
|
||||
camera->LookDirection.y = sin(camera->Yaw) * cos(camera->Pitch);
|
||||
camera->LookDirection.z = sin(camera->Pitch);
|
||||
|
||||
camera_update(camera);
|
||||
}
|
||||
|
||||
void camera_set_look(Camera* camera, glm::vec3 look_direction)
|
||||
{
|
||||
camera->LookDirection = look_direction;
|
||||
camera->Pitch = asin(-look_direction.y);
|
||||
camera->Yaw = atan2(look_direction.x, look_direction.z);
|
||||
|
||||
camera_update(camera);
|
||||
}
|
||||
|
||||
glm::vec3 camera_get_position(Camera* camera)
|
||||
{
|
||||
return camera->Position;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,12 @@
|
||||
|
||||
#include <hart_graphics.hpp>
|
||||
|
||||
namespace inferno {
|
||||
namespace inferno::graphics {
|
||||
class Shader;
|
||||
};
|
||||
|
||||
namespace inferno::scene {
|
||||
|
||||
class Shader;
|
||||
class HitInfo;
|
||||
|
||||
class Material {
|
||||
@@ -15,14 +18,14 @@ public:
|
||||
~Material();
|
||||
|
||||
std::string getName();
|
||||
void setGlShader(Shader* shader);
|
||||
Shader* getGlShader();
|
||||
void setGlShader(graphics::Shader* shader);
|
||||
graphics::Shader* getGlShader();
|
||||
|
||||
glm::vec3 sample(HitInfo* hit);
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
Shader* mGlShader;
|
||||
graphics::Shader* mGlShader;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
|
||||
#include <hart_graphics.hpp>
|
||||
|
||||
namespace inferno {
|
||||
namespace inferno::scene {
|
||||
|
||||
class ObjLoader;
|
||||
class Material;
|
||||
|
||||
// TODO: This should be procedural like everything else
|
||||
struct Vert
|
||||
{
|
||||
glm::vec3 Position;
|
||||
@@ -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<Vert> mVerticies;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#include "object.hpp"
|
||||
|
||||
#include "mesh.hpp"
|
||||
|
||||
namespace inferno::scene {
|
||||
|
||||
SceneObject* scene_object_create()
|
||||
{
|
||||
SceneObject* object = new SceneObject;
|
||||
return object;
|
||||
}
|
||||
|
||||
void scene_object_cleanup(SceneObject* object)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void scene_object_add_mesh(SceneObject* object, Mesh* mesh)
|
||||
{
|
||||
object->Meshs.push_back(mesh);
|
||||
}
|
||||
|
||||
std::vector<Mesh*>& scene_object_get_meshs(SceneObject* object)
|
||||
{
|
||||
return object->Meshs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace inferno {
|
||||
namespace inferno::scene {
|
||||
|
||||
class Mesh;
|
||||
|
||||
class Object
|
||||
{
|
||||
public:
|
||||
Object();
|
||||
~Object();
|
||||
typedef struct SceneObject {
|
||||
std::vector<Mesh*> Meshs;
|
||||
} SceneObject;
|
||||
|
||||
private:
|
||||
std::vector<Mesh*> mMeshs;
|
||||
};
|
||||
SceneObject* scene_object_create();
|
||||
void scene_object_cleanup(SceneObject* object);
|
||||
|
||||
}
|
||||
void scene_object_add_mesh(SceneObject* object, Mesh* mesh);
|
||||
std::vector<Mesh*>& scene_object_get_meshs(SceneObject* object);
|
||||
|
||||
} // namespace inferno::scene
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <assert.h>
|
||||
#include <map>
|
||||
|
||||
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<FaceVert, int, vert_less> 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<int> 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<vindices.size()-1; ++i)
|
||||
for (size_t i=1; i<vindices.size()-1; ++i)
|
||||
{
|
||||
Face face;
|
||||
FaceVert tri;
|
||||
@@ -211,21 +211,21 @@ void ObjLoader::load(std::filesystem::path file)
|
||||
mTexCoords.resize(vert_count);
|
||||
|
||||
std::map<FaceVert, int, vert_less>::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];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include <hart_graphics.hpp>
|
||||
|
||||
namespace inferno {
|
||||
namespace inferno::scene {
|
||||
|
||||
struct Face
|
||||
{
|
||||
|
||||
@@ -1,49 +1,61 @@
|
||||
#include "scene.hpp"
|
||||
|
||||
#include <scene/object.hpp>
|
||||
#include <yolo/yolo.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <scene/camera.hpp>
|
||||
#include <scene/mesh.hpp>
|
||||
#include <scene/object.hpp>
|
||||
|
||||
using namespace inferno;
|
||||
namespace inferno::scene {
|
||||
|
||||
Scene::Scene()
|
||||
Scene* scene_create()
|
||||
{
|
||||
|
||||
Scene* scene = new Scene;
|
||||
scene->Objects = std::vector<SceneObject*>();
|
||||
scene->Camera = graphics::camera_create();
|
||||
yolo::debug("Created scene {} and camera {}", scene, scene->Camera);
|
||||
return scene;
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
void scene_cleanup(Scene* scene)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Scene::setCamera(Camera* camera)
|
||||
void scene_add_object(Scene* scene, SceneObject* object)
|
||||
{
|
||||
mCurrentCamera = camera;
|
||||
mDidUpdate = true;
|
||||
yolo::debug("Using scene {}", scene);
|
||||
yolo::debug("Adding object to scene, no Objects: {}, adding to pool of: {}", object->Meshs.size(), scene->Objects.size());
|
||||
yolo::debug("Object Mesh 0 is {}", object->Meshs[0]);
|
||||
scene->Objects.push_back(object);
|
||||
scene->DidUpdate = true;
|
||||
}
|
||||
|
||||
Camera* Scene::getCamera()
|
||||
graphics::Camera* scene_get_camera(Scene* scene)
|
||||
{
|
||||
return mCurrentCamera;
|
||||
return scene->Camera;
|
||||
}
|
||||
|
||||
void Scene::addMesh(Mesh* mesh)
|
||||
std::vector<SceneObject*>& scene_get_renderables(Scene* scene)
|
||||
{
|
||||
mMeshs.push_back(mesh);
|
||||
mDidUpdate = true;
|
||||
return scene->Objects;
|
||||
}
|
||||
|
||||
bool Scene::didUpdate()
|
||||
bool scene_did_update(Scene* scene)
|
||||
{
|
||||
return mDidUpdate;
|
||||
return scene->DidUpdate;
|
||||
}
|
||||
|
||||
void Scene::newFrame()
|
||||
void scene_frame_tick(Scene* scene)
|
||||
{
|
||||
mDidUpdate = false;
|
||||
scene->DidUpdate = false;
|
||||
}
|
||||
|
||||
const std::vector<Mesh*>& Scene::getRenderables()
|
||||
void scene_tick(Scene* scene)
|
||||
{
|
||||
return mMeshs;
|
||||
for (auto& object : scene->Objects) {
|
||||
// Shit here like animation idk
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "scene/object.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace inferno {
|
||||
namespace inferno::graphics {
|
||||
class Camera;
|
||||
}
|
||||
|
||||
namespace inferno::scene {
|
||||
|
||||
class SceneObject;
|
||||
class Camera;
|
||||
class Mesh;
|
||||
class Sky;
|
||||
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
Scene();
|
||||
~Scene();
|
||||
typedef struct Scene {
|
||||
std::vector<SceneObject*> Objects;
|
||||
graphics::Camera* Camera;
|
||||
bool DidUpdate = false;
|
||||
} Scene;
|
||||
|
||||
void setCamera(Camera* camera);
|
||||
Camera* getCamera();
|
||||
void addMesh(Mesh* mesh);
|
||||
Scene* scene_create();
|
||||
void scene_cleanup(Scene* scene);
|
||||
|
||||
bool didUpdate();
|
||||
void newFrame();
|
||||
void scene_add_object(Scene* scene, SceneObject* object);
|
||||
|
||||
const std::vector<Mesh*>& getRenderables();
|
||||
graphics::Camera* scene_get_camera(Scene* scene);
|
||||
std::vector<SceneObject*>& scene_get_renderables(Scene* scene);
|
||||
|
||||
private:
|
||||
std::vector<Mesh*> mMeshs;
|
||||
bool scene_did_update(Scene* scene);
|
||||
|
||||
Camera* mCurrentCamera;
|
||||
Sky* mCurrentSky;
|
||||
void scene_frame_tick(Scene* scene);
|
||||
void scene_tick(Scene* scene);
|
||||
|
||||
private:
|
||||
bool mDidUpdate = false;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace inferno::scene
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
namespace inferno::helpers {
|
||||
|
||||
template <class T>
|
||||
class Singleton
|
||||
{
|
||||
public:
|
||||
static T& GetInstance()
|
||||
{
|
||||
static T instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
Singleton( Singleton const& ) = delete;
|
||||
void operator=( Singleton const& ) = delete;
|
||||
protected:
|
||||
Singleton() = default;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define INFERNO_VERSION "3.0.1_alpha"
|
||||
#define INFERNO_VERSION "3.0.13_alpha"
|
||||
|
||||
272
src/window.cpp
272
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);
|
||||
}
|
||||
|
||||
@@ -2,64 +2,37 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "singleton.hpp"
|
||||
#include "graphics.hpp"
|
||||
|
||||
#define WINDOW_FLAGS ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus | ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoCollapse
|
||||
|
||||
namespace inferno {
|
||||
namespace inferno::graphics {
|
||||
|
||||
typedef void (*KeyCallback)(int key, int scan, int action, int mod);
|
||||
typedef void (*MouseCallback)(double x, double y);
|
||||
|
||||
enum WINDOW_MODE
|
||||
{
|
||||
enum WINDOW_MODE {
|
||||
WIN_MODE_DEFAULT,
|
||||
WIN_MODE_FPS,
|
||||
};
|
||||
|
||||
class Window : public helpers::Singleton<Window>
|
||||
{
|
||||
public:
|
||||
Window();
|
||||
~Window();
|
||||
void window_create(std::string title, int width, int height);
|
||||
void window_cleanup();
|
||||
|
||||
void init(std::string title, int width, int height);
|
||||
void window_set_title(std::string title);
|
||||
|
||||
bool newFrame();
|
||||
void render();
|
||||
void window_set_size(int w, int h);
|
||||
void window_set_pos(int x, int y);
|
||||
glm::vec2 window_get_size();
|
||||
void window_get_pos(int& x, int& y);
|
||||
|
||||
void setTitle(std::string title);
|
||||
void setSize(int w, int h);
|
||||
void setPos(int x, int y);
|
||||
GLFWwindow* window_get_glfw_window();
|
||||
void window_set_mode(WINDOW_MODE mode);
|
||||
|
||||
glm::vec2 getSize();
|
||||
void getPos(int& x, int& y);
|
||||
GLFWwindow* getGLFWWindow() { return window; }
|
||||
void window_set_key_callback(KeyCallback callback);
|
||||
KeyCallback window_get_key_callback();
|
||||
|
||||
void setFPSMode();
|
||||
|
||||
void setKeyCallback(KeyCallback callback);
|
||||
KeyCallback getKeyCallback();
|
||||
|
||||
private:
|
||||
WINDOW_MODE mWinMode = WIN_MODE_DEFAULT;
|
||||
|
||||
private:
|
||||
void setupGLFW(std::string title);
|
||||
void setupImGui();
|
||||
void shutdownImGui();
|
||||
void shutdownGLFW();
|
||||
|
||||
static void glfwKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
KeyCallback mKeyCallback = nullptr;
|
||||
|
||||
private:
|
||||
static void glfwErrorCallback(int error, const char* description);
|
||||
|
||||
int width, height;
|
||||
const char* glslVersion;
|
||||
GLFWwindow* window;
|
||||
};
|
||||
bool window_new_frame();
|
||||
void window_render();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user