mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-07-14 05:12:25 +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;
|
||||
|
||||
CImage::CImage (
|
||||
Images::CMaterial* material,
|
||||
bool visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
const glm::vec3& origin,
|
||||
const glm::vec3& scale,
|
||||
const glm::vec3& angles,
|
||||
const glm::vec2& size,
|
||||
std::string alignment,
|
||||
const glm::vec3& color,
|
||||
float alpha,
|
||||
float brightness,
|
||||
uint32_t colorBlendMode) :
|
||||
CObject (visible, id, std::move(name), Type, origin, scale, angles),
|
||||
m_size (size),
|
||||
m_material (material),
|
||||
m_alignment (std::move(alignment)),
|
||||
m_color (color),
|
||||
m_alpha (alpha),
|
||||
m_brightness (brightness),
|
||||
m_colorBlendMode (colorBlendMode)
|
||||
Images::CMaterial* material,
|
||||
bool visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
const glm::vec3& origin,
|
||||
const glm::vec3& scale,
|
||||
const glm::vec3& angles,
|
||||
const glm::vec2& size,
|
||||
std::string alignment,
|
||||
const glm::vec3& color,
|
||||
float alpha,
|
||||
float brightness,
|
||||
uint32_t colorBlendMode,
|
||||
const glm::vec2& parallaxDepth
|
||||
) :
|
||||
CObject (visible, id, std::move(name), Type, origin, scale, angles),
|
||||
m_size (size),
|
||||
m_material (material),
|
||||
m_alignment (std::move(alignment)),
|
||||
m_color (color),
|
||||
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 brightness_val = jsonFindDefault <float> (data, "brightness", 1.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));
|
||||
|
||||
@ -67,7 +71,8 @@ WallpaperEngine::Core::CObject* CImage::fromJSON (
|
||||
WallpaperEngine::Core::aToVector3 (color_val),
|
||||
alpha,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
const glm::vec2& CImage::getParallaxDepth () const
|
||||
{
|
||||
return this->m_parallaxDepth;
|
||||
}
|
||||
|
||||
const std::string CImage::Type = "image";
|
@ -18,14 +18,14 @@ namespace WallpaperEngine::Core::Objects
|
||||
|
||||
public:
|
||||
static CObject* fromJSON (
|
||||
json data,
|
||||
CContainer* container,
|
||||
bool visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
const glm::vec3& origin,
|
||||
const glm::vec3& scale,
|
||||
const glm::vec3& angles
|
||||
json data,
|
||||
CContainer* container,
|
||||
bool visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
const glm::vec3& origin,
|
||||
const glm::vec3& scale,
|
||||
const glm::vec3& angles
|
||||
);
|
||||
|
||||
const Images::CMaterial* getMaterial () const;
|
||||
@ -35,28 +35,31 @@ namespace WallpaperEngine::Core::Objects
|
||||
const glm::vec3& getColor () const;
|
||||
const float getBrightness () const;
|
||||
const uint32_t getColorBlendMode () const;
|
||||
const glm::vec2& getParallaxDepth () const;
|
||||
|
||||
protected:
|
||||
CImage (
|
||||
Images::CMaterial* material,
|
||||
bool visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
const glm::vec3& origin,
|
||||
const glm::vec3& scale,
|
||||
const glm::vec3& angles,
|
||||
const glm::vec2& size,
|
||||
std::string alignment,
|
||||
const glm::vec3& color,
|
||||
float alpha,
|
||||
float brightness,
|
||||
uint32_t colorBlendMode
|
||||
Images::CMaterial* material,
|
||||
bool visible,
|
||||
uint32_t id,
|
||||
std::string name,
|
||||
const glm::vec3& origin,
|
||||
const glm::vec3& scale,
|
||||
const glm::vec3& angles,
|
||||
const glm::vec2& size,
|
||||
std::string alignment,
|
||||
const glm::vec3& color,
|
||||
float alpha,
|
||||
float brightness,
|
||||
uint32_t colorBlendMode,
|
||||
const glm::vec2& parallaxDepth
|
||||
);
|
||||
|
||||
static const std::string Type;
|
||||
|
||||
private:
|
||||
glm::vec2 m_size;
|
||||
const glm::vec2 m_parallaxDepth;
|
||||
Images::CMaterial* m_material;
|
||||
std::string m_alignment;
|
||||
float m_alpha;
|
||||
|
@ -34,6 +34,8 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
|
||||
}
|
||||
}
|
||||
|
||||
this->m_parallaxDisplacement = {0, 0};
|
||||
|
||||
this->m_camera->setOrthogonalProjection (
|
||||
scene->getOrthogonalProjection ()->getWidth (),
|
||||
scene->getOrthogonalProjection ()->getHeight ()
|
||||
@ -49,7 +51,6 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
|
||||
|
||||
// create all objects based off their dependencies
|
||||
{
|
||||
|
||||
auto cur = scene->getObjects ().begin ();
|
||||
auto end = scene->getObjects ().end ();
|
||||
|
||||
@ -71,7 +72,6 @@ CScene::CScene (Core::CScene* scene, CContext* context) :
|
||||
|
||||
this->m_objectsByRenderOrder.emplace_back ((*obj).second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
glBindFramebuffer (GL_FRAMEBUFFER, this->getWallpaperFramebuffer());
|
||||
// ensure we render over the whole screen
|
||||
@ -154,8 +165,6 @@ void CScene::renderFrame (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
|
||||
CMouseInput* mouse = this->getContext ()->getMouse ();
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
glm::vec2* CScene::getParallaxDisplacement ()
|
||||
{
|
||||
return &this->m_parallaxDisplacement;
|
||||
}
|
||||
|
||||
const std::string CScene::Type = "scene";
|
||||
|
@ -22,6 +22,7 @@ namespace WallpaperEngine::Render
|
||||
Core::CScene* getScene ();
|
||||
|
||||
glm::vec2* getMousePosition ();
|
||||
glm::vec2* getParallaxDisplacement ();
|
||||
|
||||
protected:
|
||||
void renderFrame (glm::ivec4 viewport) override;
|
||||
@ -38,5 +39,6 @@ namespace WallpaperEngine::Render
|
||||
std::map<int, CObject*> m_objects;
|
||||
std::vector<CObject*> m_objectsByRenderOrder;
|
||||
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::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
|
||||
if (this->getImage ()->getAlignment () == "center")
|
||||
{
|
||||
// calculate the real position of the image
|
||||
xleft = (-scene_width / 2) + (origin.x - (size.x * scale.x / 2));
|
||||
xright = (-scene_width / 2) + (origin.x + (size.x * scale.x / 2));
|
||||
ytop = (-scene_height / 2) + origin.y + (size.y * scale.y / 2);
|
||||
ybottom = (-scene_height / 2) + (origin.y - (size.y * scale.y / 2));
|
||||
this->m_pos.x = (-scene_width / 2) + (origin.x - (size.x * scale.x / 2));
|
||||
this->m_pos.z = (-scene_width / 2) + (origin.x + (size.x * scale.x / 2));
|
||||
this->m_pos.y = (-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
|
||||
{
|
||||
@ -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)
|
||||
GLfloat sceneSpacePosition [] = {
|
||||
xleft, ytop, 0.0f,
|
||||
xright, ytop, 0.0f,
|
||||
xleft, ybottom, 0.0f,
|
||||
xleft, ybottom, 0.0f,
|
||||
xright, ytop, 0.0f,
|
||||
xright, ybottom, 0.0f
|
||||
this->m_pos.x, this->m_pos.y, 0.0f,
|
||||
this->m_pos.z, this->m_pos.y, 0.0f,
|
||||
this->m_pos.x, this->m_pos.w, 0.0f,
|
||||
this->m_pos.x, this->m_pos.w, 0.0f,
|
||||
this->m_pos.z, this->m_pos.y, 0.0f,
|
||||
this->m_pos.z, this->m_pos.w, 0.0f
|
||||
};
|
||||
|
||||
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
|
||||
else if (std::next (cur) == end && this->getImage ()->isVisible () == true)
|
||||
{
|
||||
if (this->getScene ()->getScene ()->isCameraParallax () == true)
|
||||
{
|
||||
this->updateScreenSpacePosition ();
|
||||
}
|
||||
|
||||
spacePosition = *this->getSceneSpacePosition ();
|
||||
drawTo = this->getScene ()->getFBO ();
|
||||
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
|
||||
{
|
||||
return this->m_texture;
|
||||
|
@ -59,6 +59,8 @@ namespace WallpaperEngine::Render::Objects
|
||||
|
||||
protected:
|
||||
static const std::string Type;
|
||||
|
||||
void updateScreenSpacePosition ();
|
||||
private:
|
||||
const ITexture* m_texture;
|
||||
GLuint m_sceneSpacePosition;
|
||||
@ -82,6 +84,8 @@ namespace WallpaperEngine::Render::Objects
|
||||
Effects::CMaterial* m_colorBlendMaterial;
|
||||
std::vector <Effects::CPass*> m_passes;
|
||||
|
||||
glm::vec4 m_pos;
|
||||
|
||||
double m_animationTime;
|
||||
|
||||
bool m_initialized;
|
||||
|
Loading…
Reference in New Issue
Block a user