mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 05:46:48 +08:00
+ Support animated images in the background
~ ITextures can now also return sub-textures width and height + added proper code to handle animated images to properly play at normal speed this should actually fix #79 for good Signed-off-by: Alexis Maiquez <almamu@almamu.com>
This commit is contained in:
parent
34635ba6ac
commit
cad78c58f9
@ -191,7 +191,7 @@ CTexture::~CTexture ()
|
||||
delete this->getHeader ();
|
||||
}
|
||||
|
||||
const GLuint CTexture::getTextureID (int imageIndex) const
|
||||
const GLuint CTexture::getTextureID (uint32_t imageIndex) const
|
||||
{
|
||||
// ensure we do not go out of bounds
|
||||
if (imageIndex > this->m_header->imageCount)
|
||||
@ -200,14 +200,20 @@ const GLuint CTexture::getTextureID (int imageIndex) const
|
||||
return this->m_textureID [imageIndex];
|
||||
}
|
||||
|
||||
const uint32_t CTexture::getTextureWidth () const
|
||||
const uint32_t CTexture::getTextureWidth (uint32_t imageIndex) const
|
||||
{
|
||||
return this->getHeader ()->textureWidth;
|
||||
if (imageIndex > this->m_header->imageCount)
|
||||
return this->getHeader ()->textureWidth;
|
||||
|
||||
return (*this->m_header->images [imageIndex].begin ())->width;
|
||||
}
|
||||
|
||||
const uint32_t CTexture::getTextureHeight () const
|
||||
const uint32_t CTexture::getTextureHeight (uint32_t imageIndex) const
|
||||
{
|
||||
return this->getHeader ()->textureHeight;
|
||||
if (imageIndex > this->m_header->imageCount)
|
||||
return this->getHeader ()->textureHeight;
|
||||
|
||||
return (*this->m_header->images [imageIndex].begin ())->height;
|
||||
}
|
||||
|
||||
const uint32_t CTexture::getRealWidth () const
|
||||
@ -235,6 +241,11 @@ const glm::vec4* CTexture::getResolution () const
|
||||
return &this->m_resolution;
|
||||
}
|
||||
|
||||
const std::vector<ITexture::TextureFrame*>& CTexture::getFrames () const
|
||||
{
|
||||
return this->getHeader ()->frames;
|
||||
}
|
||||
|
||||
const bool CTexture::isAnimated () const
|
||||
{
|
||||
return this->getHeader ()->isAnimated ();
|
||||
@ -408,8 +419,8 @@ CTexture::TextureHeader* CTexture::parseHeader (char* fileData)
|
||||
{
|
||||
TextureFrame* first = *header->frames.begin ();
|
||||
|
||||
header->gifWidth = first->width;
|
||||
header->gifHeight = first->height;
|
||||
header->gifWidth = first->width1;
|
||||
header->gifHeight = first->height1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,10 +444,10 @@ CTexture::TextureFrame* CTexture::parseAnimation (TextureHeader* header, char**
|
||||
frame->frametime = *fPointer ++;
|
||||
frame->x = *fPointer ++;
|
||||
frame->y = *fPointer ++;
|
||||
frame->width = *fPointer ++;
|
||||
frame->unk0 = *fPointer ++;
|
||||
frame->unk1 = *fPointer ++;
|
||||
frame->height = *fPointer ++;
|
||||
frame->width1 = *fPointer ++;
|
||||
frame->width2 = *fPointer ++;
|
||||
frame->height2 = *fPointer ++;
|
||||
frame->height1 = *fPointer ++;
|
||||
|
||||
// get back the pointer into fileData so it can be reused later
|
||||
*originalFileData = reinterpret_cast <char*> (fPointer);
|
||||
|
@ -21,13 +21,14 @@ namespace WallpaperEngine::Assets
|
||||
CTexture (void* fileData);
|
||||
~CTexture ();
|
||||
|
||||
const GLuint getTextureID (int imageIndex) const override;
|
||||
const uint32_t getTextureWidth () const override;
|
||||
const uint32_t getTextureHeight () const override;
|
||||
const GLuint getTextureID (uint32_t imageIndex = 0) const override;
|
||||
const uint32_t getTextureWidth (uint32_t imageIndex = 0) const override;
|
||||
const uint32_t getTextureHeight (uint32_t imageIndex = 0) const override;
|
||||
const uint32_t getRealWidth () const override;
|
||||
const uint32_t getRealHeight () const override;
|
||||
const TextureFormat getFormat () const override;
|
||||
const glm::vec4* getResolution () const override;
|
||||
const std::vector<TextureFrame*>& getFrames () const override;
|
||||
const bool isAnimated () const override;
|
||||
|
||||
private:
|
||||
@ -74,28 +75,6 @@ namespace WallpaperEngine::Assets
|
||||
void decompressData ();
|
||||
};
|
||||
|
||||
class TextureFrame
|
||||
{
|
||||
public:
|
||||
TextureFrame();
|
||||
~TextureFrame();
|
||||
|
||||
/** The image index of this frame */
|
||||
uint32_t frameNumber;
|
||||
/** The amount of time this frame spends being displayed */
|
||||
float frametime;
|
||||
/** The x position of the frame in the texture */
|
||||
float x;
|
||||
/** The y position of the frame in the texture */
|
||||
float y;
|
||||
/** The width of the frame in the texture */
|
||||
float width;
|
||||
float unk0;
|
||||
float unk1;
|
||||
/** The height of the frame in the texture */
|
||||
float height;
|
||||
};
|
||||
|
||||
/**
|
||||
* Configures how the texture will be handled by the background
|
||||
*/
|
||||
|
@ -2,12 +2,35 @@
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <glm/vec4.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace WallpaperEngine::Assets
|
||||
{
|
||||
class ITexture
|
||||
{
|
||||
public:
|
||||
class TextureFrame
|
||||
{
|
||||
public:
|
||||
TextureFrame();
|
||||
~TextureFrame();
|
||||
|
||||
/** The image index of this frame */
|
||||
uint32_t frameNumber;
|
||||
/** The amount of time this frame spends being displayed */
|
||||
float frametime;
|
||||
/** The x position of the frame in the texture */
|
||||
float x;
|
||||
/** The y position of the frame in the texture */
|
||||
float y;
|
||||
/** The width of the frame in the texture */
|
||||
float width1;
|
||||
float width2;
|
||||
float height2;
|
||||
/** The height of the frame in the texture */
|
||||
float height1;
|
||||
};
|
||||
|
||||
enum TextureFormat : uint32_t
|
||||
{
|
||||
ARGB8888 = 0,
|
||||
@ -18,12 +41,13 @@ namespace WallpaperEngine::Assets
|
||||
R8 = 9,
|
||||
};
|
||||
|
||||
virtual const GLuint getTextureID (int imageIndex) const = 0;
|
||||
virtual const uint32_t getTextureWidth () const = 0;
|
||||
virtual const uint32_t getTextureHeight () const = 0;
|
||||
virtual const GLuint getTextureID (uint32_t imageIndex = 0) const = 0;
|
||||
virtual const uint32_t getTextureWidth (uint32_t imageIndex = 0) const = 0;
|
||||
virtual const uint32_t getTextureHeight (uint32_t imageIndex = 0) const = 0;
|
||||
virtual const uint32_t getRealWidth () const = 0;
|
||||
virtual const uint32_t getRealHeight () const = 0;
|
||||
virtual const TextureFormat getFormat () const = 0;
|
||||
virtual const std::vector<TextureFrame*>& getFrames () const = 0;
|
||||
virtual const glm::vec4* getResolution () const = 0;
|
||||
virtual const bool isAnimated () const = 0;
|
||||
};
|
||||
|
@ -69,16 +69,16 @@ GLuint CFBO::getDepthbuffer () const
|
||||
return this->m_depthbuffer;
|
||||
}
|
||||
|
||||
const GLuint CFBO::getTextureID (int imageIndex) const
|
||||
const GLuint CFBO::getTextureID (uint32_t imageIndex) const
|
||||
{
|
||||
return this->m_texture;
|
||||
}
|
||||
|
||||
const uint32_t CFBO::getTextureWidth () const
|
||||
const uint32_t CFBO::getTextureWidth (uint32_t imageIndex) const
|
||||
{
|
||||
return this->m_resolution.x;
|
||||
}
|
||||
const uint32_t CFBO::getTextureHeight () const
|
||||
const uint32_t CFBO::getTextureHeight (uint32_t imageIndex) const
|
||||
{
|
||||
return this->m_resolution.y;
|
||||
}
|
||||
@ -93,6 +93,11 @@ const uint32_t CFBO::getRealHeight () const
|
||||
return this->m_resolution.w;
|
||||
}
|
||||
|
||||
const std::vector<ITexture::TextureFrame*>& CFBO::getFrames () const
|
||||
{
|
||||
return std::vector<TextureFrame*> ();
|
||||
}
|
||||
|
||||
const glm::vec4* CFBO::getResolution () const
|
||||
{
|
||||
return &this->m_resolution;
|
||||
|
@ -18,11 +18,12 @@ namespace WallpaperEngine::Render
|
||||
const ITexture::TextureFormat getFormat () const override;
|
||||
GLuint getFramebuffer () const;
|
||||
GLuint getDepthbuffer () const;
|
||||
const GLuint getTextureID (int imageIndex) const override;
|
||||
const uint32_t getTextureWidth () const override;
|
||||
const uint32_t getTextureHeight () const override;
|
||||
const GLuint getTextureID (uint32_t imageIndex = 0) const override;
|
||||
const uint32_t getTextureWidth (uint32_t imageIndex = 0) const override;
|
||||
const uint32_t getTextureHeight (uint32_t imageIndex = 0) const override;
|
||||
const uint32_t getRealWidth () const override;
|
||||
const uint32_t getRealHeight () const override;
|
||||
const std::vector<TextureFrame*>& getFrames () const override;
|
||||
const glm::vec4* getResolution () const override;
|
||||
const bool isAnimated () const override;
|
||||
|
||||
|
@ -69,8 +69,8 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
|
||||
nameA << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_a";
|
||||
nameB << "_rt_imageLayerComposite_" << this->getImage ()->getId () << "_b";
|
||||
|
||||
this->m_currentMainFBO = this->m_mainFBO = scene->createFBO (nameA.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getRealWidth (), this->m_texture->getRealHeight (), this->m_texture->getRealWidth (), this->m_texture->getRealHeight ());
|
||||
this->m_currentSubFBO = this->m_subFBO = scene->createFBO (nameB.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getRealWidth (), this->m_texture->getRealHeight (), this->m_texture->getRealWidth (), this->m_texture->getRealHeight ());
|
||||
this->m_currentMainFBO = this->m_mainFBO = scene->createFBO (nameA.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight (), this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight ());
|
||||
this->m_currentSubFBO = this->m_subFBO = scene->createFBO (nameB.str (), ITexture::TextureFormat::ARGB8888, 1, this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight (), this->m_texture->getTextureWidth (), this->m_texture->getTextureHeight ());
|
||||
|
||||
GLfloat realWidth = this->m_texture->getRealWidth () / 2;
|
||||
GLfloat realHeight = this->m_texture->getRealHeight () / 2;
|
||||
@ -106,8 +106,14 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
|
||||
float width = 1.0f;
|
||||
float height = 1.0f;
|
||||
|
||||
if (this->getTexture ()->isAnimated () == true)
|
||||
{
|
||||
// animated images use different coordinates as they're essentially a texture atlast
|
||||
width = static_cast<float> (this->getTexture ()->getRealWidth ()) / static_cast<float> (this->getTexture ()->getTextureWidth ());
|
||||
height = static_cast<float> (this->getTexture ()->getRealHeight ()) / static_cast<float> (this->getTexture ()->getTextureHeight ());
|
||||
}
|
||||
// calculate the correct texCoord limits for the texture based on the texture screen size and real size
|
||||
if (this->getTexture () != nullptr &&
|
||||
else if (this->getTexture () != nullptr &&
|
||||
(this->getTexture ()->getTextureWidth () != this->getTexture ()->getRealWidth () ||
|
||||
this->getTexture ()->getTextureHeight () != this->getTexture ()->getRealHeight ())
|
||||
)
|
||||
@ -122,12 +128,24 @@ CImage::CImage (CScene* scene, Core::Objects::CImage* image) :
|
||||
height = size.y * scale.y / y;
|
||||
}
|
||||
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
|
||||
if (this->getTexture ()->isAnimated () == true)
|
||||
{
|
||||
// animations should be copied completely
|
||||
x = 0.0f;
|
||||
y = 0.0f;
|
||||
width = 1.0f;
|
||||
height = 1.0f;
|
||||
}
|
||||
|
||||
GLfloat texcoordCopy [] = {
|
||||
0.0f, 0.0f,
|
||||
width, 0.0f,
|
||||
0.0f, height,
|
||||
0.0f, height,
|
||||
width, 0.0f,
|
||||
x, y,
|
||||
width, y,
|
||||
x, height,
|
||||
x, height,
|
||||
width, y,
|
||||
width, height
|
||||
};
|
||||
|
||||
@ -177,18 +195,30 @@ void CImage::setup ()
|
||||
new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)),
|
||||
this->m_image->getMaterial ()
|
||||
);
|
||||
|
||||
// generate the main material used to render the image
|
||||
this->m_material = new Effects::CMaterial (
|
||||
new CEffect (this, new Core::Objects::CEffect ("", "", "", "", this->m_image)),
|
||||
this->m_image->getMaterial ()
|
||||
);
|
||||
|
||||
// generate the effects used by this material
|
||||
auto cur = this->getImage ()->getEffects ().begin ();
|
||||
auto end = this->getImage ()->getEffects ().end ();
|
||||
{
|
||||
// generate the effects used by this material
|
||||
auto cur = this->getImage ()->getEffects ().begin ();
|
||||
auto end = this->getImage ()->getEffects ().end ();
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
this->m_effects.emplace_back (new CEffect (this, *cur));
|
||||
}
|
||||
|
||||
// calculate full animation time (if any)
|
||||
this->m_animationTime = 0.0f;
|
||||
|
||||
auto cur = this->getTexture ()->getFrames ().begin ();
|
||||
auto end = this->getTexture ()->getFrames ().end ();
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
this->m_effects.emplace_back (new CEffect (this, *cur));
|
||||
this->m_animationTime += (*cur)->frametime;
|
||||
}
|
||||
|
||||
void CImage::pinpongFramebuffer (CFBO** drawTo, ITexture** asInput)
|
||||
@ -209,19 +239,29 @@ void CImage::pinpongFramebuffer (CFBO** drawTo, ITexture** asInput)
|
||||
|
||||
void CImage::simpleRender ()
|
||||
{
|
||||
// first render to the composite layer
|
||||
auto cur = this->m_copyMaterial->getPasses ().begin ();
|
||||
auto end = this->m_copyMaterial->getPasses ().end ();
|
||||
ITexture* input = this->m_mainFBO;
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
(*cur)->render (this->m_mainFBO, this->getTexture (), *this->getCopySpacePosition (), *this->getTexCoordCopy (), this->m_modelViewProjectionPass);
|
||||
// FIXME: THIS IS A QUICK HACK FOR ANIMATED IMAGES, IF ANY OF THOSE HAVE ANY EFFECT ON THEM THIS WILL LIKELY BREAK
|
||||
if (this->getTexture ()->isAnimated () == true)
|
||||
{
|
||||
input = this->getTexture ();
|
||||
}
|
||||
else
|
||||
{
|
||||
// first render to the composite layer
|
||||
auto cur = this->m_copyMaterial->getPasses ().begin ();
|
||||
auto end = this->m_copyMaterial->getPasses ().end ();
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
(*cur)->render (this->m_mainFBO, this->getTexture (), *this->getCopySpacePosition (), *this->getTexCoordCopy (), this->m_modelViewProjectionPass);
|
||||
}
|
||||
|
||||
// a simple material renders directly to the screen
|
||||
cur = this->m_material->getPasses ().begin ();
|
||||
end = this->m_material->getPasses ().end ();
|
||||
auto cur = this->m_material->getPasses ().begin ();
|
||||
auto end = this->m_material->getPasses ().end ();
|
||||
|
||||
for (; cur != end; cur ++)
|
||||
(*cur)->render (this->getScene ()->getFBO (), this->m_mainFBO, *this->getSceneSpacePosition (), *this->getTexCoordPass (), this->m_modelViewProjectionScreen);
|
||||
(*cur)->render (this->getScene ()->getFBO (), input, *this->getSceneSpacePosition (), *this->getTexCoordPass (), this->m_modelViewProjectionScreen);
|
||||
}
|
||||
|
||||
void CImage::complexRender ()
|
||||
@ -319,6 +359,11 @@ ITexture* CImage::getTexture () const
|
||||
return this->m_texture;
|
||||
}
|
||||
|
||||
const double CImage::getAnimationTime () const
|
||||
{
|
||||
return this->m_animationTime;
|
||||
}
|
||||
|
||||
const Core::Objects::CImage* CImage::getImage () const
|
||||
{
|
||||
return this->m_image;
|
||||
|
@ -45,6 +45,7 @@ namespace WallpaperEngine::Render::Objects
|
||||
const GLuint* getTexCoordCopy () const;
|
||||
const GLuint* getTexCoordPass () const;
|
||||
ITexture* getTexture () const;
|
||||
const double getAnimationTime () const;
|
||||
|
||||
/**
|
||||
* Performs a ping-pong on the available framebuffers to be able to continue rendering things to them
|
||||
@ -80,5 +81,7 @@ namespace WallpaperEngine::Render::Objects
|
||||
std::vector<CEffect*> m_effects;
|
||||
Effects::CMaterial* m_material;
|
||||
Effects::CMaterial* m_copyMaterial;
|
||||
|
||||
double m_animationTime;
|
||||
};
|
||||
}
|
||||
|
@ -138,8 +138,42 @@ void CPass::render (CFBO* drawTo, ITexture* input, GLuint position, GLuint texco
|
||||
|
||||
ITexture* texture = this->resolveTexture (input, 0, input);
|
||||
|
||||
uint32_t currentTexture = 0;
|
||||
glm::vec2 translation = {0.0f, 0.0f};
|
||||
glm::vec4 rotation = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
if (texture->isAnimated () == true)
|
||||
{
|
||||
// calculate current texture and frame
|
||||
double currentRenderTime = fmod (static_cast <double> (g_Time), this->m_material->getImage ()->getAnimationTime ());
|
||||
|
||||
// find the right frame now
|
||||
auto frameCur = texture->getFrames ().begin ();
|
||||
auto frameEnd = texture->getFrames ().end ();
|
||||
|
||||
for (; frameCur != frameEnd; frameCur ++)
|
||||
{
|
||||
currentRenderTime -= (*frameCur)->frametime;
|
||||
|
||||
if (currentRenderTime <= 0.0f)
|
||||
{
|
||||
// frame found, store coordinates and done
|
||||
currentTexture = (*frameCur)->frameNumber;
|
||||
|
||||
translation.x = (*frameCur)->x / texture->getTextureWidth (currentTexture);
|
||||
translation.y = (*frameCur)->y / texture->getTextureHeight (currentTexture);
|
||||
|
||||
rotation.x = (*frameCur)->width1 / static_cast<float> (texture->getTextureWidth (currentTexture));
|
||||
rotation.y = (*frameCur)->width2 / static_cast<float> (texture->getTextureWidth(currentTexture));
|
||||
rotation.z = (*frameCur)->height2 / static_cast<float> (texture->getTextureHeight (currentTexture));
|
||||
rotation.w = (*frameCur)->height1 / static_cast<float> (texture->getTextureHeight (currentTexture));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glActiveTexture (GL_TEXTURE0);
|
||||
glBindTexture (GL_TEXTURE_2D, texture->getTextureID (0));
|
||||
glBindTexture (GL_TEXTURE_2D, texture->getTextureID (currentTexture));
|
||||
int lastTextureIndex = 0;
|
||||
|
||||
// first bind the textures to their sampler place
|
||||
@ -233,11 +267,14 @@ void CPass::render (CFBO* drawTo, ITexture* input, GLuint position, GLuint texco
|
||||
|
||||
if (this->g_Texture0Rotation != -1)
|
||||
{
|
||||
glUniform4f (this->g_Texture0Rotation, 1.0f, 0.0f, 1.0f, 0.0f);
|
||||
// used in animations when one of the frames is vertical instead of horizontal
|
||||
// rotation with translation = origin and end of the image to display
|
||||
glUniform4f (this->g_Texture0Rotation, rotation.x, rotation.y, rotation.z, rotation.w);
|
||||
}
|
||||
if (this->g_Texture0Translation != -1)
|
||||
{
|
||||
glUniform2f (this->g_Texture0Translation, 0.0f, 0.0f);
|
||||
// this actually picks the origin point of the image from the atlast
|
||||
glUniform2f (this->g_Texture0Translation, translation.x, translation.y);
|
||||
}
|
||||
{
|
||||
auto cur = this->m_attribs.begin ();
|
||||
|
Loading…
Reference in New Issue
Block a user