mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-14 13:22:23 +08:00
Added a basic (and somewhat convincing) parallax effect for the camera
Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
parent
c13d743022
commit
625397ea0c
@ -8,27 +8,30 @@
|
|||||||
using namespace WallpaperEngine::Core::Objects;
|
using namespace WallpaperEngine::Core::Objects;
|
||||||
|
|
||||||
CImage::CImage (
|
CImage::CImage (
|
||||||
Images::CMaterial* material,
|
Images::CMaterial* material,
|
||||||
bool visible,
|
bool visible,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
std::string name,
|
std::string name,
|
||||||
const glm::vec3& origin,
|
const glm::vec3& origin,
|
||||||
const glm::vec3& scale,
|
const glm::vec3& scale,
|
||||||
const glm::vec3& angles,
|
const glm::vec3& angles,
|
||||||
const glm::vec2& size,
|
const glm::vec2& size,
|
||||||
std::string alignment,
|
std::string alignment,
|
||||||
const glm::vec3& color,
|
const glm::vec3& color,
|
||||||
float alpha,
|
float alpha,
|
||||||
float brightness,
|
float brightness,
|
||||||
uint32_t colorBlendMode) :
|
uint32_t colorBlendMode,
|
||||||
CObject (visible, id, std::move(name), Type, origin, scale, angles),
|
const glm::vec2& parallaxDepth
|
||||||
m_size (size),
|
) :
|
||||||
m_material (material),
|
CObject (visible, id, std::move(name), Type, origin, scale, angles),
|
||||||
m_alignment (std::move(alignment)),
|
m_size (size),
|
||||||
m_color (color),
|
m_material (material),
|
||||||
m_alpha (alpha),
|
m_alignment (std::move(alignment)),
|
||||||
m_brightness (brightness),
|
m_color (color),
|
||||||
m_colorBlendMode (colorBlendMode)
|
m_alpha (alpha),
|
||||||
|
m_brightness (brightness),
|
||||||
|
m_colorBlendMode (colorBlendMode),
|
||||||
|
m_parallaxDepth(parallaxDepth)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +52,7 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
|
|||||||
auto color_val = jsonFindDefault <std::string> (data, "color", "1.0 1.0 1.0");
|
auto color_val = jsonFindDefault <std::string> (data, "color", "1.0 1.0 1.0");
|
||||||
auto brightness_val = jsonFindDefault <float> (data, "brightness", 1.0);
|
auto brightness_val = jsonFindDefault <float> (data, "brightness", 1.0);
|
||||||
auto colorBlendMode_val = jsonFindDefault <uint32_t> (data, "colorBlendMode", 0);
|
auto colorBlendMode_val = jsonFindDefault <uint32_t> (data, "colorBlendMode", 0);
|
||||||
|
auto parallaxDepth_val = jsonFindDefault <std::string> (data, "parallaxDepth", "0 0");
|
||||||
|
|
||||||
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*image_it).get <std::string> (), container));
|
json content = json::parse (WallpaperEngine::FileSystem::loadFullFile ((*image_it).get <std::string> (), container));
|
||||||
|
|
||||||
@ -67,7 +71,8 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
|
|||||||
WallpaperEngine::Core::aToVector3 (color_val),
|
WallpaperEngine::Core::aToVector3 (color_val),
|
||||||
alpha,
|
alpha,
|
||||||
brightness_val,
|
brightness_val,
|
||||||
colorBlendMode_val
|
colorBlendMode_val,
|
||||||
|
WallpaperEngine::Core::aToVector2 (parallaxDepth_val)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,4 +111,10 @@ const uint32_t CImage::getColorBlendMode () const
|
|||||||
return this->m_colorBlendMode;
|
return this->m_colorBlendMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const glm::vec2& CImage::getParallaxDepth () const
|
||||||
|
{
|
||||||
|
return this->m_parallaxDepth;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string CImage::Type = "image";
|
const std::string CImage::Type = "image";
|
@ -18,14 +18,14 @@ namespace WallpaperEngine::Core::Objects
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
static CObject* fromJSON (
|
static CObject* fromJSON (
|
||||||
json data,
|
json data,
|
||||||
CContainer* container,
|
CContainer* container,
|
||||||
bool visible,
|
bool visible,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
std::string name,
|
std::string name,
|
||||||
const glm::vec3& origin,
|
const glm::vec3& origin,
|
||||||
const glm::vec3& scale,
|
const glm::vec3& scale,
|
||||||
const glm::vec3& angles
|
const glm::vec3& angles
|
||||||
);
|
);
|
||||||
|
|
||||||
const Images::CMaterial* getMaterial () const;
|
const Images::CMaterial* getMaterial () const;
|
||||||
@ -35,28 +35,31 @@ namespace WallpaperEngine::Core::Objects
|
|||||||
const glm::vec3& getColor () const;
|
const glm::vec3& getColor () const;
|
||||||
const float getBrightness () const;
|
const float getBrightness () const;
|
||||||
const uint32_t getColorBlendMode () const;
|
const uint32_t getColorBlendMode () const;
|
||||||
|
const glm::vec2& getParallaxDepth () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CImage (
|
CImage (
|
||||||
Images::CMaterial* material,
|
Images::CMaterial* material,
|
||||||
bool visible,
|
bool visible,
|
||||||
uint32_t id,
|
uint32_t id,
|
||||||
std::string name,
|
std::string name,
|
||||||
const glm::vec3& origin,
|
const glm::vec3& origin,
|
||||||
const glm::vec3& scale,
|
const glm::vec3& scale,
|
||||||
const glm::vec3& angles,
|
const glm::vec3& angles,
|
||||||
const glm::vec2& size,
|
const glm::vec2& size,
|
||||||
std::string alignment,
|
std::string alignment,
|
||||||
const glm::vec3& color,
|
const glm::vec3& color,
|
||||||
float alpha,
|
float alpha,
|
||||||
float brightness,
|
float brightness,
|
||||||
uint32_t colorBlendMode
|
uint32_t colorBlendMode,
|
||||||
|
const glm::vec2& parallaxDepth
|
||||||
);
|
);
|
||||||
|
|
||||||
static const std::string Type;
|
static const std::string Type;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
glm::vec2 m_size;
|
glm::vec2 m_size;
|
||||||
|
const glm::vec2 m_parallaxDepth;
|
||||||
Images::CMaterial* m_material;
|
Images::CMaterial* m_material;
|
||||||
std::string m_alignment;
|
std::string m_alignment;
|
||||||
float m_alpha;
|
float m_alpha;
|
||||||
|
@ -34,6 +34,8 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this->m_parallaxDisplacement = {0, 0};
|
||||||
|
|
||||||
this->m_camera->setOrthogonalProjection (
|
this->m_camera->setOrthogonalProjection (
|
||||||
scene->getOrthogonalProjection ()->getWidth (),
|
scene->getOrthogonalProjection ()->getWidth (),
|
||||||
scene->getOrthogonalProjection ()->getHeight ()
|
scene->getOrthogonalProjection ()->getHeight ()
|
||||||
@ -49,7 +51,6 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
|
|||||||
|
|
||||||
// create all objects based off their dependencies
|
// create all objects based off their dependencies
|
||||||
{
|
{
|
||||||
|
|
||||||
auto cur = scene->getObjects ().begin ();
|
auto cur = scene->getObjects ().begin ();
|
||||||
auto end = scene->getObjects ().end ();
|
auto end = scene->getObjects ().end ();
|
||||||
|
|
||||||
@ -71,7 +72,6 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
|
|||||||
|
|
||||||
this->m_objectsByRenderOrder.emplace_back ((*obj).second);
|
this->m_objectsByRenderOrder.emplace_back ((*obj).second);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Render::CObject* CScene::createObject (Core::CObject* object)
|
Render::CObject* CScene::createObject (Core::CObject* object)
|
||||||
@ -141,6 +141,17 @@ void CScene::renderFrame (glm::ivec4 viewport)
|
|||||||
// ensure the virtual mouse position is up to date
|
// ensure the virtual mouse position is up to date
|
||||||
this->updateMouse (viewport);
|
this->updateMouse (viewport);
|
||||||
|
|
||||||
|
// update the parallax position if required
|
||||||
|
if (this->getScene ()->isCameraParallax () == true)
|
||||||
|
{
|
||||||
|
float influence = this->getScene ()->getCameraParallaxMouseInfluence ();
|
||||||
|
float amount = this->getScene ()->getCameraParallaxAmount ();
|
||||||
|
float delay = this->getScene ()->getCameraParallaxDelay ();
|
||||||
|
|
||||||
|
this->m_parallaxDisplacement.x = glm::mix (this->m_parallaxDisplacement.x, (this->m_mousePosition.x * amount) * influence, delay);
|
||||||
|
this->m_parallaxDisplacement.y = glm::mix (this->m_parallaxDisplacement.y, (this->m_mousePosition.y * amount) * influence, delay);
|
||||||
|
}
|
||||||
|
|
||||||
// use the scene's framebuffer by default
|
// use the scene's framebuffer by default
|
||||||
glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer());
|
glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer());
|
||||||
// ensure we render over the whole screen
|
// ensure we render over the whole screen
|
||||||
@ -154,8 +165,6 @@ void CScene::renderFrame (glm::ivec4 viewport)
|
|||||||
|
|
||||||
void CScene::updateMouse (glm::ivec4 viewport)
|
void CScene::updateMouse (glm::ivec4 viewport)
|
||||||
{
|
{
|
||||||
// projection also affects the mouse position
|
|
||||||
auto projection = this->getScene ()->getOrthogonalProjection ();
|
|
||||||
// update virtual mouse position first
|
// update virtual mouse position first
|
||||||
CMouseInput* mouse = this->getContext ()->getMouse ();
|
CMouseInput* mouse = this->getContext ()->getMouse ();
|
||||||
// TODO: PROPERLY TRANSLATE THESE TO WHAT'S VISIBLE ON SCREEN (FOR BACKGROUNDS THAT DO NOT EXACTLY FIT ON SCREEN)
|
// TODO: PROPERLY TRANSLATE THESE TO WHAT'S VISIBLE ON SCREEN (FOR BACKGROUNDS THAT DO NOT EXACTLY FIT ON SCREEN)
|
||||||
@ -176,4 +185,10 @@ glm::vec2* CScene::getMousePosition ()
|
|||||||
return &this->m_mousePosition;
|
return &this->m_mousePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
glm::vec2* CScene::getParallaxDisplacement ()
|
||||||
|
{
|
||||||
|
return &this->m_parallaxDisplacement;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string CScene::Type = "scene";
|
const std::string CScene::Type = "scene";
|
||||||
|
@ -22,6 +22,7 @@ namespace WallpaperEngine::Render
|
|||||||
Core::CScene* getScene ();
|
Core::CScene* getScene ();
|
||||||
|
|
||||||
glm::vec2* getMousePosition ();
|
glm::vec2* getMousePosition ();
|
||||||
|
glm::vec2* getParallaxDisplacement ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void renderFrame (glm::ivec4 viewport) override;
|
void renderFrame (glm::ivec4 viewport) override;
|
||||||
@ -38,5 +39,6 @@ namespace WallpaperEngine::Render
|
|||||||
std::map<int, CObject*> m_objects;
|
std::map<int, CObject*> m_objects;
|
||||||
std::vector<CObject*> m_objectsByRenderOrder;
|
std::vector<CObject*> m_objectsByRenderOrder;
|
||||||
glm::vec2 m_mousePosition;
|
glm::vec2 m_mousePosition;
|
||||||
|
glm::vec2 m_parallaxDisplacement;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -20,19 +20,14 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
|
|||||||
glm::vec2 size = this->getSize ();
|
glm::vec2 size = this->getSize ();
|
||||||
glm::vec3 scale = this->getImage ()->getScale ();
|
glm::vec3 scale = this->getImage ()->getScale ();
|
||||||
|
|
||||||
float xleft = 0.0f;
|
|
||||||
float ytop = 0.0f;
|
|
||||||
float xright = 0.0f;
|
|
||||||
float ybottom = 0.0f;
|
|
||||||
|
|
||||||
// depending on the alignment these values might change, for now just support center
|
// depending on the alignment these values might change, for now just support center
|
||||||
if (this->getImage ()->getAlignment () == "center")
|
if (this->getImage ()->getAlignment () == "center")
|
||||||
{
|
{
|
||||||
// calculate the real position of the image
|
// calculate the real position of the image
|
||||||
xleft = (-scene_width / 2) + (origin.x - (size.x * scale.x / 2));
|
this->m_pos.x = (-scene_width / 2) + (origin.x - (size.x * scale.x / 2));
|
||||||
xright = (-scene_width / 2) + (origin.x + (size.x * scale.x / 2));
|
this->m_pos.z = (-scene_width / 2) + (origin.x + (size.x * scale.x / 2));
|
||||||
ytop = (-scene_height / 2) + origin.y + (size.y * scale.y / 2);
|
this->m_pos.y = (-scene_height / 2) + origin.y + (size.y * scale.y / 2);
|
||||||
ybottom = (-scene_height / 2) + (origin.y - (size.y * scale.y / 2));
|
this->m_pos.w = (-scene_height / 2) + (origin.y - (size.y * scale.y / 2));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -99,12 +94,12 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
|
|||||||
|
|
||||||
// build a list of vertices, these might need some change later (or maybe invert the camera)
|
// build a list of vertices, these might need some change later (or maybe invert the camera)
|
||||||
GLfloat sceneSpacePosition [] = {
|
GLfloat sceneSpacePosition [] = {
|
||||||
xleft, ytop, 0.0f,
|
this->m_pos.x, this->m_pos.y, 0.0f,
|
||||||
xright, ytop, 0.0f,
|
this->m_pos.z, this->m_pos.y, 0.0f,
|
||||||
xleft, ybottom, 0.0f,
|
this->m_pos.x, this->m_pos.w, 0.0f,
|
||||||
xleft, ybottom, 0.0f,
|
this->m_pos.x, this->m_pos.w, 0.0f,
|
||||||
xright, ytop, 0.0f,
|
this->m_pos.z, this->m_pos.y, 0.0f,
|
||||||
xright, ybottom, 0.0f
|
this->m_pos.z, this->m_pos.w, 0.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
GLfloat copySpacePosition [] = {
|
GLfloat copySpacePosition [] = {
|
||||||
@ -364,6 +359,11 @@ void CImage::render ()
|
|||||||
// determine if it's the last element in the list as this is a screen-copy-like process
|
// determine if it's the last element in the list as this is a screen-copy-like process
|
||||||
else if (std::next (cur) == end && this->getImage ()->isVisible () == true)
|
else if (std::next (cur) == end && this->getImage ()->isVisible () == true)
|
||||||
{
|
{
|
||||||
|
if (this->getScene ()->getScene ()->isCameraParallax () == true)
|
||||||
|
{
|
||||||
|
this->updateScreenSpacePosition ();
|
||||||
|
}
|
||||||
|
|
||||||
spacePosition = *this->getSceneSpacePosition ();
|
spacePosition = *this->getSceneSpacePosition ();
|
||||||
drawTo = this->getScene ()->getFBO ();
|
drawTo = this->getScene ()->getFBO ();
|
||||||
projection = this->m_modelViewProjectionScreen;
|
projection = this->m_modelViewProjectionScreen;
|
||||||
@ -381,6 +381,26 @@ void CImage::render ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CImage::updateScreenSpacePosition ()
|
||||||
|
{
|
||||||
|
double parallaxAmount = this->getScene ()->getScene ()->getCameraParallaxAmount ();
|
||||||
|
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 () *
|
||||||
|
this->getScene ()->getCamera ()->getLookAt (),
|
||||||
|
{x, y, 0.0f}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const ITexture* CImage::getTexture () const
|
const ITexture* CImage::getTexture () const
|
||||||
{
|
{
|
||||||
return this->m_texture;
|
return this->m_texture;
|
||||||
|
@ -59,6 +59,8 @@ namespace WallpaperEngine::Render::Objects
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
static const std::string Type;
|
static const std::string Type;
|
||||||
|
|
||||||
|
void updateScreenSpacePosition ();
|
||||||
private:
|
private:
|
||||||
const ITexture* m_texture;
|
const ITexture* m_texture;
|
||||||
GLuint m_sceneSpacePosition;
|
GLuint m_sceneSpacePosition;
|
||||||
@ -82,6 +84,8 @@ namespace WallpaperEngine::Render::Objects
|
|||||||
Effects::CMaterial* m_colorBlendMaterial;
|
Effects::CMaterial* m_colorBlendMaterial;
|
||||||
std::vector <Effects::CPass*> m_passes;
|
std::vector <Effects::CPass*> m_passes;
|
||||||
|
|
||||||
|
glm::vec4 m_pos;
|
||||||
|
|
||||||
double m_animationTime;
|
double m_animationTime;
|
||||||
|
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
|
Loading…
Reference in New Issue
Block a user