diff --git a/src/WallpaperEngine/Application/CApplicationContext.cpp b/src/WallpaperEngine/Application/CApplicationContext.cpp index a4665c0..23bf78b 100644 --- a/src/WallpaperEngine/Application/CApplicationContext.cpp +++ b/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 \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 \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"); } \ No newline at end of file diff --git a/src/WallpaperEngine/Application/CApplicationContext.h b/src/WallpaperEngine/Application/CApplicationContext.h index 92d7750..ed0c284 100644 --- a/src/WallpaperEngine/Application/CApplicationContext.h +++ b/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; diff --git a/src/WallpaperEngine/Assets/ITexture.h b/src/WallpaperEngine/Assets/ITexture.h index 338a592..42037a9 100644 --- a/src/WallpaperEngine/Assets/ITexture.h +++ b/src/WallpaperEngine/Assets/ITexture.h @@ -69,6 +69,7 @@ namespace WallpaperEngine::Assets NoInterpolation = 1, ClampUVs = 2, IsGif = 4, + ClampUVsBorder = 8, }; /** diff --git a/src/WallpaperEngine/Render/CFBO.cpp b/src/WallpaperEngine/Render/CFBO.cpp index 11fa2c6..ab79621 100644 --- a/src/WallpaperEngine/Render/CFBO.cpp +++ b/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); diff --git a/src/WallpaperEngine/Render/CRenderContext.cpp b/src/WallpaperEngine/Render/CRenderContext.cpp index 08ad438..6f2ed95 100644 --- a/src/WallpaperEngine/Render/CRenderContext.cpp +++ b/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 (); diff --git a/src/WallpaperEngine/Render/CWallpaper.cpp b/src/WallpaperEngine/Render/CWallpaper.cpp index 9471928..38badd4 100644 --- a/src/WallpaperEngine/Render/CWallpaper.cpp +++ b/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 diff --git a/src/WallpaperEngine/Render/CWallpaper.h b/src/WallpaperEngine/Render/CWallpaper.h index ed71611..c55f5b6 100644 --- a/src/WallpaperEngine/Render/CWallpaper.h +++ b/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 diff --git a/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp b/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp index 7994f4f..d96f397 100644 --- a/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp +++ b/src/WallpaperEngine/Render/Drivers/Output/CGLFWWindowOutput.cpp @@ -1,3 +1,4 @@ +#include #include #include "CGLFWWindowOutput.h" #include "WallpaperEngine/Logging/CLog.h"