Skip to content

Commit

Permalink
Added scaling and clamp support
Browse files Browse the repository at this point in the history
  • Loading branch information
Pasalc committed Nov 13, 2023
1 parent 4212095 commit 11666ab
Show file tree
Hide file tree
Showing 13 changed files with 371 additions and 109 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ add_executable(

src/WallpaperEngine/Render/CWallpaper.h
src/WallpaperEngine/Render/CWallpaper.cpp
src/WallpaperEngine/Render/CWallpaperState.h
src/WallpaperEngine/Render/CWallpaperState.cpp
src/WallpaperEngine/Render/CScene.h
src/WallpaperEngine/Render/CScene.cpp
src/WallpaperEngine/Render/CVideo.h
Expand Down
82 changes: 60 additions & 22 deletions src/WallpaperEngine/Application/CApplicationContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,29 @@ 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' },
{ "scaling", required_argument, nullptr, 't' },
{ "clamping", required_argument, nullptr, 't' },
{ nullptr, 0, nullptr, 0 }
};

/* std::hash::operator() isn't constexpr, so it can't be used to get hash values as compile-time constants
* So here is customHash. It skips all spaces, so hashes for " find " and "fi nd" are the same
* Basicly got it from here: https://stackoverflow.com/questions/8317508/hash-function-for-a-string
*/
constexpr size_t customHash(const char* str) {
constexpr size_t A = 54059; /* a prime */
constexpr size_t B = 76963; /* another prime */
constexpr size_t C = 86969; /* yet another prime */
constexpr size_t FIRSTH = 37; /* also prime */
size_t hash = FIRSTH;
while (*str) {
if(*str != ' ') // Skip spaces
hash = (hash * A) ^ (*str * B);
++str;
}
return hash % C;
}

std::string stringPathFixes (const std::string& s)
{
if (s.empty ())
Expand Down Expand Up @@ -66,7 +85,8 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
.mode = NORMAL_WINDOW,
.maximumFPS = 30,
.pauseOnFullscreen = true,
.window = { .geometry = {}, .clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs, .scaleToFit=false },
.window = { .geometry = {}, .clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs,
.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs, },
},
.audio =
{
Expand Down Expand Up @@ -105,6 +125,7 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
// no need to check for previous screen being in the list, as it's the only way for this variable
// to have any value
this->settings.general.screenBackgrounds[lastScreen] = translateBackground (optarg);
this->settings.general.screenScalings[lastScreen] = this->settings.render.window.scalingMode;
break;

case 'o':
Expand Down Expand Up @@ -133,6 +154,7 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
this->settings.render.mode = DESKTOP_BACKGROUND;
lastScreen = optarg;
this->settings.general.screenBackgrounds[lastScreen] = "";
this->settings.general.screenScalings[lastScreen] = this->settings.render.window.scalingMode;
break;

case 'w':
Expand Down Expand Up @@ -196,25 +218,38 @@ CApplicationContext::CApplicationContext (int argc, char* argv[])
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;
{
size_t hash = customHash(optarg);
// Use a switch statement with the hash
switch (hash) {
// --scale options
case customHash("stretch"):
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::StretchUVs;
break;
case customHash("fit"):
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFitUVs;
break;
case customHash("fill"):
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::ZoomFillUVs;
break;
case customHash("default"):
this->settings.render.window.scalingMode = WallpaperEngine::Render::CWallpaperState::TextureUVsScaling::DefaultUVs;
break;
// --clamp options
case customHash("clamp"):
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVs;
break;
case customHash("border"):
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::ClampUVsBorder;
break;
case customHash("repeat"):
this->settings.render.window.clamp = WallpaperEngine::Assets::ITexture::TextureFlags::NoFlags;
break;
default:
sLog.error("Wrong argument:");
sLog.error(optarg);
sLog.exception("Wrong argument provided for --scale or --clamp option.");
break;
}
}
break;
Expand Down Expand Up @@ -314,5 +349,8 @@ 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");
sLog.out ("\t--scaling <mode>\t Scaling mode for wallpaper. Can be stretch, fit, fill, default. Must be used before wallpaper provided.\n\
\t\t For default wallpaper last specified value will be used.\n\
\t\t Example: ./wallengine --scaling stretch --screen-root eDP-1 --bg 2667198601 --scaling fill --screen-root eDP-2 2667198602");
sLog.out ("\t--clamping <mode>\t Clamping mode for all wallpapers. Can be clamp, border, repeat. Enables GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, GL_REPEAT accordingly. Default is clamp.");
}
5 changes: 4 additions & 1 deletion src/WallpaperEngine/Application/CApplicationContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "CApplicationState.h"

