diff --git a/src/WallpaperEngine/Core/CObject.cpp b/src/WallpaperEngine/Core/CObject.cpp index 01c378b..fb26b50 100644 --- a/src/WallpaperEngine/Core/CObject.cpp +++ b/src/WallpaperEngine/Core/CObject.cpp @@ -68,6 +68,10 @@ CObject* CObject::fromJSON (json data, CContainer* container) if (image_it != data.end () && (*image_it).is_null () == false) { + // composelayer should be ignored for now, or artifacts will appear + if (*image_it == "models/util/composelayer.json") + return nullptr; + object = Objects::CImage::fromJSON ( data, container, diff --git a/src/WallpaperEngine/Core/Objects/CImage.cpp b/src/WallpaperEngine/Core/Objects/CImage.cpp index e6fe9d1..ec1a041 100644 --- a/src/WallpaperEngine/Core/Objects/CImage.cpp +++ b/src/WallpaperEngine/Core/Objects/CImage.cpp @@ -19,14 +19,16 @@ CImage::CImage ( std::string alignment, const glm::vec3& color, float alpha, - float brightness) : + float brightness, + uint32_t colorBlendMode) : CObject (visible, id, std::move(name), Type, origin, scale, angles), m_size (size), m_material (material), m_alignment (std::move(alignment)), m_color (color), m_alpha (alpha), - m_brightness (brightness) + m_brightness (brightness), + m_colorBlendMode (colorBlendMode) { } @@ -46,6 +48,7 @@ WallpaperEngine::Core::CObject* CImage::fromJSON ( auto alpha = jsonFindDefault (data, "alpha", 1.0); auto color_val = jsonFindDefault (data, "color", "1.0 1.0 1.0"); auto brightness_val = jsonFindDefault (data, "brightness", 1.0); + auto colorBlendMode_val = jsonFindDefault (data, "colorBlendMode", 0); json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*image_it).get (), container)); @@ -63,7 +66,8 @@ WallpaperEngine::Core::CObject* CImage::fromJSON ( alignment, WallpaperEngine::Core::aToVector3 (color_val), alpha, - brightness_val + brightness_val, + colorBlendMode_val ); } @@ -97,4 +101,9 @@ const float CImage::getBrightness () const return this->m_brightness; } +const uint32_t CImage::getColorBlendMode () const +{ + return this->m_colorBlendMode; +} + const std::string CImage::Type = "image"; \ No newline at end of file diff --git a/src/WallpaperEngine/Core/Objects/CImage.h b/src/WallpaperEngine/Core/Objects/CImage.h index c759891..8e719d3 100644 --- a/src/WallpaperEngine/Core/Objects/CImage.h +++ b/src/WallpaperEngine/Core/Objects/CImage.h @@ -34,6 +34,7 @@ namespace WallpaperEngine::Core::Objects const float getAlpha () const; const glm::vec3& getColor () const; const float getBrightness () const; + const uint32_t getColorBlendMode () const; protected: CImage ( @@ -48,7 +49,8 @@ namespace WallpaperEngine::Core::Objects std::string alignment, const glm::vec3& color, float alpha, - float brightness + float brightness, + uint32_t colorBlendMode ); static const std::string Type; @@ -60,5 +62,6 @@ namespace WallpaperEngine::Core::Objects float m_alpha; float m_brightness; glm::vec3 m_color; + uint32_t m_colorBlendMode; }; }; diff --git a/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp index 1065ce1..db6688e 100644 --- a/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp +++ b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.cpp @@ -139,6 +139,11 @@ const std::string& CPass::getDepthWrite ()const return this->m_depthwrite; } +void CPass::setBlendingMode (std::string mode) +{ + this->m_blending = mode; +} + void CPass::insertConstant (const std::string& name, CShaderConstant* constant) { this->m_constants.insert (std::pair (name, constant)); diff --git a/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h index fdd581c..fdbd851 100644 --- a/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h +++ b/src/WallpaperEngine/Core/Objects/Images/Materials/CPass.h @@ -28,6 +28,7 @@ namespace WallpaperEngine::Core::Objects::Images::Materials const std::string& getCullingMode () const; const std::string& getDepthTest () const; const std::string& getDepthWrite () const; + void setBlendingMode (std::string mode); void insertCombo (const std::string& name, int value); void insertConstant (const std::string& name, Effects::Constants::CShaderConstant* constant); diff --git a/src/WallpaperEngine/Render/CScene.cpp b/src/WallpaperEngine/Render/CScene.cpp index 13f9779..3397260 100644 --- a/src/WallpaperEngine/Render/CScene.cpp +++ b/src/WallpaperEngine/Render/CScene.cpp @@ -39,6 +39,11 @@ CScene::CScene (Core::CScene* scene, CContainer* container, CContext* context) : scene->getOrthogonalProjection ()->getHeight () ); + // set clear color + FloatColor clearColor = this->getScene ()->getClearColor (); + + glClearColor (clearColor.r, clearColor.g, clearColor.b, 1.0f); + // setup framebuffers this->setupFramebuffers (); @@ -136,21 +141,15 @@ void CScene::renderFrame (glm::ivec4 viewport) // ensure the virtual mouse position is up to date this->updateMouse (viewport); - // clear screen - FloatColor clearColor = this->getScene ()->getClearColor (); - - glClearColor (clearColor.r, clearColor.g, clearColor.b, 0.0f); - // use the scene's framebuffer by default glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer()); // ensure we render over the whole screen glViewport (0, 0, projection->getWidth (), projection->getHeight ()); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + for (; cur != end; cur ++) (*cur)->render (); - - // ensure we render over the whole screen - glViewport (0, 0, projection->getWidth (), projection->getHeight ()); } void CScene::updateMouse (glm::ivec4 viewport) diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index edb8df1..80f470d 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -94,8 +94,8 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) : this->m_texture->getRealWidth (), this->m_texture->getRealHeight () ); - GLfloat realWidth = this->m_texture->getRealWidth () / 2; - GLfloat realHeight = this->m_texture->getRealHeight () / 2; + GLfloat realWidth = this->m_texture->getRealWidth () / 2.0f; + GLfloat realHeight = this->m_texture->getRealHeight () / 2.0f; // build a list of vertices, these might need some change later (or maybe invert the camera) GLfloat sceneSpacePosition [] = { @@ -216,12 +216,24 @@ void CImage::setup () if (this->m_initialized) return; - // generate the main material used to render the image - this->m_material = new Effects::CMaterial ( - new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)), - this->m_image->getMaterial () - ); + // TODO: SUPPORT PASSTHROUGH (IT'S A SHADER) + { + // generate the main material used to render the image + this->m_material = new Effects::CMaterial ( + new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)), + this->m_image->getMaterial () + ); + + // add blendmode to the combos + auto cur = this->m_material->getPasses ().begin (); + auto end = this->m_material->getPasses ().end (); + + for (; cur != end; cur ++) + this->m_passes.push_back (*cur); + } + + // prepare the passes list if (this->getImage ()->getEffects ().empty () == false) { // generate the effects used by this material @@ -229,19 +241,10 @@ void CImage::setup () auto end = this->getImage ()->getEffects ().end (); for (; cur != end; cur ++) - this->m_effects.emplace_back (new CEffect (this, *cur)); - } - - // prepare the passes list - if (this->getEffects ().empty () == false) - { - auto effectCur = this->getEffects ().begin (); - auto effectEnd = this->getEffects ().end (); - - for (; effectCur != effectEnd; effectCur ++) { - auto materialCur = (*effectCur)->getMaterials ().begin (); - auto materialEnd = (*effectCur)->getMaterials ().end (); + auto effect = new CEffect (this, *cur); + auto materialCur = effect->getMaterials ().begin (); + auto materialEnd = effect->getMaterials ().end (); for (; materialCur != materialEnd; materialCur ++) { @@ -251,27 +254,52 @@ void CImage::setup () for (; passCur != passEnd; passCur ++) this->m_passes.push_back (*passCur); } + + this->m_effects.push_back (effect); } } - // add the final passes too - if (this->m_material->getPasses ().empty () == false) + if (this->m_image->getColorBlendMode () > 0) { - auto cur = this->m_material->getPasses ().begin (); - auto end = this->m_material->getPasses ().end (); + auto material = Core::Objects::Images::CMaterial::fromFile ("materials/util/effectpassthrough.json", this->getContainer ()); + + // effectpasshthrough only has one pass + (*material->getPasses ().begin ())->insertCombo ("BLENDMODE", this->m_image->getColorBlendMode ()); + + // generate the main material used to render the image + this->m_colorBlendMaterial = new Effects::CMaterial( + new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)), + material + ); + + // add blendmode to the combos + auto cur = this->m_colorBlendMaterial->getPasses ().begin (); + auto end = this->m_colorBlendMaterial->getPasses ().end (); for (; cur != end; cur ++) this->m_passes.push_back (*cur); } - // calculate full animation time (if any) - this->m_animationTime = 0.0f; + // if there's more than one pass the blendmode has to be moved from the beginning to the end + if (this->m_passes.size () > 1) + { + auto first = this->m_passes.begin (); + auto last = this->m_passes.rbegin (); - auto cur = this->getTexture ()->getFrames ().begin (); - auto end = this->getTexture ()->getFrames ().end (); + (*last)->getPass ()->setBlendingMode ((*first)->getPass ()->getBlendingMode ()); + (*first)->getPass ()->setBlendingMode ("normal"); + } - for (; cur != end; cur ++) - this->m_animationTime += (*cur)->frametime; + { + // calculate full animation time (if any) + this->m_animationTime = 0.0f; + + auto cur = this->getTexture ()->getFrames ().begin (); + auto end = this->getTexture ()->getFrames ().end (); + + for (; cur != end; cur++) + this->m_animationTime += (*cur)->frametime; + } this->m_initialized = true; } @@ -299,8 +327,8 @@ void CImage::render () return; // reset the framebuffers so the drawing always happens on the same order - this->m_currentMainFBO = this->m_subFBO; - this->m_currentSubFBO = this->m_mainFBO; + this->m_currentMainFBO = this->m_mainFBO; + this->m_currentSubFBO = this->m_subFBO; glColorMask (true, true, true, true); @@ -334,12 +362,8 @@ void CImage::render () } // determine if it's the last element in the list as this is a screen-copy-like process - else if (std::next (cur) == end) + else if (std::next (cur) == end && this->getImage ()->isVisible () == true) { - // do not draw to screen if the image is not visible - if (this->getImage ()->isVisible () == false) - return; - spacePosition = *this->getSceneSpacePosition (); drawTo = this->getScene ()->getFBO (); projection = this->m_modelViewProjectionScreen; diff --git a/src/WallpaperEngine/Render/Objects/CImage.h b/src/WallpaperEngine/Render/Objects/CImage.h index 7717ae2..9766245 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.h +++ b/src/WallpaperEngine/Render/Objects/CImage.h @@ -79,6 +79,7 @@ namespace WallpaperEngine::Render::Objects std::vector m_effects; Effects::CMaterial* m_material; + Effects::CMaterial* m_colorBlendMaterial; std::vector m_passes; double m_animationTime; diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index a517d6b..be29203 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -289,6 +289,11 @@ const CMaterial* CPass::getMaterial () const return this->m_material; } +Core::Objects::Images::Materials::CPass* CPass::getPass () +{ + return this->m_pass; +} + GLuint CPass::compileShader (Render::Shaders::Compiler* shader, GLuint type) { // reserve shaders in OpenGL @@ -464,6 +469,7 @@ void CPass::setupUniforms () if (bindCur != bindEnd) { this->m_finalTextures.insert (std::make_pair ((*bindCur).first, nullptr)); + bindCur ++; } if (cur != end) @@ -472,26 +478,66 @@ void CPass::setupUniforms () this->m_finalTextures.insert (std::make_pair (index, *cur)); index ++; - } - - if (fragCur != fragEnd && (*fragCur).second != nullptr) - { - this->m_finalTextures.insert (std::make_pair ((*fragCur).first, (*fragCur).second)); - } - - if (vertCur != vertEnd && (*vertCur).second != nullptr) - { - this->m_finalTextures.insert (std::make_pair ((*vertCur).first, (*vertCur).second)); - } - - if (bindCur != bindEnd) - bindCur ++; - if (cur != end) cur ++; + } + if (fragCur != fragEnd) + { + std::string textureName = (*fragCur).second; + + try + { + // resolve the texture first + ITexture* textureRef = nullptr; + + if (textureName.find ("_rt_") == 0) + { + textureRef = this->getMaterial ()->getEffect ()->findFBO (textureName); + + if (textureRef == nullptr) + textureRef = this->getMaterial ()->getImage ()->getScene ()->findFBO (textureName); + } + else + textureRef = this->getMaterial ()->getImage ()->getContainer ()->readTexture (textureName); + + this->m_finalTextures.insert (std::make_pair ((*fragCur).first, textureRef)); + } + catch (std::runtime_error& ex) + { + std::cerr << "Cannot resolve texture " << textureName << " for fragment shader: " << ex.what () << std::endl; + } + fragCur ++; + } + if (vertCur != vertEnd) + { + std::string textureName = (*vertCur).second; + + try + { + // resolve the texture first + ITexture* textureRef = nullptr; + + if (textureName.find ("_rt_") == 0) + { + textureRef = this->getMaterial ()->getEffect ()->findFBO (textureName); + + if (textureRef == nullptr) + textureRef = this->getMaterial ()->getImage ()->getScene ()->findFBO (textureName); + } + else + textureRef = this->getMaterial ()->getImage ()->getContainer ()->readTexture (textureName); + + this->m_finalTextures.insert (std::make_pair ((*vertCur).first, textureRef)); + } + catch (std::runtime_error& ex) + { + std::cerr << "Cannot resolve texture " << textureName << " for vertex shader: " << ex.what () << std::endl; + } + vertCur ++; + } } } diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.h b/src/WallpaperEngine/Render/Objects/Effects/CPass.h index fb31c1e..0ab2f22 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.h +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.h @@ -24,6 +24,7 @@ namespace WallpaperEngine::Render::Objects::Effects void render (CFBO* drawTo, ITexture* input, GLuint position, GLuint texcoord, glm::mat4 projection); const CMaterial* getMaterial () const; + Core::Objects::Images::Materials::CPass* getPass (); private: enum UniformType diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.cpp b/src/WallpaperEngine/Render/Shaders/Compiler.cpp index da3782c..87b2b80 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.cpp +++ b/src/WallpaperEngine/Render/Shaders/Compiler.cpp @@ -711,47 +711,10 @@ namespace WallpaperEngine::Render::Shaders this->m_foundCombos->insert (std::make_pair (*combo, true)); } - if (textureName != data.end ()) - { - // also ensure that the textureName is loaded and we know about it - ITexture* texture = this->m_container->readTexture ((*textureName).get ()); - - this->m_textures.insert ( - std::make_pair (index, texture) - ); - } } - else - { - // check for texture name too - if (textureName != data.end ()) - { - try - { - // also ensure that the textureName is loaded and we know about it - ITexture* texture = this->m_container->readTexture ((*textureName).get ()); - this->m_textures.insert ( - std::make_pair (index, texture) - ); - } - catch (CAssetLoadException& ex) - { - // cannot resolve texture - // TODO: TAKE CARE OF FBOS - this->m_textures.insert ( - std::make_pair (index, nullptr) - ); - } - } - else - { - this->m_textures.insert ( - std::make_pair (index, nullptr) - ); - } - - } + if (textureName != data.end ()) + this->m_textures.insert (std::make_pair (index, *textureName)); // samplers are not saved, we can ignore them for now return; @@ -798,7 +761,7 @@ namespace WallpaperEngine::Render::Shaders return this->m_combos; } - const std::map & Compiler::getTextures () const + const std::map & Compiler::getTextures () const { return this->m_textures; } diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.h b/src/WallpaperEngine/Render/Shaders/Compiler.h index 710a113..bcbd4a5 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.h +++ b/src/WallpaperEngine/Render/Shaders/Compiler.h @@ -91,7 +91,7 @@ namespace WallpaperEngine::Render::Shaders /** * @return The list of textures inferred from the shader's code */ - const std::map & getTextures () const; + const std::map & getTextures () const; private: /** @@ -263,7 +263,7 @@ namespace WallpaperEngine::Render::Shaders /** * List of textures that the shader expects (inferred from sampler2D and it's JSON data) */ - std::map m_textures; + std::map m_textures; bool m_includesProcessed = false; }; }