From 4e3254e843f061dcb27a16534f7b787c800a76d2 Mon Sep 17 00:00:00 2001 From: Alexis Maiquez Date: Wed, 26 Oct 2022 09:09:13 +0200 Subject: [PATCH] Improved detection of "previous" textures (fixes 2370927443) Added support for PKGV0018 Try to prevent crashing when shaders do not compile and go with whatever can be displayed Signed-off-by: Alexis Maiquez --- src/WallpaperEngine/Assets/CPackage.cpp | 3 +- .../Core/Objects/Images/CMaterial.cpp | 22 +++++++----- .../Core/Objects/Images/CMaterial.h | 8 +++-- src/WallpaperEngine/Render/CScene.cpp | 12 +++++-- src/WallpaperEngine/Render/Objects/CImage.cpp | 9 ++++- src/WallpaperEngine/Render/Objects/CImage.h | 2 ++ .../Render/Objects/Effects/CPass.cpp | 25 ++++++++----- .../Render/Shaders/Compiler.cpp | 35 +++++++++---------- 8 files changed, 75 insertions(+), 41 deletions(-) diff --git a/src/WallpaperEngine/Assets/CPackage.cpp b/src/WallpaperEngine/Assets/CPackage.cpp index e90b808..b8c8b57 100644 --- a/src/WallpaperEngine/Assets/CPackage.cpp +++ b/src/WallpaperEngine/Assets/CPackage.cpp @@ -114,7 +114,8 @@ void CPackage::validateHeader (FILE* fp) strcmp ("PKGV0013", pointer) != 0 && strcmp ("PKGV0014", pointer) != 0 && strcmp ("PKGV0015", pointer) != 0 && - strcmp ("PKGV0016", pointer) != 0) + strcmp ("PKGV0016", pointer) != 0 && + strcmp ("PKGV0018", pointer) != 0) { std::stringstream msg; msg << "Unsupported package version: " << pointer; diff --git a/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp b/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp index d94d4c9..6088e58 100644 --- a/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp +++ b/src/WallpaperEngine/Core/Objects/Images/CMaterial.cpp @@ -9,38 +9,39 @@ using namespace WallpaperEngine::Assets; using namespace WallpaperEngine::Core::Objects; using namespace WallpaperEngine::Core::Objects::Images; -CMaterial::CMaterial () : - m_target ("") +CMaterial::CMaterial (const std::string& name) : + m_target (""), + m_name (name) { } CMaterial* CMaterial::fromFile (const std::string& filename, CContainer* container) { return fromJSON ( - json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)) + filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)) ); } CMaterial* CMaterial::fromFile (const std::string& filename, const std::string& target, CContainer* container) { return fromJSON ( - json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)), target + filename, json::parse (WallpaperEngine::FileSystem::loadFullFile (filename, container)), target ); } -CMaterial* CMaterial::fromJSON (json data, const std::string& target) +CMaterial* CMaterial::fromJSON (const std::string& name, json data, const std::string& target) { - CMaterial* material = fromJSON (data); + CMaterial* material = fromJSON (name, data); material->setTarget (target); return material; } -CMaterial* CMaterial::fromJSON (json data) +CMaterial* CMaterial::fromJSON (const std::string& name, json data) { auto passes_it = jsonFindRequired (data, "passes", "Material must have at least one pass"); - CMaterial* material = new CMaterial (); + CMaterial* material = new CMaterial (name); auto cur = (*passes_it).begin (); auto end = (*passes_it).end (); @@ -84,6 +85,11 @@ const std::string& CMaterial::getTarget () const return this->m_target; } +const std::string& CMaterial::getName () const +{ + return this->m_name; +} + const bool CMaterial::hasTarget () const { return this->m_target.empty () == false; diff --git a/src/WallpaperEngine/Core/Objects/Images/CMaterial.h b/src/WallpaperEngine/Core/Objects/Images/CMaterial.h index a38cf99..952f764 100644 --- a/src/WallpaperEngine/Core/Objects/Images/CMaterial.h +++ b/src/WallpaperEngine/Core/Objects/Images/CMaterial.h @@ -15,9 +15,9 @@ namespace WallpaperEngine::Core::Objects::Images { public: static CMaterial* fromFile (const std::string& filename, CContainer* container); - static CMaterial* fromJSON (json data); + static CMaterial* fromJSON (const std::string& name, json data); static CMaterial* fromFile (const std::string& filename, const std::string& target, CContainer* container); - static CMaterial* fromJSON (json data, const std::string& target); + static CMaterial* fromJSON (const std::string& name, json data, const std::string& target); void insertPass (Materials::CPass* mass); void insertTextureBind (Effects::CBind* bind); @@ -26,13 +26,15 @@ namespace WallpaperEngine::Core::Objects::Images const std::map & getTextureBinds () const; const std::string& getTarget () const; const bool hasTarget () const; + const std::string& getName () const; protected: - CMaterial (); + CMaterial (const std::string& name); void setTarget (const std::string& target); private: std::vector m_passes; std::map m_textureBindings; std::string m_target; + std::string m_name; }; }; diff --git a/src/WallpaperEngine/Render/CScene.cpp b/src/WallpaperEngine/Render/CScene.cpp index 6089f27..8e42f47 100644 --- a/src/WallpaperEngine/Render/CScene.cpp +++ b/src/WallpaperEngine/Render/CScene.cpp @@ -46,8 +46,16 @@ CScene::CScene (Core::CScene* scene, CContainer* container, CContext* context) : for (; objectsCur != objectsEnd; objectsCur ++) { - if ((*objectsCur)->is () == true) - (*objectsCur)->as ()->setup (); + try + { + if ((*objectsCur)->is () == true) + (*objectsCur)->as ()->setup (); + } + catch (std::runtime_error ex) + { + std::cerr << "Cannot setup image resource: " << std::endl; + std::cerr << ex.what () << std::endl; + } } } diff --git a/src/WallpaperEngine/Render/Objects/CImage.cpp b/src/WallpaperEngine/Render/Objects/CImage.cpp index e01a45f..6ec01e6 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.cpp +++ b/src/WallpaperEngine/Render/Objects/CImage.cpp @@ -7,7 +7,8 @@ using namespace WallpaperEngine::Render::Objects; CImage::CImage (CScene* scene, Core::Objects::CImage* image) : Render::CObject (scene, Type, image), m_image (image), - m_texture (nullptr) + m_texture (nullptr), + m_initialized (false) { auto projection = this->getScene ()->getScene ()->getOrthogonalProjection (); @@ -219,6 +220,8 @@ void CImage::setup () for (; cur != end; cur ++) this->m_animationTime += (*cur)->frametime; + + this->m_initialized = true; } void CImage::pinpongFramebuffer (CFBO** drawTo, ITexture** asInput) @@ -341,6 +344,10 @@ void CImage::complexRender () void CImage::render () { + // do not try to render something that did not initialize successfully + if (this->m_initialized == false) + return; + // first and foremost reset the framebuffer switching this->m_currentMainFBO = this->m_mainFBO; this->m_currentSubFBO = this->m_subFBO; diff --git a/src/WallpaperEngine/Render/Objects/CImage.h b/src/WallpaperEngine/Render/Objects/CImage.h index 72a1082..f8d4b4b 100644 --- a/src/WallpaperEngine/Render/Objects/CImage.h +++ b/src/WallpaperEngine/Render/Objects/CImage.h @@ -83,5 +83,7 @@ namespace WallpaperEngine::Render::Objects Effects::CMaterial* m_copyMaterial; double m_animationTime; + + bool m_initialized; }; } diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index 235b6da..84a64a4 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -37,10 +37,8 @@ ITexture* CPass::resolveTexture (ITexture* expected, int index, ITexture* previo { auto it = this->m_fbos.find (index); - if (it == this->m_fbos.end ()) - return nullptr; - - expected = (*it).second; + if (it != this->m_fbos.end ()) + expected = (*it).second; } // first check in the binds and replace it if necessary @@ -203,7 +201,11 @@ void CPass::render (CFBO* drawTo, ITexture* input, GLuint position, GLuint texco if ((*cur).first <= lastTextureIndex) continue; - texture = this->resolveTexture ((*cur).second, (*cur).first); + texture = this->resolveTexture ((*cur).second, (*cur).first, input); + + if (texture == nullptr) + continue; + // set the active texture index glActiveTexture (GL_TEXTURE0 + (*cur).first); // bind the correct texture here @@ -221,7 +223,11 @@ void CPass::render (CFBO* drawTo, ITexture* input, GLuint position, GLuint texco if ((*cur).first <= lastTextureIndex) continue; - texture = this->resolveTexture ((*cur).second, (*cur).first); + texture = this->resolveTexture ((*cur).second, (*cur).first, input); + + if (texture == nullptr) + continue; + // set the active texture index glActiveTexture (GL_TEXTURE0 + (*cur).first); // bind the correct texture here @@ -479,7 +485,8 @@ void CPass::setupUniforms () namestream << "g_Texture" << (*cur).first << "Resolution"; texture = this->resolveTexture ((*cur).second, (*cur).first, texture); - this->addUniform (namestream.str (), texture->getResolution ()); + if (texture != nullptr) + this->addUniform (namestream.str (), texture->getResolution ()); } } @@ -498,7 +505,9 @@ void CPass::setupUniforms () namestream << "g_Texture" << (*cur).first << "Resolution"; texture = this->resolveTexture ((*cur).second, (*cur).first, texture); - this->addUniform (namestream.str (), texture->getResolution ()); + + if (texture != nullptr) + this->addUniform (namestream.str (), texture->getResolution ()); } } diff --git a/src/WallpaperEngine/Render/Shaders/Compiler.cpp b/src/WallpaperEngine/Render/Shaders/Compiler.cpp index b56192c..d78ec97 100644 --- a/src/WallpaperEngine/Render/Shaders/Compiler.cpp +++ b/src/WallpaperEngine/Render/Shaders/Compiler.cpp @@ -392,7 +392,7 @@ namespace WallpaperEngine::Render::Shaders this->m_compiledContent += "// [COMBO] " + configuration; - this->parseComboConfiguration (configuration, 1); BREAK_IF_ERROR; + this->parseComboConfiguration (configuration, 0); BREAK_IF_ERROR; } else if (this->peekString ("[COMBO_OFF]", it) == true) { @@ -478,12 +478,13 @@ namespace WallpaperEngine::Render::Shaders if (this->m_recursive == false) { // add the opengl compatibility at the top - finalCode = "#version 150\n" + finalCode = "#version 130\n" "#define highp\n" "#define mediump\n" "#define lowp\n" "#define mul(x, y) ((y) * (x))\n" "#define max(x, y) max (y, x)\n" + "#define fmod(x, y) (x-y*trunc(x/y))\n" "#define lerp mix\n" "#define frac fract\n" "#define CAST2(x) (vec2(x))\n" @@ -491,32 +492,17 @@ namespace WallpaperEngine::Render::Shaders "#define CAST4(x) (vec4(x))\n" "#define CAST3X3(x) (mat3(x))\n" "#define saturate(x) (clamp(x, 0.0, 1.0))\n" - "#define texSample2D texture2D\n" + "#define texSample2D texture\n" "#define texSample2DLod textureLod\n" "#define atan2 atan\n" "#define ddx dFdx\n" "#define ddy(x) dFdy(-(x))\n" "#define GLSL 1\n" - "#define HLSL 1\n" "#define float1 float\n" "#define float2 vec2\n" "#define float3 vec3\n" "#define float4 vec4\n"; - if (this->m_type == Type_Vertex) - { - finalCode += - "#define varying out\n" - "#define attribute in\n"; - } - else - { - finalCode += - "#define varying in\n" - "#define gl_FragColor glOutColor\n" - "out vec4 glOutColor;\n"; - } - // add combo values auto cur = this->m_combos->begin (); auto end = this->m_combos->end (); @@ -681,6 +667,19 @@ namespace WallpaperEngine::Render::Shaders ); } } + else + { + // material name is not resolved on compile time, but passes will do it after + + // extract the texture number from the name + char value = name.at (std::string("g_Texture").length ()); + // now convert it to integer + int index = value - '0'; + + this->m_textures.insert ( + std::make_pair (index, nullptr) + ); + } // samplers are not saved, we can ignore them for now return;