#include "WallpaperEngine/Assets/ITexture.h"
#include "WallpaperEngine/Render/CWallpaperState.h"

namespace WallpaperEngine::Application
{
Expand Down Expand Up @@ -52,6 +53,8 @@ namespace WallpaperEngine::Application
std::map <std::string, std::filesystem::path> screenBackgrounds;
/** Properties to change values for */
std::map <std::string, std::string> properties;
/** The scaling mode for different screens */
std::map <std::string, WallpaperEngine::Render::CWallpaperState::TextureUVsScaling> screenScalings;
} general;

/**
Expand All @@ -71,7 +74,7 @@ namespace WallpaperEngine::Application
/** The window size used in explicit window */
glm::ivec4 geometry;
WallpaperEngine::Assets::ITexture::TextureFlags clamp;
bool scaleToFit;
WallpaperEngine::Render::CWallpaperState::TextureUVsScaling scalingMode;
} window;
} render;

Expand Down
4 changes: 2 additions & 2 deletions src/WallpaperEngine/Application/CWallpaperApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,13 +322,13 @@ namespace WallpaperEngine::Application
for (const auto& it : this->m_backgrounds)
context->setWallpaper (
it.first,
WallpaperEngine::Render::CWallpaper::fromWallpaper (it.second->getWallpaper (), *context, *audioContext)
WallpaperEngine::Render::CWallpaper::fromWallpaper (it.second->getWallpaper (), *context, *audioContext, this->m_context.settings.general.screenScalings[it.first])
);

// set the default rendering wallpaper if available
if (this->m_defaultBackground != nullptr)
context->setDefaultWallpaper (WallpaperEngine::Render::CWallpaper::fromWallpaper (
this->m_defaultBackground->getWallpaper (), *context, *audioContext
this->m_defaultBackground->getWallpaper (), *context, *audioContext, this->m_context.settings.render.window.scalingMode
));

static time_t seconds;
Expand Down
4 changes: 2 additions & 2 deletions src/WallpaperEngine/Render/CRenderContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ namespace WallpaperEngine::Render

// render the background
if (ref != this->m_wallpapers.end ())
ref->second->render (viewport->viewport, this->getOutput ().renderVFlip (), this->getApp().getContext().settings.render.window.scaleToFit);
ref->second->render (viewport->viewport, this->getOutput ().renderVFlip ());
else
this->m_defaultWallpaper->render (viewport->viewport, this->getOutput ().renderVFlip (), this->getApp().getContext().settings.render.window.scaleToFit);
this->m_defaultWallpaper->render (viewport->viewport, this->getOutput ().renderVFlip ());

#if !NDEBUG
glPopDebugGroup ();
Expand Down
6 changes: 4 additions & 2 deletions src/WallpaperEngine/Render/CScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include "WallpaperEngine/Render/Objects/CImage.h"
#include "WallpaperEngine/Render/Objects/CSound.h"

#include "WallpaperEngine/Render/CWallpaperState.h"

#include "CScene.h"

extern float g_Time;
Expand All @@ -14,8 +16,8 @@ extern float g_TimeLast;
using namespace WallpaperEngine;
using namespace WallpaperEngine::Render;

CScene::CScene (Core::CScene* scene, CRenderContext& context, CAudioContext& audioContext) :
CWallpaper (scene, Type, context, audioContext),
CScene::CScene (Core::CScene* scene, CRenderContext& context, CAudioContext& audioContext, const CWallpaperState::TextureUVsScaling& scalingMode) :
CWallpaper (scene, Type, context, audioContext, scalingMode),
m_mousePosition (),
m_mousePositionLast (),
m_parallaxDisplacement ()
Expand Down
2 changes: 1 addition & 1 deletion src/WallpaperEngine/Render/CScene.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace WallpaperEngine::Render
class CScene : public CWallpaper
{
public:
CScene (Core::CScene* scene, CRenderContext& context, CAudioContext& audioContext);
CScene (Core::CScene* scene, CRenderContext& context, CAudioContext& audioContext, const CWallpaperState::TextureUVsScaling& scalingMode);

CCamera* getCamera () const;

Expand Down
4 changes: 2 additions & 2 deletions src/WallpaperEngine/Render/CVideo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ void* get_proc_address (void* ctx, const char* name)
return static_cast<CVideo*> (ctx)->getContext ().getDriver ().getProcAddress (name);
}

