Hopefully properly support Fullscreen and Passthrough images

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2023-03-30 02:01:07 +02:00
parent 2119b0c1ee
commit 9a5913921c
4 changed files with 112 additions and 40 deletions

View File

@ -58,9 +58,6 @@ CObject* CObject::fromJSON (json data, CScene* scene, CContainer* container)
if (image_it != data.end () && !(*image_it).is_null ())
{
if (*image_it == "models/util/composelayer.json")
return nullptr;
object = Objects::CImage::fromJSON (
scene,
data,

View File

@ -27,7 +27,10 @@ CImage::CImage (
CUserSettingFloat* alpha,
float brightness,
uint32_t colorBlendMode,
const glm::vec2& parallaxDepth
const glm::vec2& parallaxDepth,
bool fullscreen,
bool passthrough,
bool autosize
) :
CObject (scene, visible, id, std::move(name), Type, origin, scale, angles),
m_size (size),
@ -37,7 +40,10 @@ CImage::CImage (
m_alpha (alpha),
m_brightness (brightness),
m_colorBlendMode (colorBlendMode),
m_parallaxDepth(parallaxDepth)
m_parallaxDepth(parallaxDepth),
m_fullscreen (fullscreen),
m_passthrough (passthrough),
m_autosize (autosize)
{
}
@ -64,6 +70,9 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*image_it).get <std::string> (), container));
auto material_it = jsonFindRequired (content, "material", "Image must have a material");
auto fullscreen = jsonFindDefault <bool> (content, "fullscreen", false);
auto passthrough = jsonFindDefault <bool> (content, "passthrough", false);
auto autosize = jsonFindDefault <bool> (content, "autosize", false);
return new CImage (
scene,
@ -80,7 +89,10 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
alpha,
brightness_val,
colorBlendMode_val,
WallpaperEngine::Core::aToVector2 (parallaxDepth_val)
WallpaperEngine::Core::aToVector2 (parallaxDepth_val),
fullscreen,
passthrough,
autosize
);
}
@ -125,4 +137,19 @@ const glm::vec2& CImage::getParallaxDepth () const
return this->m_parallaxDepth;
}
bool CImage::isFullscreen () const
{
return this->m_fullscreen;
}
bool CImage::isPassthrough () const
{
return this->m_passthrough;
}
bool CImage::isAutosize () const
{
return this->m_autosize;
}
const std::string CImage::Type = "image";

View File

@ -66,13 +66,25 @@ namespace WallpaperEngine::Core::Objects
* @return Parallax depth of the image
*/
[[nodiscard]] const glm::vec2& getParallaxDepth () const;
/**
* @return If the image is fullscreen or not
*/
[[nodiscard]] bool isFullscreen () const;
/**
* @return If the image is passthrough or not
*/
[[nodiscard]] bool isPassthrough () const;
/**
* @return If the image is autosized or not
*/
[[nodiscard]] bool isAutosize () const;
protected:
CImage (
CScene* scene, Images::CMaterial* material, CUserSettingBoolean* visible, uint32_t id, std::string name,
CUserSettingVector3* origin, CUserSettingVector3* scale, const glm::vec3& angles, const glm::vec2& size,
std::string alignment, CUserSettingVector3* color, CUserSettingFloat* alpha, float brightness,
uint32_t colorBlendMode, const glm::vec2& parallaxDepth
uint32_t colorBlendMode, const glm::vec2& parallaxDepth, bool fullscreen, bool passthrough, bool autosize
);
/**
@ -97,5 +109,11 @@ namespace WallpaperEngine::Core::Objects
CUserSettingVector3* m_color;
/** The color blending mode used for the image, special value for shaders */
uint32_t m_colorBlendMode;
/** If the image is fullscreen or not */
bool m_fullscreen;
/** If the image is passthrough or not */
bool m_passthrough;
/** If the image's size should be automatically determined */
bool m_autosize;
};
}

View File

