Selaa lähdekoodia

Added --clamp-strategy option

Pasalc 2 vuotta sitten
vanhempi
commit
f6bff679ca

+ 27 - 2
src/WallpaperEngine/Application/CApplicationContext.cpp

@@ -28,6 +28,7 @@ struct option long_options[] = {
     { "noautomute", no_argument,            nullptr, 'm' },
     { "no-fullscreen-pause", no_argument,   nullptr, 'n' },
     { "disable-mouse", no_argument,         nullptr, 'e' },
+    { "clamp-strategy", required_argument,  nullptr, 't' },
     { nullptr, 0,                           nullptr, 0 }
 };
 
@@ -65,7 +66,7 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
             .mode = NORMAL_WINDOW,
             .maximumFPS = 30,
             .pauseOnFullscreen = true,
-            .window = { .geometry = {}},
+            .window = { .geometry = {}, .clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs, .scaleToFit=false },
         },
         .audio =
         {
@@ -89,7 +90,7 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
 
     std::string lastScreen;
 
-    while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w:mn", long_options, nullptr)) != -1)
+    while ((c = getopt_long (argc, argv, "b:r:p:d:shf:a:w:mnt:", long_options, nullptr)) != -1)
     {
         switch (c)
         {
@@ -194,6 +195,29 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
                 this->settings.mouse.enabled = false;
                 break;
 
+            case 't':
+            {
+                char opt = optarg[0];
+                switch (opt)
+                {
+                case 's':/* stretch*/
+                    this->settings.render.window.scaleToFit=true;
+                    break;
+                case 'b':/* clamp border (crop black)*/
+                    this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVsBorder;//clampStrategy(optarg);
+                    break;
+                case 'c':/* clamp*/
+                    this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs;
+                    break;
+                case 'r':
+                    this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::NoFlags;
+                    break;
+                default:
+                    sLog.error("Wrong argument provided for clamp-strategy");
+                    break;
+                }
+            }
+            break;
             default:
                 sLog.out ("Default on path parsing: ", optarg);
                 break;
@@ -290,4 +314,5 @@ void CApplicationContext::printHelp (const char* route)
     sLog.out ("\t--set-property <name=value>\tOverrides the default value of the given property");
     sLog.out ("\t--no-fullscreen-pause\tPrevents the background pausing when an app is fullscreen");
     sLog.out ("\t--disable-mouse\tDisables mouse interactions");
+    sLog.out ("\t--clamp-strategy <strategy>\t Clamp strategy if wallpaper doesn't fit screen. Can be stretch, border, repeat, clamp. Can be shortend to s, b, r, c. Default is clamp");
 }

+ 4 - 0
src/WallpaperEngine/Application/CApplicationContext.h

@@ -11,6 +11,8 @@
 
 #include "CApplicationState.h"
 
+#include "WallpaperEngine/Assets/ITexture.h"
+
 namespace WallpaperEngine::Application
 {
 	/**
@@ -68,6 +70,8 @@ namespace WallpaperEngine::Application
                 {
                     /** The window size used in explicit window */
                     glm::ivec4 geometry;
+                    WallpaperEngine::Assets::ITexture::TextureFlags clamp;
+                    bool scaleToFit;
                 } window;
             } render;
 

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

@@ -69,6 +69,7 @@ namespace WallpaperEngine::Assets
             NoInterpolation = 1,
             ClampUVs = 2,
             IsGif = 4,
+            ClampUVsBorder = 8,
         };
 
         /**

+ 5 - 0
src/WallpaperEngine/Render/CFBO.cpp

@@ -41,6 +41,11 @@ CFBO::CFBO (
         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     }
+    else if (flags & TextureFlags::ClampUVsBorder)
+    {
+        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+        glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+    }
     else
     {
         glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

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

@@ -36,9 +36,9 @@ namespace WallpaperEngine::Render
 
         // render the background
         if (ref != this->m_wallpapers.end ())
-            ref->second->render (viewport->viewport, this->getOutput ().renderVFlip ());
+            ref->second->render (viewport->viewport, this->getOutput ().renderVFlip (), this->getApp().getContext().settings.render.window.scaleToFit);
         else
-            this->m_defaultWallpaper->render (viewport->viewport, this->getOutput ().renderVFlip ());
+            this->m_defaultWallpaper->render (viewport->viewport, this->getOutput ().renderVFlip (), this->getApp().getContext().settings.render.window.scaleToFit);
 
 #if !NDEBUG
         glPopDebugGroup ();

+ 64 - 16
src/WallpaperEngine/Render/CWallpaper.cpp

@@ -211,23 +211,70 @@ void CWallpaper::setDestinationFramebuffer (GLuint framebuffer)
     this->m_destFramebuffer = framebuffer;
 }
 
-void CWallpaper::render (glm::ivec4 viewport, bool vflip)
-{
-    this->renderFrame (viewport);
-
-    uint32_t projectionWidth = this->getWidth ();
-    uint32_t projectionHeight = this->getHeight ();
-
-    float ustart = 0.0f;
-    float uend = 1.0f;
-    float vstart = 1.0f;
-    float vend = 0.0f;
-
-    if (vflip)
-    {
+void CWallpaper::setTextureUVs(const glm::ivec4& viewport, const bool vflip, const bool scale,
+    float& ustart, float& uend, float& vstart, float& vend){
+    
+    ustart = 0.0f;
+    uend = 1.0f;
+    vstart = 1.0f;
+    vend = 0.0f;
+    if (vflip){
         vstart = 0.0f;
         vend = 1.0f;
     }
+    if(!scale){
+        uint32_t projectionWidth = this->getWidth ();
+        uint32_t projectionHeight = this->getHeight ();
+
+        if (
+            (viewport.w > viewport.z && projectionWidth >= projectionHeight) ||
+                (viewport.z > viewport.w && projectionHeight > projectionWidth)
+            )
+        {
+            int newWidth = viewport.w / (float) projectionHeight * projectionWidth;
+            float newCenter = newWidth / 2.0f;
+            float viewportCenter = viewport.z / 2.0;
+
+            float left = newCenter - viewportCenter;
+            float right = newCenter + viewportCenter;
+
+            ustart = left / newWidth;
+            uend = right / newWidth;
+        }
+
+        if (
+            (viewport.z > viewport.w && projectionWidth >= projectionHeight) ||
+                (viewport.w > viewport.z && projectionHeight > projectionWidth)
+            )
+        {
+            int newHeight = viewport.z / (float) projectionWidth * projectionHeight;
+            float newCenter = newHeight / 2.0f;
+            float viewportCenter = viewport.w / 2.0;
+
+            float down = newCenter - viewportCenter;
+            float up = newCenter + viewportCenter;
+
+            if (vflip)
+            {
+                vstart = down / newHeight;
+                vend = up / newHeight;
+            }
+            else
+            {
+                vstart = up / newHeight;
+                vend = down / newHeight;
+            }
+        }
+    }
+}
+
+void CWallpaper::render (glm::ivec4 viewport, bool vflip, bool scale)
+{
+    this->renderFrame (viewport);
+
+    float ustart,uend,vstart,vend;
+    setTextureUVs(viewport, vflip, scale, ustart, uend, vstart, vend);
+    
     GLfloat texCoords [] = {
         ustart, vstart,
         uend, vstart,
@@ -270,12 +317,13 @@ void CWallpaper::setupFramebuffers ()
 {
     uint32_t width = this->getWidth ();
     uint32_t height = this->getHeight ();
-
+    ITexture::TextureFlags clamp = this->getContext().getApp().getContext().settings.render.window.clamp;
+    
     // create framebuffer for the scene
     this->m_sceneFBO = this->createFBO (
         "_rt_FullFrameBuffer",
         ITexture::TextureFormat::ARGB8888,
-        ITexture::TextureFlags::ClampUVs,
+        clamp,
         1.0,
         width, height,
         width, height

+ 6 - 1
src/WallpaperEngine/Render/CWallpaper.h

@@ -34,10 +34,15 @@ namespace WallpaperEngine::Render
 
         ~CWallpaper ();
 
+        /**
+         * Get texture UV coordinates for render
+         */
+        void setTextureUVs(const glm::ivec4& viewport, const bool vflip, const bool scale, 
+            float& ustart, float& uend, float& vstart, float& vend);
         /**
          * Performs a render pass of the wallpaper
          */
-        void render (glm::ivec4 viewport, bool vflip);
+        void render (glm::ivec4 viewport, bool vflip, bool scale);
 
         /**
          * @return The container to resolve files for this wallpaper

+ 1 - 0
src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp

@@ -1,3 +1,4 @@
+#include <GL/glew.h>
 #include <GLFW/glfw3.h>
 #include "CGLFWWindowOutput.h"
 #include "WallpaperEngine/Logging/CLog.h"