CVideo::CVideo (Core::CVideo* video, CRenderContext& context, CAudioContext& audioContext) :
CWallpaper (video, Type, context, audioContext),
CVideo::CVideo (Core::CVideo* video, CRenderContext& context, CAudioContext& audioContext, const CWallpaperState::TextureUVsScaling& scalingMode) :
CWallpaper (video, Type, context, audioContext, scalingMode),
m_width (16),
m_height (16),
m_mpvGl (nullptr)
Expand Down
2 changes: 1 addition & 1 deletion src/WallpaperEngine/Render/CVideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace WallpaperEngine::Render
class CVideo : public CWallpaper
{
public:
CVideo (Core::CVideo* video, CRenderContext& context, CAudioContext& audioContext);
CVideo (Core::CVideo* video, CRenderContext& context, CAudioContext& audioContext, const CWallpaperState::TextureUVsScaling& scalingMode);

Core::CVideo* getVideo ();

Expand Down
81 changes: 15 additions & 66 deletions src/WallpaperEngine/Render/CWallpaper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

using namespace WallpaperEngine::Render;

CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context, CAudioContext& audioContext) :
CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRenderContext& context, CAudioContext& audioContext, const CWallpaperState::TextureUVsScaling& scalingMode) :
CContextAware (context),
m_wallpaperData (wallpaperData),
m_type (std::move(type)),
Expand All @@ -22,7 +22,8 @@ CWallpaper::CWallpaper (Core::CWallpaper* wallpaperData, std::string type, CRend
a_Position (GL_NONE),
a_TexCoord (GL_NONE),
m_vaoBuffer (GL_NONE),
m_audioContext (audioContext)
m_audioContext (audioContext),
m_state(scalingMode)
{
// generate the VAO to stop opengl from complaining
glGenVertexArrays (1, &this->m_vaoBuffer);
Expand Down Expand Up @@ -201,78 +202,26 @@ void CWallpaper::setupShaders ()
this->a_TexCoord = glGetAttribLocation (this->m_shader, "a_TexCoord");
}

void CWallpaper::updateTexCoord (GLfloat* texCoords, GLsizeiptr size) const
{
glBindBuffer (GL_ARRAY_BUFFER, this->m_texCoordBuffer);
glBufferData (GL_ARRAY_BUFFER, size, texCoords, GL_STATIC_DRAW);
}
void CWallpaper::setDestinationFramebuffer (GLuint framebuffer)
{
this->m_destFramebuffer = framebuffer;
}

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 ();
const float m1 = float(viewport.z) / projectionWidth;
const float m2 = float(viewport.w) / projectionHeight;
const float m = std::max(m1,m2);
projectionWidth*=m;
projectionHeight*=m;
if (projectionWidth!=viewport.z)
{
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 (projectionHeight!=viewport.w)
{
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::updateUVs(const glm::ivec4& viewport, const bool vflip){
//update UVs if something has changed, otherwise use old values
if(this->m_state.hasChanged(viewport, vflip, this->getWidth(), this->getHeight())){
// Update wallpaper state
this->m_state.updateState(viewport, vflip, this->getWidth(), this->getHeight());
}
}

void CWallpaper::render (glm::ivec4 viewport, bool vflip, bool scale)
void CWallpaper::render (glm::ivec4 viewport, bool vflip)
{
this->renderFrame (viewport);
//Update UVs coordinates according to scaling mode of this wallpaper
updateUVs(viewport,vflip);
auto [ ustart, uend, vstart, vend ] = this->m_state.getTextureUVs();

float ustart,uend,vstart,vend;
setTextureUVs(viewport, vflip, scale, ustart, uend, vstart, vend);

GLfloat texCoords [] = {
ustart, vstart,
uend, vstart,
Expand Down Expand Up @@ -363,12 +312,12 @@ CFBO* CWallpaper::getFBO () const
return this->m_sceneFBO;
}

CWallpaper* CWallpaper::fromWallpaper (Core::CWallpaper* wallpaper, CRenderContext& context, CAudioContext& audioContext)
CWallpaper* CWallpaper::fromWallpaper (Core::CWallpaper* wallpaper, CRenderContext& context, CAudioContext& audioContext, const CWallpaperState::TextureUVsScaling& scalingMode)
{
if (wallpaper->is <Core::CScene> ())
return new WallpaperEngine::Render::CScene (wallpaper->as <Core::CScene> (), context, audioContext);
return new WallpaperEngine::Render::CScene (wallpaper->as <Core::CScene> (), context, audioContext, scalingMode);
else if (wallpaper->is <Core::CVideo> ())
return new WallpaperEngine::Render::CVideo (wallpaper->as <Core::CVideo> (), context, audioContext);
return new WallpaperEngine::Render::CVideo (wallpaper->as <Core::CVideo> (), context, audioContext, scalingMode);
else
sLog.exception ("Unsupported wallpaper type");
}
Loading

0 comments on commit 11666ab

Please sign in to comment.