diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 36feab0b7a..ef069114dc 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -192,7 +192,8 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int } */ TranslatedTexture * glTex=GetTexID(translation); - if (glTex->glTexID==0) glGenTextures(1,&glTex->glTexID); + bool firstCall = glTex->glTexID == 0; + if (firstCall) glGenTextures(1,&glTex->glTexID); if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); glBindTexture(GL_TEXTURE_2D, glTex->glTexID); FGLDebug::LabelObject(GL_TEXTURE, glTex->glTexID, name); @@ -256,7 +257,10 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int sourcetype = GL_BGRA; } - glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, sourcetype, GL_UNSIGNED_BYTE, buffer); + if (!firstCall && glBufferID > 0) + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, rw, rh, sourcetype, GL_UNSIGNED_BYTE, buffer); + else + glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, sourcetype, GL_UNSIGNED_BYTE, buffer); if (deletebuffer && buffer) free(buffer); else if (glBufferID) diff --git a/src/swrenderer/r_swscene.cpp b/src/swrenderer/r_swscene.cpp index 214fb2a0c9..8e25222669 100644 --- a/src/swrenderer/r_swscene.cpp +++ b/src/swrenderer/r_swscene.cpp @@ -86,38 +86,40 @@ public: SWSceneDrawer::SWSceneDrawer() { - PaletteTexture = new FSWPaletteTexture; + PaletteTexture.reset(new FSWPaletteTexture); } SWSceneDrawer::~SWSceneDrawer() { - if (PaletteTexture != nullptr) delete PaletteTexture; - if (FBTexture != nullptr) delete FBTexture; } sector_t *SWSceneDrawer::RenderView(player_t *player) { + // Avoid using the pixel buffer from the last frame + FBTextureIndex = (FBTextureIndex + 1) % 2; + auto &fbtex = FBTexture[FBTextureIndex]; + DCanvas buffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor()); - if (FBTexture == nullptr || FBTexture->SystemTexture[0] == nullptr || - FBTexture->GetWidth() != screen->GetWidth() || - FBTexture->GetHeight() != screen->GetHeight() || - (V_IsTrueColor() ? 1:0) != FBTexture->WidthBits) + if (fbtex == nullptr || fbtex->SystemTexture[0] == nullptr || + fbtex->GetWidth() != screen->GetWidth() || + fbtex->GetHeight() != screen->GetHeight() || + (V_IsTrueColor() ? 1:0) != fbtex->WidthBits) { // This manually constructs its own material here. - if (FBTexture != nullptr) delete FBTexture; - FBTexture = new FSWSceneTexture(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor()); - FBTexture->SystemTexture[0]->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor() ? 4 : 1); - auto mat = FMaterial::ValidateTexture(FBTexture, false); - mat->AddTextureLayer(PaletteTexture); + fbtex.reset(); + fbtex.reset(new FSWSceneTexture(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor())); + fbtex->SystemTexture[0]->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor() ? 4 : 1); + auto mat = FMaterial::ValidateTexture(fbtex.get(), false); + mat->AddTextureLayer(PaletteTexture.get()); } - auto buf = FBTexture->SystemTexture[0]->MapBuffer(); + auto buf = fbtex->SystemTexture[0]->MapBuffer(); if (!buf) I_FatalError("Unable to map buffer for software rendering"); buffer.SetBuffer(screen->GetWidth(), screen->GetHeight(), screen->GetWidth(), buf); SWRenderer->RenderView(player, &buffer); - FBTexture->SystemTexture[0]->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer"); + fbtex->SystemTexture[0]->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer"); auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); - screen->DrawTexture(FBTexture, 0, 0, DTA_SpecialColormap, map, TAG_DONE); + screen->DrawTexture(fbtex.get(), 0, 0, DTA_SpecialColormap, map, TAG_DONE); SWRenderer->DrawRemainingPlayerSprites(); return r_viewpoint.sector; } diff --git a/src/swrenderer/r_swscene.h b/src/swrenderer/r_swscene.h index ef52c20c65..9c6921ee41 100644 --- a/src/swrenderer/r_swscene.h +++ b/src/swrenderer/r_swscene.h @@ -6,13 +6,15 @@ #include "hwrenderer/scene/hw_clipper.h" #include "r_utility.h" #include "c_cvars.h" +#include class FSWSceneTexture; class SWSceneDrawer { - FTexture *PaletteTexture = nullptr; - FSWSceneTexture *FBTexture = nullptr; + std::unique_ptr PaletteTexture; + std::unique_ptr FBTexture[2]; + int FBTextureIndex = 0; bool FBIsTruecolor = false; public: