Parcourir la source

Upgraded to shader version 330
Added support for shader patches
Removed useless DEBUG define in favour of NDEBUG

Signed-off-by: Alexis Maiquez <almamu@almamu.com>

Alexis Maiquez il y a 3 ans
Parent
commit
37631e9c40

+ 14 - 2
CMakeLists.txt

@@ -4,10 +4,16 @@ project(linux-wallpaperengine)
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
 set(OpenGL_GL_PREFERENCE "LEGACY")
+set(DATADIR ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME})
+set(PATCHESDIR ${DATADIR}/patches/)
+
+if(NOT ERRORONLY)
+    set(ERRORONLY 0)
+endif()
 
 # if you're developing you might find this debug option useful for shader output, although RenderDoc is encouraged
-add_compile_definitions(DEBUG=1)
-add_compile_definitions(ERRORONLY=1)
+add_compile_definitions(ERRORONLY=${ERRORONLY})
+add_compile_definitions(DATADIR="${DATADIR}")
 
 find_package(X11 REQUIRED)
 find_package(Xrandr REQUIRED)
@@ -254,4 +260,10 @@ check_function_exists(XSetIOErrorExitHandler HAVE_XSETIOERROREXITHANDLER)
 
 if(HAVE_XSETIOERROREXITHANDLER)
     add_compile_definitions(HAVE_XSETIOERROREXITHANDLER=1)
+endif()
+
+# set some install parameters if not in debug mode
+if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
+    install(TARGETS linux-wallpaperengine)
+    install(DIRECTORY share/ DESTINATION share/${PROJECT_NAME})
 endif()

+ 13 - 0
share/patches/vhstest.vert.json

@@ -0,0 +1,13 @@
+{
+  "patches": [
+    {
+      "matches": [
+        "uniform float g_Chromatic;",
+        "g_AudioSpectrum16Left[g_Chromatic]"
+      ],
+      "replacements": {
+        "g_AudioSpectrum16Left[g_Chromatic]": "g_AudioSpectrum16Left[int(g_Chromatic)]"
+      }
+    }
+  ]
+}

+ 5 - 0
src/WallpaperEngine/Application/CWallpaperApplication.cpp

@@ -34,6 +34,11 @@ void CWallpaperApplication::setupContainer ()
     this->m_vfs.addPkg (std::filesystem::path (this->m_context.background) / "scene.pkg");
     this->m_vfs.addPkg (std::filesystem::path (this->m_context.background) / "gifscene.pkg");
     this->m_vfs.add (new CDirectory (this->m_context.assets));
+#if !NDEBUG
+	this->m_vfs.add (new CDirectory ("../share/"));
+#else
+	this->m_vfs.add (new CDirectory (DATADIR));
+#endif /* DEBUG */
 
     // TODO: move this somewhere else?
     CVirtualContainer* container = new CVirtualContainer ();

+ 16 - 12
src/WallpaperEngine/Assets/CContainer.cpp

@@ -18,9 +18,9 @@ const ITexture* CContainer::readTexture (std::string filename) const
 
     ITexture* result = new CTexture (textureContents);
 
-#if DEBUG
+#if !NDEBUG
         glObjectLabel (GL_TEXTURE, result->getTextureID (), -1, filename.c_str ());
-#endif /* DEBUG */
+#endif /* NDEBUG */
 
     return result;
 }
@@ -33,21 +33,25 @@ std::string CContainer::readShader (const std::string& filename) const
 	if (*it++ == "workshop")
 	{
 		std::filesystem::path workshopId = *it++;
-		std::filesystem::path shaderfile = *++it;
 
-		try
+		if (++it != shader.end ())
 		{
-			shader = std::filesystem::path ("zcompat") / "scene" / "shaders" / workshopId / shaderfile;
-			// replace the old path with the new one
-			std::string contents = this->readFileAsString (shader);
+			std::filesystem::path shaderfile = *it;
 
-			sLog.out ("Replaced ", filename, " with compat ", shader);
+			try
+			{
+				shader = std::filesystem::path ("zcompat") / "scene" / "shaders" / workshopId / shaderfile;
+				// replace the old path with the new one
+				std::string contents = this->readFileAsString (shader);
 
-			return contents;
-		}
-		catch (CAssetLoadException&)
-		{
+				sLog.out ("Replaced ", filename, " with compat ", shader);
+
+				return contents;
+			}
+			catch (CAssetLoadException&)
+			{
 
+			}
 		}
 	}
 

+ 0 - 1
src/WallpaperEngine/Assets/CContainer.h

@@ -64,7 +64,6 @@ namespace WallpaperEngine::Assets
          */
         std::string readIncludeShader (const std::string& filename) const;
 
