From 09e68345f46673cf15086e8d8d17192d2ed25cc4 Mon Sep 17 00:00:00 2001 From: Struma Date: Mon, 3 May 2021 02:18:03 -0400 Subject: [PATCH] Copy all frames of animated bitmaps --- src/display/bitmap.cpp | 53 +++++++++++++++++++++++++++++++++++------- src/display/bitmap.h | 9 +++---- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/src/display/bitmap.cpp b/src/display/bitmap.cpp index d490acda..3e9ac3aa 100644 --- a/src/display/bitmap.cpp +++ b/src/display/bitmap.cpp @@ -650,10 +650,42 @@ Bitmap::Bitmap(const Bitmap &other) other.ensureNonMega(); p = new BitmapPrivate(this); - - p->gl = shState->texPool().request(other.width(), other.height()); - - blt(0, 0, other, rect()); + + if (!other.isAnimated()) { + p->gl = shState->texPool().request(other.width(), other.height()); + blt(0, 0, other, rect()); + } + else { + p->animation.enabled = true; + p->animation.fps = other.getAnimationFPS(); + p->animation.width = other.width(); + p->animation.height = other.height(); + p->animation.lastFrame = 0; + p->animation.loop = other.getLooping(); + + char *tmp = new char[p->animation.width * p->animation.height * 4]; + for (const TEXFBO &frame : other.getFrames()) { + TEXFBO copyframe; + try { + copyframe = shState->texPool().request(p->animation.width, p->animation.height); + } catch(const Exception &e) { + for (TEXFBO &f : p->animation.frames) + shState->texPool().release(f); + delete tmp; + throw e; + } + + // FIXME: gotta see if I can copy textures directly from one TEXFBO to the other + // I'm an idiot so I don't already know + FBO::bind(frame.fbo); + gl.ReadPixels(0,0,p->animation.width,p->animation.height,GL_RGBA,GL_UNSIGNED_BYTE,tmp); + TEX::bind(copyframe.tex); + TEX::uploadImage(p->animation.width, p->animation.height, tmp, GL_RGBA); + + p->animation.frames.push_back(copyframe); + } + delete tmp; + } } Bitmap::~Bitmap() @@ -1797,7 +1829,7 @@ void Bitmap::play() p->animation.play(); } -bool Bitmap::isPlaying() +bool Bitmap::isPlaying() const { if (!p->animation.playing) return false; @@ -1824,7 +1856,7 @@ void Bitmap::gotoAndPlay(int frame) p->animation.play(); } -int Bitmap::numFrames() +int Bitmap::numFrames() const { if (!p->animation.enabled) return 1; return p->animation.frames.size(); @@ -1964,7 +1996,12 @@ void Bitmap::setAnimationFPS(float FPS) if (restart) p->animation.play(); } -float Bitmap::getAnimationFPS() +std::vector &Bitmap::getFrames() const +{ + return p->animation.frames; +} + +float Bitmap::getAnimationFPS() const { GUARD_MEGA; @@ -1978,7 +2015,7 @@ void Bitmap::setLooping(bool loop) p->animation.loop = loop; } -bool Bitmap::getLooping() +bool Bitmap::getLooping() const { GUARD_MEGA; diff --git a/src/display/bitmap.h b/src/display/bitmap.h index 0ee0751d..5d06f453 100644 --- a/src/display/bitmap.h +++ b/src/display/bitmap.h @@ -123,10 +123,10 @@ public: // Animation functions void stop(); void play(); - bool isPlaying(); + bool isPlaying() const; void gotoAndStop(int frame); void gotoAndPlay(int frame); - int numFrames(); + int numFrames() const; int currentFrameI() const; int addFrame(Bitmap &source, int position = -1); @@ -134,12 +134,13 @@ public: void nextFrame(); void previousFrame(); + std::vector &getFrames() const; void setAnimationFPS(float FPS); - float getAnimationFPS(); + float getAnimationFPS() const; void setLooping(bool loop); - bool getLooping(); + bool getLooping() const; void ensureNotPlaying() const; // ----------