mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-14 05:12:25 +08:00
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>
This commit is contained in:
parent
4e0f02f64d
commit
37631e9c40
@ -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
share/patches/vhstest.vert.json
Normal file
13
share/patches/vhstest.vert.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"patches": [
|
||||
{
|
||||
"matches": [
|
||||
"uniform float g_Chromatic;",
|
||||
"g_AudioSpectrum16Left[g_Chromatic]"
|
||||
],
|
||||
"replacements": {
|
||||
"g_AudioSpectrum16Left[g_Chromatic]": "g_AudioSpectrum16Left[int(g_Chromatic)]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -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 ();
|
||||
|
@ -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&)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,6 @@ namespace WallpaperEngine::Assets
|
||||
*/
|
||||
std::string readIncludeShader (const std::string& filename) const;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Reads a file as string
|
||||
*
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
|
@ -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 ());
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user