-    private:
         /**
          * Reads a file as string
          *

+ 2 - 2
src/WallpaperEngine/Logging/CLog.h

@@ -35,7 +35,7 @@ namespace WallpaperEngine::Logging
         template<typename... Data>
         void debug (Data... data)
         {
-#if DEBUG && !ERRORONLY
+#if (!NDEBUG) && (!ERRORONLY)
             // buffer the string first
             std::stringbuf buffer;
             std::ostream bufferStream (&buffer);
@@ -51,7 +51,7 @@ namespace WallpaperEngine::Logging
         template<typename... Data>
         void debugerror (Data... data)
         {
-#if DEBUG && ERRORONLY
+#if (!NDEBUG) && (ERRORONLY)
             // buffer the string first
             std::stringbuf buffer;
             std::ostream bufferStream (&buffer);

+ 2 - 2
src/WallpaperEngine/Render/CFBO.cpp

@@ -32,8 +32,8 @@ CFBO::CFBO (
     // give OpenGL an empty image
     glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
     // label stuff for debugging
-#if DEBUG
-        glObjectLabel (GL_TEXTURE, this->m_texture, -1, this->m_name.c_str ());
+#if !NDEBUG
+	glObjectLabel (GL_TEXTURE, this->m_texture, -1, this->m_name.c_str ());
 #endif /* DEBUG */
     // set filtering parameters, otherwise the texture is not rendered
     if (flags & TextureFlags::ClampUVs)

+ 5 - 7
src/WallpaperEngine/Render/CRenderContext.cpp

