mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
154 lines
6.0 KiB
C++
154 lines
6.0 KiB
C++
#include "CWallpaperState.h"
|
|
#include "WallpaperEngine/Logging/CLog.h"
|
|
#include <algorithm>
|
|
|
|
using namespace WallpaperEngine::Render;
|
|
|
|
// Reset UVs to 0/1 values
|
|
void CWallpaperState::resetUVs () {
|
|
this->UVs.ustart = 0;
|
|
this->UVs.uend = 1;
|
|
if (vflip) {
|
|
this->UVs.vstart = 0.0f;
|
|
this->UVs.vend = 1.0f;
|
|
} else {
|
|
this->UVs.vstart = 1.0f;
|
|
this->UVs.vend = 0.0f;
|
|
}
|
|
}
|
|
|
|
// Update Us coordinates for current viewport and projection
|
|
void CWallpaperState::updateUs (const int& projectionWidth, const int& projectionHeight) {
|
|
const float viewportWidth = this->getViewportWidth ();
|
|
const float viewportHeight = this->getViewportHeight ();
|
|
const int newWidth = viewportHeight / projectionHeight * projectionWidth;
|
|
const float newCenter = newWidth / 2.0f;
|
|
const float viewportCenter = viewportWidth / 2.0;
|
|
|
|
const float left = newCenter - viewportCenter;
|
|
const float right = newCenter + viewportCenter;
|
|
|
|
this->UVs.ustart = left / newWidth;
|
|
this->UVs.uend = right / newWidth;
|
|
}
|
|
|
|
// Update Vs coordinates for current viewport and projection
|
|
void CWallpaperState::updateVs (const int& projectionWidth, const int& projectionHeight) {
|
|
const float viewportWidth = this->getViewportWidth ();
|
|
const float viewportHeight = this->getViewportHeight ();
|
|
const int newHeight = viewportWidth / projectionWidth * projectionHeight;
|
|
const float newCenter = newHeight / 2.0f;
|
|
const float viewportCenter = viewportHeight / 2.0;
|
|
|
|
const float down = newCenter - viewportCenter;
|
|
const float up = newCenter + viewportCenter;
|
|
|
|
if (vflip) {
|
|
this->UVs.vstart = down / newHeight;
|
|
this->UVs.vend = up / newHeight;
|
|
} else {
|
|
this->UVs.vstart = up / newHeight;
|
|
this->UVs.vend = down / newHeight;
|
|
}
|
|
}
|
|
|
|
template <> void CWallpaperState::updateTextureUVs<CWallpaperState::TextureUVsScaling::StretchUVs> () {
|
|
this->resetUVs ();
|
|
}
|
|
|
|
template <> void CWallpaperState::updateTextureUVs<CWallpaperState::TextureUVsScaling::ZoomFillUVs> () {
|
|
this->resetUVs ();
|
|
|
|
const int viewportWidth = this->getViewportWidth ();
|
|
const int viewportHeight = this->getViewportHeight ();
|
|
int projectionWidth = this->getProjectionWidth ();
|
|
int projectionHeight = this->getProjectionHeight ();
|
|
|
|
const float m1 = static_cast<float> (viewportWidth) / projectionWidth;
|
|
const float m2 = static_cast<float> (viewportHeight) / projectionHeight;
|
|
const float m = std::max (m1, m2);
|
|
projectionWidth *= m;
|
|
projectionHeight *= m;
|
|
|
|
if (projectionWidth != viewportWidth) {
|
|
this->updateUs (projectionWidth, projectionHeight);
|
|
} else if (projectionHeight != viewportHeight) {
|
|
this->updateVs (projectionWidth, projectionHeight);
|
|
}
|
|
}
|
|
|
|
template <> void CWallpaperState::updateTextureUVs<CWallpaperState::TextureUVsScaling::ZoomFitUVs> () {
|
|
this->resetUVs ();
|
|
|
|
const int viewportWidth = this->getViewportWidth ();
|
|
const int viewportHeight = this->getViewportHeight ();
|
|
int projectionWidth = this->getProjectionWidth ();
|
|
int projectionHeight = this->getProjectionHeight ();
|
|
|
|
const float m1 = static_cast<float> (viewportWidth) / projectionWidth;
|
|
const float m2 = static_cast<float> (viewportHeight) / projectionHeight;
|
|
const float m = std::min (m1, m2);
|
|
projectionWidth *= m;
|
|
projectionHeight *= m;
|
|
|
|
if (projectionWidth != viewportWidth) {
|
|
this->updateUs (projectionWidth, projectionHeight);
|
|
} else if (projectionHeight != viewportHeight) {
|
|
this->updateVs (projectionWidth, projectionHeight);
|
|
}
|
|
}
|
|
|
|
template <> void CWallpaperState::updateTextureUVs<CWallpaperState::TextureUVsScaling::DefaultUVs> () {
|
|
this->resetUVs ();
|
|
|
|
const int viewportWidth = this->getViewportWidth ();
|
|
const int viewportHeight = this->getViewportHeight ();
|
|
const int projectionWidth = this->getProjectionWidth ();
|
|
const int projectionHeight = this->getProjectionHeight ();
|
|
|
|
if ((viewportHeight > viewportWidth && projectionWidth >= projectionHeight) ||
|
|
(viewportWidth > viewportHeight && projectionHeight > projectionWidth)) {
|
|
updateUs (projectionWidth, projectionHeight);
|
|
}
|
|
|
|
if ((viewportWidth > viewportHeight && projectionWidth >= projectionHeight) ||
|
|
(viewportHeight > viewportWidth && projectionHeight > projectionWidth)) {
|
|
updateVs (projectionWidth, projectionHeight);
|
|
}
|
|
}
|
|
|
|
template <CWallpaperState::TextureUVsScaling T> void CWallpaperState::updateTextureUVs () {
|
|
sLog.exception (
|
|
"Using generic template for scaling is not allowed. Write specialization template for your scaling mode.\
|
|
This message is for developers, if you are just user it's a bug.");
|
|
}
|
|
|
|
void CWallpaperState::updateState (const glm::ivec4& viewport, const bool& vflip, const int& projectionWidth,
|
|
const int& projectionHeight) {
|
|
this->viewport.width = viewport.z;
|
|
this->viewport.height = viewport.w;
|
|
this->vflip = vflip;
|
|
this->projection.width = projectionWidth;
|
|
this->projection.height = projectionHeight;
|
|
|
|
// Set texture UVs according to choosen scaling mode for this wallpaper
|
|
switch (this->getTextureUVsScaling ()) {
|
|
case CWallpaperState::TextureUVsScaling::StretchUVs:
|
|
this->updateTextureUVs<CWallpaperState::TextureUVsScaling::StretchUVs> ();
|
|
break;
|
|
case CWallpaperState::TextureUVsScaling::ZoomFillUVs:
|
|
this->updateTextureUVs<CWallpaperState::TextureUVsScaling::ZoomFillUVs> ();
|
|
break;
|
|
case CWallpaperState::TextureUVsScaling::ZoomFitUVs:
|
|
this->updateTextureUVs<CWallpaperState::TextureUVsScaling::ZoomFitUVs> ();
|
|
break;
|
|
case CWallpaperState::TextureUVsScaling::DefaultUVs:
|
|
this->updateTextureUVs<CWallpaperState::TextureUVsScaling::DefaultUVs> ();
|
|
break;
|
|
default:
|
|
sLog.exception (
|
|
"Switch case for specified scaling mode doesn't exist. Add your realisation in switch statement.\
|
|
This message is for developers, if you are just user it's a bug.");
|
|
break;
|
|
}
|
|
} |