Improve start screen logo rendering by rendering it directly to screen instead of using StartupTexture

This commit is contained in:
Magnus Norddahl 2024-10-30 00:00:46 +01:00
commit 7bbd69e7e3
3 changed files with 62 additions and 20 deletions

View file

@ -49,6 +49,7 @@
#include "v_draw.h"
#include "g_input.h"
#include "texturemanager.h"
#include "image.h"
// Text mode color values
enum{
@ -678,7 +679,8 @@ void FStartScreen::Render(bool force)
twod->Begin(screen->GetWidth(), screen->GetHeight());
// At this point the shader for untextured rendering has not been loaded yet, so we got to clear the screen by rendering a texture with black color.
DrawTexture(twod, StartupTexture, 0, 0, DTA_VirtualWidthF, StartupTexture->GetDisplayWidth(), DTA_VirtualHeightF, StartupTexture->GetDisplayHeight(), DTA_KeepRatio, true, DTA_Color, PalEntry(255,0,0,0), TAG_END);
// Note: StartupTexture is just a dummy here. Its contents doesn't matter. A normal clear could be used for VKD, but kept here to make the commit compatible with GZD.
DrawTexture(twod, StartupTexture, 0, 0, DTA_VirtualWidthF, StartupTexture->GetDisplayWidth(), DTA_VirtualHeightF, StartupTexture->GetDisplayHeight(), DTA_KeepRatio, true, DTA_Color, PalEntry(255, 0, 0, 0), TAG_END);
if (HeaderTexture)
{
@ -686,6 +688,12 @@ void FStartScreen::Render(bool force)
displayheight = HeaderTexture->GetDisplayHeight() + StartupTexture->GetDisplayHeight();
DrawTexture(twod, HeaderTexture, 0, 0, DTA_VirtualWidthF, displaywidth, DTA_VirtualHeightF, displayheight, TAG_END);
DrawTexture(twod, StartupTexture, 0, 32, DTA_VirtualWidthF, displaywidth, DTA_VirtualHeightF, displayheight, TAG_END);
for (auto& image : Images)
{
image->RenderImage(image->Texture);
}
if (NetMaxPos >= 0) DrawTexture(twod, NetTexture, 0, displayheight - 16, DTA_VirtualWidthF, displaywidth, DTA_VirtualHeightF, displayheight, TAG_END);
}
else
@ -693,6 +701,11 @@ void FStartScreen::Render(bool force)
displaywidth = StartupTexture->GetDisplayWidth();
displayheight = StartupTexture->GetDisplayHeight();
DrawTexture(twod, StartupTexture, 0, 0, DTA_VirtualWidthF, displaywidth, DTA_VirtualHeightF, displayheight, TAG_END);
for (auto& image : Images)
{
image->RenderImage(image->Texture);
}
}
twod->End();
@ -704,6 +717,23 @@ void FStartScreen::Render(bool force)
minwaittime = (newtime - nowtime) * 2;
}
void FStartScreen::AddImage(const char* name, std::function<void(FGameTexture* texture)> renderImage)
{
// at this point we do not have a working texture manager yet, so we have to do the lookup via the file system
int lump = fileSystem.CheckNumForName(name, FileSys::ns_graphics);
if (lump != -1)
{
auto iBackground = FImageSource::GetImage(lump, false);
if (iBackground)
{
auto image = std::make_unique<StartScreenImage>();
image->Bitmap = iBackground->GetCachedBitmap(nullptr, FImageSource::normal);
image->RenderImage = std::move(renderImage);
Images.Push(std::move(image));
}
}
}
FImageSource* CreateStartScreenTexture(FBitmap& srcdata);
void FStartScreen::ValidateTexture()
@ -724,5 +754,14 @@ void FStartScreen::ValidateTexture()
auto imgsource = CreateStartScreenTexture(NetBitmap);
NetTexture = MakeGameTexture(new FImageTexture(imgsource), nullptr, ETextureType::Override);
}
for (auto& image : Images)
{
if (image->Texture == nullptr && image->Bitmap.GetWidth() > 0)
{
auto imgsource = CreateStartScreenTexture(image->Bitmap);
image->Texture = MakeGameTexture(new FImageTexture(imgsource), nullptr, ETextureType::Override);
}
}
}

