diff --git a/source/blood/src/credits.cpp b/source/blood/src/credits.cpp index cecfa39d5..9636e2fd9 100644 --- a/source/blood/src/credits.cpp +++ b/source/blood/src/credits.cpp @@ -172,7 +172,7 @@ void credPlaySmk(const char *_pzSMK, const char *_pzWAV, int nWav) uint8_t palette[768]; AnimTextures animtex; TArray pFrame(nWidth * nHeight + std::max(nWidth, nHeight), true); - animtex.SetSize(nWidth, nHeight); + animtex.SetSize(AnimTexture::Paletted, nWidth, nHeight); int nFrameRate = Smacker_GetFrameRate(hSMK); int nFrames = Smacker_GetNumFrames(hSMK); diff --git a/source/build/src/animvpx.cpp b/source/build/src/animvpx.cpp index 5ef1b66d7..0fcb12894 100644 --- a/source/build/src/animvpx.cpp +++ b/source/build/src/animvpx.cpp @@ -14,6 +14,8 @@ #include "bitmap.h" #include "v_draw.h" #include "v_video.h" +#include "texturemanager.h" +#include "animtexture.h" #undef UNUSED #define VPX_CODEC_DISABLE_COMPAT 1 @@ -21,74 +23,6 @@ #include #include "animvpx.h" - -class VPXTexture : public FTexture -{ -public: - VPXTexture(); - void SetFrame(const void* data, int width, int height); - virtual FBitmap GetBgraBitmap(const PalEntry* remap, int* trans) override; - -protected: - - const void* data; - -public: - -}; - -//========================================================================== -// -// -// -//========================================================================== - -VPXTexture::VPXTexture() {} - -void VPXTexture::SetFrame(const void *data_, int width, int height) -{ - Width = width; - Height = height; - data = data_; - SystemTextures.Clean(); -} - -//=========================================================================== -// -// FPNGTexture::CopyPixels -// -//=========================================================================== - -FBitmap VPXTexture::GetBgraBitmap(const PalEntry* remap, int* trans) -{ - FBitmap bmp; - - bmp.Create(Width, Height); - - auto spix = (uint8_t*)data; - auto dpix = bmp.GetPixels(); - for (int i = 0; i < Width * Height; i++) - { - int p = i * 4; - float y = spix[p] * (1/255.f); - float u = spix[p+1] * (1 / 255.f) - 0.5f; - float v = spix[p+2] * (1 / 255.f) - 0.5f; - - y = 1.1643f * (y - 0.0625f); - - float r = y + 1.5958f * v; - float g = y - 0.39173f * u - 0.81290f * v; - float b = y + 2.017f * u; - - dpix[p + 0] = (uint8_t)(clamp(b, 0, 1.f) * 255); - dpix[p + 1] = (uint8_t)(clamp(g, 0, 1.f) * 255); - dpix[p + 2] = (uint8_t)(clamp(r, 0, 1.f) * 255); - dpix[p + 3] = 255; - } - return bmp; -} - - const char *animvpx_read_ivf_header_errmsg[] = { "All OK", "couldn't read 32-byte IVF header", @@ -418,17 +352,18 @@ static int which; void animvpx_setup_glstate(int32_t animvpx_flags) { ////////// GL STATE ////////// - vpxtex[0] = MakeGameTexture(new VPXTexture, nullptr, ETextureType::Special); - vpxtex[1] = MakeGameTexture(new VPXTexture, nullptr, ETextureType::Special); + vpxtex[0] = TexMan.FindGameTexture("AnimTextureFrame1", ETextureType::Override); + vpxtex[1] = TexMan.FindGameTexture("AnimTextureFrame2", ETextureType::Override); + sampler = CLAMP_XY; GLInterface.ClearScreen(0, true); } void animvpx_restore_glstate(void) { - delete vpxtex[0]; + vpxtex[0]->CleanHardwareData(); vpxtex[0] = nullptr; - delete vpxtex[1]; + vpxtex[1]->CleanHardwareData(); vpxtex[1] = nullptr; } @@ -443,8 +378,8 @@ int32_t animvpx_render_frame(animvpx_codec_ctx *codec, double animvpx_aspect) return 2; // shouldn't happen which ^= 1; - static_cast(vpxtex[which]->GetTexture())->SetFrame(codec->pic, codec->width, codec->height); - vpxtex[which]->CleanHardwareData(); + static_cast(vpxtex[which]->GetTexture())->SetFrameSize(AnimTexture::YUV, codec->width, codec->height); + static_cast(vpxtex[which]->GetTexture())->SetFrame(nullptr, codec->pic); float vid_wbyh = ((float)codec->width)/codec->height; if (animvpx_aspect > 0) diff --git a/source/common/textures/animtexture.cpp b/source/common/textures/animtexture.cpp index 2d06eccab..b19efa167 100644 --- a/source/common/textures/animtexture.cpp +++ b/source/common/textures/animtexture.cpp @@ -33,6 +33,8 @@ */ #include "animtexture.h" #include "bitmap.h" +#include "texturemanager.h" +#include "templates.h" //========================================================================== // @@ -40,17 +42,19 @@ // //========================================================================== -void AnimTexture::SetFrameSize(int width, int height) +void AnimTexture::SetFrameSize(int format, int width, int height) { FTexture::SetSize(width, height); - Image.Resize(width * height); + Image.Resize(width * height * (format == Paletted ? 1 : 3)); + pixelformat = format; } void AnimTexture::SetFrame(const uint8_t* palette, const void* data_) { memcpy(Palette, palette, 768); - memcpy(Image.Data(), data_, Width * Height); + memcpy(Image.Data(), data_, Width * Height * (pixelformat == Paletted ? 1 : 3)); CleanHardwareTextures(); + pixelformat = Paletted; } //=========================================================================== @@ -67,14 +71,51 @@ FBitmap AnimTexture::GetBgraBitmap(const PalEntry* remap, int* trans) auto spix = Image.Data(); auto dpix = bmp.GetPixels(); - for (int i = 0; i < Width * Height; i++) + if (pixelformat == Paletted) { - int p = i * 4; - int index = spix[i]; - dpix[p + 0] = Palette[index * 3 + 2]; - dpix[p + 1] = Palette[index * 3 + 1]; - dpix[p + 2] = Palette[index * 3]; - dpix[p + 3] = 255; + for (int i = 0; i < Width * Height; i++) + { + int p = i * 4; + int index = spix[i]; + dpix[p + 0] = Palette[index * 3 + 2]; + dpix[p + 1] = Palette[index * 3 + 1]; + dpix[p + 2] = Palette[index * 3]; + dpix[p + 3] = 255; + } + } + else if (pixelformat == RGB) + { + for (int i = 0; i < Width * Height; i++) + { + int p = i * 4; + dpix[p + 0] = spix[p + 2]; + dpix[p + 1] = spix[p + 1]; + dpix[p + 2] = spix[p]; + dpix[p + 3] = 255; + } + } + else if (pixelformat == YUV) + { + for (int i = 0; i < Width * Height; i++) + { + int p = i * 4; + float y = spix[p] * (1 / 255.f); + float u = spix[p + 1] * (1 / 255.f) - 0.5f; + float v = spix[p + 2] * (1 / 255.f) - 0.5f; + + y = 1.1643f * (y - 0.0625f); + + float r = y + 1.5958f * v; + float g = y - 0.39173f * u - 0.81290f * v; + float b = y + 2.017f * u; + + dpix[p + 0] = (uint8_t)(clamp(b, 0.f, 1.f) * 255); + dpix[p + 1] = (uint8_t)(clamp(g, 0.f, 1.f) * 255); + dpix[p + 2] = (uint8_t)(clamp(r, 0.f, 1.f) * 255); + dpix[p + 3] = 255; + } + return bmp; + } return bmp; } @@ -88,20 +129,20 @@ FBitmap AnimTexture::GetBgraBitmap(const PalEntry* remap, int* trans) AnimTextures::AnimTextures() { active = 1; - tex[0] = MakeGameTexture(new AnimTexture, "", ETextureType::Special); - tex[1] = MakeGameTexture(new AnimTexture, "", ETextureType::Special); + tex[0] = TexMan.FindGameTexture("AnimTextureFrame1", ETextureType::Override); + tex[1] = TexMan.FindGameTexture("AnimTextureFrame2", ETextureType::Override); } AnimTextures::~AnimTextures() { - delete tex[0]; - delete tex[1]; + tex[0]->CleanHardwareData(true); + tex[1]->CleanHardwareData(true); } -void AnimTextures::SetSize(int width, int height) +void AnimTextures::SetSize(int format, int width, int height) { - static_cast(tex[0]->GetTexture())->SetFrameSize(width, height); - static_cast(tex[1]->GetTexture())->SetFrameSize(width, height); + static_cast(tex[0]->GetTexture())->SetFrameSize(format, width, height); + static_cast(tex[1]->GetTexture())->SetFrameSize(format, width, height); tex[0]->SetSize(width, height); tex[1]->SetSize(width, height); } @@ -111,8 +152,3 @@ void AnimTextures::SetFrame(const uint8_t* palette, const void* data) active ^= 1; static_cast(tex[active]->GetTexture())->SetFrame(palette, data); } - -FGameTexture* AnimTextures::GetFrame() -{ - return tex[active]; -} diff --git a/source/common/textures/animtexture.h b/source/common/textures/animtexture.h index 2515253a7..5710d44b3 100644 --- a/source/common/textures/animtexture.h +++ b/source/common/textures/animtexture.h @@ -7,9 +7,16 @@ class AnimTexture : public FTexture { uint8_t Palette[768]; TArray Image; + int pixelformat; public: + enum + { + Paletted = 0, + RGB = 1, + YUV = 2 + }; AnimTexture() = default; - void SetFrameSize(int width, int height); + void SetFrameSize(int format, int width, int height); void SetFrame(const uint8_t* palette, const void* data); virtual FBitmap GetBgraBitmap(const PalEntry* remap, int* trans) override; }; @@ -22,7 +29,15 @@ class AnimTextures public: AnimTextures(); ~AnimTextures(); - void SetSize(int width, int height); + void SetSize(int format, int width, int height); void SetFrame(const uint8_t* palette, const void* data); - FGameTexture* GetFrame(); + FGameTexture* GetFrame() + { + return tex[active]; + } + + FTextureID GetFrameID() + { + return tex[active]->GetID(); + } }; diff --git a/source/common/textures/texturemanager.cpp b/source/common/textures/texturemanager.cpp index 73918db92..60ed0c747 100644 --- a/source/common/textures/texturemanager.cpp +++ b/source/common/textures/texturemanager.cpp @@ -45,6 +45,7 @@ #include "sc_man.h" #include "image.h" #include "vectors.h" +#include "animtexture.h" #include "formats/multipatchtexture.h" FTextureManager TexMan; @@ -1158,6 +1159,9 @@ void FTextureManager::Init(void (*progressFunc_)(), void (*checkForHacks)(BuildI AddGameTexture(CreateShaderTexture(false, true)); AddGameTexture(CreateShaderTexture(true, false)); AddGameTexture(CreateShaderTexture(true, true)); + // Add two animtexture entries so that movie playback can call functions using texture IDs. + AddGameTexture(MakeGameTexture(new AnimTexture(), "AnimTextureFrame1", ETextureType::Override)); + AddGameTexture(MakeGameTexture(new AnimTexture(), "AnimTextureFrame2", ETextureType::Override)); int wadcnt = fileSystem.GetNumWads(); diff --git a/source/duke3d/src/anim.cpp b/source/duke3d/src/anim.cpp index 2bbf0774a..1276042b7 100644 --- a/source/duke3d/src/anim.cpp +++ b/source/duke3d/src/anim.cpp @@ -444,7 +444,7 @@ int32_t Anim_Play(const char *fn) { AnimTextures animtex; - animtex.SetSize(320, 200); + animtex.SetSize(AnimTexture::Paletted, 320, 200); do { diff --git a/source/exhumed/src/movie.cpp b/source/exhumed/src/movie.cpp index 5938bbb71..c6f9e16ee 100644 --- a/source/exhumed/src/movie.cpp +++ b/source/exhumed/src/movie.cpp @@ -216,7 +216,7 @@ void PlayMovie(const char* fileName) int z = 0; AnimTextures animtex; - animtex.SetSize(200, 320); + animtex.SetSize(AnimTexture::Paletted, 200, 320); // Read a frame in first if (ReadFrame(fp, palette)) diff --git a/source/rr/src/anim.cpp b/source/rr/src/anim.cpp index 7e31a9d13..59743cfeb 100644 --- a/source/rr/src/anim.cpp +++ b/source/rr/src/anim.cpp @@ -480,7 +480,7 @@ int32_t Anim_Play(const char *fn) { AnimTextures animtex; - animtex.SetSize(320, 200); + animtex.SetSize(AnimTexture::Paletted, 320, 200); do { diff --git a/source/sw/src/anim.cpp b/source/sw/src/anim.cpp index 592a9667c..b14955f8f 100644 --- a/source/sw/src/anim.cpp +++ b/source/sw/src/anim.cpp @@ -262,7 +262,7 @@ playanm(short anim_num) { AnimTextures animtex; - animtex.SetSize(320, 200); + animtex.SetSize(AnimTexture::Paletted, 320, 200); if (ANIMnum == 1) { // draw the first frame