@@ -23,7 +23,7 @@ void CustomXIOErrorExitHandler (Display* dsp, void* userdata)
 {
     auto context = static_cast <CRenderContext*> (userdata);
 
-#ifdef DEBUG
+#if !NDEBUG
     sLog.debugerror ("Critical XServer error detected. Attempting to recover...");
 #endif /* DEBUG */
 
@@ -33,7 +33,7 @@ void CustomXIOErrorExitHandler (Display* dsp, void* userdata)
 
 int CustomXErrorHandler (Display* dpy, XErrorEvent* event)
 {
-#ifdef DEBUG
+#if !NDEBUG
     sLog.debugerror ("Detected X error");
 #endif /* DEBUG */
 
@@ -45,7 +45,7 @@ int CustomXErrorHandler (Display* dpy, XErrorEvent* event)
 
 int CustomXIOErrorHandler (Display* dsp)
 {
-#ifdef DEBUG
+#if !NDEBUG
     sLog.debugerror ("Detected X error");
 #endif /* DEBUG */
 
@@ -188,7 +188,7 @@ void CRenderContext::renderScreens ()
 
     for (const auto& cur : this->m_viewports)
     {
-#if DEBUG
+#if !NDEBUG
 		std::string str = "Rendering to screen " + cur.name;
 
 		glPushDebugGroup (GL_DEBUG_SOURCE_APPLICATION, 0, -1, str.c_str ());
@@ -199,9 +199,7 @@ void CRenderContext::renderScreens ()
         // scenes need to render a new frame for each viewport as they produce different results
         // but videos should only be rendered once per group of viewports
         firstFrame = false;
-        renderFrame = !this->m_wallpaper->is <CVideo> ();
-
-#if DEBUG
+#if !NDEBUG
 		glPopDebugGroup ();
 #endif /* DEBUG */
     }

+ 10 - 7
src/WallpaperEngine/Render/CWallpaper.cpp

@@ -87,10 +87,11 @@ void CWallpaper::setupShaders ()
     GLuint vertexShaderID = glCreateShader (GL_VERTEX_SHADER);
 
     // give shader's source code to OpenGL to be compiled
-    const char* sourcePointer = "#version 120\n"
-                                "attribute vec3 a_Position;\n"
-                                "attribute vec2 a_TexCoord;\n"
-                                "varying vec2 v_TexCoord;\n"
+    const char* sourcePointer = "#version 330\n"
+								"precision highp float;\n"
+                                "in vec3 a_Position;\n"
+                                "in vec2 a_TexCoord;\n"
+                                "out vec2 v_TexCoord;\n"
                                 "void main () {\n"
                                 "gl_Position = vec4 (a_Position, 1.0);\n"
                                 "v_TexCoord = a_TexCoord;\n"
@@ -125,11 +126,13 @@ void CWallpaper::setupShaders ()
     GLuint fragmentShaderID = glCreateShader (GL_FRAGMENT_SHADER);
 
     // give shader's source code to OpenGL to be compiled
-    sourcePointer = "#version 120\n"
+    sourcePointer = "#version 330\n"
+					"precision highp float;\n"
                     "uniform sampler2D g_Texture0;\n"
-                    "varying vec2 v_TexCoord;\n"
+                    "in vec2 v_TexCoord;\n"
+					"out vec4 out_FragColor;\n"
                     "void main () {\n"
-                    "gl_FragColor = texture2D (g_Texture0, v_TexCoord);\n"
+                    "out_FragColor = texture (g_Texture0, v_TexCoord);\n"
                     "}";
 
     glShaderSource (fragmentShaderID, 1, &sourcePointer, nullptr);

+ 1 - 1
src/WallpaperEngine/Render/Drivers/COpenGLDriver.cpp

@@ -18,7 +18,7 @@ COpenGLDriver::COpenGLDriver (const char* windowTitle) :
     glfwWindowHint (GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
     glfwWindowHint (GLFW_VISIBLE, GLFW_FALSE);
 
-#if DEBUG
+#if !NDEBUG
 	glfwWindowHint (GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);
 #endif /* DEBUG */
 

+ 4 - 3
src/WallpaperEngine/Render/Objects/CImage.cpp

@@ -102,6 +102,7 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
     // register both FBOs into the scene
     std::ostringstream nameA, nameB;
 
+	// TODO: determine when _rt_imageLayerComposite and _rt_imageLayerAlbedo is used
     nameA << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_a";
     nameB << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_b";
 
@@ -395,7 +396,7 @@ void CImage::render ()
     if (this->getScene ()->getScene ()->isCameraParallax ())
         this->updateScreenSpacePosition ();
 
-#if DEBUG
+#if !NDEBUG
 	std::string str = "Rendering ";
 
 	if (this->getScene ()->getScene ()->isBloom () && this->getId () == 0xFFFFFFFF)
@@ -421,8 +422,8 @@ void CImage::render ()
         (*cur)->render ();
     }
 
-#if DEBUG
-        glPopDebugGroup ();
+#if !NDEBUG
+	glPopDebugGroup ();
 #endif /* DEBUG */
 }
 

+ 2 - 2
src/WallpaperEngine/Render/Objects/Effects/CPass.cpp

@@ -246,7 +246,7 @@ void CPass::render ()
         glBindBuffer (GL_ARRAY_BUFFER, *cur->value);
         glVertexAttribPointer (cur->id, cur->elements, cur->type, GL_FALSE, 0, nullptr);
 
-#if DEBUG
+#if !NDEBUG
 		glObjectLabel (GL_BUFFER, *cur->value, -1, (
 				"Image " + std::to_string (this->getMaterial ()->getImage ()->getId ()) +
 				" Pass " + this->m_pass->getShader() +
@@ -429,7 +429,7 @@ void CPass::setupShaders ()
         sLog.exception (message);
     }
 
-#if DEBUG
+#if !NDEBUG
 	glObjectLabel (GL_PROGRAM, this->m_programID, -1, this->m_pass->getShader ().c_str ());
 	glObjectLabel (GL_SHADER, vertexShaderID, -1, (this->m_pass->getShader () + ".vert").c_str ());
 	glObjectLabel (GL_SHADER, fragmentShaderID, -1, (this->m_pass->getShader () + ".frag").c_str ());

+ 125 - 12
src/WallpaperEngine/Render/Shaders/Compiler.cpp

@@ -12,6 +12,8 @@
 #include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantVector4.h>
 #include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantInteger.h>
 #include <WallpaperEngine/Core/Objects/Effects/Constants/CShaderConstantFloat.h>
+#include <regex>
+#include <filesystem>
 
 #include "WallpaperEngine/Assets/CAssetLoadException.h"
 #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h"
@@ -498,17 +500,14 @@ namespace WallpaperEngine::Render::Shaders
         if (!this->m_recursive)
         {
             // add the opengl compatibility at the top
-            finalCode =   "#version 150\n"
+            finalCode =   "#version 330\n"
                           "// ======================================================\n"
                           "// Processed shader " + this->m_file + "\n"
                           "// ======================================================\n"
-                          "#define highp\n"
-                          "#define mediump\n"
-                          "#define lowp\n"
+                          "precision highp float;\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 max(x, y) max (y, x)\n"
+						  "#define lerp mix\n"
                           "#define frac fract\n"
                           "#define CAST2(x) (vec2(x))\n"
                           "#define CAST3(x) (vec3(x))\n"
@@ -518,13 +517,21 @@ namespace WallpaperEngine::Render::Shaders
                           "#define texSample2D texture\n"
                           "#define texSample2DLod textureLod\n"
                           "#define atan2 atan\n"
+						  "#define fmod(x, y) ((x)-(y)*trunc((x)/(y)))\n"
                           "#define ddx dFdx\n"
                           "#define ddy(x) dFdy(-(x))\n"
-                          "#define GLSL 1\n"
-                          "#define float1 float\n"
-                          "#define float2 vec2\n"
-                          "#define float3 vec3\n"
-                          "#define float4 vec4\n\n";
+                          "#define GLSL 1\n\n";
+
+			if (this->m_type == Type_Vertex)
+			{
+				finalCode += "#define attribute in\n"
+							 "#define varying out\n";
+			}
+			else
+			{
+				finalCode += "out vec4 out_FragColor;\n"
+							 "#define varying in\n";
+			}
 
             finalCode +=  "// ======================================================\n"
                           "// Shader combo parameter definitions\n"
@@ -551,8 +558,69 @@ namespace WallpaperEngine::Render::Shaders
 
                 finalCode += "#define " + cur.first + " " + std::to_string (cur.second) + "\n";
             }
+
+			// define to 0 everything else found in the code
+			std::regex ifs ("#if ([A-Za-z0-9_]+)");
+			auto words_begin = std::sregex_iterator (this->m_compiledContent.begin (), this->m_compiledContent.end (), ifs);
+			auto words_end = std::sregex_iterator ();
+			std::map <std::string, bool> inserted;
+
+			for (; words_begin != words_end; words_begin ++)
+			{
+				std::string define = (*words_begin).str ().substr (4);
+
+				if (
+					this->m_foundCombos->find (define) != this->m_foundCombos->end () ||
+					this->m_baseCombos.find (define) != this->m_baseCombos.end () ||
+					inserted.find (define) != inserted.end ())
+					continue;
+
+				finalCode += "#define " + define + " 0\n";
+			}
         }
 
+		// replace gl_FragColor with the equivalent
+		std::string from = "gl_FragColor";
+		std::string to = "out_FragColor";
+
+		size_t start_pos = 0;
+		while((start_pos = this->m_compiledContent.find(from, start_pos)) != std::string::npos) {
+			this->m_compiledContent.replace(start_pos, from.length(), to);
+			start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
+		}
+
+		// replace sample occurrences
+		from = "sample";
+		to = "_sample";
+
+		start_pos = 0;
+		while((start_pos = this->m_compiledContent.find(from, start_pos)) != std::string::npos) {
+			// ensure that after it comes something like a space or a ; or a tab
+			std::string after = this->m_compiledContent.substr (start_pos + from.length (), 1);
+
+			if (
+				after != " " && after != ";" && after != "\t" &&
+				after != "=" && after != "+" && after != "-" &&
+				after != "/" && after != "*" && after != "." &&
+				after != "," && after != ")")
+			{
+				start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
+				continue;
+			}
+
+			this->m_compiledContent.replace(start_pos, from.length(), to);
+			start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
+		}
+
+		try
+		{
+			this->applyPatches ();
+		}
+		catch (CAssetLoadException&)
+		{
+			// nothing important, no patch was found
+		}
+
         finalCode += this->m_compiledContent;
 
         if (!this->m_recursive)
@@ -566,6 +634,51 @@ namespace WallpaperEngine::Render::Shaders
     #undef BREAK_IF_ERROR
     }
 
+	void Compiler::applyPatches ()
+	{
+		// small patches for things, looks like the official wpengine does the same thing
+		std::filesystem::path file = this->m_file;
+		file = "patches" / file.filename ();
+
+		if (this->m_type == Type_Vertex)
+			file += ".vert";
+		else if (this->m_type == Type_Pixel)
+			file += ".frag";
+
+		file += ".json";
+
+		std::string tmp = file;
+		std::string patchContents = this->m_container.readFileAsString (file);
+
+		json data = json::parse (patchContents);
+		auto patches = data.find ("patches");
+
+		for (auto patch : *patches)
+		{
+			auto matches = patch.find ("matches");
+
+			// check for matches first, as these signal whether the patch can be applied or not
+			for (const auto& match : *matches)
+				if (this->m_compiledContent.find (match) == std::string::npos)
+					continue;
+
+			auto replacements = patch.find ("replacements");
+
+			for (const auto& replacement : (*replacements).items ())
+			{
+				// replace gl_FragColor with the equivalent
+				std::string from = replacement.key ();
+				std::string to = replacement.value ();
+
+				size_t start_pos = 0;
+				while((start_pos = this->m_compiledContent.find(from, start_pos)) != std::string::npos) {
+					this->m_compiledContent.replace(start_pos, from.length(), to);
+					start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
+				}
+			}
+		}
+	}
+
     void Compiler::parseComboConfiguration (const std::string& content, int defaultValue)
     {
         json data = json::parse (content);

+ 5 - 0
src/WallpaperEngine/Render/Shaders/Compiler.h

@@ -199,6 +199,11 @@ namespace WallpaperEngine::Render::Shaders
          * @param content The parameter configuration
          */
         void parseParameterConfiguration (const std::string& type, const std::string& name, const std::string& content);
+		/**
+		 * Applies any available patches for this shader
+		 */
+		void applyPatches ();
+
         /**
          * The shader file this instance is loading
          */