View file

@ -50,6 +50,12 @@ struct RgbQuad
uint8_t rgbReserved;
};
struct StartScreenImage
{
FBitmap Bitmap;
FGameTexture* Texture;
std::function<void(FGameTexture* texture)> RenderImage;
};
extern const RgbQuad TextModePalette[16];
@ -68,6 +74,7 @@ protected:
FGameTexture* StartupTexture = nullptr;
FGameTexture* HeaderTexture = nullptr;
FGameTexture* NetTexture = nullptr;
TArray<std::unique_ptr<StartScreenImage>> Images;
public:
FStartScreen(int maxp) { MaxPos = maxp; }
virtual ~FStartScreen();
@ -79,13 +86,12 @@ public:
virtual bool NetInit(const char* message, int numplayers);
virtual void NetDone() {}
virtual void NetTick() {}
FBitmap& GetBitmap() { return StartupBitmap; }
int GetScale() const { return Scale; }
void AddImage(const char* name, std::function<void(FGameTexture* texture)> renderImage);
protected:
void ClearBlock(FBitmap& bitmap_info, RgbQuad fill, int x, int y, int bytewidth, int height);
FBitmap AllocTextBitmap();
void DrawTextScreen(FBitmap& bitmap_info, const uint8_t* text_screen);
int DrawChar(FBitmap& screen, double x, double y, unsigned charnum, uint8_t attrib);
int DrawChar(FBitmap& screen, double x, double y, unsigned charnum, RgbQuad fg, RgbQuad bg);

View file

@ -38,6 +38,8 @@
#include "startupinfo.h"
#include "image.h"
#include "texturemanager.h"
#include "v_video.h"
#include "v_draw.h"
// Hexen startup screen
#define ST_PROGRESS_X 64 // Start of notches x screen pos.
@ -71,25 +73,20 @@ public:
FGenericStartScreen::FGenericStartScreen(int max_progress)
: FStartScreen(max_progress)
{
// at this point we do not have a working texture manager yet, so we have to do the lookup via the file system
int startup_lump = fileSystem.CheckNumForName("BOOTLOGO", FileSys::ns_graphics);
StartupBitmap.Create(640 * 2, 480 * 2);
ClearBlock(StartupBitmap, { 0, 0, 0, 255 }, 0, 0, 640 * 2, 480 * 2);
// This also needs to work if the lump turns out to be unusable.
if (startup_lump != -1)
{
auto iBackground = FImageSource::GetImage(startup_lump, false);
if (iBackground)
{
Background = iBackground->GetCachedBitmap(nullptr, FImageSource::normal);
if (Background.GetWidth() < 640 * 2 || Background.GetHeight() < 480 * 2)
StartupBitmap.Blit(320 * 2 - Background.GetWidth()/2, 220 * 2 - Background.GetHeight() / 2, Background);
else
StartupBitmap.Blit(0, 0, Background, 640 * 2, 480 * 2);
}
}
AddImage("BOOTLOGO", [](FGameTexture* tex) {
double scrwidth = screen->GetWidth();
double scrheight = screen->GetHeight();
double scale = scrheight / 2160.0;
double imgwidth = tex->GetDisplayWidth() * scale;
double imgheight = tex->GetDisplayHeight() * scale;
double imgx = (scrwidth - imgwidth) * 0.5;
double imgy = (scrheight - imgheight) * 0.5;
DrawTexture(twod, tex, imgx, imgy, DTA_DestWidthF, imgwidth, DTA_DestHeightF, imgheight, DTA_VirtualWidthF, scrwidth, DTA_VirtualHeightF, scrheight, DTA_KeepRatio, true, TAG_END);
});
}
//==========================================================================