@ -31,6 +31,17 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
glm::vec3 origin = this->getImage ()->getOrigin ();
glm::vec2 size = this->getSize ();
glm::vec3 scale = this->getImage ()->getScale ();
// fullscreen layers should use the whole projection's size
// TODO: WHAT SHOULD AUTOSIZE DO?
if (this->getImage ()->isFullscreen ())
{
size = { scene_width, scene_height };
origin = { scene_width / 2, scene_height / 2, 0 };
// TODO: CHANGE ALIGNMENT TOO?
}
glm::vec2 scaledSize = size * glm::vec2 (scale);
// calculate the center and shift from there
@ -86,16 +97,14 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
}
else
{
glm::vec2 realSize = size * glm::vec2 (scale);
// TODO: create a dummy texture of correct size, fbo constructors should be enough, but this should be properly handled
this->m_texture = new CFBO (
"",
ITexture::TextureFormat::ARGB8888,
ITexture::TextureFlags::NoFlags,
1,
realSize.x, realSize.y,
realSize.x, realSize.y
size.x, size.y,
size.x, size.y
);
}
@ -123,9 +132,6 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
this->m_texture->getRealWidth (), this->m_texture->getRealHeight ()
);
GLfloat realWidth = this->m_texture->getRealWidth ();
GLfloat realHeight = this->m_texture->getRealHeight ();
// build a list of vertices, these might need some change later (or maybe invert the camera)
GLfloat sceneSpacePosition [] = {
this->m_pos.x, this->m_pos.y, 0.0f,
@ -136,24 +142,6 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
this->m_pos.z, this->m_pos.w, 0.0f
};
GLfloat copySpacePosition [] = {
0.0, realHeight, 0.0f,
0.0, 0.0, 0.0f,
realWidth, realHeight, 0.0f,
realWidth, realHeight, 0.0f,
0.0, 0.0, 0.0f,
realWidth, 0.0, 0.0f
};
GLfloat passSpacePosition [] = {
-1.0, 1.0, 0.0f,
-1.0, -1.0, 0.0f,
1.0, 1.0, 0.0f,
1.0, 1.0, 0.0f,
-1.0, -1.0, 0.0f,
1.0, -1.0, 0.0f
};
float width = 1.0f;
float height = 1.0f;
@ -166,9 +154,8 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
// calculate the correct texCoord limits for the texture based on the texture screen size and real size
else if (this->getTexture () != nullptr &&
(this->getTexture ()->getTextureWidth () != this->getTexture ()->getRealWidth () ||
this->getTexture ()->getTextureHeight () != this->getTexture ()->getRealHeight ())
)
{
this->getTexture ()->getTextureHeight () != this->getTexture ()->getRealHeight ())
) {
uint32_t x = 1;
uint32_t y = 1;
@ -179,6 +166,7 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
height = scaledSize.y / y;
}
// TODO: RECALCULATE THESE POSITIONS FOR PASSTHROUGH SO THEY TAKE THE RIGHT PART OF THE TEXTURE
float x = 0.0f;
float y = 0.0f;
@ -191,6 +179,27 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
height = 1.0f;
}
GLfloat realWidth = size.x;
GLfloat realHeight = size.y;
GLfloat realX = 0.0;
GLfloat realY = 0.0;
if (this->getImage ()->isPassthrough())
{
x = -((this->m_pos.x + (scene_width / 2)) / size.x);
y = -((this->m_pos.w + (scene_height / 2)) / size.y);
height = (this->m_pos.y + (scene_height / 2)) / size.y;
width = (this->m_pos.z + (scene_width / 2)) / size.x;
if (this->getImage ()->isFullscreen ())
{
realX = -1.0;
realY = -1.0;
realWidth = 1.0;
realHeight = 1.0;
}
}
GLfloat texcoordCopy [] = {
x, height,
x, y,
@ -200,6 +209,15 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
width, y
};
GLfloat copySpacePosition [] = {
realX, realHeight, 0.0f,
realX, realY, 0.0f,
realWidth, realHeight, 0.0f,
realWidth, realHeight, 0.0f,
realX, realY, 0.0f,
realWidth, realY, 0.0f
};
GLfloat texcoordPass [] = {
0.0f, 1.0f,
0.0f, 0.0f,
@ -209,6 +227,15 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
1.0f, 0.0f
};
GLfloat passSpacePosition [] = {
-1.0, 1.0, 0.0f,
-1.0, -1.0, 0.0f,
1.0, 1.0, 0.0f,
1.0, 1.0, 0.0f,
-1.0, -1.0, 0.0f,
1.0, -1.0, 0.0f
};
// bind vertex list to the openGL buffers
glGenBuffers (1, &this->m_sceneSpacePosition);
glBindBuffer (GL_ARRAY_BUFFER, this->m_sceneSpacePosition);
@ -246,6 +273,10 @@ void CImage::setup ()
// TODO: SUPPORT PASSTHROUGH (IT'S A SHADER)
// passthrough images without effects are bad, do not draw them
if (this->getImage ()->isPassthrough() && this->getImage ()->getEffects ().empty ())
return;
{
// generate the main material used to render the image
this->m_material = new Effects::CMaterial (
@ -387,13 +418,15 @@ void CImage::pinpongFramebuffer (const CFBO** drawTo, const ITexture** asInput)
void CImage::render ()
{
// do not try to render something that did not initialize successfully
// non-visible materials do need to be rendered
if (!this->m_initialized)
return;
glColorMask (true, true, true, true);
// update the position if required
if (this->getScene ()->getScene ()->isCameraParallax ())
// TODO: There's more images that are not affected by parallax, autosize or fullscreen are not affected
if (this->getScene ()->getScene ()->isCameraParallax () && !this->getImage ()->isFullscreen ())
this->updateScreenSpacePosition ();
#if !NDEBUG
@ -433,12 +466,9 @@ void CImage::updateScreenSpacePosition ()
glm::vec2 depth = this->getImage ()->getParallaxDepth ();
glm::vec2* displacement = this->getScene ()->getParallaxDisplacement ();
// no need to update if the depth is 0
if (depth.x == 0.0 && depth.y == 0.0)
return;
float x = (depth.x + parallaxAmount) * displacement->x * this->getSize ().x;
float y = (depth.y + parallaxAmount) * displacement->y * this->getSize ().x;
this->m_modelViewProjectionScreen =
glm::translate (
this->getScene ()->getCamera ()->getProjection () *