From 7613bf254ac319fac15f1605c95c38a026e8d116 Mon Sep 17 00:00:00 2001 From: Alexis Maiquez Date: Wed, 1 Sep 2021 01:27:01 +0200 Subject: [PATCH] ~ updated readme to reflect current status + added texture resolution to CTexture so it can be properly used in the CPass + framebuffer textures now have filtering specified (prevents black screen), still need to adjust information about the texture + added proper uniform variable registration to ease the usage Signed-off-by: Alexis Maiquez --- README.md | 10 +- src/WallpaperEngine/Assets/CTexture.cpp | 12 + src/WallpaperEngine/Assets/CTexture.h | 3 + src/WallpaperEngine/Render/CWallpaper.cpp | 12 + .../Render/Objects/Effects/CPass.cpp | 250 +++++++++++++----- .../Render/Objects/Effects/CPass.h | 51 +++- 6 files changed, 261 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index d2d5a75..09ba51c 100644 --- a/README.md +++ b/README.md @@ -30,11 +30,7 @@ Once Wallpaper Engine is downloaded open the installation folder (usually on C:\ ![folder](docs/images/screenshot_folder.png) -All the folders we see must be compressed in a single zip file for the project to load them: - -![compression](docs/images/zip.png) - -The zip must be named "assets.zip" and placed on the same folder as the directory where the project is going to be run from. +The assets folder itself can be copied to the same folder where the binary lives. ## 5.3. Compilation steps The project is built on CMake as build engine. First we need to create the directory where the build will be stored and get into it: @@ -55,7 +51,7 @@ Finally we can compile the project to generate the actual executable make ``` -**REMEMBER: The assets.zip file has to be at the same folder as the executable** +**REMEMBER: The assets folder has to be at the same folder as the executable** ## 5.4. Running a background Currently both compressed and uncompressed backgrounds are supported. @@ -72,7 +68,7 @@ Uncompressed backgrounds are just plain folders including all the resources and ./wallengine --dir folder ``` -#### 5.4.3. Running as a screen's background +#### 5.4.3. Running as a screen's background (NOT SUPPORTED IN THIS BUILD YET) Only screens configured with the XRandr extension are supported. To specify the screen names (as reported from xrandr tool) just use the ```--screen-root``` switch. You can specify multiple screens at the same time, for example: ``` ./wallengine --screen-root HDMI-1 --screen-root DVI-D-1 diff --git a/src/WallpaperEngine/Assets/CTexture.cpp b/src/WallpaperEngine/Assets/CTexture.cpp index 6a9ab26..955a2af 100644 --- a/src/WallpaperEngine/Assets/CTexture.cpp +++ b/src/WallpaperEngine/Assets/CTexture.cpp @@ -14,6 +14,13 @@ CTexture::CTexture (void* fileData) if (this->m_header->freeImageFormat != FREE_IMAGE_FORMAT::FIF_UNKNOWN) throw std::runtime_error ("Normal images are not supported yet"); + // set the texture resolution + // TODO: SUPPORT SPRITES + this->m_resolution = { + this->m_header->width, this->m_header->height, + this->m_header->textureWidth, this->m_header->textureHeight + }; + GLint formatGL; // detect the image format and hand it to openGL to be used @@ -120,6 +127,11 @@ const CTexture::TextureHeader* CTexture::getHeader () const return this->m_header; } +const glm::vec4* CTexture::getResolution () const +{ + return &this->m_resolution; +} + CTexture::TextureMipmap::TextureMipmap () { } diff --git a/src/WallpaperEngine/Assets/CTexture.h b/src/WallpaperEngine/Assets/CTexture.h index fadcc20..c77da1c 100644 --- a/src/WallpaperEngine/Assets/CTexture.h +++ b/src/WallpaperEngine/Assets/CTexture.h @@ -5,6 +5,7 @@ #include #include +#include namespace WallpaperEngine::Assets { @@ -143,6 +144,7 @@ namespace WallpaperEngine::Assets const GLuint getTextureID () const; const TextureHeader* getHeader () const; + const glm::vec4* getResolution () const; private: @@ -151,5 +153,6 @@ namespace WallpaperEngine::Assets TextureHeader* m_header; GLuint m_textureID; + glm::vec4 m_resolution; }; } \ No newline at end of file diff --git a/src/WallpaperEngine/Render/CWallpaper.cpp b/src/WallpaperEngine/Render/CWallpaper.cpp index a2014d1..49b04cc 100644 --- a/src/WallpaperEngine/Render/CWallpaper.cpp +++ b/src/WallpaperEngine/Render/CWallpaper.cpp @@ -61,6 +61,12 @@ void CWallpaper::setupFramebuffers () // give OpenGL an empty image glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + // set filtering parameters, otherwise the texture is not rendered + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // create the depth render buffer for the main framebuffer glGenRenderbuffers (1, &this->m_mainDepthBuffer); glBindRenderbuffer (GL_RENDERBUFFER, this->m_mainDepthBuffer); @@ -85,6 +91,12 @@ void CWallpaper::setupFramebuffers () // give OpenGL an empty image glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + // set filtering parameters, otherwise the texture is not rendered + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // create the depth render buffer for the main framebuffer glGenRenderbuffers (1, &this->m_subDepthBuffer); glBindRenderbuffer (GL_RENDERBUFFER, this->m_subDepthBuffer); diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp index 060dcea..a762c29 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.cpp @@ -1,3 +1,4 @@ +#include #include "CPass.h" #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" @@ -58,6 +59,12 @@ void CPass::render (GLuint drawTo, GLuint input) if (drawTo > 0) glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // update variables used in the render process (like g_ModelViewProjectionMatrix) + this->m_modelViewProjectionMatrix = + this->m_material->getImage ()->getScene ()->getCamera ()->getProjection () * + this->m_material->getImage ()->getScene ()->getCamera ()->getLookAt () * + glm::mat4 (1.0f); + // use the shader we have registered glUseProgram (this->m_programID); @@ -143,63 +150,40 @@ void CPass::render (GLuint drawTo, GLuint input) } } - // add static things - if (this->g_Texture0 != -1) + // add uniforms { -#ifdef DEBUG - std::cout << "g_Texture0 = 0\n"; -#endif /* DEBUG */ - glUniform1i (this->g_Texture0, 0); - } - if (this->g_Texture1 != -1) - { -#ifdef DEBUG - std::cout << "g_Texture1 = 1\n"; -#endif /* DEBUG */ - glUniform1i (this->g_Texture1, 1); - } - if (this->g_Texture2 != -1) - { -#ifdef DEBUG - std::cout << "g_Texture2 = 2\n"; -#endif /* DEBUG */ - glUniform1i (this->g_Texture2, 2); - } - if (this->g_Time != -1) - { -#ifdef DEBUG - std::cout << "g_Time = " << (float) ::g_Time << "\n"; -#endif /* DEBUG */ - glUniform1d (this->g_Time, (float) ::g_Time); - } - if (this->g_ModelViewProjectionMatrix != -1) - { - // calculate the new matrix - glm::mat4 projection = this->m_material->getImage ()->getScene ()->getCamera ()->getProjection (); - glm::mat4 view = this->m_material->getImage ()->getScene ()->getCamera ()->getLookAt (); - glm::mat4 model = glm::mat4 (1.0f); - glm::mat4 mvp = projection * view * model; + auto cur = this->m_uniforms.begin (); + auto end = this->m_uniforms.end (); - glUniformMatrix4fv (this->g_ModelViewProjectionMatrix, 1, GL_FALSE, &mvp [0] [0]); + for (; cur != end; cur ++) + { + switch ((*cur)->type) + { + case Double: + glUniform1d ((*cur)->id, *static_cast ((*cur)->value)); + break; + case Float: + glUniform1f ((*cur)->id, *static_cast ((*cur)->value)); + break; + case Integer: + glUniform1i ((*cur)->id, *static_cast ((*cur)->value)); + break; + case Vector4: + glUniform4fv ((*cur)->id, 1, glm::value_ptr (*static_cast ((*cur)->value))); + break; + case Vector3: + glUniform3fv ((*cur)->id, 1, glm::value_ptr (*static_cast ((*cur)->value))); + break; + case Vector2: + glUniform2fv ((*cur)->id, 1, glm::value_ptr (*static_cast ((*cur)->value))); + break; + case Matrix4: + glUniformMatrix4fv ((*cur)->id, 1, GL_FALSE, glm::value_ptr (*static_cast ((*cur)->value))); + break; + } + } + } -#ifdef DEBUG - std::cout << "g_ModelViewProjectionMatrix\n"; -#endif /* DEBUG */ - } - if (this->g_Brightness != -1) - { -#ifdef DEBUG - std::cout << "g_Brightness = 1.0\n"; -#endif /* DEBUG */ - glUniform1f (this->g_Brightness, 1.0f); - } - if (this->g_UserAlpha != -1) - { -#ifdef DEBUG - std::cout << "g_UserAlpha = 1.0\n"; -#endif /* DEBUG */ - glUniform1f (this->g_UserAlpha, 1.0f); - } if (this->g_Texture0Rotation != -1) { #ifdef DEBUG @@ -460,30 +444,100 @@ void CPass::setupShaders () glDeleteShader (vertexShaderID); glDeleteShader (fragmentShaderID); + // setup uniforms + this->setupUniforms (); // get information from the program, like uniforms, etc // support three textures for now - this->g_Texture0 = glGetUniformLocation (this->m_programID, "g_Texture0"); - this->g_Texture1 = glGetUniformLocation (this->m_programID, "g_Texture1"); - this->g_Texture2 = glGetUniformLocation (this->m_programID, "g_Texture2"); - this->g_Time = glGetUniformLocation (this->m_programID, "g_Time"); this->g_Texture0Rotation = glGetUniformLocation (this->m_programID, "g_Texture0Rotation"); this->g_Texture0Translation = glGetUniformLocation (this->m_programID, "g_Texture0Translation"); - this->g_ModelViewProjectionMatrix = glGetUniformLocation (this->m_programID, "g_ModelViewProjectionMatrix"); - this->g_UserAlpha = glGetUniformLocation (this->m_programID, "g_UserAlpha"); - this->g_Brightness = glGetUniformLocation (this->m_programID, "g_Brightness"); // bind a_TexCoord and a_Position this->a_TexCoord = glGetAttribLocation (this->m_programID, "a_TexCoord"); this->a_Position = glGetAttribLocation (this->m_programID, "a_Position"); } +void CPass::setupUniforms () +{ + // register all the texture uniforms with correct values + this->addUniform ("g_Texture0", 0); + this->addUniform ("g_Texture1", 1); + this->addUniform ("g_Texture2", 2); + this->addUniform ("g_Texture3", 3); + this->addUniform ("g_Texture4", 4); + this->addUniform ("g_Texture5", 5); + this->addUniform ("g_Texture6", 6); + this->addUniform ("g_Texture7", 7); + // register all the texture sizes required + this->addUniform ("g_Texture0Resolution", this->m_material->getImage ()->getTexture ()->getResolution ()); + // register the extra texture resolutions + { + auto cur = this->m_textures.begin (); + auto end = this->m_textures.end (); + + for (int index = 1; cur != end; cur ++, index ++) + { + std::ostringstream namestream; + + namestream << "g_Texture" << index << "Resolution"; + + this->addUniform (namestream.str (), (*cur)->getResolution ()); + } + } + + // register variables like brightness and alpha with some default value + this->addUniform ("g_Brightness", 1.0f); + this->addUniform ("g_UserAlpha", 1.0f); + // add some external variables + this->addUniform ("g_Time", &g_Time); + // add model-view-projection matrix + this->addUniform ("g_ModelViewProjectionMatrix", &this->m_modelViewProjectionMatrix); +} + +template +void CPass::addUniform (const std::string& name, UniformType type, T value) +{ + GLint id = glGetUniformLocation (this->m_programID, name.c_str ()); + + // parameter not found, can be ignored + if (id == -1) + return; + + // build a copy of the value and allocate it somewhere + T* newValue = new T (value); + + // uniform found, add it to the list + this->m_uniforms.emplace_back ( + new UniformEntry (id, name, type, newValue) + ); +} + +template +void CPass::addUniform (const std::string& name, UniformType type, T* value) +{ + // this version is used to reference to system variables so things like g_Time works fine + GLint id = glGetUniformLocation (this->m_programID, name.c_str ()); + + // parameter not found, can be ignored + if (id == -1) + return; + + // uniform found, add it to the list + this->m_uniforms.emplace_back ( + new UniformEntry (id, name, type, value) + ); +} + void CPass::setupTextures () { auto cur = this->m_pass->getTextures ().begin (); auto end = this->m_pass->getTextures ().end (); - for (; cur != end; cur ++) + for (int index = 0; cur != end; cur ++, index ++) { + // ignore first texture as that'll be the input of the last pass/image + if (index == 0) + continue; + uint32_t textureSize = 0; // get the first texture on the first pass (this one represents the image assigned to this object) @@ -553,3 +607,75 @@ void CPass::setupShaderVariables () } } } + +// define some basic methods for the template +/*template double Core::jsonFindDefault (nlohmann::json& data, const char *key, double defaultValue);*/ +void CPass::addUniform (const std::string& name, int value) +{ + this->addUniform (name, UniformType::Integer, value); +} + +void CPass::addUniform (const std::string& name, const int* value) +{ + this->addUniform (name, UniformType::Integer, value); +} + +void CPass::addUniform (const std::string& name, double value) +{ + this->addUniform (name, UniformType::Double, value); +} + +void CPass::addUniform (const std::string& name, const double* value) +{ + this->addUniform (name, UniformType::Double, value); +} + +void CPass::addUniform (const std::string& name, float value) +{ + this->addUniform (name, UniformType::Float, value); +} + +void CPass::addUniform (const std::string& name, const float* value) +{ + this->addUniform (name, UniformType::Float, value); +} + +void CPass::addUniform (const std::string& name, glm::vec2 value) +{ + this->addUniform (name, UniformType::Vector2, value); +} + +void CPass::addUniform (const std::string& name, const glm::vec2* value) +{ + this->addUniform (name, UniformType::Vector2, value); +} + +void CPass::addUniform (const std::string& name, glm::vec3 value) +{ + this->addUniform (name, UniformType::Vector3, value); +} + +void CPass::addUniform (const std::string& name, const glm::vec3* value) +{ + this->addUniform (name, UniformType::Vector3, value); +} + +void CPass::addUniform (const std::string& name, glm::vec4 value) +{ + this->addUniform (name, UniformType::Vector4, value); +} + +void CPass::addUniform (const std::string& name, const glm::vec4* value) +{ + this->addUniform (name, UniformType::Vector4, value); +} + +void CPass::addUniform (const std::string& name, glm::mat4 value) +{ + this->addUniform (name, UniformType::Matrix4, value); +} + +void CPass::addUniform (const std::string& name, const glm::mat4* value) +{ + this->addUniform (name, UniformType::Matrix4, value); +} diff --git a/src/WallpaperEngine/Render/Objects/Effects/CPass.h b/src/WallpaperEngine/Render/Objects/Effects/CPass.h index 31c6637..b6d2bf8 100644 --- a/src/WallpaperEngine/Render/Objects/Effects/CPass.h +++ b/src/WallpaperEngine/Render/Objects/Effects/CPass.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include "WallpaperEngine/Render/Shaders/Variables/CShaderVariable.h" #include "WallpaperEngine/Render/Objects/Effects/CMaterial.h" @@ -22,17 +23,58 @@ namespace WallpaperEngine::Render::Objects::Effects void render (GLuint drawTo, GLuint input); private: + enum UniformType + { + Float = 0, + Matrix4 = 1, + Integer = 2, + Vector2 = 3, + Vector3 = 4, + Vector4 = 5, + Double = 6 + }; + + class UniformEntry + { + public: + UniformEntry (GLint id, std::string name, UniformType type, const void* value) : + id (id), name (std::move (name)), type (type), value (value) { } + + GLint id; + std::string name; + UniformType type; + const void* value; + }; + static GLuint compileShader (Render::Shaders::Compiler* shader, GLuint type); void setupTextures (); void setupShaders (); void setupShaderVariables (); + void setupUniforms (); + void addUniform (const std::string& name, int value); + void addUniform (const std::string& name, double value); + void addUniform (const std::string& name, float value); + void addUniform (const std::string& name, glm::vec2 value); + void addUniform (const std::string& name, glm::vec3 value); + void addUniform (const std::string& name, glm::vec4 value); + void addUniform (const std::string& name, glm::mat4 value); + void addUniform (const std::string& name, const int* value); + void addUniform (const std::string& name, const double* value); + void addUniform (const std::string& name, const float* value); + void addUniform (const std::string& name, const glm::vec2* value); + void addUniform (const std::string& name, const glm::vec3* value); + void addUniform (const std::string& name, const glm::vec4* value); + void addUniform (const std::string& name, const glm::mat4* value); + template void addUniform (const std::string& name, UniformType type, T value); + template void addUniform (const std::string& name, UniformType type, T* value); CMaterial* m_material; Core::Objects::Images::Materials::CPass* m_pass; std::vector m_textures; std::map m_variables; std::map m_attribs; - std::map m_uniforms; + std::vector m_uniforms; + glm::mat4 m_modelViewProjectionMatrix; Render::Shaders::Compiler* m_fragShader; Render::Shaders::Compiler* m_vertShader; @@ -40,17 +82,10 @@ namespace WallpaperEngine::Render::Objects::Effects GLuint m_programID; // shader variables used temporary - GLint g_Texture0; - GLint g_Texture1; - GLint g_Texture2; - GLint g_Time; GLint g_Texture0Rotation; GLint g_Texture0Translation; - GLint g_ModelViewProjectionMatrix; GLint a_TexCoord; GLint a_Position; - GLint g_UserAlpha; - GLint g_Brightness; GLint positionAttribute; }; }