From cbe79b535b2014c8f72ffe636783fffb9fce011a Mon Sep 17 00:00:00 2001 From: Alexis Maiquez Date: Wed, 11 Sep 2019 15:32:57 +0200 Subject: [PATCH] ~ changed wrong class name crom CPassess to CPass + added parsing of bind section for shader passes ~ various new classes to properly handle texture targets, shader passes and materials Signed-off-by: Alexis Maiquez --- CMakeLists.txt | 15 +- src/WallpaperEngine/Core/Objects/CEffect.cpp | 30 ++- src/WallpaperEngine/Core/Objects/CEffect.h | 4 +- .../Core/Objects/Effects/CBind.cpp | 39 +++ .../Core/Objects/Effects/CBind.h | 26 ++ .../Core/Objects/Images/CMaterial.cpp | 17 +- .../Core/Objects/Images/CMaterial.h | 12 +- .../Materials/{CPassess.cpp => CPass.cpp} | 32 +-- .../Images/Materials/{CPassess.h => CPass.h} | 6 +- .../Render/Objects/CEffect.cpp | 90 +++++++ src/WallpaperEngine/Render/Objects/CEffect.h | 47 ++++ src/WallpaperEngine/Render/Objects/CImage.cpp | 16 +- src/WallpaperEngine/Render/Objects/CImage.h | 13 +- .../Render/Objects/Effects/CFBO.cpp | 34 +++ .../Render/Objects/Effects/CFBO.h | 25 ++ .../Render/Objects/Effects/CMaterial.cpp | 46 ++++ .../Render/Objects/Effects/CMaterial.h | 52 ++++ .../Render/Objects/Effects/CPass.cpp | 255 ++++++++++++++++++ .../Render/Objects/Effects/CPass.h | 41 +++ 19 files changed, 757 insertions(+), 43 deletions(-) create mode 100644 src/WallpaperEngine/Core/Objects/Effects/CBind.cpp create mode 100644 src/WallpaperEngine/Core/Objects/Effects/CBind.h rename src/WallpaperEngine/Core/Objects/Images/Materials/{CPassess.cpp => CPass.cpp} (76%) rename src/WallpaperEngine/Core/Objects/Images/Materials/{CPassess.h => CPass.h} (88%) create mode 100644 src/WallpaperEngine/Render/Objects/CEffect.cpp create mode 100644 src/WallpaperEngine/Render/Objects/CEffect.h create mode 100644 src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp create mode 100644 src/WallpaperEngine/Render/Objects/Effects/CFBO.h create mode 100644 src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp create mode 100644 src/WallpaperEngine/Render/Objects/Effects/CMaterial.h create mode 100644 src/WallpaperEngine/Render/Objects/Effects/CPass.cpp create mode 100644 src/WallpaperEngine/Render/Objects/Effects/CPass.h diff --git a/CMakeLists.txt b/CMakeLists.txt index df36a5d..40c5622 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,15 @@ add_executable( src/WallpaperEngine/Render/Objects/CImage.cpp src/WallpaperEngine/Render/Objects/CSound.h src/WallpaperEngine/Render/Objects/CSound.cpp + src/WallpaperEngine/Render/Objects/CEffect.h + src/WallpaperEngine/Render/Objects/CEffect.cpp + + src/WallpaperEngine/Render/Objects/Effects/CFBO.h + src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp + src/WallpaperEngine/Render/Objects/Effects/CPass.h + src/WallpaperEngine/Render/Objects/Effects/CPass.cpp + src/WallpaperEngine/Render/Objects/Effects/CMaterial.h + src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp src/WallpaperEngine/FileSystem/FileSystem.cpp src/WallpaperEngine/FileSystem/FileSystem.h @@ -100,6 +109,8 @@ add_executable( src/WallpaperEngine/Core/Objects/Effects/CFBO.h src/WallpaperEngine/Core/Objects/Effects/CFBO.cpp + src/WallpaperEngine/Core/Objects/Effects/CBind.h + src/WallpaperEngine/Core/Objects/Effects/CBind.cpp src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h src/WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.cpp @@ -135,8 +146,8 @@ add_executable( src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp src/WallpaperEngine/Core/Objects/Images/CMaterial.h - src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.cpp - src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.h + src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp + src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h ) target_link_libraries(wallengine ${X11_LIBRARIES} ${XRANDR_LIBRARIES} ${X11_Xxf86vm_LIB} ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${ZLIB_LIBRARIES} ${IRRLICHT_LIBRARY} ${LZ4_LIBRARY} ${SDL_LIBRARY} ${SDL_MIXER_LIBRARIES}) \ No newline at end of file diff --git a/src/WallpaperEngine/Core/Objects/CEffect.cpp b/src/WallpaperEngine/Core/Objects/CEffect.cpp index 7c8b76f..8a63905 100644 --- a/src/WallpaperEngine/Core/Objects/CEffect.cpp +++ b/src/WallpaperEngine/Core/Objects/CEffect.cpp @@ -167,7 +167,7 @@ CEffect* CEffect::fromJSON (json data, Core::CObject* object) return effect; } -void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPassess* pass) +void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass) { auto cur = (*combos_it).begin (); auto end = (*combos_it).end (); @@ -178,7 +178,7 @@ void CEffect::combosFromJSON (json::const_iterator combos_it, Core::Objects::Ima } } -void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPassess* pass) +void CEffect::constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass) { auto cur = (*constants_it).begin (); auto end = (*constants_it).end (); @@ -241,24 +241,38 @@ void CEffect::materialsFromJSON (json::const_iterator passes_it, CEffect* effect { auto materialfile = (*cur).find ("material"); auto target = (*cur).find ("target"); + auto bind = (*cur).find ("bind"); if (materialfile == (*cur).end ()) { throw std::runtime_error ("Effect pass must have a material file"); } + Images::CMaterial* material = nullptr; + if (target == (*cur).end ()) { - effect->insertMaterial ( - Images::CMaterial::fromFile ((*materialfile).get ().c_str ()) - ); + material = Images::CMaterial::fromFile ((*materialfile).get ().c_str ()); } else { - effect->insertMaterial ( - Images::CMaterial::fromFile ((*materialfile).get ().c_str (), *target) - ); + material = Images::CMaterial::fromFile ((*materialfile).get ().c_str (), *target); } + + if (bind != (*cur).end ()) + { + auto bindCur = (*bind).begin (); + auto bindEnd = (*bind).end (); + + for (; bindCur != bindEnd; bindCur ++) + { + material->insertTextureBind ( + Effects::CBind::fromJSON (*bindCur) + ); + } + } + + effect->insertMaterial (material); } } diff --git a/src/WallpaperEngine/Core/Objects/CEffect.h b/src/WallpaperEngine/Core/Objects/CEffect.h index a463068..c05db72 100644 --- a/src/WallpaperEngine/Core/Objects/CEffect.h +++ b/src/WallpaperEngine/Core/Objects/CEffect.h @@ -36,8 +36,8 @@ namespace WallpaperEngine::Core::Objects Effects::CFBO* findFBO (const std::string& name); protected: - static void constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPassess* pass); - static void combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPassess* pass); + static void constantsFromJSON (json::const_iterator constants_it, Core::Objects::Images::Materials::CPass* pass); + static void combosFromJSON (json::const_iterator combos_it, Core::Objects::Images::Materials::CPass* pass); static void fbosFromJSON (json::const_iterator fbos_it, CEffect* effect); static void dependencyFromJSON (json::const_iterator dependencies_it, CEffect* effect); static void materialsFromJSON (json::const_iterator passes_it, CEffect* effect); diff --git a/src/WallpaperEngine/Core/Objects/Effects/CBind.cpp b/src/WallpaperEngine/Core/Objects/Effects/CBind.cpp new file mode 100644 index 0000000..c890115 --- /dev/null +++ b/src/WallpaperEngine/Core/Objects/Effects/CBind.cpp @@ -0,0 +1,39 @@ +#include "CBind.h" + +#include + +using namespace WallpaperEngine::Core::Objects::Effects; + +CBind::CBind (std::string name, irr::u32 index) : + m_name (std::move(name)), + m_index (index) +{ +} + +CBind* CBind::fromJSON (json data) +{ + auto name_it = data.find ("name"); + auto index_it = data.find ("index"); + + if (name_it == data.end ()) + { + throw std::runtime_error ("bind must have texture name"); + } + + if (index_it == data.end ()) + { + throw std::runtime_error ("bind must have index"); + } + + return new CBind (*name_it, *index_it); +} + +const std::string& CBind::getName () const +{ + return this->m_name; +} + +const irr::u32& CBind::getIndex () const +{ + return this->m_index; +} \ No newline at end of file diff --git a/src/WallpaperEngine/Core/Objects/Effects/CBind.h b/src/WallpaperEngine/Core/Objects/Effects/CBind.h new file mode 100644 index 0000000..a4cbeb1 --- /dev/null +++ b/src/WallpaperEngine/Core/Objects/Effects/CBind.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +#include +#include + +namespace WallpaperEngine::Core::Objects::Effects +{ + using json = nlohmann::json; + + class CBind + { + public: + static CBind* fromJSON (json data); + + CBind (std::string name, irr::u32 index); + + const std::string& getName () const; + const irr::u32& getIndex () const; + + private: + std::string m_name; + irr::u32 m_index; + }; +} diff --git a/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp b/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp index 4f3583c..af269b2 100644 --- a/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp +++ b/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp @@ -5,6 +5,7 @@ #include "WallpaperEngine/FileSystem/FileSystem.h" +using namespace WallpaperEngine::Core::Objects; using namespace WallpaperEngine::Core::Objects::Images; CMaterial::CMaterial () : @@ -51,27 +52,37 @@ CMaterial* CMaterial::fromJSON (json data) for (; cur != end; cur ++) { material->insertPass ( - Materials::CPassess::fromJSON (*cur) + Materials::CPass::fromJSON (*cur) ); } return material; } -void CMaterial::insertPass (Materials::CPassess* mass) +void CMaterial::insertPass (Materials::CPass* mass) { this->m_passes.push_back (mass); } +void CMaterial::insertTextureBind (Effects::CBind* bind) +{ + this->m_textureBindings.push_back (bind); +} + void CMaterial::setTarget (const std::string& target) { this->m_target = target; } -const std::vector & CMaterial::getPasses () const +const std::vector & CMaterial::getPasses () const { return this->m_passes; } +const std::vector & CMaterial::getTextureBinds () const +{ + return this->m_textureBindings; +} + const std::string& CMaterial::getTarget () const { return this->m_target; diff --git a/src/WallpaperEngine/Core/Objects/Images/CMaterial.h b/src/WallpaperEngine/Core/Objects/Images/CMaterial.h index 107c341..0fe2e54 100644 --- a/src/WallpaperEngine/Core/Objects/Images/CMaterial.h +++ b/src/WallpaperEngine/Core/Objects/Images/CMaterial.h @@ -3,7 +3,8 @@ #include #include -#include "WallpaperEngine/Core/Objects/Images/Materials/CPassess.h" +#include "WallpaperEngine/Core/Objects/Images/Materials/CPass.h" +#include "WallpaperEngine/Core/Objects/Effects/CBind.h" namespace WallpaperEngine::Core::Objects::Images { @@ -17,9 +18,11 @@ namespace WallpaperEngine::Core::Objects::Images static CMaterial* fromFile (const irr::io::path& filename, const std::string& target); static CMaterial* fromJSON (json data, const std::string& target); - void insertPass (Materials::CPassess* mass); + void insertPass (Materials::CPass* mass); + void insertTextureBind (Effects::CBind* bind); - const std::vector & getPasses () const; + const std::vector & getPasses () const; + const std::vector & getTextureBinds () const; const std::string& getTarget () const; const bool hasTarget () const; protected: @@ -27,7 +30,8 @@ namespace WallpaperEngine::Core::Objects::Images void setTarget (const std::string& target); private: - std::vector m_passes; + std::vector m_passes; + std::vector m_textureBindings; std::string m_target; }; }; diff --git a/src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.cpp b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp similarity index 76% rename from src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.cpp rename to src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp index 5873126..8db6d1a 100644 --- a/src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.cpp +++ b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp @@ -1,9 +1,9 @@ -#include "CPassess.h" +#include "CPass.h" using namespace WallpaperEngine::Core::Objects::Effects::Constants; using namespace WallpaperEngine::Core::Objects::Images::Materials; -CPassess::CPassess (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader) : +CPass::CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader) : m_blending (std::move(blending)), m_cullmode (std::move(cullmode)), m_depthtest (std::move(depthtest)), @@ -12,7 +12,7 @@ CPassess::CPassess (std::string blending, std::string cullmode, std::string dept { } -CPassess* CPassess::fromJSON (json data) +CPass* CPass::fromJSON (json data) { auto blending_it = data.find ("blending"); auto cullmode_it = data.find ("cullmode"); @@ -56,7 +56,7 @@ CPassess* CPassess::fromJSON (json data) } } - CPassess* pass = new CPassess ( + CPass* pass = new CPass ( *blending_it, *cullmode_it, *depthtest_it, @@ -105,62 +105,62 @@ CPassess* CPassess::fromJSON (json data) return pass; } -void CPassess::insertTexture (const std::string& texture) +void CPass::insertTexture (const std::string& texture) { this->m_textures.push_back (texture); } -void CPassess::setTexture (int index, const std::string& texture) +void CPass::setTexture (int index, const std::string& texture) { this->m_textures.at (index) = texture; } -void CPassess::insertCombo (const std::string& name, int value) +void CPass::insertCombo (const std::string& name, int value) { this->m_combos.insert (std::pair (name, value)); } -const std::vector& CPassess::getTextures () const +const std::vector& CPass::getTextures () const { return this->m_textures; } -const std::map& CPassess::getConstants () const +const std::map& CPass::getConstants () const { return this->m_constants; } -const std::map& CPassess::getCombos () const +const std::map& CPass::getCombos () const { return this->m_combos; } -const std::string& CPassess::getShader () const +const std::string& CPass::getShader () const { return this->m_shader; } -const std::string& CPassess::getBlendingMode () const +const std::string& CPass::getBlendingMode () const { return this->m_blending; } -const std::string& CPassess::getCullingMode () const +const std::string& CPass::getCullingMode () const { return this->m_cullmode; } -const std::string& CPassess::getDepthTest () const +const std::string& CPass::getDepthTest () const { return this->m_depthtest; } -const std::string& CPassess::getDepthWrite ()const +const std::string& CPass::getDepthWrite ()const { return this->m_depthwrite; } -void CPassess::insertConstant (const std::string& name, CShaderConstant* constant) +void CPass::insertConstant (const std::string& name, CShaderConstant* constant) { this->m_constants.insert (std::pair (name, constant)); } \ No newline at end of file diff --git a/src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.h b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h similarity index 88% rename from src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.h rename to src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h index 6e3e042..517c2cd 100644 --- a/src/WallpaperEngine/Core/Objects/Images/Materials/CPassess.h +++ b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h @@ -13,11 +13,11 @@ namespace WallpaperEngine::Core::Objects::Images::Materials { using json = nlohmann::json; - class CPassess + class CPass { friend class Core::Objects::CEffect; public: - static CPassess* fromJSON (json data); + static CPass* fromJSON (json data); const std::vector& getTextures () const; const std::map& getConstants () const; @@ -33,7 +33,7 @@ namespace WallpaperEngine::Core::Objects::Images::Materials void insertConstant (const std::string& name, Effects::Constants::CShaderConstant* constant); protected: - CPassess (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader); + CPass (std::string blending, std::string cullmode, std::string depthtest, std::string depthwrite, std::string shader); void insertTexture (const std::string& texture); void setTexture (int index, const std::string& texture); diff --git a/src/WallpaperEngine/Render/Objects/CEffect.cpp b/src/WallpaperEngine/Render/Objects/CEffect.cpp new file mode 100644 index 0000000..92a90f2 --- /dev/null +++ b/src/WallpaperEngine/Render/Objects/CEffect.cpp @@ -0,0 +1,90 @@ +#include "CEffect.h" + +using namespace WallpaperEngine::Render::Objects; + +CEffect::CEffect (CImage* image, Core::Objects::CEffect* effect, Irrlicht::CContext* context, irr::video::ITexture* input) : + m_context (context), + m_image (image), + m_effect (effect), + m_inputTexture (input) +{ + irr::core::dimension2du size = irr::core::dimension2du ( + this->m_image->getImage ()->getSize ().X, + this->m_image->getImage ()->getSize ().Y + ); + + this->m_outputTexture = this->m_context->getDevice ()->getVideoDriver ()->addRenderTargetTexture ( + size, + ( + "_rt_WALLENGINELINUX_OUTPUT_" + + std::to_string (image->getImage ()->getId ()) + "_" + + std::to_string (this->m_image->getEffects ().size ()) + + "_output" + ).c_str () + ); + + this->generateFBOs (); + this->generatePasses (); +} + +const irr::video::ITexture* CEffect::getInputTexture () const +{ + return this->m_inputTexture; +} + +const irr::video::ITexture* CEffect::getOutputTexture () const +{ + return this->m_outputTexture; +} + +const CImage* CEffect::getImage () const +{ + return this->m_image; +} + +const std::vector& CEffect::getMaterials () const +{ + return this->m_materials; +} + +Effects::CFBO* CEffect::findFBO (const std::string& name) +{ + auto cur = this->m_fbos.begin (); + auto end = this->m_fbos.end (); + + for (; cur != end; cur ++) + { + if ((*cur)->getName () == name) + { + return *cur; + } + } + + return nullptr; +} + +void CEffect::generatePasses () +{ + auto cur = this->m_effect->getMaterials ().begin (); + auto end = this->m_effect->getMaterials ().end (); + + for (; cur != end; cur ++) + { + this->m_materials.push_back ( + new Effects::CMaterial (this->m_context, this, *cur) + ); + } +} + +void CEffect::generateFBOs () +{ + auto cur = this->m_effect->getFbos ().begin (); + auto end = this->m_effect->getFbos ().end (); + + for (; cur != end; cur ++) + { + this->m_fbos.push_back ( + new Effects::CFBO (*cur, this->m_image->getImage (), this->m_context) + ); + } +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Objects/CEffect.h b/src/WallpaperEngine/Render/Objects/CEffect.h new file mode 100644 index 0000000..717ba25 --- /dev/null +++ b/src/WallpaperEngine/Render/Objects/CEffect.h @@ -0,0 +1,47 @@ +#pragma once + +#include + +#include "WallpaperEngine/Irrlicht/CContext.h" + +#include "WallpaperEngine/Render/Objects/CImage.h" +#include "WallpaperEngine/Render/Objects/Effects/CFBO.h" +#include "WallpaperEngine/Render/Objects/Effects/CPass.h" +#include "WallpaperEngine/Render/Objects/Effects/CMaterial.h" + +namespace WallpaperEngine::Render::Objects::Effects +{ + class CMaterial; +} + +namespace WallpaperEngine::Render::Objects +{ + class CImage; + + class CEffect + { + public: + CEffect (CImage* image, Core::Objects::CEffect* effect, Irrlicht::CContext* context, irr::video::ITexture* input); + + const irr::video::ITexture* getOutputTexture () const; + const irr::video::ITexture* getInputTexture () const; + const CImage* getImage () const; + + const std::vector& getMaterials () const; + + Effects::CFBO* findFBO (const std::string& name); + private: + void generatePasses (); + void generateFBOs (); + + Irrlicht::CContext* m_context; + CImage* m_image; + Core::Objects::CEffect* m_effect; + + std::vector m_fbos; + std::vector m_materials; + + irr::video::ITexture* m_inputTexture; + irr::video::ITexture* m_outputTexture; + }; +}; diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index 922ee99..72e81cf 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -102,7 +102,7 @@ void CImage::generateMaterial () for (; cur != end; cur++) { - this->generatePass (*cur, nullptr); + this->generatePass (*cur); } auto effectCur = this->m_image->getEffects ().begin (); @@ -120,13 +120,13 @@ void CImage::generateMaterial () for (; cur != end; cur++) { - this->generatePass (*cur, *effectCur); + this->generatePass (*cur); } } } } -void CImage::generatePass (Core::Objects::Images::Materials::CPassess* pass, Core::Objects::CEffect* effect) +void CImage::generatePass (Core::Objects::Images::Materials::CPass* pass) { std::vector textures = pass->getTextures (); irr::video::SMaterial material; @@ -233,6 +233,16 @@ const irr::core::aabbox3d& CImage::getBoundingBox() const return this->m_boundingBox; } +const Core::Objects::CImage* CImage::getImage () const +{ + return this->m_image; +} + +const std::vector& CImage::getEffects () const +{ + return this->m_effects; +} + void CImage::OnSetConstants (irr::video::IMaterialRendererServices *services, int32_t userData) { irr::f32 g_Texture0 = 0; diff --git a/src/WallpaperEngine/Render/Objects/CImage.h b/src/WallpaperEngine/Render/Objects/CImage.h index 4ac4a8b..1a04ec1 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.h +++ b/src/WallpaperEngine/Render/Objects/CImage.h @@ -2,6 +2,7 @@ #include "WallpaperEngine/Core/Objects/CImage.h" +#include "WallpaperEngine/Render/Objects/CEffect.h" #include "WallpaperEngine/Render/CObject.h" #include "WallpaperEngine/Render/CScene.h" @@ -11,22 +12,28 @@ using namespace WallpaperEngine; namespace WallpaperEngine::Render::Objects { + class CEffect; + class CImage : public CObject, public irr::video::IShaderConstantSetCallBack { public: CImage (CScene* scene, Core::Objects::CImage* image); - virtual void OnSetConstants (irr::video::IMaterialRendererServices* services, int32_t userData); + void OnSetConstants (irr::video::IMaterialRendererServices* services, int32_t userData) override; void render () override; const irr::core::aabbox3d& getBoundingBox() const override; + const Core::Objects::CImage* getImage () const; + const std::vector& getEffects () const; + protected: static const std::string Type; private: + void generateFBOs (); void generateMaterial (); - void generatePass (Core::Objects::Images::Materials::CPassess* pass, Core::Objects::CEffect* effect); + void generatePass (Core::Objects::Images::Materials::CPass* pass); irr::video::S3DVertex m_vertex [4]; irr::u32 m_passes; @@ -36,6 +43,8 @@ namespace WallpaperEngine::Render::Objects Core::Objects::CImage* m_image; irr::core::aabbox3d m_boundingBox; + std::vector m_effects; + std::vector m_vertexShaders; std::vector m_pixelShaders; }; diff --git a/src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp b/src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp new file mode 100644 index 0000000..1b8bc01 --- /dev/null +++ b/src/WallpaperEngine/Render/Objects/Effects/CFBO.cpp @@ -0,0 +1,34 @@ +#include "CFBO.h" + +using namespace WallpaperEngine::Render::Objects::Effects; + +CFBO::CFBO (Core::Objects::Effects::CFBO* fbo, const Core::Objects::CImage* image, Irrlicht::CContext* context) : + m_fbo (fbo) +{ + irr::core::dimension2du size = irr::core::dimension2du ( + image->getSize ().X * this->getScale (), + image->getSize ().Y * this->getScale () + ); + + context->getDevice ()->getVideoDriver ()->addRenderTargetTexture (size, this->getName ().c_str ()); +} + +const irr::video::ITexture* CFBO::getTexture () const +{ + return this->m_texture; +} + +const std::string& CFBO::getName () const +{ + return this->m_fbo->getName (); +} + +const irr::f32& CFBO::getScale () const +{ + return this->m_fbo->getScale (); +} + +const std::string& CFBO::getFormat () const +{ + return this->m_fbo->getFormat (); +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Objects/Effects/CFBO.h b/src/WallpaperEngine/Render/Objects/Effects/CFBO.h new file mode 100644 index 0000000..9660c21 --- /dev/null +++ b/src/WallpaperEngine/Render/Objects/Effects/CFBO.h @@ -0,0 +1,25 @@ +#pragma once + +#include + +#include "WallpaperEngine/Core/Objects/Effects/CFBO.h" +#include "WallpaperEngine/Core/Objects/CImage.h" + +#include "WallpaperEngine/Irrlicht/CContext.h" + +namespace WallpaperEngine::Render::Objects::Effects +{ + class CFBO + { + public: + CFBO (Core::Objects::Effects::CFBO* fbo, const Core::Objects::CImage* image, Irrlicht::CContext* context); + + const irr::video::ITexture* getTexture () const; + const std::string& getName () const; + const irr::f32& getScale () const; + const std::string& getFormat () const; + private: + irr::video::ITexture* m_texture; + const Core::Objects::Effects::CFBO* m_fbo; + }; +}; diff --git a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp new file mode 100644 index 0000000..68ab2fc --- /dev/null +++ b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.cpp @@ -0,0 +1,46 @@ +#include "CMaterial.h" + +using namespace WallpaperEngine::Render::Objects; + +using namespace WallpaperEngine::Render::Objects::Effects; + +CMaterial::CMaterial (Irrlicht::CContext* context, Render::Objects::CEffect* effect, Core::Objects::Images::CMaterial* material) : + m_context (context), + m_effect (effect), + m_material (material) +{ + this->generatePasses (); +} + +const std::vector& CMaterial::getPasses () const +{ + return this->m_passes; +} + +const CImage* CMaterial::getImage () const +{ + return this->m_effect->getImage (); +} + +const irr::video::ITexture* CMaterial::getOutputTexture () const +{ + return this->m_outputTexture; +} + +const irr::video::ITexture* CMaterial::getInputTexture () const +{ + return this->m_inputTexture; +} + +void CMaterial::generatePasses () +{ + auto cur = this->m_material->getPasses ().begin (); + auto end = this->m_material->getPasses ().end (); + + for (; cur != end; cur ++) + { + this->m_passes.push_back ( + new CPass (this->m_context, this, *cur) + ); + } +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h new file mode 100644 index 0000000..76addfb --- /dev/null +++ b/src/WallpaperEngine/Render/Objects/Effects/CMaterial.h @@ -0,0 +1,52 @@ +#pragma once + +#include + +#include "WallpaperEngine/Core/Objects/Images/CMaterial.h" +#include "WallpaperEngine/Core/Objects/CEffect.h" + +#include "WallpaperEngine/Irrlicht/CContext.h" + +#include "WallpaperEngine/Render/Objects/Effects/CPass.h" +#include "WallpaperEngine/Render/Objects/CEffect.h" + +#include "CPass.h" + +using namespace WallpaperEngine; + +namespace WallpaperEngine::Render::Objects +{ + class CEffect; + class CImage; +} + +namespace WallpaperEngine::Render::Objects::Effects +{ + class CPass; + + class CMaterial + { + friend class CPass; + public: + CMaterial (Irrlicht::CContext* context, Render::Objects::CEffect* effect, Core::Objects::Images::CMaterial* material); + + const irr::video::ITexture* getOutputTexture () const; + const irr::video::ITexture* getInputTexture () const; + + const std::vector& getPasses () const; + const CImage* getImage () const; + + private: + void generatePasses (); + + Irrlicht::CContext* m_context; + + irr::video::ITexture* m_inputTexture; + irr::video::ITexture* m_outputTexture; + + Render::Objects::CEffect* m_effect; + Core::Objects::Images::CMaterial* m_material; + + std::vector m_passes; + }; +}; diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp new file mode 100644 index 0000000..3a4ef54 --- /dev/null +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -0,0 +1,255 @@ +#include "CPass.h" + +#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" +#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloat.h" +#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableInteger.h" +#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector2.h" +#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector3.h" +#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector4.h" +#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableFloatPointer.h" +#include "WallpaperEngine/Render/Shaders/Variables/CShaderVariableVector2Pointer.h" + +#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstant.h" +#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h" +#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h" +#include "WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector3.h" + +using namespace WallpaperEngine::Core::Objects::Effects::Constants; +using namespace WallpaperEngine::Render::Shaders::Variables; + +using namespace WallpaperEngine::Render::Objects::Effects; + +CPass::CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::Images::Materials::CPass* pass) : + m_material (material), + m_pass (pass), + m_context (context), + m_inputTexture (nullptr), + m_outputTexture (nullptr) +{ + irr::io::path vertPath = this->m_context->resolveVertexShader (pass->getShader ()); + irr::io::path fragPath = this->m_context->resolveFragmentShader (pass->getShader ()); + // register fragment shader + this->m_fragShader = new Render::Shaders::Compiler ( + this->m_context, vertPath, Render::Shaders::Compiler::Type::Type_Pixel, pass->getCombos (), false + ); + // register vertex shader + this->m_vertShader = new Render::Shaders::Compiler ( + this->m_context, fragPath, Render::Shaders::Compiler::Type::Type_Vertex, pass->getCombos (), false + ); + + // initialize material data and compile shader used for this pass + this->m_irrlichtMaterial.Wireframe = false; + this->m_irrlichtMaterial.Lighting = false; + this->m_irrlichtMaterial.setFlag (irr::video::EMF_LIGHTING, false); + this->m_irrlichtMaterial.setFlag (irr::video::EMF_BLEND_OPERATION, true); + this->m_irrlichtMaterial.MaterialType = (irr::video::E_MATERIAL_TYPE) + this->m_context->getDevice ()->getVideoDriver ()->getGPUProgrammingServices ()->addHighLevelShaderMaterial ( + this->m_vertShader->precompile ().c_str (), "main", irr::video::EVST_VS_2_0, + this->m_fragShader->precompile ().c_str (), "main", irr::video::EPST_PS_2_0, + this, irr::video::EMT_TRANSPARENT_ALPHA_CHANNEL, 0, irr::video::EGSL_DEFAULT + ); + + this->setupShaderVariables (); +} + +const irr::video::ITexture* CPass::getOutputTexture () const +{ + return this->m_outputTexture; +} + +const irr::video::ITexture* CPass::getInputTexture () const +{ + return this->m_inputTexture; +} + +const irr::video::SMaterial& CPass::getMaterial () const +{ + return this->m_irrlichtMaterial; +} + +void CPass::OnSetConstants (irr::video::IMaterialRendererServices *services, int32_t userData) +{ + irr::f32 g_Texture0 = 0; + irr::f32 g_Texture1 = 1; + irr::f32 g_Texture2 = 2; + irr::f32 g_Texture3 = 3; + irr::f32 g_Texture4 = 4; + irr::f32 g_Texture5 = 5; + irr::f32 g_Texture6 = 6; + irr::f32 g_Texture7 = 7; + + const Core::Objects::CImage* image = this->m_material->getImage ()->getImage (); + + irr::f32 g_Texture0Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z }; + irr::f32 g_Texture1Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z }; + irr::f32 g_Texture2Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z }; + irr::f32 g_Texture3Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z }; + irr::f32 g_Texture4Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z }; + irr::f32 g_Texture5Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z }; + irr::f32 g_Texture6Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z }; + irr::f32 g_Texture7Rotation [4] = { image->getAngles ().X, image->getAngles ().Y, image->getAngles ().Z, image->getAngles ().Z }; + + irr::f32 g_Texture0Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y }; + irr::f32 g_Texture1Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y }; + irr::f32 g_Texture2Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y }; + irr::f32 g_Texture3Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y }; + irr::f32 g_Texture4Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y }; + irr::f32 g_Texture5Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y }; + irr::f32 g_Texture6Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y }; + irr::f32 g_Texture7Resolution [4] = { image->getSize ().X, image->getSize ().Y, image->getSize ().X, image->getSize ().Y }; + + irr::video::IVideoDriver* driver = services->getVideoDriver (); + + irr::core::matrix4 worldViewProj; + worldViewProj = driver->getTransform (irr::video::ETS_PROJECTION); + worldViewProj *= driver->getTransform (irr::video::ETS_VIEW); + worldViewProj *= driver->getTransform (irr::video::ETS_WORLD); + + auto cur = this->m_vertShader->getParameters ().begin (); + auto end = this->m_vertShader->getParameters ().end (); + + for (; cur != end; cur ++) + { + if ((*cur)->is () == true) + { + services->setVertexShaderConstant ( + (*cur)->getName ().c_str (), + (irr::s32*) (*cur)->getValue (), + (*cur)->getSize () + ); + } + else if ( + (*cur)->is () == true || + (*cur)->is () == true || + (*cur)->is () == true || + (*cur)->is () == true) + { + services->setVertexShaderConstant ( + (*cur)->getName ().c_str (), + (irr::f32*) (*cur)->getValue (), + (*cur)->getSize () + ); + } + } + + cur = this->m_fragShader->getParameters ().begin (); + end = this->m_fragShader->getParameters ().end (); + + for (; cur != end; cur ++) + { + if ((*cur)->is () == true) + { + services->setPixelShaderConstant ( + (*cur)->getName ().c_str (), + (irr::s32*) (*cur)->getValue (), + (*cur)->getSize () + ); + } + else if ( + (*cur)->is () == true || + (*cur)->is () == true || + (*cur)->is () == true || + (*cur)->is () == true) + { + services->setPixelShaderConstant ( + (*cur)->getName ().c_str (), + (irr::f32*) (*cur)->getValue (), + (*cur)->getSize () + ); + } + } + + cur = this->m_context->getShaderVariables ().begin (); + end = this->m_context->getShaderVariables ().end (); + + for (; cur != end; cur ++) + { + if ((*cur)->is () == true) + { + services->setPixelShaderConstant ( + (*cur)->getName ().c_str (), + (irr::f32*) (*cur)->getValue (), + (*cur)->getSize () + ); + services->setVertexShaderConstant ( + (*cur)->getName ().c_str (), + (irr::f32*) (*cur)->getValue (), + (*cur)->getSize () + ); + } + } + + services->setVertexShaderConstant ("g_ModelViewProjectionMatrix", worldViewProj.pointer(), 16); + + services->setVertexShaderConstant ("g_Texture0Resolution", g_Texture0Resolution, 4); + services->setVertexShaderConstant ("g_Texture1Resolution", g_Texture1Resolution, 4); + services->setVertexShaderConstant ("g_Texture2Resolution", g_Texture2Resolution, 4); + services->setVertexShaderConstant ("g_Texture3Resolution", g_Texture3Resolution, 4); + services->setVertexShaderConstant ("g_Texture4Resolution", g_Texture4Resolution, 4); + services->setVertexShaderConstant ("g_Texture5Resolution", g_Texture5Resolution, 4); + services->setVertexShaderConstant ("g_Texture6Resolution", g_Texture6Resolution, 4); + services->setVertexShaderConstant ("g_Texture7Resolution", g_Texture7Resolution, 4); + + services->setVertexShaderConstant ("g_Texture0Rotation", g_Texture0Rotation, 4); + services->setVertexShaderConstant ("g_Texture1Rotation", g_Texture1Rotation, 4); + services->setVertexShaderConstant ("g_Texture2Rotation", g_Texture2Rotation, 4); + services->setVertexShaderConstant ("g_Texture3Rotation", g_Texture3Rotation, 4); + services->setVertexShaderConstant ("g_Texture4Rotation", g_Texture4Rotation, 4); + services->setVertexShaderConstant ("g_Texture5Rotation", g_Texture5Rotation, 4); + services->setVertexShaderConstant ("g_Texture6Rotation", g_Texture6Rotation, 4); + services->setVertexShaderConstant ("g_Texture7Rotation", g_Texture7Rotation, 4); + + services->setPixelShaderConstant ("g_Texture0", &g_Texture0, 1); + services->setPixelShaderConstant ("g_Texture1", &g_Texture1, 1); + services->setPixelShaderConstant ("g_Texture2", &g_Texture2, 1); + services->setPixelShaderConstant ("g_Texture3", &g_Texture3, 1); + services->setPixelShaderConstant ("g_Texture4", &g_Texture4, 1); + services->setPixelShaderConstant ("g_Texture5", &g_Texture5, 1); + services->setPixelShaderConstant ("g_Texture6", &g_Texture6, 1); + services->setPixelShaderConstant ("g_Texture7", &g_Texture7, 1); +} + +void CPass::setupShaderVariables () +{ + // find variables in the shaders and set the value with the constants if possible + auto cur = this->m_pass->getConstants ().begin (); + auto end = this->m_pass->getConstants ().end (); + + for (; cur != end; cur ++) + { + CShaderVariable* vertexVar = this->m_vertShader->findParameter ((*cur).first); + CShaderVariable* pixelVar = this->m_fragShader->findParameter ((*cur).first); + + if (pixelVar) + { + if (pixelVar->is () && (*cur).second->is ()) + { + pixelVar->as ()->setValue (*(*cur).second->as ()->getValue ()); + } + else if (pixelVar->is () && (*cur).second->is ()) + { + pixelVar->as ()->setValue (*(*cur).second->as ()->getValue ()); + } + else if (pixelVar->is () && (*cur).second->is ()) + { + pixelVar->as ()->setValue (*(*cur).second->as ()->getValue ()); + } + } + + if (vertexVar) + { + if (vertexVar->is () && (*cur).second->is ()) + { + vertexVar->as ()->setValue (*(*cur).second->as ()->getValue ()); + } + else if (vertexVar->is () && (*cur).second->is ()) + { + vertexVar->as ()->setValue (*(*cur).second->as ()->getValue ()); + } + else if (vertexVar->is () && (*cur).second->is ()) + { + vertexVar->as ()->setValue (*(*cur).second->as ()->getValue ()); + } + } + } +} \ No newline at end of file diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.h b/src/WallpaperEngine/Render/Objects/Effects/CPass.h new file mode 100644 index 0000000..591ed0b --- /dev/null +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.h @@ -0,0 +1,41 @@ +#pragma once + +#include + +#include "WallpaperEngine/Irrlicht/CContext.h" + +#include "WallpaperEngine/Render/Objects/Effects/CMaterial.h" +#include "WallpaperEngine/Render/Shaders/Compiler.h" + +namespace WallpaperEngine::Render::Objects::Effects +{ + class CMaterial; + + class CPass : public irr::video::IShaderConstantSetCallBack + { + public: + CPass (Irrlicht::CContext* context, CMaterial* material, Core::Objects::Images::Materials::CPass* pass); + + void OnSetConstants (irr::video::IMaterialRendererServices* services, int32_t userData) override; + + const irr::video::ITexture* getOutputTexture () const; + const irr::video::ITexture* getInputTexture () const; + + const irr::video::SMaterial& getMaterial () const; + + private: + void setupShaderVariables (); + + CMaterial* m_material; + Core::Objects::Images::Materials::CPass* m_pass; + Irrlicht::CContext* m_context; + + irr::video::ITexture* m_inputTexture; + irr::video::ITexture* m_outputTexture; + + irr::video::SMaterial m_irrlichtMaterial; + + Render::Shaders::Compiler* m_fragShader; + Render::Shaders::Compiler* m_vertShader; + }; +}