Added a basic (and somewhat convincing) parallax effect for the camera

Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
Alexis Maiquez 2022-11-03 18:43:05 +01:00
parent c13d743022
commit 625397ea0c
6 changed files with 117 additions and 62 deletions

View File

@ -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";

View File

@ -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;

View File

@ -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";

View File

@ -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;
}; };
} }

View File

@ -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;

View File

@ -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;