From 6eab4a882ce7d49612f41ae85788baa4274ac4ed Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 6 Dec 2018 01:11:04 +0100 Subject: [PATCH 01/66] - narrowing down the public interface of the texture class Cannot refactor if the entire class is this wide open to everything. Not complete yet, doesn't fully compile! --- src/am_map.cpp | 21 +- src/d_main.cpp | 8 +- src/f_wipe.cpp | 4 +- src/fragglescript/t_func.cpp | 4 +- src/g_shared/a_decals.cpp | 6 +- src/g_shared/a_dynlight.cpp | 2 +- src/g_statusbar/sbarinfo.cpp | 42 ++-- src/g_statusbar/sbarinfo_commands.cpp | 32 +-- src/g_statusbar/shared_sbar.cpp | 24 +- src/gl/renderer/gl_renderstate.cpp | 12 +- src/gl/shaders/gl_postprocessshader.cpp | 13 +- src/gl/system/gl_framebuffer.cpp | 16 +- src/gl/textures/gl_hwtexture.cpp | 8 +- src/hu_scores.cpp | 6 +- src/hwrenderer/scene/hw_bsp.cpp | 2 +- src/hwrenderer/scene/hw_fakeflat.cpp | 8 +- src/hwrenderer/scene/hw_flats.cpp | 2 +- src/hwrenderer/scene/hw_renderhacks.cpp | 4 +- src/hwrenderer/scene/hw_sky.cpp | 10 +- src/hwrenderer/scene/hw_skydome.cpp | 6 +- src/hwrenderer/scene/hw_skyportal.cpp | 2 +- src/hwrenderer/scene/hw_sprites.cpp | 4 +- src/hwrenderer/scene/hw_walls.cpp | 8 +- src/hwrenderer/scene/hw_weapon.cpp | 2 +- src/hwrenderer/textures/hw_material.cpp | 58 +---- src/hwrenderer/textures/hw_material.h | 9 +- src/hwrenderer/textures/hw_precache.cpp | 15 +- src/hwrenderer/utility/hw_draw2d.cpp | 2 +- src/intermission/intermission.cpp | 8 +- src/menu/loadsavemenu.cpp | 2 +- src/p_acs.cpp | 2 +- src/p_doors.cpp | 5 +- src/p_sectors.cpp | 18 +- src/polyrenderer/drawers/poly_draw_args.cpp | 12 +- src/polyrenderer/drawers/poly_draw_args.h | 22 +- src/polyrenderer/poly_renderthread.cpp | 4 +- src/polyrenderer/poly_renderthread.h | 2 +- src/polyrenderer/scene/poly_decal.cpp | 12 +- src/polyrenderer/scene/poly_model.cpp | 4 +- src/polyrenderer/scene/poly_model.h | 2 +- src/polyrenderer/scene/poly_plane.cpp | 20 +- src/polyrenderer/scene/poly_plane.h | 2 +- src/polyrenderer/scene/poly_playersprite.cpp | 21 +- src/polyrenderer/scene/poly_playersprite.h | 4 +- src/polyrenderer/scene/poly_sky.cpp | 32 ++- src/polyrenderer/scene/poly_sky.h | 6 +- src/polyrenderer/scene/poly_sprite.cpp | 33 +-- src/polyrenderer/scene/poly_sprite.h | 2 +- src/polyrenderer/scene/poly_wall.cpp | 36 +-- src/polyrenderer/scene/poly_wall.h | 14 +- src/polyrenderer/scene/poly_wallsprite.cpp | 12 +- src/posix/cocoa/i_video.mm | 22 +- src/r_data/gldefs.cpp | 20 +- src/r_data/sprites.cpp | 4 +- src/r_sky.cpp | 24 +- src/r_utility.cpp | 2 +- src/scripting/vm/jit_move.cpp | 2 +- src/scripting/vm/vmexec.h | 2 +- src/scripting/vmthunks.cpp | 2 +- src/swrenderer/r_renderthread.cpp | 2 +- src/swrenderer/r_swrenderer.cpp | 2 +- src/swrenderer/things/r_playersprite.h | 2 +- src/swrenderer/viewport/r_spritedrawer.cpp | 8 +- src/textures/animations.cpp | 4 +- src/textures/formats/canvastexture.cpp | 2 +- src/textures/formats/multipatchtexture.cpp | 4 +- src/textures/formats/worldtexture.cpp | 2 +- src/textures/skyboxtexture.cpp | 5 +- src/textures/skyboxtexture.h | 8 +- src/textures/texture.cpp | 82 ++----- src/textures/textures.h | 223 ++++++++++++++++--- src/v_2ddrawer.cpp | 23 +- src/v_draw.cpp | 42 ++-- src/v_font.cpp | 34 +-- 74 files changed, 608 insertions(+), 518 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 505e3561f..379c4f713 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1198,8 +1198,8 @@ static void AM_ScrollParchment (double dmapx, double dmapy) if (backtex != NULL) { - int pwidth = backtex->GetWidth(); - int pheight = backtex->GetHeight(); + int pwidth = backtex->GetDisplayWidth(); + int pheight = backtex->GetDisplayHeight(); while(mapxstart > 0) mapxstart -= pwidth; @@ -1692,8 +1692,8 @@ void AM_clearFB (const AMColor &color) FTexture *backtex = TexMan[mapback]; if (backtex != NULL) { - int pwidth = backtex->GetWidth(); - int pheight = backtex->GetHeight(); + int pwidth = backtex->GetDisplayWidth(); + int pheight = backtex->GetDisplayHeight(); int x, y; //blit the automap background to the screen. @@ -2212,8 +2212,7 @@ void AM_drawSubsectors() } // Draw the polygon. - FTexture *pic = TexMan(maptex); - if (pic != nullptr && pic->UseType != ETextureType::Null) + if (maptex.isValid()) { // Hole filling "subsectors" are not necessarily convex so they require real triangulation. // These things are extremely rare so performance is secondary here. @@ -3116,7 +3115,7 @@ void AM_drawThings () static void DrawMarker (FTexture *tex, double x, double y, int yadjust, INTBOOL flip, double xscale, double yscale, int translation, double alpha, uint32_t fillcolor, FRenderStyle renderstyle) { - if (tex == NULL || tex->UseType == ETextureType::Null) + if (tex == NULL || !tex->isValid()) { return; } @@ -3125,8 +3124,8 @@ static void DrawMarker (FTexture *tex, double x, double y, int yadjust, AM_rotatePoint (&x, &y); } screen->DrawTexture (tex, CXMTOF(x) + f_x, CYMTOF(y) + yadjust + f_y, - DTA_DestWidthF, tex->GetScaledWidthDouble() * CleanXfac * xscale, - DTA_DestHeightF, tex->GetScaledHeightDouble() * CleanYfac * yscale, + DTA_DestWidthF, tex->GetDisplayWidthDouble() * CleanXfac * xscale, + DTA_DestHeightF, tex->GetDisplayHeightDouble() * CleanYfac * yscale, DTA_ClipTop, f_y, DTA_ClipBottom, f_y + f_h, DTA_ClipLeft, f_x, @@ -3185,9 +3184,9 @@ void AM_drawAuthorMarkers () if (mark->picnum.isValid()) { tex = TexMan(mark->picnum); - if (tex->Rotations != 0xFFFF) + if (tex->GetRotations() != 0xFFFF) { - spriteframe_t *sprframe = &SpriteFrames[tex->Rotations]; + spriteframe_t *sprframe = &SpriteFrames[tex->GetRotations()]; picnum = sprframe->Texture[0]; flip = sprframe->Flip & 1; tex = TexMan[picnum]; diff --git a/src/d_main.cpp b/src/d_main.cpp index 7827bffd2..601a5558c 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -835,15 +835,15 @@ void D_Display () FString pstring = "By "; tex = TexMan(gameinfo.PauseSign); - x = (SCREENWIDTH - tex->GetScaledWidth() * CleanXfac)/2 + - tex->GetScaledLeftOffset(0) * CleanXfac; + x = (SCREENWIDTH - tex->GetDisplayWidth() * CleanXfac)/2 + + tex->GetDisplayLeftOffset() * CleanXfac; screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE); if (paused && multiplayer) { pstring += players[paused - 1].userinfo.GetName(); screen->DrawText(SmallFont, CR_RED, (screen->GetWidth() - SmallFont->StringWidth(pstring)*CleanXfac) / 2, - (tex->GetScaledHeight() * CleanYfac) + 4, pstring, DTA_CleanNoMove, true, TAG_DONE); + (tex->GetDisplayHeight() * CleanYfac) + 4, pstring, DTA_CleanNoMove, true, TAG_DONE); } } @@ -856,7 +856,7 @@ void D_Display () if (picnum.isValid()) { FTexture *tex = TexMan[picnum]; - screen->DrawTexture (tex, 160 - tex->GetScaledWidth()/2, 100 - tex->GetScaledHeight()/2, + screen->DrawTexture (tex, 160 - tex->GetDisplayWidth()/2, 100 - tex->GetDisplayHeight()/2, DTA_320x200, true, TAG_DONE); } NoWipe = 10; diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index 25c283038..cd8c48f40 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -304,8 +304,8 @@ bool Wiper_Melt::Run(int ticks) // Only draw for the final tick. // No need for optimization. Wipes won't ever be drawn with anything else. - int w = startScreen->GetWidth(); - int h = startScreen->GetHeight(); + int w = startScreen->GetDisplayWidth(); + int h = startScreen->GetDisplayHeight(); dpt.x = i * w / WIDTH; dpt.y = MAX(0, y[i] * h / HEIGHT); rect.left = dpt.x; diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 6c475c0f8..a6fceb5c7 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1904,7 +1904,7 @@ void FParser::SF_FloorTexture(void) t_return.type = svt_string; FTexture * tex = TexMan[sector->GetTexture(sector_t::floor)]; - t_return.string = tex? tex->Name : ""; + t_return.string = tex? tex->GetName() : ""; } } @@ -1994,7 +1994,7 @@ void FParser::SF_CeilingTexture(void) t_return.type = svt_string; FTexture * tex = TexMan[sector->GetTexture(sector_t::ceiling)]; - t_return.string = tex? tex->Name : ""; + t_return.string = tex? tex->GetName() : ""; } } diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index bb503fec0..7837ade74 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -264,7 +264,7 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, double x, double y, F3DFloor * FTexture *texture = TexMan[tex]; - if (texture == NULL || texture->bNoDecals) + if (texture == NULL || texture->allowNoDecals()) { return FNullTextureID(); } @@ -497,10 +497,10 @@ void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, doub return; } - int dwidth = tex->GetWidth (); + int dwidth = tex->GetDisplayWidth (); DecalWidth = dwidth * ScaleX; - DecalLeft = tex->GetLeftOffset(0) * ScaleX; + DecalLeft = tex->GetDisplayLeftOffset() * ScaleX; DecalRight = DecalWidth - DecalLeft; SpreadSource = this; SpreadTemplate = tpl; diff --git a/src/g_shared/a_dynlight.cpp b/src/g_shared/a_dynlight.cpp index 13ce1f9c1..3434d73af 100644 --- a/src/g_shared/a_dynlight.cpp +++ b/src/g_shared/a_dynlight.cpp @@ -937,7 +937,7 @@ CCMD(listlights) if (dl->target) { FTextureID spr = sprites[dl->target->sprite].GetSpriteFrame(dl->target->frame, 0, 0., nullptr); - Printf(", frame = %s ", TexMan[spr]->Name.GetChars()); + Printf(", frame = %s ", TexMan[spr]->GetName().GetChars()); } diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index c4941713b..34cf09c3c 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -1188,12 +1188,12 @@ public: if((offsetflags & SBarInfoCommand::CENTER) == SBarInfoCommand::CENTER) { - if (forceWidth < 0) dx -= (texture->GetScaledWidthDouble()/2.0)-texture->GetScaledLeftOffsetDouble(0); - else dx -= forceWidth*(0.5-(texture->GetScaledLeftOffsetDouble(0)/texture->GetScaledWidthDouble())); - //Unoptimalized ^^formula is dx -= forceWidth/2.0-(texture->GetScaledLeftOffsetDouble()*forceWidth/texture->GetScaledWidthDouble()); + if (forceWidth < 0) dx -= (texture->GetDisplayWidthDouble()/2.0)-texture->GetDisplayLeftOffsetDouble(); + else dx -= forceWidth*(0.5-(texture->GetDisplayLeftOffsetDouble()/texture->GetDisplayWidthDouble())); + //Unoptimalized ^^formula is dx -= forceWidth/2.0-(texture->GetScaledLeftOffsetDouble()*forceWidth/texture->GetDisplayWidthDouble()); - if (forceHeight < 0) dy -= (texture->GetScaledHeightDouble()/2.0)-texture->GetScaledTopOffsetDouble(0); - else dy -= forceHeight*(0.5-(texture->GetScaledTopOffsetDouble(0)/texture->GetScaledHeightDouble())); + if (forceHeight < 0) dy -= (texture->GetDisplayHeightDouble()/2.0)-texture->GetDisplayTopOffsetDouble(); + else dy -= forceHeight*(0.5-(texture->GetDisplayTopOffsetDouble()/texture->GetDisplayHeightDouble())); } dx += xOffset; @@ -1202,12 +1202,12 @@ public: if(!fullScreenOffsets) { double tmp = 0; - w = forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth; - h = forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight; - double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble(0); - double dcy = clip[1] == 0 ? 0 : dy + clip[1] - texture->GetScaledTopOffsetDouble(0); - double dcr = clip[2] == 0 ? INT_MAX : dx + w - clip[2] - texture->GetScaledLeftOffsetDouble(0); - double dcb = clip[3] == 0 ? INT_MAX : dy + h - clip[3] - texture->GetScaledTopOffsetDouble(0); + w = forceWidth < 0 ? texture->GetDisplayWidthDouble() : forceWidth; + h = forceHeight < 0 ? texture->GetDisplayHeightDouble() : forceHeight; + double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetDisplayLeftOffsetDouble(); + double dcy = clip[1] == 0 ? 0 : dy + clip[1] - texture->GetDisplayTopOffsetDouble(); + double dcr = clip[2] == 0 ? INT_MAX : dx + w - clip[2] - texture->GetDisplayLeftOffsetDouble(); + double dcb = clip[3] == 0 ? INT_MAX : dy + h - clip[3] - texture->GetDisplayTopOffsetDouble(); if(clip[0] != 0 || clip[1] != 0) { @@ -1271,8 +1271,8 @@ public: bool xright = *x < 0 && !x.RelCenter(); bool ybot = *y < 0 && !y.RelCenter(); - w = (forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth); - h = (forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight); + w = (forceWidth < 0 ? texture->GetDisplayWidthDouble() : forceWidth); + h = (forceHeight < 0 ? texture->GetDisplayHeightDouble() : forceHeight); if(vid_fps && rx < 0 && ry >= 0) ry += 10; @@ -1289,10 +1289,10 @@ public: // Check for clipping if(clip[0] != 0 || clip[1] != 0 || clip[2] != 0 || clip[3] != 0) { - rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble(0))*Scale.X); - rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble(0))*Scale.Y); - rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble(0))*Scale.X); - rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble(0))*Scale.Y); + rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetDisplayLeftOffsetDouble())*Scale.X); + rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetDisplayTopOffsetDouble())*Scale.Y); + rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetDisplayLeftOffsetDouble())*Scale.X); + rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetDisplayTopOffsetDouble())*Scale.Y); } if(clearDontDraw) @@ -1389,13 +1389,13 @@ public: int character = (unsigned char)*str; if (script->spacingCharacter == '\0') //If we are monospaced lets use the offset - ax += (c->GetLeftOffset(0) + 1); //ignore x offsets since we adapt to character size + ax += (c->GetDisplayLeftOffset() + 1); //ignore x offsets since we adapt to character size double rx, ry, rw, rh; rx = ax + xOffset; ry = ay + yOffset; - rw = c->GetScaledWidthDouble(); - rh = c->GetScaledHeightDouble(); + rw = c->GetDisplayWidthDouble(); + rh = c->GetDisplayHeightDouble(); if(script->spacingCharacter != '\0') { @@ -1453,7 +1453,7 @@ public: DTA_Alpha, Alpha, TAG_DONE); if (script->spacingCharacter == '\0') - ax += width + spacing - (c->GetLeftOffset(0) + 1); + ax += width + spacing - (c->GetDisplayLeftOffsetDouble() + 1); else //width gets changed at the call to GetChar() ax += font->GetCharWidth((unsigned char) script->spacingCharacter) + spacing; str++; diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index fa321660a..f605e2dc4 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -69,8 +69,8 @@ class CommandDrawImage : public SBarInfoCommandFlowControl { double scale1, scale2; scale1 = scale2 = 1.0f; - double texwidth = (int) (texture->GetScaledWidthDouble()*spawnScaleX); - double texheight = (int) (texture->GetScaledHeightDouble()*spawnScaleY); + double texwidth = (int) (texture->GetDisplayWidthDouble()*spawnScaleX); + double texheight = (int) (texture->GetDisplayHeightDouble()*spawnScaleY); if (w != -1 && (wGetScaledWidthDouble()*spawnScaleX); - h=(int) (texture->GetScaledHeightDouble()*spawnScaleY); + w=(int) (texture->GetDisplayWidthDouble()*spawnScaleX); + h=(int) (texture->GetDisplayHeightDouble()*spawnScaleY); } statusBar->DrawGraphic(texture, imgx, imgy, block->XOffset(), block->YOffset(), frameAlpha, block->FullScreenOffsets(), translatable, false, offset, false, w, h); @@ -300,7 +300,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl if (flags & DI_ALTERNATEONFAIL) { - SetTruth(texture == NULL || texture->UseType == ETextureType::Null, block, statusBar); + SetTruth(texture == NULL || !texture->isValid(), block, statusBar); } } protected: @@ -2266,11 +2266,11 @@ class CommandDrawInventoryBar : public SBarInfoCommand int spacing; if (!vertical) { - spacing = box->GetScaledWidth(); + spacing = box->GetDisplayWidth(); } else { - spacing = box->GetScaledHeight(); + spacing = box->GetDisplayHeight(); } return spacing + ((style != STYLE_Strife) ? 1 : -1); } @@ -2370,21 +2370,21 @@ class CommandDrawKeyBar : public SBarInfoCommand if(!vertical) { statusBar->DrawGraphic(TexMan(item->TextureIDVar(NAME_Icon)), x+slotOffset, y+rowOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); - rowWidth = rowIconSize == -1 ? TexMan(item->TextureIDVar(NAME_Icon))->GetScaledHeight()+2 : rowIconSize; + rowWidth = rowIconSize == -1 ? TexMan(item->TextureIDVar(NAME_Icon))->GetDisplayHeight()+2 : rowIconSize; } else { statusBar->DrawGraphic(TexMan(item->TextureIDVar(NAME_Icon)), x+rowOffset, y+slotOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); - rowWidth = rowIconSize == -1 ? TexMan(item->TextureIDVar(NAME_Icon))->GetScaledWidth()+2 : rowIconSize; + rowWidth = rowIconSize == -1 ? TexMan(item->TextureIDVar(NAME_Icon))->GetDisplayWidth()+2 : rowIconSize; } // If cmd.special is -1 then the slot size is auto detected if(iconSize == -1) { if(!vertical) - slotOffset += (reverse ? -1 : 1) * (TexMan(item->TextureIDVar(NAME_Icon))->GetScaledWidth() + 2); + slotOffset += (reverse ? -1 : 1) * (TexMan(item->TextureIDVar(NAME_Icon))->GetDisplayWidth() + 2); else - slotOffset += (reverse ? -1 : 1) * (TexMan(item->TextureIDVar(NAME_Icon))->GetScaledHeight() + 2); + slotOffset += (reverse ? -1 : 1) * (TexMan(item->TextureIDVar(NAME_Icon))->GetDisplayHeight() + 2); } else slotOffset += (reverse ? -iconSize : iconSize); @@ -2504,7 +2504,7 @@ class CommandDrawBar : public SBarInfoCommand else { // Draw background - if (bg != NULL && bg->GetScaledWidth() == fg->GetScaledWidth() && bg->GetScaledHeight() == fg->GetScaledHeight()) + if (bg != NULL && bg->GetDisplayWidth() == fg->GetDisplayWidth() && bg->GetDisplayHeight() == fg->GetDisplayHeight()) statusBar->DrawGraphic(bg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); else statusBar->DrawGraphic(fg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, nulclip, true); @@ -2513,7 +2513,7 @@ class CommandDrawBar : public SBarInfoCommand // {cx, cy, cr, cb} double Clip[4] = {0, 0, 0, 0}; - int sizeOfImage = (horizontal ? fg->GetScaledWidth()-border*2 : fg->GetScaledHeight()-border*2); + int sizeOfImage = (horizontal ? fg->GetDisplayWidth()-border*2 : fg->GetDisplayHeight()-border*2); Clip[(!horizontal)|((horizontal ? !reverse : reverse)<<1)] = sizeOfImage - sizeOfImage *value; // Draw background if(border != 0) @@ -2521,7 +2521,7 @@ class CommandDrawBar : public SBarInfoCommand for(unsigned int i = 0;i < 4;i++) Clip[i] += border; - if (bg != NULL && bg->GetScaledWidth() == fg->GetScaledWidth() && bg->GetScaledHeight() == fg->GetScaledHeight()) + if (bg != NULL && bg->GetDisplayWidth() == fg->GetDisplayWidth() && bg->GetDisplayHeight() == fg->GetDisplayHeight()) statusBar->DrawGraphic(bg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, Clip); else statusBar->DrawGraphic(fg, this->x, this->y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, false, 0, false, -1, -1, Clip, true); @@ -2802,7 +2802,7 @@ class CommandDrawBar : public SBarInfoCommand // [BL] Since we used a percentage (in order to get the most fluid animation) // we need to establish a cut off point so the last pixel won't hang as the animation slows if(pixel == -1 && statusBar->Images[foreground]) - pixel = MAX(1 / 65536., 1./statusBar->Images[foreground]->GetWidth()); + pixel = MAX(1 / 65536., 1./statusBar->Images[foreground]->GetDisplayWidth()); if(fabs(drawValue - value) < pixel) drawValue = value; @@ -3115,7 +3115,7 @@ class CommandDrawGem : public SBarInfoCommand SBarInfoCoordinate drawY = y; if(wiggle && drawValue != goalValue) // Should only wiggle when the value doesn't equal what is being drawn. drawY += chainWiggle; - int chainWidth = chainImg->GetScaledWidth(); + int chainWidth = chainImg->GetDisplayWidth(); int offset = (int) (((double) (chainWidth-leftPadding-rightPadding)/100)*drawValue); statusBar->DrawGraphic(chainImg, x+(offset%chainSize), drawY, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); if(gemImg != NULL) diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 766e18d6a..ea2db01fe 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -820,8 +820,8 @@ void DBaseStatusBar::RefreshBackground () const FTexture *p = TexMan[gameinfo.Border.b]; if (p != NULL) { - screen->FlatFill(0, y, x, y + p->GetHeight(), p, true); - screen->FlatFill(x2, y, SCREENWIDTH, y + p->GetHeight(), p, true); + screen->FlatFill(0, y, x, y + p->GetDisplayHeight(), p, true); + screen->FlatFill(x2, y, SCREENWIDTH, y + p->GetDisplayHeight(), p, true); } } } @@ -864,8 +864,8 @@ void DBaseStatusBar::DrawCrosshair () { size *= CrosshairSize; } - w = int(CrosshairImage->GetWidth() * size); - h = int(CrosshairImage->GetHeight() * size); + w = int(CrosshairImage->GetDisplayWidth() * size); + h = int(CrosshairImage->GetDisplayHeight() * size); if (crosshairhealth) { @@ -1325,8 +1325,8 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int fla FTexture *tex = (flags & DI_DONTANIMATE)? TexMan[texture] : TexMan(texture); - double texwidth = tex->GetScaledWidthDouble() * scaleX; - double texheight = tex->GetScaledHeightDouble() * scaleY; + double texwidth = tex->GetDisplayWidthDouble() * scaleX; + double texheight = tex->GetDisplayHeightDouble() * scaleY; if (boxwidth > 0 || boxheight > 0) { @@ -1378,14 +1378,14 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int fla { case DI_ITEM_HCENTER: x -= boxwidth / 2; break; case DI_ITEM_RIGHT: x -= boxwidth; break; - case DI_ITEM_HOFFSET: x -= tex->GetScaledLeftOffsetDouble(0) * boxwidth / texwidth; break; + case DI_ITEM_HOFFSET: x -= tex->GetDisplayLeftOffsetDouble() * boxwidth / texwidth; break; } switch (flags & DI_ITEM_VMASK) { case DI_ITEM_VCENTER: y -= boxheight / 2; break; case DI_ITEM_BOTTOM: y -= boxheight; break; - case DI_ITEM_VOFFSET: y -= tex->GetScaledTopOffsetDouble(0) * boxheight / texheight; break; + case DI_ITEM_VOFFSET: y -= tex->GetDisplayTopOffsetDouble() * boxheight / texheight; break; } if (!fullscreenOffsets) @@ -1520,13 +1520,13 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d } if (!monospaced) //If we are monospaced lets use the offset - x += (c->GetLeftOffset(0) + 1); //ignore x offsets since we adapt to character size + x += (c->GetDisplayLeftOffsetDouble() + 1); //ignore x offsets since we adapt to character size double rx, ry, rw, rh; rx = x + drawOffset.X; ry = y + drawOffset.Y; - rw = c->GetScaledWidthDouble(); - rh = c->GetScaledHeightDouble(); + rw = c->GetDisplayWidthDouble(); + rh = c->GetDisplayHeightDouble(); if (!fullscreenOffsets) { @@ -1560,7 +1560,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d TAG_DONE); if (!monospaced) - x += width + spacing - (c->GetLeftOffset(0) + 1); + x += width + spacing - (c->GetDisplayLeftOffsetDouble() + 1); else x += spacing; } diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 883231bc4..4a683a090 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -303,7 +303,8 @@ void FGLRenderState::Apply() void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader) { - if (mat->tex->bHasCanvas) +#if 0 + if (mat->tex->isHardwareCanvas()) { mTempTM = TM_OPAQUE; } @@ -317,8 +318,8 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio auto tex = mat->tex; if (tex->UseType == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER; - if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX; - else if ((tex->bWarped || tex->shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; + if (tex->sHardwareCanvas()) clampmode = CLAMP_CAMTEX; + else if ((tex->isWarped() || tex->shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; // avoid rebinding the same texture multiple times. if (mat == lastMaterial && lastClamp == clampmode && translation == lastTranslation) return; @@ -330,7 +331,7 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio int maxbound = 0; // Textures that are already scaled in the texture lump will not get replaced by hires textures. - int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && tex->Scale.X == 1 && tex->Scale.Y == 1 && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0; + int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled() && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0; int numLayers = mat->GetLayers(); auto base = static_cast(mat->GetLayer(0)); @@ -350,6 +351,7 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio FHardwareTexture::Unbind(i); maxBoundMaterial = maxbound; } +#endif } //========================================================================== @@ -595,4 +597,4 @@ bool FGLRenderState::SetDepthClamp(bool on) return res; } -} \ No newline at end of file +} diff --git a/src/gl/shaders/gl_postprocessshader.cpp b/src/gl/shaders/gl_postprocessshader.cpp index 9c33cfdc1..6f13b899b 100644 --- a/src/gl/shaders/gl_postprocessshader.cpp +++ b/src/gl/shaders/gl_postprocessshader.cpp @@ -217,7 +217,7 @@ void PostProcessShaderInstance::BindTextures() FString name = pair->Value; FTexture *tex = TexMan(TexMan.CheckForTexture(name, ETextureType::Any)); - if (tex && tex->UseType != ETextureType::Null) + if (tex && tex->isValid()) { glUniform1i(location, textureUnit); @@ -225,16 +225,17 @@ void PostProcessShaderInstance::BindTextures() auto it = mTextureHandles.find(tex); if (it == mTextureHandles.end()) { - FBitmap bitmap; - bitmap.Create(tex->GetWidth(), tex->GetHeight()); - tex->CopyTrueColorPixels(&bitmap, 0, 0); + // Why does this completely circumvent the normal way of handling textures? + int width, height; + auto buffer = tex->CreateTexBuffer(0, width, height); GLuint handle = 0; glGenTextures(1, &handle); glBindTexture(GL_TEXTURE_2D, handle); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex->GetWidth(), tex->GetHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, bitmap.GetPixels()); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + delete[] buffer; mTextureHandles[tex] = handle; } else @@ -247,4 +248,4 @@ void PostProcessShaderInstance::BindTextures() } } -} \ No newline at end of file +} diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index d3d242cd4..314426ff0 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -347,16 +347,16 @@ void OpenGLFrameBuffer::SetTextureFilterMode() IHardwareTexture *OpenGLFrameBuffer::CreateHardwareTexture(FTexture *tex) { - return new FHardwareTexture(tex->bNoCompress); + return new FHardwareTexture(true/*tex->bNoCompress*/); } void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) { auto tex = mat->tex; - if (tex->UseType == ETextureType::SWCanvas) return; + if (tex->isSWCanvas()) return; // Textures that are already scaled in the texture lump will not get replaced by hires textures. - int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && tex->Scale.X == 1 && tex->Scale.Y == 1) ? CTF_CheckHires : 0; + int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled()) ? CTF_CheckHires : 0; int numLayers = mat->GetLayers(); auto base = static_cast(mat->GetLayer(0)); @@ -527,9 +527,9 @@ FTexture *OpenGLFrameBuffer::WipeStartScreen() const auto &viewport = screen->mScreenViewport; auto tex = new FWrapperTexture(viewport.width, viewport.height, 1); - tex->SystemTexture[0]->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen"); + tex->GetSystemTexture(0)->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen"); glFinish(); - static_cast(tex->SystemTexture[0])->Bind(0, false, false); + static_cast(tex->GetSystemTexture(0))->Bind(0, false, false); GLRenderer->mBuffers->BindCurrentFB(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height); @@ -549,12 +549,12 @@ FTexture *OpenGLFrameBuffer::WipeEndScreen() GLRenderer->Flush(); const auto &viewport = screen->mScreenViewport; auto tex = new FWrapperTexture(viewport.width, viewport.height, 1); - tex->SystemTexture[0]->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen"); + tex->GetSystemTexture(0)->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen"); glFinish(); - static_cast(tex->SystemTexture[0])->Bind(0, false, false); + static_cast(tex->GetSystemTexture(0))->Bind(0, false, false); GLRenderer->mBuffers->BindCurrentFB(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height); return tex; } -} \ No newline at end of file +} diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 568c05be1..75d940d3b 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -422,6 +422,7 @@ void FHardwareTexture::BindToFrameBuffer(int width, int height) bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags) { +#if 0 int usebright = false; if (translation <= 0) @@ -445,7 +446,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i // Create this texture unsigned char * buffer = nullptr; - if (!tex->bHasCanvas) + if (!tex->isHardwareCanvas()) { buffer = tex->CreateTexBuffer(translation, w, h, flags | CTF_ProcessData); } @@ -462,9 +463,10 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i } delete[] buffer; } - if (tex->bHasCanvas) static_cast(tex)->NeedUpdate(); + if (tex->isHardwareCanvas()) static_cast(tex)->NeedUpdate(); GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255); +#endif return true; } -} \ No newline at end of file +} diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index fd4c4123b..1fc3b9a35 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -210,14 +210,14 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh if (players[i].mo->ScoreIcon.isValid()) { FTexture *pic = TexMan[players[i].mo->ScoreIcon]; - width = pic->GetScaledWidth() - pic->GetScaledLeftOffset(0) + 2; + width = pic->GetDisplayWidth() - pic->GetDisplayLeftOffset() + 2; if (width > maxscorewidth) { maxscorewidth = width; } // The icon's top offset does not count toward its height, because // zdoom.pk3's standard Hexen class icons are designed that way. - int height = pic->GetScaledHeight() - pic->GetScaledTopOffset(0); + int height = pic->GetDisplayHeight() - pic->GetDisplayTopOffset(); if (height > maxiconheight) { maxiconheight = height; @@ -446,7 +446,7 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, if (teamplay && Teams[player->userinfo.GetTeam()].GetLogo().IsNotEmpty ()) { FTexture *pic = TexMan[Teams[player->userinfo.GetTeam()].GetLogo().GetChars ()]; - screen->DrawTexture (pic, col1 - (pic->GetScaledWidth() + 2) * CleanXfac, y, + screen->DrawTexture (pic, col1 - (pic->GetDisplayWidth() + 2) * CleanXfac, y, DTA_CleanNoMove, true, TAG_DONE); } } diff --git a/src/hwrenderer/scene/hw_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp index 39d4145f3..4375bc7a1 100644 --- a/src/hwrenderer/scene/hw_bsp.cpp +++ b/src/hwrenderer/scene/hw_bsp.cpp @@ -278,7 +278,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip) if (!seg->linedef->isVisualPortal()) { FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::mid)); - if (!tex || tex->UseType==ETextureType::Null) + if (!tex || !tex->isValid()) { // nothing to do here! seg->linedef->validcount=validcount; diff --git a/src/hwrenderer/scene/hw_fakeflat.cpp b/src/hwrenderer/scene/hw_fakeflat.cpp index 38cfaeefc..a70c74d0e 100644 --- a/src/hwrenderer/scene/hw_fakeflat.cpp +++ b/src/hwrenderer/scene/hw_fakeflat.cpp @@ -118,7 +118,7 @@ bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto if (bs_ceilingheight1 <= fs_floorheight1 && bs_ceilingheight2 <= fs_floorheight2) { FTexture * tex = TexMan(sidedef->GetTexture(side_t::top)); - if (!tex || tex->UseType == ETextureType::Null) return false; + if (!tex || !tex->isValid()) return false; if (backsector->GetTexture(sector_t::ceiling) == skyflatnum && frontsector->GetTexture(sector_t::ceiling) == skyflatnum) return false; return true; @@ -127,7 +127,7 @@ bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto if (fs_ceilingheight1 <= bs_floorheight1 && fs_ceilingheight2 <= bs_floorheight2) { FTexture * tex = TexMan(sidedef->GetTexture(side_t::bottom)); - if (!tex || tex->UseType == ETextureType::Null) return false; + if (!tex || !tex->isValid()) return false; // properly render skies (consider door "open" if both floors are sky): if (backsector->GetTexture(sector_t::ceiling) == skyflatnum && @@ -141,12 +141,12 @@ bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto if (bs_ceilingheight1 < fs_ceilingheight1 || bs_ceilingheight2 < fs_ceilingheight2) { FTexture * tex = TexMan(sidedef->GetTexture(side_t::top)); - if (!tex || tex->UseType == ETextureType::Null) return false; + if (!tex || !tex->isValid()) return false; } if (bs_floorheight1 > fs_floorheight1 || bs_floorheight2 > fs_floorheight2) { FTexture * tex = TexMan(sidedef->GetTexture(side_t::bottom)); - if (!tex || tex->UseType == ETextureType::Null) return false; + if (!tex || !tex->isValid()) return false; } if (backsector->GetTexture(sector_t::ceiling) == skyflatnum && frontsector->GetTexture(sector_t::ceiling) == skyflatnum) return false; diff --git a/src/hwrenderer/scene/hw_flats.cpp b/src/hwrenderer/scene/hw_flats.cpp index 4e53635b7..b63987fd0 100644 --- a/src/hwrenderer/scene/hw_flats.cpp +++ b/src/hwrenderer/scene/hw_flats.cpp @@ -70,7 +70,7 @@ bool hw_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte float xscale1 = secplane->Scale.X; float yscale1 = secplane->Scale.Y; - if (gltexture->tex->bHasCanvas) + if (gltexture->hasCanvas()) { yscale1 = 0 - yscale1; } diff --git a/src/hwrenderer/scene/hw_renderhacks.cpp b/src/hwrenderer/scene/hw_renderhacks.cpp index 6814fd5f5..8f75bb02f 100644 --- a/src/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/hwrenderer/scene/hw_renderhacks.cpp @@ -351,7 +351,7 @@ bool HWDrawInfo::DoOneSectorUpper(subsector_t * subsec, float Planez, area_t in_ { // If there's a texture abort FTexture * tex = TexMan[seg->sidedef->GetTexture(side_t::top)]; - if (!tex || tex->UseType == ETextureType::Null) continue; + if (!tex || !tex->isValid()) continue; else return false; } } @@ -409,7 +409,7 @@ bool HWDrawInfo::DoOneSectorLower(subsector_t * subsec, float Planez, area_t in_ { // If there's a texture abort FTexture * tex = TexMan[seg->sidedef->GetTexture(side_t::bottom)]; - if (!tex || tex->UseType == ETextureType::Null) continue; + if (!tex || !tex->isValid()) continue; else return false; } } diff --git a/src/hwrenderer/scene/hw_sky.cpp b/src/hwrenderer/scene/hw_sky.cpp index 695321312..15d6b6f7c 100644 --- a/src/hwrenderer/scene/hw_sky.cpp +++ b/src/hwrenderer/scene/hw_sky.cpp @@ -61,7 +61,7 @@ void GLSkyInfo::init(int sky1, PalEntry FadeColor) FTextureID texno = s->GetTexture(pos); texture[0] = FMaterial::ValidateTexture(texno, false, true); - if (!texture[0] || texture[0]->tex->UseType == ETextureType::Null) goto normalsky; + if (!texture[0] || !texture[0]->tex->isValid()) goto normalsky; skytexno1 = texno; x_offset[0] = s->GetTextureXOffset(pos) * (360.f/65536.f); y_offset = s->GetTextureYOffset(pos); @@ -244,7 +244,7 @@ void GLWall::SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vert if (bs->GetPlaneTexZ(sector_t::floor)==fs->GetPlaneTexZ(sector_t::floor)+1.) { FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::bottom)); - if (!tex || tex->UseType==ETextureType::Null) return; + if (!tex || !tex->isValid()) return; // very, very, very ugly special case (See Icarus MAP14) // It is VERY important that this is only done for a floor height difference of 1 @@ -327,8 +327,8 @@ void GLWall::SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,v if (bs->special == GLSector_NoSkyDraw) return; FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::bottom)); - // For lower skies the normal logic only applies to walls with no lower texture! - if (tex->UseType==ETextureType::Null) + // For lower skies the normal logic only applies to walls with no lower texture. + if (!tex->isValid()) { if (bs->GetTexture(sector_t::floor)==skyflatnum) { @@ -346,7 +346,7 @@ void GLWall::SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,v } zbottom[0]=zbottom[1]=-32768.0f; - if ((tex && tex->UseType!=ETextureType::Null) || bs->GetTexture(sector_t::floor)!=skyflatnum) + if ((tex && !tex->isValid()) || bs->GetTexture(sector_t::floor)!=skyflatnum) { ztop[0]=zfloor[0]; ztop[1]=zfloor[1]; diff --git a/src/hwrenderer/scene/hw_skydome.cpp b/src/hwrenderer/scene/hw_skydome.cpp index 27342cf7d..f0436ca53 100644 --- a/src/hwrenderer/scene/hw_skydome.cpp +++ b/src/hwrenderer/scene/hw_skydome.cpp @@ -293,7 +293,7 @@ void FSkyVertexBuffer::SetupMatrices(FMaterial *tex, float x_offset, float y_off float yscale = 1.f; if (texh <= 128 && (level.flags & LEVEL_FORCETILEDSKY)) { - modelMatrix.translate(0.f, (-40 + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f); + modelMatrix.translate(0.f, (-40 + tex->tex->GetSkyOffset() + skyoffset)*skyoffsetfactor, 0.f); modelMatrix.scale(1.f, 1.2f * 1.17f, 1.f); yscale = 240.f / texh; } @@ -311,12 +311,12 @@ void FSkyVertexBuffer::SetupMatrices(FMaterial *tex, float x_offset, float y_off } else if (texh <= 240) { - modelMatrix.translate(0.f, (200 - texh + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f); + modelMatrix.translate(0.f, (200 - texh + tex->tex->GetSkyOffset() + skyoffset)*skyoffsetfactor, 0.f); modelMatrix.scale(1.f, 1.f + ((texh - 200.f) / 200.f) * 1.17f, 1.f); } else { - modelMatrix.translate(0.f, (-40 + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f); + modelMatrix.translate(0.f, (-40 + tex->tex->GetSkyOffset() + skyoffset)*skyoffsetfactor, 0.f); modelMatrix.scale(1.f, 1.2f * 1.17f, 1.f); yscale = 240.f / texh; } diff --git a/src/hwrenderer/scene/hw_skyportal.cpp b/src/hwrenderer/scene/hw_skyportal.cpp index cb04c1e86..0f0450165 100644 --- a/src/hwrenderer/scene/hw_skyportal.cpp +++ b/src/hwrenderer/scene/hw_skyportal.cpp @@ -181,7 +181,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state) di->SetupView(state, 0, 0, 0, !!(mState->MirrorFlag & 1), !!(mState->PlaneMirrorFlag & 1)); state.SetVertexBuffer(vertexBuffer); - if (origin->texture[0] && origin->texture[0]->tex->bSkybox) + if (origin->texture[0] && origin->texture[0]->tex->isSkybox()) { RenderBox(di, state, origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->sky2); } diff --git a/src/hwrenderer/scene/hw_sprites.cpp b/src/hwrenderer/scene/hw_sprites.cpp index 84a91a307..4d31c71d7 100644 --- a/src/hwrenderer/scene/hw_sprites.cpp +++ b/src/hwrenderer/scene/hw_sprites.cpp @@ -791,7 +791,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t // Animate picnum overrides. auto tex = TexMan(thing->picnum); if (tex == nullptr) return; - patch = tex->id; + patch = tex->GetID(); mirror = false; } else @@ -910,7 +910,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t // allow disabling of the fullbright flag by a brightmap definition // (e.g. to do the gun flashes of Doom's zombies correctly. fullbright = (thing->flags5 & MF5_BRIGHT) || - ((thing->renderflags & RF_FULLBRIGHT) && (!gltexture || !gltexture->tex->bDisableFullbright)); + ((thing->renderflags & RF_FULLBRIGHT) && (!gltexture || !gltexture->tex->isFullbrightDisabled())); lightlevel = fullbright ? 255 : hw_ClampLight(rendersector->GetTexture(sector_t::ceiling) == skyflatnum ? diff --git a/src/hwrenderer/scene/hw_walls.cpp b/src/hwrenderer/scene/hw_walls.cpp index 70ca0f633..47023d524 100644 --- a/src/hwrenderer/scene/hw_walls.cpp +++ b/src/hwrenderer/scene/hw_walls.cpp @@ -1000,7 +1000,7 @@ bool GLWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto if (gltexture != NULL) { bool normalize = false; - if (gltexture->tex->bHasCanvas) normalize = true; + if (gltexture->tex->isHardwareCanvas()) normalize = true; else if (flags & GLWF_CLAMPY) { // for negative scales we can get negative coordinates here. @@ -1029,7 +1029,7 @@ void GLWall::CheckTexturePosition(FTexCoordInfo *tci) { float sub; - if (gltexture->tex->bHasCanvas) return; + if (gltexture->tex->isHardwareCanvas()) return; // clamp texture coordinates to a reasonable range. // Extremely large values can cause visual problems @@ -1223,7 +1223,7 @@ void GLWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, // // FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::top)); - if (!tex || tex->UseType==ETextureType::Null) + if (!tex || !tex->isValid()) { if (front->GetTexture(sector_t::ceiling) == skyflatnum && back->GetTexture(sector_t::ceiling) == skyflatnum && !wrap) @@ -1259,7 +1259,7 @@ void GLWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, // // tex = TexMan(seg->sidedef->GetTexture(side_t::bottom)); - if (!tex || tex->UseType==ETextureType::Null) + if (!tex || !tex->isValid()) { // texture is missing - use the lower plane bottomleft = MIN(bfh1,ffh1); diff --git a/src/hwrenderer/scene/hw_weapon.cpp b/src/hwrenderer/scene/hw_weapon.cpp index 171c28647..6cb719fae 100644 --- a/src/hwrenderer/scene/hw_weapon.cpp +++ b/src/hwrenderer/scene/hw_weapon.cpp @@ -132,7 +132,7 @@ static bool isBright(DPSprite *psp) if (lump.isValid()) { FTexture * tex = TexMan(lump); - if (tex) disablefullbright = tex->bDisableFullbright; + if (tex) disablefullbright = tex->isFullbrightDisabled(); } return psp->GetState()->GetFullbright() && !disablefullbright; } diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 303c3e83a..6f0e3eeca 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -164,12 +164,12 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { mShaderIndex = SHADER_Paletted; } - else if (tx->bWarped) + else if (tx->isWarped()) { - mShaderIndex = tx->bWarped; // This picks SHADER_Warp1 or SHADER_Warp2 + mShaderIndex = tx->isWarped(); // This picks SHADER_Warp1 or SHADER_Warp2 tx->shaderspeed = static_cast(tx)->GetSpeed(); } - else if (tx->bHasCanvas) + else if (tx->isHardwareCanvas()) { if (tx->shaderindex >= FIRST_USER_SHADER) { @@ -265,7 +265,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) mMaxBound = -1; mMaterials.Push(this); tx->Material[expanded] = this; - if (tx->bHasCanvas) tx->bTranslucent = 0; + if (tx->isHardwareCanvas()) tx->bTranslucent = 0; } //=========================================================================== @@ -484,19 +484,19 @@ int FMaterial::GetAreas(FloatRect **pAreas) const // //========================================================================== -FMaterial * FMaterial::ValidateTexture(FTexture * tex, bool expand) +FMaterial * FMaterial::ValidateTexture(FTexture * tex, bool expand, bool create) { again: - if (tex && tex->UseType!=ETextureType::Null) + if (tex && tex->isValid()) { if (tex->bNoExpand) expand = false; FMaterial *gltex = tex->Material[expand]; - if (gltex == NULL) + if (gltex == NULL && create) { if (expand) { - if (tex->bWarped || tex->bHasCanvas || tex->shaderindex >= FIRST_USER_SHADER || (tex->shaderindex >= SHADER_Specular && tex->shaderindex <= SHADER_PBRBrightmap)) + if (tex->isWarped() || tex->isHardwareCanvas() || tex->shaderindex >= FIRST_USER_SHADER || (tex->shaderindex >= SHADER_Specular && tex->shaderindex <= SHADER_PBRBrightmap)) { tex->bNoExpand = true; goto again; @@ -518,9 +518,9 @@ again: return NULL; } -FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translate) +FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translate, bool create) { - return ValidateTexture(translate? TexMan(no) : TexMan[no], expand); + return ValidateTexture(translate? TexMan(no) : TexMan[no], expand, create); } @@ -554,41 +554,3 @@ void FMaterial::Clean(bool f) mBaseLayer->Clean(f); } -//========================================================================== -// -// Prints some texture info -// -//========================================================================== - -CCMD(textureinfo) -{ - int cntt = 0; - for (int i = 0; i < TexMan.NumTextures(); i++) - { - FTexture *tex = TexMan.ByIndex(i); - if (tex->SystemTexture[0] || tex->SystemTexture[1] || tex->Material[0] || tex->Material[1]) - { - int lump = tex->GetSourceLump(); - Printf(PRINT_LOG, "Texture '%s' (Index %d, Lump %d, Name '%s'):\n", tex->Name.GetChars(), i, lump, Wads.GetLumpFullName(lump)); - if (tex->Material[0]) - { - Printf(PRINT_LOG, "in use (normal)\n"); - } - else if (tex->SystemTexture[0]) - { - Printf(PRINT_LOG, "referenced (normal)\n"); - } - if (tex->Material[1]) - { - Printf(PRINT_LOG, "in use (expanded)\n"); - } - else if (tex->SystemTexture[1]) - { - Printf(PRINT_LOG, "referenced (normal)\n"); - } - cntt++; - } - } - Printf(PRINT_LOG, "%d system textures\n", cntt); -} - diff --git a/src/hwrenderer/textures/hw_material.h b/src/hwrenderer/textures/hw_material.h index c35b23c08..e16c8059f 100644 --- a/src/hwrenderer/textures/hw_material.h +++ b/src/hwrenderer/textures/hw_material.h @@ -87,6 +87,11 @@ public: { return mTextureLayers.Size() + 1; } + + bool hasCanvas() + { + return tex->isHardwareCanvas(); + } IHardwareTexture *GetLayer(int i, FTexture **pLayer = nullptr) { @@ -165,8 +170,8 @@ public: static void DeleteAll(); static void FlushAll(); - static FMaterial *ValidateTexture(FTexture * tex, bool expand); - static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans); + static FMaterial *ValidateTexture(FTexture * tex, bool expand, bool create = true); + static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans, bool create = true); }; #endif diff --git a/src/hwrenderer/textures/hw_precache.cpp b/src/hwrenderer/textures/hw_precache.cpp index a6342d2fb..492610a7c 100644 --- a/src/hwrenderer/textures/hw_precache.cpp +++ b/src/hwrenderer/textures/hw_precache.cpp @@ -48,11 +48,6 @@ static void PrecacheTexture(FTexture *tex, int cache) FMaterial * gltex = FMaterial::ValidateTexture(tex, false); if (gltex) gltex->Precache(); } - else - { - // make sure that software pixel buffers do not stick around for unneeded textures. - tex->Unload(); - } } //========================================================================== @@ -91,14 +86,14 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl if (texhitlist[i] & (FTextureManager::HIT_Sky | FTextureManager::HIT_Wall)) { FTexture *tex = TexMan.ByIndex(i); - if (tex->bSkybox) + if (tex->isSkybox()) { FSkyBox *sb = static_cast(tex); for (int i = 0; i<6; i++) { if (sb->faces[i]) { - int index = sb->faces[i]->id.GetIndex(); + int index = sb->faces[i]->GetID().GetIndex(); texhitlist[index] |= FTextureManager::HIT_Flat; } } @@ -181,11 +176,13 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl { if (!texhitlist[i]) { - if (tex->Material[0]) tex->Material[0]->Clean(true); + auto mat = FMaterial::ValidateTexture(tex, false, false); + if (mat) mat->Clean(true); } if (spritehitlist[i] == nullptr || (*spritehitlist[i]).CountUsed() == 0) { - if (tex->Material[1]) tex->Material[1]->Clean(true); + auto mat = FMaterial::ValidateTexture(tex, true, false); + if (mat) mat->Clean(true); } } } diff --git a/src/hwrenderer/utility/hw_draw2d.cpp b/src/hwrenderer/utility/hw_draw2d.cpp index f15ddc2c4..0e224b26d 100644 --- a/src/hwrenderer/utility/hw_draw2d.cpp +++ b/src/hwrenderer/utility/hw_draw2d.cpp @@ -169,7 +169,7 @@ void Draw2D(F2DDrawer *drawer, FRenderState &state) state.EnableTexture(true); // Canvas textures are stored upside down - if (cmd.mTexture->bHasCanvas) + if (cmd.mTexture->isHardwareCanvas()) { state.mTextureMatrix.loadIdentity(); state.mTextureMatrix.scale(1.f, -1.f, 1.f); diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 65f31910e..0477cb5af 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -573,8 +573,8 @@ void DIntermissionScreenCast::Drawer () screen->DrawTexture (pic, 160, 170, DTA_320x200, true, DTA_FlipX, sprframe->Flip & 1, - DTA_DestHeightF, pic->GetScaledHeightDouble() * castscale.Y, - DTA_DestWidthF, pic->GetScaledWidthDouble() * castscale.X, + DTA_DestHeightF, pic->GetDisplayHeightDouble() * castscale.Y, + DTA_DestWidthF, pic->GetDisplayWidthDouble() * castscale.X, DTA_RenderStyle, mDefaults->RenderStyle, DTA_Alpha, mDefaults->Alpha, DTA_TranslationIndex, casttranslation, @@ -616,8 +616,8 @@ void DIntermissionScreenScroller::Drawer () if (mTicker >= mScrollDelay && mTicker < mScrollDelay + mScrollTime && tex != NULL && tex2 != NULL) { - int fwidth = tex->GetScaledWidth(); - int fheight = tex->GetScaledHeight(); + int fwidth = tex->GetDisplayWidth(); + int fheight = tex->GetDisplayHeight(); double xpos1 = 0, ypos1 = 0, xpos2 = 0, ypos2 = 0; diff --git a/src/menu/loadsavemenu.cpp b/src/menu/loadsavemenu.cpp index 8211cc57f..6361e8e4f 100644 --- a/src/menu/loadsavemenu.cpp +++ b/src/menu/loadsavemenu.cpp @@ -502,7 +502,7 @@ unsigned FSavegameManager::ExtractSaveData(int index) { SavePic = PNGTexture_CreateFromFile(png, node->Filename); delete png; - if (SavePic->GetWidth() == 1 && SavePic->GetHeight() == 1) + if (SavePic->GetDisplayWidth() == 1 && SavePic->GetDisplayHeight() == 1) { delete SavePic; SavePic = nullptr; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 44038184d..7cb94029f 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -6690,7 +6690,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) auto a = SingleActorFromTID(args[0], activator); if (a != nullptr) { - return GlobalACSStrings.AddString(TexMan[a->floorpic]->Name); + return GlobalACSStrings.AddString(TexMan[a->floorpic]->GetName()); } else { diff --git a/src/p_doors.cpp b/src/p_doors.cpp index fa08f3259..aac4097f9 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -294,7 +294,7 @@ void DDoor::DoorSound(bool raise, DSeqNode *curseq) const continue; FTexture *tex = TexMan[line->sidedef[0]->GetTexture(side_t::top)]; - texname = tex ? tex->Name.GetChars() : NULL; + texname = tex ? tex->GetName().GetChars() : NULL; if (texname != NULL && texname[0] == 'D' && texname[1] == 'O' && texname[2] == 'R') { switch (texname[3]) @@ -715,9 +715,8 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, picnum = tex1[side_t::top].texture; - // don't forget texture scaling here! FTexture *tex = TexMan[picnum]; - topdist = tex ? tex->GetScaledHeight() : 64; + topdist = tex ? tex->GetDisplayHeight() : 64; topdist = m_Sector->ceilingplane.fD() - topdist * m_Sector->ceilingplane.fC(); diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 0f8285e93..56df21cba 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -480,7 +480,7 @@ static inline void CheckShortestTex (FTextureID texnum, double &minsize) FTexture *tex = TexMan[texnum]; if (tex != NULL) { - double h = tex->GetScaledHeight(); + double h = tex->GetDisplayHeight(); if (h < minsize) { minsize = h; @@ -501,7 +501,7 @@ double FindShortestTextureAround (sector_t *sec) CheckShortestTex (check->sidedef[1]->GetTexture(side_t::bottom), minsize); } } - return minsize < FLT_MAX ? minsize : TexMan[0]->GetHeight(); + return minsize < FLT_MAX ? minsize : TexMan[0]->GetDisplayHeight(); } // @@ -526,7 +526,7 @@ double FindShortestUpperAround (sector_t *sec) CheckShortestTex (check->sidedef[1]->GetTexture(side_t::top), minsize); } } - return minsize < FLT_MAX ? minsize : TexMan[0]->GetHeight(); + return minsize < FLT_MAX ? minsize : TexMan[0]->GetDisplayHeight(); } // @@ -1147,11 +1147,11 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac) FTexture *tex = TexMan[GetTexture(sector_t::floor)]; if (tex != NULL && tex->isGlowing()) { - if (!tex->bAutoGlowing) tex = TexMan(GetTexture(sector_t::floor)); + if (!tex->isAutoGlowing()) tex = TexMan(GetTexture(sector_t::floor)); if (tex->isGlowing()) // recheck the current animation frame. { tex->GetGlowColor(bottomglowcolor); - bottomglowcolor[3] = (float)tex->GlowHeight; + bottomglowcolor[3] = (float)tex->GetGlowHeight(); } } } @@ -1192,12 +1192,12 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac) FTexture *tex = TexMan[GetTexture(sector_t::ceiling)]; if (tex != NULL && tex->isGlowing()) { - if (!tex->bAutoGlowing) tex = TexMan(GetTexture(sector_t::ceiling)); + if (!tex->isAutoGlowing()) tex = TexMan(GetTexture(sector_t::ceiling)); if (tex->isGlowing()) // recheck the current animation frame. { ret = true; tex->GetGlowColor(topglowcolor); - topglowcolor[3] = (float)tex->GlowHeight; + topglowcolor[3] = (float)tex->GetGlowHeight(); } } } @@ -1216,12 +1216,12 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac) FTexture *tex = TexMan[GetTexture(sector_t::floor)]; if (tex != NULL && tex->isGlowing()) { - if (!tex->bAutoGlowing) tex = TexMan(GetTexture(sector_t::floor)); + if (!tex->isAutoGlowing()) tex = TexMan(GetTexture(sector_t::floor)); if (tex->isGlowing()) // recheck the current animation frame. { ret = true; tex->GetGlowColor(bottomglowcolor); - bottomglowcolor[3] = (float)tex->GlowHeight; + bottomglowcolor[3] = (float)tex->GetGlowHeight(); } } } diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index 158c24dcf..c249e2a7e 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -47,7 +47,7 @@ void PolyDrawArgs::SetTexture(const uint8_t *texels, int width, int height) mTranslation = nullptr; } -void PolyDrawArgs::SetTexture(FTexture *texture, FRenderStyle style) +void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, FRenderStyle style) { mTexture = texture; mTextureWidth = texture->GetWidth(); @@ -59,7 +59,7 @@ void PolyDrawArgs::SetTexture(FTexture *texture, FRenderStyle style) mTranslation = nullptr; } -void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style) +void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, uint32_t translationID, FRenderStyle style) { // Alphatexture overrides translations. if (translationID != 0xffffffff && translationID != 0 && !(style.Flags & STYLEF_RedIsAlpha)) @@ -140,7 +140,7 @@ void PolyDrawArgs::SetColor(uint32_t bgra, uint8_t palindex) } } -void PolyDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright) +void PolyDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FSoftwareTexture *tex, bool fullbright) { SetTexture(tex, translationID, renderstyle); SetColor(0xff000000 | fillcolor, fillcolor >> 24); @@ -203,7 +203,7 @@ void PolyDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint3 ///////////////////////////////////////////////////////////////////////////// -void RectDrawArgs::SetTexture(FTexture *texture, FRenderStyle style) +void RectDrawArgs::SetTexture(FSoftwareTexture *texture, FRenderStyle style) { mTexture = texture; mTextureWidth = texture->GetWidth(); @@ -215,7 +215,7 @@ void RectDrawArgs::SetTexture(FTexture *texture, FRenderStyle style) mTranslation = nullptr; } -void RectDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style) +void RectDrawArgs::SetTexture(FSoftwareTexture *texture, uint32_t translationID, FRenderStyle style) { // Alphatexture overrides translations. if (translationID != 0xffffffff && translationID != 0 && !(style.Flags & STYLEF_RedIsAlpha)) @@ -291,7 +291,7 @@ void RectDrawArgs::Draw(PolyRenderThread *thread, double x0, double x1, double y thread->DrawQueue->Push(*this); } -void RectDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *tex, bool fullbright) +void RectDrawArgs::SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FSoftwareTexture *tex, bool fullbright) { SetTexture(tex, translationID, renderstyle); SetColor(0xff000000 | fillcolor, fillcolor >> 24); diff --git a/src/polyrenderer/drawers/poly_draw_args.h b/src/polyrenderer/drawers/poly_draw_args.h index 8450bd655..b40e209a2 100644 --- a/src/polyrenderer/drawers/poly_draw_args.h +++ b/src/polyrenderer/drawers/poly_draw_args.h @@ -27,7 +27,7 @@ #include "screen_triangle.h" class PolyRenderThread; -class FTexture; +class FSoftwareTexture; class Mat4f; enum class PolyDrawMode @@ -67,8 +67,8 @@ class PolyDrawArgs public: void SetClipPlane(int index, const PolyClipPlane &plane) { mClipPlane[index] = plane; } void SetTexture(const uint8_t *texels, int width, int height); - void SetTexture(FTexture *texture, FRenderStyle style); - void SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style); + void SetTexture(FSoftwareTexture *texture, FRenderStyle style); + void SetTexture(FSoftwareTexture *texture, uint32_t translationID, FRenderStyle style); void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed); void SetDepthTest(bool enable) { mDepthTest = enable; } void SetStencilTestValue(uint8_t stencilTestValue) { mStencilTestValue = stencilTestValue; } @@ -76,7 +76,7 @@ public: void SetWriteStencil(bool enable, uint8_t stencilWriteValue = 0) { mWriteStencil = enable; mStencilWriteValue = stencilWriteValue; } void SetWriteDepth(bool enable) { mWriteDepth = enable; } void SetStyle(TriBlendMode blendmode, double alpha = 1.0) { mBlendMode = blendmode; mAlpha = (uint32_t)(alpha * 256.0 + 0.5); } - void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright); + void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FSoftwareTexture *texture, bool fullbright); void SetColor(uint32_t bgra, uint8_t palindex); void SetLights(PolyLight *lights, int numLights) { mLights = lights; mNumLights = numLights; } void SetDynLightColor(uint32_t color) { mDynLightColor = color; } @@ -85,7 +85,7 @@ public: bool WriteColor() const { return mWriteColor; } - FTexture *Texture() const { return mTexture; } + FSoftwareTexture *Texture() const { return mTexture; } const uint8_t *TexturePixels() const { return mTexturePixels; } int TextureWidth() const { return mTextureWidth; } int TextureHeight() const { return mTextureHeight; } @@ -131,7 +131,7 @@ private: bool mWriteStencil = true; bool mWriteColor = true; bool mWriteDepth = true; - FTexture *mTexture = nullptr; + FSoftwareTexture *mTexture = nullptr; const uint8_t *mTexturePixels = nullptr; int mTextureWidth = 0; int mTextureHeight = 0; @@ -166,15 +166,15 @@ private: class RectDrawArgs { public: - void SetTexture(FTexture *texture, FRenderStyle style); - void SetTexture(FTexture *texture, uint32_t translationID, FRenderStyle style); + void SetTexture(FSoftwareTexture *texture, FRenderStyle style); + void SetTexture(FSoftwareTexture *texture, uint32_t translationID, FRenderStyle style); void SetLight(FSWColormap *basecolormap, uint32_t lightlevel); void SetStyle(TriBlendMode blendmode, double alpha = 1.0) { mBlendMode = blendmode; mAlpha = (uint32_t)(alpha * 256.0 + 0.5); } - void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FTexture *texture, bool fullbright); + void SetStyle(const FRenderStyle &renderstyle, double alpha, uint32_t fillcolor, uint32_t translationID, FSoftwareTexture *texture, bool fullbright); void SetColor(uint32_t bgra, uint8_t palindex); void Draw(PolyRenderThread *thread, double x0, double x1, double y0, double y1, double u0, double u1, double v0, double v1); - FTexture *Texture() const { return mTexture; } + FSoftwareTexture *Texture() const { return mTexture; } const uint8_t *TexturePixels() const { return mTexturePixels; } int TextureWidth() const { return mTextureWidth; } int TextureHeight() const { return mTextureHeight; } @@ -207,7 +207,7 @@ public: float V1() const { return mV1; } private: - FTexture *mTexture = nullptr; + FSoftwareTexture *mTexture = nullptr; const uint8_t *mTexturePixels = nullptr; int mTextureWidth = 0; int mTextureHeight = 0; diff --git a/src/polyrenderer/poly_renderthread.cpp b/src/polyrenderer/poly_renderthread.cpp index 7febb4bb7..f9bc3831c 100644 --- a/src/polyrenderer/poly_renderthread.cpp +++ b/src/polyrenderer/poly_renderthread.cpp @@ -74,7 +74,7 @@ void PolyRenderThread::FlushDrawQueue() } } -void PolyRenderThread::PrepareTexture(FTexture *texture, FRenderStyle style) +void PolyRenderThread::PrepareTexture(FSoftwareTexture *texture, FRenderStyle style) { if (texture == nullptr) return; @@ -92,7 +92,7 @@ void PolyRenderThread::PrepareTexture(FTexture *texture, FRenderStyle style) std::unique_lock lock(loadmutex); texture->GetPixels(style); - const FTexture::Span *spans; + const FSoftwareTextureSpan *spans; texture->GetColumn(style, 0, &spans); if (PolyRenderer::Instance()->RenderTarget->IsBgra()) { diff --git a/src/polyrenderer/poly_renderthread.h b/src/polyrenderer/poly_renderthread.h index b9a6b32db..69e2e67e8 100644 --- a/src/polyrenderer/poly_renderthread.h +++ b/src/polyrenderer/poly_renderthread.h @@ -57,7 +57,7 @@ public: TArray AddedLightsArray; // Make sure texture can accessed safely - void PrepareTexture(FTexture *texture, FRenderStyle style); + void PrepareTexture(FSoftwareTexture *texture, FRenderStyle style); // Setup poly object in a threadsafe manner void PreparePolyObject(subsector_t *sub); diff --git a/src/polyrenderer/scene/poly_decal.cpp b/src/polyrenderer/scene/poly_decal.cpp index f15c15ba3..c91c48ad1 100644 --- a/src/polyrenderer/scene/poly_decal.cpp +++ b/src/polyrenderer/scene/poly_decal.cpp @@ -49,9 +49,11 @@ void RenderPolyDecal::Render(PolyRenderThread *thread, DBaseDecal *decal, const if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid()) return; - FTexture *tex = TexMan(decal->PicNum, true); - if (tex == nullptr || tex->UseType == ETextureType::Null) + FTexture *ttex = TexMan(decal->PicNum, true); + if (ttex == nullptr || !ttex->isValid()) return; + + FSoftwareTexture *tex = ttex->GetSoftwareTexture(); sector_t *front, *back; GetDecalSectors(decal, line, &front, &back); @@ -73,16 +75,16 @@ void RenderPolyDecal::Render(PolyRenderThread *thread, DBaseDecal *decal, const bool flipTextureX = (decal->RenderFlags & RF_XFLIP) == RF_XFLIP; double u_left = flipTextureX ? 1.0 : 0.0; - double u_right = flipTextureX ? 1.0 - tex->Scale.X : tex->Scale.X; + double u_right = flipTextureX ? 1.0 - tex->GetScale().X : tex->GetScale().X; double u_unit = (u_right - u_left) / (edge_left + edge_right); double zpos = GetDecalZ(decal, line, front, back); - double spriteHeight = decal->ScaleY / tex->Scale.Y * tex->GetHeight(); + double spriteHeight = decal->ScaleY / tex->GetScale().Y * tex->GetHeight(); double ztop = zpos + spriteHeight - spriteHeight * 0.5; double zbottom = zpos - spriteHeight * 0.5; double v_top = 0.0; - double v_bottom = tex->Scale.Y; + double v_bottom = tex->GetScale().Y; double v_unit = (v_bottom - v_top) / (zbottom - ztop); // Clip decal to wall part diff --git a/src/polyrenderer/scene/poly_model.cpp b/src/polyrenderer/scene/poly_model.cpp index cba1c991b..50deccdb6 100644 --- a/src/polyrenderer/scene/poly_model.cpp +++ b/src/polyrenderer/scene/poly_model.cpp @@ -67,7 +67,7 @@ static bool isBright(DPSprite *psp) if (lump.isValid()) { FTexture * tex = TexMan(lump); - if (tex) disablefullbright = tex->bDisableFullbright; + if (tex) disablefullbright = tex->isFullbrightDisabled(); } return psp->GetState()->GetFullbright() && !disablefullbright; } @@ -238,7 +238,7 @@ void PolyModelRenderer::SetInterpolation(double interpolation) void PolyModelRenderer::SetMaterial(FTexture *skin, bool clampNoFilter, int translation) { - SkinTexture = skin; + SkinTexture = skin? skin->GetSoftwareTexture() : nullptr; } void PolyModelRenderer::SetTransform() diff --git a/src/polyrenderer/scene/poly_model.h b/src/polyrenderer/scene/poly_model.h index ff7269e18..bdf6c9423 100644 --- a/src/polyrenderer/scene/poly_model.h +++ b/src/polyrenderer/scene/poly_model.h @@ -65,7 +65,7 @@ public: uint32_t Translation; Mat4f ObjectToWorld; - FTexture *SkinTexture = nullptr; + FSoftwareTexture *SkinTexture = nullptr; unsigned int *IndexBuffer = nullptr; FModelVertex *VertexBuffer = nullptr; float InterpolationFactor = 0.0; diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index 18d24cfd7..0f5a24235 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -67,10 +67,10 @@ void RenderPolyPlane::RenderNormal(PolyRenderThread *thread, const PolyTransferH if (picnum != skyflatnum) { FTexture *tex = TexMan(picnum); - if (!tex || tex->UseType == ETextureType::Null) + if (!tex || !tex->isValid()) return; - PolyPlaneUVTransform transform = PolyPlaneUVTransform(ceiling ? fakeflat.FrontSector->planes[sector_t::ceiling].xform : fakeflat.FrontSector->planes[sector_t::floor].xform, tex); + PolyPlaneUVTransform transform = PolyPlaneUVTransform(ceiling ? fakeflat.FrontSector->planes[sector_t::ceiling].xform : fakeflat.FrontSector->planes[sector_t::floor].xform, tex->GetSoftwareTexture()); TriVertex *vertices = CreatePlaneVertices(thread, fakeflat.Subsector, transform, ceiling ? fakeflat.FrontSector->ceilingplane : fakeflat.FrontSector->floorplane); PolyDrawArgs args; @@ -78,7 +78,7 @@ void RenderPolyPlane::RenderNormal(PolyRenderThread *thread, const PolyTransferH SetDynLights(thread, args, fakeflat.Subsector, ceiling); args.SetStencilTestValue(stencilValue); args.SetWriteStencil(true, stencilValue + 1); - args.SetTexture(tex, DefaultRenderStyle()); + args.SetTexture(tex->GetSoftwareTexture(), DefaultRenderStyle()); args.SetStyle(TriBlendMode::Opaque); PolyTriangleDrawer::DrawArray(thread->DrawQueue, args, vertices, fakeflat.Subsector->numlines, PolyDrawMode::TriangleFan); } @@ -389,12 +389,12 @@ TriVertex *RenderPolyPlane::CreateSkyPlaneVertices(PolyRenderThread *thread, sub ///////////////////////////////////////////////////////////////////////////// -PolyPlaneUVTransform::PolyPlaneUVTransform(const FTransform &transform, FTexture *tex) +PolyPlaneUVTransform::PolyPlaneUVTransform(const FTransform &transform, FSoftwareTexture *tex) { if (tex) { - xscale = (float)(transform.xScale * tex->Scale.X / tex->GetWidth()); - yscale = (float)(transform.yScale * tex->Scale.Y / tex->GetHeight()); + xscale = (float)(transform.xScale * tex->GetScale().X / tex->GetWidth()); + yscale = (float)(transform.yScale * tex->GetScale().Y / tex->GetHeight()); double planeang = (transform.Angle + transform.baseAngle).Radians(); cosine = (float)cos(planeang); @@ -510,8 +510,8 @@ void Render3DFloorPlane::RenderPlanes(PolyRenderThread *thread, subsector_t *sub void Render3DFloorPlane::Render(PolyRenderThread *thread) { FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture; - FTexture *tex = TexMan(picnum); - if (tex->UseType == ETextureType::Null) + auto tex = TexMan(picnum); + if (!tex->isValid()) return; PolyCameraLight *cameraLight = PolyCameraLight::Instance(); @@ -528,7 +528,7 @@ void Render3DFloorPlane::Render(PolyRenderThread *thread) int actualextralight = foggy ? 0 : PolyRenderer::Instance()->Viewpoint.extralight << 4; lightlevel = clamp(lightlevel + actualextralight, 0, 255); - PolyPlaneUVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex); + PolyPlaneUVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex->GetSoftwareTexture()); TriVertex *vertices = thread->FrameMemory->AllocMemory(sub->numlines); if (ceiling) @@ -562,6 +562,6 @@ void Render3DFloorPlane::Render(PolyRenderThread *thread) } args.SetStencilTestValue(stencilValue); args.SetWriteStencil(true, stencilValue + 1); - args.SetTexture(tex, DefaultRenderStyle()); + args.SetTexture(tex->GetSoftwareTexture(), DefaultRenderStyle()); PolyTriangleDrawer::DrawArray(thread->DrawQueue, args, vertices, sub->numlines, PolyDrawMode::TriangleFan); } diff --git a/src/polyrenderer/scene/poly_plane.h b/src/polyrenderer/scene/poly_plane.h index 96c115c19..74c6c7956 100644 --- a/src/polyrenderer/scene/poly_plane.h +++ b/src/polyrenderer/scene/poly_plane.h @@ -29,7 +29,7 @@ class PolyDrawSectorPortal; class PolyPlaneUVTransform { public: - PolyPlaneUVTransform(const FTransform &transform, FTexture *tex); + PolyPlaneUVTransform(const FTransform &transform, FSoftwareTexture *tex); TriVertex GetVertex(vertex_t *v1, double height) const { diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index ada83a747..dd4654aab 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -162,7 +162,7 @@ void RenderPolyPlayerSprites::RenderRemainingSprites() { for (const PolyHWAccelPlayerSprite &sprite : AcceleratedSprites) { - screen->DrawTexture(sprite.pic, + screen->DrawTexture(sprite.pic->GetTexture(), viewwindowx + sprite.x1, viewwindowy + viewheight / 2 - sprite.texturemid * sprite.yscale - 0.5, DTA_DestWidthF, FIXED2DBL(sprite.pic->GetWidth() * sprite.xscale), @@ -198,7 +198,8 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p spriteframe_t* sprframe; FTextureID picnum; uint16_t flip; - FTexture* tex; + FTexture* ttex; + FSoftwareTexture* tex; bool noaccel; double alpha = owner->Alpha; @@ -226,10 +227,12 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p picnum = sprframe->Texture[0]; flip = sprframe->Flip & 1; - tex = TexMan(picnum); + ttex = TexMan(picnum); - if (tex->UseType == ETextureType::Null) + if (!ttex->isValid()) return; + + tex = ttex->GetSoftwareTexture(); if (pspr->firstTic) { // Can't interpolate the first tic. @@ -290,7 +293,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p vis.renderflags = owner->renderflags; - vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->GetTopOffsetPo(); + vis.texturemid = (BASEYCENTER - sy) * tex->GetScale().Y + tex->GetTopOffsetPo(); if (viewpoint.camera->player && (renderToCanvas || viewheight == renderTarget->GetHeight() || @@ -304,20 +307,20 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p } vis.x1 = x1 < 0 ? 0 : x1; vis.x2 = x2 >= viewwidth ? viewwidth : x2; - vis.xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X); - vis.yscale = float(pspriteyscale / tex->Scale.Y); + vis.xscale = FLOAT2FIXED(pspritexscale / tex->GetScale().X); + vis.yscale = float(pspriteyscale / tex->GetScale().Y); vis.pic = tex; // If flip is used, provided that it's not already flipped (that would just invert itself) // (It's an XOR...) if (!(flip) != !(pspr->Flags & PSPF_FLIP)) { - vis.xiscale = -FLOAT2FIXED(pspritexiscale * tex->Scale.X); + vis.xiscale = -FLOAT2FIXED(pspritexiscale * tex->GetScale().X); vis.startfrac = (tex->GetWidth() << FRACBITS) - 1; } else { - vis.xiscale = FLOAT2FIXED(pspritexiscale * tex->Scale.X); + vis.xiscale = FLOAT2FIXED(pspritexiscale * tex->GetScale().X); vis.startfrac = 0; } diff --git a/src/polyrenderer/scene/poly_playersprite.h b/src/polyrenderer/scene/poly_playersprite.h index 010c1c7be..cba6cda52 100644 --- a/src/polyrenderer/scene/poly_playersprite.h +++ b/src/polyrenderer/scene/poly_playersprite.h @@ -47,7 +47,7 @@ public: fixed_t xscale = 0; float yscale = 0.0f; - FTexture *pic = nullptr; + FSoftwareTexture *pic = nullptr; fixed_t xiscale = 0; fixed_t startfrac = 0; @@ -67,7 +67,7 @@ public: class PolyHWAccelPlayerSprite { public: - FTexture *pic = nullptr; + FSoftwareTexture *pic = nullptr; double texturemid = 0.0; float yscale = 0.0f; fixed_t xscale = 0; diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp index 59157bf7b..1cca9dca4 100644 --- a/src/polyrenderer/scene/poly_sky.cpp +++ b/src/polyrenderer/scene/poly_sky.cpp @@ -63,7 +63,7 @@ void PolySkyDome::Render(PolyRenderThread *thread, const Mat4f &worldToView, con float offsetBaseV = 0.25f; float scaleFrontU = frameSetup.frontcyl / (float)frameSetup.frontskytex->GetWidth(); - float scaleFrontV = (float)frameSetup.frontskytex->Scale.Y * scaleBaseV; + float scaleFrontV = (float)frameSetup.frontskytex->GetScale().Y * scaleBaseV; float offsetFrontU = (float)((frameSetup.frontpos / 65536.0 + frameSetup.frontcyl / 2) / frameSetup.frontskytex->GetWidth()); float offsetFrontV = (float)((frameSetup.skymid / frameSetup.frontskytex->GetHeight() + offsetBaseV) * scaleBaseV); @@ -115,7 +115,7 @@ void PolySkyDome::RenderRow(PolyRenderThread *thread, PolyDrawArgs &args, int ro PolyTriangleDrawer::DrawArray(thread->DrawQueue, args, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleStrip); } -void PolySkyDome::RenderCapColorRow(PolyRenderThread *thread, PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap) +void PolySkyDome::RenderCapColorRow(PolyRenderThread *thread, PolyDrawArgs &args, FSoftwareTexture *skytex, int row, bool bottomCap) { uint32_t solid = skytex->GetSkyCapColor(bottomCap); uint8_t palsolid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)]; @@ -214,7 +214,7 @@ Mat4f PolySkyDome::GLSkyMath() float x_offset = 0.0f; float y_offset = 0.0f; bool mirror = false; - FTexture *tex = mCurrentSetup.frontskytex; + FSoftwareTexture *tex = mCurrentSetup.frontskytex; int texh = 0; int texw = 0; @@ -231,7 +231,7 @@ Mat4f PolySkyDome::GLSkyMath() float yscale = 1.f; if (texh <= 128 && (level.flags & LEVEL_FORCETILEDSKY)) { - modelMatrix = modelMatrix * Mat4f::Translate(0.f, 0.f, (-40 + tex->SkyOffset + skyoffset)*skyoffsetfactor); + modelMatrix = modelMatrix * Mat4f::Translate(0.f, 0.f, (-40 + tex->GetSkyOffset() + skyoffset)*skyoffsetfactor); modelMatrix = modelMatrix * Mat4f::Scale(1.f, 1.f, 1.2f * 1.17f); yscale = 240.f / texh; } @@ -249,12 +249,12 @@ Mat4f PolySkyDome::GLSkyMath() } else if (texh <= 240) { - modelMatrix = modelMatrix * Mat4f::Translate(0.f, 0.f, (200 - texh + tex->SkyOffset + skyoffset)*skyoffsetfactor); + modelMatrix = modelMatrix * Mat4f::Translate(0.f, 0.f, (200 - texh + tex->GetSkyOffset() + skyoffset)*skyoffsetfactor); modelMatrix = modelMatrix * Mat4f::Scale(1.f, 1.f, 1.f + ((texh - 200.f) / 200.f) * 1.17f); } else { - modelMatrix = modelMatrix * Mat4f::Translate(0.f, 0.f, (-40 + tex->SkyOffset + skyoffset)*skyoffsetfactor); + modelMatrix = modelMatrix * Mat4f::Translate(0.f, 0.f, (-40 + tex->GetSkyOffset() + skyoffset)*skyoffsetfactor); modelMatrix = modelMatrix * Mat4f::Scale(1.f, 1.f, 1.2f * 1.17f); yscale = 240.f / texh; } @@ -277,6 +277,14 @@ Mat4f PolySkyDome::GLSkyMath() ///////////////////////////////////////////////////////////////////////////// +static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true) +{ + auto tex = TexMan(texid, true); + if (tex == nullptr) return nullptr; + if (!allownull && !tex->isValid()) return nullptr; + return tex->GetSoftwareTexture(); +} + void PolySkySetup::Update() { FTextureID sky1tex, sky2tex; @@ -299,9 +307,9 @@ void PolySkySetup::Update() if (!(sectorSky & PL_SKYFLAT)) { // use sky1 sky1: - frontskytex = TexMan(sky1tex, true); + frontskytex = GetSWTex(sky1tex); if (level.flags & LEVEL_DOUBLESKY) - backskytex = TexMan(sky2tex, true); + backskytex = GetSWTex(sky2tex); else backskytex = nullptr; skyflip = false; @@ -312,7 +320,7 @@ void PolySkySetup::Update() } else if (sectorSky == PL_SKYFLAT) { // use sky2 - frontskytex = TexMan(sky2tex, true); + frontskytex = GetSWTex(sky2tex); backskytex = nullptr; frontcyl = sky2cyl; skyflip = false; @@ -338,8 +346,8 @@ void PolySkySetup::Update() pos = side_t::top; } - frontskytex = TexMan(s->GetTexture(pos), true); - if (frontskytex == nullptr || frontskytex->UseType == ETextureType::Null) + frontskytex = GetSWTex(s->GetTexture(pos), false); + if (frontskytex == nullptr) { // [RH] The blank texture: Use normal sky instead. goto sky1; } @@ -361,7 +369,7 @@ void PolySkySetup::Update() // allow old sky textures to be used. skyflip = l->args[2] ? false : true; - int frontxscale = int(frontskytex->Scale.X * 1024); + int frontxscale = int(frontskytex->GetScale().X * 1024); frontcyl = MAX(frontskytex->GetWidth(), frontxscale); } diff --git a/src/polyrenderer/scene/poly_sky.h b/src/polyrenderer/scene/poly_sky.h index 6c70edbb0..441086511 100644 --- a/src/polyrenderer/scene/poly_sky.h +++ b/src/polyrenderer/scene/poly_sky.h @@ -31,8 +31,8 @@ public: bool operator==(const PolySkySetup &that) const { return memcmp(this, &that, sizeof(PolySkySetup)) == 0; } bool operator!=(const PolySkySetup &that) const { return memcmp(this, &that, sizeof(PolySkySetup)) != 0; } - FTexture *frontskytex = nullptr; - FTexture *backskytex = nullptr; + FSoftwareTexture *frontskytex = nullptr; + FSoftwareTexture *backskytex = nullptr; bool skyflip = 0; int frontpos = 0; int backpos = 0; @@ -58,7 +58,7 @@ private: void CreateSkyHemisphere(bool zflip); void CreateDome(); void RenderRow(PolyRenderThread *thread, PolyDrawArgs &args, int row, uint32_t capcolor, uint8_t capcolorindex); - void RenderCapColorRow(PolyRenderThread *thread, PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap); + void RenderCapColorRow(PolyRenderThread *thread, PolyDrawArgs &args, FSoftwareTexture *skytex, int row, bool bottomCap); TriVertex SetVertexXYZ(float xx, float yy, float zz, float uu = 0, float vv = 0); diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 086d9485f..73da1528b 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -49,13 +49,13 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right) DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac); bool flipTextureX = false; - FTexture *tex = GetSpriteTexture(thing, flipTextureX); + FSoftwareTexture *tex = GetSpriteTexture(thing, flipTextureX); if (tex == nullptr) return false; DVector2 spriteScale = thing->Scale; - double thingxscalemul = spriteScale.X / tex->Scale.X; - double thingyscalemul = spriteScale.Y / tex->Scale.Y; + double thingxscalemul = spriteScale.X / tex->GetScale().X; + double thingyscalemul = spriteScale.Y / tex->GetScale().Y; double spriteWidth = thingxscalemul * tex->GetWidth(); double spriteHeight = thingyscalemul * tex->GetHeight(); @@ -105,11 +105,11 @@ void RenderPolySprite::Render(PolyRenderThread *thread, AActor *thing, subsector posZ += thing->GetBobOffset(viewpoint.TicFrac); bool flipTextureX = false; - FTexture *tex = GetSpriteTexture(thing, flipTextureX); - if (tex == nullptr || tex->UseType == ETextureType::Null) + FSoftwareTexture *tex = GetSpriteTexture(thing, flipTextureX); + if (tex == nullptr) return; - double thingyscalemul = thing->Scale.Y / tex->Scale.Y; + double thingyscalemul = thing->Scale.Y / tex->GetScale().Y; double spriteHeight = thingyscalemul * tex->GetHeight(); posZ -= (tex->GetHeight() - tex->GetTopOffsetPo()) * thingyscalemul; @@ -302,7 +302,7 @@ bool RenderPolySprite::IsThingCulled(AActor *thing) return false; } -FTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool &flipX) +FSoftwareTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool &flipX) { const auto &viewpoint = PolyRenderer::Instance()->Viewpoint; flipX = false; @@ -312,16 +312,17 @@ FTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool &flipX) if (thing->picnum.isValid()) { - FTexture *tex = TexMan(thing->picnum); - if (tex->UseType == ETextureType::Null) + FTexture *ttex = TexMan(thing->picnum); + if (!ttex || !ttex->isValid()) { return nullptr; } + FSoftwareTexture *tex = ttex->GetSoftwareTexture(); - if (tex->Rotations != 0xFFFF) + if (ttex->GetRotations() != 0xFFFF) { // choose a different rotation based on player view - spriteframe_t *sprframe = &SpriteFrames[tex->Rotations]; + spriteframe_t *sprframe = &SpriteFrames[ttex->GetRotations()]; DVector3 pos = thing->InterpolatedPosition(viewpoint.TicFrac); pos.Z += thing->GetBobOffset(viewpoint.TicFrac); DAngle ang = (pos - viewpoint.Pos).Angle(); @@ -335,7 +336,13 @@ FTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool &flipX) rot = (ang - thing->Angles.Yaw + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28; } flipX = (sprframe->Flip & (1 << rot)) != 0; - tex = TexMan[sprframe->Texture[rot]]; // Do not animate the rotation + ttex = TexMan[sprframe->Texture[rot]]; // Do not animate the rotation + tex = ttex->GetSoftwareTexture(); + if (!ttex || !ttex->isValid()) + { + return nullptr; + } + FSoftwareTexture *tex = ttex->GetSoftwareTexture(); } return tex; } @@ -364,7 +371,7 @@ FTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool &flipX) DAngle sprangle = thing->GetSpriteAngle((pos - viewpoint.Pos).Angle(), viewpoint.TicFrac); FTextureID tex = sprdef->GetSpriteFrame(thing->frame, -1, sprangle, &flipX); if (!tex.isValid()) return nullptr; - return TexMan[tex]; + return TexMan[tex]->GetSoftwareTexture(); } } } diff --git a/src/polyrenderer/scene/poly_sprite.h b/src/polyrenderer/scene/poly_sprite.h index d036176d3..7997228d6 100644 --- a/src/polyrenderer/scene/poly_sprite.h +++ b/src/polyrenderer/scene/poly_sprite.h @@ -31,7 +31,7 @@ public: static bool GetLine(AActor *thing, DVector2 &left, DVector2 &right); static bool IsThingCulled(AActor *thing); - static FTexture *GetSpriteTexture(AActor *thing, /*out*/ bool &flipX); + static FSoftwareTexture *GetSpriteTexture(AActor *thing, /*out*/ bool &flipX); private: static double PerformSpriteClipAdjustment(AActor *thing, const DVector2 &thingpos, double spriteheight, double z); diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index 3ba2e9f56..297e549f4 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -172,7 +172,7 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, seg_t *line, sector_t wall.FogBoundary = IsFogBoundary(frontsector, backsector); FTexture *midtex = TexMan(line->sidedef->GetTexture(side_t::mid), true); - if ((midtex && midtex->UseType != ETextureType::Null) || wall.FogBoundary) + if ((midtex && midtex->isValid()) || wall.FogBoundary) translucentWallsOutput.push_back(thread->FrameMemory->NewObject(wall)); if (polyportal) @@ -526,10 +526,10 @@ void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2) v2.v = texv1 * inv_t2 + texv2 * t2; } -FTexture *RenderPolyWall::GetTexture(const line_t *line, const side_t *side, side_t::ETexpart texpart) +FSoftwareTexture *RenderPolyWall::GetTexture(const line_t *line, const side_t *side, side_t::ETexpart texpart) { FTexture *tex = TexMan(side->GetTexture(texpart), true); - if (tex == nullptr || tex->UseType == ETextureType::Null) + if (tex == nullptr || !tex->isValid()) { // Mapping error. Doom floodfills this with a plane. // This code doesn't do that, but at least it uses the "right" texture.. @@ -549,10 +549,10 @@ FTexture *RenderPolyWall::GetTexture(const line_t *line, const side_t *side, sid tex = TexMan(line->frontsector->GetTexture(sector_t::floor), true); } - if (tex == nullptr || tex->UseType == ETextureType::Null) + if (tex == nullptr || !tex->isValid()) return nullptr; } - return tex; + return tex? tex->GetSoftwareTexture() : nullptr; } int RenderPolyWall::GetLightLevel() @@ -572,13 +572,13 @@ int RenderPolyWall::GetLightLevel() ///////////////////////////////////////////////////////////////////////////// -PolyWallTextureCoordsU::PolyWallTextureCoordsU(FTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart wallpart) +PolyWallTextureCoordsU::PolyWallTextureCoordsU(FSoftwareTexture *tex, const seg_t *lineseg, const line_t *line, const side_t *side, side_t::ETexpart wallpart) { // Calculate the U texture coordinate for the line double lineu1 = side->GetTextureXOffset(wallpart); double lineu2 = side->GetTextureXOffset(wallpart) + line->sidedef[0]->TexelLength * side->GetTextureXScale(wallpart); - lineu1 *= tex->Scale.X / tex->GetWidth(); - lineu2 *= tex->Scale.X / tex->GetWidth(); + lineu1 *= tex->GetScale().X / tex->GetWidth(); + lineu2 *= tex->GetScale().X / tex->GetWidth(); // Calculate where we are on the lineseg double t1, t2; @@ -606,11 +606,11 @@ PolyWallTextureCoordsU::PolyWallTextureCoordsU(FTexture *tex, const seg_t *lines ///////////////////////////////////////////////////////////////////////////// -PolyWallTextureCoordsV::PolyWallTextureCoordsV(FTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart wallpart, double topz, double bottomz, double unpeggedceil, double topTexZ, double bottomTexZ) +PolyWallTextureCoordsV::PolyWallTextureCoordsV(FSoftwareTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart wallpart, double topz, double bottomz, double unpeggedceil, double topTexZ, double bottomTexZ) { double yoffset = side->GetTextureYOffset(wallpart); - if (tex->bWorldPanning) - yoffset *= side->GetTextureYScale(wallpart) * tex->Scale.Y; + if (tex->useWorldPanning()) + yoffset *= side->GetTextureYScale(wallpart) * tex->GetScale().Y; switch (wallpart) { @@ -626,8 +626,8 @@ PolyWallTextureCoordsV::PolyWallTextureCoordsV(FTexture *tex, const line_t *line break; } - v1 *= tex->Scale.Y / tex->GetHeight(); - v2 *= tex->Scale.Y / tex->GetHeight(); + v1 *= tex->GetScale().Y / tex->GetHeight(); + v2 *= tex->GetScale().Y / tex->GetHeight(); double texZHeight = (bottomTexZ - topTexZ); if (texZHeight > 0.0f || texZHeight < -0.0f) @@ -641,12 +641,12 @@ PolyWallTextureCoordsV::PolyWallTextureCoordsV(FTexture *tex, const line_t *line } } -void PolyWallTextureCoordsV::CalcVTopPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double yoffset) +void PolyWallTextureCoordsV::CalcVTopPart(FSoftwareTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double yoffset) { bool pegged = (line->flags & ML_DONTPEGTOP) == 0; if (pegged) // bottom to top { - double texHeight = tex->GetHeight() / tex->Scale.Y; + double texHeight = tex->GetHeight() / tex->GetScale().Y; v1 = (topz - bottomz) * side->GetTextureYScale(side_t::top) - yoffset; v2 = -yoffset; v1 = texHeight - v1; @@ -659,7 +659,7 @@ void PolyWallTextureCoordsV::CalcVTopPart(FTexture *tex, const line_t *line, con } } -void PolyWallTextureCoordsV::CalcVMidPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double yoffset) +void PolyWallTextureCoordsV::CalcVMidPart(FSoftwareTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double yoffset) { bool pegged = (line->flags & ML_DONTPEGBOTTOM) == 0; if (pegged) // top to bottom @@ -669,7 +669,7 @@ void PolyWallTextureCoordsV::CalcVMidPart(FTexture *tex, const line_t *line, con } else // bottom to top { - double texHeight = tex->GetHeight() / tex->Scale.Y; + double texHeight = tex->GetHeight() / tex->GetScale().Y; v1 = yoffset - (topz - bottomz) * side->GetTextureYScale(side_t::mid); v2 = yoffset; v1 = texHeight + v1; @@ -677,7 +677,7 @@ void PolyWallTextureCoordsV::CalcVMidPart(FTexture *tex, const line_t *line, con } } -void PolyWallTextureCoordsV::CalcVBottomPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double unpeggedceil, double yoffset) +void PolyWallTextureCoordsV::CalcVBottomPart(FSoftwareTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double unpeggedceil, double yoffset) { bool pegged = (line->flags & ML_DONTPEGBOTTOM) == 0; if (pegged) // top to bottom diff --git a/src/polyrenderer/scene/poly_wall.h b/src/polyrenderer/scene/poly_wall.h index 4bd5d6617..03850b0fc 100644 --- a/src/polyrenderer/scene/poly_wall.h +++ b/src/polyrenderer/scene/poly_wall.h @@ -48,7 +48,7 @@ public: const line_t *LineSegLine = nullptr; const line_t *Line = nullptr; const side_t *Side = nullptr; - FTexture *Texture = nullptr; + FSoftwareTexture *Texture = nullptr; side_t::ETexpart Wallpart = side_t::mid; double TopTexZ = 0.0; double BottomTexZ = 0.0; @@ -72,13 +72,13 @@ private: void SetDynLights(PolyRenderThread *thread, PolyDrawArgs &args); static bool IsFogBoundary(sector_t *front, sector_t *back); - static FTexture *GetTexture(const line_t *Line, const side_t *Side, side_t::ETexpart texpart); + static FSoftwareTexture *GetTexture(const line_t *Line, const side_t *Side, side_t::ETexpart texpart); }; class PolyWallTextureCoordsU { public: - PolyWallTextureCoordsU(FTexture *tex, const seg_t *lineseg, const line_t *linesegline, const side_t *side, side_t::ETexpart wallpart); + PolyWallTextureCoordsU(FSoftwareTexture *tex, const seg_t *lineseg, const line_t *linesegline, const side_t *side, side_t::ETexpart wallpart); double u1, u2; }; @@ -86,14 +86,14 @@ public: class PolyWallTextureCoordsV { public: - PolyWallTextureCoordsV(FTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart wallpart, double topz, double bottomz, double unpeggedceil, double topTexZ, double bottomTexZ); + PolyWallTextureCoordsV(FSoftwareTexture *tex, const line_t *line, const side_t *side, side_t::ETexpart wallpart, double topz, double bottomz, double unpeggedceil, double topTexZ, double bottomTexZ); double v1, v2; private: - void CalcVTopPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double yoffset); - void CalcVMidPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double yoffset); - void CalcVBottomPart(FTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double unpeggedceil, double yoffset); + void CalcVTopPart(FSoftwareTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double yoffset); + void CalcVMidPart(FSoftwareTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double yoffset); + void CalcVBottomPart(FSoftwareTexture *tex, const line_t *line, const side_t *side, double topz, double bottomz, double unpeggedceil, double yoffset); }; class PolyTranslucentWall : public PolyTranslucentObject diff --git a/src/polyrenderer/scene/poly_wallsprite.cpp b/src/polyrenderer/scene/poly_wallsprite.cpp index 7702dbd3d..4313b6863 100644 --- a/src/polyrenderer/scene/poly_wallsprite.cpp +++ b/src/polyrenderer/scene/poly_wallsprite.cpp @@ -40,13 +40,13 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, AActor *thing, subse pos.Z += thing->GetBobOffset(viewpoint.TicFrac); bool flipTextureX = false; - FTexture *tex = RenderPolySprite::GetSpriteTexture(thing, flipTextureX); - if (tex == nullptr || tex->UseType == ETextureType::Null) + FSoftwareTexture *tex = RenderPolySprite::GetSpriteTexture(thing, flipTextureX); + if (tex == nullptr) return; DVector2 spriteScale = thing->Scale; - double thingxscalemul = spriteScale.X / tex->Scale.X; - double thingyscalemul = spriteScale.Y / tex->Scale.Y; + double thingxscalemul = spriteScale.X / tex->GetScale().X; + double thingyscalemul = spriteScale.Y / tex->GetScale().Y; double spriteHeight = thingyscalemul * tex->GetHeight(); DAngle ang = thing->Angles.Yaw + 90; @@ -91,8 +91,8 @@ void RenderPolyWallSprite::Render(PolyRenderThread *thread, AActor *thing, subse vertices[i].y = (float)p.Y; vertices[i].z = (float)(pos.Z + spriteHeight * offsets[i].second); vertices[i].w = 1.0f; - vertices[i].u = (float)(offsets[i].first * tex->Scale.X); - vertices[i].v = (float)((1.0f - offsets[i].second) * tex->Scale.Y); + vertices[i].u = (float)(offsets[i].first * tex->GetScale().X); + vertices[i].v = (float)((1.0f - offsets[i].second) * tex->GetScale().Y); if (flipTextureX) vertices[i].u = 1.0f - vertices[i].u; } diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index cb54f76c9..9243cd5be 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -652,13 +652,16 @@ bool I_SetCursor(FTexture* cursorpic) NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSCursor* cursor = nil; - if (NULL != cursorpic && ETextureType::Null != cursorpic->UseType) + if (NULL != cursorpic && cursorpic->isValid()) { // Create bitmap image representation + + int w, h; + auto sbuffer = cursorpic->CreateTexBuffer(0, w, h); - const NSInteger imageWidth = cursorpic->GetWidth(); - const NSInteger imageHeight = cursorpic->GetHeight(); - const NSInteger imagePitch = imageWidth * 4; + const NSInteger imageWidth = w; + const NSInteger imageHeight = h; + const NSInteger imagePitch = w * 4; NSBitmapImageRep* bitmapImageRep = [NSBitmapImageRep alloc]; [bitmapImageRep initWithBitmapDataPlanes:NULL @@ -675,20 +678,15 @@ bool I_SetCursor(FTexture* cursorpic) // Load bitmap data to representation uint8_t* buffer = [bitmapImageRep bitmapData]; - memset(buffer, 0, imagePitch * imageHeight); - - FBitmap bitmap(buffer, imagePitch, imageWidth, imageHeight); - cursorpic->CopyTrueColorPixels(&bitmap, 0, 0); + memcpy(buffer, sbuffer, imagePitch * imageHeight); + delete [] sbuffer; // Swap red and blue components in each pixel for (size_t i = 0; i < size_t(imageWidth * imageHeight); ++i) { const size_t offset = i * 4; - - const uint8_t temp = buffer[offset ]; - buffer[offset ] = buffer[offset + 2]; - buffer[offset + 2] = temp; + std::swap(buffer[offset ], buffer[offset + 2]); } // Create image from representation and set it as cursor diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 0861a9773..4f07ea48d 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -73,9 +73,7 @@ static void ParseVavoomSkybox() int facecount=0; int maplump = -1; bool error = false; - FSkyBox * sb = new FSkyBox; - sb->Name = sc.String; - sb->Name.ToUpper(); + FSkyBox * sb = new FSkyBox(sc.String); sb->fliptop = true; sc.MustGetStringName("{"); while (!sc.CheckString("}")) @@ -91,7 +89,7 @@ static void ParseVavoomSkybox() FTexture *tex = TexMan.FindTexture(sc.String, ETextureType::Wall, FTextureManager::TEXMAN_TryAny); if (tex == NULL) { - sc.ScriptMessage("Texture '%s' not found in Vavoom skybox '%s'\n", sc.String, sb->Name.GetChars()); + sc.ScriptMessage("Texture '%s' not found in Vavoom skybox '%s'\n", sc.String, sb->GetName().GetChars()); error = true; } sb->faces[facecount] = tex; @@ -101,7 +99,7 @@ static void ParseVavoomSkybox() } if (facecount != 6) { - sc.ScriptError("%s: Skybox definition requires 6 faces", sb->Name.GetChars()); + sc.ScriptError("%s: Skybox definition requires 6 faces", sb->GetName().GetChars()); } sb->SetSize(); if (!error) TexMan.AddTexture(sb); @@ -1140,14 +1138,6 @@ class GLDefsParser if (bmtex != NULL) { - /* I do not think this is needed any longer - if (tex->bWarped != 0) - { - Printf("Cannot combine warping with brightmap on texture '%s'\n", tex->Name.GetChars()); - return; - } - */ - bmtex->bMasked = false; tex->Brightmap = bmtex; } @@ -1367,7 +1357,7 @@ class GLDefsParser usershader.defines.AppendFormat("#define %s texture%d\n", texNameList[i].GetChars(), texNameIndex[i] + firstUserTexture); } - if (tex->bWarped != 0) + if (tex->isWarped() != 0) { Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars()); return; @@ -1608,7 +1598,7 @@ class GLDefsParser if (desc.shader.IsNotEmpty()) { - if (tex->bWarped != 0) + if (tex->isWarped() != 0) { Printf("Cannot combine warping with hardware shader on texture '%s'\n", tex->Name.GetChars()); return; diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index c1f1f3e02..6af8f5bda 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -122,7 +122,7 @@ static bool R_InstallSpriteLump (FTextureID lump, unsigned frame, char rot, bool if (frame >= MAX_SPRITE_FRAMES || rotation > 16) { - Printf (TEXTCOLOR_RED "R_InstallSpriteLump: Bad frame characters in lump %s\n", TexMan[lump]->Name.GetChars()); + Printf (TEXTCOLOR_RED "R_InstallSpriteLump: Bad frame characters in lump %s\n", TexMan[lump]->GetName().GetChars()); return false; } @@ -176,7 +176,7 @@ static bool R_InstallSpriteLump (FTextureID lump, unsigned frame, char rot, bool // [RH] Seperated out of R_InitSpriteDefs() -static void R_InstallSprite (int num, spriteframewithrotate *sprtemp, int &maxframe) +void R_InstallSprite (int num, spriteframewithrotate *sprtemp, int &maxframe) { int frame; int framestart; diff --git a/src/r_sky.cpp b/src/r_sky.cpp index 13d130adb..6297a822d 100644 --- a/src/r_sky.cpp +++ b/src/r_sky.cpp @@ -100,7 +100,7 @@ void R_InitSkyMap () if (skytex1 == nullptr) return; - if ((level.flags & LEVEL_DOUBLESKY) && skytex1->GetHeight() != skytex2->GetHeight()) + if ((level.flags & LEVEL_DOUBLESKY) && skytex1->GetDisplayHeight() != skytex2->GetDisplayHeight()) { Printf (TEXTCOLOR_BOLD "Both sky textures must be the same height." TEXTCOLOR_NORMAL "\n"); sky2texture = sky1texture; @@ -119,20 +119,30 @@ void R_InitSkyMap () // the screen when looking fully up. // h > 200: Unstretched, but the baseline is shifted down so that the top // of the texture is at the top of the screen when looking fully up. - skyheight = skytex1->GetScaledHeight(); - skystretch = false; - skytexturemid = 0; + skyheight = skytex1->GetDisplayHeight(); + if (skyheight >= 128 && skyheight < 200) { skystretch = (r_skymode == 1 && skyheight >= 128 && level.IsFreelookAllowed() && !(level.flags & LEVEL_FORCETILEDSKY)) ? 1 : 0; + } + else skystretch = false; + + // Anything below is only for the software renderer (todo - move it there!) + // Note: I don't think it is good that this stuff gets cached globally. + // For something that only needs to be once per frame it is rather pointless and makes it hard to swap out the underlying textures based on user settings. + FSoftwareTexture *sskytex1 = skytex1->GetSoftwareTexture(); + FSoftwareTexture *sskytex2 = skytex2->GetSoftwareTexture(); + skytexturemid = 0; + if (skyheight >= 128 && skyheight < 200) + { skytexturemid = -28; } else if (skyheight > 200) { - skytexturemid = (200 - skyheight) * skytex1->Scale.Y +((r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)) ? skytex1->SkyOffset + testskyoffset : 0); + skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y +((r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() + testskyoffset : 0); } if (viewwidth != 0 && viewheight != 0) @@ -155,8 +165,8 @@ void R_InitSkyMap () // giving a total sky width of 1024 pixels. So if the sky texture is no wider than 1024, // we map it to a cylinder with circumfrence 1024. For larger ones, we use the width of // the texture as the cylinder's circumfrence. - sky1cyl = MAX(skytex1->GetWidth(), fixed_t(skytex1->Scale.X * 1024)); - sky2cyl = MAX(skytex2->GetWidth(), fixed_t(skytex2->Scale.Y * 1024)); + sky1cyl = MAX(sskytex1->GetWidth(), fixed_t(sskytex1->GetScale().X * 1024)); + sky2cyl = MAX(sskytex2->GetWidth(), fixed_t(sskytex2->GetScale().Y * 1024)); } diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 52d9a4bd4..40b640e46 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -1108,7 +1108,7 @@ void SetCameraToTexture(AActor *viewpoint, const FString &texturename, double fo { // Only proceed if the texture actually has a canvas. FTexture *tex = TexMan[textureid]; - if (tex && tex->bHasCanvas) + if (tex && tex->isCanvas()) { FCanvasTextureInfo::Add(viewpoint, textureid, fov); } diff --git a/src/scripting/vm/jit_move.cpp b/src/scripting/vm/jit_move.cpp index b8953b2aa..0706f37b6 100644 --- a/src/scripting/vm/jit_move.cpp +++ b/src/scripting/vm/jit_move.cpp @@ -53,7 +53,7 @@ static void CastCo2S(FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %0 static int CastS2So(FString *b) { return FSoundID(*b); } static void CastSo2S(FString *a, int b) { *a = S_sfx[b].name; } static void CastSID2S(FString *a, unsigned int b) { *a = (b >= sprites.Size()) ? "TNT1" : sprites[b].name; } -static void CastTID2S(FString *a, int b) { auto tex = TexMan[*(FTextureID*)&b]; *a = (tex == nullptr) ? "(null)" : tex->Name.GetChars(); } +static void CastTID2S(FString *a, int b) { auto tex = TexMan[*(FTextureID*)&b]; *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); } void JitCompiler::EmitCAST() { diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index 59fbc7afc..d24534987 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -1875,7 +1875,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c { ASSERTS(a); ASSERTD(b); auto tex = TexMan[*(FTextureID*)&(reg.d[b])]; - reg.s[a] = tex == nullptr ? "(null)" : tex->Name.GetChars(); + reg.s[a] = tex == nullptr ? "(null)" : tex->GetName().GetChars(); break; } diff --git a/src/scripting/vmthunks.cpp b/src/scripting/vmthunks.cpp index c6998fec2..10a2b726f 100644 --- a/src/scripting/vmthunks.cpp +++ b/src/scripting/vmthunks.cpp @@ -2372,7 +2372,7 @@ DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, ReceivedWeapon, ReceivedWeapon) static int GetMugshot(DBaseStatusBar *self, int accuracy, int stateflags, const FString &def_face) { auto tex = self->mugshot.GetFace(self->CPlayer, def_face, accuracy, (FMugShot::StateFlags)stateflags); - return (tex ? tex->id.GetIndex() : -1); + return (tex ? tex->GetID().GetIndex() : -1); } DEFINE_ACTION_FUNCTION_NATIVE(DBaseStatusBar, GetMugshot, GetMugshot) diff --git a/src/swrenderer/r_renderthread.cpp b/src/swrenderer/r_renderthread.cpp index 986879618..775528d71 100644 --- a/src/swrenderer/r_renderthread.cpp +++ b/src/swrenderer/r_renderthread.cpp @@ -107,7 +107,7 @@ namespace swrenderer std::unique_lock lock(loadmutex); texture->GetPixels(style); - const FTexture::Span *spans; + const FSoftwareTextureSpan *spans; texture->GetColumn(style, 0, &spans); if (Viewport->RenderTarget->IsBgra()) { diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index a20b474cd..f8bb68ad7 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -88,7 +88,7 @@ void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache) { if (cache & FTextureManager::HIT_Columnmode) { - const FTexture::Span *spanp; + const FSoftwareTextureSpan *spanp; if (isbgra) tex->GetColumnBgra(0, &spanp); else diff --git a/src/swrenderer/things/r_playersprite.h b/src/swrenderer/things/r_playersprite.h index 64dd66172..24e6b25f0 100644 --- a/src/swrenderer/things/r_playersprite.h +++ b/src/swrenderer/things/r_playersprite.h @@ -39,7 +39,7 @@ namespace swrenderer fixed_t xscale = 0; float yscale = 0.0f; - FTexture *pic = nullptr; + FSoftwareTexture *pic = nullptr; fixed_t xiscale = 0; fixed_t startfrac = 0; diff --git a/src/swrenderer/viewport/r_spritedrawer.cpp b/src/swrenderer/viewport/r_spritedrawer.cpp index 20abfca51..7eb8007c1 100644 --- a/src/swrenderer/viewport/r_spritedrawer.cpp +++ b/src/swrenderer/viewport/r_spritedrawer.cpp @@ -62,14 +62,14 @@ namespace swrenderer dc_iscale = iscale; dc_textureheight = tex->GetHeight(); - const FTexture::Span *span; + const FSoftwareTextureSpan *span; const uint8_t *column; if (viewport->RenderTarget->IsBgra() && !drawer_needs_pal_input) column = (const uint8_t *)tex->GetColumnBgra(col >> FRACBITS, &span); else column = tex->GetColumn(style, col >> FRACBITS, &span); - FTexture::Span unmaskedSpan[2]; + FSoftwareTextureSpan unmaskedSpan[2]; if (unmasked) { span = unmaskedSpan; @@ -192,9 +192,9 @@ namespace swrenderer } // Grab the posts we need to draw - const FTexture::Span *span; + const FSoftwareTextureSpan *span; tex->GetColumnBgra(col >> FRACBITS, &span); - FTexture::Span unmaskedSpan[2]; + FSoftwareTextureSpan unmaskedSpan[2]; if (unmasked) { span = unmaskedSpan; diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index c1b8f5c48..7ac07fb25 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -224,7 +224,7 @@ void FTextureManager::InitAnimated (void) (anim_p[21] << 16) | (anim_p[22] << 24); // SMMU-style swirly hack? Don't apply on already-warping texture - if (animspeed > 65535 && tex1 != NULL && !tex1->bWarped) + if (animspeed > 65535 && tex1 != NULL && !tex1->isWarped()) { FTexture *warper = new FWarpTexture (tex1, 2); ReplaceTexture (pic1, warper, false); @@ -622,7 +622,7 @@ void FTextureManager::ParseWarp(FScanner &sc) // don't warp a texture more than once - if (!warper->bWarped) + if (!warper->isWarped()) { warper = new FWarpTexture (warper, type2? 2:1); ReplaceTexture (picnum, warper, false); diff --git a/src/textures/formats/canvastexture.cpp b/src/textures/formats/canvastexture.cpp index 49729818b..d27e1c8fb 100644 --- a/src/textures/formats/canvastexture.cpp +++ b/src/textures/formats/canvastexture.cpp @@ -61,7 +61,7 @@ FCanvasTexture::~FCanvasTexture () Unload (); } -const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) +const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) { bNeedsUpdate = true; if (Canvas == NULL) diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index fb9381808..beb25e6d0 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -164,7 +164,7 @@ public: protected: uint8_t *Pixels; - Span **Spans; + FSoftwareTextureSpan **Spans; int DefinitionLump; struct TexPart @@ -199,7 +199,7 @@ protected: // The getters must optionally redirect if it's a simple one-patch texture. const uint8_t *GetPixels(FRenderStyle style) override { return bRedirect ? Parts->Texture->GetPixels(style) : FWorldTexture::GetPixels(style); } - const uint8_t *GetColumn(FRenderStyle style, unsigned int col, const Span **out) override + const uint8_t *GetColumn(FRenderStyle style, unsigned int col, const FSoftwareTextureSpan **out) override { return bRedirect ? Parts->Texture->GetColumn(style, col, out) : FWorldTexture::GetColumn(style, col, out); } diff --git a/src/textures/formats/worldtexture.cpp b/src/textures/formats/worldtexture.cpp index db50c7fb4..d0b91c3a6 100644 --- a/src/textures/formats/worldtexture.cpp +++ b/src/textures/formats/worldtexture.cpp @@ -102,7 +102,7 @@ void FWorldTexture::Unload () // //========================================================================== -const uint8_t *FWorldTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) +const uint8_t *FWorldTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) { int index = !!(style.Flags & STYLEF_RedIsAlpha); GetPixels(style); diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 36581553c..bcaa1c801 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -33,7 +33,8 @@ // //----------------------------------------------------------------------------- -FSkyBox::FSkyBox() +FSkyBox::FSkyBox(const char *name) +: FTexture(name) { faces[0]=faces[1]=faces[2]=faces[3]=faces[4]=faces[5]=NULL; UseType = ETextureType::Override; @@ -58,7 +59,7 @@ FSkyBox::~FSkyBox() // //----------------------------------------------------------------------------- -const uint8_t *FSkyBox::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) +const uint8_t *FSkyBox::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) { if (faces[0]) return faces[0]->GetColumn(style, column, spans_out); return NULL; diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index 79fb9da4d..fd07b29d6 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -15,9 +15,9 @@ public: FTexture * faces[6]; bool fliptop; - FSkyBox(); + FSkyBox(const char *name = nullptr); ~FSkyBox(); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); const uint8_t *GetPixels (FRenderStyle style); int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); bool UseBasePalette(); @@ -27,9 +27,7 @@ public: { if (faces[0]) { - Width=faces[0]->GetWidth(); - Height=faces[0]->GetHeight(); - CalcBitSize(); + CopySize(faces[0]); } } diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 85b57798d..8bfa3be54 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -240,7 +240,7 @@ void FTexture::Unload() // //========================================================================== -const uint32_t *FTexture::GetColumnBgra(unsigned int column, const Span **spans_out) +const uint32_t *FTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) { const uint32_t *pixels = GetPixelsBgra(); if (pixels == nullptr) return nullptr; @@ -327,14 +327,14 @@ void FTexture::CalcBitSize () // //========================================================================== -FTexture::Span **FTexture::CreateSpans (const uint8_t *pixels) const +FSoftwareTextureSpan **FTexture::CreateSpans (const uint8_t *pixels) const { - Span **spans, *span; + FSoftwareTextureSpan **spans, *span; if (!bMasked) { // Texture does not have holes, so it can use a simpler span structure - spans = (Span **)M_Malloc (sizeof(Span*)*Width + sizeof(Span)*2); - span = (Span *)&spans[Width]; + spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*Width + sizeof(FSoftwareTextureSpan)*2); + span = (FSoftwareTextureSpan *)&spans[Width]; for (int x = 0; x < Width; ++x) { spans[x] = span; @@ -378,10 +378,10 @@ FTexture::Span **FTexture::CreateSpans (const uint8_t *pixels) const } // Allocate space for the spans - spans = (Span **)M_Malloc (sizeof(Span*)*numcols + sizeof(Span)*numspans); + spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*numcols + sizeof(FSoftwareTextureSpan)*numspans); // Fill in the spans - for (x = 0, span = (Span *)&spans[numcols], data_p = pixels; x < numcols; ++x) + for (x = 0, span = (FSoftwareTextureSpan *)&spans[numcols], data_p = pixels; x < numcols; ++x) { newspan = true; spans[x] = span; @@ -421,7 +421,7 @@ FTexture::Span **FTexture::CreateSpans (const uint8_t *pixels) const return spans; } -void FTexture::FreeSpans (Span **spans) const +void FTexture::FreeSpans (FSoftwareTextureSpan **spans) const { M_Free (spans); } @@ -996,29 +996,22 @@ PalEntry FTexture::GetSkyCapColor(bool bottom) int FTexture::CheckRealHeight() { - const FTexture::Span *span; - int maxy = 0, miny = GetHeight(); - - for (int i = 0; i < GetWidth(); ++i) + auto pixels = GetPixels(DefaultRenderStyle()); + + for(int h = GetHeight()-1; h>= 0; h--) { - GetColumn(DefaultRenderStyle(), i, &span); - while (span->Length != 0) + for(int w = 0; w < GetWidth(); w++) { - if (span->TopOffset < miny) + if (pixels[h + w * GetHeight()] != 0) { - miny = span->TopOffset; + // Scale maxy before returning it + h = int((h * 2) / Scale.Y); + h = (h >> 1) + (h & 1); + return h; } - if (span->TopOffset + span->Length > maxy) - { - maxy = span->TopOffset + span->Length; - } - span++; } } - // Scale maxy before returning it - maxy = int((maxy * 2) / Scale.Y); - maxy = (maxy >> 1) + (maxy & 1); - return maxy; + return 0; } //========================================================================== @@ -1461,7 +1454,7 @@ void FTexture::SetSpriteAdjust() // //=========================================================================== -const uint8_t *FTexture::GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) +const uint8_t *FTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) { return nullptr; } @@ -1511,43 +1504,6 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits) SystemTexture[0] = screen->CreateHardwareTexture(this); } -//========================================================================== -// -// Debug stuff -// -//========================================================================== - -#ifdef _DEBUG -// Prints the spans generated for a texture. Only needed for debugging. -CCMD (printspans) -{ - if (argv.argc() != 2) - return; - - FTextureID picnum = TexMan.CheckForTexture (argv[1], ETextureType::Any); - if (!picnum.Exists()) - { - Printf ("Unknown texture %s\n", argv[1]); - return; - } - FTexture *tex = TexMan[picnum]; - for (int x = 0; x < tex->GetWidth(); ++x) - { - const FTexture::Span *spans; - Printf ("%4d:", x); - tex->GetColumn(DefaultRenderStyle(), x, &spans); - while (spans->Length != 0) - { - Printf (" (%4d,%4d)", spans->TopOffset, spans->TopOffset+spans->Length-1); - spans++; - } - Printf ("\n"); - } -} - -#endif - - //=========================================================================== // // Coordinate helper. diff --git a/src/textures/textures.h b/src/textures/textures.h index 4c4cd57c6..f02c6e23b 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -211,10 +211,40 @@ enum FTextureFormat : uint32_t TEX_Count }; +class FSoftwareTexture; +class FGLRenderState; + +struct FSoftwareTextureSpan +{ + uint16_t TopOffset; + uint16_t Length; // A length of 0 terminates this column +}; + +struct spriteframewithrotate; +class FSerializer; // Base texture class class FTexture { + // This is initialization code that is allowed to have full access. + friend void R_InitSpriteDefs (); + friend void R_InstallSprite (int num, spriteframewithrotate *sprtemp, int &maxframe); + friend class GLDefsParser; + + // The serializer also needs access to more specific info that shouldn't be accessible through the interface. + friend FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTextureID *defval); + + // For now only give access to classes which cannot be reworked yet. None of these should remain here when all is done. + friend class FSoftwareTexture; + friend class FWarpTexture; + friend class FMaterial; + friend class FGLRenderState; // For now this needs access to some fields in ApplyMaterial. This should be rerouted through the Material class + friend struct FTexCoordInfo; + friend class FHardwareTexture; + friend class FMultiPatchTexture; + friend class FSkyBox; + friend void RecordTextureColors (FTexture *pic, uint8_t *usedcolors); + public: static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype); @@ -223,6 +253,61 @@ public: void AddAutoMaterials(); unsigned char *CreateUpsampledTextureBuffer(unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight, bool hasAlpha); + // These should only be used in places where the texture scaling must be ignored and absolutely nowhere else! + // Preferably all code depending on the physical texture size should be rewritten, unless it is part of the software rasterizer. + //int GetPixelWidth() { return GetWidth(); } + //int GetPixelHeight() { return GetHeight(); } + + // These are mainly meant for 2D code which only needs logical information about the texture to position it properly. + int GetDisplayWidth() { return GetScaledWidth(); } + int GetDisplayHeight() { return GetScaledHeight(); } + double GetDisplayWidthDouble() { return GetScaledWidthDouble(); } + double GetDisplayHeightDouble() { return GetScaledHeightDouble(); } + int GetDisplayLeftOffset() { return GetScaledLeftOffset(0); } + int GetDisplayTopOffset() { return GetScaledTopOffset(0); } + double GetDisplayLeftOffsetDouble() { return GetScaledLeftOffsetDouble(0); } + double GetDisplayTopOffsetDouble() { return GetScaledTopOffsetDouble(0); } + + + bool isValid() const { return UseType != ETextureType::Null; } + bool isSWCanvas() const { return UseType == ETextureType::SWCanvas; } + bool isSkybox() const { return bSkybox; } + bool isFullbrightDisabled() const { return bDisableFullbright; } + bool isHardwareCanvas() const { return bHasCanvas; } // There's two here so that this can deal with software canvases in the hardware renderer later. + bool isCanvas() const { return bHasCanvas; } + int isWarped() const { return bWarped; } + int GetRotations() const { return Rotations; } + void SetRotations(int rot) { Rotations = int16_t(rot); } + + const FString &GetName() const { return Name; } + bool allowNoDecals() const { return bNoDecals; } + bool isScaled() const { return Scale.X != 1 || Scale.Y != 1; } + int GetSkyOffset() const { return SkyOffset; } + FTextureID GetID() const { return id; } + PalEntry GetSkyCapColor(bool bottom); + virtual FTexture *GetRawTexture(); // for FMultiPatchTexture to override + void GetGlowColor(float *data); + bool isGlowing() const { return bGlowing; } + bool isAutoGlowing() const { return bAutoGlowing; } + int GetGlowHeight() const { return GlowHeight; } + bool isFullbright() const { return bFullbright; } + void CreateDefaultBrightmap(); + bool FindHoles(const unsigned char * buffer, int w, int h); + +public: + static void FlipSquareBlock (uint8_t *block, int x, int y); + static void FlipSquareBlockBgra (uint32_t *block, int x, int y); + static void FlipSquareBlockRemap (uint8_t *block, int x, int y, const uint8_t *remap); + static void FlipNonSquareBlock (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch); + static void FlipNonSquareBlockBgra (uint32_t *blockto, const uint32_t *blockfrom, int x, int y, int srcpitch); + static void FlipNonSquareBlockRemap (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch, const uint8_t *remap); + static bool SmoothEdges(unsigned char * buffer,int w, int h); + static PalEntry averageColor(const uint32_t *data, int size, int maxout); + + + FSoftwareTexture *GetSoftwareTexture(); + +protected: //int16_t LeftOffset, TopOffset; uint8_t WidthBits, HeightBits; @@ -234,6 +319,7 @@ public: FMaterial *Material[2] = { nullptr, nullptr }; IHardwareTexture *SystemTexture[2] = { nullptr, nullptr }; + FSoftwareTexture *SoftwareTexture; // None of the following pointers are owned by this texture, they are all controlled by the texture manager. @@ -292,17 +378,11 @@ public: - struct Span - { - uint16_t TopOffset; - uint16_t Length; // A length of 0 terminates this column - }; - // Returns a single column of the texture - virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); + virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); // Returns a single column of the texture, in BGRA8 format - virtual const uint32_t *GetColumnBgra(unsigned int column, const Span **spans_out); + virtual const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out); // Returns the whole texture, stored in column-major order virtual const uint8_t *GetPixels(FRenderStyle style); @@ -318,7 +398,6 @@ public: virtual bool UseBasePalette(); virtual int GetSourceLump() { return SourceLump; } virtual FTexture *GetRedirect(); - virtual FTexture *GetRawTexture(); // for FMultiPatchTexture to override virtual void Unload (); @@ -392,8 +471,6 @@ public: } void SetScaledSize(int fitwidth, int fitheight); - PalEntry GetSkyCapColor(bool bottom); - static PalEntry averageColor(const uint32_t *data, int size, int maxout); protected: uint16_t Width, Height, WidthMask; @@ -448,8 +525,8 @@ protected: FTexture (const char *name = NULL, int lumpnum = -1); - Span **CreateSpans (const uint8_t *pixels) const; - void FreeSpans (Span **spans) const; + FSoftwareTextureSpan **CreateSpans (const uint8_t *pixels) const; + void FreeSpans (FSoftwareTextureSpan **spans) const; void CalcBitSize (); void CopyInfo(FTexture *other) { @@ -481,21 +558,7 @@ private: PalEntry CeilingSkyColor; public: - static void FlipSquareBlock (uint8_t *block, int x, int y); - static void FlipSquareBlockBgra (uint32_t *block, int x, int y); - static void FlipSquareBlockRemap (uint8_t *block, int x, int y, const uint8_t *remap); - static void FlipNonSquareBlock (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch); - static void FlipNonSquareBlockBgra (uint32_t *blockto, const uint32_t *blockfrom, int x, int y, int srcpitch); - static void FlipNonSquareBlockRemap (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch, const uint8_t *remap); -public: - - void GetGlowColor(float *data); - bool isGlowing() { return bGlowing; } - bool isFullbright() { return bFullbright; } - void CreateDefaultBrightmap(); - bool FindHoles(const unsigned char * buffer, int w, int h); - static bool SmoothEdges(unsigned char * buffer,int w, int h); void CheckTrans(unsigned char * buffer, int size, int trans); bool ProcessData(unsigned char * buffer, int w, int h, bool ispatch); int CheckRealHeight(); @@ -504,6 +567,100 @@ public: friend class FTextureManager; }; +// For now this is just a minimal wrapper around FTexture. Once the software renderer no longer accesses FTexture directly, it is time for cleaning up. +class FSoftwareTexture +{ + FTexture *mTexture; + + +public: + FSoftwareTexture(FTexture *tex) + { + mTexture = tex; + } + + FTexture *GetTexture() const + { + return mTexture; + } + + // The feature from hell... :( + bool useWorldPanning() const + { + return mTexture->bWorldPanning; + } + + bool UseBasePalette() const { return mTexture->UseBasePalette(); } + int GetSkyOffset() const { return mTexture->GetSkyOffset(); } + PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); } + + int GetWidth () { return mTexture->GetWidth(); } + int GetHeight () { return mTexture->GetHeight(); } + + int GetScaledWidth () { return mTexture->GetScaledWidth(); } + int GetScaledHeight () { return mTexture->GetScaledHeight(); } + double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); } + double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); } + double GetScaleY() const { return mTexture->GetScaleY(); } + + // Now with improved offset adjustment. + int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); } + int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted); } + int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted); } + int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted); } + double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted); } + double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted); } + + // Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets + // should use these, so that if changes are needed, this is the only place to edit. + + // For the original software renderer + int GetLeftOffsetSW() { return GetLeftOffset(r_spriteadjustSW); } + int GetTopOffsetSW() { return GetTopOffset(r_spriteadjustSW); } + int GetScaledLeftOffsetSW() { return GetScaledLeftOffset(r_spriteadjustSW); } + int GetScaledTopOffsetSW() { return GetScaledTopOffset(r_spriteadjustSW); } + + // For the softpoly renderer, in case it wants adjustment + int GetLeftOffsetPo() { return GetLeftOffset(r_spriteadjustSW); } + int GetTopOffsetPo() { return GetTopOffset(r_spriteadjustSW); } + int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); } + int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); } + + DVector2 GetScale() const { return mTexture->Scale; } + + // Returns a single column of the texture + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) + { + return mTexture->GetColumn(style, column, spans_out); + } + + // Returns a single column of the texture, in BGRA8 format + const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) + { + return mTexture->GetColumnBgra(column, spans_out); + } + + // Returns the whole texture, stored in column-major order + const uint8_t *GetPixels(FRenderStyle style) + { + return mTexture->GetPixels(style); + } + + // Returns the whole texture, stored in column-major order, in BGRA8 format + const uint32_t *GetPixelsBgra() + { + return mTexture->GetPixelsBgra(); + } + +}; + + +inline FSoftwareTexture *FTexture::GetSoftwareTexture() +{ + if (!SoftwareTexture) SoftwareTexture = new FSoftwareTexture(this); + return SoftwareTexture; +} + class FxAddSub; // Texture manager class FTextureManager @@ -703,13 +860,13 @@ class FWorldTexture : public FTexture { protected: uint8_t *Pixeldata[2] = { nullptr, nullptr }; - Span **Spandata[2] = { nullptr, nullptr }; + FSoftwareTextureSpan **Spandata[2] = { nullptr, nullptr }; uint8_t PixelsAreStatic = 0; // can be set by subclasses which provide static pixel buffers. FWorldTexture(const char *name = nullptr, int lumpnum = -1); ~FWorldTexture(); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out) override; + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) override; const uint8_t *GetPixels(FRenderStyle style) override; void Unload() override; virtual uint8_t *MakeTexture(FRenderStyle style) = 0; @@ -763,7 +920,7 @@ public: FCanvasTexture (const char *name, int width, int height); ~FCanvasTexture (); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); const uint8_t *GetPixels (FRenderStyle style); const uint32_t *GetPixelsBgra() override; void Unload (); @@ -782,7 +939,7 @@ protected: DCanvas *CanvasBgra = nullptr; uint8_t *Pixels = nullptr; uint32_t *PixelsBgra = nullptr; - Span DummySpans[2]; + FSoftwareTextureSpan DummySpans[2]; bool bNeedsUpdate = true; bool bDidUpdate = false; bool bPixelsAllocated = false; @@ -799,6 +956,10 @@ class FWrapperTexture : public FTexture { public: FWrapperTexture(int w, int h, int bits = 1); + IHardwareTexture *GetSystemTexture(int slot) + { + return SystemTexture[slot]; + } }; extern FTextureManager TexMan; diff --git a/src/v_2ddrawer.cpp b/src/v_2ddrawer.cpp index 6b4305de9..2a58f9f31 100644 --- a/src/v_2ddrawer.cpp +++ b/src/v_2ddrawer.cpp @@ -125,7 +125,6 @@ void F2DDrawer::AddIndices(int firstvert, int count, ...) bool F2DDrawer::SetStyle(FTexture *tex, DrawParms &parms, PalEntry &vertexcolor, RenderCommand &quad) { - auto fmt = tex->GetFormat(); FRenderStyle style = parms.style; float alpha; bool stencilling; @@ -298,12 +297,12 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms) dg.mType = DrawTypeTriangles; dg.mVertCount = 4; dg.mTexture = img; - if (img->bWarped) dg.mFlags |= DTF_Wrap; + if (img->isWarped()) dg.mFlags |= DTF_Wrap; dg.mTranslation = 0; SetStyle(img, parms, vertexcolor, dg); - if (!img->bHasCanvas && parms.remap != nullptr && !parms.remap->Inactive) + if (!img->isHardwareCanvas() && parms.remap != nullptr && !parms.remap->Inactive) { dg.mTranslation = parms.remap; } @@ -378,7 +377,7 @@ void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms ) dg.mTranslation = 0; SetStyle(img, parms, vertexcolor, dg); - if (!img->bHasCanvas && parms.remap != nullptr && !parms.remap->Inactive) + if (!img->isHardwareCanvas() && parms.remap != nullptr && !parms.remap->Inactive) dg.mTranslation = parms.remap; double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384; @@ -466,8 +465,8 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, float cosrot = (float)cos(rotation.Radians()); float sinrot = (float)sin(rotation.Radians()); - float uscale = float(1.f / (texture->GetScaledWidth() * scalex)); - float vscale = float(1.f / (texture->GetScaledHeight() * scaley)); + float uscale = float(1.f / (texture->GetDisplayWidth() * scalex)); + float vscale = float(1.f / (texture->GetDisplayHeight() * scaley)); float ox = float(originx); float oy = float(originy); @@ -529,17 +528,17 @@ void F2DDrawer::AddFlatFill(int left, int top, int right, int bottom, FTexture * // scaling is not used here. if (!local_origin) { - fU1 = float(left) / src->GetWidth(); - fV1 = float(top) / src->GetHeight(); - fU2 = float(right) / src->GetWidth(); - fV2 = float(bottom) / src->GetHeight(); + fU1 = float(left) / src->GetDisplayWidth(); + fV1 = float(top) / src->GetDisplayHeight(); + fU2 = float(right) / src->GetDisplayWidth(); + fV2 = float(bottom) / src->GetDisplayHeight(); } else { fU1 = 0; fV1 = 0; - fU2 = float(right - left) / src->GetWidth(); - fV2 = float(bottom - top) / src->GetHeight(); + fU2 = float(right - left) / src->GetDisplayWidth(); + fV2 = float(bottom - top) / src->GetDisplayHeight(); } dg.mVertIndex = (int)mVertices.Reserve(4); auto ptr = &mVertices[dg.mVertIndex]; diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 80f51f141..36c9c921e 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -312,23 +312,23 @@ bool DFrameBuffer::SetTextureParms(DrawParms *parms, FTexture *img, double xx, d { parms->x = xx; parms->y = yy; - parms->texwidth = img->GetScaledWidthDouble(); - parms->texheight = img->GetScaledHeightDouble(); + parms->texwidth = img->GetDisplayWidthDouble(); + parms->texheight = img->GetDisplayHeightDouble(); if (parms->top == INT_MAX || parms->fortext) { - parms->top = img->GetScaledTopOffset(0); + parms->top = img->GetDisplayTopOffset(); } if (parms->left == INT_MAX || parms->fortext) { - parms->left = img->GetScaledLeftOffset(0); + parms->left = img->GetDisplayLeftOffset(); } if (parms->destwidth == INT_MAX || parms->fortext) { - parms->destwidth = img->GetScaledWidthDouble(); + parms->destwidth = img->GetDisplayWidthDouble(); } if (parms->destheight == INT_MAX || parms->fortext) { - parms->destheight = img->GetScaledHeightDouble(); + parms->destheight = img->GetDisplayHeightDouble(); } switch (parms->cleanmode) @@ -470,7 +470,7 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3 if (!fortext) { - if (img == NULL || img->UseType == ETextureType::Null) + if (img == NULL || !img->isValid()) { ListEnd(tags); return false; @@ -650,8 +650,8 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3 assert(fortext == false); if (img == NULL) return false; parms->cleanmode = DTA_Fullscreen; - parms->virtWidth = img->GetScaledWidthDouble(); - parms->virtHeight = img->GetScaledHeightDouble(); + parms->virtWidth = img->GetDisplayWidthDouble(); + parms->virtHeight = img->GetDisplayHeightDouble(); } break; @@ -697,19 +697,19 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3 break; case DTA_SrcX: - parms->srcx = ListGetDouble(tags) / img->GetScaledWidthDouble(); + parms->srcx = ListGetDouble(tags) / img->GetDisplayWidthDouble(); break; case DTA_SrcY: - parms->srcy = ListGetDouble(tags) / img->GetScaledHeightDouble(); + parms->srcy = ListGetDouble(tags) / img->GetDisplayHeightDouble(); break; case DTA_SrcWidth: - parms->srcwidth = ListGetDouble(tags) / img->GetScaledWidthDouble(); + parms->srcwidth = ListGetDouble(tags) / img->GetDisplayWidthDouble(); break; case DTA_SrcHeight: - parms->srcheight = ListGetDouble(tags) / img->GetScaledHeightDouble(); + parms->srcheight = ListGetDouble(tags) / img->GetDisplayHeightDouble(); break; case DTA_TopOffset: @@ -741,8 +741,8 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3 if (fortext) return false; if (ListGetInt(tags)) { - parms->left = img->GetScaledWidthDouble() * 0.5; - parms->top = img->GetScaledHeightDouble() * 0.5; + parms->left = img->GetDisplayWidthDouble() * 0.5; + parms->top = img->GetDisplayHeightDouble() * 0.5; } break; @@ -751,8 +751,8 @@ bool DFrameBuffer::ParseDrawTextureTags(FTexture *img, double x, double y, uint3 if (fortext) return false; if (ListGetInt(tags)) { - parms->left = img->GetScaledWidthDouble() * 0.5; - parms->top = img->GetScaledHeightDouble(); + parms->left = img->GetDisplayWidthDouble() * 0.5; + parms->top = img->GetDisplayHeightDouble(); } break; @@ -1305,15 +1305,15 @@ void DFrameBuffer::DrawFrame (int left, int top, int width, int height) // Draw top and bottom sides. p = TexMan[border->t]; - FlatFill(left, top - p->GetHeight(), right, top, p, true); + FlatFill(left, top - p->GetDisplayHeight(), right, top, p, true); p = TexMan[border->b]; - FlatFill(left, bottom, right, bottom + p->GetHeight(), p, true); + FlatFill(left, bottom, right, bottom + p->GetDisplayHeight(), p, true); // Draw left and right sides. p = TexMan[border->l]; - FlatFill(left - p->GetWidth(), top, left, bottom, p, true); + FlatFill(left - p->GetDisplayWidth(), top, left, bottom, p, true); p = TexMan[border->r]; - FlatFill(right, top, right + p->GetWidth(), bottom, p, true); + FlatFill(right, top, right + p->GetDisplayWidth(), bottom, p, true); // Draw beveled corners. DrawTexture (TexMan[border->tl], left-offset, top-offset, TAG_DONE); diff --git a/src/v_font.cpp b/src/v_font.cpp index eed94341b..ea50ae4cc 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -171,7 +171,7 @@ class FFontChar1 : public FTexture { public: FFontChar1 (FTexture *sourcelump); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); const uint8_t *GetPixels (FRenderStyle style); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); @@ -192,7 +192,7 @@ public: FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); ~FFontChar2 (); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const Span **spans_out); + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); const uint8_t *GetPixels (FRenderStyle style); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); @@ -201,7 +201,7 @@ protected: int SourceLump; int SourcePos; uint8_t *Pixels; - Span **Spans; + FSoftwareTextureSpan **Spans; const uint8_t *SourceRemap; void MakeTexture (); @@ -532,25 +532,15 @@ FFont *FFont::FindFont (FName name) void RecordTextureColors (FTexture *pic, uint8_t *usedcolors) { int x; - - for (x = pic->GetWidth() - 1; x >= 0; x--) + + auto pixels = pic->GetPixels(DefaultRenderStyle()); + auto size = pic->GetWidth() * pic->GetHeight(); + + for(x = 0;x < size; x++) { - const FTexture::Span *spans; - const uint8_t *column = pic->GetColumn(DefaultRenderStyle(), x, &spans); // This shouldn't use the spans... - - while (spans->Length != 0) - { - const uint8_t *source = column + spans->TopOffset; - int count = spans->Length; - - do - { - usedcolors[*source++] = 1; - } while (--count); - - spans++; - } + usedcolors[pixels[x]]++; } + pic->Unload(); } //========================================================================== @@ -1623,7 +1613,7 @@ void FFontChar1::MakeTexture () // //========================================================================== -const uint8_t *FFontChar1::GetColumn(FRenderStyle, unsigned int column, const Span **spans_out) +const uint8_t *FFontChar1::GetColumn(FRenderStyle, unsigned int column, const FSoftwareTextureSpan **spans_out) { if (Pixels == NULL) { @@ -1747,7 +1737,7 @@ const uint8_t *FFontChar2::GetPixels (FRenderStyle) // //========================================================================== -const uint8_t *FFontChar2::GetColumn(FRenderStyle, unsigned int column, const Span **spans_out) +const uint8_t *FFontChar2::GetColumn(FRenderStyle, unsigned int column, const FSoftwareTextureSpan **spans_out) { if (Pixels == NULL) { From a4d61e6fb13cfe89327222d6fcfbace35f6f0dd0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 6 Dec 2018 20:12:15 +0100 Subject: [PATCH 02/66] - everything compiles again. As a bonus this already fixes several bugs caused by the botched texture scaling implementation the original texture manager came with. System cursors are currently disabled because they rely on functionality that needs to be moved to different classes. --- src/gl/renderer/gl_renderstate.cpp | 4 +- src/gl/textures/gl_hwtexture.cpp | 2 - src/swrenderer/line/r_line.cpp | 73 ++++++++++--------- src/swrenderer/line/r_line.h | 2 +- src/swrenderer/line/r_renderdrawsegment.cpp | 79 ++++++++++++--------- src/swrenderer/line/r_renderdrawsegment.h | 2 +- src/swrenderer/line/r_walldraw.cpp | 16 ++--- src/swrenderer/line/r_walldraw.h | 6 +- src/swrenderer/plane/r_flatplane.cpp | 2 +- src/swrenderer/plane/r_flatplane.h | 2 +- src/swrenderer/plane/r_skyplane.cpp | 30 +++++--- src/swrenderer/plane/r_skyplane.h | 4 +- src/swrenderer/plane/r_slopeplane.cpp | 2 +- src/swrenderer/plane/r_slopeplane.h | 2 +- src/swrenderer/plane/r_visibleplane.cpp | 11 +-- src/swrenderer/r_renderthread.cpp | 2 +- src/swrenderer/r_renderthread.h | 2 +- src/swrenderer/r_swrenderer.cpp | 7 +- src/swrenderer/r_swscene.cpp | 14 ++-- src/swrenderer/scene/r_opaque_pass.cpp | 8 +-- src/swrenderer/things/r_decal.cpp | 7 +- src/swrenderer/things/r_decal.h | 2 +- src/swrenderer/things/r_model.cpp | 6 +- src/swrenderer/things/r_playersprite.cpp | 23 +++--- src/swrenderer/things/r_playersprite.h | 2 +- src/swrenderer/things/r_sprite.cpp | 11 +-- src/swrenderer/things/r_visiblesprite.h | 2 +- src/swrenderer/things/r_wallsprite.cpp | 7 +- src/swrenderer/things/r_wallsprite.h | 2 +- src/swrenderer/viewport/r_skydrawer.cpp | 4 +- src/swrenderer/viewport/r_skydrawer.h | 4 +- src/swrenderer/viewport/r_spandrawer.cpp | 6 +- src/swrenderer/viewport/r_spandrawer.h | 2 +- src/swrenderer/viewport/r_spritedrawer.cpp | 4 +- src/swrenderer/viewport/r_spritedrawer.h | 4 +- src/textures/formats/brightmaptexture.cpp | 6 +- src/textures/texturemanager.cpp | 14 ++-- src/textures/textures.h | 38 ++++++++-- src/v_font.cpp | 26 +++---- src/wi_stuff.cpp | 14 ++-- src/win32/i_system.cpp | 11 +++ 41 files changed, 268 insertions(+), 197 deletions(-) diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 4a683a090..30a291899 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -303,7 +303,6 @@ void FGLRenderState::Apply() void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader) { -#if 0 if (mat->tex->isHardwareCanvas()) { mTempTM = TM_OPAQUE; @@ -318,7 +317,7 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio auto tex = mat->tex; if (tex->UseType == ETextureType::SWCanvas) clampmode = CLAMP_NOFILTER; - if (tex->sHardwareCanvas()) clampmode = CLAMP_CAMTEX; + if (tex->isHardwareCanvas()) clampmode = CLAMP_CAMTEX; else if ((tex->isWarped() || tex->shaderindex >= FIRST_USER_SHADER) && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE; // avoid rebinding the same texture multiple times. @@ -351,7 +350,6 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio FHardwareTexture::Unbind(i); maxBoundMaterial = maxbound; } -#endif } //========================================================================== diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 75d940d3b..f6cdc8415 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -422,7 +422,6 @@ void FHardwareTexture::BindToFrameBuffer(int width, int height) bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags) { -#if 0 int usebright = false; if (translation <= 0) @@ -465,7 +464,6 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i } if (tex->isHardwareCanvas()) static_cast(tex)->NeedUpdate(); GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255); -#endif return true; } diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 77ac90f5b..ddb291c36 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -425,7 +425,7 @@ namespace swrenderer if (!onlyUpdatePlaneClip) // allocate space for masked texture tables, if needed // [RH] Don't just allocate the space; fill it in too. - if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != ETextureType::Null || draw_segment->Has3DFloorWalls() || IsFogBoundary(mFrontSector, mBackSector)) && + if ((sidedef->GetTexture(side_t::mid).isValid() || draw_segment->Has3DFloorWalls() || IsFogBoundary(mFrontSector, mBackSector)) && (mCeilingClipped != ProjectedWallCull::OutsideBelow || !sidedef->GetTexture(side_t::top).isValid()) && (mFloorClipped != ProjectedWallCull::OutsideAbove || !sidedef->GetTexture(side_t::bottom).isValid()) && (WallC.sz1 >= TOO_CLOSE_Z && WallC.sz2 >= TOO_CLOSE_Z)) @@ -451,11 +451,12 @@ namespace swrenderer lwal = draw_segment->maskedtexturecol; swal = draw_segment->swall; - FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid), true); - double yscale = pic->Scale.Y * sidedef->GetTextureYScale(side_t::mid); + FTexture *tex = TexMan(sidedef->GetTexture(side_t::mid), true); + FSoftwareTexture *pic = tex && tex->isValid()? tex->GetSoftwareTexture() : nullptr; + double yscale = pic->GetScale().Y * sidedef->GetTextureYScale(side_t::mid); fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); - if (pic->bWorldPanning) + if (pic->useWorldPanning()) { xoffset = xs_RoundToInt(xoffset * lwallscale); } @@ -769,7 +770,8 @@ namespace swrenderer } } - FTexture *midtex = TexMan(sidedef->GetTexture(side_t::mid), true); + FTexture *ftex = TexMan(sidedef->GetTexture(side_t::mid), true); + FSoftwareTexture *midtex = ftex && ftex->isValid() ? ftex->GetSoftwareTexture() : nullptr; bool segtextured = midtex != NULL || mTopPart.Texture != NULL || mBottomPart.Texture != NULL; @@ -777,9 +779,9 @@ namespace swrenderer if (needlights && (segtextured || (mBackSector && IsFogBoundary(mFrontSector, mBackSector)))) { lwallscale = - midtex ? (midtex->Scale.X * sidedef->GetTextureXScale(side_t::mid)) : - mTopPart.Texture ? (mTopPart.Texture->Scale.X * sidedef->GetTextureXScale(side_t::top)) : - mBottomPart.Texture ? (mBottomPart.Texture->Scale.X * sidedef->GetTextureXScale(side_t::bottom)) : + midtex ? (midtex->GetScale().X * sidedef->GetTextureXScale(side_t::mid)) : + mTopPart.Texture ? (mTopPart.Texture->GetScale().X * sidedef->GetTextureXScale(side_t::top)) : + mBottomPart.Texture ? (mBottomPart.Texture->GetScale().X * sidedef->GetTextureXScale(side_t::bottom)) : 1.; walltexcoords.Project(Thread->Viewport.get(), sidedef->TexelLength * lwallscale, WallC.sx1, WallC.sx2, WallT); @@ -814,13 +816,14 @@ namespace swrenderer // No top texture for skyhack lines if (mFrontSector->GetTexture(sector_t::ceiling) == skyflatnum && mBackSector->GetTexture(sector_t::ceiling) == skyflatnum) return; - mTopPart.Texture = TexMan(sidedef->GetTexture(side_t::top), true); + FTexture *tex = TexMan(sidedef->GetTexture(side_t::top), true); + mTopPart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; mTopPart.TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::top)); double rowoffset = sidedef->GetTextureYOffset(side_t::top); mTopPart.TextureScaleU = sidedef->GetTextureXScale(side_t::top); mTopPart.TextureScaleV = sidedef->GetTextureYScale(side_t::top); - double yrepeat = mTopPart.Texture->Scale.Y * mTopPart.TextureScaleV; + double yrepeat = mTopPart.Texture->GetScale().Y * mTopPart.TextureScaleV; if (yrepeat >= 0) { // normal orientation if (linedef->flags & ML_DONTPEGTOP) @@ -848,7 +851,7 @@ namespace swrenderer mTopPart.TextureMid = (mBackSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat; } } - if (mTopPart.Texture->bWorldPanning) + if (mTopPart.Texture->useWorldPanning()) { mTopPart.TextureMid += rowoffset * yrepeat; } @@ -871,12 +874,13 @@ namespace swrenderer if (linedef->isVisualPortal()) return; if (linedef->special == Line_Horizon) return; - mMiddlePart.Texture = TexMan(sidedef->GetTexture(side_t::mid), true); + auto tex = TexMan(sidedef->GetTexture(side_t::mid), true); + mMiddlePart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; mMiddlePart.TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); double rowoffset = sidedef->GetTextureYOffset(side_t::mid); mMiddlePart.TextureScaleU = sidedef->GetTextureXScale(side_t::mid); mMiddlePart.TextureScaleV = sidedef->GetTextureYScale(side_t::mid); - double yrepeat = mMiddlePart.Texture->Scale.Y * mMiddlePart.TextureScaleV; + double yrepeat = mMiddlePart.Texture->GetScale().Y * mMiddlePart.TextureScaleV; if (yrepeat >= 0) { // normal orientation if (linedef->flags & ML_DONTPEGBOTTOM) @@ -904,7 +908,7 @@ namespace swrenderer mMiddlePart.TextureMid = (mFrontSector->GetPlaneTexZ(sector_t::ceiling) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + mMiddlePart.Texture->GetHeight(); } } - if (mMiddlePart.Texture->bWorldPanning) + if (mMiddlePart.Texture->useWorldPanning()) { mMiddlePart.TextureMid += rowoffset * yrepeat; } @@ -935,13 +939,14 @@ namespace swrenderer frontlowertop = mBackSector->GetPlaneTexZ(sector_t::ceiling); } - mBottomPart.Texture = TexMan(sidedef->GetTexture(side_t::bottom), true); + FTexture *tex = TexMan(sidedef->GetTexture(side_t::bottom), true);; + mBottomPart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; mBottomPart.TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::bottom)); double rowoffset = sidedef->GetTextureYOffset(side_t::bottom); mBottomPart.TextureScaleU = sidedef->GetTextureXScale(side_t::bottom); mBottomPart.TextureScaleV = sidedef->GetTextureYScale(side_t::bottom); - double yrepeat = mBottomPart.Texture->Scale.Y * mBottomPart.TextureScaleV; + double yrepeat = mBottomPart.Texture->GetScale().Y * mBottomPart.TextureScaleV; if (yrepeat >= 0) { // normal orientation if (linedef->flags & ML_DONTPEGBOTTOM) @@ -969,7 +974,7 @@ namespace swrenderer mBottomPart.TextureMid = (mBackSector->GetPlaneTexZ(sector_t::floor) - Thread->Viewport->viewpoint.Pos.Z) * yrepeat + mBottomPart.Texture->GetHeight(); } } - if (mBottomPart.Texture->bWorldPanning) + if (mBottomPart.Texture->useWorldPanning()) { mBottomPart.TextureMid += rowoffset * yrepeat; } @@ -1101,7 +1106,7 @@ namespace swrenderer } else { // two sided line - if (mTopPart.Texture != NULL && mTopPart.Texture->UseType != ETextureType::Null) + if (mTopPart.Texture != nullptr) { // top wall for (int x = x1; x < x2; ++x) { @@ -1114,7 +1119,7 @@ namespace swrenderer memcpy(ceilingclip + x1, walltop.ScreenY + x1, (x2 - x1) * sizeof(short)); } - if (mBottomPart.Texture != NULL && mBottomPart.Texture->UseType != ETextureType::Null) + if (mBottomPart.Texture != nullptr) { // bottom wall for (int x = x1; x < x2; ++x) { @@ -1132,19 +1137,19 @@ namespace swrenderer void SWRenderLine::RenderTopTexture(int x1, int x2) { if (mMiddlePart.Texture) return; - if (!mTopPart.Texture || mTopPart.Texture->UseType == ETextureType::Null) return; + if (!mTopPart.Texture) return; if (!viewactive) return; - FTexture *rw_pic = mTopPart.Texture; - double xscale = rw_pic->Scale.X * mTopPart.TextureScaleU; - double yscale = rw_pic->Scale.Y * mTopPart.TextureScaleV; + auto rw_pic = mTopPart.Texture; + double xscale = rw_pic->GetScale().X * mTopPart.TextureScaleU; + double yscale = rw_pic->GetScale().Y * mTopPart.TextureScaleV; if (xscale != lwallscale) { walltexcoords.ProjectPos(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT); lwallscale = xscale; } fixed_t offset; - if (mTopPart.Texture->bWorldPanning) + if (mTopPart.Texture->useWorldPanning()) { offset = xs_RoundToInt(mTopPart.TextureOffsetU * xscale); } @@ -1179,19 +1184,19 @@ namespace swrenderer void SWRenderLine::RenderMiddleTexture(int x1, int x2) { - if (!mMiddlePart.Texture || mMiddlePart.Texture->UseType == ETextureType::Null) return; + if (!mMiddlePart.Texture) return; if (!viewactive) return; - FTexture *rw_pic = mMiddlePart.Texture; - double xscale = rw_pic->Scale.X * mMiddlePart.TextureScaleU; - double yscale = rw_pic->Scale.Y * mMiddlePart.TextureScaleV; + auto rw_pic = mMiddlePart.Texture; + double xscale = rw_pic->GetScale().X * mMiddlePart.TextureScaleU; + double yscale = rw_pic->GetScale().Y * mMiddlePart.TextureScaleV; if (xscale != lwallscale) { walltexcoords.ProjectPos(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT); lwallscale = xscale; } fixed_t offset; - if (mMiddlePart.Texture->bWorldPanning) + if (mMiddlePart.Texture->useWorldPanning()) { offset = xs_RoundToInt(mMiddlePart.TextureOffsetU * xscale); } @@ -1227,19 +1232,19 @@ namespace swrenderer void SWRenderLine::RenderBottomTexture(int x1, int x2) { if (mMiddlePart.Texture) return; - if (!mBottomPart.Texture || mBottomPart.Texture->UseType == ETextureType::Null) return; + if (!mBottomPart.Texture) return; if (!viewactive) return; - FTexture *rw_pic = mBottomPart.Texture; - double xscale = rw_pic->Scale.X * mBottomPart.TextureScaleU; - double yscale = rw_pic->Scale.Y * mBottomPart.TextureScaleV; + auto rw_pic = mBottomPart.Texture; + double xscale = rw_pic->GetScale().X * mBottomPart.TextureScaleU; + double yscale = rw_pic->GetScale().Y * mBottomPart.TextureScaleV; if (xscale != lwallscale) { walltexcoords.ProjectPos(Thread->Viewport.get(), mLineSegment->sidedef->TexelLength*xscale, WallC.sx1, WallC.sx2, WallT); lwallscale = xscale; } fixed_t offset; - if (mBottomPart.Texture->bWorldPanning) + if (mBottomPart.Texture->useWorldPanning()) { offset = xs_RoundToInt(mBottomPart.TextureOffsetU * xscale); } diff --git a/src/swrenderer/line/r_line.h b/src/swrenderer/line/r_line.h index a76f4dc7c..dbe2cbb60 100644 --- a/src/swrenderer/line/r_line.h +++ b/src/swrenderer/line/r_line.h @@ -65,7 +65,7 @@ namespace swrenderer double TextureMid; double TextureScaleU; double TextureScaleV; - FTexture *Texture; + FSoftwareTexture *Texture; }; class SWRenderLine : VisibleSegmentRenderer diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index fbc18b0c6..060f40fa1 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -162,11 +162,12 @@ namespace swrenderer if (curline->sidedef->GetTexture(side_t::mid).isNull()) return false; - FTexture *tex = TexMan(curline->sidedef->GetTexture(side_t::mid), true); + FTexture *ttex = TexMan(curline->sidedef->GetTexture(side_t::mid), true); if (i_compatflags & COMPATF_MASKEDMIDTEX) { - tex = tex->GetRawTexture(); + ttex = ttex->GetRawTexture(); } + FSoftwareTexture *tex = ttex->GetSoftwareTexture(); const short *mfloorclip = ds->sprbottomclip - ds->x1; const short *mceilingclip = ds->sprtopclip - ds->x1; @@ -221,7 +222,7 @@ namespace swrenderer MaskedScaleY = -MaskedScaleY; sprflipvert = true; } - if (tex->bWorldPanning) + if (tex->useWorldPanning()) { // rowoffset is added before the multiply so that the masked texture will // still be positioned in world units rather than texels. @@ -354,7 +355,7 @@ namespace swrenderer } else { // Texture does wrap vertically. - if (tex->bWorldPanning) + if (tex->useWorldPanning()) { // rowoffset is added before the multiply so that the masked texture will // still be positioned in world units rather than texels. @@ -459,8 +460,8 @@ namespace swrenderer scaledside = rover->master->sidedef[0]; scaledpart = side_t::mid; } - xscale = rw_pic->Scale.X * scaledside->GetTextureXScale(scaledpart); - yscale = rw_pic->Scale.Y * scaledside->GetTextureYScale(scaledpart); + xscale = rw_pic->GetScale().X * scaledside->GetTextureXScale(scaledpart); + yscale = rw_pic->GetScale().Y * scaledside->GetTextureYScale(scaledpart); double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid) + rover->master->sidedef[0]->GetTextureYOffset(side_t::mid); double planez = rover->model->GetPlaneTexZ(sector_t::ceiling); @@ -470,7 +471,7 @@ namespace swrenderer rowoffset += rw_pic->GetHeight(); } double texturemid = (planez - Thread->Viewport->viewpoint.Pos.Z) * yscale; - if (rw_pic->bWorldPanning) + if (rw_pic->useWorldPanning()) { // rowoffset is added before the multiply so that the masked texture will // still be positioned in world units rather than texels. @@ -531,7 +532,7 @@ namespace swrenderer // kg3D - walls of fake floors void RenderDrawSegment::RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade) { - FTexture *const DONT_DRAW = ((FTexture*)(intptr_t)-1); + FSoftwareTexture *const DONT_DRAW = ((FSoftwareTexture*)(intptr_t)-1); int i, j; F3DFloor *rover, *fover = nullptr; int passed, last; @@ -637,17 +638,22 @@ namespace swrenderer { // don't ever draw (but treat as something has been found) rw_pic = DONT_DRAW; } - else if (fover->flags & FF_UPPERTEXTURE) - { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); - } - else if (fover->flags & FF_LOWERTEXTURE) - { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); - } else { - rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); + FTexture *rw_tex = nullptr; + if (fover->flags & FF_UPPERTEXTURE) + { + rw_tex = TexMan(curline->sidedef->GetTexture(side_t::top), true); + } + else if (fover->flags & FF_LOWERTEXTURE) + { + rw_tex = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); + } + else + { + rw_tex = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); + } + rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } } else if (frontsector->e->XFloor.ffloors.Size()) @@ -696,18 +702,20 @@ namespace swrenderer if (!rw_pic) { fover = nullptr; + FTexture *rw_tex; if (rover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); + rw_tex = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if (rover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); + rw_tex = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); + rw_tex = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); } + rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } // correct colors now FDynamicColormap *basecolormap = nullptr; @@ -819,17 +827,22 @@ namespace swrenderer { rw_pic = DONT_DRAW; // don't ever draw (but treat as something has been found) } - else if (fover->flags & FF_UPPERTEXTURE) - { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); - } - else if (fover->flags & FF_LOWERTEXTURE) - { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); - } else { - rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); + FTexture *rw_tex; + if (fover->flags & FF_UPPERTEXTURE) + { + rw_tex = TexMan(curline->sidedef->GetTexture(side_t::top), true); + } + else if (fover->flags & FF_LOWERTEXTURE) + { + rw_tex = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); + } + else + { + rw_tex = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); + } + rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } } else if (frontsector->e->XFloor.ffloors.Size()) @@ -875,18 +888,20 @@ namespace swrenderer if (rw_pic == nullptr) { fover = nullptr; + FTexture *rw_tex; if (rover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); + rw_tex = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if (rover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); + rw_tex = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); + rw_tex = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); } + rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } // correct colors now FDynamicColormap *basecolormap = nullptr; diff --git a/src/swrenderer/line/r_renderdrawsegment.h b/src/swrenderer/line/r_renderdrawsegment.h index 82186f317..3c45c9ab5 100644 --- a/src/swrenderer/line/r_renderdrawsegment.h +++ b/src/swrenderer/line/r_renderdrawsegment.h @@ -55,7 +55,7 @@ namespace swrenderer float rw_light = 0.0f; float rw_lightstep = 0.0f; fixed_t rw_offset = 0; - FTexture *rw_pic = nullptr; + FSoftwareTexture *rw_pic = nullptr; ProjectedWallLine wallupper; ProjectedWallLine walllower; diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 138efab84..0dce2236e 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -54,7 +54,7 @@ namespace swrenderer { - WallSampler::WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FTexture *texture) + WallSampler::WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FSoftwareTexture *texture) { xoffset += FLOAT2FIXED(xmagnitude * 0.5); @@ -62,7 +62,7 @@ namespace swrenderer { height = texture->GetHeight(); - int uv_fracbits = 32 - texture->HeightBits; + int uv_fracbits = 32 - texture->GetHeightBits(); if (uv_fracbits != 32) { uv_max = height << uv_fracbits; @@ -92,7 +92,7 @@ namespace swrenderer // If the texture's width isn't a power of 2, then we need to make it a // positive offset for proper clamping. int width; - if (col < 0 && (width = texture->GetWidth()) != (1 << texture->WidthBits)) + if (col < 0 && (width = texture->GetWidth()) != (1 << texture->GetWidthBits())) { col = width + (col % width); } @@ -332,10 +332,10 @@ namespace swrenderer void RenderWallPart::ProcessWallWorker(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal) { - if (rw_pic->UseType == ETextureType::Null) + if (rw_pic == nullptr) return; - int fracbits = 32 - rw_pic->HeightBits; + int fracbits = 32 - rw_pic->GetHeightBits(); if (fracbits == 32) { // Hack for one pixel tall textures fracbits = 0; @@ -428,7 +428,7 @@ namespace swrenderer void RenderWallPart::ProcessWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal) { // Textures that aren't masked can use the faster ProcessNormalWall. - if (!rw_pic->bMasked && drawerargs.IsMaskedDrawer()) + if (!rw_pic->GetTexture()->isMasked() && drawerargs.IsMaskedDrawer()) { drawerargs.SetStyle(true, false, OPAQUE); } @@ -516,7 +516,7 @@ namespace swrenderer } } - void RenderWallPart::Render(const WallDrawerArgs &drawerargs, sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap) + void RenderWallPart::Render(const WallDrawerArgs &drawerargs, sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FSoftwareTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap) { this->drawerargs = drawerargs; this->x1 = x1; @@ -537,7 +537,7 @@ namespace swrenderer Thread->PrepareTexture(pic, DefaultRenderStyle()); // Get correct render style? Shaded won't get here. - if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits) + if (rw_pic->GetHeight() != 1 << rw_pic->GetHeightBits()) { ProcessWallNP2(walltop, wallbottom, texturemid, swall, lwall, top, bottom); } diff --git a/src/swrenderer/line/r_walldraw.h b/src/swrenderer/line/r_walldraw.h index d3cd026a2..b3a47a7d3 100644 --- a/src/swrenderer/line/r_walldraw.h +++ b/src/swrenderer/line/r_walldraw.h @@ -50,7 +50,7 @@ namespace swrenderer sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, - FTexture *rw_pic, + FSoftwareTexture *rw_pic, int x1, int x2, const short *walltop, @@ -82,7 +82,7 @@ namespace swrenderer int x1 = 0; int x2 = 0; - FTexture *rw_pic = nullptr; + FSoftwareTexture *rw_pic = nullptr; sector_t *frontsector = nullptr; seg_t *curline = nullptr; FWallCoords WallC; @@ -103,7 +103,7 @@ namespace swrenderer struct WallSampler { WallSampler() { } - WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FTexture *texture); + WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FSoftwareTexture *texture); uint32_t uv_pos; uint32_t uv_step; diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index 51d376bd4..d826dbc56 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -60,7 +60,7 @@ namespace swrenderer Thread = thread; } - void RenderFlatPlane::Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *colormap, FTexture *texture) + void RenderFlatPlane::Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *colormap, FSoftwareTexture *texture) { if (alpha <= 0) { diff --git a/src/swrenderer/plane/r_flatplane.h b/src/swrenderer/plane/r_flatplane.h index 56b70a40c..9e01afb94 100644 --- a/src/swrenderer/plane/r_flatplane.h +++ b/src/swrenderer/plane/r_flatplane.h @@ -34,7 +34,7 @@ namespace swrenderer { public: RenderFlatPlane(RenderThread *thread); - void Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *basecolormap, FTexture *texture); + void Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *basecolormap, FSoftwareTexture *texture); RenderThread *Thread = nullptr; diff --git a/src/swrenderer/plane/r_skyplane.cpp b/src/swrenderer/plane/r_skyplane.cpp index afa9496c0..de30a0a89 100644 --- a/src/swrenderer/plane/r_skyplane.cpp +++ b/src/swrenderer/plane/r_skyplane.cpp @@ -59,6 +59,14 @@ EXTERN_CVAR(Int, r_skymode) namespace swrenderer { + static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true) + { + auto tex = TexMan(texid, true); + if (tex == nullptr) return nullptr; + if (!allownull && !tex->isValid()) return nullptr; + return tex->GetSoftwareTexture(); + } + RenderSkyPlane::RenderSkyPlane(RenderThread *thread) { Thread = thread; @@ -86,9 +94,9 @@ namespace swrenderer if (!(pl->sky & PL_SKYFLAT)) { // use sky1 sky1: - frontskytex = TexMan(sky1tex, true); + frontskytex = GetSWTex(sky1tex); if (level.flags & LEVEL_DOUBLESKY) - backskytex = TexMan(sky2tex, true); + backskytex = GetSWTex(sky2tex); else backskytex = NULL; skyflip = 0; @@ -99,7 +107,7 @@ namespace swrenderer } else if (pl->sky == PL_SKYFLAT) { // use sky2 - frontskytex = TexMan(sky2tex, true); + frontskytex = GetSWTex(sky2tex); backskytex = NULL; frontcyl = sky2cyl; skyflip = 0; @@ -125,8 +133,8 @@ namespace swrenderer pos = side_t::top; } - frontskytex = TexMan(s->GetTexture(pos), true); - if (frontskytex == NULL || frontskytex->UseType == ETextureType::Null) + frontskytex = GetSWTex(s->GetTexture(pos)); + if (frontskytex == nullptr) { // [RH] The blank texture: Use normal sky instead. goto sky1; } @@ -148,7 +156,7 @@ namespace swrenderer // allow old sky textures to be used. skyflip = l->args[2] ? 0u : ~0u; - int frontxscale = int(frontskytex->Scale.X * 1024); + int frontxscale = int(frontskytex->GetScale().X * 1024); frontcyl = MAX(frontskytex->GetWidth(), frontxscale); if (skystretch) { @@ -231,16 +239,16 @@ namespace swrenderer void RenderSkyPlane::DrawSkyColumn(int start_x, int y1, int y2) { - if (1 << frontskytex->HeightBits == frontskytex->GetHeight()) + if (1 << frontskytex->GetHeightBits() == frontskytex->GetHeight()) { - double texturemid = skymid * frontskytex->Scale.Y + frontskytex->GetHeight(); - DrawSkyColumnStripe(start_x, y1, y2, frontskytex->Scale.Y, texturemid, frontskytex->Scale.Y); + double texturemid = skymid * frontskytex->GetScale().Y + frontskytex->GetHeight(); + DrawSkyColumnStripe(start_x, y1, y2, frontskytex->GetScale().Y, texturemid, frontskytex->GetScale().Y); } else { auto viewport = Thread->Viewport.get(); - double yrepeat = frontskytex->Scale.Y; - double scale = frontskytex->Scale.Y * skyscale; + double yrepeat = frontskytex->GetScale().Y; + double scale = frontskytex->GetScale().Y * skyscale; double iscale = 1 / scale; short drawheight = short(frontskytex->GetHeight() * scale); double topfrac = fmod(skymid + iscale * (1 - viewport->CenterY), frontskytex->GetHeight()); diff --git a/src/swrenderer/plane/r_skyplane.h b/src/swrenderer/plane/r_skyplane.h index 79a27c987..ac5e07d25 100644 --- a/src/swrenderer/plane/r_skyplane.h +++ b/src/swrenderer/plane/r_skyplane.h @@ -41,8 +41,8 @@ namespace swrenderer void DrawSkyColumnStripe(int start_x, int y1, int y2, double scale, double texturemid, double yrepeat); void DrawSkyColumn(int start_x, int y1, int y2); - FTexture *frontskytex = nullptr; - FTexture *backskytex = nullptr; + FSoftwareTexture *frontskytex = nullptr; + FSoftwareTexture *backskytex = nullptr; angle_t skyflip = 0; int frontpos = 0; int backpos = 0; diff --git a/src/swrenderer/plane/r_slopeplane.cpp b/src/swrenderer/plane/r_slopeplane.cpp index 20eb3dbf4..fb20f107e 100644 --- a/src/swrenderer/plane/r_slopeplane.cpp +++ b/src/swrenderer/plane/r_slopeplane.cpp @@ -64,7 +64,7 @@ namespace swrenderer Thread = thread; } - void RenderSlopePlane::Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *colormap, FTexture *texture) + void RenderSlopePlane::Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *colormap, FSoftwareTexture *texture) { static const float ifloatpow2[16] = { diff --git a/src/swrenderer/plane/r_slopeplane.h b/src/swrenderer/plane/r_slopeplane.h index c59fa3f58..88ef199cb 100644 --- a/src/swrenderer/plane/r_slopeplane.h +++ b/src/swrenderer/plane/r_slopeplane.h @@ -33,7 +33,7 @@ namespace swrenderer { public: RenderSlopePlane(RenderThread *thread); - void Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *basecolormap, FTexture *texture); + void Render(VisiblePlane *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked, FDynamicColormap *basecolormap, FSoftwareTexture *texture); RenderThread *Thread = nullptr; diff --git a/src/swrenderer/plane/r_visibleplane.cpp b/src/swrenderer/plane/r_visibleplane.cpp index ac4e07079..6ba69d90c 100644 --- a/src/swrenderer/plane/r_visibleplane.cpp +++ b/src/swrenderer/plane/r_visibleplane.cpp @@ -113,23 +113,24 @@ namespace swrenderer } else // regular flat { - FTexture *tex = TexMan(picnum, true); + FTexture *ttex = TexMan(picnum, true); - if (tex->UseType == ETextureType::Null) + if (!ttex->isValid()) { return; } + FSoftwareTexture *tex = ttex->GetSoftwareTexture(); if (!masked && !additive) { // If we're not supposed to see through this plane, draw it opaque. alpha = OPAQUE; } - else if (!tex->bMasked) + else if (!tex->isMasked()) { // Don't waste time on a masked texture if it isn't really masked. masked = false; } - double xscale = xform.xScale * tex->Scale.X; - double yscale = xform.yScale * tex->Scale.Y; + double xscale = xform.xScale * tex->GetScale().X; + double yscale = xform.yScale * tex->GetScale().Y; if (!height.isSlope() && !tilt) { diff --git a/src/swrenderer/r_renderthread.cpp b/src/swrenderer/r_renderthread.cpp index 775528d71..ae0837e6a 100644 --- a/src/swrenderer/r_renderthread.cpp +++ b/src/swrenderer/r_renderthread.cpp @@ -89,7 +89,7 @@ namespace swrenderer return pal_drawers.get(); } - void RenderThread::PrepareTexture(FTexture *texture, FRenderStyle style) + void RenderThread::PrepareTexture(FSoftwareTexture *texture, FRenderStyle style) { if (texture == nullptr) return; diff --git a/src/swrenderer/r_renderthread.h b/src/swrenderer/r_renderthread.h index b65713e07..8823b59cf 100644 --- a/src/swrenderer/r_renderthread.h +++ b/src/swrenderer/r_renderthread.h @@ -88,7 +88,7 @@ namespace swrenderer SWPixelFormatDrawers *Drawers(RenderViewport *viewport); // Make sure texture can accessed safely - void PrepareTexture(FTexture *texture, FRenderStyle style); + void PrepareTexture(FSoftwareTexture *texture, FRenderStyle style); // Setup poly object in a threadsafe manner void PreparePolyObject(subsector_t *sub); diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index f8bb68ad7..66e4b7956 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -80,12 +80,13 @@ FRenderer *CreateSWRenderer() return new FSoftwareRenderer; } -void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache) +void FSoftwareRenderer::PrecacheTexture(FTexture *ttex, int cache) { bool isbgra = V_IsTrueColor(); - if (tex != NULL) + if (ttex != NULL) { + FSoftwareTexture *tex = ttex->GetSoftwareTexture(); if (cache & FTextureManager::HIT_Columnmode) { const FSoftwareTextureSpan *spanp; @@ -232,6 +233,7 @@ void FSoftwareRenderer::SetClearColor(int color) void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, double fov) { +#if 0 // This will require a complete redesign. auto renderTarget = V_IsPolyRenderer() ? PolyRenderer::Instance()->RenderTarget : mScene.MainThread()->Viewport->RenderTarget; auto &cameraViewpoint = V_IsPolyRenderer() ? PolyRenderer::Instance()->Viewpoint : mScene.MainThread()->Viewport->viewpoint; auto &cameraViewwindow = V_IsPolyRenderer() ? PolyRenderer::Instance()->Viewwindow : mScene.MainThread()->Viewport->viewwindow; @@ -310,6 +312,7 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin // Sync state back to zdoom r_viewpoint = cameraViewpoint; r_viewwindow = cameraViewwindow; +#endif } void FSoftwareRenderer::SetColormap() diff --git a/src/swrenderer/r_swscene.cpp b/src/swrenderer/r_swscene.cpp index c29e4fb67..7a3cfe2d7 100644 --- a/src/swrenderer/r_swscene.cpp +++ b/src/swrenderer/r_swscene.cpp @@ -83,15 +83,15 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) FBTextureIndex = (FBTextureIndex + 1) % 2; auto &fbtex = FBTexture[FBTextureIndex]; - if (fbtex == nullptr || fbtex->SystemTexture[0] == nullptr || - fbtex->GetWidth() != screen->GetWidth() || - fbtex->GetHeight() != screen->GetHeight() || - (V_IsTrueColor() ? 1:0) != fbtex->WidthBits) + if (fbtex == nullptr || fbtex->GetSystemTexture(0) == nullptr || + fbtex->GetDisplayWidth() != screen->GetWidth() || + fbtex->GetDisplayHeight() != screen->GetHeight() || + (V_IsTrueColor() ? 1:0) != fbtex->GetColorFormat()) { // This manually constructs its own material here. fbtex.reset(); fbtex.reset(new FWrapperTexture(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor())); - fbtex->SystemTexture[0]->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor() ? 4 : 1); + fbtex->GetSystemTexture(0)->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor() ? 4 : 1); auto mat = FMaterial::ValidateTexture(fbtex.get(), false); mat->AddTextureLayer(PaletteTexture.get()); @@ -99,10 +99,10 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) Canvas.reset(new DCanvas(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor())); } - auto buf = fbtex->SystemTexture[0]->MapBuffer(); + auto buf = fbtex->GetSystemTexture(0)->MapBuffer(); if (!buf) I_FatalError("Unable to map buffer for software rendering"); SWRenderer->RenderView(player, Canvas.get(), buf); - fbtex->SystemTexture[0]->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer"); + fbtex->GetSystemTexture(0)->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer"); auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); screen->DrawTexture(fbtex.get(), 0, 0, DTA_SpecialColormap, map, TAG_DONE); diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index de6922500..ccdfb5784 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -1024,15 +1024,15 @@ namespace swrenderer sprite.picnum = thing->picnum; sprite.tex = TexMan(sprite.picnum); - if (sprite.tex->UseType == ETextureType::Null) + if (!sprite.tex->isValid()) { return false; } - if (sprite.tex->Rotations != 0xFFFF) + if (sprite.tex->GetRotations() != 0xFFFF) { // choose a different rotation based on player view - spriteframe_t *sprframe = &SpriteFrames[sprite.tex->Rotations]; + spriteframe_t *sprframe = &SpriteFrames[sprite.tex->GetRotations()]; DAngle ang = (sprite.pos - Thread->Viewport->viewpoint.Pos).Angle(); angle_t rot; if (sprframe->Texture[0] == sprframe->Texture[1]) @@ -1096,7 +1096,7 @@ namespace swrenderer return false; } - if (sprite.voxel == nullptr && (sprite.tex == nullptr || sprite.tex->UseType == ETextureType::Null)) + if (sprite.voxel == nullptr && (sprite.tex == nullptr || !sprite.tex->isValid())) { return false; } diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index 1f9dbf6a7..0f2e15296 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -129,13 +129,14 @@ namespace swrenderer } } - FTexture *WallSpriteTile = TexMan(decal->PicNum, true); + FTexture *tex = TexMan(decal->PicNum, true); flipx = (uint8_t)(decal->RenderFlags & RF_XFLIP); - if (WallSpriteTile == NULL || WallSpriteTile->UseType == ETextureType::Null) + if (tex == NULL || !tex->isValid()) { return; } + FSoftwareTexture *WallSpriteTile = tex->GetSoftwareTexture(); // Determine left and right edges of sprite. Since this sprite is bound // to a wall, we use the wall's angle instead of the decal's. This is @@ -333,7 +334,7 @@ namespace swrenderer } while (needrepeat--); } - void RenderDecal::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style) + void RenderDecal::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style) { auto viewport = thread->Viewport.get(); diff --git a/src/swrenderer/things/r_decal.h b/src/swrenderer/things/r_decal.h index e617b04a6..82eab4d8f 100644 --- a/src/swrenderer/things/r_decal.h +++ b/src/swrenderer/things/r_decal.h @@ -16,6 +16,6 @@ namespace swrenderer private: static void Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass); - static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style); + static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style); }; } diff --git a/src/swrenderer/things/r_model.cpp b/src/swrenderer/things/r_model.cpp index 611d75669..26d54f104 100644 --- a/src/swrenderer/things/r_model.cpp +++ b/src/swrenderer/things/r_model.cpp @@ -107,7 +107,7 @@ namespace swrenderer if (lump.isValid()) { FTexture * tex = TexMan(lump); - if (tex) disablefullbright = tex->bDisableFullbright; + if (tex) disablefullbright = tex->isFullbrightDisabled(); } return psp->GetState()->GetFullbright() && !disablefullbright; } @@ -354,7 +354,7 @@ namespace swrenderer args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, visibility, fullbrightSprite); args.SetLights(Lights, NumLights); args.SetNormal(FVector3(0.0f, 0.0f, 0.0f)); - args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture, fullbrightSprite); + args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture->GetSoftwareTexture(), fullbrightSprite); args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); @@ -371,7 +371,7 @@ namespace swrenderer args.SetLight(GetColorTable(sector->Colormap, sector->SpecialColors[sector_t::sprites], true), lightlevel, visibility, fullbrightSprite); args.SetLights(Lights, NumLights); args.SetNormal(FVector3(0.0f, 0.0f, 0.0f)); - args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture, fullbrightSprite); + args.SetStyle(RenderStyle, RenderAlpha, fillcolor, Translation, SkinTexture->GetSoftwareTexture(), fullbrightSprite); args.SetDepthTest(true); args.SetWriteDepth(true); args.SetWriteStencil(false); diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index a51b3b5fd..6322ef637 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -226,7 +226,7 @@ namespace swrenderer flip = sprframe->Flip & 1; tex = TexMan(picnum); - if (tex->UseType == ETextureType::Null) + if (!tex->isValid()) return; if (pspr->firstTic) @@ -263,8 +263,8 @@ namespace swrenderer double pspriteyscale = pspritexscale * viewport->BaseYaspectMul * ((double)SCREENHEIGHT / SCREENWIDTH) * r_viewwindow.WidescreenRatio; double pspritexiscale = 1 / pspritexscale; - int tleft = tex->GetScaledLeftOffset(0); - int twidth = tex->GetScaledWidth(); + int tleft = tex->GetDisplayLeftOffset(); + int twidth = tex->GetDisplayWidth(); // calculate edges of the shape tx = (pspr->Flags & PSPF_MIRROR) ? ((BASEXCENTER - twidth) - (sx - tleft)) : ((sx - BASEXCENTER) - tleft); @@ -286,7 +286,8 @@ namespace swrenderer vis.renderflags = owner->renderflags; - vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->GetTopOffset(0); + FSoftwareTexture *stex = tex->GetSoftwareTexture(); + vis.texturemid = (BASEYCENTER - sy) * stex->GetScale().Y + stex->GetTopOffset(0); // Force it to use software rendering when drawing to a canvas texture. bool renderToCanvas = viewport->RenderingToCanvas; @@ -303,20 +304,20 @@ namespace swrenderer } vis.x1 = x1 < 0 ? 0 : x1; vis.x2 = x2 >= viewwidth ? viewwidth : x2; - vis.xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X); - vis.yscale = float(pspriteyscale / tex->Scale.Y); - vis.pic = tex; + vis.xscale = FLOAT2FIXED(pspritexscale / stex->GetScale().X); + vis.yscale = float(pspriteyscale / stex->GetScale().Y); + vis.pic = stex; // If flip is used, provided that it's not already flipped (that would just invert itself) // (It's an XOR...) if (!(flip) != !(pspr->Flags & PSPF_FLIP)) { - vis.xiscale = -FLOAT2FIXED(pspritexiscale * tex->Scale.X); - vis.startfrac = (tex->GetWidth() << FRACBITS) - 1; + vis.xiscale = -FLOAT2FIXED(pspritexiscale * stex->GetScale().X); + vis.startfrac = (stex->GetWidth() << FRACBITS) - 1; } else { - vis.xiscale = FLOAT2FIXED(pspritexiscale * tex->Scale.X); + vis.xiscale = FLOAT2FIXED(pspritexiscale * stex->GetScale().X); vis.startfrac = 0; } @@ -455,7 +456,7 @@ namespace swrenderer { for (const HWAccelPlayerSprite &sprite : AcceleratedSprites) { - screen->DrawTexture(sprite.pic, + screen->DrawTexture(sprite.pic->GetTexture(), viewwindowx + sprite.x1, viewwindowy + viewheight / 2 - sprite.texturemid * sprite.yscale - 0.5, DTA_DestWidthF, FIXED2DBL(sprite.pic->GetWidth() * sprite.xscale), diff --git a/src/swrenderer/things/r_playersprite.h b/src/swrenderer/things/r_playersprite.h index 24e6b25f0..6b7be57c1 100644 --- a/src/swrenderer/things/r_playersprite.h +++ b/src/swrenderer/things/r_playersprite.h @@ -59,7 +59,7 @@ namespace swrenderer class HWAccelPlayerSprite { public: - FTexture *pic = nullptr; + FSoftwareTexture *pic = nullptr; double texturemid = 0.0; float yscale = 0.0f; fixed_t xscale = 0; diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index 1251860d9..49531337a 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -72,8 +72,9 @@ EXTERN_CVAR(Bool, gl_light_sprites) namespace swrenderer { - void RenderSprite::Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *tex, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap) + void RenderSprite::Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *ttex, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap) { + FSoftwareTexture *tex = ttex->GetSoftwareTexture(); // transform the origin point double tr_x = pos.X - thread->Viewport->viewpoint.Pos.X; double tr_y = pos.Y - thread->Viewport->viewpoint.Pos.Y; @@ -151,7 +152,7 @@ namespace swrenderer renderflags ^= RF_XFLIP; // calculate edges of the shape - const double thingxscalemul = spriteScale.X / tex->Scale.X; + const double thingxscalemul = spriteScale.X / tex->GetScale().X; tx -= ((renderflags & RF_XFLIP) ? (tex->GetWidth() - tex->GetLeftOffsetSW() - 1) : tex->GetLeftOffsetSW()) * thingxscalemul; double dtx1 = tx * xscale; @@ -168,10 +169,10 @@ namespace swrenderer if ((x2 < renderportal->WindowLeft || x2 <= x1)) return; - xscale = spriteScale.X * xscale / tex->Scale.X; + xscale = spriteScale.X * xscale / tex->GetScale().X; fixed_t iscale = (fixed_t)(FRACUNIT / xscale); // Round towards zero to avoid wrapping in edge cases - double yscale = spriteScale.Y / tex->Scale.Y; + double yscale = spriteScale.Y / tex->GetScale().Y; // store information in a vissprite RenderSprite *vis = thread->FrameMemory->NewObject(); @@ -309,7 +310,7 @@ namespace swrenderer auto vis = this; fixed_t frac; - FTexture *tex; + FSoftwareTexture *tex; int x2; fixed_t xiscale; diff --git a/src/swrenderer/things/r_visiblesprite.h b/src/swrenderer/things/r_visiblesprite.h index 37787a809..01b9198d1 100644 --- a/src/swrenderer/things/r_visiblesprite.h +++ b/src/swrenderer/things/r_visiblesprite.h @@ -55,7 +55,7 @@ namespace swrenderer virtual void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) = 0; - FTexture *pic = nullptr; + FSoftwareTexture *pic = nullptr; short x1 = 0, x2 = 0; float gzb = 0.0f, gzt = 0.0f; // global bottom / top for silhouette clipping diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index a9f815425..d6cf90d22 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -71,8 +71,9 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); namespace swrenderer { - void RenderWallSprite::Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *pic, const DVector2 &scale, int renderflags, int spriteshade, bool foggy, FDynamicColormap *basecolormap) + void RenderWallSprite::Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *ppic, const DVector2 &scale, int renderflags, int spriteshade, bool foggy, FDynamicColormap *basecolormap) { + FSoftwareTexture *pic = ppic->GetSoftwareTexture(); FWallCoords wallc; double x1, x2; DVector2 left, right; @@ -205,7 +206,7 @@ namespace swrenderer calclighting = true; // Draw it - FTexture *WallSpriteTile = spr->pic; + auto WallSpriteTile = spr->pic; if (spr->renderflags & RF_YFLIP) { sprflipvert = true; @@ -254,7 +255,7 @@ namespace swrenderer } } - void RenderWallSprite::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style) + void RenderWallSprite::DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style) { auto viewport = thread->Viewport.get(); diff --git a/src/swrenderer/things/r_wallsprite.h b/src/swrenderer/things/r_wallsprite.h index fa127ccf4..d4851d07c 100644 --- a/src/swrenderer/things/r_wallsprite.h +++ b/src/swrenderer/things/r_wallsprite.h @@ -17,7 +17,7 @@ namespace swrenderer void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; private: - static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style); + static void DrawColumn(RenderThread *thread, SpriteDrawerArgs &drawerargs, int x, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style); FWallCoords wallc; uint32_t Translation = 0; diff --git a/src/swrenderer/viewport/r_skydrawer.cpp b/src/swrenderer/viewport/r_skydrawer.cpp index c134a46e2..2bbab5abf 100644 --- a/src/swrenderer/viewport/r_skydrawer.cpp +++ b/src/swrenderer/viewport/r_skydrawer.cpp @@ -47,7 +47,7 @@ namespace swrenderer dc_viewport = viewport; } - void SkyDrawerArgs::SetFrontTexture(RenderThread *thread, FTexture *texture, uint32_t column) + void SkyDrawerArgs::SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column) { if (thread->Viewport->RenderTarget->IsBgra()) { @@ -61,7 +61,7 @@ namespace swrenderer } } - void SkyDrawerArgs::SetBackTexture(RenderThread *thread, FTexture *texture, uint32_t column) + void SkyDrawerArgs::SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column) { if (texture == nullptr) { diff --git a/src/swrenderer/viewport/r_skydrawer.h b/src/swrenderer/viewport/r_skydrawer.h index 24c7e6f08..69ff04d9b 100644 --- a/src/swrenderer/viewport/r_skydrawer.h +++ b/src/swrenderer/viewport/r_skydrawer.h @@ -15,8 +15,8 @@ namespace swrenderer public: void SetDest(RenderViewport *viewport, int x, int y); void SetCount(int count) { dc_count = count; } - void SetFrontTexture(RenderThread *thread, FTexture *texture, uint32_t column); - void SetBackTexture(RenderThread *thread, FTexture *texture, uint32_t column); + void SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column); + void SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column); void SetTextureVPos(uint32_t texturefrac) { dc_texturefrac = texturefrac; } void SetTextureVStep(uint32_t iscale) { dc_iscale = iscale; } void SetSolidTop(uint32_t color) { solid_top = color; } diff --git a/src/swrenderer/viewport/r_spandrawer.cpp b/src/swrenderer/viewport/r_spandrawer.cpp index 0c1689f14..8c4bb26a7 100644 --- a/src/swrenderer/viewport/r_spandrawer.cpp +++ b/src/swrenderer/viewport/r_spandrawer.cpp @@ -30,14 +30,14 @@ namespace swrenderer spanfunc = &SWPixelFormatDrawers::DrawSpan; } - void SpanDrawerArgs::SetTexture(RenderThread *thread, FTexture *tex) + void SpanDrawerArgs::SetTexture(RenderThread *thread, FSoftwareTexture *tex) { thread->PrepareTexture(tex, DefaultRenderStyle()); ds_texwidth = tex->GetWidth(); ds_texheight = tex->GetHeight(); - ds_xbits = tex->WidthBits; - ds_ybits = tex->HeightBits; + ds_xbits = tex->GetWidthBits(); + ds_ybits = tex->GetHeightBits(); if ((1 << ds_xbits) > tex->GetWidth()) { ds_xbits--; diff --git a/src/swrenderer/viewport/r_spandrawer.h b/src/swrenderer/viewport/r_spandrawer.h index 3dc7c6191..b31b571b2 100644 --- a/src/swrenderer/viewport/r_spandrawer.h +++ b/src/swrenderer/viewport/r_spandrawer.h @@ -19,7 +19,7 @@ namespace swrenderer void SetDestY(RenderViewport *viewport, int y) { ds_viewport = viewport; ds_y = y; } void SetDestX1(int x) { ds_x1 = x; } void SetDestX2(int x) { ds_x2 = x; } - void SetTexture(RenderThread *thread, FTexture *tex); + void SetTexture(RenderThread *thread, FSoftwareTexture *tex); void SetTextureLOD(double lod) { ds_lod = lod; } void SetTextureUPos(double u) { ds_xfrac = (uint32_t)(int64_t)(u * 4294967296.0); } void SetTextureVPos(double v) { ds_yfrac = (uint32_t)(int64_t)(v * 4294967296.0); } diff --git a/src/swrenderer/viewport/r_spritedrawer.cpp b/src/swrenderer/viewport/r_spritedrawer.cpp index 7eb8007c1..f53fe70b2 100644 --- a/src/swrenderer/viewport/r_spritedrawer.cpp +++ b/src/swrenderer/viewport/r_spritedrawer.cpp @@ -43,7 +43,7 @@ namespace swrenderer colfunc = &SWPixelFormatDrawers::DrawColumn; } - void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked) + void SpriteDrawerArgs::DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked) { if (x < thread->X1 || x >= thread->X2) return; @@ -126,7 +126,7 @@ namespace swrenderer } } - void SpriteDrawerArgs::DrawMaskedColumnBgra(RenderThread *thread, int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked) + void SpriteDrawerArgs::DrawMaskedColumnBgra(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked) { dc_viewport = thread->Viewport.get(); dc_x = x; diff --git a/src/swrenderer/viewport/r_spritedrawer.h b/src/swrenderer/viewport/r_spritedrawer.h index f6a3aae79..e025d5c9e 100644 --- a/src/swrenderer/viewport/r_spritedrawer.h +++ b/src/swrenderer/viewport/r_spritedrawer.h @@ -33,7 +33,7 @@ namespace swrenderer void SetSolidColor(int color) { dc_color = color; dc_color_bgra = GPalette.BaseColors[color]; } void SetDynamicLight(uint32_t color) { dynlightcolor = color; } - void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked = false); + void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style, bool unmasked = false); void FillColumn(RenderThread *thread); void DrawVoxelBlocks(RenderThread *thread, const VoxelBlock *blocks, int blockcount); @@ -71,7 +71,7 @@ namespace swrenderer private: bool SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags); static fixed_t GetAlpha(int type, fixed_t alpha); - void DrawMaskedColumnBgra(RenderThread *thread, int x, fixed_t iscale, FTexture *tex, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked); + void DrawMaskedColumnBgra(RenderThread *thread, int x, fixed_t iscale, FSoftwareTexture *tex, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked); uint8_t *dc_dest = nullptr; int dc_dest_y = 0; diff --git a/src/textures/formats/brightmaptexture.cpp b/src/textures/formats/brightmaptexture.cpp index 7b3dae3a6..c649f3e17 100644 --- a/src/textures/formats/brightmaptexture.cpp +++ b/src/textures/formats/brightmaptexture.cpp @@ -66,9 +66,9 @@ FBrightmapTexture::FBrightmapTexture (FTexture *source) Name = ""; SourcePic = source; CopySize(source); - bNoDecals = source->bNoDecals; - Rotations = source->Rotations; - UseType = source->UseType; + bNoDecals = true; + Rotations = 0xffff; + UseType = ETextureType::Override; bMasked = false; id.SetInvalid(); SourceLump = -1; diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 4080018bf..6a64f4c6f 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -1399,7 +1399,7 @@ DEFINE_ACTION_FUNCTION(_TexMan, GetName) if (tex != nullptr) { - if (tex->Name.IsNotEmpty()) retval = tex->Name; + if (tex->GetName().IsNotEmpty()) retval = tex->GetName(); else { // Textures for full path names do not have their own name, they merely link to the source lump. @@ -1423,8 +1423,8 @@ static int GetTextureSize(int texid, int *py) int x, y; if (tex != nullptr) { - x = tex->GetWidth(); - y = tex->GetHeight(); + x = tex->GetDisplayWidth(); + y = tex->GetDisplayHeight(); } else x = y = -1; if (py) *py = y; @@ -1453,8 +1453,8 @@ static void GetScaledSize(int texid, DVector2 *pvec) double x, y; if (tex != nullptr) { - x = tex->GetScaledWidthDouble(); - y = tex->GetScaledHeightDouble(); + x = tex->GetDisplayWidthDouble(); + y = tex->GetDisplayHeightDouble(); } else x = y = -1; if (pvec) @@ -1484,8 +1484,8 @@ static void GetScaledOffset(int texid, DVector2 *pvec) double x, y; if (tex != nullptr) { - x = tex->GetScaledLeftOffsetDouble(0); - y = tex->GetScaledTopOffsetDouble(0); + x = tex->GetDisplayLeftOffsetDouble(); + y = tex->GetDisplayTopOffsetDouble(); } else x = y = -1; if (pvec) diff --git a/src/textures/textures.h b/src/textures/textures.h index f02c6e23b..1e8885ceb 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -222,6 +222,12 @@ struct FSoftwareTextureSpan struct spriteframewithrotate; class FSerializer; +namespace OpenGLRenderer +{ + class FGLRenderState; + class FHardwareTexture; +} + // Base texture class class FTexture @@ -238,11 +244,13 @@ class FTexture friend class FSoftwareTexture; friend class FWarpTexture; friend class FMaterial; - friend class FGLRenderState; // For now this needs access to some fields in ApplyMaterial. This should be rerouted through the Material class + friend class OpenGLRenderer::FGLRenderState; // For now this needs access to some fields in ApplyMaterial. This should be rerouted through the Material class friend struct FTexCoordInfo; - friend class FHardwareTexture; + friend class OpenGLRenderer::FHardwareTexture; friend class FMultiPatchTexture; friend class FSkyBox; + friend class FBrightmapTexture; + friend class FFontChar1; friend void RecordTextureColors (FTexture *pic, uint8_t *usedcolors); @@ -275,6 +283,7 @@ public: bool isFullbrightDisabled() const { return bDisableFullbright; } bool isHardwareCanvas() const { return bHasCanvas; } // There's two here so that this can deal with software canvases in the hardware renderer later. bool isCanvas() const { return bHasCanvas; } + bool isMiscPatch() const { return UseType == ETextureType::MiscPatch; } // only used by the intermission screen to decide whether to tile the background image or not. int isWarped() const { return bWarped; } int GetRotations() const { return Rotations; } void SetRotations(int rot) { Rotations = int16_t(rot); } @@ -282,10 +291,12 @@ public: const FString &GetName() const { return Name; } bool allowNoDecals() const { return bNoDecals; } bool isScaled() const { return Scale.X != 1 || Scale.Y != 1; } + bool isMasked() const { return bMasked; } int GetSkyOffset() const { return SkyOffset; } FTextureID GetID() const { return id; } PalEntry GetSkyCapColor(bool bottom); virtual FTexture *GetRawTexture(); // for FMultiPatchTexture to override + virtual int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method. void GetGlowColor(float *data); bool isGlowing() const { return bGlowing; } bool isAutoGlowing() const { return bAutoGlowing; } @@ -319,7 +330,7 @@ protected: FMaterial *Material[2] = { nullptr, nullptr }; IHardwareTexture *SystemTexture[2] = { nullptr, nullptr }; - FSoftwareTexture *SoftwareTexture; + FSoftwareTexture *SoftwareTexture = nullptr; // None of the following pointers are owned by this texture, they are all controlled by the texture manager. @@ -396,7 +407,6 @@ protected: virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL); virtual int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf = NULL); virtual bool UseBasePalette(); - virtual int GetSourceLump() { return SourceLump; } virtual FTexture *GetRedirect(); virtual void Unload (); @@ -589,6 +599,11 @@ public: { return mTexture->bWorldPanning; } + + bool isMasked() + { + return mTexture->bMasked; + } bool UseBasePalette() const { return mTexture->UseBasePalette(); } int GetSkyOffset() const { return mTexture->GetSkyOffset(); } @@ -596,7 +611,10 @@ public: int GetWidth () { return mTexture->GetWidth(); } int GetHeight () { return mTexture->GetHeight(); } - + int GetWidthBits() { return mTexture->WidthBits; } + int GetHeightBits() { return mTexture->HeightBits; } + bool Mipmapped() { return mTexture->Mipmapped(); } + int GetScaledWidth () { return mTexture->GetScaledWidth(); } int GetScaledHeight () { return mTexture->GetScaledHeight(); } double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); } @@ -652,6 +670,11 @@ public: return mTexture->GetPixelsBgra(); } + void Unload() + { + mTexture->Unload(); + } + }; @@ -960,6 +983,11 @@ public: { return SystemTexture[slot]; } + + int GetColorFormat() const + { + return WidthBits; + } }; extern FTextureManager TexMan; diff --git a/src/v_font.cpp b/src/v_font.cpp index ea50ae4cc..b863e4256 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -402,8 +402,8 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, if (i != 124-start || !stcfn121) charLumps[i] = pic; - int height = pic->GetScaledHeight(); - int yoffs = pic->GetScaledTopOffset(0); + int height = pic->GetDisplayHeight(); + int yoffs = pic->GetDisplayTopOffset(); if (yoffs > maxyoffs) { @@ -421,7 +421,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, { if (!noTranslate) Chars[i].Pic = new FFontChar1 (charLumps[i]); else Chars[i].Pic = charLumps[i]; - Chars[i].XMove = Chars[i].Pic->GetScaledWidth(); + Chars[i].XMove = Chars[i].Pic->GetDisplayWidth(); } else { @@ -465,7 +465,7 @@ FFont::~FFont () { for (int i = 0; i < count; ++i) { - if (Chars[i].Pic != NULL && Chars[i].Pic->Name[0] == 0) + if (Chars[i].Pic != nullptr && Chars[i].Pic->GetName().IsEmpty()) { delete Chars[i].Pic; } @@ -843,8 +843,8 @@ double GetBottomAlignOffset(FFont *font, int c) FTexture *tex_zero = font->GetChar('0', &w); FTexture *texc = font->GetChar(c, &w); double offset = 0; - if (texc) offset += texc->GetScaledTopOffsetDouble(0); - if (tex_zero) offset += -tex_zero->GetScaledTopOffsetDouble(0) + tex_zero->GetScaledHeightDouble(); + if (texc) offset += texc->GetDisplayTopOffsetDouble(); + if (tex_zero) offset += -tex_zero->GetDisplayTopOffsetDouble() + tex_zero->GetDisplayHeightDouble(); return offset; } @@ -999,8 +999,8 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) { FTexture *pic = TexMan[picnum]; - FontHeight = pic->GetHeight (); - SpaceWidth = pic->GetWidth (); + FontHeight = pic->GetDisplayHeight (); + SpaceWidth = pic->GetDisplayWidth (); GlobalKerning = 0; FirstChar = LastChar = 'A'; @@ -1498,8 +1498,8 @@ FSinglePicFont::FSinglePicFont(const char *picname) : FTexture *pic = TexMan[picnum]; FontName = picname; - FontHeight = pic->GetScaledHeight(); - SpaceWidth = pic->GetScaledWidth(); + FontHeight = pic->GetDisplayHeight(); + SpaceWidth = pic->GetDisplayWidth(); GlobalKerning = 0; FirstChar = LastChar = 'A'; ActiveColors = 0; @@ -1927,8 +1927,8 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l pic = charlumps[i] = lumplist[i]; if (pic != NULL) { - int height = pic->GetScaledHeight(); - int yoffs = pic->GetScaledTopOffset(0); + int height = pic->GetDisplayHeight(); + int yoffs = pic->GetDisplayTopOffset(); if (yoffs > maxyoffs) { @@ -1945,7 +1945,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l { if (!noTranslate) Chars[i].Pic = new FFontChar1 (charlumps[i]); else Chars[i].Pic = charlumps[i]; - Chars[i].XMove = Chars[i].Pic->GetScaledWidth(); + Chars[i].XMove = Chars[i].Pic->GetDisplayWidth(); } else { diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index e3e010fed..4c3129c98 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -217,10 +217,10 @@ private: int bottom; - right = c[i]->GetScaledWidth(); - bottom = c[i]->GetScaledHeight(); - left = lnodes[n].x - c[i]->GetScaledLeftOffset(0); - top = lnodes[n].y - c[i]->GetScaledTopOffset(0); + right = c[i]->GetDisplayWidth(); + bottom = c[i]->GetDisplayHeight(); + left = lnodes[n].x - c[i]->GetDisplayLeftOffset(); + top = lnodes[n].y - c[i]->GetDisplayTopOffset(); right += left; bottom += top; @@ -589,13 +589,13 @@ void DInterBackground::drawBackground(int state, bool drawsplat, bool snl_pointe if (background) { // background - if (background->UseType == ETextureType::MiscPatch) + if (background->isMiscPatch()) { // scale all animations below to fit the size of the base pic // The base pic is always scaled to fit the screen so this allows // placing the animations precisely where they belong on the base pic - animwidth = background->GetScaledWidthDouble(); - animheight = background->GetScaledHeightDouble(); + animwidth = background->GetDisplayWidthDouble(); + animheight = background->GetDisplayHeightDouble(); screen->FillBorder(NULL); screen->DrawTexture(background, 0, 0, DTA_Fullscreen, true, TAG_DONE); } diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 1e5c78640..6b6ce6aef 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -912,10 +912,12 @@ int I_PickIWad(WadStuff *wads, int numwads, bool showwin, int defaultiwad) // //========================================================================== +// Custom cursors temporarily disabled until this can directly reference a texture's backing image. bool I_SetCursor(FTexture *cursorpic) { HCURSOR cursor; +#if 0 if (cursorpic != NULL && cursorpic->UseType != ETextureType::Null) { // Must be no larger than 32x32. @@ -939,6 +941,7 @@ bool I_SetCursor(FTexture *cursorpic) atterm(DestroyCustomCursor); } else +#endif { DestroyCustomCursor(); cursor = LoadCursor(NULL, IDC_ARROW); @@ -974,6 +977,7 @@ bool I_SetCursor(FTexture *cursorpic) static HCURSOR CreateCompatibleCursor(FTexture *cursorpic) { +#if 0 int picwidth = cursorpic->GetWidth(); int picheight = cursorpic->GetHeight(); @@ -1025,6 +1029,9 @@ static HCURSOR CreateCompatibleCursor(FTexture *cursorpic) // Create the cursor from the bitmaps. return CreateBitmapCursor(cursorpic->GetLeftOffset(0), cursorpic->GetTopOffset(0), and_mask, xor_mask); +#else + return nullptr; +#endif } //========================================================================== @@ -1037,6 +1044,7 @@ static HCURSOR CreateCompatibleCursor(FTexture *cursorpic) static HCURSOR CreateAlphaCursor(FTexture *cursorpic) { +#if 0 HDC dc; BITMAPV5HEADER bi; HBITMAP color, mono; @@ -1109,6 +1117,9 @@ static HCURSOR CreateAlphaCursor(FTexture *cursorpic) } return CreateBitmapCursor(cursorpic->GetLeftOffset(0) * scale, cursorpic->GetTopOffset(0) * scale, mono, color); +#else + return nullptr; +#endif } //========================================================================== From d500dc99ea58399d1d3392cd4577501754c60e98 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 6 Dec 2018 20:21:33 +0100 Subject: [PATCH 03/66] - handle the Harmony status bar icon scaling a bit more robustly. Considering that the physical texture size should be abstracted away from modding this needs to be done differently. Doing any calculations with physical texture sizes on the mod side is only going to cause errors so this had been changed to always return scaled size. --- wadsrc/static/zscript/statusbar/harm_sbar.txt | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/wadsrc/static/zscript/statusbar/harm_sbar.txt b/wadsrc/static/zscript/statusbar/harm_sbar.txt index 42a30f2fc..729df7cda 100644 --- a/wadsrc/static/zscript/statusbar/harm_sbar.txt +++ b/wadsrc/static/zscript/statusbar/harm_sbar.txt @@ -1,6 +1,6 @@ class HarmonyStatusBar : DoomStatusBar { - int scalestate; + double scaleFactor; override void Init() { @@ -10,22 +10,14 @@ class HarmonyStatusBar : DoomStatusBar let tex = TexMan.CheckForTexture("MEDIA0", TexMan.Type_Sprite); if (tex.isValid()) { - int size = TexMan.GetSize(tex); Vector2 ssize = TexMan.GetScaledSize(tex); - if (ssize.X ~== size) scalestate = 1; - else scalestate = 0; + Vector2 facs = (ssize.X / 31, ssize.Y / 18); + scaleFactor = min(facs.X, facs.Y, 1); } - else scalestate = 1; } override void Draw (int state, double TicFrac) { - if (!scalestate) - { - Super.Draw(state, TicFrac); - return; - } - BaseStatusBar.Draw (state, TicFrac); if (state == HUD_StatusBar) @@ -44,13 +36,13 @@ class HarmonyStatusBar : DoomStatusBar { Vector2 iconbox = (40, 20); // Draw health - DrawImage("MEDIA0", (20, -2), scale:(0.3, 0.3)); + DrawImage("MEDIA0", (20, -2), scale(scaleFactor, scaleFactor)); DrawString(mHUDFont, FormatNumber(CPlayer.health, 3), (44, -20)); let armor = CPlayer.mo.FindInventory("BasicArmor"); if (armor != null && armor.Amount > 0) { - DrawInventoryIcon(armor, (20, -22), scale:(0.3, 0.3)); + DrawInventoryIcon(armor, (20, -22), scale(scaleFactor, scaleFactor)); DrawString(mHUDFont, FormatNumber(armor.Amount, 3), (44, -40)); } Inventory ammotype1, ammotype2; @@ -58,13 +50,13 @@ class HarmonyStatusBar : DoomStatusBar int invY = -20; if (ammotype1 != null) { - DrawInventoryIcon(ammotype1, (-14, -4), scale:(0.3, 0.3)); + DrawInventoryIcon(ammotype1, (-14, -4), scale(scaleFactor, scaleFactor)); DrawString(mHUDFont, FormatNumber(ammotype1.Amount, 3), (-30, -20), DI_TEXT_ALIGN_RIGHT); invY -= 20; } if (ammotype2 != null && ammotype2 != ammotype1) { - DrawInventoryIcon(ammotype2, (-14, invY + 17), scale:(0.3, 0.3)); + DrawInventoryIcon(ammotype2, (-14, invY + 17), scale(scaleFactor, scaleFactor)); DrawString(mHUDFont, FormatNumber(ammotype2.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT); invY -= 20; } From 32e245f2b90ed4f286a44e4a10a6d22f165cf936 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 6 Dec 2018 20:52:03 +0100 Subject: [PATCH 04/66] - moved the software rendering specific parts of the sky setup to r_skyplane.cpp. --- src/polyrenderer/scene/poly_sky.cpp | 5 ++ src/r_sky.cpp | 67 ++----------------- src/r_sky.h | 4 -- src/r_utility.cpp | 2 + src/swrenderer/plane/r_skyplane.cpp | 57 ++++++++++++++++ src/swrenderer/r_swscene.cpp | 2 + wadsrc/static/zscript/statusbar/harm_sbar.txt | 8 +-- 7 files changed, 77 insertions(+), 68 deletions(-) diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp index 1cca9dca4..cf5fc755d 100644 --- a/src/polyrenderer/scene/poly_sky.cpp +++ b/src/polyrenderer/scene/poly_sky.cpp @@ -32,6 +32,11 @@ EXTERN_CVAR(Float, skyoffset) +extern double skytexturemid; +extern float skyiscale; +extern double skyscale; +extern fixed_t sky1cyl, sky2cyl; + PolySkyDome::PolySkyDome() { diff --git a/src/r_sky.cpp b/src/r_sky.cpp index 6297a822d..5b161dde1 100644 --- a/src/r_sky.cpp +++ b/src/r_sky.cpp @@ -44,19 +44,9 @@ // FTextureID skyflatnum; FTextureID sky1texture, sky2texture; -double skytexturemid; -double skyscale; -float skyiscale; -bool skystretch; - -fixed_t sky1cyl, sky2cyl; double sky1pos, sky2pos; float hw_sky1pos, hw_sky2pos; - -CUSTOM_CVAR(Int, testskyoffset, 0, 0) -{ - R_InitSkyMap(); -} +bool skystretch; // [RH] Stretch sky texture if not taller than 128 pixels? // Also now controls capped skies. 0 = normal, 1 = stretched, 2 = capped @@ -67,10 +57,6 @@ CUSTOM_CVAR (Int, r_skymode, 2, CVAR_ARCHIVE) CVAR(Float, skyoffset, 0, 0) // for testing - - -int freelookviewheight; - //========================================================================== // // R_InitSkyMap @@ -79,7 +65,7 @@ int freelookviewheight; // //========================================================================== -void R_InitSkyMap () +void R_InitSkyMap() { int skyheight; FTexture *skytex1, *skytex2; @@ -102,7 +88,7 @@ void R_InitSkyMap () if ((level.flags & LEVEL_DOUBLESKY) && skytex1->GetDisplayHeight() != skytex2->GetDisplayHeight()) { - Printf (TEXTCOLOR_BOLD "Both sky textures must be the same height." TEXTCOLOR_NORMAL "\n"); + Printf(TEXTCOLOR_BOLD "Both sky textures must be the same height." TEXTCOLOR_NORMAL "\n"); sky2texture = sky1texture; } @@ -120,56 +106,17 @@ void R_InitSkyMap () // h > 200: Unstretched, but the baseline is shifted down so that the top // of the texture is at the top of the screen when looking fully up. skyheight = skytex1->GetDisplayHeight(); - + if (skyheight >= 128 && skyheight < 200) { skystretch = (r_skymode == 1 - && skyheight >= 128 - && level.IsFreelookAllowed() - && !(level.flags & LEVEL_FORCETILEDSKY)) ? 1 : 0; + && skyheight >= 128 + && level.IsFreelookAllowed() + && !(level.flags & LEVEL_FORCETILEDSKY)) ? 1 : 0; } else skystretch = false; - - // Anything below is only for the software renderer (todo - move it there!) - // Note: I don't think it is good that this stuff gets cached globally. - // For something that only needs to be once per frame it is rather pointless and makes it hard to swap out the underlying textures based on user settings. - FSoftwareTexture *sskytex1 = skytex1->GetSoftwareTexture(); - FSoftwareTexture *sskytex2 = skytex2->GetSoftwareTexture(); - skytexturemid = 0; - if (skyheight >= 128 && skyheight < 200) - { - skytexturemid = -28; - } - else if (skyheight > 200) - { - skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y +((r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() + testskyoffset : 0); - } - - if (viewwidth != 0 && viewheight != 0) - { - skyiscale = float(r_Yaspect / freelookviewheight); - skyscale = freelookviewheight / r_Yaspect; - - skyiscale *= float(r_viewpoint.FieldOfView.Degrees / 90.); - skyscale *= float(90. / r_viewpoint.FieldOfView.Degrees); - } - - if (skystretch) - { - skyscale *= (double)SKYSTRETCH_HEIGHT / skyheight; - skyiscale *= skyheight / (float)SKYSTRETCH_HEIGHT; - skytexturemid *= skyheight / (double)SKYSTRETCH_HEIGHT; - } - - // The standard Doom sky texture is 256 pixels wide, repeated 4 times over 360 degrees, - // giving a total sky width of 1024 pixels. So if the sky texture is no wider than 1024, - // we map it to a cylinder with circumfrence 1024. For larger ones, we use the width of - // the texture as the cylinder's circumfrence. - sky1cyl = MAX(sskytex1->GetWidth(), fixed_t(sskytex1->GetScale().X * 1024)); - sky2cyl = MAX(sskytex2->GetWidth(), fixed_t(sskytex2->GetScale().Y * 1024)); } - //========================================================================== // // R_UpdateSky diff --git a/src/r_sky.h b/src/r_sky.h index d9963d96c..05154e2fd 100644 --- a/src/r_sky.h +++ b/src/r_sky.h @@ -31,13 +31,9 @@ #include "textures/textures.h" extern FTextureID skyflatnum; -extern fixed_t sky1cyl, sky2cyl; extern FTextureID sky1texture, sky2texture; extern double sky1pos, sky2pos; extern float hw_sky1pos, hw_sky2pos; -extern double skytexturemid; -extern float skyiscale; -extern double skyscale; extern bool skystretch; extern int freelookviewheight; diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 40b640e46..d12f3bf4d 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -144,6 +144,8 @@ bool setsizeneeded; unsigned int R_OldBlend = ~0; int validcount = 1; // increment every time a check is made int dl_validcount = 1; // increment every time a check is made +int freelookviewheight; + FCanvasTextureInfo *FCanvasTextureInfo::List; DVector3a view; diff --git a/src/swrenderer/plane/r_skyplane.cpp b/src/swrenderer/plane/r_skyplane.cpp index de30a0a89..feac5b5da 100644 --- a/src/swrenderer/plane/r_skyplane.cpp +++ b/src/swrenderer/plane/r_skyplane.cpp @@ -57,8 +57,65 @@ CVAR(Bool, r_linearsky, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG); EXTERN_CVAR(Int, r_skymode) + +double skytexturemid; +double skyscale; +float skyiscale; +fixed_t sky1cyl, sky2cyl; + +void InitSoftwareSky() +{ + auto skytex1 = TexMan(sky1texture, true); + auto skytex2 = TexMan(sky2texture, true); + + if (skytex1 == nullptr) + return; + + // Note: I don't think it is good that this stuff gets cached globally. + // For something that only needs to be once per frame it is rather pointless and makes it hard to swap out the underlying textures based on user settings. + FSoftwareTexture *sskytex1 = skytex1->GetSoftwareTexture(); + FSoftwareTexture *sskytex2 = skytex2->GetSoftwareTexture(); + skytexturemid = 0; + int skyheight = skytex1->GetDisplayHeight(); + if (skyheight >= 128 && skyheight < 200) + { + skytexturemid = -28; + } + else if (skyheight > 200) + { + skytexturemid = (200 - skyheight) * sskytex1->GetScale().Y + ((r_skymode == 2 && !(level.flags & LEVEL_FORCETILEDSKY)) ? skytex1->GetSkyOffset() : 0); + } + + if (viewwidth != 0 && viewheight != 0) + { + skyiscale = float(r_Yaspect / freelookviewheight); + skyscale = freelookviewheight / r_Yaspect; + + skyiscale *= float(r_viewpoint.FieldOfView.Degrees / 90.); + skyscale *= float(90. / r_viewpoint.FieldOfView.Degrees); + } + + if (skystretch) + { + skyscale *= (double)SKYSTRETCH_HEIGHT / skyheight; + skyiscale *= skyheight / (float)SKYSTRETCH_HEIGHT; + skytexturemid *= skyheight / (double)SKYSTRETCH_HEIGHT; + } + + // The standard Doom sky texture is 256 pixels wide, repeated 4 times over 360 degrees, + // giving a total sky width of 1024 pixels. So if the sky texture is no wider than 1024, + // we map it to a cylinder with circumfrence 1024. For larger ones, we use the width of + // the texture as the cylinder's circumfrence. + sky1cyl = MAX(sskytex1->GetWidth(), fixed_t(sskytex1->GetScale().X * 1024)); + sky2cyl = MAX(sskytex2->GetWidth(), fixed_t(sskytex2->GetScale().Y * 1024)); +} + + + + namespace swrenderer { + static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true) { auto tex = TexMan(texid, true); diff --git a/src/swrenderer/r_swscene.cpp b/src/swrenderer/r_swscene.cpp index 7a3cfe2d7..c8b8da57c 100644 --- a/src/swrenderer/r_swscene.cpp +++ b/src/swrenderer/r_swscene.cpp @@ -37,6 +37,7 @@ // [RH] Base blending values (for e.g. underwater) int BaseBlendR, BaseBlendG, BaseBlendB; float BaseBlendA; +void InitSoftwareSky(); @@ -80,6 +81,7 @@ SWSceneDrawer::~SWSceneDrawer() sector_t *SWSceneDrawer::RenderView(player_t *player) { // Avoid using the pixel buffer from the last frame + InitSoftwareSky(); // do this here to avoid problems when texture modes are changed on the fly. FBTextureIndex = (FBTextureIndex + 1) % 2; auto &fbtex = FBTexture[FBTextureIndex]; diff --git a/wadsrc/static/zscript/statusbar/harm_sbar.txt b/wadsrc/static/zscript/statusbar/harm_sbar.txt index 729df7cda..ebed03f92 100644 --- a/wadsrc/static/zscript/statusbar/harm_sbar.txt +++ b/wadsrc/static/zscript/statusbar/harm_sbar.txt @@ -36,13 +36,13 @@ class HarmonyStatusBar : DoomStatusBar { Vector2 iconbox = (40, 20); // Draw health - DrawImage("MEDIA0", (20, -2), scale(scaleFactor, scaleFactor)); + DrawImage("MEDIA0", (20, -2), scale:(scaleFactor, scaleFactor)); DrawString(mHUDFont, FormatNumber(CPlayer.health, 3), (44, -20)); let armor = CPlayer.mo.FindInventory("BasicArmor"); if (armor != null && armor.Amount > 0) { - DrawInventoryIcon(armor, (20, -22), scale(scaleFactor, scaleFactor)); + DrawInventoryIcon(armor, (20, -22), scale:(scaleFactor, scaleFactor)); DrawString(mHUDFont, FormatNumber(armor.Amount, 3), (44, -40)); } Inventory ammotype1, ammotype2; @@ -50,13 +50,13 @@ class HarmonyStatusBar : DoomStatusBar int invY = -20; if (ammotype1 != null) { - DrawInventoryIcon(ammotype1, (-14, -4), scale(scaleFactor, scaleFactor)); + DrawInventoryIcon(ammotype1, (-14, -4), scale:(scaleFactor, scaleFactor)); DrawString(mHUDFont, FormatNumber(ammotype1.Amount, 3), (-30, -20), DI_TEXT_ALIGN_RIGHT); invY -= 20; } if (ammotype2 != null && ammotype2 != ammotype1) { - DrawInventoryIcon(ammotype2, (-14, invY + 17), scale(scaleFactor, scaleFactor)); + DrawInventoryIcon(ammotype2, (-14, invY + 17), scale:(scaleFactor, scaleFactor)); DrawString(mHUDFont, FormatNumber(ammotype2.Amount, 3), (-30, invY), DI_TEXT_ALIGN_RIGHT); invY -= 20; } From 4c67785c4022983919d86c25d66559a6b5b8193c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 00:04:39 +0100 Subject: [PATCH 05/66] - moved the span and swtruecolor creation code into FSoftwareTexture. --- src/CMakeLists.txt | 2 + src/polyrenderer/poly_all.cpp | 1 + src/swrenderer/r_all.cpp | 1 + src/swrenderer/r_swrenderer.cpp | 2 +- src/swrenderer/textures/r_swtexture.cpp | 453 +++++++++++++++++++++ src/swrenderer/textures/r_swtexture.h | 129 ++++++ src/textures/formats/canvastexture.cpp | 6 + src/textures/formats/multipatchtexture.cpp | 8 +- src/textures/formats/warptexture.cpp | 6 +- src/textures/formats/worldtexture.cpp | 51 --- src/textures/skyboxtexture.cpp | 12 - src/textures/skyboxtexture.h | 2 +- src/textures/texture.cpp | 366 ----------------- src/textures/textures.h | 145 +------ src/v_font.cpp | 54 +-- 15 files changed, 608 insertions(+), 630 deletions(-) create mode 100644 src/swrenderer/textures/r_swtexture.cpp create mode 100644 src/swrenderer/textures/r_swtexture.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0ec18032e..2a0d2a413 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -681,6 +681,7 @@ file( GLOB HEADER_FILES sound/wildmidi/*.h xlat/*.h swrenderer/*.h + swrenderer/textures/*.h swrenderer/drawers/*.h swrenderer/scene/*.h swrenderer/segments/*.h @@ -1244,6 +1245,7 @@ set (PCH_SOURCES sound/wildmidi/reverb.cpp sound/wildmidi/wildmidi_lib.cpp sound/wildmidi/wm_error.cpp + swrenderer/textures/r_swtexture.cpp events.cpp ) diff --git a/src/polyrenderer/poly_all.cpp b/src/polyrenderer/poly_all.cpp index 1a777fbb1..29b3c7fe1 100644 --- a/src/polyrenderer/poly_all.cpp +++ b/src/polyrenderer/poly_all.cpp @@ -1,3 +1,4 @@ +#include "../swrenderer/textures/r_swtexture.h" #include "poly_renderer.cpp" #include "poly_renderthread.cpp" #include "drawers/poly_buffer.cpp" diff --git a/src/swrenderer/r_all.cpp b/src/swrenderer/r_all.cpp index 8eaf961f6..c1dc53734 100644 --- a/src/swrenderer/r_all.cpp +++ b/src/swrenderer/r_all.cpp @@ -1,3 +1,4 @@ +#include "textures/r_swtexture.h" #include "r_memory.cpp" #include "r_renderthread.cpp" #include "r_swrenderer.cpp" diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index 66e4b7956..721873da1 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -84,7 +84,7 @@ void FSoftwareRenderer::PrecacheTexture(FTexture *ttex, int cache) { bool isbgra = V_IsTrueColor(); - if (ttex != NULL) + if (ttex != NULL && ttex->isValid()) { FSoftwareTexture *tex = ttex->GetSoftwareTexture(); if (cache & FTextureManager::HIT_Columnmode) diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp new file mode 100644 index 000000000..8a389f44a --- /dev/null +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -0,0 +1,453 @@ +/* +** texture.cpp +** The base texture class +** +**--------------------------------------------------------------------------- +** Copyright 2004-2007 Randy Heit +** Copyright 2006-2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "r_swtexture.h" +#include "bitmap.h" +#include "m_alloc.h" + + + + +//========================================================================== +// +// +// +//========================================================================== + +const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) +{ + const uint32_t *pixels = GetPixelsBgra(); + if (pixels == nullptr) return nullptr; + + column %= GetWidth(); + + if (spans_out != nullptr) + GetColumn(DefaultRenderStyle(), column, spans_out); // This isn't the right way to create the spans. + return pixels + column * GetHeight(); +} + +const uint32_t *FSoftwareTexture::GetPixelsBgra() +{ + if (PixelsBgra.empty() || mTexture->CheckModified(DefaultRenderStyle())) + { + if (!GetColumn(DefaultRenderStyle(), 0, nullptr)) + return nullptr; + + FBitmap bitmap; + bitmap.Create(GetWidth(), GetHeight()); + mTexture->CopyTrueColorPixels(&bitmap, 0, 0); + GenerateBgraFromBitmap(bitmap); + } + return PixelsBgra.data(); +} + +//========================================================================== +// +// +// +//========================================================================== + +FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const uint8_t *pixels) +{ + FSoftwareTextureSpan **spans, *span; + + if (!mTexture->isMasked()) + { // Texture does not have holes, so it can use a simpler span structure + spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*GetWidth() + sizeof(FSoftwareTextureSpan)*2); + span = (FSoftwareTextureSpan *)&spans[GetWidth()]; + for (int x = 0; x < GetWidth(); ++x) + { + spans[x] = span; + } + span[0].Length = GetHeight(); + span[0].TopOffset = 0; + span[1].Length = 0; + span[1].TopOffset = 0; + } + else + { // Texture might have holes, so build a complete span structure + int numcols = GetWidth(); + int numrows = GetHeight(); + int numspans = numcols; // One span to terminate each column + const uint8_t *data_p; + bool newspan; + int x, y; + + data_p = pixels; + + // Count the number of spans in this texture + for (x = numcols; x > 0; --x) + { + newspan = true; + for (y = numrows; y > 0; --y) + { + + if (*data_p++ == 0) + { + if (!newspan) + { + newspan = true; + } + } + else if (newspan) + { + newspan = false; + numspans++; + } + } + } + + // Allocate space for the spans + spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*numcols + sizeof(FSoftwareTextureSpan)*numspans); + + // Fill in the spans + for (x = 0, span = (FSoftwareTextureSpan *)&spans[numcols], data_p = pixels; x < numcols; ++x) + { + newspan = true; + spans[x] = span; + for (y = 0; y < numrows; ++y) + { + if (*data_p++ == 0) + { + if (!newspan) + { + newspan = true; + span++; + } + } + else + { + if (newspan) + { + newspan = false; + span->TopOffset = y; + span->Length = 1; + } + else + { + span->Length++; + } + } + } + if (!newspan) + { + span++; + } + span->TopOffset = 0; + span->Length = 0; + span++; + } + } + return spans; +} + +void FSoftwareTexture::FreeSpans (FSoftwareTextureSpan **spans) +{ + M_Free (spans); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSoftwareTexture::GenerateBgraFromBitmap(const FBitmap &bitmap) +{ + CreatePixelsBgraWithMipmaps(); + + // Transpose + const uint32_t *src = (const uint32_t *)bitmap.GetPixels(); + uint32_t *dest = PixelsBgra.data(); + for (int x = 0; x < GetWidth(); x++) + { + for (int y = 0; y < GetHeight(); y++) + { + dest[y + x * GetHeight()] = src[x + y * GetWidth()]; + } + } + + GenerateBgraMipmaps(); +} + +void FSoftwareTexture::CreatePixelsBgraWithMipmaps() +{ + int levels = MipmapLevels(); + int buffersize = 0; + for (int i = 0; i < levels; i++) + { + int w = MAX(GetWidth() >> i, 1); + int h = MAX(GetHeight() >> i, 1); + buffersize += w * h; + } + PixelsBgra.resize(buffersize, 0xffff0000); +} + +int FSoftwareTexture::MipmapLevels() +{ + int widthbits = 0; + while ((GetWidth() >> widthbits) != 0) widthbits++; + + int heightbits = 0; + while ((GetHeight() >> heightbits) != 0) heightbits++; + + return MAX(widthbits, heightbits); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSoftwareTexture::GenerateBgraMipmaps() +{ + struct Color4f + { + float a, r, g, b; + Color4f operator*(const Color4f &v) const { return Color4f{ a * v.a, r * v.r, g * v.g, b * v.b }; } + Color4f operator/(const Color4f &v) const { return Color4f{ a / v.a, r / v.r, g / v.g, b / v.b }; } + Color4f operator+(const Color4f &v) const { return Color4f{ a + v.a, r + v.r, g + v.g, b + v.b }; } + Color4f operator-(const Color4f &v) const { return Color4f{ a - v.a, r - v.r, g - v.g, b - v.b }; } + Color4f operator*(float s) const { return Color4f{ a * s, r * s, g * s, b * s }; } + Color4f operator/(float s) const { return Color4f{ a / s, r / s, g / s, b / s }; } + Color4f operator+(float s) const { return Color4f{ a + s, r + s, g + s, b + s }; } + Color4f operator-(float s) const { return Color4f{ a - s, r - s, g - s, b - s }; } + }; + + int levels = MipmapLevels(); + std::vector image(PixelsBgra.size()); + + // Convert to normalized linear colorspace + { + for (int x = 0; x < GetWidth(); x++) + { + for (int y = 0; y < GetHeight(); y++) + { + uint32_t c8 = PixelsBgra[x * GetHeight() + y]; + Color4f c; + c.a = powf(APART(c8) * (1.0f / 255.0f), 2.2f); + c.r = powf(RPART(c8) * (1.0f / 255.0f), 2.2f); + c.g = powf(GPART(c8) * (1.0f / 255.0f), 2.2f); + c.b = powf(BPART(c8) * (1.0f / 255.0f), 2.2f); + image[x * GetHeight() + y] = c; + } + } + } + + // Generate mipmaps + { + std::vector smoothed(GetWidth() * GetHeight()); + Color4f *src = image.data(); + Color4f *dest = src + GetWidth() * GetHeight(); + for (int i = 1; i < levels; i++) + { + int srcw = MAX(GetWidth() >> (i - 1), 1); + int srch = MAX(GetHeight() >> (i - 1), 1); + int w = MAX(GetWidth() >> i, 1); + int h = MAX(GetHeight() >> i, 1); + + // Downscale + for (int x = 0; x < w; x++) + { + int sx0 = x * 2; + int sx1 = MIN((x + 1) * 2, srcw - 1); + for (int y = 0; y < h; y++) + { + int sy0 = y * 2; + int sy1 = MIN((y + 1) * 2, srch - 1); + + Color4f src00 = src[sy0 + sx0 * srch]; + Color4f src01 = src[sy1 + sx0 * srch]; + Color4f src10 = src[sy0 + sx1 * srch]; + Color4f src11 = src[sy1 + sx1 * srch]; + Color4f c = (src00 + src01 + src10 + src11) * 0.25f; + + dest[y + x * h] = c; + } + } + + // Sharpen filter with a 3x3 kernel: + for (int x = 0; x < w; x++) + { + for (int y = 0; y < h; y++) + { + Color4f c = { 0.0f, 0.0f, 0.0f, 0.0f }; + for (int kx = -1; kx < 2; kx++) + { + for (int ky = -1; ky < 2; ky++) + { + int a = y + ky; + int b = x + kx; + if (a < 0) a = h - 1; + if (a == h) a = 0; + if (b < 0) b = w - 1; + if (b == w) b = 0; + c = c + dest[a + b * h]; + } + } + c = c * (1.0f / 9.0f); + smoothed[y + x * h] = c; + } + } + float k = 0.08f; + for (int j = 0; j < w * h; j++) + dest[j] = dest[j] + (dest[j] - smoothed[j]) * k; + + src = dest; + dest += w * h; + } + } + + // Convert to bgra8 sRGB colorspace + { + Color4f *src = image.data() + GetWidth() * GetHeight(); + uint32_t *dest = PixelsBgra.data() + GetWidth() * GetHeight(); + for (int i = 1; i < levels; i++) + { + int w = MAX(GetWidth() >> i, 1); + int h = MAX(GetHeight() >> i, 1); + for (int j = 0; j < w * h; j++) + { + uint32_t a = (uint32_t)clamp(powf(MAX(src[j].a, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f); + uint32_t r = (uint32_t)clamp(powf(MAX(src[j].r, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f); + uint32_t g = (uint32_t)clamp(powf(MAX(src[j].g, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f); + uint32_t b = (uint32_t)clamp(powf(MAX(src[j].b, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f); + dest[j] = (a << 24) | (r << 16) | (g << 8) | b; + } + src += w * h; + dest += w * h; + } + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSoftwareTexture::GenerateBgraMipmapsFast() +{ + uint32_t *src = PixelsBgra.data(); + uint32_t *dest = src + GetWidth() * GetHeight(); + int levels = MipmapLevels(); + for (int i = 1; i < levels; i++) + { + int srcw = MAX(GetWidth() >> (i - 1), 1); + int srch = MAX(GetHeight() >> (i - 1), 1); + int w = MAX(GetWidth() >> i, 1); + int h = MAX(GetHeight() >> i, 1); + + for (int x = 0; x < w; x++) + { + int sx0 = x * 2; + int sx1 = MIN((x + 1) * 2, srcw - 1); + + for (int y = 0; y < h; y++) + { + int sy0 = y * 2; + int sy1 = MIN((y + 1) * 2, srch - 1); + + uint32_t src00 = src[sy0 + sx0 * srch]; + uint32_t src01 = src[sy1 + sx0 * srch]; + uint32_t src10 = src[sy0 + sx1 * srch]; + uint32_t src11 = src[sy1 + sx1 * srch]; + + uint32_t alpha = (APART(src00) + APART(src01) + APART(src10) + APART(src11) + 2) / 4; + uint32_t red = (RPART(src00) + RPART(src01) + RPART(src10) + RPART(src11) + 2) / 4; + uint32_t green = (GPART(src00) + GPART(src01) + GPART(src10) + GPART(src11) + 2) / 4; + uint32_t blue = (BPART(src00) + BPART(src01) + BPART(src10) + BPART(src11) + 2) / 4; + + dest[y + x * h] = (alpha << 24) | (red << 16) | (green << 8) | blue; + } + } + + src = dest; + dest += w * h; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +const uint8_t *FSoftwareTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) +{ + int index = !!(style.Flags & STYLEF_RedIsAlpha); + auto Pixeldata = GetPixels(style); + if ((unsigned)column >= (unsigned)GetWidth()) + { + if (mTexture->WidthMask + 1 == GetWidth()) + { + column &= mTexture->WidthMask; + } + else + { + column %= GetWidth(); + } + } + if (spans_out != nullptr) + { + if (Spandata[index] == nullptr) + { + Spandata[index] = CreateSpans (Pixeldata); + } + *spans_out = Spandata[index][column]; + } + return Pixeldata + column*GetHeight(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSoftwareTexture::FreeAllSpans() +{ + for(int i = 0; i < 2; i++) + { + if (Spandata[i] != nullptr) + { + FreeSpans (Spandata[i]); + Spandata[i] = nullptr; + } + } +} + diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h new file mode 100644 index 000000000..a6aaa02bb --- /dev/null +++ b/src/swrenderer/textures/r_swtexture.h @@ -0,0 +1,129 @@ +#pragma once +#include "textures/textures.h" + + +struct FSoftwareTextureSpan +{ + uint16_t TopOffset; + uint16_t Length; // A length of 0 terminates this column +}; + + +// For now this is just a minimal wrapper around FTexture. Once the software renderer no longer accesses FTexture directly, it is time for cleaning up. +class FSoftwareTexture +{ + FTexture *mTexture; + FTexture *mSource; + std::vector PixelsBgra; + FSoftwareTextureSpan **Spandata[2] = { nullptr, nullptr }; + + +public: + FSoftwareTexture(FTexture *tex) + { + mTexture = tex; + mSource = tex; + } + + virtual ~FSoftwareTexture() + { + FreeAllSpans(); + } + + FTexture *GetTexture() const + { + return mTexture; + } + + // The feature from hell... :( + bool useWorldPanning() const + { + return mTexture->bWorldPanning; + } + + bool isMasked() + { + return mTexture->bMasked; + } + + bool UseBasePalette() const { return mTexture->UseBasePalette(); } + int GetSkyOffset() const { return mTexture->GetSkyOffset(); } + PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); } + + int GetWidth () { return mTexture->GetWidth(); } + int GetHeight () { return mTexture->GetHeight(); } + int GetWidthBits() { return mTexture->WidthBits; } + int GetHeightBits() { return mTexture->HeightBits; } + bool Mipmapped() { return mTexture->Mipmapped(); } + + int GetScaledWidth () { return mTexture->GetScaledWidth(); } + int GetScaledHeight () { return mTexture->GetScaledHeight(); } + double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); } + double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); } + double GetScaleY() const { return mTexture->GetScaleY(); } + + // Now with improved offset adjustment. + int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); } + int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted); } + int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted); } + int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted); } + double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted); } + double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted); } + + // Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets + // should use these, so that if changes are needed, this is the only place to edit. + + // For the original software renderer + int GetLeftOffsetSW() { return GetLeftOffset(r_spriteadjustSW); } + int GetTopOffsetSW() { return GetTopOffset(r_spriteadjustSW); } + int GetScaledLeftOffsetSW() { return GetScaledLeftOffset(r_spriteadjustSW); } + int GetScaledTopOffsetSW() { return GetScaledTopOffset(r_spriteadjustSW); } + + // For the softpoly renderer, in case it wants adjustment + int GetLeftOffsetPo() { return GetLeftOffset(r_spriteadjustSW); } + int GetTopOffsetPo() { return GetTopOffset(r_spriteadjustSW); } + int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); } + int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); } + + DVector2 GetScale() const { return mTexture->Scale; } + + // Returns the whole texture, stored in column-major order + const uint8_t *GetPixels(FRenderStyle style) + { + return mTexture->GetPixels(style); + } + + void Unload() + { + mTexture->Unload(); + PixelsBgra = std::vector(); + } + + void GenerateBgraFromBitmap(const FBitmap &bitmap); + void CreatePixelsBgraWithMipmaps(); + void GenerateBgraMipmaps(); + void GenerateBgraMipmapsFast(); + int MipmapLevels(); + void FreeAllSpans(); + + FSoftwareTextureSpan **CreateSpans (const uint8_t *pixels); + void FreeSpans (FSoftwareTextureSpan **spans); + + // Returns a single column of the texture + virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); + + // Returns a single column of the texture, in BGRA8 format + virtual const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out); + + // Returns the whole texture, stored in column-major order, in BGRA8 format + virtual const uint32_t *GetPixelsBgra(); + + +}; + + +inline FSoftwareTexture *FTexture::GetSoftwareTexture() +{ + if (!SoftwareTexture) SoftwareTexture = new FSoftwareTexture(this); + return SoftwareTexture; +} diff --git a/src/textures/formats/canvastexture.cpp b/src/textures/formats/canvastexture.cpp index d27e1c8fb..c760d7351 100644 --- a/src/textures/formats/canvastexture.cpp +++ b/src/textures/formats/canvastexture.cpp @@ -44,10 +44,12 @@ FCanvasTexture::FCanvasTexture (const char *name, int width, int height) CalcBitSize (); bMasked = false; + /* DummySpans[0].TopOffset = 0; DummySpans[0].Length = height; DummySpans[1].TopOffset = 0; DummySpans[1].Length = 0; + */ UseType = ETextureType::Wall; bNeedsUpdate = true; bDidUpdate = false; @@ -61,6 +63,7 @@ FCanvasTexture::~FCanvasTexture () Unload (); } +#if 0 const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) { bNeedsUpdate = true; @@ -85,6 +88,7 @@ const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column } return Pixels + column*Height; } +#endif const uint8_t *FCanvasTexture::GetPixels (FRenderStyle style) { @@ -96,6 +100,7 @@ const uint8_t *FCanvasTexture::GetPixels (FRenderStyle style) return Pixels; } +#if 0 const uint32_t *FCanvasTexture::GetPixelsBgra() { bNeedsUpdate = true; @@ -105,6 +110,7 @@ const uint32_t *FCanvasTexture::GetPixelsBgra() } return PixelsBgra; } +#endif void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical. { diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index beb25e6d0..cb12f9ba5 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -164,7 +164,7 @@ public: protected: uint8_t *Pixels; - FSoftwareTextureSpan **Spans; + //FSoftwareTextureSpan **Spans; int DefinitionLump; struct TexPart @@ -199,8 +199,6 @@ protected: // The getters must optionally redirect if it's a simple one-patch texture. const uint8_t *GetPixels(FRenderStyle style) override { return bRedirect ? Parts->Texture->GetPixels(style) : FWorldTexture::GetPixels(style); } - const uint8_t *GetColumn(FRenderStyle style, unsigned int col, const FSoftwareTextureSpan **out) override - { return bRedirect ? Parts->Texture->GetColumn(style, col, out) : FWorldTexture::GetColumn(style, col, out); } private: @@ -215,7 +213,7 @@ private: //========================================================================== FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum) -: Pixels (0), Spans(0), Parts(nullptr), Inits(nullptr), bRedirect(false), bTranslucentPatches(false) +: Pixels (0), Parts(nullptr), Inits(nullptr), bRedirect(false), bTranslucentPatches(false) { union { @@ -1065,7 +1063,7 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init) //========================================================================== FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype) -: Pixels (0), Spans(0), Parts(0), bRedirect(false), bTranslucentPatches(false) +: Pixels (0), Parts(0), bRedirect(false), bTranslucentPatches(false) { TArray parts; TArray inits; diff --git a/src/textures/formats/warptexture.cpp b/src/textures/formats/warptexture.cpp index 88a761ba0..a19c5b284 100644 --- a/src/textures/formats/warptexture.cpp +++ b/src/textures/formats/warptexture.cpp @@ -59,7 +59,7 @@ void FWarpTexture::Unload () { SourcePic->Unload (); FWorldTexture::Unload(); - FreeAllSpans(); + //FreeAllSpans(); } bool FWarpTexture::CheckModified (FRenderStyle style) @@ -67,6 +67,7 @@ bool FWarpTexture::CheckModified (FRenderStyle style) return screen->FrameTime != GenTime[!!(style.Flags & STYLEF_RedIsAlpha)]; } +/* const uint32_t *FWarpTexture::GetPixelsBgra() { auto Pixels = GetPixels(DefaultRenderStyle()); @@ -85,6 +86,7 @@ const uint32_t *FWarpTexture::GetPixelsBgra() } return PixelsBgra.data(); } +*/ uint8_t *FWarpTexture::MakeTexture(FRenderStyle style) @@ -93,7 +95,7 @@ uint8_t *FWarpTexture::MakeTexture(FRenderStyle style) const uint8_t *otherpix = SourcePic->GetPixels(style); auto Pixels = new uint8_t[Width * Height]; WarpBuffer(Pixels, otherpix, Width, Height, WidthOffsetMultiplier, HeightOffsetMultiplier, time, Speed, bWarped); - FreeAllSpans(); + //FreeAllSpans(); GenTime[!!(style.Flags & STYLEF_RedIsAlpha)] = time; return Pixels; } diff --git a/src/textures/formats/worldtexture.cpp b/src/textures/formats/worldtexture.cpp index d0b91c3a6..e409ae512 100644 --- a/src/textures/formats/worldtexture.cpp +++ b/src/textures/formats/worldtexture.cpp @@ -56,25 +56,6 @@ FWorldTexture::FWorldTexture(const char *name, int lumpnum) FWorldTexture::~FWorldTexture() { Unload(); - FreeAllSpans(); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FWorldTexture::FreeAllSpans() -{ - for(int i = 0; i < 2; i++) - { - if (Spandata[i] != nullptr) - { - FreeSpans (Spandata[i]); - Spandata[i] = nullptr; - } - } } //========================================================================== @@ -102,38 +83,6 @@ void FWorldTexture::Unload () // //========================================================================== -const uint8_t *FWorldTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) -{ - int index = !!(style.Flags & STYLEF_RedIsAlpha); - GetPixels(style); - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != nullptr) - { - if (Spandata[index] == nullptr) - { - Spandata[index] = CreateSpans (Pixeldata[index]); - } - *spans_out = Spandata[index][column]; - } - return Pixeldata[index] + column*Height; -} - -//========================================================================== -// -// -// -//========================================================================== - const uint8_t *FWorldTexture::GetPixels (FRenderStyle style) { if (CheckModified(style)) diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index bcaa1c801..9cc1baa4b 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -53,18 +53,6 @@ FSkyBox::~FSkyBox() // The faces are only referenced but not owned so don't delete them. } -//----------------------------------------------------------------------------- -// -// If something attempts to use this as a texture just pass the information of the first face. -// -//----------------------------------------------------------------------------- - -const uint8_t *FSkyBox::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) -{ - if (faces[0]) return faces[0]->GetColumn(style, column, spans_out); - return NULL; -} - //----------------------------------------------------------------------------- // // diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index fd07b29d6..b796d4281 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -17,7 +17,7 @@ public: FSkyBox(const char *name = nullptr); ~FSkyBox(); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); + //const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); const uint8_t *GetPixels (FRenderStyle style); int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); bool UseBasePalette(); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 8bfa3be54..ef948fc76 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -231,40 +231,6 @@ FTexture::~FTexture () void FTexture::Unload() { - PixelsBgra = std::vector(); -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint32_t *FTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) -{ - const uint32_t *pixels = GetPixelsBgra(); - if (pixels == nullptr) return nullptr; - - column %= Width; - - if (spans_out != nullptr) - GetColumn(DefaultRenderStyle(), column, spans_out); // This isn't the right way to create the spans. - return pixels + column * Height; -} - -const uint32_t *FTexture::GetPixelsBgra() -{ - if (PixelsBgra.empty() || CheckModified(DefaultRenderStyle())) - { - if (!GetColumn(DefaultRenderStyle(), 0, nullptr)) - return nullptr; - - FBitmap bitmap; - bitmap.Create(GetWidth(), GetHeight()); - CopyTrueColorPixels(&bitmap, 0, 0); - GenerateBgraFromBitmap(bitmap); - } - return PixelsBgra.data(); } //========================================================================== @@ -327,333 +293,6 @@ void FTexture::CalcBitSize () // //========================================================================== -FSoftwareTextureSpan **FTexture::CreateSpans (const uint8_t *pixels) const -{ - FSoftwareTextureSpan **spans, *span; - - if (!bMasked) - { // Texture does not have holes, so it can use a simpler span structure - spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*Width + sizeof(FSoftwareTextureSpan)*2); - span = (FSoftwareTextureSpan *)&spans[Width]; - for (int x = 0; x < Width; ++x) - { - spans[x] = span; - } - span[0].Length = Height; - span[0].TopOffset = 0; - span[1].Length = 0; - span[1].TopOffset = 0; - } - else - { // Texture might have holes, so build a complete span structure - int numcols = Width; - int numrows = Height; - int numspans = numcols; // One span to terminate each column - const uint8_t *data_p; - bool newspan; - int x, y; - - data_p = pixels; - - // Count the number of spans in this texture - for (x = numcols; x > 0; --x) - { - newspan = true; - for (y = numrows; y > 0; --y) - { - - if (*data_p++ == 0) - { - if (!newspan) - { - newspan = true; - } - } - else if (newspan) - { - newspan = false; - numspans++; - } - } - } - - // Allocate space for the spans - spans = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*numcols + sizeof(FSoftwareTextureSpan)*numspans); - - // Fill in the spans - for (x = 0, span = (FSoftwareTextureSpan *)&spans[numcols], data_p = pixels; x < numcols; ++x) - { - newspan = true; - spans[x] = span; - for (y = 0; y < numrows; ++y) - { - if (*data_p++ == 0) - { - if (!newspan) - { - newspan = true; - span++; - } - } - else - { - if (newspan) - { - newspan = false; - span->TopOffset = y; - span->Length = 1; - } - else - { - span->Length++; - } - } - } - if (!newspan) - { - span++; - } - span->TopOffset = 0; - span->Length = 0; - span++; - } - } - return spans; -} - -void FTexture::FreeSpans (FSoftwareTextureSpan **spans) const -{ - M_Free (spans); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FTexture::GenerateBgraFromBitmap(const FBitmap &bitmap) -{ - CreatePixelsBgraWithMipmaps(); - - // Transpose - const uint32_t *src = (const uint32_t *)bitmap.GetPixels(); - uint32_t *dest = PixelsBgra.data(); - for (int x = 0; x < Width; x++) - { - for (int y = 0; y < Height; y++) - { - dest[y + x * Height] = src[x + y * Width]; - } - } - - GenerateBgraMipmaps(); -} - -void FTexture::CreatePixelsBgraWithMipmaps() -{ - int levels = MipmapLevels(); - int buffersize = 0; - for (int i = 0; i < levels; i++) - { - int w = MAX(Width >> i, 1); - int h = MAX(Height >> i, 1); - buffersize += w * h; - } - PixelsBgra.resize(buffersize, 0xffff0000); -} - -int FTexture::MipmapLevels() const -{ - int widthbits = 0; - while ((Width >> widthbits) != 0) widthbits++; - - int heightbits = 0; - while ((Height >> heightbits) != 0) heightbits++; - - return MAX(widthbits, heightbits); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FTexture::GenerateBgraMipmaps() -{ - struct Color4f - { - float a, r, g, b; - Color4f operator*(const Color4f &v) const { return Color4f{ a * v.a, r * v.r, g * v.g, b * v.b }; } - Color4f operator/(const Color4f &v) const { return Color4f{ a / v.a, r / v.r, g / v.g, b / v.b }; } - Color4f operator+(const Color4f &v) const { return Color4f{ a + v.a, r + v.r, g + v.g, b + v.b }; } - Color4f operator-(const Color4f &v) const { return Color4f{ a - v.a, r - v.r, g - v.g, b - v.b }; } - Color4f operator*(float s) const { return Color4f{ a * s, r * s, g * s, b * s }; } - Color4f operator/(float s) const { return Color4f{ a / s, r / s, g / s, b / s }; } - Color4f operator+(float s) const { return Color4f{ a + s, r + s, g + s, b + s }; } - Color4f operator-(float s) const { return Color4f{ a - s, r - s, g - s, b - s }; } - }; - - int levels = MipmapLevels(); - std::vector image(PixelsBgra.size()); - - // Convert to normalized linear colorspace - { - for (int x = 0; x < Width; x++) - { - for (int y = 0; y < Height; y++) - { - uint32_t c8 = PixelsBgra[x * Height + y]; - Color4f c; - c.a = powf(APART(c8) * (1.0f / 255.0f), 2.2f); - c.r = powf(RPART(c8) * (1.0f / 255.0f), 2.2f); - c.g = powf(GPART(c8) * (1.0f / 255.0f), 2.2f); - c.b = powf(BPART(c8) * (1.0f / 255.0f), 2.2f); - image[x * Height + y] = c; - } - } - } - - // Generate mipmaps - { - std::vector smoothed(Width * Height); - Color4f *src = image.data(); - Color4f *dest = src + Width * Height; - for (int i = 1; i < levels; i++) - { - int srcw = MAX(Width >> (i - 1), 1); - int srch = MAX(Height >> (i - 1), 1); - int w = MAX(Width >> i, 1); - int h = MAX(Height >> i, 1); - - // Downscale - for (int x = 0; x < w; x++) - { - int sx0 = x * 2; - int sx1 = MIN((x + 1) * 2, srcw - 1); - for (int y = 0; y < h; y++) - { - int sy0 = y * 2; - int sy1 = MIN((y + 1) * 2, srch - 1); - - Color4f src00 = src[sy0 + sx0 * srch]; - Color4f src01 = src[sy1 + sx0 * srch]; - Color4f src10 = src[sy0 + sx1 * srch]; - Color4f src11 = src[sy1 + sx1 * srch]; - Color4f c = (src00 + src01 + src10 + src11) * 0.25f; - - dest[y + x * h] = c; - } - } - - // Sharpen filter with a 3x3 kernel: - for (int x = 0; x < w; x++) - { - for (int y = 0; y < h; y++) - { - Color4f c = { 0.0f, 0.0f, 0.0f, 0.0f }; - for (int kx = -1; kx < 2; kx++) - { - for (int ky = -1; ky < 2; ky++) - { - int a = y + ky; - int b = x + kx; - if (a < 0) a = h - 1; - if (a == h) a = 0; - if (b < 0) b = w - 1; - if (b == w) b = 0; - c = c + dest[a + b * h]; - } - } - c = c * (1.0f / 9.0f); - smoothed[y + x * h] = c; - } - } - float k = 0.08f; - for (int j = 0; j < w * h; j++) - dest[j] = dest[j] + (dest[j] - smoothed[j]) * k; - - src = dest; - dest += w * h; - } - } - - // Convert to bgra8 sRGB colorspace - { - Color4f *src = image.data() + Width * Height; - uint32_t *dest = PixelsBgra.data() + Width * Height; - for (int i = 1; i < levels; i++) - { - int w = MAX(Width >> i, 1); - int h = MAX(Height >> i, 1); - for (int j = 0; j < w * h; j++) - { - uint32_t a = (uint32_t)clamp(powf(MAX(src[j].a, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f); - uint32_t r = (uint32_t)clamp(powf(MAX(src[j].r, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f); - uint32_t g = (uint32_t)clamp(powf(MAX(src[j].g, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f); - uint32_t b = (uint32_t)clamp(powf(MAX(src[j].b, 0.0f), 1.0f / 2.2f) * 255.0f + 0.5f, 0.0f, 255.0f); - dest[j] = (a << 24) | (r << 16) | (g << 8) | b; - } - src += w * h; - dest += w * h; - } - } -} - -//========================================================================== -// -// -// -//========================================================================== - -void FTexture::GenerateBgraMipmapsFast() -{ - uint32_t *src = PixelsBgra.data(); - uint32_t *dest = src + Width * Height; - int levels = MipmapLevels(); - for (int i = 1; i < levels; i++) - { - int srcw = MAX(Width >> (i - 1), 1); - int srch = MAX(Height >> (i - 1), 1); - int w = MAX(Width >> i, 1); - int h = MAX(Height >> i, 1); - - for (int x = 0; x < w; x++) - { - int sx0 = x * 2; - int sx1 = MIN((x + 1) * 2, srcw - 1); - - for (int y = 0; y < h; y++) - { - int sy0 = y * 2; - int sy1 = MIN((y + 1) * 2, srch - 1); - - uint32_t src00 = src[sy0 + sx0 * srch]; - uint32_t src01 = src[sy1 + sx0 * srch]; - uint32_t src10 = src[sy0 + sx1 * srch]; - uint32_t src11 = src[sy1 + sx1 * srch]; - - uint32_t alpha = (APART(src00) + APART(src01) + APART(src10) + APART(src11) + 2) / 4; - uint32_t red = (RPART(src00) + RPART(src01) + RPART(src10) + RPART(src11) + 2) / 4; - uint32_t green = (GPART(src00) + GPART(src01) + GPART(src10) + GPART(src11) + 2) / 4; - uint32_t blue = (BPART(src00) + BPART(src01) + BPART(src10) + BPART(src11) + 2) / 4; - - dest[y + x * h] = (alpha << 24) | (red << 16) | (green << 8) | blue; - } - } - - src = dest; - dest += w * h; - } -} - -//========================================================================== -// -// -// -//========================================================================== - void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style) { const uint8_t *pixels = GetPixels(style); @@ -1454,11 +1093,6 @@ void FTexture::SetSpriteAdjust() // //=========================================================================== -const uint8_t *FTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) -{ - return nullptr; -} - const uint8_t *FTexture::GetPixels(FRenderStyle style) { return nullptr; diff --git a/src/textures/textures.h b/src/textures/textures.h index 1e8885ceb..b703e00f5 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -214,12 +214,6 @@ enum FTextureFormat : uint32_t class FSoftwareTexture; class FGLRenderState; -struct FSoftwareTextureSpan -{ - uint16_t TopOffset; - uint16_t Length; // A length of 0 terminates this column -}; - struct spriteframewithrotate; class FSerializer; namespace OpenGLRenderer @@ -388,19 +382,9 @@ protected: int shaderindex = 0; - - // Returns a single column of the texture - virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); - - // Returns a single column of the texture, in BGRA8 format - virtual const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out); - // Returns the whole texture, stored in column-major order virtual const uint8_t *GetPixels(FRenderStyle style); - // Returns the whole texture, stored in column-major order, in BGRA8 format - virtual const uint32_t *GetPixelsBgra(); - // Returns true if GetPixelsBgra includes mipmaps virtual bool Mipmapped() { return true; } @@ -535,8 +519,6 @@ protected: FTexture (const char *name = NULL, int lumpnum = -1); - FSoftwareTextureSpan **CreateSpans (const uint8_t *pixels) const; - void FreeSpans (FSoftwareTextureSpan **spans) const; void CalcBitSize (); void CopyInfo(FTexture *other) { @@ -545,13 +527,6 @@ protected: Rotations = other->Rotations; } - std::vector PixelsBgra; - - void GenerateBgraFromBitmap(const FBitmap &bitmap); - void CreatePixelsBgraWithMipmaps(); - void GenerateBgraMipmaps(); - void GenerateBgraMipmapsFast(); - int MipmapLevels() const; public: @@ -577,112 +552,6 @@ public: friend class FTextureManager; }; -// For now this is just a minimal wrapper around FTexture. Once the software renderer no longer accesses FTexture directly, it is time for cleaning up. -class FSoftwareTexture -{ - FTexture *mTexture; - - -public: - FSoftwareTexture(FTexture *tex) - { - mTexture = tex; - } - - FTexture *GetTexture() const - { - return mTexture; - } - - // The feature from hell... :( - bool useWorldPanning() const - { - return mTexture->bWorldPanning; - } - - bool isMasked() - { - return mTexture->bMasked; - } - - bool UseBasePalette() const { return mTexture->UseBasePalette(); } - int GetSkyOffset() const { return mTexture->GetSkyOffset(); } - PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); } - - int GetWidth () { return mTexture->GetWidth(); } - int GetHeight () { return mTexture->GetHeight(); } - int GetWidthBits() { return mTexture->WidthBits; } - int GetHeightBits() { return mTexture->HeightBits; } - bool Mipmapped() { return mTexture->Mipmapped(); } - - int GetScaledWidth () { return mTexture->GetScaledWidth(); } - int GetScaledHeight () { return mTexture->GetScaledHeight(); } - double GetScaledWidthDouble () { return mTexture->GetScaledWidthDouble(); } - double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); } - double GetScaleY() const { return mTexture->GetScaleY(); } - - // Now with improved offset adjustment. - int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted); } - int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted); } - int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted); } - int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted); } - double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted); } - double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted); } - - // Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets - // should use these, so that if changes are needed, this is the only place to edit. - - // For the original software renderer - int GetLeftOffsetSW() { return GetLeftOffset(r_spriteadjustSW); } - int GetTopOffsetSW() { return GetTopOffset(r_spriteadjustSW); } - int GetScaledLeftOffsetSW() { return GetScaledLeftOffset(r_spriteadjustSW); } - int GetScaledTopOffsetSW() { return GetScaledTopOffset(r_spriteadjustSW); } - - // For the softpoly renderer, in case it wants adjustment - int GetLeftOffsetPo() { return GetLeftOffset(r_spriteadjustSW); } - int GetTopOffsetPo() { return GetTopOffset(r_spriteadjustSW); } - int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); } - int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); } - - DVector2 GetScale() const { return mTexture->Scale; } - - // Returns a single column of the texture - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) - { - return mTexture->GetColumn(style, column, spans_out); - } - - // Returns a single column of the texture, in BGRA8 format - const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) - { - return mTexture->GetColumnBgra(column, spans_out); - } - - // Returns the whole texture, stored in column-major order - const uint8_t *GetPixels(FRenderStyle style) - { - return mTexture->GetPixels(style); - } - - // Returns the whole texture, stored in column-major order, in BGRA8 format - const uint32_t *GetPixelsBgra() - { - return mTexture->GetPixelsBgra(); - } - - void Unload() - { - mTexture->Unload(); - } - -}; - - -inline FSoftwareTexture *FTexture::GetSoftwareTexture() -{ - if (!SoftwareTexture) SoftwareTexture = new FSoftwareTexture(this); - return SoftwareTexture; -} class FxAddSub; // Texture manager @@ -883,17 +752,14 @@ class FWorldTexture : public FTexture { protected: uint8_t *Pixeldata[2] = { nullptr, nullptr }; - FSoftwareTextureSpan **Spandata[2] = { nullptr, nullptr }; uint8_t PixelsAreStatic = 0; // can be set by subclasses which provide static pixel buffers. FWorldTexture(const char *name = nullptr, int lumpnum = -1); ~FWorldTexture(); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) override; - const uint8_t *GetPixels(FRenderStyle style) override; void Unload() override; + const uint8_t *GetPixels(FRenderStyle style) override; virtual uint8_t *MakeTexture(FRenderStyle style) = 0; - void FreeAllSpans(); }; // A texture that doesn't really exist @@ -914,7 +780,7 @@ public: virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL) override; virtual int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf = NULL) override; - const uint32_t *GetPixelsBgra() override; + //const uint32_t *GetPixelsBgra() override; bool CheckModified (FRenderStyle) override; float GetSpeed() const { return Speed; } @@ -943,9 +809,10 @@ public: FCanvasTexture (const char *name, int width, int height); ~FCanvasTexture (); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); + //const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); + //const uint32_t *GetPixelsBgra() override; + const uint8_t *GetPixels (FRenderStyle style); - const uint32_t *GetPixelsBgra() override; void Unload (); bool CheckModified (FRenderStyle) override; void NeedUpdate() { bNeedsUpdate=true; } @@ -962,7 +829,7 @@ protected: DCanvas *CanvasBgra = nullptr; uint8_t *Pixels = nullptr; uint32_t *PixelsBgra = nullptr; - FSoftwareTextureSpan DummySpans[2]; + //FSoftwareTextureSpan DummySpans[2]; bool bNeedsUpdate = true; bool bDidUpdate = false; bool bPixelsAllocated = false; diff --git a/src/v_font.cpp b/src/v_font.cpp index b863e4256..82b2ed19d 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -171,7 +171,6 @@ class FFontChar1 : public FTexture { public: FFontChar1 (FTexture *sourcelump); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); const uint8_t *GetPixels (FRenderStyle style); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); @@ -192,7 +191,6 @@ public: FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); ~FFontChar2 (); - const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); const uint8_t *GetPixels (FRenderStyle style); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); @@ -201,7 +199,6 @@ protected: int SourceLump; int SourcePos; uint8_t *Pixels; - FSoftwareTextureSpan **Spans; const uint8_t *SourceRemap; void MakeTexture (); @@ -1607,23 +1604,6 @@ void FFontChar1::MakeTexture () } } -//========================================================================== -// -// FFontChar1 :: GetColumn -// -//========================================================================== - -const uint8_t *FFontChar1::GetColumn(FRenderStyle, unsigned int column, const FSoftwareTextureSpan **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - - BaseTexture->GetColumn(DefaultRenderStyle(), column, spans_out); - return Pixels + column*Height; -} - //========================================================================== // // FFontChar1 :: SetSourceRemap @@ -1672,7 +1652,7 @@ FFontChar1::~FFontChar1 () //========================================================================== FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs) -: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), Spans (0), SourceRemap(NULL) +: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), SourceRemap(NULL) { UseType = ETextureType::FontChar; Width = width; @@ -1691,11 +1671,6 @@ FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, in FFontChar2::~FFontChar2 () { Unload (); - if (Spans != NULL) - { - FreeSpans (Spans); - Spans = NULL; - } } //========================================================================== @@ -1731,33 +1706,6 @@ const uint8_t *FFontChar2::GetPixels (FRenderStyle) return Pixels; } -//========================================================================== -// -// FFontChar2 :: GetColumn -// -//========================================================================== - -const uint8_t *FFontChar2::GetColumn(FRenderStyle, unsigned int column, const FSoftwareTextureSpan **spans_out) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - if (column >= Width) - { - column = WidthMask; - } - if (spans_out != NULL) - { - if (Spans == NULL) - { - Spans = CreateSpans (Pixels); - } - *spans_out = Spans[column]; - } - return Pixels + column*Height; -} - //========================================================================== // // FFontChar2 :: SetSourceRemap From 18c1a3abe5f7c9ca48d7f14af30492b500861b56 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 00:58:37 +0100 Subject: [PATCH 06/66] - make the FWarpTexture class local to the software renderer. This class has only meaning for software-based warping so it doesn't have to be a part of the FTexture hierarchy. Making it a subclass of FSoftwareTexture is fully sufficient. --- src/CMakeLists.txt | 2 +- src/hwrenderer/textures/hw_material.cpp | 1 - src/swrenderer/line/r_line.cpp | 1 + src/swrenderer/textures/r_swtexture.cpp | 2 +- src/swrenderer/textures/r_swtexture.h | 38 +++++++++- src/{ => swrenderer}/textures/warpbuffer.h | 0 .../textures}/warptexture.cpp | 70 +++++-------------- src/textures/animations.cpp | 8 +-- src/textures/formats/worldtexture.cpp | 4 -- src/textures/texture.cpp | 6 -- src/textures/textures.h | 37 +--------- 11 files changed, 64 insertions(+), 105 deletions(-) rename src/{ => swrenderer}/textures/warpbuffer.h (100%) rename src/{textures/formats => swrenderer/textures}/warptexture.cpp (63%) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2a0d2a413..035e2016c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1118,7 +1118,6 @@ set (PCH_SOURCES textures/formats/shadertexture.cpp textures/formats/tgatexture.cpp textures/formats/worldtexture.cpp - textures/formats/warptexture.cpp textures/hires/hqresize.cpp textures/hires/hirestex.cpp xlat/parse_xlat.cpp @@ -1246,6 +1245,7 @@ set (PCH_SOURCES sound/wildmidi/wildmidi_lib.cpp sound/wildmidi/wm_error.cpp swrenderer/textures/r_swtexture.cpp + swrenderer/textures/warptexture.cpp events.cpp ) diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 6f0e3eeca..530be9458 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -167,7 +167,6 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) else if (tx->isWarped()) { mShaderIndex = tx->isWarped(); // This picks SHADER_Warp1 or SHADER_Warp2 - tx->shaderspeed = static_cast(tx)->GetSpeed(); } else if (tx->isHardwareCanvas()) { diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index ddb291c36..f77971a28 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -941,6 +941,7 @@ namespace swrenderer FTexture *tex = TexMan(sidedef->GetTexture(side_t::bottom), true);; mBottomPart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; + if (!mBottomPart.Texture) return; mBottomPart.TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::bottom)); double rowoffset = sidedef->GetTextureYOffset(side_t::bottom); diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index 8a389f44a..67a48beef 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -61,7 +61,7 @@ const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoft const uint32_t *FSoftwareTexture::GetPixelsBgra() { - if (PixelsBgra.empty() || mTexture->CheckModified(DefaultRenderStyle())) + if (PixelsBgra.empty() || CheckModified(DefaultRenderStyle())) { if (!GetColumn(DefaultRenderStyle(), 0, nullptr)) return nullptr; diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index a6aaa02bb..3d350e9c5 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -12,8 +12,10 @@ struct FSoftwareTextureSpan // For now this is just a minimal wrapper around FTexture. Once the software renderer no longer accesses FTexture directly, it is time for cleaning up. class FSoftwareTexture { +protected: FTexture *mTexture; FTexture *mSource; + uint8_t *Pixels[2]; std::vector PixelsBgra; FSoftwareTextureSpan **Spandata[2] = { nullptr, nullptr }; @@ -88,7 +90,7 @@ public: DVector2 GetScale() const { return mTexture->Scale; } // Returns the whole texture, stored in column-major order - const uint8_t *GetPixels(FRenderStyle style) + virtual const uint8_t *GetPixels(FRenderStyle style) { return mTexture->GetPixels(style); } @@ -98,6 +100,11 @@ public: mTexture->Unload(); PixelsBgra = std::vector(); } + + // Returns true if the next call to GetPixels() will return an image different from the + // last call to GetPixels(). This should be considered valid only if a call to CheckModified() + // is immediately followed by a call to GetPixels(). + virtual bool CheckModified (FRenderStyle style) { return false; } void GenerateBgraFromBitmap(const FBitmap &bitmap); void CreatePixelsBgraWithMipmaps(); @@ -121,9 +128,36 @@ public: }; +// A texture that returns a wiggly version of another texture. +class FWarpTexture : public FSoftwareTexture +{ + TArray WarpedPixels[2]; + int bWarped = 0; +public: + FWarpTexture (FTexture *source, int warptype); + + const uint32_t *GetPixelsBgra() override; + bool CheckModified (FRenderStyle) override; + + float GetSpeed() const { return mTexture->shaderspeed; } + + uint64_t GenTime[2] = { 0, 0 }; + uint64_t GenTimeBgra = 0; + int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd] +protected: + + const uint8_t *GetPixels(FRenderStyle style); + int NextPo2 (int v); // [mxd] + void SetupMultipliers (int width, int height); // [mxd] +}; + inline FSoftwareTexture *FTexture::GetSoftwareTexture() { - if (!SoftwareTexture) SoftwareTexture = new FSoftwareTexture(this); + if (!SoftwareTexture) + { + if (bWarped) SoftwareTexture = new FWarpTexture(this, bWarped); + else SoftwareTexture = new FSoftwareTexture(this); + } return SoftwareTexture; } diff --git a/src/textures/warpbuffer.h b/src/swrenderer/textures/warpbuffer.h similarity index 100% rename from src/textures/warpbuffer.h rename to src/swrenderer/textures/warpbuffer.h diff --git a/src/textures/formats/warptexture.cpp b/src/swrenderer/textures/warptexture.cpp similarity index 63% rename from src/textures/formats/warptexture.cpp rename to src/swrenderer/textures/warptexture.cpp index a19c5b284..41f563ed4 100644 --- a/src/textures/formats/warptexture.cpp +++ b/src/swrenderer/textures/warptexture.cpp @@ -4,6 +4,7 @@ ** **--------------------------------------------------------------------------- ** Copyright 2004-2006 Randy Heit +** Copyright 2006-2018 Christoph Oelckers ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -35,46 +36,31 @@ #include "doomtype.h" #include "r_utility.h" -#include "textures/textures.h" +#include "r_swtexture.h" #include "warpbuffer.h" #include "v_video.h" FWarpTexture::FWarpTexture (FTexture *source, int warptype) - : SourcePic (source) + : FSoftwareTexture (source) { - CopyInfo(source); if (warptype == 2) SetupMultipliers(256, 128); SetupMultipliers(128, 128); // [mxd] bWarped = warptype; } -FWarpTexture::~FWarpTexture () -{ - Unload (); - delete SourcePic; -} - -void FWarpTexture::Unload () -{ - SourcePic->Unload (); - FWorldTexture::Unload(); - //FreeAllSpans(); -} - bool FWarpTexture::CheckModified (FRenderStyle style) { return screen->FrameTime != GenTime[!!(style.Flags & STYLEF_RedIsAlpha)]; } -/* const uint32_t *FWarpTexture::GetPixelsBgra() { auto Pixels = GetPixels(DefaultRenderStyle()); if (PixelsBgra.empty() || GenTime[0] != GenTimeBgra) { CreatePixelsBgraWithMipmaps(); - for (int i = 0; i < Width * Height; i++) + for (int i = 0; i < GetWidth() * GetHeight(); i++) { if (Pixels[i] != 0) PixelsBgra[i] = 0xff000000 | GPalette.BaseColors[Pixels[i]].d; @@ -86,18 +72,21 @@ const uint32_t *FWarpTexture::GetPixelsBgra() } return PixelsBgra.data(); } -*/ -uint8_t *FWarpTexture::MakeTexture(FRenderStyle style) +const uint8_t *FWarpTexture::GetPixels(FRenderStyle style) { + int index = !!(style.Flags & STYLEF_RedIsAlpha); uint64_t time = screen->FrameTime; - const uint8_t *otherpix = SourcePic->GetPixels(style); - auto Pixels = new uint8_t[Width * Height]; - WarpBuffer(Pixels, otherpix, Width, Height, WidthOffsetMultiplier, HeightOffsetMultiplier, time, Speed, bWarped); - //FreeAllSpans(); - GenTime[!!(style.Flags & STYLEF_RedIsAlpha)] = time; - return Pixels; + if (time != GenTime[index]) + { + const uint8_t *otherpix = FSoftwareTexture::GetPixels(style); + WarpedPixels[index].Resize(GetWidth() * GetHeight()); + WarpBuffer(WarpedPixels[index].Data(), otherpix, GetWidth(), GetHeight(), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->shaderspeed, bWarped); + FreeAllSpans(); + GenTime[index] = time; + } + return WarpedPixels[index].Data(); } // [mxd] Non power of 2 textures need different offset multipliers, otherwise warp animation won't sync across texture @@ -105,10 +94,10 @@ void FWarpTexture::SetupMultipliers (int width, int height) { WidthOffsetMultiplier = width; HeightOffsetMultiplier = height; - int widthpo2 = NextPo2(Width); - int heightpo2 = NextPo2(Height); - if(widthpo2 != Width) WidthOffsetMultiplier = (int)(WidthOffsetMultiplier * ((float)widthpo2 / Width)); - if(heightpo2 != Height) HeightOffsetMultiplier = (int)(HeightOffsetMultiplier * ((float)heightpo2 / Height)); + int widthpo2 = NextPo2(GetWidth()); + int heightpo2 = NextPo2(GetHeight()); + if(widthpo2 != GetWidth()) WidthOffsetMultiplier = (int)(WidthOffsetMultiplier * ((float)widthpo2 / GetWidth())); + if(heightpo2 != GetHeight()) HeightOffsetMultiplier = (int)(HeightOffsetMultiplier * ((float)heightpo2 / GetHeight())); } int FWarpTexture::NextPo2 (int v) @@ -121,24 +110,3 @@ int FWarpTexture::NextPo2 (int v) v |= v >> 16; return ++v; } - -//========================================================================== -// -// FMultiPatchTexture :: CopyTrueColorPixels -// -// True color texture generation must never hit the paletted path which -// always warps the buffer. -// As a result even CopyTrueColorTranslated must be overrideen here. -// -//========================================================================== - -int FWarpTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) -{ - return SourcePic->CopyTrueColorPixels(bmp, x, y, rotate, inf); -} - -int FWarpTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf) -{ - return SourcePic->CopyTrueColorTranslated(bmp, x, y, rotate, remap, inf); -} - diff --git a/src/textures/animations.cpp b/src/textures/animations.cpp index 7ac07fb25..031a940e7 100644 --- a/src/textures/animations.cpp +++ b/src/textures/animations.cpp @@ -226,8 +226,7 @@ void FTextureManager::InitAnimated (void) // SMMU-style swirly hack? Don't apply on already-warping texture if (animspeed > 65535 && tex1 != NULL && !tex1->isWarped()) { - FTexture *warper = new FWarpTexture (tex1, 2); - ReplaceTexture (pic1, warper, false); + tex1->bWarped = 2; } // These tests were not really relevant for swirling textures, or even potentially // harmful, so they have been moved to the else block. @@ -624,13 +623,12 @@ void FTextureManager::ParseWarp(FScanner &sc) // don't warp a texture more than once if (!warper->isWarped()) { - warper = new FWarpTexture (warper, type2? 2:1); - ReplaceTexture (picnum, warper, false); + warper->bWarped = type2? 2:1; } if (sc.CheckFloat()) { - static_cast(warper)->SetSpeed(float(sc.Float)); + warper->SetSpeed(float(sc.Float)); } // No decals on warping textures, by default. diff --git a/src/textures/formats/worldtexture.cpp b/src/textures/formats/worldtexture.cpp index e409ae512..6613265fd 100644 --- a/src/textures/formats/worldtexture.cpp +++ b/src/textures/formats/worldtexture.cpp @@ -85,10 +85,6 @@ void FWorldTexture::Unload () const uint8_t *FWorldTexture::GetPixels (FRenderStyle style) { - if (CheckModified(style)) - { - Unload(); - } int index = !!(style.Flags & STYLEF_RedIsAlpha); if (Pixeldata[index] == nullptr) { diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index ef948fc76..6cfb04c19 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -45,7 +45,6 @@ #include "c_dispatch.h" #include "v_video.h" #include "m_fixed.h" -#include "textures/warpbuffer.h" #include "hwrenderer/textures/hw_material.h" #include "hwrenderer/textures/hw_ihwtexture.h" @@ -239,11 +238,6 @@ void FTexture::Unload() // //========================================================================== -bool FTexture::CheckModified (FRenderStyle) -{ - return false; -} - FTextureFormat FTexture::GetFormat() { return TEX_Pal; diff --git a/src/textures/textures.h b/src/textures/textures.h index b703e00f5..32e989afa 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -382,6 +382,7 @@ protected: int shaderindex = 0; + // Returns the whole texture, stored in column-major order virtual const uint8_t *GetPixels(FRenderStyle style); @@ -400,6 +401,7 @@ protected: // Fill the native texture buffer with pixel data for this image virtual void FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt); + void SetSpeed(float fac) { shaderspeed = fac; } int GetWidth () { return Width; } int GetHeight () { return Height; } @@ -443,11 +445,6 @@ protected: void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, int rotate, const uint8_t *translation, FRenderStyle style); - // Returns true if the next call to GetPixels() will return an image different from the - // last call to GetPixels(). This should be considered valid only if a call to CheckModified() - // is immediately followed by a call to GetPixels(). - virtual bool CheckModified (FRenderStyle style); - static void InitGrayMap(); void CopySize(FTexture *BaseTexture) @@ -770,34 +767,6 @@ public: void SetSize (int width, int height); }; -// A texture that returns a wiggly version of another texture. -class FWarpTexture : public FWorldTexture -{ -public: - FWarpTexture (FTexture *source, int warptype); - ~FWarpTexture (); - void Unload() override; - - virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL) override; - virtual int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf = NULL) override; - //const uint32_t *GetPixelsBgra() override; - bool CheckModified (FRenderStyle) override; - - float GetSpeed() const { return Speed; } - int GetSourceLump() { return SourcePic->GetSourceLump(); } - void SetSpeed(float fac) { Speed = fac; } - - uint64_t GenTime[2] = { 0, 0 }; - uint64_t GenTimeBgra = 0; - float Speed = 1.f; - int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd] -protected: - FTexture *SourcePic; - - uint8_t *MakeTexture (FRenderStyle style) override; - int NextPo2 (int v); // [mxd] - void SetupMultipliers (int width, int height); // [mxd] -}; // A texture that can be drawn to. class DCanvas; @@ -814,7 +783,7 @@ public: const uint8_t *GetPixels (FRenderStyle style); void Unload (); - bool CheckModified (FRenderStyle) override; + bool CheckModified (FRenderStyle) /*override*/; void NeedUpdate() { bNeedsUpdate=true; } void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; } DCanvas *GetCanvas() { return Canvas; } From bde3558dc21a55c0aafa2598d2bfa69dbf111b0b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 02:13:11 +0100 Subject: [PATCH 07/66] - moved the bit size variables to FSoftwareTexture They are only needed by the software rasterizer. --- src/hwrenderer/textures/hw_material.cpp | 2 +- src/r_data/models/models_voxel.cpp | 3 -- src/swrenderer/textures/r_swtexture.cpp | 52 ++++++++++++++++++---- src/swrenderer/textures/r_swtexture.h | 14 +++--- src/textures/formats/automaptexture.cpp | 1 - src/textures/formats/buildtexture.cpp | 1 - src/textures/formats/canvastexture.cpp | 34 -------------- src/textures/formats/ddstexture.cpp | 1 - src/textures/formats/emptytexture.cpp | 2 - src/textures/formats/flattexture.cpp | 2 - src/textures/formats/imgztexture.cpp | 2 - src/textures/formats/jpegtexture.cpp | 1 - src/textures/formats/multipatchtexture.cpp | 8 +--- src/textures/formats/patchtexture.cpp | 5 +-- src/textures/formats/pcxtexture.cpp | 1 - src/textures/formats/pngtexture.cpp | 1 - src/textures/formats/rawpagetexture.cpp | 3 -- src/textures/formats/shadertexture.cpp | 1 - src/textures/formats/tgatexture.cpp | 1 - src/textures/texture.cpp | 43 ++---------------- src/textures/textures.h | 11 ++--- src/v_font.cpp | 1 - 22 files changed, 61 insertions(+), 129 deletions(-) diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 530be9458..fe1cda7cf 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -160,7 +160,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) mShaderIndex = SHADER_Default; sourcetex = tex = tx; - if (tx->UseType == ETextureType::SWCanvas && tx->WidthBits == 0) + if (tx->UseType == ETextureType::SWCanvas && static_cast(tx)->GetColorFormat() == 0) { mShaderIndex = SHADER_Paletted; } diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index e25a72613..6067e2f9e 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -70,9 +70,6 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) SourceVox = vox; Width = 16; Height = 16; - WidthBits = 4; - HeightBits = 4; - WidthMask = 15; bNoCompress = true; } diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index 67a48beef..79560d5b2 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -41,6 +41,40 @@ +//========================================================================== +// +// +// +//========================================================================== + +void FSoftwareTexture::CalcBitSize () +{ + // WidthBits is rounded down, and HeightBits is rounded up + int i; + + for (i = 0; (1 << i) < GetWidth(); ++i) + { } + + WidthBits = i; + + // Having WidthBits that would allow for columns past the end of the + // texture is not allowed, even if it means the entire texture is + // not drawn. + if (GetWidth() < (1 << WidthBits)) + { + WidthBits--; + } + WidthMask = (1 << WidthBits) - 1; + + //
The minimum height is 2, because we cannot shift right 32 bits. + // Scratch that. Somebody actually made a 1x1 texture, so now we have to handle it. + for (i = 0; (1 << i) < GetHeight(); ++i) + { } + + HeightBits = i; +} + + //========================================================================== // // @@ -61,7 +95,7 @@ const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoft const uint32_t *FSoftwareTexture::GetPixelsBgra() { - if (PixelsBgra.empty() || CheckModified(DefaultRenderStyle())) + if (PixelsBgra.Size() == 0 || CheckModified(DefaultRenderStyle())) { if (!GetColumn(DefaultRenderStyle(), 0, nullptr)) return nullptr; @@ -71,7 +105,7 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra() mTexture->CopyTrueColorPixels(&bitmap, 0, 0); GenerateBgraFromBitmap(bitmap); } - return PixelsBgra.data(); + return PixelsBgra.Data(); } //========================================================================== @@ -191,7 +225,7 @@ void FSoftwareTexture::GenerateBgraFromBitmap(const FBitmap &bitmap) // Transpose const uint32_t *src = (const uint32_t *)bitmap.GetPixels(); - uint32_t *dest = PixelsBgra.data(); + uint32_t *dest = PixelsBgra.Data(); for (int x = 0; x < GetWidth(); x++) { for (int y = 0; y < GetHeight(); y++) @@ -213,7 +247,7 @@ void FSoftwareTexture::CreatePixelsBgraWithMipmaps() int h = MAX(GetHeight() >> i, 1); buffersize += w * h; } - PixelsBgra.resize(buffersize, 0xffff0000); + PixelsBgra.Resize(buffersize); } int FSoftwareTexture::MipmapLevels() @@ -249,7 +283,7 @@ void FSoftwareTexture::GenerateBgraMipmaps() }; int levels = MipmapLevels(); - std::vector image(PixelsBgra.size()); + std::vector image(PixelsBgra.Size()); // Convert to normalized linear colorspace { @@ -335,7 +369,7 @@ void FSoftwareTexture::GenerateBgraMipmaps() // Convert to bgra8 sRGB colorspace { Color4f *src = image.data() + GetWidth() * GetHeight(); - uint32_t *dest = PixelsBgra.data() + GetWidth() * GetHeight(); + uint32_t *dest = PixelsBgra.Data() + GetWidth() * GetHeight(); for (int i = 1; i < levels; i++) { int w = MAX(GetWidth() >> i, 1); @@ -362,7 +396,7 @@ void FSoftwareTexture::GenerateBgraMipmaps() void FSoftwareTexture::GenerateBgraMipmapsFast() { - uint32_t *src = PixelsBgra.data(); + uint32_t *src = PixelsBgra.Data(); uint32_t *dest = src + GetWidth() * GetHeight(); int levels = MipmapLevels(); for (int i = 1; i < levels; i++) @@ -413,9 +447,9 @@ const uint8_t *FSoftwareTexture::GetColumn(FRenderStyle style, unsigned int colu auto Pixeldata = GetPixels(style); if ((unsigned)column >= (unsigned)GetWidth()) { - if (mTexture->WidthMask + 1 == GetWidth()) + if (WidthMask + 1 == GetWidth()) { - column &= mTexture->WidthMask; + column &= WidthMask; } else { diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index 3d350e9c5..8c3e5a2f1 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -15,9 +15,11 @@ class FSoftwareTexture protected: FTexture *mTexture; FTexture *mSource; - uint8_t *Pixels[2]; - std::vector PixelsBgra; + TArray PixelsBgra; FSoftwareTextureSpan **Spandata[2] = { nullptr, nullptr }; + uint8_t WidthBits = 0, HeightBits = 0; + uint16_t WidthMask = 0; + public: @@ -25,6 +27,7 @@ public: { mTexture = tex; mSource = tex; + CalcBitSize(); } virtual ~FSoftwareTexture() @@ -48,14 +51,15 @@ public: return mTexture->bMasked; } + void CalcBitSize(); bool UseBasePalette() const { return mTexture->UseBasePalette(); } int GetSkyOffset() const { return mTexture->GetSkyOffset(); } PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); } int GetWidth () { return mTexture->GetWidth(); } int GetHeight () { return mTexture->GetHeight(); } - int GetWidthBits() { return mTexture->WidthBits; } - int GetHeightBits() { return mTexture->HeightBits; } + int GetWidthBits() { return WidthBits; } + int GetHeightBits() { return HeightBits; } bool Mipmapped() { return mTexture->Mipmapped(); } int GetScaledWidth () { return mTexture->GetScaledWidth(); } @@ -98,7 +102,7 @@ public: void Unload() { mTexture->Unload(); - PixelsBgra = std::vector(); + PixelsBgra.Reset(); } // Returns true if the next call to GetPixels() will return an image different from the diff --git a/src/textures/formats/automaptexture.cpp b/src/textures/formats/automaptexture.cpp index 4d6ddfeaf..b779da1d9 100644 --- a/src/textures/formats/automaptexture.cpp +++ b/src/textures/formats/automaptexture.cpp @@ -80,7 +80,6 @@ FAutomapTexture::FAutomapTexture (int lumpnum) { Width = 320; Height = uint16_t(Wads.LumpLength(lumpnum) / 320); - CalcBitSize (); } //========================================================================== diff --git a/src/textures/formats/buildtexture.cpp b/src/textures/formats/buildtexture.cpp index 3df85f90b..69ec03d2c 100644 --- a/src/textures/formats/buildtexture.cpp +++ b/src/textures/formats/buildtexture.cpp @@ -81,7 +81,6 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8 Height = height; _LeftOffset[1] = _LeftOffset[0] = left; _TopOffset[1] = _TopOffset[0] = top; - CalcBitSize (); Name.Format("%sBTIL%04d", pathprefix.GetChars(), tilenum); UseType = ETextureType::Override; } diff --git a/src/textures/formats/canvastexture.cpp b/src/textures/formats/canvastexture.cpp index c760d7351..eb3982702 100644 --- a/src/textures/formats/canvastexture.cpp +++ b/src/textures/formats/canvastexture.cpp @@ -41,15 +41,8 @@ FCanvasTexture::FCanvasTexture (const char *name, int width, int height) Name = name; Width = width; Height = height; - CalcBitSize (); bMasked = false; - /* - DummySpans[0].TopOffset = 0; - DummySpans[0].Length = height; - DummySpans[1].TopOffset = 0; - DummySpans[1].Length = 0; - */ UseType = ETextureType::Wall; bNeedsUpdate = true; bDidUpdate = false; @@ -63,33 +56,6 @@ FCanvasTexture::~FCanvasTexture () Unload (); } -#if 0 -const uint8_t *FCanvasTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) -{ - bNeedsUpdate = true; - if (Canvas == NULL) - { - MakeTexture (style); - } - if ((unsigned)column >= (unsigned)Width) - { - if (WidthMask + 1 == Width) - { - column &= WidthMask; - } - else - { - column %= Width; - } - } - if (spans_out != NULL) - { - *spans_out = DummySpans; - } - return Pixels + column*Height; -} -#endif - const uint8_t *FCanvasTexture::GetPixels (FRenderStyle style) { bNeedsUpdate = true; diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index c0988bec7..04f36adbb 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -292,7 +292,6 @@ FDDSTexture::FDDSTexture (FileReader &lump, int lumpnum, void *vsurfdesc) Width = uint16_t(surf->Width); Height = uint16_t(surf->Height); - CalcBitSize (); if (surf->PixelFormat.Flags & DDPF_FOURCC) { diff --git a/src/textures/formats/emptytexture.cpp b/src/textures/formats/emptytexture.cpp index 19698551f..d49cdbf09 100644 --- a/src/textures/formats/emptytexture.cpp +++ b/src/textures/formats/emptytexture.cpp @@ -81,9 +81,7 @@ FEmptyTexture::FEmptyTexture (int lumpnum) : FWorldTexture(NULL, lumpnum) { bMasked = true; - WidthBits = HeightBits = 1; Width = Height = 1; - WidthMask = 0; PixelsAreStatic = 3; } diff --git a/src/textures/formats/flattexture.cpp b/src/textures/formats/flattexture.cpp index 1d2a47e56..0e29defc1 100644 --- a/src/textures/formats/flattexture.cpp +++ b/src/textures/formats/flattexture.cpp @@ -92,9 +92,7 @@ FFlatTexture::FFlatTexture (int lumpnum) bMasked = false; bTranslucent = false; - WidthBits = HeightBits = bits; Width = Height = 1 << bits; - WidthMask = (1 << bits) - 1; } //========================================================================== diff --git a/src/textures/formats/imgztexture.cpp b/src/textures/formats/imgztexture.cpp index b01de82a6..2d0894de3 100644 --- a/src/textures/formats/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -113,7 +113,6 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 _LeftOffset[1] = _LeftOffset[0] = l; _TopOffset[1] = _TopOffset[0] = t; isalpha = _isalpha; - CalcBitSize (); } //========================================================================== @@ -132,7 +131,6 @@ uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style) int dest_adv = Height; int dest_rew = Width * Height - 1; - CalcBitSize (); auto Pixels = new uint8_t[Width*Height]; dest_p = Pixels; diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index f3f626622..56165a731 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -253,7 +253,6 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) Width = width; Height = height; - CalcBitSize (); } //========================================================================== diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index cb12f9ba5..31c8ffd21 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -254,7 +254,6 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl Width = SAFESHORT(mtexture.d->width); Height = SAFESHORT(mtexture.d->height); Name = (char *)mtexture.d->name; - CalcBitSize (); Scale.X = mtexture.d->ScaleX ? mtexture.d->ScaleX / 8. : 1.; Scale.Y = mtexture.d->ScaleY ? mtexture.d->ScaleY / 8. : 1.; @@ -400,9 +399,7 @@ uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork) uint8_t *FMultiPatchTexture::MakeTexture (FRenderStyle style) { - // Add a little extra space at the end if the texture's height is not - // a power of 2, in case somebody accidentally makes it repeat vertically. - int numpix = Width * Height + (1 << HeightBits) - Height; + int numpix = Width * Height; uint8_t blendwork[256]; bool buildrgb = bComplex; @@ -620,7 +617,6 @@ void FMultiPatchTexture::CheckForHacks () Height == 128) { Height = 200; - HeightBits = 8; return; } @@ -1220,8 +1216,6 @@ FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype) Printf("Texture %s has invalid dimensions (%d, %d)\n", Name.GetChars(), Width, Height); Width = Height = 1; } - CalcBitSize (); - sc.SetCMode(false); } diff --git a/src/textures/formats/patchtexture.cpp b/src/textures/formats/patchtexture.cpp index 2fe928b05..ed6630ffb 100644 --- a/src/textures/formats/patchtexture.cpp +++ b/src/textures/formats/patchtexture.cpp @@ -159,7 +159,6 @@ FPatchTexture::FPatchTexture (int lumpnum, patch_t * header, bool isalphatex) _LeftOffset[1] = _LeftOffset[0] = header->leftoffset; _TopOffset[1] = _TopOffset[0] = header->topoffset; DetectBadPatches(); - CalcBitSize (); } //========================================================================== @@ -208,9 +207,7 @@ uint8_t *FPatchTexture::MakeTexture (FRenderStyle style) return Pixels; } - // Add a little extra space at the end if the texture's height is not - // a power of 2, in case somebody accidentally makes it repeat vertically. - int numpix = Width * Height + (1 << HeightBits) - Height; + int numpix = Width * Height; numspans = Width; diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index 4f7972312..f97cf03b8 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -148,7 +148,6 @@ FPCXTexture::FPCXTexture(int lumpnum, PCXHeader & hdr) bMasked = false; Width = LittleShort(hdr.xmax) - LittleShort(hdr.xmin) + 1; Height = LittleShort(hdr.ymax) - LittleShort(hdr.ymin) + 1; - CalcBitSize(); } //========================================================================== diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index bdb232c0c..2071fedf0 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -209,7 +209,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename Width = width; Height = height; - CalcBitSize (); memset(trans, 255, 256); diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index 0d42544fe..9a829acc3 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -159,9 +159,6 @@ FRawPageTexture::FRawPageTexture (int lumpnum) { Width = 320; Height = 200; - WidthBits = 8; - HeightBits = 8; - WidthMask = 255; // Special case hack for Heretic's E2 end pic. This is not going to be exposed as an editing feature because the implications would be horrible. if (Name.CompareNoCase("E2END") == 0 && gameinfo.gametype == GAME_Heretic) diff --git a/src/textures/formats/shadertexture.cpp b/src/textures/formats/shadertexture.cpp index 1b1ab5c6f..123ddd223 100644 --- a/src/textures/formats/shadertexture.cpp +++ b/src/textures/formats/shadertexture.cpp @@ -51,7 +51,6 @@ public: Name.Format("BarShader%c%c", vertical ? 'v' : 'h', reverse ? 'r' : 'f'); Width = vertical ? 2 : 256; Height = vertical ? 256 : 2; - CalcBitSize(); bMasked = false; bTranslucent = false; PixelsAreStatic = 2; // The alpha buffer is static, but if this gets used as a regular texture, a separate buffer needs to be made. diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index 36e0144ab..44bac1bfd 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -136,7 +136,6 @@ FTGATexture::FTGATexture (int lumpnum, TGAHeader * hdr) Height = hdr->height; // Alpha channel is used only for 32 bit RGBA and paletted images with RGBA palettes. bMasked = (hdr->img_desc&15)==8 && (hdr->bpp==32 || (hdr->img_type==1 && hdr->cm_size==32)); - CalcBitSize(); } //========================================================================== diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 6cfb04c19..ea5e41769 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -177,10 +177,10 @@ FTexture * FTexture::CreateTexture (const char *name, int lumpnum, ETextureType FTexture::FTexture (const char *name, int lumpnum) : - WidthBits(0), HeightBits(0), Scale(1,1), SourceLump(lumpnum), + Scale(1,1), SourceLump(lumpnum), UseType(ETextureType::Any), bNoDecals(false), bNoRemap0(false), bWorldPanning(false), bMasked(true), bAlphaTexture(false), bHasCanvas(false), bWarped(0), bComplex(false), bMultiPatch(false), bKeepAround(false), bFullNameTexture(false), - Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0), WidthMask(0) + Rotations(0xFFFF), SkyOffset(0), Width(0), Height(0) { bBrightmapChecked = false; bGlowing = false; @@ -254,39 +254,6 @@ void FTexture::SetFrontSkyLayer () // //========================================================================== -void FTexture::CalcBitSize () -{ - // WidthBits is rounded down, and HeightBits is rounded up - int i; - - for (i = 0; (1 << i) < Width; ++i) - { } - - WidthBits = i; - - // Having WidthBits that would allow for columns past the end of the - // texture is not allowed, even if it means the entire texture is - // not drawn. - if (Width < (1 << WidthBits)) - { - WidthBits--; - } - WidthMask = (1 << WidthBits) - 1; - - //
The minimum height is 2, because we cannot shift right 32 bits. - // Scratch that. Somebody actually made a 1x1 texture, so now we have to handle it. - for (i = 0; (1 << i) < Height; ++i) - { } - - HeightBits = i; -} - -//========================================================================== -// -// -// -//========================================================================== - void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style) { const uint8_t *pixels = GetPixels(style); @@ -1102,9 +1069,6 @@ FDummyTexture::FDummyTexture () { Width = 64; Height = 64; - HeightBits = 6; - WidthBits = 6; - WidthMask = 63; UseType = ETextureType::Null; } @@ -1112,7 +1076,6 @@ void FDummyTexture::SetSize (int width, int height) { Width = width; Height = height; - CalcBitSize (); } @@ -1126,7 +1089,7 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits) { Width = w; Height = h; - WidthBits = bits; + Format = bits; UseType = ETextureType::SWCanvas; bNoCompress = true; SystemTexture[0] = screen->CreateHardwareTexture(this); diff --git a/src/textures/textures.h b/src/textures/textures.h index 32e989afa..c93d79609 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -315,8 +315,6 @@ public: protected: //int16_t LeftOffset, TopOffset; - uint8_t WidthBits, HeightBits; - DVector2 Scale; int SourceLump; @@ -455,16 +453,13 @@ protected: _TopOffset[1] = BaseTexture->_TopOffset[1]; _LeftOffset[0] = BaseTexture->_LeftOffset[0]; _LeftOffset[1] = BaseTexture->_LeftOffset[1]; - WidthBits = BaseTexture->WidthBits; - HeightBits = BaseTexture->HeightBits; Scale = BaseTexture->Scale; - WidthMask = (1 << WidthBits) - 1; } void SetScaledSize(int fitwidth, int fitheight); protected: - uint16_t Width, Height, WidthMask; + uint16_t Width, Height; int16_t _LeftOffset[2], _TopOffset[2]; static uint8_t GrayMap[256]; uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false) @@ -516,7 +511,6 @@ protected: FTexture (const char *name = NULL, int lumpnum = -1); - void CalcBitSize (); void CopyInfo(FTexture *other) { CopySize(other); @@ -813,6 +807,7 @@ public: // A wrapper around a hardware texture, to allow using it in the 2D drawing interface. class FWrapperTexture : public FTexture { + int Format; public: FWrapperTexture(int w, int h, int bits = 1); IHardwareTexture *GetSystemTexture(int slot) @@ -822,7 +817,7 @@ public: int GetColorFormat() const { - return WidthBits; + return Format; } }; diff --git a/src/v_font.cpp b/src/v_font.cpp index 82b2ed19d..4985b2407 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1659,7 +1659,6 @@ FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, in Height = height; _LeftOffset[1] = _LeftOffset[0] = leftofs; _TopOffset[1] = _TopOffset[0] = topofs; - CalcBitSize (); } //========================================================================== From 3491182ac309d394331568e155584d58fb5fed99 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 02:21:39 +0100 Subject: [PATCH 08/66] - fixed compilation --- src/g_statusbar/sbarinfo.cpp | 1 - src/swrenderer/textures/warptexture.cpp | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index 34cf09c3c..aade1b1f9 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -1190,7 +1190,6 @@ public: { if (forceWidth < 0) dx -= (texture->GetDisplayWidthDouble()/2.0)-texture->GetDisplayLeftOffsetDouble(); else dx -= forceWidth*(0.5-(texture->GetDisplayLeftOffsetDouble()/texture->GetDisplayWidthDouble())); - //Unoptimalized ^^formula is dx -= forceWidth/2.0-(texture->GetScaledLeftOffsetDouble()*forceWidth/texture->GetDisplayWidthDouble()); if (forceHeight < 0) dy -= (texture->GetDisplayHeightDouble()/2.0)-texture->GetDisplayTopOffsetDouble(); else dy -= forceHeight*(0.5-(texture->GetDisplayTopOffsetDouble()/texture->GetDisplayHeightDouble())); diff --git a/src/swrenderer/textures/warptexture.cpp b/src/swrenderer/textures/warptexture.cpp index 41f563ed4..294bf694f 100644 --- a/src/swrenderer/textures/warptexture.cpp +++ b/src/swrenderer/textures/warptexture.cpp @@ -57,7 +57,7 @@ bool FWarpTexture::CheckModified (FRenderStyle style) const uint32_t *FWarpTexture::GetPixelsBgra() { auto Pixels = GetPixels(DefaultRenderStyle()); - if (PixelsBgra.empty() || GenTime[0] != GenTimeBgra) + if (PixelsBgra.Size() == 0 || GenTime[0] != GenTimeBgra) { CreatePixelsBgraWithMipmaps(); for (int i = 0; i < GetWidth() * GetHeight(); i++) @@ -70,7 +70,7 @@ const uint32_t *FWarpTexture::GetPixelsBgra() GenerateBgraMipmapsFast(); GenTimeBgra = GenTime[0]; } - return PixelsBgra.data(); + return PixelsBgra.Data(); } From 9fedecbe602989d37f05000e835dadadf7b2f26e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 02:31:30 +0100 Subject: [PATCH 09/66] Renamed FTextureManager::GetTexture to GetTextureID It doesn't return a texture after all and I want to repurpose the name for something else. --- src/c_cmds.cpp | 2 +- src/c_console.cpp | 2 +- src/fragglescript/t_func.cpp | 8 ++++---- src/fragglescript/t_load.cpp | 2 +- src/g_level.cpp | 6 +++--- src/p_acs.cpp | 8 ++++---- src/p_sectors.cpp | 8 ++++---- src/r_data/gldefs.cpp | 2 +- src/serializer.cpp | 2 +- src/textures/texture.cpp | 1 + src/textures/texturemanager.cpp | 2 +- src/textures/textures.h | 11 ++++++++--- src/wi_stuff.cpp | 2 +- 13 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index f43e77473..2aa941913 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -1052,7 +1052,7 @@ CCMD(changesky) sky1name = argv[1]; if (sky1name[0] != 0) { - FTextureID newsky = TexMan.GetTexture(sky1name, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); + FTextureID newsky = TexMan.GetTextureID(sky1name, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); if (newsky.Exists()) { sky1texture = level.skytexture1 = newsky; diff --git a/src/c_console.cpp b/src/c_console.cpp index 9a38ae1cf..b5f1a3cb2 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -555,7 +555,7 @@ void C_InitConback() if (!conback.isValid()) { - conback = TexMan.GetTexture (gameinfo.TitlePage, ETextureType::MiscPatch); + conback = TexMan.GetTextureID (gameinfo.TitlePage, ETextureType::MiscPatch); conshade = MAKEARGB(175,0,0,0); conline = true; } diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index a6fceb5c7..579201a3a 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1892,7 +1892,7 @@ void FParser::SF_FloorTexture(void) if(t_argc > 1) { int i = -1; - FTextureID picnum = TexMan.GetTexture(t_argv[1].string, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); + FTextureID picnum = TexMan.GetTextureID(t_argv[1].string, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); // set all sectors with tag FSSectorTagIterator itr(tagnum); @@ -1982,7 +1982,7 @@ void FParser::SF_CeilingTexture(void) if(t_argc > 1) { int i = -1; - FTextureID picnum = TexMan.GetTexture(t_argv[1].string, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); + FTextureID picnum = TexMan.GetTextureID(t_argv[1].string, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); // set all sectors with tag FSSectorTagIterator itr(tagnum); @@ -2235,7 +2235,7 @@ void FParser::SF_SetLineTexture(void) position=3-position; texture = stringvalue(t_argv[3]); - texturenum = TexMan.GetTexture(texture, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + texturenum = TexMan.GetTextureID(texture, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); FLineIdIterator itr(tag); while ((i = itr.Next()) >= 0) @@ -2252,7 +2252,7 @@ void FParser::SF_SetLineTexture(void) } else // and an improved legacy version { - FTextureID picnum = TexMan.GetTexture(t_argv[1].string, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + FTextureID picnum = TexMan.GetTextureID(t_argv[1].string, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); side = !!intvalue(t_argv[2]); int sections = intvalue(t_argv[3]); diff --git a/src/fragglescript/t_load.cpp b/src/fragglescript/t_load.cpp index 1d13118a8..1d5b86ce0 100644 --- a/src/fragglescript/t_load.cpp +++ b/src/fragglescript/t_load.cpp @@ -189,7 +189,7 @@ void FScriptLoader::ParseInfoCmd(char *line, FString &scriptsrc) sc.MustGetStringName("="); sc.MustGetString(); - sky2texture = sky1texture = level.skytexture1 = level.skytexture2 = TexMan.GetTexture (sc.String, ETextureType::Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); + sky2texture = sky1texture = level.skytexture1 = level.skytexture2 = TexMan.GetTextureID (sc.String, ETextureType::Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); R_InitSkyMap (); } else if (sc.Compare("interpic")) diff --git a/src/g_level.cpp b/src/g_level.cpp index fe5477bf6..873bcf97d 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -968,7 +968,7 @@ void G_DoLoadLevel (int position, bool autosave, bool newGame) // a flat. The data is in the WAD only because // we look for an actual index, instead of simply // setting one. - skyflatnum = TexMan.GetTexture (gameinfo.SkyFlatName, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); + skyflatnum = TexMan.GetTextureID (gameinfo.SkyFlatName, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); // DOOM determines the sky texture to be used // depending on the current episode and the game version. @@ -1455,8 +1455,8 @@ void G_InitLevelLocals () level.info = info; level.skyspeed1 = info->skyspeed1; level.skyspeed2 = info->skyspeed2; - level.skytexture1 = TexMan.GetTexture(info->SkyPic1, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); - level.skytexture2 = TexMan.GetTexture(info->SkyPic2, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); + level.skytexture1 = TexMan.GetTextureID(info->SkyPic1, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); + level.skytexture2 = TexMan.GetTextureID(info->SkyPic2, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_ReturnFirst); level.fadeto = info->fadeto; level.cdtrack = info->cdtrack; level.cdid = info->cdid; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 7cb94029f..708b100aa 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -3747,7 +3747,7 @@ void DLevelScript::ChangeFlat (int tag, int name, bool floorOrCeiling) if (flatname == NULL) return; - flat = TexMan.GetTexture (flatname, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); + flat = TexMan.GetTextureID(flatname, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); FSectorTagIterator it(tag); while ((secnum = it.Next()) >= 0) @@ -3779,7 +3779,7 @@ void DLevelScript::SetLineTexture (int lineid, int side, int position, int name) side = !!side; - texture = TexMan.GetTexture (texname, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + texture = TexMan.GetTextureID(texname, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); FLineIdIterator itr(lineid); while ((linenum = itr.Next()) >= 0) @@ -9865,11 +9865,11 @@ scriptwait: sky2name = FBehavior::StaticLookupString (STACK(1)); if (sky1name[0] != 0) { - sky1texture = level.skytexture1 = TexMan.GetTexture (sky1name, ETextureType::Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); + sky1texture = level.skytexture1 = TexMan.GetTextureID(sky1name, ETextureType::Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); } if (sky2name[0] != 0) { - sky2texture = level.skytexture2 = TexMan.GetTexture (sky2name, ETextureType::Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); + sky2texture = level.skytexture2 = TexMan.GetTextureID(sky2name, ETextureType::Wall, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_ReturnFirst); } R_InitSkyMap (); sp -= 2; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 56df21cba..23881740b 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -1397,8 +1397,8 @@ void P_ReplaceTextures(const char *fromname, const char *toname, int flags) if ((flags ^ (NOT_BOTTOM | NOT_MIDDLE | NOT_TOP)) != 0) { - picnum1 = TexMan.GetTexture(fromname, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); - picnum2 = TexMan.GetTexture(toname, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + picnum1 = TexMan.GetTextureID(fromname, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + picnum2 = TexMan.GetTextureID(toname, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); for (auto &side : level.sides) { @@ -1414,8 +1414,8 @@ void P_ReplaceTextures(const char *fromname, const char *toname, int flags) } if ((flags ^ (NOT_FLOOR | NOT_CEILING)) != 0) { - picnum1 = TexMan.GetTexture(fromname, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); - picnum2 = TexMan.GetTexture(toname, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); + picnum1 = TexMan.GetTextureID(fromname, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); + picnum2 = TexMan.GetTextureID(toname, ETextureType::Flat, FTextureManager::TEXMAN_Overridable); for (auto &sec : level.sectors) { diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 4f07ea48d..2baa54ec1 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -977,7 +977,7 @@ class GLDefsParser sc.MustGetString(); if (facecount<6) { - sb->faces[facecount] = TexMan[TexMan.GetTexture(sc.String, ETextureType::Wall, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_Overridable)]; + sb->faces[facecount] = TexMan[TexMan.GetTextureID(sc.String, ETextureType::Wall, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_Overridable)]; } facecount++; } diff --git a/src/serializer.cpp b/src/serializer.cpp index e0f74420f..c6a0191bf 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -1545,7 +1545,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe assert(nameval.IsString() && typeval.IsInt()); if (nameval.IsString() && typeval.IsInt()) { - value = TexMan.GetTexture(UnicodeToString(nameval.GetString()), static_cast(typeval.GetInt())); + value = TexMan.GetTextureID(UnicodeToString(nameval.GetString()), static_cast(typeval.GetInt())); } else { diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index ea5e41769..ed3eedb28 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -1211,3 +1211,4 @@ void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y) mWorldPanning = tex->bWorldPanning; mWidth = tex->GetWidth(); } + diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 6a64f4c6f..6c7a75ef9 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -329,7 +329,7 @@ int FTextureManager::ListTextures (const char *name, TArray &list, b // //========================================================================== -FTextureID FTextureManager::GetTexture (const char *name, ETextureType usetype, BITFIELD flags) +FTextureID FTextureManager::GetTextureID (const char *name, ETextureType usetype, BITFIELD flags) { FTextureID i; diff --git a/src/textures/textures.h b/src/textures/textures.h index c93d79609..2bc6cab1a 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -298,6 +298,11 @@ public: bool isFullbright() const { return bFullbright; } void CreateDefaultBrightmap(); bool FindHoles(const unsigned char * buffer, int w, int h); + uint64_t CacheID() + { + // Just a temporary placeholder. This needs to be done differently as things progress. + return (uint64_t)(intptr_t)GetRedirect(); + } public: static void FlipSquareBlock (uint8_t *block, int x, int y); @@ -562,7 +567,7 @@ public: } FTexture *operator[] (const char *texname) { - FTextureID texnum = GetTexture (texname, ETextureType::MiscPatch); + FTextureID texnum = GetTextureID (texname, ETextureType::MiscPatch); if (!texnum.Exists()) return NULL; return Textures[texnum.GetIndex()].Texture; } @@ -586,7 +591,7 @@ public: } FTexture *operator() (const char *texname) { - FTextureID texnum = GetTexture (texname, ETextureType::MiscPatch); + FTextureID texnum = GetTextureID (texname, ETextureType::MiscPatch); if (texnum.texnum == -1) return NULL; return Textures[Translation[texnum.texnum]].Texture; } @@ -621,7 +626,7 @@ public: }; FTextureID CheckForTexture (const char *name, ETextureType usetype, BITFIELD flags=TEXMAN_TryAny); - FTextureID GetTexture (const char *name, ETextureType usetype, BITFIELD flags=0); + FTextureID GetTextureID (const char *name, ETextureType usetype, BITFIELD flags=0); int ListTextures (const char *name, TArray &list, bool listall = false); void AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup=0, bool texture1=false); diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 4c3129c98..01340ce19 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -516,7 +516,7 @@ bool DInterBackground::LoadBackground(bool isenterpic) else { Printf("Intermission script %s not found!\n", lumpname + 1); - texture = TexMan.GetTexture("INTERPIC", ETextureType::MiscPatch); + texture = TexMan.GetTextureID("INTERPIC", ETextureType::MiscPatch); } } background = TexMan[texture]; From 3dc9eab74354066df3e17759fffd7cd7886cca79 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 02:43:27 +0100 Subject: [PATCH 10/66] Renamed the operator() and [] methods in FTextureManager which take a name The operators cannot be easily searched for so this makes it hard to do any evaluations on the use of this method. --- src/d_main.cpp | 11 ++++++----- src/g_statusbar/shared_sbar.cpp | 2 +- src/hu_scores.cpp | 2 +- src/p_sectors.cpp | 4 ++-- src/posix/cocoa/i_video.mm | 2 +- src/textures/textures.h | 19 ++++++++++--------- src/v_draw.cpp | 16 ++++++++-------- src/wi_stuff.cpp | 10 +++++----- 8 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index 601a5558c..39f7bd8e0 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -184,18 +184,19 @@ CVAR (Int, snd_drawoutput, 0, 0); CUSTOM_CVAR (String, vid_cursor, "None", CVAR_ARCHIVE | CVAR_NOINITCALL) { bool res = false; + if (!stricmp(self, "None" ) && gameinfo.CursorPic.IsNotEmpty()) { - res = I_SetCursor(TexMan[gameinfo.CursorPic]); + res = I_SetCursor(TexMan.GetTextureByName(gameinfo.CursorPic)); } else { - res = I_SetCursor(TexMan[self]); + res = I_SetCursor(TexMan.GetTextureByName(self)); } if (!res) { - I_SetCursor(TexMan["cursor"]); + I_SetCursor(TexMan.GetTextureByName("cursor")); } } @@ -834,7 +835,7 @@ void D_Display () int x; FString pstring = "By "; - tex = TexMan(gameinfo.PauseSign); + tex = TexMan.GetTextureByName(gameinfo.PauseSign, true); x = (SCREENWIDTH - tex->GetDisplayWidth() * CleanXfac)/2 + tex->GetDisplayLeftOffset() * CleanXfac; screen->DrawTexture (tex, x, 4, DTA_CleanNoMove, true, TAG_DONE); @@ -1241,7 +1242,7 @@ void D_DoAdvanceDemo (void) case 3: if (gameinfo.advisoryTime) { - Advisory = TexMan["ADVISOR"]; + Advisory = TexMan.GetTextureByName("ADVISOR"); demosequence = 1; pagetic = (int)(gameinfo.advisoryTime * TICRATE); break; diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index ea2db01fe..06dd1e57a 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -817,7 +817,7 @@ void DBaseStatusBar::RefreshBackground () const if (setblocks >= 10) { - FTexture *p = TexMan[gameinfo.Border.b]; + FTexture *p = TexMan.GetTextureByName(gameinfo.Border.b); if (p != NULL) { screen->FlatFill(0, y, x, y + p->GetDisplayHeight(), p, true); diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index 1fc3b9a35..435acc8f0 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -445,7 +445,7 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, if (teamplay && Teams[player->userinfo.GetTeam()].GetLogo().IsNotEmpty ()) { - FTexture *pic = TexMan[Teams[player->userinfo.GetTeam()].GetLogo().GetChars ()]; + FTexture *pic = TexMan.GetTextureByName(Teams[player->userinfo.GetTeam()].GetLogo().GetChars ()); screen->DrawTexture (pic, col1 - (pic->GetDisplayWidth() + 2) * CleanXfac, y, DTA_CleanNoMove, true, TAG_DONE); } diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 23881740b..fd323e65f 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -501,7 +501,7 @@ double FindShortestTextureAround (sector_t *sec) CheckShortestTex (check->sidedef[1]->GetTexture(side_t::bottom), minsize); } } - return minsize < FLT_MAX ? minsize : TexMan[0]->GetDisplayHeight(); + return minsize < FLT_MAX ? minsize : TexMan.ByIndex(0)->GetDisplayHeight(); } // @@ -526,7 +526,7 @@ double FindShortestUpperAround (sector_t *sec) CheckShortestTex (check->sidedef[1]->GetTexture(side_t::top), minsize); } } - return minsize < FLT_MAX ? minsize : TexMan[0]->GetDisplayHeight(); + return minsize < FLT_MAX ? minsize : TexMan.ByIndex(0)->GetDisplayHeight(); } // diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 9243cd5be..d10c590b2 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -647,7 +647,7 @@ CUSTOM_CVAR(Bool, vid_hidpi, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINI // --------------------------------------------------------------------------- -bool I_SetCursor(FTexture* cursorpic) +bool I_SetCursor(FTexture *cursorpic) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; NSCursor* cursor = nil; diff --git a/src/textures/textures.h b/src/textures/textures.h index 2bc6cab1a..e75ce0a8a 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -565,12 +565,16 @@ public: if ((unsigned)texnum.GetIndex() >= Textures.Size()) return NULL; return Textures[texnum.GetIndex()].Texture; } - FTexture *operator[] (const char *texname) + + FTexture *GetTextureByName(const char *name, bool animate = false) { - FTextureID texnum = GetTextureID (texname, ETextureType::MiscPatch); - if (!texnum.Exists()) return NULL; - return Textures[texnum.GetIndex()].Texture; + FTextureID texnum = GetTextureID (name, ETextureType::MiscPatch); + if (!texnum.Exists()) return nullptr; + if (!animate) return Textures[texnum.GetIndex()].Texture; + else return Textures[Translation[texnum.GetIndex()]].Texture; + } + FTexture *ByIndex(int i) { if (unsigned(i) >= Textures.Size()) return NULL; @@ -589,18 +593,15 @@ public: } return Textures[picnum].Texture; } + /* FTexture *operator() (const char *texname) { FTextureID texnum = GetTextureID (texname, ETextureType::MiscPatch); if (texnum.texnum == -1) return NULL; return Textures[Translation[texnum.texnum]].Texture; } + */ - FTexture *ByIndexTranslated(int i) - { - if (unsigned(i) >= Textures.Size()) return NULL; - return Textures[Translation[i]].Texture; - } //public: FTextureID PalCheck(FTextureID tex); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 36c9c921e..00c6307ef 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -1304,22 +1304,22 @@ void DFrameBuffer::DrawFrame (int left, int top, int width, int height) int bottom = top + height; // Draw top and bottom sides. - p = TexMan[border->t]; + p = TexMan.GetTextureByName(border->t); FlatFill(left, top - p->GetDisplayHeight(), right, top, p, true); - p = TexMan[border->b]; + p = TexMan.GetTextureByName(border->b); FlatFill(left, bottom, right, bottom + p->GetDisplayHeight(), p, true); // Draw left and right sides. - p = TexMan[border->l]; + p = TexMan.GetTextureByName(border->l); FlatFill(left - p->GetDisplayWidth(), top, left, bottom, p, true); - p = TexMan[border->r]; + p = TexMan.GetTextureByName(border->r); FlatFill(right, top, right + p->GetDisplayWidth(), bottom, p, true); // Draw beveled corners. - DrawTexture (TexMan[border->tl], left-offset, top-offset, TAG_DONE); - DrawTexture (TexMan[border->tr], left+width, top-offset, TAG_DONE); - DrawTexture (TexMan[border->bl], left-offset, top+height, TAG_DONE); - DrawTexture (TexMan[border->br], left+width, top+height, TAG_DONE); + DrawTexture (TexMan.GetTextureByName(border->tl), left-offset, top-offset, TAG_DONE); + DrawTexture (TexMan.GetTextureByName(border->tr), left+width, top-offset, TAG_DONE); + DrawTexture (TexMan.GetTextureByName(border->bl), left-offset, top+height, TAG_DONE); + DrawTexture (TexMan.GetTextureByName(border->br), left+width, top+height, TAG_DONE); } DEFINE_ACTION_FUNCTION(_Screen, DrawFrame) diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 01340ce19..17f6a913a 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -383,13 +383,13 @@ bool DInterBackground::LoadBackground(bool isenterpic) case 1: // Splat sc.MustGetString(); - splat = TexMan[sc.String]; + splat = TexMan.GetTextureByName(sc.String); break; case 2: // Pointers while (sc.GetString() && !sc.Crossed) { - yah.Push(TexMan[sc.String]); + yah.Push(TexMan.GetTextureByName(sc.String)); } if (sc.Crossed) sc.UnGet(); @@ -481,14 +481,14 @@ bool DInterBackground::LoadBackground(bool isenterpic) if (!sc.CheckString("{")) { sc.MustGetString(); - an.frames.Push(TexMan[sc.String]); + an.frames.Push(TexMan.GetTextureByName(sc.String)); } else { while (!sc.CheckString("}")) { sc.MustGetString(); - an.frames.Push(TexMan[sc.String]); + an.frames.Push(TexMan.GetTextureByName(sc.String)); } } an.ctr = -1; @@ -503,7 +503,7 @@ bool DInterBackground::LoadBackground(bool isenterpic) an.loc.y = sc.Number; sc.MustGetString(); an.frames.Reserve(1); // allocate exactly one element - an.frames[0] = TexMan[sc.String]; + an.frames[0] = TexMan.GetTextureByName(sc.String); anims.Push(an); break; From 79a0f7680135c815df325ea9d71a47b2d7aef5a8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 02:53:18 +0100 Subject: [PATCH 11/66] - replaced TexMan.operator() with two functions. This was done to make reviewing easier, again because it is virtually impossible to search for the operators in the code. Going through this revealed quite a few places where texture animations were on but shouldn't and even more places that did not check PASLVERS, although they were preparing some paletted rendering. --- src/am_map.cpp | 8 ++-- src/d_main.cpp | 2 +- src/g_statusbar/sbarinfo_commands.cpp | 26 ++++++------- src/g_statusbar/shared_sbar.cpp | 2 +- src/gl/shaders/gl_postprocessshader.cpp | 2 +- src/hwrenderer/scene/hw_bsp.cpp | 2 +- src/hwrenderer/scene/hw_fakeflat.cpp | 8 ++-- src/hwrenderer/scene/hw_sky.cpp | 8 ++-- src/hwrenderer/scene/hw_sprites.cpp | 2 +- src/hwrenderer/scene/hw_walls.cpp | 6 +-- src/hwrenderer/scene/hw_weapon.cpp | 2 +- src/hwrenderer/textures/hw_material.cpp | 2 +- src/intermission/intermission.cpp | 2 +- src/p_3dmidtex.cpp | 2 +- src/p_sectors.cpp | 6 +-- src/polyrenderer/scene/poly_decal.cpp | 2 +- src/polyrenderer/scene/poly_model.cpp | 2 +- src/polyrenderer/scene/poly_plane.cpp | 4 +- src/polyrenderer/scene/poly_playersprite.cpp | 2 +- src/polyrenderer/scene/poly_sky.cpp | 2 +- src/polyrenderer/scene/poly_sprite.cpp | 2 +- src/polyrenderer/scene/poly_wall.cpp | 12 +++--- src/r_data/models/models.cpp | 2 +- src/r_data/models/models_md2.cpp | 2 +- src/r_data/models/models_md3.cpp | 4 +- src/r_data/models/models_obj.cpp | 4 +- src/r_data/models/models_ue1.cpp | 2 +- src/r_sky.cpp | 4 +- src/swrenderer/line/r_line.cpp | 10 ++--- src/swrenderer/line/r_renderdrawsegment.cpp | 26 ++++++------- src/swrenderer/plane/r_skyplane.cpp | 6 +-- src/swrenderer/plane/r_visibleplane.cpp | 2 +- src/swrenderer/scene/r_opaque_pass.cpp | 2 +- src/swrenderer/things/r_decal.cpp | 2 +- src/swrenderer/things/r_model.cpp | 2 +- src/swrenderer/things/r_playersprite.cpp | 2 +- src/textures/textures.h | 41 ++++++++++---------- src/v_collection.cpp | 2 +- src/v_draw.cpp | 6 +-- src/v_font.cpp | 2 +- wadsrc/static/zscript/statusbar/alt_hud.txt | 4 +- 41 files changed, 115 insertions(+), 116 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 379c4f713..932ec42ed 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -2234,7 +2234,7 @@ void AM_drawSubsectors() } else indices.clear(); - screen->FillSimplePoly(TexMan(maptex), + screen->FillSimplePoly(TexMan.GetTexture(maptex, true), &points[0], points.Size(), originx, originy, scale / scalex, @@ -3019,7 +3019,7 @@ void AM_drawThings () rotation = int((angle.Normalized360() * (16. / 360.)).Degrees); const FTextureID textureID = frame->Texture[show > 2 ? rotation : 0]; - texture = TexMan(textureID); + texture = TexMan.GetTexture(textureID, true); } if (texture == NULL) goto drawTriangle; // fall back to standard display if no sprite can be found. @@ -3150,7 +3150,7 @@ void AM_drawMarks () { if (markpoints[i].x != -1) { - DrawMarker (TexMan(marknums[i]), markpoints[i].x, markpoints[i].y, -3, 0, + DrawMarker (TexMan.GetTexture(marknums[i], true), markpoints[i].x, markpoints[i].y, -3, 0, 1, 1, 0, 1, 0, LegacyRenderStyles[STYLE_Normal]); } } @@ -3183,7 +3183,7 @@ void AM_drawAuthorMarkers () if (mark->picnum.isValid()) { - tex = TexMan(mark->picnum); + tex = TexMan.GetTexture(mark->picnum, true); if (tex->GetRotations() != 0xFFFF) { spriteframe_t *sprframe = &SpriteFrames[tex->GetRotations()]; diff --git a/src/d_main.cpp b/src/d_main.cpp index 39f7bd8e0..3f5036831 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1052,7 +1052,7 @@ void D_PageDrawer (void) screen->Clear(0, 0, SCREENWIDTH, SCREENHEIGHT, 0, 0); if (Page.Exists()) { - screen->DrawTexture (TexMan(Page), 0, 0, + screen->DrawTexture (TexMan.GetTexture(Page, true), 0, 0, DTA_Fullscreen, true, DTA_Masked, false, DTA_BilinearFilter, true, diff --git a/src/g_statusbar/sbarinfo_commands.cpp b/src/g_statusbar/sbarinfo_commands.cpp index f605e2dc4..6094f82ea 100644 --- a/src/g_statusbar/sbarinfo_commands.cpp +++ b/src/g_statusbar/sbarinfo_commands.cpp @@ -241,7 +241,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl applyscale = false; } if(type == PLAYERICON) - texture = TexMan(statusBar->CPlayer->mo->ScoreIcon); + texture = TexMan.GetTexture(statusBar->CPlayer->mo->ScoreIcon, true); else if(type == AMMO1) { auto ammo = statusBar->ammo1; @@ -270,7 +270,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl { auto item = statusBar->CPlayer->mo->FindInventory(NAME_Sigil); if (item != NULL) - texture = TexMan(item->TextureIDVar(NAME_Icon)); + texture = TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true); } else if(type == HEXENARMOR_ARMOR || type == HEXENARMOR_SHIELD || type == HEXENARMOR_HELM || type == HEXENARMOR_AMULET) { @@ -292,9 +292,9 @@ class CommandDrawImage : public SBarInfoCommandFlowControl } } else if(type == INVENTORYICON) - texture = TexMan(sprite); + texture = TexMan.GetTexture(sprite, true); else if(type == SELECTEDINVENTORYICON && statusBar->CPlayer->mo->InvSel != NULL) - texture = TexMan(statusBar->CPlayer->mo->InvSel->TextureIDVar(NAME_Icon)); + texture = TexMan.GetTexture(statusBar->CPlayer->mo->InvSel->TextureIDVar(NAME_Icon), true); else if(image >= 0) texture = statusBar->Images[image]; @@ -316,7 +316,7 @@ class CommandDrawImage : public SBarInfoCommandFlowControl spawnScaleY = item->Scale.Y; } - texture = TexMan(icon); + texture = TexMan.GetTexture(icon, true); } enum ImageType @@ -2131,7 +2131,7 @@ class CommandDrawInventoryBar : public SBarInfoCommand statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgARTIBOX], rx, ry, block->XOffset(), block->YOffset(), bgalpha, block->FullScreenOffsets()); if(style != STYLE_Strife) //Strife draws the cursor before the icons - statusBar->DrawGraphic(TexMan(item->TextureIDVar(NAME_Icon)), rx - (style == STYLE_HexenStrict ? 2 : 0), ry - (style == STYLE_HexenStrict ? 1 : 0), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, item->IntVar(NAME_Amount) <= 0); + statusBar->DrawGraphic(TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true), rx - (style == STYLE_HexenStrict ? 2 : 0), ry - (style == STYLE_HexenStrict ? 1 : 0), block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, item->IntVar(NAME_Amount) <= 0); if(item == statusBar->CPlayer->mo->InvSel) { if(style == STYLE_Heretic) @@ -2146,7 +2146,7 @@ class CommandDrawInventoryBar : public SBarInfoCommand statusBar->DrawGraphic(statusBar->Images[statusBar->invBarOffset + imgSELECTBOX], rx, ry, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); } if(style == STYLE_Strife) - statusBar->DrawGraphic(TexMan(item->TextureIDVar(NAME_Icon)), rx, ry, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, item->IntVar(NAME_Amount) <= 0); + statusBar->DrawGraphic(TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true), rx, ry, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets(), false, item->IntVar(NAME_Amount) <= 0); if(counters != NULL && (alwaysShowCounter || item->IntVar(NAME_Amount) != 1)) { counters[i]->valueArgument = item->IntVar(NAME_Amount); @@ -2369,22 +2369,22 @@ class CommandDrawKeyBar : public SBarInfoCommand { if(!vertical) { - statusBar->DrawGraphic(TexMan(item->TextureIDVar(NAME_Icon)), x+slotOffset, y+rowOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); - rowWidth = rowIconSize == -1 ? TexMan(item->TextureIDVar(NAME_Icon))->GetDisplayHeight()+2 : rowIconSize; + statusBar->DrawGraphic(TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true), x+slotOffset, y+rowOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); + rowWidth = rowIconSize == -1 ? TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true)->GetDisplayHeight()+2 : rowIconSize; } else { - statusBar->DrawGraphic(TexMan(item->TextureIDVar(NAME_Icon)), x+rowOffset, y+slotOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); - rowWidth = rowIconSize == -1 ? TexMan(item->TextureIDVar(NAME_Icon))->GetDisplayWidth()+2 : rowIconSize; + statusBar->DrawGraphic(TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true), x+rowOffset, y+slotOffset, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets()); + rowWidth = rowIconSize == -1 ? TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true)->GetDisplayWidth()+2 : rowIconSize; } // If cmd.special is -1 then the slot size is auto detected if(iconSize == -1) { if(!vertical) - slotOffset += (reverse ? -1 : 1) * (TexMan(item->TextureIDVar(NAME_Icon))->GetDisplayWidth() + 2); + slotOffset += (reverse ? -1 : 1) * (TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true)->GetDisplayWidth() + 2); else - slotOffset += (reverse ? -1 : 1) * (TexMan(item->TextureIDVar(NAME_Icon))->GetDisplayHeight() + 2); + slotOffset += (reverse ? -1 : 1) * (TexMan.GetTexture(item->TextureIDVar(NAME_Icon), true)->GetDisplayHeight() + 2); } else slotOffset += (reverse ? -iconSize : iconSize); diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 06dd1e57a..37d30d176 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -1323,7 +1323,7 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, double x, double y, int fla if (!texture.isValid()) return; - FTexture *tex = (flags & DI_DONTANIMATE)? TexMan[texture] : TexMan(texture); + FTexture *tex = TexMan.GetTexture(texture, !(flags & DI_DONTANIMATE)); double texwidth = tex->GetDisplayWidthDouble() * scaleX; double texheight = tex->GetDisplayHeightDouble() * scaleY; diff --git a/src/gl/shaders/gl_postprocessshader.cpp b/src/gl/shaders/gl_postprocessshader.cpp index 6f13b899b..e57196462 100644 --- a/src/gl/shaders/gl_postprocessshader.cpp +++ b/src/gl/shaders/gl_postprocessshader.cpp @@ -216,7 +216,7 @@ void PostProcessShaderInstance::BindTextures() continue; FString name = pair->Value; - FTexture *tex = TexMan(TexMan.CheckForTexture(name, ETextureType::Any)); + FTexture *tex = TexMan.GetTexture(TexMan.CheckForTexture(name, ETextureType::Any), true); if (tex && tex->isValid()) { glUniform1i(location, textureUnit); diff --git a/src/hwrenderer/scene/hw_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp index 4375bc7a1..6198ce32c 100644 --- a/src/hwrenderer/scene/hw_bsp.cpp +++ b/src/hwrenderer/scene/hw_bsp.cpp @@ -277,7 +277,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip) { if (!seg->linedef->isVisualPortal()) { - FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::mid)); + FTexture * tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::mid), true); if (!tex || !tex->isValid()) { // nothing to do here! diff --git a/src/hwrenderer/scene/hw_fakeflat.cpp b/src/hwrenderer/scene/hw_fakeflat.cpp index a70c74d0e..510e7d48a 100644 --- a/src/hwrenderer/scene/hw_fakeflat.cpp +++ b/src/hwrenderer/scene/hw_fakeflat.cpp @@ -117,7 +117,7 @@ bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto // now check for closed sectors! if (bs_ceilingheight1 <= fs_floorheight1 && bs_ceilingheight2 <= fs_floorheight2) { - FTexture * tex = TexMan(sidedef->GetTexture(side_t::top)); + FTexture * tex = TexMan.GetTexture(sidedef->GetTexture(side_t::top), true); if (!tex || !tex->isValid()) return false; if (backsector->GetTexture(sector_t::ceiling) == skyflatnum && frontsector->GetTexture(sector_t::ceiling) == skyflatnum) return false; @@ -126,7 +126,7 @@ bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto if (fs_ceilingheight1 <= bs_floorheight1 && fs_ceilingheight2 <= bs_floorheight2) { - FTexture * tex = TexMan(sidedef->GetTexture(side_t::bottom)); + FTexture * tex = TexMan.GetTexture(sidedef->GetTexture(side_t::bottom), true); if (!tex || !tex->isValid()) return false; // properly render skies (consider door "open" if both floors are sky): @@ -140,12 +140,12 @@ bool hw_CheckClip(side_t * sidedef, sector_t * frontsector, sector_t * backsecto // preserve a kind of transparent door/lift special effect: if (bs_ceilingheight1 < fs_ceilingheight1 || bs_ceilingheight2 < fs_ceilingheight2) { - FTexture * tex = TexMan(sidedef->GetTexture(side_t::top)); + FTexture * tex = TexMan.GetTexture(sidedef->GetTexture(side_t::top), true); if (!tex || !tex->isValid()) return false; } if (bs_floorheight1 > fs_floorheight1 || bs_floorheight2 > fs_floorheight2) { - FTexture * tex = TexMan(sidedef->GetTexture(side_t::bottom)); + FTexture * tex = TexMan.GetTexture(sidedef->GetTexture(side_t::bottom), true); if (!tex || !tex->isValid()) return false; } if (backsector->GetTexture(sector_t::ceiling) == skyflatnum && diff --git a/src/hwrenderer/scene/hw_sky.cpp b/src/hwrenderer/scene/hw_sky.cpp index 15d6b6f7c..c2c6b8189 100644 --- a/src/hwrenderer/scene/hw_sky.cpp +++ b/src/hwrenderer/scene/hw_sky.cpp @@ -243,13 +243,13 @@ void GLWall::SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vert { if (bs->GetPlaneTexZ(sector_t::floor)==fs->GetPlaneTexZ(sector_t::floor)+1.) { - FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::bottom)); + FTexture * tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::bottom), true); if (!tex || !tex->isValid()) return; // very, very, very ugly special case (See Icarus MAP14) // It is VERY important that this is only done for a floor height difference of 1 // or it will cause glitches elsewhere. - tex = TexMan(seg->sidedef->GetTexture(side_t::mid)); + tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::mid), true); if (tex != NULL && !(seg->linedef->flags & ML_DONTPEGTOP) && seg->sidedef->GetTextureYOffset(side_t::mid) > 0) { @@ -265,7 +265,7 @@ void GLWall::SkyTop(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,vert ztop[0]=ztop[1]=32768.0f; - FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::top)); + FTexture * tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::top), true); if (bs->GetTexture(sector_t::ceiling) != skyflatnum) { @@ -325,7 +325,7 @@ void GLWall::SkyBottom(HWDrawInfo *di, seg_t * seg,sector_t * fs,sector_t * bs,v if (fs->GetTexture(sector_t::floor)==skyflatnum) { if (bs->special == GLSector_NoSkyDraw) return; - FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::bottom)); + FTexture * tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::bottom), true); // For lower skies the normal logic only applies to walls with no lower texture. if (!tex->isValid()) diff --git a/src/hwrenderer/scene/hw_sprites.cpp b/src/hwrenderer/scene/hw_sprites.cpp index 4d31c71d7..c3911b460 100644 --- a/src/hwrenderer/scene/hw_sprites.cpp +++ b/src/hwrenderer/scene/hw_sprites.cpp @@ -789,7 +789,7 @@ void GLSprite::Process(HWDrawInfo *di, AActor* thing, sector_t * sector, area_t if (isPicnumOverride) { // Animate picnum overrides. - auto tex = TexMan(thing->picnum); + auto tex = TexMan.GetTexture(thing->picnum, true); if (tex == nullptr) return; patch = tex->GetID(); mirror = false; diff --git a/src/hwrenderer/scene/hw_walls.cpp b/src/hwrenderer/scene/hw_walls.cpp index 47023d524..ef131ada4 100644 --- a/src/hwrenderer/scene/hw_walls.cpp +++ b/src/hwrenderer/scene/hw_walls.cpp @@ -1222,7 +1222,7 @@ void GLWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, // Set up the top // // - FTexture * tex = TexMan(seg->sidedef->GetTexture(side_t::top)); + FTexture * tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::top), true); if (!tex || !tex->isValid()) { if (front->GetTexture(sector_t::ceiling) == skyflatnum && @@ -1258,7 +1258,7 @@ void GLWall::DoMidTexture(HWDrawInfo *di, seg_t * seg, bool drawfogboundary, // Set up the bottom // // - tex = TexMan(seg->sidedef->GetTexture(side_t::bottom)); + tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::bottom), true); if (!tex || !tex->isValid()) { // texture is missing - use the lower plane @@ -2057,7 +2057,7 @@ void GLWall::Process(HWDrawInfo *di, seg_t *seg, sector_t * frontsector, sector_ sector_t *backsec = isportal? seg->linedef->getPortalDestination()->frontsector : backsector; bool drawfogboundary = !di->isFullbrightScene() && hw_CheckFog(frontsector, backsec); - FTexture *tex = TexMan(seg->sidedef->GetTexture(side_t::mid)); + FTexture *tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::mid), true); if (tex != NULL) { if (i_compatflags & COMPATF_MASKEDMIDTEX) diff --git a/src/hwrenderer/scene/hw_weapon.cpp b/src/hwrenderer/scene/hw_weapon.cpp index 6cb719fae..1e18a6e2f 100644 --- a/src/hwrenderer/scene/hw_weapon.cpp +++ b/src/hwrenderer/scene/hw_weapon.cpp @@ -131,7 +131,7 @@ static bool isBright(DPSprite *psp) FTextureID lump = sprites[psp->GetSprite()].GetSpriteFrame(psp->GetFrame(), 0, 0., nullptr); if (lump.isValid()) { - FTexture * tex = TexMan(lump); + FTexture * tex = TexMan.GetTexture(lump, true); if (tex) disablefullbright = tex->isFullbrightDisabled(); } return psp->GetState()->GetFullbright() && !disablefullbright; diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index fe1cda7cf..ab833a715 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -519,7 +519,7 @@ again: FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translate, bool create) { - return ValidateTexture(translate? TexMan(no) : TexMan[no], expand, create); + return ValidateTexture(TexMan.GetTexture(no, translate), expand, create); } diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 0477cb5af..1cec8dbaa 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -568,7 +568,7 @@ void DIntermissionScreenCast::Drawer () } sprframe = &SpriteFrames[sprites[castsprite].spriteframes + caststate->GetFrame()]; - pic = TexMan(sprframe->Texture[0]); + pic = TexMan.GetTexture(sprframe->Texture[0], true); screen->DrawTexture (pic, 160, 170, DTA_320x200, true, diff --git a/src/p_3dmidtex.cpp b/src/p_3dmidtex.cpp index 7a2363be6..6b54d6558 100644 --- a/src/p_3dmidtex.cpp +++ b/src/p_3dmidtex.cpp @@ -229,7 +229,7 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, double *ptextop, do side_t *side = line->sidedef[sideno]; FTextureID texnum = side->GetTexture(side_t::mid); if (!texnum.isValid()) return false; - FTexture * tex= TexMan(texnum); + FTexture * tex= TexMan.GetTexture(texnum, true); if (!tex) return false; FTexCoordInfo tci; diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index fd323e65f..43da7038f 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -1147,7 +1147,7 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac) FTexture *tex = TexMan[GetTexture(sector_t::floor)]; if (tex != NULL && tex->isGlowing()) { - if (!tex->isAutoGlowing()) tex = TexMan(GetTexture(sector_t::floor)); + if (!tex->isAutoGlowing()) tex = TexMan.GetTexture(GetTexture(sector_t::floor), true); if (tex->isGlowing()) // recheck the current animation frame. { tex->GetGlowColor(bottomglowcolor); @@ -1192,7 +1192,7 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac) FTexture *tex = TexMan[GetTexture(sector_t::ceiling)]; if (tex != NULL && tex->isGlowing()) { - if (!tex->isAutoGlowing()) tex = TexMan(GetTexture(sector_t::ceiling)); + if (!tex->isAutoGlowing()) tex = TexMan.GetTexture(GetTexture(sector_t::ceiling), true); if (tex->isGlowing()) // recheck the current animation frame. { ret = true; @@ -1216,7 +1216,7 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac) FTexture *tex = TexMan[GetTexture(sector_t::floor)]; if (tex != NULL && tex->isGlowing()) { - if (!tex->isAutoGlowing()) tex = TexMan(GetTexture(sector_t::floor)); + if (!tex->isAutoGlowing()) tex = TexMan.GetTexture(GetTexture(sector_t::floor), true); if (tex->isGlowing()) // recheck the current animation frame. { ret = true; diff --git a/src/polyrenderer/scene/poly_decal.cpp b/src/polyrenderer/scene/poly_decal.cpp index c91c48ad1..442c70de8 100644 --- a/src/polyrenderer/scene/poly_decal.cpp +++ b/src/polyrenderer/scene/poly_decal.cpp @@ -49,7 +49,7 @@ void RenderPolyDecal::Render(PolyRenderThread *thread, DBaseDecal *decal, const if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid()) return; - FTexture *ttex = TexMan(decal->PicNum, true); + FTexture *ttex = TexMan.GetPalettedTexture(decal->PicNum, true); if (ttex == nullptr || !ttex->isValid()) return; diff --git a/src/polyrenderer/scene/poly_model.cpp b/src/polyrenderer/scene/poly_model.cpp index 50deccdb6..a2f7875cb 100644 --- a/src/polyrenderer/scene/poly_model.cpp +++ b/src/polyrenderer/scene/poly_model.cpp @@ -66,7 +66,7 @@ static bool isBright(DPSprite *psp) FTextureID lump = sprites[psp->GetSprite()].GetSpriteFrame(psp->GetFrame(), 0, 0., nullptr); if (lump.isValid()) { - FTexture * tex = TexMan(lump); + FTexture * tex = TexMan.GetPalettedTexture(lump, true); if (tex) disablefullbright = tex->isFullbrightDisabled(); } return psp->GetState()->GetFullbright() && !disablefullbright; diff --git a/src/polyrenderer/scene/poly_plane.cpp b/src/polyrenderer/scene/poly_plane.cpp index 0f5a24235..926092f5c 100644 --- a/src/polyrenderer/scene/poly_plane.cpp +++ b/src/polyrenderer/scene/poly_plane.cpp @@ -66,7 +66,7 @@ void RenderPolyPlane::RenderNormal(PolyRenderThread *thread, const PolyTransferH FTextureID picnum = fakeflat.FrontSector->GetTexture(ceiling ? sector_t::ceiling : sector_t::floor); if (picnum != skyflatnum) { - FTexture *tex = TexMan(picnum); + FTexture *tex = TexMan.GetPalettedTexture(picnum, true); if (!tex || !tex->isValid()) return; @@ -510,7 +510,7 @@ void Render3DFloorPlane::RenderPlanes(PolyRenderThread *thread, subsector_t *sub void Render3DFloorPlane::Render(PolyRenderThread *thread) { FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture; - auto tex = TexMan(picnum); + auto tex = TexMan.GetPalettedTexture(picnum, true); if (!tex->isValid()) return; diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index dd4654aab..a0a5dd597 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -227,7 +227,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p picnum = sprframe->Texture[0]; flip = sprframe->Flip & 1; - ttex = TexMan(picnum); + ttex = TexMan.GetPalettedTexture(picnum, true); if (!ttex->isValid()) return; diff --git a/src/polyrenderer/scene/poly_sky.cpp b/src/polyrenderer/scene/poly_sky.cpp index cf5fc755d..3e7cd072c 100644 --- a/src/polyrenderer/scene/poly_sky.cpp +++ b/src/polyrenderer/scene/poly_sky.cpp @@ -284,7 +284,7 @@ Mat4f PolySkyDome::GLSkyMath() static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true) { - auto tex = TexMan(texid, true); + auto tex = TexMan.GetPalettedTexture(texid, true); if (tex == nullptr) return nullptr; if (!allownull && !tex->isValid()) return nullptr; return tex->GetSoftwareTexture(); diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 73da1528b..79ddf2312 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -312,7 +312,7 @@ FSoftwareTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool if (thing->picnum.isValid()) { - FTexture *ttex = TexMan(thing->picnum); + FTexture *ttex = TexMan.GetPalettedTexture(thing->picnum, true); if (!ttex || !ttex->isValid()) { return nullptr; diff --git a/src/polyrenderer/scene/poly_wall.cpp b/src/polyrenderer/scene/poly_wall.cpp index 297e549f4..70472eef7 100644 --- a/src/polyrenderer/scene/poly_wall.cpp +++ b/src/polyrenderer/scene/poly_wall.cpp @@ -171,7 +171,7 @@ bool RenderPolyWall::RenderLine(PolyRenderThread *thread, seg_t *line, sector_t wall.Alpha = wall.Line->alpha; wall.FogBoundary = IsFogBoundary(frontsector, backsector); - FTexture *midtex = TexMan(line->sidedef->GetTexture(side_t::mid), true); + FTexture *midtex = TexMan.GetPalettedTexture(line->sidedef->GetTexture(side_t::mid), true); if ((midtex && midtex->isValid()) || wall.FogBoundary) translucentWallsOutput.push_back(thread->FrameMemory->NewObject(wall)); @@ -528,7 +528,7 @@ void RenderPolyWall::ClampHeight(TriVertex &v1, TriVertex &v2) FSoftwareTexture *RenderPolyWall::GetTexture(const line_t *line, const side_t *side, side_t::ETexpart texpart) { - FTexture *tex = TexMan(side->GetTexture(texpart), true); + FTexture *tex = TexMan.GetPalettedTexture(side->GetTexture(texpart), true); if (tex == nullptr || !tex->isValid()) { // Mapping error. Doom floodfills this with a plane. @@ -537,16 +537,16 @@ FSoftwareTexture *RenderPolyWall::GetTexture(const line_t *line, const side_t *s if (line && line->backsector && line->sidedef[0] == side) { if (texpart == side_t::top) - tex = TexMan(line->backsector->GetTexture(sector_t::ceiling), true); + tex = TexMan.GetPalettedTexture(line->backsector->GetTexture(sector_t::ceiling), true); else if (texpart == side_t::bottom) - tex = TexMan(line->backsector->GetTexture(sector_t::floor), true); + tex = TexMan.GetPalettedTexture(line->backsector->GetTexture(sector_t::floor), true); } if (line && line->backsector && line->sidedef[1] == side) { if (texpart == side_t::top) - tex = TexMan(line->frontsector->GetTexture(sector_t::ceiling), true); + tex = TexMan.GetPalettedTexture(line->frontsector->GetTexture(sector_t::ceiling), true); else if (texpart == side_t::bottom) - tex = TexMan(line->frontsector->GetTexture(sector_t::floor), true); + tex = TexMan.GetPalettedTexture(line->frontsector->GetTexture(sector_t::floor), true); } if (tex == nullptr || !tex->isValid()) diff --git a/src/r_data/models/models.cpp b/src/r_data/models/models.cpp index e8cb52678..6516ac5fd 100644 --- a/src/r_data/models/models.cpp +++ b/src/r_data/models/models.cpp @@ -268,7 +268,7 @@ void FModelRenderer::RenderFrameModels(const FSpriteModelFrame *smf, const FStat if (smf->modelIDs[i] != -1) { FModel * mdl = Models[smf->modelIDs[i]]; - FTexture *tex = smf->skinIDs[i].isValid() ? TexMan(smf->skinIDs[i]) : nullptr; + FTexture *tex = smf->skinIDs[i].isValid() ? TexMan.GetTexture(smf->skinIDs[i], true) : nullptr; mdl->BuildVertexBuffer(this); mdl->PushSpriteMDLFrame(smf, i); diff --git a/src/r_data/models/models_md2.cpp b/src/r_data/models/models_md2.cpp index ce9566a8f..d203bf15a 100644 --- a/src/r_data/models/models_md2.cpp +++ b/src/r_data/models/models_md2.cpp @@ -364,7 +364,7 @@ void FDMDModel::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame if (!skin) { if (info.numSkins == 0 || !skins[0].isValid()) return; - skin = TexMan(skins[0]); + skin = TexMan.GetTexture(skins[0], true); if (!skin) return; } diff --git a/src/r_data/models/models_md3.cpp b/src/r_data/models/models_md3.cpp index b3f12b853..67fcb38ef 100644 --- a/src/r_data/models/models_md3.cpp +++ b/src/r_data/models/models_md3.cpp @@ -356,11 +356,11 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame { if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid()) { - surfaceSkin = TexMan(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i]); + surfaceSkin = TexMan.GetTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i], true); } else if(surf->numSkins > 0 && surf->skins[0].isValid()) { - surfaceSkin = TexMan(surf->skins[0]); + surfaceSkin = TexMan.GetTexture(surf->skins[0], true); } if (!surfaceSkin) diff --git a/src/r_data/models/models_obj.cpp b/src/r_data/models/models_obj.cpp index b6adb29cf..bbf8e3b5b 100644 --- a/src/r_data/models/models_obj.cpp +++ b/src/r_data/models/models_obj.cpp @@ -636,11 +636,11 @@ void FOBJModel::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame { if (i < MD3_MAX_SURFACES && curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid()) { - userSkin = TexMan(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i]); + userSkin = TexMan.GetTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i], true); } else if (surf->skin.isValid()) { - userSkin = TexMan(surf->skin); + userSkin = TexMan.GetTexture(surf->skin, true); } } diff --git a/src/r_data/models/models_ue1.cpp b/src/r_data/models/models_ue1.cpp index bd4f54e3d..c51dbc7fb 100644 --- a/src/r_data/models/models_ue1.cpp +++ b/src/r_data/models/models_ue1.cpp @@ -235,7 +235,7 @@ void FUE1Model::RenderFrame( FModelRenderer *renderer, FTexture *skin, int frame if ( !sskin ) { if ( curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].isValid() ) - sskin = TexMan(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum]); + sskin = TexMan.GetTexture(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum], true); if ( !sskin ) { vofs += vsize; diff --git a/src/r_sky.cpp b/src/r_sky.cpp index 5b161dde1..94fb65644 100644 --- a/src/r_sky.cpp +++ b/src/r_sky.cpp @@ -80,8 +80,8 @@ void R_InitSkyMap() sky2texture = TexMan.CheckForTexture("-noflat-", ETextureType::Any); } - skytex1 = TexMan(sky1texture, true); - skytex2 = TexMan(sky2texture, true); + skytex1 = TexMan.GetTexture(sky1texture, false); + skytex2 = TexMan.GetTexture(sky2texture, false); if (skytex1 == nullptr) return; diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index f77971a28..c3bc08d9f 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -451,7 +451,7 @@ namespace swrenderer lwal = draw_segment->maskedtexturecol; swal = draw_segment->swall; - FTexture *tex = TexMan(sidedef->GetTexture(side_t::mid), true); + FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true); FSoftwareTexture *pic = tex && tex->isValid()? tex->GetSoftwareTexture() : nullptr; double yscale = pic->GetScale().Y * sidedef->GetTextureYScale(side_t::mid); fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); @@ -770,7 +770,7 @@ namespace swrenderer } } - FTexture *ftex = TexMan(sidedef->GetTexture(side_t::mid), true); + FTexture *ftex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true); FSoftwareTexture *midtex = ftex && ftex->isValid() ? ftex->GetSoftwareTexture() : nullptr; bool segtextured = midtex != NULL || mTopPart.Texture != NULL || mBottomPart.Texture != NULL; @@ -816,7 +816,7 @@ namespace swrenderer // No top texture for skyhack lines if (mFrontSector->GetTexture(sector_t::ceiling) == skyflatnum && mBackSector->GetTexture(sector_t::ceiling) == skyflatnum) return; - FTexture *tex = TexMan(sidedef->GetTexture(side_t::top), true); + FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::top), true); mTopPart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; mTopPart.TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::top)); @@ -874,7 +874,7 @@ namespace swrenderer if (linedef->isVisualPortal()) return; if (linedef->special == Line_Horizon) return; - auto tex = TexMan(sidedef->GetTexture(side_t::mid), true); + auto tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true); mMiddlePart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; mMiddlePart.TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); double rowoffset = sidedef->GetTextureYOffset(side_t::mid); @@ -939,7 +939,7 @@ namespace swrenderer frontlowertop = mBackSector->GetPlaneTexZ(sector_t::ceiling); } - FTexture *tex = TexMan(sidedef->GetTexture(side_t::bottom), true);; + FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::bottom), true); mBottomPart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; if (!mBottomPart.Texture) return; diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index 060f40fa1..eb23daad0 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -162,7 +162,7 @@ namespace swrenderer if (curline->sidedef->GetTexture(side_t::mid).isNull()) return false; - FTexture *ttex = TexMan(curline->sidedef->GetTexture(side_t::mid), true); + FTexture *ttex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::mid), true); if (i_compatflags & COMPATF_MASKEDMIDTEX) { ttex = ttex->GetRawTexture(); @@ -643,15 +643,15 @@ namespace swrenderer FTexture *rw_tex = nullptr; if (fover->flags & FF_UPPERTEXTURE) { - rw_tex = TexMan(curline->sidedef->GetTexture(side_t::top), true); + rw_tex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::top), true); } else if (fover->flags & FF_LOWERTEXTURE) { - rw_tex = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); + rw_tex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_tex = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); + rw_tex = TexMan.GetPalettedTexture(fover->master->sidedef[0]->GetTexture(side_t::mid), true); } rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } @@ -705,15 +705,15 @@ namespace swrenderer FTexture *rw_tex; if (rover->flags & FF_UPPERTEXTURE) { - rw_tex = TexMan(curline->sidedef->GetTexture(side_t::top), true); + rw_tex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::top), true); } else if (rover->flags & FF_LOWERTEXTURE) { - rw_tex = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); + rw_tex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_tex = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); + rw_tex = TexMan.GetPalettedTexture(rover->master->sidedef[0]->GetTexture(side_t::mid), true); } rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } @@ -832,15 +832,15 @@ namespace swrenderer FTexture *rw_tex; if (fover->flags & FF_UPPERTEXTURE) { - rw_tex = TexMan(curline->sidedef->GetTexture(side_t::top), true); + rw_tex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::top), true); } else if (fover->flags & FF_LOWERTEXTURE) { - rw_tex = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); + rw_tex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_tex = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); + rw_tex = TexMan.GetPalettedTexture(fover->master->sidedef[0]->GetTexture(side_t::mid), true); } rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } @@ -891,15 +891,15 @@ namespace swrenderer FTexture *rw_tex; if (rover->flags & FF_UPPERTEXTURE) { - rw_tex = TexMan(curline->sidedef->GetTexture(side_t::top), true); + rw_tex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::top), true); } else if (rover->flags & FF_LOWERTEXTURE) { - rw_tex = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); + rw_tex = TexMan.GetPalettedTexture(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_tex = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); + rw_tex = TexMan.GetPalettedTexture(rover->master->sidedef[0]->GetTexture(side_t::mid), true); } rw_pic = rw_tex && rw_tex->isValid() ? rw_tex->GetSoftwareTexture() : nullptr; } diff --git a/src/swrenderer/plane/r_skyplane.cpp b/src/swrenderer/plane/r_skyplane.cpp index feac5b5da..4f444ece5 100644 --- a/src/swrenderer/plane/r_skyplane.cpp +++ b/src/swrenderer/plane/r_skyplane.cpp @@ -65,8 +65,8 @@ fixed_t sky1cyl, sky2cyl; void InitSoftwareSky() { - auto skytex1 = TexMan(sky1texture, true); - auto skytex2 = TexMan(sky2texture, true); + auto skytex1 = TexMan.GetPalettedTexture(sky1texture, true); + auto skytex2 = TexMan.GetPalettedTexture(sky2texture, true); if (skytex1 == nullptr) return; @@ -118,7 +118,7 @@ namespace swrenderer static FSoftwareTexture *GetSWTex(FTextureID texid, bool allownull = true) { - auto tex = TexMan(texid, true); + auto tex = TexMan.GetPalettedTexture(texid, true); if (tex == nullptr) return nullptr; if (!allownull && !tex->isValid()) return nullptr; return tex->GetSoftwareTexture(); diff --git a/src/swrenderer/plane/r_visibleplane.cpp b/src/swrenderer/plane/r_visibleplane.cpp index 6ba69d90c..72e838812 100644 --- a/src/swrenderer/plane/r_visibleplane.cpp +++ b/src/swrenderer/plane/r_visibleplane.cpp @@ -113,7 +113,7 @@ namespace swrenderer } else // regular flat { - FTexture *ttex = TexMan(picnum, true); + FTexture *ttex = TexMan.GetPalettedTexture(picnum, true); if (!ttex->isValid()) { diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index ccdfb5784..e2a8c7877 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -1023,7 +1023,7 @@ namespace swrenderer { sprite.picnum = thing->picnum; - sprite.tex = TexMan(sprite.picnum); + sprite.tex = TexMan.GetPalettedTexture(sprite.picnum, true); if (!sprite.tex->isValid()) { return false; diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index 0f2e15296..a0a77da0d 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -129,7 +129,7 @@ namespace swrenderer } } - FTexture *tex = TexMan(decal->PicNum, true); + FTexture *tex = TexMan.GetPalettedTexture(decal->PicNum, true); flipx = (uint8_t)(decal->RenderFlags & RF_XFLIP); if (tex == NULL || !tex->isValid()) diff --git a/src/swrenderer/things/r_model.cpp b/src/swrenderer/things/r_model.cpp index 26d54f104..938b5f20c 100644 --- a/src/swrenderer/things/r_model.cpp +++ b/src/swrenderer/things/r_model.cpp @@ -106,7 +106,7 @@ namespace swrenderer FTextureID lump = sprites[psp->GetSprite()].GetSpriteFrame(psp->GetFrame(), 0, 0., nullptr); if (lump.isValid()) { - FTexture * tex = TexMan(lump); + FTexture * tex = TexMan.GetTexture(lump, true); if (tex) disablefullbright = tex->isFullbrightDisabled(); } return psp->GetState()->GetFullbright() && !disablefullbright; diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 6322ef637..3020ce07c 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -224,7 +224,7 @@ namespace swrenderer picnum = sprframe->Texture[0]; flip = sprframe->Flip & 1; - tex = TexMan(picnum); + tex = TexMan.GetTexture(picnum, true); if (!tex->isValid()) return; diff --git a/src/textures/textures.h b/src/textures/textures.h index e75ce0a8a..e8eca3b0d 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -566,41 +566,40 @@ public: return Textures[texnum.GetIndex()].Texture; } + // This only gets used in UI code so we do not need PALVERS handling. FTexture *GetTextureByName(const char *name, bool animate = false) { FTextureID texnum = GetTextureID (name, ETextureType::MiscPatch); if (!texnum.Exists()) return nullptr; if (!animate) return Textures[texnum.GetIndex()].Texture; else return Textures[Translation[texnum.GetIndex()]].Texture; - } - FTexture *ByIndex(int i) + FTexture *GetTexture(FTextureID texnum, bool animate) + { + if ((size_t)texnum.texnum >= Textures.Size()) return nullptr; + if (animate) texnum = Translation[texnum.GetIndex()]; + return Textures[texnum.GetIndex()].Texture; + } + + // This is the only access function that should be used inside the software renderer. + FTexture *GetPalettedTexture(FTextureID texnum, bool animate) + { + if ((size_t)texnum.texnum >= Textures.Size()) return nullptr; + if (animate) texnum = Translation[texnum.GetIndex()]; + texnum = PalCheck(texnum).GetIndex(); + return Textures[texnum.GetIndex()].Texture; + } + + FTexture *ByIndex(int i, bool animate = false) { if (unsigned(i) >= Textures.Size()) return NULL; + if (animate) i = Translation[i]; return Textures[i].Texture; } FTexture *FindTexture(const char *texname, ETextureType usetype = ETextureType::MiscPatch, BITFIELD flags = TEXMAN_TryAny); - // Get texture with translation - FTexture *operator() (FTextureID texnum, bool withpalcheck=false) - { - if ((size_t)texnum.texnum >= Textures.Size()) return NULL; - int picnum = Translation[texnum.texnum]; - if (withpalcheck) - { - picnum = PalCheck(picnum).GetIndex(); - } - return Textures[picnum].Texture; - } - /* - FTexture *operator() (const char *texname) - { - FTextureID texnum = GetTextureID (texname, ETextureType::MiscPatch); - if (texnum.texnum == -1) return NULL; - return Textures[Translation[texnum.texnum]].Texture; - } - */ + //public: diff --git a/src/v_collection.cpp b/src/v_collection.cpp index 95f35097a..053eeec45 100644 --- a/src/v_collection.cpp +++ b/src/v_collection.cpp @@ -77,5 +77,5 @@ FTexture *FImageCollection::operator[] (int index) const { return NULL; } - return ImageMap[index].Exists()? TexMan(ImageMap[index]) : NULL; + return ImageMap[index].Exists()? TexMan.GetPalettedTexture(ImageMap[index], true) : NULL; } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 00c6307ef..442705e71 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -175,7 +175,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawTexture) if (!screen->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); - FTexture *tex = animate ? TexMan(FSetTextureID(texid)) : TexMan[FSetTextureID(texid)]; + FTexture *tex = TexMan.ByIndex(texid, animate); VMVa_List args = { param + 4, 0, numparam - 5, va_reginfo + 4 }; screen->DrawTexture(tex, x, y, args); return 0; @@ -231,7 +231,7 @@ DEFINE_ACTION_FUNCTION(_Screen, DrawShape) if (!screen->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); - FTexture *tex = animate ? TexMan(FSetTextureID(texid)) : TexMan[FSetTextureID(texid)]; + FTexture *tex = TexMan.ByIndex(texid, animate); VMVa_List args = { param + 3, 0, numparam - 4, va_reginfo + 3 }; screen->DrawShape(tex, shape, args); @@ -1354,7 +1354,7 @@ void DFrameBuffer::DrawBorder (int x1, int y1, int x2, int y2) if (picnum.isValid()) { - FlatFill (x1, y1, x2, y2, TexMan(picnum)); + FlatFill (x1, y1, x2, y2, TexMan.GetTexture(picnum, false)); } else { diff --git a/src/v_font.cpp b/src/v_font.cpp index 4985b2407..c875c6eec 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1519,7 +1519,7 @@ FTexture *FSinglePicFont::GetChar (int code, int *const width) const *width = SpaceWidth; if (code == 'a' || code == 'A') { - return TexMan(PicNum); + return TexMan.GetPalettedTexture(PicNum, true); } else { diff --git a/wadsrc/static/zscript/statusbar/alt_hud.txt b/wadsrc/static/zscript/statusbar/alt_hud.txt index 6f7a5f8dd..ccc9b568d 100644 --- a/wadsrc/static/zscript/statusbar/alt_hud.txt +++ b/wadsrc/static/zscript/statusbar/alt_hud.txt @@ -674,7 +674,7 @@ class AltHud ui { double trans = rover == CPlayer.mo.InvSel ? 1.0 : 0.4; - DrawImageToBox(AltIcon.isValid()? AltIcon : rover.Icon, x, y, 19, 25, trans); + DrawImageToBox(AltIcon.isValid()? AltIcon : rover.Icon, x, y, 19, 25, trans, true); if (rover.Amount > 1) { int xx; @@ -989,4 +989,4 @@ class AltHud ui } } -} \ No newline at end of file +} From 42b18e6dfb500de3b8688a0552f1c1f23e745c1f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 02:53:50 +0100 Subject: [PATCH 12/66] - Disable PALVERS substitution when true color rendering is active. --- src/textures/texturemanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 6c7a75ef9..76e512cdf 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -1131,10 +1131,10 @@ void FTextureManager::InitPalettedVersions() // //========================================================================== -// fixme: The way this is used, it is mostly useless. FTextureID FTextureManager::PalCheck(FTextureID tex) { - if (vid_nopalsubstitutions) return tex; + // In any true color mode this shouldn't do anything. + if (vid_nopalsubstitutions || V_IsTrueColor()) return tex; auto ftex = operator[](tex); if (ftex != nullptr && ftex->PalVersion != nullptr) return ftex->PalVersion->id; return tex; From 9409843931a61c111d9e55339333bda9fd8a64fc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 03:01:40 +0100 Subject: [PATCH 13/66] - replaced the last access operator, too Now everything uses a function. This really wasn't what operators are supposef to be used for. --- src/am_map.cpp | 8 ++++---- src/c_console.cpp | 2 +- src/d_main.cpp | 2 +- src/fragglescript/t_func.cpp | 4 ++-- src/g_shared/a_decals.cpp | 4 ++-- src/g_shared/a_dynlight.cpp | 2 +- src/g_statusbar/sbar_mugshot.cpp | 2 +- src/g_statusbar/shared_sbar.cpp | 2 +- src/hu_scores.cpp | 4 ++-- src/hwrenderer/scene/hw_decal.cpp | 2 +- src/hwrenderer/scene/hw_renderhacks.cpp | 4 ++-- src/intermission/intermission.cpp | 14 +++++++------- src/p_acs.cpp | 8 ++++---- src/p_doors.cpp | 4 ++-- src/p_sectors.cpp | 8 ++++---- src/polyrenderer/scene/poly_playersprite.cpp | 2 +- src/polyrenderer/scene/poly_sprite.cpp | 4 ++-- src/r_data/gldefs.cpp | 14 +++++++------- src/r_data/sprites.cpp | 6 +++--- src/r_utility.cpp | 4 ++-- src/scripting/vm/jit_move.cpp | 2 +- src/scripting/vm/vmexec.h | 2 +- src/serializer.cpp | 2 +- src/swrenderer/scene/r_opaque_pass.cpp | 4 ++-- src/swrenderer/things/r_playersprite.cpp | 2 +- src/textures/formats/multipatchtexture.cpp | 4 ++-- src/textures/texturemanager.cpp | 10 +++++----- src/textures/textures.h | 12 ++---------- src/v_font.cpp | 10 +++++----- src/wi_stuff.cpp | 2 +- 30 files changed, 71 insertions(+), 79 deletions(-) diff --git a/src/am_map.cpp b/src/am_map.cpp index 932ec42ed..4357136eb 100644 --- a/src/am_map.cpp +++ b/src/am_map.cpp @@ -1194,7 +1194,7 @@ static void AM_ScrollParchment (double dmapx, double dmapy) if (mapback.isValid()) { - FTexture *backtex = TexMan[mapback]; + FTexture *backtex = TexMan.GetTexture(mapback); if (backtex != NULL) { @@ -1689,7 +1689,7 @@ void AM_clearFB (const AMColor &color) } else { - FTexture *backtex = TexMan[mapback]; + FTexture *backtex = TexMan.GetTexture(mapback); if (backtex != NULL) { int pwidth = backtex->GetDisplayWidth(); @@ -3189,7 +3189,7 @@ void AM_drawAuthorMarkers () spriteframe_t *sprframe = &SpriteFrames[tex->GetRotations()]; picnum = sprframe->Texture[0]; flip = sprframe->Flip & 1; - tex = TexMan[picnum]; + tex = TexMan.GetTexture(picnum); } } else @@ -3204,7 +3204,7 @@ void AM_drawAuthorMarkers () spriteframe_t *sprframe = &SpriteFrames[sprdef->spriteframes + mark->frame]; picnum = sprframe->Texture[0]; flip = sprframe->Flip & 1; - tex = TexMan[picnum]; + tex = TexMan.GetTexture(picnum); } } FActorIterator it (mark->args[0]); diff --git a/src/c_console.cpp b/src/c_console.cpp index b5f1a3cb2..caea2a741 100644 --- a/src/c_console.cpp +++ b/src/c_console.cpp @@ -1083,7 +1083,7 @@ void C_DrawConsole () else if (ConBottom) { int visheight; - FTexture *conpic = TexMan[conback]; + FTexture *conpic = TexMan.GetTexture(conback); visheight = ConBottom; diff --git a/src/d_main.cpp b/src/d_main.cpp index 3f5036831..b4f4c5b35 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -856,7 +856,7 @@ void D_Display () D_DrawIcon = NULL; if (picnum.isValid()) { - FTexture *tex = TexMan[picnum]; + FTexture *tex = TexMan.GetTexture(picnum); screen->DrawTexture (tex, 160 - tex->GetDisplayWidth()/2, 100 - tex->GetDisplayHeight()/2, DTA_320x200, true, TAG_DONE); } diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 579201a3a..87858f91f 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -1903,7 +1903,7 @@ void FParser::SF_FloorTexture(void) } t_return.type = svt_string; - FTexture * tex = TexMan[sector->GetTexture(sector_t::floor)]; + FTexture * tex = TexMan.GetTexture(sector->GetTexture(sector_t::floor)); t_return.string = tex? tex->GetName() : ""; } } @@ -1993,7 +1993,7 @@ void FParser::SF_CeilingTexture(void) } t_return.type = svt_string; - FTexture * tex = TexMan[sector->GetTexture(sector_t::ceiling)]; + FTexture * tex = TexMan.GetTexture(sector->GetTexture(sector_t::ceiling)); t_return.string = tex? tex->GetName() : ""; } } diff --git a/src/g_shared/a_decals.cpp b/src/g_shared/a_decals.cpp index 7837ade74..09110bf75 100644 --- a/src/g_shared/a_decals.cpp +++ b/src/g_shared/a_decals.cpp @@ -262,7 +262,7 @@ FTextureID DBaseDecal::StickToWall (side_t *wall, double x, double y, F3DFloor * else return FNullTextureID(); CalcFracPos (wall, x, y); - FTexture *texture = TexMan[tex]; + FTexture *texture = TexMan.GetTexture(tex); if (texture == NULL || texture->allowNoDecals()) { @@ -492,7 +492,7 @@ void DBaseDecal::Spread (const FDecalTemplate *tpl, side_t *wall, double x, doub GetWallStuff (wall, v1, ldx, ldy); rorg = Length (x - v1->fX(), y - v1->fY()); - if ((tex = TexMan[PicNum]) == NULL) + if ((tex = TexMan.GetTexture(PicNum)) == NULL) { return; } diff --git a/src/g_shared/a_dynlight.cpp b/src/g_shared/a_dynlight.cpp index 3434d73af..64d294aab 100644 --- a/src/g_shared/a_dynlight.cpp +++ b/src/g_shared/a_dynlight.cpp @@ -937,7 +937,7 @@ CCMD(listlights) if (dl->target) { FTextureID spr = sprites[dl->target->sprite].GetSpriteFrame(dl->target->frame, 0, 0., nullptr); - Printf(", frame = %s ", TexMan[spr]->GetName().GetChars()); + Printf(", frame = %s ", TexMan.GetTexture(spr)->GetName().GetChars()); } diff --git a/src/g_statusbar/sbar_mugshot.cpp b/src/g_statusbar/sbar_mugshot.cpp index 950438f21..cf3c1f009 100644 --- a/src/g_statusbar/sbar_mugshot.cpp +++ b/src/g_statusbar/sbar_mugshot.cpp @@ -96,7 +96,7 @@ FTexture *FMugShotFrame::GetTexture(const char *default_face, const char *skin_f } sprite.UnlockBuffer(); } - return TexMan[TexMan.CheckForTexture(sprite, ETextureType::Any, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_AllowSkins)]; + return TexMan.GetTexture(TexMan.CheckForTexture(sprite, ETextureType::Any, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_AllowSkins)); } //=========================================================================== diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 37d30d176..1ed349d3a 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -203,7 +203,7 @@ void ST_LoadCrosshair(bool alwaysload) } } CrosshairNum = num; - CrosshairImage = TexMan[texid]; + CrosshairImage = TexMan.GetTexture(texid); } //--------------------------------------------------------------------------- diff --git a/src/hu_scores.cpp b/src/hu_scores.cpp index 435acc8f0..c9ed444af 100644 --- a/src/hu_scores.cpp +++ b/src/hu_scores.cpp @@ -209,7 +209,7 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh } if (players[i].mo->ScoreIcon.isValid()) { - FTexture *pic = TexMan[players[i].mo->ScoreIcon]; + FTexture *pic = TexMan.GetTexture(players[i].mo->ScoreIcon); width = pic->GetDisplayWidth() - pic->GetDisplayLeftOffset() + 2; if (width > maxscorewidth) { @@ -422,7 +422,7 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2, if (player->mo->ScoreIcon.isValid()) { - FTexture *pic = TexMan[player->mo->ScoreIcon]; + FTexture *pic = TexMan.GetTexture(player->mo->ScoreIcon); screen->DrawTexture (pic, col3, y, DTA_CleanNoMove, true, TAG_DONE); diff --git a/src/hwrenderer/scene/hw_decal.cpp b/src/hwrenderer/scene/hw_decal.cpp index 815032314..9bce744c4 100644 --- a/src/hwrenderer/scene/hw_decal.cpp +++ b/src/hwrenderer/scene/hw_decal.cpp @@ -208,7 +208,7 @@ void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &nor flipy = !!(decal->RenderFlags & RF_YFLIP); - FTexture *texture = TexMan[decalTile]; + FTexture *texture = TexMan.GetTexture(decalTile); if (texture == NULL) return; diff --git a/src/hwrenderer/scene/hw_renderhacks.cpp b/src/hwrenderer/scene/hw_renderhacks.cpp index 8f75bb02f..59d71231d 100644 --- a/src/hwrenderer/scene/hw_renderhacks.cpp +++ b/src/hwrenderer/scene/hw_renderhacks.cpp @@ -350,7 +350,7 @@ bool HWDrawInfo::DoOneSectorUpper(subsector_t * subsec, float Planez, area_t in_ if (sec->GetPlaneTexZ(sector_t::ceiling) == Planez) { // If there's a texture abort - FTexture * tex = TexMan[seg->sidedef->GetTexture(side_t::top)]; + FTexture * tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::top)); if (!tex || !tex->isValid()) continue; else return false; } @@ -408,7 +408,7 @@ bool HWDrawInfo::DoOneSectorLower(subsector_t * subsec, float Planez, area_t in_ if (sec->GetPlaneTexZ(sector_t::floor) == Planez) { // If there's a texture abort - FTexture * tex = TexMan[seg->sidedef->GetTexture(side_t::bottom)]; + FTexture * tex = TexMan.GetTexture(seg->sidedef->GetTexture(side_t::bottom)); if (!tex || !tex->isValid()) continue; else return false; } diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index 1cec8dbaa..e4cd6ac30 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -162,11 +162,11 @@ void DIntermissionScreen::Drawer () { if (!mFlatfill) { - screen->DrawTexture (TexMan[mBackground], 0, 0, DTA_Fullscreen, true, TAG_DONE); + screen->DrawTexture (TexMan.GetTexture(mBackground), 0, 0, DTA_Fullscreen, true, TAG_DONE); } else { - screen->FlatFill (0,0, SCREENWIDTH, SCREENHEIGHT, TexMan[mBackground]); + screen->FlatFill (0,0, SCREENWIDTH, SCREENHEIGHT, TexMan.GetTexture(mBackground)); } } else @@ -176,7 +176,7 @@ void DIntermissionScreen::Drawer () for (unsigned i=0; i < mOverlays.Size(); i++) { if (CheckOverlay(i)) - screen->DrawTexture (TexMan[mOverlays[i].mPic], mOverlays[i].x, mOverlays[i].y, DTA_320x200, true, TAG_DONE); + screen->DrawTexture (TexMan.GetTexture(mOverlays[i].mPic), mOverlays[i].x, mOverlays[i].y, DTA_320x200, true, TAG_DONE); } if (!mFlatfill) screen->FillBorder (NULL); } @@ -229,11 +229,11 @@ void DIntermissionScreenFader::Drawer () if (mType == FADE_In) factor = 1.0 - factor; int color = MAKEARGB(int(factor*255), 0,0,0); - screen->DrawTexture (TexMan[mBackground], 0, 0, DTA_Fullscreen, true, DTA_ColorOverlay, color, TAG_DONE); + screen->DrawTexture (TexMan.GetTexture(mBackground), 0, 0, DTA_Fullscreen, true, DTA_ColorOverlay, color, TAG_DONE); for (unsigned i=0; i < mOverlays.Size(); i++) { if (CheckOverlay(i)) - screen->DrawTexture (TexMan[mOverlays[i].mPic], mOverlays[i].x, mOverlays[i].y, DTA_320x200, true, DTA_ColorOverlay, color, TAG_DONE); + screen->DrawTexture (TexMan.GetTexture(mOverlays[i].mPic), mOverlays[i].x, mOverlays[i].y, DTA_320x200, true, DTA_ColorOverlay, color, TAG_DONE); } screen->FillBorder (NULL); } @@ -611,8 +611,8 @@ int DIntermissionScreenScroller::Responder (event_t *ev) void DIntermissionScreenScroller::Drawer () { - FTexture *tex = TexMan[mFirstPic]; - FTexture *tex2 = TexMan[mSecondPic]; + FTexture *tex = TexMan.GetTexture(mFirstPic); + FTexture *tex2 = TexMan.GetTexture(mSecondPic); if (mTicker >= mScrollDelay && mTicker < mScrollDelay + mScrollTime && tex != NULL && tex2 != NULL) { diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 708b100aa..2456e4a8f 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -4574,10 +4574,10 @@ bool DLevelScript::DoCheckActorTexture(int tid, AActor *activator, int string, b { return 0; } - FTexture *tex = TexMan.FindTexture(FBehavior::StaticLookupString(string), ETextureType::Flat, + FTextureID tex = TexMan.CheckForTexture(FBehavior::StaticLookupString(string), ETextureType::Flat, FTextureManager::TEXMAN_Overridable|FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_DontCreate); - if (tex == NULL) + if (!tex.Exists()) { // If the texture we want to check against doesn't exist, then // they're obviously not the same. return 0; @@ -4596,7 +4596,7 @@ bool DLevelScript::DoCheckActorTexture(int tid, AActor *activator, int string, b NextHighestCeilingAt(actor->Sector, actor->X(), actor->Y(), actor->Z(), actor->Top(), 0, &resultsec, &resffloor); secpic = resffloor ? *resffloor->bottom.texture : resultsec->planes[sector_t::ceiling].Texture; } - return tex == TexMan[secpic]; + return tex == secpic; } @@ -6690,7 +6690,7 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound) auto a = SingleActorFromTID(args[0], activator); if (a != nullptr) { - return GlobalACSStrings.AddString(TexMan[a->floorpic]->GetName()); + return GlobalACSStrings.AddString(TexMan.GetTexture(a->floorpic)->GetName()); } else { diff --git a/src/p_doors.cpp b/src/p_doors.cpp index aac4097f9..da7d1336e 100644 --- a/src/p_doors.cpp +++ b/src/p_doors.cpp @@ -293,7 +293,7 @@ void DDoor::DoorSound(bool raise, DSeqNode *curseq) const if (line->backsector == NULL) continue; - FTexture *tex = TexMan[line->sidedef[0]->GetTexture(side_t::top)]; + FTexture *tex = TexMan.GetTexture(line->sidedef[0]->GetTexture(side_t::top)); texname = tex ? tex->GetName().GetChars() : NULL; if (texname != NULL && texname[0] == 'D' && texname[1] == 'O' && texname[2] == 'R') { @@ -715,7 +715,7 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay, picnum = tex1[side_t::top].texture; - FTexture *tex = TexMan[picnum]; + FTexture *tex = TexMan.GetTexture(picnum); topdist = tex ? tex->GetDisplayHeight() : 64; topdist = m_Sector->ceilingplane.fD() - topdist * m_Sector->ceilingplane.fC(); diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 43da7038f..d716fd8bf 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -477,7 +477,7 @@ static inline void CheckShortestTex (FTextureID texnum, double &minsize) { if (texnum.isValid() || (texnum.isNull() && (i_compatflags & COMPATF_SHORTTEX))) { - FTexture *tex = TexMan[texnum]; + FTexture *tex = TexMan.GetTexture(texnum); if (tex != NULL) { double h = tex->GetDisplayHeight(); @@ -1144,7 +1144,7 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac) auto c = planes[sector_t::floor].GlowColor; if (c == 0) { - FTexture *tex = TexMan[GetTexture(sector_t::floor)]; + FTexture *tex = TexMan.GetTexture(GetTexture(sector_t::floor)); if (tex != NULL && tex->isGlowing()) { if (!tex->isAutoGlowing()) tex = TexMan.GetTexture(GetTexture(sector_t::floor), true); @@ -1189,7 +1189,7 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac) auto c = planes[sector_t::ceiling].GlowColor; if (c == 0) { - FTexture *tex = TexMan[GetTexture(sector_t::ceiling)]; + FTexture *tex = TexMan.GetTexture(GetTexture(sector_t::ceiling)); if (tex != NULL && tex->isGlowing()) { if (!tex->isAutoGlowing()) tex = TexMan.GetTexture(GetTexture(sector_t::ceiling), true); @@ -1213,7 +1213,7 @@ double GetFriction(const sector_t *self, int plane, double *pMoveFac) c = planes[sector_t::floor].GlowColor; if (c == 0) { - FTexture *tex = TexMan[GetTexture(sector_t::floor)]; + FTexture *tex = TexMan.GetTexture(GetTexture(sector_t::floor)); if (tex != NULL && tex->isGlowing()) { if (!tex->isAutoGlowing()) tex = TexMan.GetTexture(GetTexture(sector_t::floor), true); diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index a0a5dd597..64a115290 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -227,7 +227,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p picnum = sprframe->Texture[0]; flip = sprframe->Flip & 1; - ttex = TexMan.GetPalettedTexture(picnum, true); + ttex = TexMan.GetTexture(picnum); if (!ttex->isValid()) return; diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 79ddf2312..be5b85f00 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -336,7 +336,7 @@ FSoftwareTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool rot = (ang - thing->Angles.Yaw + (45.0 / 2 * 9 - 180.0 / 16)).BAMs() >> 28; } flipX = (sprframe->Flip & (1 << rot)) != 0; - ttex = TexMan[sprframe->Texture[rot]]; // Do not animate the rotation + ttex = TexMan.GetPalettedTexture(sprframe->Texture[rot], false); // Do not animate the rotation tex = ttex->GetSoftwareTexture(); if (!ttex || !ttex->isValid()) { @@ -371,7 +371,7 @@ FSoftwareTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool DAngle sprangle = thing->GetSpriteAngle((pos - viewpoint.Pos).Angle(), viewpoint.TicFrac); FTextureID tex = sprdef->GetSpriteFrame(thing->frame, -1, sprangle, &flipX); if (!tex.isValid()) return nullptr; - return TexMan[tex]->GetSoftwareTexture(); + return TexMan.GetPalettedTexture(tex, false)->GetSoftwareTexture(); } } } diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 2baa54ec1..fa67b9c55 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -977,7 +977,7 @@ class GLDefsParser sc.MustGetString(); if (facecount<6) { - sb->faces[facecount] = TexMan[TexMan.GetTextureID(sc.String, ETextureType::Wall, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_Overridable)]; + sb->faces[facecount] = TexMan.GetTexture(TexMan.GetTextureID(sc.String, ETextureType::Wall, FTextureManager::TEXMAN_TryAny|FTextureManager::TEXMAN_Overridable)); } facecount++; } @@ -1008,7 +1008,7 @@ class GLDefsParser { sc.MustGetString(); FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Flat,FTextureManager::TEXMAN_TryAny); - FTexture *tex = TexMan[flump]; + FTexture *tex = TexMan.GetTexture(flump); if (tex) tex->bAutoGlowing = tex->bGlowing = tex->bFullbright = true; } } @@ -1019,7 +1019,7 @@ class GLDefsParser { sc.MustGetString(); FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Wall,FTextureManager::TEXMAN_TryAny); - FTexture *tex = TexMan[flump]; + FTexture *tex = TexMan.GetTexture(flump); if (tex) tex->bAutoGlowing = tex->bGlowing = tex->bFullbright = true; } } @@ -1028,7 +1028,7 @@ class GLDefsParser sc.SetCMode(true); sc.MustGetString(); FTextureID flump=TexMan.CheckForTexture(sc.String, ETextureType::Flat,FTextureManager::TEXMAN_TryAny); - FTexture *tex = TexMan[flump]; + FTexture *tex = TexMan.GetTexture(flump); sc.MustGetStringName(","); sc.MustGetString(); PalEntry color = V_GetColor(NULL, sc.String); @@ -1081,7 +1081,7 @@ class GLDefsParser sc.MustGetString(); FTextureID no = TexMan.CheckForTexture(sc.String, type, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_Overridable); - FTexture *tex = TexMan[no]; + FTexture *tex = TexMan.GetTexture(no); sc.MustGetToken('{'); while (!sc.CheckToken('}')) @@ -1186,7 +1186,7 @@ class GLDefsParser sc.MustGetString(); FTextureID no = TexMan.CheckForTexture(sc.String, type, FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_Overridable); - FTexture *tex = TexMan[no]; + FTexture *tex = TexMan.GetTexture(no); sc.MustGetToken('{'); while (!sc.CheckToken('}')) @@ -1489,7 +1489,7 @@ class GLDefsParser sc.MustGetString(); FTextureID no = TexMan.CheckForTexture(sc.String, type); - FTexture *tex = TexMan[no]; + FTexture *tex = TexMan.GetTexture(no); sc.MustGetToken('{'); while (!sc.CheckToken('}')) diff --git a/src/r_data/sprites.cpp b/src/r_data/sprites.cpp index 6af8f5bda..f8a53cf7d 100644 --- a/src/r_data/sprites.cpp +++ b/src/r_data/sprites.cpp @@ -122,7 +122,7 @@ static bool R_InstallSpriteLump (FTextureID lump, unsigned frame, char rot, bool if (frame >= MAX_SPRITE_FRAMES || rotation > 16) { - Printf (TEXTCOLOR_RED "R_InstallSpriteLump: Bad frame characters in lump %s\n", TexMan[lump]->GetName().GetChars()); + Printf (TEXTCOLOR_RED "R_InstallSpriteLump: Bad frame characters in lump %s\n", TexMan.GetTexture(lump)->GetName().GetChars()); return false; } @@ -286,7 +286,7 @@ void R_InstallSprite (int num, spriteframewithrotate *sprtemp, int &maxframe) { for (int rot = 0; rot < 16; ++rot) { - TexMan[sprtemp[frame].Texture[rot]]->Rotations = framestart + frame; + TexMan.GetTexture(sprtemp[frame].Texture[rot])->Rotations = framestart + frame; } } } @@ -414,7 +414,7 @@ void R_InitSpriteDefs () int hash = hashes[intname % smax].Head; while (hash != -1) { - FTexture *tex = TexMan[hash]; + FTexture *tex = TexMan.GetTexture(hash); if (TEX_DWNAME(tex) == intname) { bool res = R_InstallSpriteLump (FTextureID(hash), tex->Name[4] - 'A', tex->Name[5], false, sprtemp, maxframe); diff --git a/src/r_utility.cpp b/src/r_utility.cpp index d12f3bf4d..bce73181c 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -1069,7 +1069,7 @@ void FCanvasTextureInfo::Add (AActor *viewpoint, FTextureID picnum, double fov) { return; } - texture = static_cast(TexMan[picnum]); + texture = static_cast(TexMan.GetTexture(picnum)); if (!texture->bHasCanvas) { Printf ("%s is not a valid target for a camera\n", texture->Name.GetChars()); @@ -1109,7 +1109,7 @@ void SetCameraToTexture(AActor *viewpoint, const FString &texturename, double fo if (textureid.isValid()) { // Only proceed if the texture actually has a canvas. - FTexture *tex = TexMan[textureid]; + FTexture *tex = TexMan.GetTexture(textureid); if (tex && tex->isCanvas()) { FCanvasTextureInfo::Add(viewpoint, textureid, fov); diff --git a/src/scripting/vm/jit_move.cpp b/src/scripting/vm/jit_move.cpp index 0706f37b6..54c055cb2 100644 --- a/src/scripting/vm/jit_move.cpp +++ b/src/scripting/vm/jit_move.cpp @@ -53,7 +53,7 @@ static void CastCo2S(FString *a, int b) { PalEntry c(b); a->Format("%02x %02x %0 static int CastS2So(FString *b) { return FSoundID(*b); } static void CastSo2S(FString *a, int b) { *a = S_sfx[b].name; } static void CastSID2S(FString *a, unsigned int b) { *a = (b >= sprites.Size()) ? "TNT1" : sprites[b].name; } -static void CastTID2S(FString *a, int b) { auto tex = TexMan[*(FTextureID*)&b]; *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); } +static void CastTID2S(FString *a, int b) { auto tex = TexMan.GetTexture(*(FTextureID*)&b); *a = (tex == nullptr) ? "(null)" : tex->GetName().GetChars(); } void JitCompiler::EmitCAST() { diff --git a/src/scripting/vm/vmexec.h b/src/scripting/vm/vmexec.h index d24534987..97996376d 100644 --- a/src/scripting/vm/vmexec.h +++ b/src/scripting/vm/vmexec.h @@ -1874,7 +1874,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c case CAST_TID2S: { ASSERTS(a); ASSERTD(b); - auto tex = TexMan[*(FTextureID*)&(reg.d[b])]; + auto tex = TexMan.GetTexture(*(FTextureID*)&(reg.d[b])); reg.s[a] = tex == nullptr ? "(null)" : tex->GetName().GetChars(); break; } diff --git a/src/serializer.cpp b/src/serializer.cpp index c6a0191bf..535c739e7 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -1515,7 +1515,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTe } FTextureID chk = value; if (chk.GetIndex() >= TexMan.NumTextures()) chk.SetNull(); - FTexture *pic = TexMan[chk]; + FTexture *pic = TexMan.GetTexture(chk); const char *name; if (Wads.GetLinkedTexture(pic->SourceLump) == pic) diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index e2a8c7877..1b03361ef 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -1054,7 +1054,7 @@ namespace swrenderer { sprite.renderflags ^= RF_XFLIP; } - sprite.tex = TexMan[sprite.picnum]; // Do not animate the rotation + sprite.tex = TexMan.GetPalettedTexture(sprite.picnum, false); // Do not animate the rotation } } else @@ -1084,7 +1084,7 @@ namespace swrenderer { sprite.renderflags ^= RF_XFLIP; } - sprite.tex = TexMan[tex]; // Do not animate the rotation + sprite.tex = TexMan.GetPalettedTexture(tex, false); // Do not animate the rotation } if (r_drawvoxels) diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 3020ce07c..548bb5c8a 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -224,7 +224,7 @@ namespace swrenderer picnum = sprframe->Texture[0]; flip = sprframe->Flip & 1; - tex = TexMan.GetTexture(picnum, true); + tex = TexMan.GetTexture(picnum); if (!tex->isValid()) return; diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index 31c8ffd21..e89c66dde 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -1234,7 +1234,7 @@ void FMultiPatchTexture::ResolvePatches() TexMan.ListTextures(Inits[i].TexName, list, true); for (int i = list.Size() - 1; i >= 0; i--) { - if (list[i] != id && !TexMan[list[i]]->bMultiPatch) + if (list[i] != id && !TexMan.GetTexture(list[i])->bMultiPatch) { texno = list[i]; break; @@ -1263,7 +1263,7 @@ void FMultiPatchTexture::ResolvePatches() } else { - Parts[i].Texture = TexMan[texno]; + Parts[i].Texture = TexMan.GetTexture(texno); bComplex |= Parts[i].Texture->bComplex; Parts[i].Texture->bKeepAround = true; if (Inits[i].UseOffsets) diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 76e512cdf..e470cff66 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -1116,8 +1116,8 @@ void FTextureManager::InitPalettedVersions() } if (pic1.isValid() && pic2.isValid()) { - FTexture *owner = TexMan[pic1]; - FTexture *owned = TexMan[pic2]; + FTexture *owner = GetTexture(pic1); + FTexture *owned = GetTexture(pic2); if (owner && owned) owner->PalVersion = owned; } @@ -1135,7 +1135,7 @@ FTextureID FTextureManager::PalCheck(FTextureID tex) { // In any true color mode this shouldn't do anything. if (vid_nopalsubstitutions || V_IsTrueColor()) return tex; - auto ftex = operator[](tex); + auto ftex = GetTexture(tex); if (ftex != nullptr && ftex->PalVersion != nullptr) return ftex->PalVersion->id; return tex; } @@ -1259,7 +1259,7 @@ void FTextureManager::AdjustSpriteOffsets() Wads.GetLumpName(str, i); str[8] = 0; FTextureID texid = TexMan.CheckForTexture(str, ETextureType::Sprite, 0); - if (texid.isValid() && Wads.GetLumpFile(TexMan[texid]->SourceLump) > Wads.GetIwadNum()) + if (texid.isValid() && Wads.GetLumpFile(GetTexture(texid)->SourceLump) > Wads.GetIwadNum()) { // This texture has been replaced by some PWAD. memcpy(&sprid, str, 4); @@ -1294,7 +1294,7 @@ void FTextureManager::AdjustSpriteOffsets() } if (texno.isValid()) { - FTexture * tex = TexMan[texno]; + FTexture * tex = GetTexture(texno); int lumpnum = tex->GetSourceLump(); // We only want to change texture offsets for sprites in the IWAD or the file this lump originated from. diff --git a/src/textures/textures.h b/src/textures/textures.h index e8eca3b0d..a7b80e58f 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -558,14 +558,6 @@ public: FTextureManager (); ~FTextureManager (); - // Get texture without translation -//private: - FTexture *operator[] (FTextureID texnum) - { - if ((unsigned)texnum.GetIndex() >= Textures.Size()) return NULL; - return Textures[texnum.GetIndex()].Texture; - } - // This only gets used in UI code so we do not need PALVERS handling. FTexture *GetTextureByName(const char *name, bool animate = false) { @@ -575,9 +567,9 @@ public: else return Textures[Translation[texnum.GetIndex()]].Texture; } - FTexture *GetTexture(FTextureID texnum, bool animate) + FTexture *GetTexture(FTextureID texnum, bool animate = false) { - if ((size_t)texnum.texnum >= Textures.Size()) return nullptr; + if ((size_t)texnum.GetIndex() >= Textures.Size()) return nullptr; if (animate) texnum = Translation[texnum.GetIndex()]; return Textures[texnum.GetIndex()].Texture; } diff --git a/src/v_font.cpp b/src/v_font.cpp index c875c6eec..276b7cb62 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -384,7 +384,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, !TexMan.CheckForTexture("STCFN122", ETextureType::MiscPatch).isValid()) { // insert the incorrectly named '|' graphic in its correct position. - if (count > 124-start) charLumps[124-start] = TexMan[lump]; + if (count > 124-start) charLumps[124-start] = TexMan.GetTexture(lump); lump.SetInvalid(); stcfn121 = true; } @@ -392,7 +392,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, if (lump.isValid()) { - FTexture *pic = TexMan[lump]; + FTexture *pic = TexMan.GetTexture(lump); if (pic != NULL) { // set the lump here only if it represents a valid texture @@ -994,7 +994,7 @@ FSingleLumpFont::FSingleLumpFont (const char *name, int lump) : FFont(lump) void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) { - FTexture *pic = TexMan[picnum]; + FTexture *pic = TexMan.GetTexture(picnum); FontHeight = pic->GetDisplayHeight (); SpaceWidth = pic->GetDisplayWidth (); @@ -1492,7 +1492,7 @@ FSinglePicFont::FSinglePicFont(const char *picname) : I_FatalError ("%s is not a font or texture", picname); } - FTexture *pic = TexMan[picnum]; + FTexture *pic = TexMan.GetTexture(picnum); FontName = picname; FontHeight = pic->GetDisplayHeight(); @@ -2143,7 +2143,7 @@ void V_InitCustomFonts() FTextureID texid = TexMan.CheckForTexture(sc.String, ETextureType::MiscPatch); if (texid.Exists()) { - *p = TexMan[texid]; + *p = TexMan.GetTexture(texid); } else if (Wads.GetLumpFile(sc.LumpNum) >= Wads.GetIwadNum()) { diff --git a/src/wi_stuff.cpp b/src/wi_stuff.cpp index 17f6a913a..905a27287 100644 --- a/src/wi_stuff.cpp +++ b/src/wi_stuff.cpp @@ -519,7 +519,7 @@ bool DInterBackground::LoadBackground(bool isenterpic) texture = TexMan.GetTextureID("INTERPIC", ETextureType::MiscPatch); } } - background = TexMan[texture]; + background = TexMan.GetTexture(texture); return noautostartmap; } From 69cc1f831c7cc9f5988b2974fddf9fb106de8747 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 7 Dec 2018 03:35:10 +0100 Subject: [PATCH 14/66] Renamed FTexture::GetPixels This was needed to allow refactoring without letting all the other GetPixels get in the way. --- src/swrenderer/textures/r_swtexture.h | 2 +- src/textures/formats/canvastexture.cpp | 2 +- src/textures/formats/multipatchtexture.cpp | 4 +-- src/textures/formats/worldtexture.cpp | 2 +- src/textures/skyboxtexture.cpp | 4 +-- src/textures/skyboxtexture.h | 2 +- src/textures/texture.cpp | 39 +++++++++++++++++----- src/textures/textures.h | 6 ++-- src/v_font.cpp | 14 ++++---- 9 files changed, 49 insertions(+), 26 deletions(-) diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index 8c3e5a2f1..273a748db 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -96,7 +96,7 @@ public: // Returns the whole texture, stored in column-major order virtual const uint8_t *GetPixels(FRenderStyle style) { - return mTexture->GetPixels(style); + return mTexture->Get8BitPixels(style); } void Unload() diff --git a/src/textures/formats/canvastexture.cpp b/src/textures/formats/canvastexture.cpp index eb3982702..683e9f9d6 100644 --- a/src/textures/formats/canvastexture.cpp +++ b/src/textures/formats/canvastexture.cpp @@ -56,7 +56,7 @@ FCanvasTexture::~FCanvasTexture () Unload (); } -const uint8_t *FCanvasTexture::GetPixels (FRenderStyle style) +const uint8_t *FCanvasTexture::Get8BitPixels (FRenderStyle style) { bNeedsUpdate = true; if (Canvas == NULL) diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index e89c66dde..226f85de9 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -198,7 +198,7 @@ protected: uint8_t *MakeTexture (FRenderStyle style); // The getters must optionally redirect if it's a simple one-patch texture. - const uint8_t *GetPixels(FRenderStyle style) override { return bRedirect ? Parts->Texture->GetPixels(style) : FWorldTexture::GetPixels(style); } + const uint8_t *Get8BitPixels(FRenderStyle style) override { return bRedirect ? Parts->Texture->Get8BitPixels(style) : FWorldTexture::Get8BitPixels(style); } private: @@ -1289,7 +1289,7 @@ void FMultiPatchTexture::ResolvePatches() CheckForHacks(); // If this texture is just a wrapper around a single patch, we can simply - // forward GetPixels() and GetColumn() calls to that patch. + // forward getter calls to that patch. if (NumParts == 1) { diff --git a/src/textures/formats/worldtexture.cpp b/src/textures/formats/worldtexture.cpp index 6613265fd..edba839c6 100644 --- a/src/textures/formats/worldtexture.cpp +++ b/src/textures/formats/worldtexture.cpp @@ -83,7 +83,7 @@ void FWorldTexture::Unload () // //========================================================================== -const uint8_t *FWorldTexture::GetPixels (FRenderStyle style) +const uint8_t *FWorldTexture::Get8BitPixels (FRenderStyle style) { int index = !!(style.Flags & STYLEF_RedIsAlpha); if (Pixeldata[index] == nullptr) diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 9cc1baa4b..a1f22d9f4 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -59,9 +59,9 @@ FSkyBox::~FSkyBox() // //----------------------------------------------------------------------------- -const uint8_t *FSkyBox::GetPixels (FRenderStyle style) +const uint8_t *FSkyBox::Get8BitPixels (FRenderStyle style) { - if (faces[0]) return faces[0]->GetPixels(style); + if (faces[0]) return faces[0]->Get8BitPixels(style); return NULL; } diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index b796d4281..08dfdd653 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -18,7 +18,7 @@ public: FSkyBox(const char *name = nullptr); ~FSkyBox(); //const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); - const uint8_t *GetPixels (FRenderStyle style); + const uint8_t *Get8BitPixels (FRenderStyle style); int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); bool UseBasePalette(); void Unload (); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index ed3eedb28..61cc9ab44 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -256,7 +256,7 @@ void FTexture::SetFrontSkyLayer () void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style) { - const uint8_t *pixels = GetPixels(style); + const uint8_t *pixels = Get8BitPixels(style); int srcwidth = Width; int srcheight = Height; int step_x = Height; @@ -435,7 +435,7 @@ void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat f { case TEX_Pal: case TEX_Gray: - pix = GetPixels(fmt == TEX_Pal? DefaultRenderStyle() : LegacyRenderStyles[STYLE_Shaded]); + pix = Get8BitPixels(fmt == TEX_Pal? DefaultRenderStyle() : LegacyRenderStyles[STYLE_Shaded]); stride = pitch - w; for (y = 0; y < h; ++y) { @@ -479,14 +479,14 @@ int FTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyI { PalEntry *palette = screen->GetPalette(); for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values - bmp->CopyPixelData(x, y, GetPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, palette, inf); + bmp->CopyPixelData(x, y, Get8BitPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, palette, inf); for(int i=1;i<256;i++) palette[i].a = 0; return 0; } int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf) { - bmp->CopyPixelData(x, y, GetPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, remap, inf); + bmp->CopyPixelData(x, y, Get8BitPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, remap, inf); return 0; } @@ -596,7 +596,7 @@ PalEntry FTexture::GetSkyCapColor(bool bottom) int FTexture::CheckRealHeight() { - auto pixels = GetPixels(DefaultRenderStyle()); + auto pixels = Get8BitPixels(DefaultRenderStyle()); for(int h = GetHeight()-1; h>= 0; h--) { @@ -683,11 +683,11 @@ void FTexture::CreateDefaultBrightmap() if (UseBasePalette() && TexMan.HasGlobalBrightmap && UseType != ETextureType::Decal && UseType != ETextureType::MiscPatch && UseType != ETextureType::FontChar && Brightmap == NULL && bWarped == 0 && - GetPixels(DefaultRenderStyle()) + Get8BitPixels(DefaultRenderStyle()) ) { // May have one - let's check when we use this texture - const uint8_t *texbuf = GetPixels(DefaultRenderStyle()); + const uint8_t *texbuf = Get8BitPixels(DefaultRenderStyle()); const int white = ColorMatcher.Pick(255, 255, 255); int size = GetWidth() * GetHeight(); @@ -1054,7 +1054,7 @@ void FTexture::SetSpriteAdjust() // //=========================================================================== -const uint8_t *FTexture::GetPixels(FRenderStyle style) +const uint8_t *FTexture::Get8BitPixels(FRenderStyle style) { return nullptr; } @@ -1212,3 +1212,26 @@ void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y) mWidth = tex->GetWidth(); } +///////////// + + +class TextureCache +{ + struct ItemCacheInfo + { + int palettedCount; // counts use of final paletted textures + int palettedCountCompose; // counts use of images needed for composition (can be freed after precaching) + int rgbaCount; // counts use of final true color software textures + int rawCount; // counts use of raw images needed for composition (can be freed after precaching) + int textureCount; // counts use of hardware textures + }; + TMap> pixelCachePaletted; // 8 bit column major for composition and software rendering + TMap> pixelCacheRgba; // 32 bit column major for software true color rendering + TMap> pixelCacheRaw; // 32 bit row major for composition + TMap hwTextureCache; // native system textures. + + TMap cacheMarker; + + void PrecacheLevel(); +}; + diff --git a/src/textures/textures.h b/src/textures/textures.h index a7b80e58f..ec0df68ee 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -387,7 +387,7 @@ protected: // Returns the whole texture, stored in column-major order - virtual const uint8_t *GetPixels(FRenderStyle style); + virtual const uint8_t *Get8BitPixels(FRenderStyle style); // Returns true if GetPixelsBgra includes mipmaps virtual bool Mipmapped() { return true; } @@ -746,7 +746,7 @@ protected: ~FWorldTexture(); void Unload() override; - const uint8_t *GetPixels(FRenderStyle style) override; + const uint8_t *Get8BitPixels(FRenderStyle style) override; virtual uint8_t *MakeTexture(FRenderStyle style) = 0; }; @@ -772,7 +772,7 @@ public: //const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); //const uint32_t *GetPixelsBgra() override; - const uint8_t *GetPixels (FRenderStyle style); + const uint8_t *Get8BitPixels (FRenderStyle style); void Unload (); bool CheckModified (FRenderStyle) /*override*/; void NeedUpdate() { bNeedsUpdate=true; } diff --git a/src/v_font.cpp b/src/v_font.cpp index 276b7cb62..c2d56717c 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -171,7 +171,7 @@ class FFontChar1 : public FTexture { public: FFontChar1 (FTexture *sourcelump); - const uint8_t *GetPixels (FRenderStyle style); + const uint8_t *Get8BitPixels (FRenderStyle style); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); ~FFontChar1 (); @@ -191,7 +191,7 @@ public: FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); ~FFontChar2 (); - const uint8_t *GetPixels (FRenderStyle style); + const uint8_t *Get8BitPixels (FRenderStyle style); void SetSourceRemap(const uint8_t *sourceremap); void Unload (); @@ -530,7 +530,7 @@ void RecordTextureColors (FTexture *pic, uint8_t *usedcolors) { int x; - auto pixels = pic->GetPixels(DefaultRenderStyle()); + auto pixels = pic->Get8BitPixels(DefaultRenderStyle()); auto size = pic->GetWidth() * pic->GetHeight(); for(x = 0;x < size; x++) @@ -1569,7 +1569,7 @@ FFontChar1::FFontChar1 (FTexture *sourcelump) // //========================================================================== -const uint8_t *FFontChar1::GetPixels (FRenderStyle) +const uint8_t *FFontChar1::Get8BitPixels (FRenderStyle) { if (Pixels == NULL) { @@ -1589,7 +1589,7 @@ void FFontChar1::MakeTexture () // Make the texture as normal, then remap it so that all the colors // are at the low end of the palette Pixels = new uint8_t[Width*Height]; - const uint8_t *pix = BaseTexture->GetPixels(DefaultRenderStyle()); + const uint8_t *pix = BaseTexture->Get8BitPixels(DefaultRenderStyle()); if (!SourceRemap) { @@ -1690,13 +1690,13 @@ void FFontChar2::Unload () //========================================================================== // -// FFontChar2 :: GetPixels +// FFontChar2 :: Get8BitPixels // // Like for FontChar1, the render style has no relevance here as well. // //========================================================================== -const uint8_t *FFontChar2::GetPixels (FRenderStyle) +const uint8_t *FFontChar2::Get8BitPixels (FRenderStyle) { if (Pixels == NULL) { From 82bd742ea3b21f8fe8fcd633d507b6008100e1ae Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 8 Dec 2018 12:42:35 +0100 Subject: [PATCH 15/66] - reworked how the software renderer manages its textures. * it's no longer the main texture objects managing the pixel buffer but FSoftwareTexture. * create proper spans for true color textures. The paletted spans only match if the image does not have any translucent pixels. * create proper warp textures instead of working off the paletted variants. As a side effect, caching of pixel buffers for texture composition is temporarily disabled, as it management of texture redirections. These things will be reimplemented once things progress further. The existing methods here had their share of serious issues that should be fixed. --- src/polyrenderer/poly_renderthread.cpp | 8 +- src/r_data/models/models_voxel.cpp | 8 +- src/r_utility.cpp | 2 +- src/swrenderer/r_renderthread.cpp | 8 +- src/swrenderer/textures/r_swtexture.cpp | 153 ++++++++++++++------- src/swrenderer/textures/r_swtexture.h | 70 +++++----- src/swrenderer/textures/warptexture.cpp | 30 ++-- src/textures/formats/automaptexture.cpp | 8 +- src/textures/formats/brightmaptexture.cpp | 8 -- src/textures/formats/buildtexture.cpp | 11 +- src/textures/formats/canvastexture.cpp | 12 +- src/textures/formats/ddstexture.cpp | 16 +-- src/textures/formats/emptytexture.cpp | 10 +- src/textures/formats/flattexture.cpp | 12 +- src/textures/formats/imgztexture.cpp | 10 +- src/textures/formats/jpegtexture.cpp | 13 +- src/textures/formats/multipatchtexture.cpp | 19 ++- src/textures/formats/patchtexture.cpp | 16 +-- src/textures/formats/pcxtexture.cpp | 23 ++-- src/textures/formats/pngtexture.cpp | 31 ++--- src/textures/formats/rawpagetexture.cpp | 10 +- src/textures/formats/shadertexture.cpp | 11 +- src/textures/formats/tgatexture.cpp | 9 +- src/textures/formats/worldtexture.cpp | 46 ------- src/textures/skyboxtexture.cpp | 27 +--- src/textures/skyboxtexture.h | 4 +- src/textures/texture.cpp | 67 ++++----- src/textures/texturemanager.cpp | 14 -- src/textures/textures.h | 35 ++--- src/v_font.cpp | 136 +++--------------- src/v_font.h | 1 + 31 files changed, 322 insertions(+), 506 deletions(-) diff --git a/src/polyrenderer/poly_renderthread.cpp b/src/polyrenderer/poly_renderthread.cpp index f9bc3831c..d5b7b6284 100644 --- a/src/polyrenderer/poly_renderthread.cpp +++ b/src/polyrenderer/poly_renderthread.cpp @@ -91,14 +91,18 @@ void PolyRenderThread::PrepareTexture(FSoftwareTexture *texture, FRenderStyle st std::unique_lock lock(loadmutex); - texture->GetPixels(style); const FSoftwareTextureSpan *spans; - texture->GetColumn(style, 0, &spans); if (PolyRenderer::Instance()->RenderTarget->IsBgra()) { texture->GetPixelsBgra(); texture->GetColumnBgra(0, &spans); } + else + { + bool alpha = !!(style.Flags & STYLEF_RedIsAlpha); + texture->GetPixels(alpha); + texture->GetColumn(alpha, 0, &spans); + } } void PolyRenderThread::PreparePolyObject(subsector_t *sub) diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index 6067e2f9e..dca6a4cd8 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -53,7 +53,7 @@ public: int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; bool UseBasePalette() override { return false; } - uint8_t *MakeTexture(FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; protected: FVoxel *SourceVox; @@ -79,10 +79,10 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) // //=========================================================================== -uint8_t *FVoxelTexture::MakeTexture (FRenderStyle style) +TArray FVoxelTexture::Get8BitPixels(bool alphatex) { // GetPixels gets called when a translated palette is used so we still need to implement it here. - auto Pixels = new uint8_t[256]; + TArray Pixels(256, true); uint8_t *pp = SourceVox->Palette; if(pp != NULL) @@ -94,7 +94,7 @@ uint8_t *FVoxelTexture::MakeTexture (FRenderStyle style) pe.g = (pp[1] << 2) | (pp[1] >> 4); pe.b = (pp[2] << 2) | (pp[2] >> 4); // Alphatexture handling is just for completeness, but rather unlikely to be used ever. - Pixels[i] = (style.Flags & STYLEF_RedIsAlpha)? pe.r : ColorMatcher.Pick(pe); + Pixels[i] = alphatex? pe.r : ColorMatcher.Pick(pe); } } else diff --git a/src/r_utility.cpp b/src/r_utility.cpp index bce73181c..6adfbc5ac 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -1163,7 +1163,7 @@ void FCanvasTextureInfo::EmptyList () for (probe = List; probe != NULL; probe = next) { next = probe->Next; - probe->Texture->Unload(); + //probe->Texture->Unload(); delete probe; } List = NULL; diff --git a/src/swrenderer/r_renderthread.cpp b/src/swrenderer/r_renderthread.cpp index ae0837e6a..91c2c196c 100644 --- a/src/swrenderer/r_renderthread.cpp +++ b/src/swrenderer/r_renderthread.cpp @@ -106,14 +106,18 @@ namespace swrenderer std::unique_lock lock(loadmutex); - texture->GetPixels(style); const FSoftwareTextureSpan *spans; - texture->GetColumn(style, 0, &spans); if (Viewport->RenderTarget->IsBgra()) { texture->GetPixelsBgra(); texture->GetColumnBgra(0, &spans); } + else + { + bool alpha = !!(style.Flags & STYLEF_RedIsAlpha); + texture->GetPixels(alpha); + texture->GetColumn(alpha, 0, &spans); + } } void RenderThread::PreparePolyObject(subsector_t *sub) diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index 79560d5b2..8470227ce 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -39,7 +39,16 @@ #include "m_alloc.h" - +FSoftwareTexture *FTexture::GetSoftwareTexture() +{ + if (!SoftwareTexture) + { + if (bWarped) SoftwareTexture = new FWarpTexture(this, bWarped); + // else if (GetRedirect() != this) ... must be decided later. The current data structures make it hard to do this without creating a mess. + else SoftwareTexture = new FSoftwareTexture(this); + } + return SoftwareTexture; +} //========================================================================== // @@ -74,32 +83,31 @@ void FSoftwareTexture::CalcBitSize () HeightBits = i; } - //========================================================================== // // // //========================================================================== -const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) +const uint8_t *FSoftwareTexture::GetPixels(int style) { - const uint32_t *pixels = GetPixelsBgra(); - if (pixels == nullptr) return nullptr; - - column %= GetWidth(); - - if (spans_out != nullptr) - GetColumn(DefaultRenderStyle(), column, spans_out); // This isn't the right way to create the spans. - return pixels + column * GetHeight(); + if (Pixels.Size() == 0 || CheckModified(style)) + { + Pixels = mSource->Get8BitPixels(style); + } + return Pixels.Data(); } +//========================================================================== +// +// +// +//========================================================================== + const uint32_t *FSoftwareTexture::GetPixelsBgra() { - if (PixelsBgra.Size() == 0 || CheckModified(DefaultRenderStyle())) + if (PixelsBgra.Size() == 0 || CheckModified(2)) { - if (!GetColumn(DefaultRenderStyle(), 0, nullptr)) - return nullptr; - FBitmap bitmap; bitmap.Create(GetWidth(), GetHeight()); mTexture->CopyTrueColorPixels(&bitmap, 0, 0); @@ -108,13 +116,86 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra() return PixelsBgra.Data(); } +//========================================================================== +// +// +// +//========================================================================== + +const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const FSoftwareTextureSpan **spans_out) +{ + auto Pixeldata = GetPixels(index); + if ((unsigned)column >= (unsigned)GetWidth()) + { + if (WidthMask + 1 == GetWidth()) + { + column &= WidthMask; + } + else + { + column %= GetWidth(); + } + } + if (spans_out != nullptr) + { + if (Spandata[index] == nullptr) + { + Spandata[index] = CreateSpans(Pixeldata); + } + *spans_out = Spandata[index][column]; + } + return Pixeldata + column * GetHeight(); +} + //========================================================================== // // // //========================================================================== -FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const uint8_t *pixels) +const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) +{ + auto Pixeldata = GetPixelsBgra(); + if ((unsigned)column >= (unsigned)GetWidth()) + { + if (WidthMask + 1 == GetWidth()) + { + column &= WidthMask; + } + else + { + column %= GetWidth(); + } + } + if (spans_out != nullptr) + { + if (Spandata[2] == nullptr) + { + Spandata[2] = CreateSpans(Pixeldata); + } + *spans_out = Spandata[2][column]; + } + return Pixeldata + column * GetHeight(); +} + +//========================================================================== +// +// +// +//========================================================================== + +static bool isTranslucent(uint8_t val) +{ + return val == 0; +} + +static bool isTranslucent(uint32_t val) +{ + return (val & 0xff000000) == 0; +} + +template +FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const T *pixels) { FSoftwareTextureSpan **spans, *span; @@ -136,7 +217,7 @@ FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const uint8_t *pixels) int numcols = GetWidth(); int numrows = GetHeight(); int numspans = numcols; // One span to terminate each column - const uint8_t *data_p; + const T *data_p; bool newspan; int x, y; @@ -149,7 +230,7 @@ FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const uint8_t *pixels) for (y = numrows; y > 0; --y) { - if (*data_p++ == 0) + if (isTranslucent(*data_p++)) { if (!newspan) { @@ -174,7 +255,7 @@ FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const uint8_t *pixels) spans[x] = span; for (y = 0; y < numrows; ++y) { - if (*data_p++ == 0) + if (isTranslucent(*data_p++)) { if (!newspan) { @@ -441,41 +522,9 @@ void FSoftwareTexture::GenerateBgraMipmapsFast() // //========================================================================== -const uint8_t *FSoftwareTexture::GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) -{ - int index = !!(style.Flags & STYLEF_RedIsAlpha); - auto Pixeldata = GetPixels(style); - if ((unsigned)column >= (unsigned)GetWidth()) - { - if (WidthMask + 1 == GetWidth()) - { - column &= WidthMask; - } - else - { - column %= GetWidth(); - } - } - if (spans_out != nullptr) - { - if (Spandata[index] == nullptr) - { - Spandata[index] = CreateSpans (Pixeldata); - } - *spans_out = Spandata[index][column]; - } - return Pixeldata + column*GetHeight(); -} - -//========================================================================== -// -// -// -//========================================================================== - void FSoftwareTexture::FreeAllSpans() { - for(int i = 0; i < 2; i++) + for(int i = 0; i < 3; i++) { if (Spandata[i] != nullptr) { diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index 273a748db..af65003bf 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -15,13 +15,17 @@ class FSoftwareTexture protected: FTexture *mTexture; FTexture *mSource; + TArray Pixels; TArray PixelsBgra; - FSoftwareTextureSpan **Spandata[2] = { nullptr, nullptr }; + FSoftwareTextureSpan **Spandata[3] = { }; uint8_t WidthBits = 0, HeightBits = 0; uint16_t WidthMask = 0; + void FreeAllSpans(); + template FSoftwareTextureSpan **CreateSpans(const T *pixels); + void FreeSpans(FSoftwareTextureSpan **spans); + void CalcBitSize(); - public: FSoftwareTexture(FTexture *tex) { @@ -34,7 +38,7 @@ public: { FreeAllSpans(); } - + FTexture *GetTexture() const { return mTexture; @@ -51,7 +55,6 @@ public: return mTexture->bMasked; } - void CalcBitSize(); bool UseBasePalette() const { return mTexture->UseBasePalette(); } int GetSkyOffset() const { return mTexture->GetSkyOffset(); } PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); } @@ -93,35 +96,25 @@ public: DVector2 GetScale() const { return mTexture->Scale; } - // Returns the whole texture, stored in column-major order - virtual const uint8_t *GetPixels(FRenderStyle style) - { - return mTexture->Get8BitPixels(style); - } - void Unload() { - mTexture->Unload(); + Pixels.Reset(); PixelsBgra.Reset(); } // Returns true if the next call to GetPixels() will return an image different from the // last call to GetPixels(). This should be considered valid only if a call to CheckModified() // is immediately followed by a call to GetPixels(). - virtual bool CheckModified (FRenderStyle style) { return false; } + virtual bool CheckModified (int which) { return false; } void GenerateBgraFromBitmap(const FBitmap &bitmap); void CreatePixelsBgraWithMipmaps(); void GenerateBgraMipmaps(); void GenerateBgraMipmapsFast(); int MipmapLevels(); - void FreeAllSpans(); - - FSoftwareTextureSpan **CreateSpans (const uint8_t *pixels); - void FreeSpans (FSoftwareTextureSpan **spans); // Returns a single column of the texture - virtual const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); + virtual const uint8_t *GetColumn(int style, unsigned int column, const FSoftwareTextureSpan **spans_out); // Returns a single column of the texture, in BGRA8 format virtual const uint32_t *GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out); @@ -129,39 +122,42 @@ public: // Returns the whole texture, stored in column-major order, in BGRA8 format virtual const uint32_t *GetPixelsBgra(); - + // Returns the whole texture, stored in column-major order + virtual const uint8_t *GetPixels(int style); + + const uint8_t *GetPixels(FRenderStyle style) + { + bool alpha = !!(style.Flags & STYLEF_RedIsAlpha); + return GetPixels(alpha); + } + + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) + { + bool alpha = !!(style.Flags & STYLEF_RedIsAlpha); + return GetColumn(alpha, column, spans_out); + } + }; // A texture that returns a wiggly version of another texture. class FWarpTexture : public FSoftwareTexture { TArray WarpedPixels[2]; + TArray WarpedPixelsRgba; + int bWarped = 0; + uint64_t GenTime[3] = { 0, 0, 0 }; + int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd] + public: FWarpTexture (FTexture *source, int warptype); const uint32_t *GetPixelsBgra() override; - bool CheckModified (FRenderStyle) override; + const uint8_t *GetPixels(int style) override; + bool CheckModified (int which) override; - float GetSpeed() const { return mTexture->shaderspeed; } +private: - uint64_t GenTime[2] = { 0, 0 }; - uint64_t GenTimeBgra = 0; - int WidthOffsetMultiplier, HeightOffsetMultiplier; // [mxd] -protected: - - const uint8_t *GetPixels(FRenderStyle style); int NextPo2 (int v); // [mxd] void SetupMultipliers (int width, int height); // [mxd] }; - - -inline FSoftwareTexture *FTexture::GetSoftwareTexture() -{ - if (!SoftwareTexture) - { - if (bWarped) SoftwareTexture = new FWarpTexture(this, bWarped); - else SoftwareTexture = new FSoftwareTexture(this); - } - return SoftwareTexture; -} diff --git a/src/swrenderer/textures/warptexture.cpp b/src/swrenderer/textures/warptexture.cpp index 294bf694f..22cbcaf7d 100644 --- a/src/swrenderer/textures/warptexture.cpp +++ b/src/swrenderer/textures/warptexture.cpp @@ -49,38 +49,32 @@ FWarpTexture::FWarpTexture (FTexture *source, int warptype) bWarped = warptype; } -bool FWarpTexture::CheckModified (FRenderStyle style) +bool FWarpTexture::CheckModified (int style) { - return screen->FrameTime != GenTime[!!(style.Flags & STYLEF_RedIsAlpha)]; + return screen->FrameTime != GenTime[style]; } const uint32_t *FWarpTexture::GetPixelsBgra() { - auto Pixels = GetPixels(DefaultRenderStyle()); - if (PixelsBgra.Size() == 0 || GenTime[0] != GenTimeBgra) + uint64_t time = screen->FrameTime; + if (time != GenTime[2]) { - CreatePixelsBgraWithMipmaps(); - for (int i = 0; i < GetWidth() * GetHeight(); i++) - { - if (Pixels[i] != 0) - PixelsBgra[i] = 0xff000000 | GPalette.BaseColors[Pixels[i]].d; - else - PixelsBgra[i] = 0; - } - GenerateBgraMipmapsFast(); - GenTimeBgra = GenTime[0]; + auto otherpix = FSoftwareTexture::GetPixelsBgra(); + WarpedPixelsRgba.Resize(GetWidth() * GetHeight()); + WarpBuffer(WarpedPixelsRgba.Data(), otherpix, GetWidth(), GetHeight(), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->shaderspeed, bWarped); + FreeAllSpans(); + GenTime[2] = time; } - return PixelsBgra.Data(); + return WarpedPixelsRgba.Data(); } -const uint8_t *FWarpTexture::GetPixels(FRenderStyle style) +const uint8_t *FWarpTexture::GetPixels(int index) { - int index = !!(style.Flags & STYLEF_RedIsAlpha); uint64_t time = screen->FrameTime; if (time != GenTime[index]) { - const uint8_t *otherpix = FSoftwareTexture::GetPixels(style); + const uint8_t *otherpix = FSoftwareTexture::GetPixels(index); WarpedPixels[index].Resize(GetWidth() * GetHeight()); WarpBuffer(WarpedPixels[index].Data(), otherpix, GetWidth(), GetHeight(), WidthOffsetMultiplier, HeightOffsetMultiplier, time, mTexture->shaderspeed, bWarped); FreeAllSpans(); diff --git a/src/textures/formats/automaptexture.cpp b/src/textures/formats/automaptexture.cpp index b779da1d9..4eb4ec353 100644 --- a/src/textures/formats/automaptexture.cpp +++ b/src/textures/formats/automaptexture.cpp @@ -50,7 +50,7 @@ class FAutomapTexture : public FWorldTexture { public: FAutomapTexture(int lumpnum); - uint8_t *MakeTexture (FRenderStyle style); + TArray Get8BitPixels(bool alphatex); }; @@ -88,15 +88,15 @@ FAutomapTexture::FAutomapTexture (int lumpnum) // //========================================================================== -uint8_t *FAutomapTexture::MakeTexture (FRenderStyle style) +TArray FAutomapTexture::Get8BitPixels(bool alphatex) { int x, y; FMemLump data = Wads.ReadLump (SourceLump); const uint8_t *indata = (const uint8_t *)data.GetMem(); - auto Pixels = new uint8_t[Width * Height]; + TArray Pixels(Width * Height, true); - const uint8_t *remap = GetRemap(style); + const uint8_t *remap = GetRemap(alphatex); for (x = 0; x < Width; ++x) { for (y = 0; y < Height; ++y) diff --git a/src/textures/formats/brightmaptexture.cpp b/src/textures/formats/brightmaptexture.cpp index c649f3e17..314ac6f74 100644 --- a/src/textures/formats/brightmaptexture.cpp +++ b/src/textures/formats/brightmaptexture.cpp @@ -45,7 +45,6 @@ class FBrightmapTexture : public FWorldTexture public: FBrightmapTexture (FTexture *source); - uint8_t *MakeTexture(FRenderStyle style) override; int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; bool UseBasePalette() override { return false; } @@ -74,13 +73,6 @@ FBrightmapTexture::FBrightmapTexture (FTexture *source) SourceLump = -1; } -uint8_t *FBrightmapTexture::MakeTexture(FRenderStyle style) -{ - // This function is only necessary to satisfy the parent class's interface. - // This will never be called. - return nullptr; -} - int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) { SourcePic->CopyTrueColorTranslated(bmp, x, y, rotate, TexMan.GlobalBrightmap.Palette); diff --git a/src/textures/formats/buildtexture.cpp b/src/textures/formats/buildtexture.cpp index 69ec03d2c..9d4fa2fdc 100644 --- a/src/textures/formats/buildtexture.cpp +++ b/src/textures/formats/buildtexture.cpp @@ -56,7 +56,7 @@ class FBuildTexture : public FWorldTexture { public: FBuildTexture (const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top); - uint8_t *MakeTexture(FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; bool UseBasePalette() override { return false; } FTextureFormat GetFormat() override { return TEX_RGB; } @@ -76,7 +76,6 @@ protected: FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top) : RawPixels (pixels), Translation(translation) { - PixelsAreStatic = 3; Width = width; Height = height; _LeftOffset[1] = _LeftOffset[0] = left; @@ -85,16 +84,16 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8 UseType = ETextureType::Override; } -uint8_t *FBuildTexture::MakeTexture(FRenderStyle style) +TArray FBuildTexture::Get8BitPixels(bool alphatex) { - auto Pixels = new uint8_t[Width * Height]; + TArray Pixels(Width * Height, true); FRemapTable *Remap = translationtables[TRANSLATION_Standard][Translation]; for (int i = 0; i < Width*Height; i++) { auto c = RawPixels[i]; - Pixels[i] = (style.Flags & STYLEF_RedIsAlpha) ? Remap->Palette[c].Luminance() : Remap->Remap[c]; + Pixels[i] = alphatex ? Remap->Palette[c].Luminance() : Remap->Remap[c]; } - return (uint8_t*)Pixels; + return Pixels; } int FBuildTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) diff --git a/src/textures/formats/canvastexture.cpp b/src/textures/formats/canvastexture.cpp index 683e9f9d6..da6358928 100644 --- a/src/textures/formats/canvastexture.cpp +++ b/src/textures/formats/canvastexture.cpp @@ -51,12 +51,9 @@ FCanvasTexture::FCanvasTexture (const char *name, int width, int height) bPixelsAllocated = false; } -FCanvasTexture::~FCanvasTexture () -{ - Unload (); -} -const uint8_t *FCanvasTexture::Get8BitPixels (FRenderStyle style) +#if 0 +const uint8_t *FCanvasTexture::Get8BitPixels(bool alphatex) { bNeedsUpdate = true; if (Canvas == NULL) @@ -66,7 +63,6 @@ const uint8_t *FCanvasTexture::Get8BitPixels (FRenderStyle style) return Pixels; } -#if 0 const uint32_t *FCanvasTexture::GetPixelsBgra() { bNeedsUpdate = true; @@ -76,7 +72,6 @@ const uint32_t *FCanvasTexture::GetPixelsBgra() } return PixelsBgra; } -#endif void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical. { @@ -97,6 +92,7 @@ void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style memset (Pixels, 0, Width*Height/2); memset (Pixels+Width*Height/2, 255, Width*Height/2); } +#endif void FCanvasTexture::MakeTextureBgra() { @@ -118,6 +114,7 @@ void FCanvasTexture::MakeTextureBgra() memset(PixelsBgra + Width*Height / 2, 255, Width*Height / 2 * 4); } +#if 0 void FCanvasTexture::Unload () { if (bPixelsAllocated) @@ -148,6 +145,7 @@ void FCanvasTexture::Unload () FTexture::Unload(); } +#endif bool FCanvasTexture::CheckModified (FRenderStyle) { diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index 04f36adbb..5a2007e66 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -163,7 +163,7 @@ public: FDDSTexture (FileReader &lump, int lumpnum, void *surfdesc); FTextureFormat GetFormat () override; - uint8_t *MakeTexture(FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; protected: uint32_t Format; @@ -398,30 +398,30 @@ FTextureFormat FDDSTexture::GetFormat() // //========================================================================== -uint8_t *FDDSTexture::MakeTexture (FRenderStyle style) +TArray FDDSTexture::Get8BitPixels(bool alphatex) { auto lump = Wads.OpenLumpReader (SourceLump); - auto Pixels = new uint8_t[Width*Height]; + TArray Pixels(Width*Height, true); lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet); - int pmode = (style.Flags & STYLEF_RedIsAlpha) ? PIX_Alphatex : PIX_Palette; + int pmode = alphatex ? PIX_Alphatex : PIX_Palette; if (Format >= 1 && Format <= 4) // RGB: Format is # of bytes per pixel { - ReadRGB (lump, Pixels, pmode); + ReadRGB (lump, Pixels.Data(), pmode); } else if (Format == ID_DXT1) { - DecompressDXT1 (lump, Pixels, pmode); + DecompressDXT1 (lump, Pixels.Data(), pmode); } else if (Format == ID_DXT3 || Format == ID_DXT2) { - DecompressDXT3 (lump, Format == ID_DXT2, Pixels, pmode); + DecompressDXT3 (lump, Format == ID_DXT2, Pixels.Data(), pmode); } else if (Format == ID_DXT5 || Format == ID_DXT4) { - DecompressDXT5 (lump, Format == ID_DXT4, Pixels, pmode); + DecompressDXT5 (lump, Format == ID_DXT4, Pixels.Data(), pmode); } return Pixels; } diff --git a/src/textures/formats/emptytexture.cpp b/src/textures/formats/emptytexture.cpp index d49cdbf09..d793c9fb3 100644 --- a/src/textures/formats/emptytexture.cpp +++ b/src/textures/formats/emptytexture.cpp @@ -48,10 +48,9 @@ class FEmptyTexture : public FWorldTexture { - uint8_t Pixel = 0; public: FEmptyTexture (int lumpnum); - uint8_t *MakeTexture(FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; }; //========================================================================== @@ -82,7 +81,6 @@ FEmptyTexture::FEmptyTexture (int lumpnum) { bMasked = true; Width = Height = 1; - PixelsAreStatic = 3; } //========================================================================== @@ -91,8 +89,10 @@ FEmptyTexture::FEmptyTexture (int lumpnum) // //========================================================================== -uint8_t *FEmptyTexture::MakeTexture(FRenderStyle style) +TArray FEmptyTexture::Get8BitPixels(bool alphatex) { - return &Pixel; + TArray Pixel(1, true); + Pixel[0] = 0; + return Pixel; } diff --git a/src/textures/formats/flattexture.cpp b/src/textures/formats/flattexture.cpp index 0e29defc1..7f1dfbd52 100644 --- a/src/textures/formats/flattexture.cpp +++ b/src/textures/formats/flattexture.cpp @@ -48,7 +48,7 @@ class FFlatTexture : public FWorldTexture { public: FFlatTexture (int lumpnum); - uint8_t *MakeTexture (FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; }; @@ -101,16 +101,16 @@ FFlatTexture::FFlatTexture (int lumpnum) // //========================================================================== -uint8_t *FFlatTexture::MakeTexture (FRenderStyle style) +TArray FFlatTexture::Get8BitPixels(bool alphatex) { auto lump = Wads.OpenLumpReader (SourceLump); - auto Pixels = new uint8_t[Width*Height]; - auto numread = lump.Read (Pixels, Width*Height); + TArray Pixels(Width*Height, true); + auto numread = lump.Read (Pixels.Data(), Width*Height); if (numread < Width*Height) { - memset (Pixels + numread, 0xBB, Width*Height - numread); + memset (Pixels.Data() + numread, 0xBB, Width*Height - numread); } - FTexture::FlipSquareBlockRemap(Pixels, Width, Height, GetRemap(style)); + FTexture::FlipSquareBlockRemap(Pixels.Data(), Width, Height, GetRemap(alphatex)); return Pixels; } diff --git a/src/textures/formats/imgztexture.cpp b/src/textures/formats/imgztexture.cpp index 2d0894de3..108baf4b9 100644 --- a/src/textures/formats/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -66,7 +66,7 @@ class FIMGZTexture : public FWorldTexture public: FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool isalpha); - uint8_t *MakeTexture (FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; bool UseBasePalette() override { return !isalpha; } @@ -121,7 +121,7 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 // //========================================================================== -uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style) +TArray FIMGZTexture::Get8BitPixels(bool alphatex) { FMemLump lump = Wads.ReadLump (SourceLump); const ImageHeader *imgz = (const ImageHeader *)lump.GetMem(); @@ -131,10 +131,10 @@ uint8_t *FIMGZTexture::MakeTexture (FRenderStyle style) int dest_adv = Height; int dest_rew = Width * Height - 1; - auto Pixels = new uint8_t[Width*Height]; - dest_p = Pixels; + TArray Pixels(Width*Height, true); + dest_p = Pixels.Data(); - const uint8_t *remap = GetRemap(style, isalpha); + const uint8_t *remap = GetRemap(alphatex, isalpha); // Convert the source image from row-major to column-major format and remap it if (!imgz->Compression) diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index 56165a731..8da8a6729 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -186,7 +186,7 @@ public: FTextureFormat GetFormat () override; int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; bool UseBasePalette() override; - uint8_t *MakeTexture (FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; }; //========================================================================== @@ -272,17 +272,16 @@ FTextureFormat FJPEGTexture::GetFormat() // //========================================================================== -uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style) +TArray FJPEGTexture::Get8BitPixels(bool doalpha) { auto lump = Wads.OpenLumpReader (SourceLump); JSAMPLE *buff = NULL; - bool doalpha = !!(style.Flags & STYLEF_RedIsAlpha); jpeg_decompress_struct cinfo; jpeg_error_mgr jerr; - auto Pixels = new uint8_t[Width * Height]; - memset (Pixels, 0xBA, Width * Height); + TArray Pixels(Width * Height, true); + memset (Pixels.Data(), 0xBA, Width * Height); cinfo.err = jpeg_std_error(&jerr); cinfo.err->output_message = JPEG_OutputMessage; @@ -311,7 +310,7 @@ uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style) { int num_scanlines = jpeg_read_scanlines(&cinfo, &buff, 1); uint8_t *in = buff; - uint8_t *out = Pixels + y; + uint8_t *out = Pixels.Data() + y; switch (cinfo.out_color_space) { case JCS_RGB: @@ -325,7 +324,7 @@ uint8_t *FJPEGTexture::MakeTexture (FRenderStyle style) case JCS_GRAYSCALE: { - auto remap = GetRemap(style, true); + auto remap = GetRemap(doalpha, true); for (int x = Width; x > 0; --x) { *out = remap[in[0]]; diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index 226f85de9..b546b44ac 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -195,10 +195,10 @@ protected: bool bRedirect; bool bTranslucentPatches; - uint8_t *MakeTexture (FRenderStyle style); + TArray MakeTexture (bool alphatex); // The getters must optionally redirect if it's a simple one-patch texture. - const uint8_t *Get8BitPixels(FRenderStyle style) override { return bRedirect ? Parts->Texture->Get8BitPixels(style) : FWorldTexture::Get8BitPixels(style); } + TArray Get8BitPixels(bool alphatex) override { return bRedirect ? Parts->Texture->Get8BitPixels(alphatex) : MakeTexture(alphatex); } private: @@ -305,7 +305,6 @@ FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchl FMultiPatchTexture::~FMultiPatchTexture () { - Unload (); if (Parts != NULL) { for(int i=0; i FMultiPatchTexture::MakeTexture (bool alphatex) { int numpix = Width * Height; uint8_t blendwork[256]; bool buildrgb = bComplex; - auto Pixels = new uint8_t[numpix]; - memset (Pixels, 0, numpix); + TArray Pixels(numpix, true); + memset (Pixels.Data(), 0, numpix); - if (style.Flags & STYLEF_RedIsAlpha) + if (alphatex) { buildrgb = !UseBasePalette(); } @@ -434,7 +433,7 @@ uint8_t *FMultiPatchTexture::MakeTexture (FRenderStyle style) { trans = GetBlendMap(Parts[i].Blend, blendwork); } - Parts[i].Texture->CopyToBlock (Pixels, Width, Height, Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, style); + Parts[i].Texture->CopyToBlock (Pixels.Data(), Width, Height, Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, alphatex); } } } @@ -448,12 +447,12 @@ uint8_t *FMultiPatchTexture::MakeTexture (FRenderStyle style) for(int y = 0; y < Height; y++) { uint8_t *in = buffer + Width * y * 4; - uint8_t *out = Pixels + y; + uint8_t *out = Pixels.Data() + y; for (int x = 0; x < Width; x++) { if (*out == 0 && in[3] != 0) { - *out = RGBToPalette(style, in[2], in[1], in[0]); + *out = RGBToPalette(alphatex, in[2], in[1], in[0]); } out += Height; in += 4; diff --git a/src/textures/formats/patchtexture.cpp b/src/textures/formats/patchtexture.cpp index ed6630ffb..0b18f837f 100644 --- a/src/textures/formats/patchtexture.cpp +++ b/src/textures/formats/patchtexture.cpp @@ -62,7 +62,7 @@ class FPatchTexture : public FWorldTexture bool isalpha = false; public: FPatchTexture (int lumpnum, patch_t *header, bool isalphatex); - uint8_t *MakeTexture (FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; void DetectBadPatches(); @@ -167,7 +167,7 @@ FPatchTexture::FPatchTexture (int lumpnum, patch_t * header, bool isalphatex) // //========================================================================== -uint8_t *FPatchTexture::MakeTexture (FRenderStyle style) +TArray FPatchTexture::Get8BitPixels(bool alphatex) { uint8_t *remap, remaptable[256]; int numspans; @@ -179,7 +179,7 @@ uint8_t *FPatchTexture::MakeTexture (FRenderStyle style) maxcol = (const column_t *)((const uint8_t *)patch + Wads.LumpLength (SourceLump) - 3); - remap = GetRemap(style, isalpha); + remap = GetRemap(alphatex, isalpha); // Special case for skies if (bNoRemap0 && remap == GPalette.Remap) { @@ -190,11 +190,11 @@ uint8_t *FPatchTexture::MakeTexture (FRenderStyle style) if (badflag) { - auto Pixels = new uint8_t[Width * Height]; + TArray Pixels(Width * Height, true); uint8_t *out; // Draw the image to the buffer - for (x = 0, out = Pixels; x < Width; ++x) + for (x = 0, out = Pixels.Data(); x < Width; ++x) { const uint8_t *in = (const uint8_t *)patch + LittleLong(patch->columnofs[x]) + 3; @@ -211,13 +211,13 @@ uint8_t *FPatchTexture::MakeTexture (FRenderStyle style) numspans = Width; - auto Pixels = new uint8_t[numpix]; - memset (Pixels, 0, numpix); + TArray Pixels(numpix, true); + memset (Pixels.Data(), 0, numpix); // Draw the image to the buffer for (x = 0; x < Width; ++x) { - uint8_t *outtop = Pixels + x*Height; + uint8_t *outtop = Pixels.Data() + x*Height; const column_t *column = (const column_t *)((const uint8_t *)patch + LittleLong(patch->columnofs[x])); int top = -1; diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index f97cf03b8..f144e7d8f 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -94,7 +94,7 @@ protected: void ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr); void ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr, int planes); - uint8_t *MakeTexture (FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; }; @@ -370,19 +370,18 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr // //========================================================================== -uint8_t *FPCXTexture::MakeTexture(FRenderStyle style) +TArray FPCXTexture::Get8BitPixels(bool alphatex) { uint8_t PaletteMap[256]; PCXHeader header; int bitcount; - bool alphatex = !!(style.Flags & STYLEF_RedIsAlpha); auto lump = Wads.OpenLumpReader(SourceLump); lump.Read(&header, sizeof(header)); bitcount = header.bitsPerPixel * header.numColorPlanes; - auto Pixels = new uint8_t[Width*Height]; + TArray Pixels(Width*Height, true); if (bitcount < 24) { @@ -394,7 +393,7 @@ uint8_t *FPCXTexture::MakeTexture(FRenderStyle style) case 1: PaletteMap[0] = alphatex? 0 : GrayMap[0]; PaletteMap[1] = alphatex? 255 : GrayMap[255]; - ReadPCX1bit (Pixels, lump, &header); + ReadPCX1bit (Pixels.Data(), lump, &header); break; case 4: @@ -402,7 +401,7 @@ uint8_t *FPCXTexture::MakeTexture(FRenderStyle style) { PaletteMap[i] = RGBToPalettePrecise(alphatex, header.palette[i * 3], header.palette[i * 3 + 1], header.palette[i * 3 + 2]); } - ReadPCX4bits (Pixels, lump, &header); + ReadPCX4bits (Pixels.Data(), lump, &header); break; } } @@ -420,19 +419,17 @@ uint8_t *FPCXTexture::MakeTexture(FRenderStyle style) PaletteMap[i] = RGBToPalettePrecise(alphatex, r, g, b); } lump.Seek(sizeof(header), FileReader::SeekSet); - ReadPCX8bits (Pixels, lump, &header); + ReadPCX8bits (Pixels.Data(), lump, &header); } if (Width == Height) { - FlipSquareBlockRemap(Pixels, Width, Height, PaletteMap); + FlipSquareBlockRemap(Pixels.Data(), Width, Height, PaletteMap); } else { - uint8_t *newpix = new uint8_t[Width*Height]; - FlipNonSquareBlockRemap (newpix, Pixels, Width, Height, Width, PaletteMap); - uint8_t *oldpix = Pixels; - Pixels = newpix; - delete[] oldpix; + TArray newpix(Width*Height, true); + FlipNonSquareBlockRemap (newpix.Data(), Pixels.Data(), Width, Height, Width, PaletteMap); + return newpix; } } else diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index 2071fedf0..5c77ce5de 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -55,7 +55,7 @@ public: FTextureFormat GetFormat () override; int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; bool UseBasePalette() override; - uint8_t *MakeTexture(FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; protected: void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap); @@ -389,11 +389,10 @@ void FPNGTexture::ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap) // //========================================================================== -uint8_t *FPNGTexture::MakeTexture (FRenderStyle style) +TArray FPNGTexture::Get8BitPixels(bool alphatex) { FileReader *lump; FileReader lfr; - bool alphatex = !!(style.Flags & STYLEF_RedIsAlpha); if (SourceLump >= 0) { @@ -405,10 +404,10 @@ uint8_t *FPNGTexture::MakeTexture (FRenderStyle style) lump = &fr; } - auto Pixels = new uint8_t[Width*Height]; + TArray Pixels(Width*Height, true); if (StartOfIDAT == 0) { - memset (Pixels, 0x99, Width*Height); + memset (Pixels.Data(), 0x99, Width*Height); } else { @@ -419,45 +418,43 @@ uint8_t *FPNGTexture::MakeTexture (FRenderStyle style) if (ColorType == 0 || ColorType == 3) /* Grayscale and paletted */ { - M_ReadIDAT (*lump, Pixels, Width, Height, Width, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); + M_ReadIDAT (*lump, Pixels.Data(), Width, Height, Width, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); if (Width == Height) { if (!alphatex) { - FTexture::FlipSquareBlockRemap (Pixels, Width, Height, PaletteMap); + FTexture::FlipSquareBlockRemap (Pixels.Data(), Width, Height, PaletteMap); } else if (ColorType == 0) { - FTexture::FlipSquareBlock (Pixels, Width, Height); + FTexture::FlipSquareBlock (Pixels.Data(), Width, Height); } else { uint8_t alpharemap[256]; ReadAlphaRemap(lump, alpharemap); - FTexture::FlipSquareBlockRemap(Pixels, Width, Height, alpharemap); + FTexture::FlipSquareBlockRemap(Pixels.Data(), Width, Height, alpharemap); } } else { - uint8_t *newpix = new uint8_t[Width*Height]; + TArray newpix(Width*Height, true); if (!alphatex) { - FTexture::FlipNonSquareBlockRemap (newpix, Pixels, Width, Height, Width, PaletteMap); + FTexture::FlipNonSquareBlockRemap (newpix.Data(), Pixels.Data(), Width, Height, Width, PaletteMap); } else if (ColorType == 0) { - FTexture::FlipNonSquareBlock (newpix, Pixels, Width, Height, Width); + FTexture::FlipNonSquareBlock (newpix.Data(), Pixels.Data(), Width, Height, Width); } else { uint8_t alpharemap[256]; ReadAlphaRemap(lump, alpharemap); - FTexture::FlipNonSquareBlockRemap(newpix, Pixels, Width, Height, Width, alpharemap); + FTexture::FlipNonSquareBlockRemap(newpix.Data(), Pixels.Data(), Width, Height, Width, alpharemap); } - uint8_t *oldpix = Pixels; - Pixels = newpix; - delete[] oldpix; + return newpix; } } else /* RGB and/or Alpha present */ @@ -469,7 +466,7 @@ uint8_t *FPNGTexture::MakeTexture (FRenderStyle style) M_ReadIDAT (*lump, tempix, Width, Height, Width*bytesPerPixel, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); in = tempix; - out = Pixels; + out = Pixels.Data(); // Convert from source format to paletted, column-major. // Formats with alpha maps are reduced to only 1 bit of alpha. diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index 9a829acc3..78b48cfac 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -52,7 +52,7 @@ class FRawPageTexture : public FWorldTexture int mPaletteLump = -1; public: FRawPageTexture (int lumpnum); - uint8_t *MakeTexture (FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; }; @@ -174,17 +174,17 @@ FRawPageTexture::FRawPageTexture (int lumpnum) // //========================================================================== -uint8_t *FRawPageTexture::MakeTexture (FRenderStyle style) +TArray FRawPageTexture::Get8BitPixels(bool alphatex) { FMemLump lump = Wads.ReadLump (SourceLump); const uint8_t *source = (const uint8_t *)lump.GetMem(); const uint8_t *source_p = source; uint8_t *dest_p; - auto Pixels = new uint8_t[Width*Height]; - dest_p = Pixels; + TArray Pixels(Width*Height, true); + dest_p = Pixels.Data(); - const uint8_t *remap = GetRemap(style); + const uint8_t *remap = GetRemap(alphatex); // This does not handle the custom palette. // User maps are encouraged to use a real image format when replacing E2END and the original could never be used anywhere else. diff --git a/src/textures/formats/shadertexture.cpp b/src/textures/formats/shadertexture.cpp index 123ddd223..e21bf4f24 100644 --- a/src/textures/formats/shadertexture.cpp +++ b/src/textures/formats/shadertexture.cpp @@ -53,7 +53,6 @@ public: Height = vertical ? 256 : 2; bMasked = false; bTranslucent = false; - PixelsAreStatic = 2; // The alpha buffer is static, but if this gets used as a regular texture, a separate buffer needs to be made. // Fill the column/row with shading values. // Vertical shaders have have minimum alpha at the top @@ -100,24 +99,24 @@ public: } } - uint8_t *MakeTexture(FRenderStyle style) override + TArray Get8BitPixels(bool alphatex) override { - if (style.Flags & STYLEF_RedIsAlpha) + TArray Pix(512, true); + if (alphatex) { - return Pixels; + memcpy(Pix.Data(), Pixels, 512); } else { // Since this presents itself to the game as a regular named texture // it can easily be used on walls and flats and should work as such, // even if it makes little sense. - auto Pix = new uint8_t[512]; for (int i = 0; i < 512; i++) { Pix[i] = GrayMap[Pixels[i]]; } - return Pix; } + return Pix; } int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index 44bac1bfd..9416f6398 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -85,7 +85,7 @@ public: protected: void ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel); - uint8_t *MakeTexture (FRenderStyle style) override; + TArray Get8BitPixels(bool alphatex) override; }; //========================================================================== @@ -191,7 +191,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe // //========================================================================== -uint8_t *FTGATexture::MakeTexture (FRenderStyle style) +TArray FTGATexture::Get8BitPixels(bool alphatex) { uint8_t PaletteMap[256]; auto lump = Wads.OpenLumpReader (SourceLump); @@ -199,9 +199,8 @@ uint8_t *FTGATexture::MakeTexture (FRenderStyle style) uint16_t w; uint8_t r,g,b,a; uint8_t * buffer; - bool alphatex = !!(style.Flags & STYLEF_RedIsAlpha); - auto Pixels = new uint8_t[Width*Height]; + TArray Pixels(Width*Height, true); lump.Read(&hdr, sizeof(hdr)); lump.Seek(hdr.id_len, FileReader::SeekCur); @@ -356,7 +355,7 @@ uint8_t *FTGATexture::MakeTexture (FRenderStyle style) case 3: // Grayscale { - auto remap = GetRemap(style, true); + auto remap = GetRemap(alphatex, true); switch (hdr.bpp) { case 8: diff --git a/src/textures/formats/worldtexture.cpp b/src/textures/formats/worldtexture.cpp index edba839c6..66b9ec3b4 100644 --- a/src/textures/formats/worldtexture.cpp +++ b/src/textures/formats/worldtexture.cpp @@ -47,49 +47,3 @@ FWorldTexture::FWorldTexture(const char *name, int lumpnum) { } -//========================================================================== -// -// -// -//========================================================================== - -FWorldTexture::~FWorldTexture() -{ - Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - -void FWorldTexture::Unload () -{ - for(int i = 0; i < 2; i++) - { - if (!(PixelsAreStatic & (1 << i))) - { - delete[] Pixeldata[i]; - } - Pixeldata[i] = nullptr; - } - FTexture::Unload(); -} - -//========================================================================== -// -// -// -//========================================================================== - -const uint8_t *FWorldTexture::Get8BitPixels (FRenderStyle style) -{ - int index = !!(style.Flags & STYLEF_RedIsAlpha); - if (Pixeldata[index] == nullptr) - { - Pixeldata[index] = MakeTexture (style); - } - return Pixeldata[index]; -} - diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index a1f22d9f4..6a3572b03 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -48,21 +48,10 @@ FSkyBox::FSkyBox(const char *name) // //----------------------------------------------------------------------------- -FSkyBox::~FSkyBox() +TArray FSkyBox::Get8BitPixels(bool alphatex) { - // The faces are only referenced but not owned so don't delete them. -} - -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -const uint8_t *FSkyBox::Get8BitPixels (FRenderStyle style) -{ - if (faces[0]) return faces[0]->Get8BitPixels(style); - return NULL; + if (faces[0]) return faces[0]->Get8BitPixels(alphatex); + return FTexture::Get8BitPixels(alphatex); } //----------------------------------------------------------------------------- @@ -88,13 +77,3 @@ bool FSkyBox::UseBasePalette() return false; // not really but here it's not important. } -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -void FSkyBox::Unload () -{ -} - diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index 08dfdd653..0dec6aa54 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -16,9 +16,7 @@ public: bool fliptop; FSkyBox(const char *name = nullptr); - ~FSkyBox(); - //const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); - const uint8_t *Get8BitPixels (FRenderStyle style); + TArray Get8BitPixels(bool alphatex); int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); bool UseBasePalette(); void Unload (); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 61cc9ab44..da2c0de03 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -225,11 +225,11 @@ FTexture::~FTexture () if (SystemTexture[i] != nullptr) delete SystemTexture[i]; SystemTexture[i] = nullptr; } - -} - -void FTexture::Unload() -{ + if (SoftwareTexture != nullptr) + { + delete SoftwareTexture; + SoftwareTexture = nullptr; + } } //========================================================================== @@ -254,15 +254,16 @@ void FTexture::SetFrontSkyLayer () // //========================================================================== -void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, FRenderStyle style) +void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, bool style) { - const uint8_t *pixels = Get8BitPixels(style); + auto image = Get8BitPixels(style); // should use composition cache + const uint8_t *pixels = image.Data(); int srcwidth = Width; int srcheight = Height; int step_x = Height; int step_y = 1; FClipRect cr = {0, 0, dwidth, dheight}; - if (style.Flags & STYLEF_RedIsAlpha) translation = nullptr; // do not apply translations to alpha textures. + if (style) translation = nullptr; // do not apply translations to alpha textures. if (ClipCopyPixelRect(&cr, xpos, ypos, pixels, srcwidth, srcheight, step_x, step_y, rotate)) { @@ -425,7 +426,6 @@ void FTexture::FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x, void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt) { - const uint8_t *pix; int x, y, w, h, stride; w = GetWidth(); @@ -435,7 +435,9 @@ void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat f { case TEX_Pal: case TEX_Gray: - pix = Get8BitPixels(fmt == TEX_Pal? DefaultRenderStyle() : LegacyRenderStyles[STYLE_Shaded]); + { + auto ppix = Get8BitPixels(fmt == TEX_Gray); // should use composition cache + auto pix = ppix.Data(); stride = pitch - w; for (y = 0; y < h; ++y) { @@ -449,6 +451,7 @@ void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat f buff += stride; } break; + } case TEX_RGB: { @@ -479,14 +482,16 @@ int FTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyI { PalEntry *palette = screen->GetPalette(); for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values - bmp->CopyPixelData(x, y, Get8BitPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, palette, inf); + auto ppix = Get8BitPixels(false); // should use composition cache + bmp->CopyPixelData(x, y, ppix.Data(), Width, Height, Height, 1, rotate, palette, inf); for(int i=1;i<256;i++) palette[i].a = 0; return 0; } int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf) { - bmp->CopyPixelData(x, y, Get8BitPixels(DefaultRenderStyle()), Width, Height, Height, 1, rotate, remap, inf); + auto ppix = Get8BitPixels(false); // should use composition cache + bmp->CopyPixelData(x, y, ppix.Data(), Width, Height, Height, 1, rotate, remap, inf); return 0; } @@ -596,7 +601,7 @@ PalEntry FTexture::GetSkyCapColor(bool bottom) int FTexture::CheckRealHeight() { - auto pixels = Get8BitPixels(DefaultRenderStyle()); + auto pixels = Get8BitPixels(false); for(int h = GetHeight()-1; h>= 0; h--) { @@ -682,12 +687,10 @@ void FTexture::CreateDefaultBrightmap() // Check for brightmaps if (UseBasePalette() && TexMan.HasGlobalBrightmap && UseType != ETextureType::Decal && UseType != ETextureType::MiscPatch && UseType != ETextureType::FontChar && - Brightmap == NULL && bWarped == 0 && - Get8BitPixels(DefaultRenderStyle()) - ) + Brightmap == NULL && bWarped == 0) { // May have one - let's check when we use this texture - const uint8_t *texbuf = Get8BitPixels(DefaultRenderStyle()); + auto texbuf = Get8BitPixels(false); const int white = ColorMatcher.Pick(255, 255, 255); int size = GetWidth() * GetHeight(); @@ -1050,13 +1053,15 @@ void FTexture::SetSpriteAdjust() //=========================================================================== // -// empty stubs to be overloaded by child classes. +// the default just returns an empty texture. // //=========================================================================== -const uint8_t *FTexture::Get8BitPixels(FRenderStyle style) +TArray FTexture::Get8BitPixels(bool alphatex) { - return nullptr; + TArray Pixels(Width * Height, true); + memset(Pixels.Data(), 0, Width * Height); + return Pixels; } //=========================================================================== @@ -1212,26 +1217,4 @@ void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y) mWidth = tex->GetWidth(); } -///////////// - - -class TextureCache -{ - struct ItemCacheInfo - { - int palettedCount; // counts use of final paletted textures - int palettedCountCompose; // counts use of images needed for composition (can be freed after precaching) - int rgbaCount; // counts use of final true color software textures - int rawCount; // counts use of raw images needed for composition (can be freed after precaching) - int textureCount; // counts use of hardware textures - }; - TMap> pixelCachePaletted; // 8 bit column major for composition and software rendering - TMap> pixelCacheRgba; // 32 bit column major for software true color rendering - TMap> pixelCacheRaw; // 32 bit row major for composition - TMap hwTextureCache; // native system textures. - - TMap cacheMarker; - - void PrecacheLevel(); -}; diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index e470cff66..85221b11e 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -363,20 +363,6 @@ FTexture *FTextureManager::FindTexture(const char *texname, ETextureType usetype return !texnum.isValid()? NULL : Textures[texnum.GetIndex()].Texture; } -//========================================================================== -// -// FTextureManager :: UnloadAll -// -//========================================================================== - -void FTextureManager::UnloadAll () -{ - for (unsigned int i = 0; i < Textures.Size(); ++i) - { - Textures[i].Texture->Unload (); - } -} - //========================================================================== // // FTextureManager :: AddTexture diff --git a/src/textures/textures.h b/src/textures/textures.h index ec0df68ee..811c9bede 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -298,11 +298,9 @@ public: bool isFullbright() const { return bFullbright; } void CreateDefaultBrightmap(); bool FindHoles(const unsigned char * buffer, int w, int h); - uint64_t CacheID() - { - // Just a temporary placeholder. This needs to be done differently as things progress. - return (uint64_t)(intptr_t)GetRedirect(); - } + + // Returns the whole texture, stored in column-major order + virtual TArray Get8BitPixels(bool alphatex); public: static void FlipSquareBlock (uint8_t *block, int x, int y); @@ -386,9 +384,6 @@ protected: - // Returns the whole texture, stored in column-major order - virtual const uint8_t *Get8BitPixels(FRenderStyle style); - // Returns true if GetPixelsBgra includes mipmaps virtual bool Mipmapped() { return true; } @@ -397,8 +392,6 @@ protected: virtual bool UseBasePalette(); virtual FTexture *GetRedirect(); - virtual void Unload (); - // Returns the native pixel format for this image virtual FTextureFormat GetFormat(); @@ -446,7 +439,7 @@ protected: virtual void SetFrontSkyLayer(); - void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, int rotate, const uint8_t *translation, FRenderStyle style); + void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, int rotate, const uint8_t *translation, bool style); static void InitGrayMap(); @@ -467,9 +460,9 @@ protected: uint16_t Width, Height; int16_t _LeftOffset[2], _TopOffset[2]; static uint8_t GrayMap[256]; - uint8_t *GetRemap(FRenderStyle style, bool srcisgrayscale = false) + uint8_t *GetRemap(bool wantluminance, bool srcisgrayscale = false) { - if (style.Flags & STYLEF_RedIsAlpha) + if (wantluminance) { return translationtables[TRANSLATION_Standard][srcisgrayscale ? STD_Gray : STD_Grayscale]->Remap; } @@ -651,8 +644,6 @@ public: // This function can be used for such things as warping textures. void ReplaceTexture (FTextureID picnum, FTexture *newtexture, bool free); - void UnloadAll (); - int NumTextures () const { return (int)Textures.Size(); } void UpdateAnimations (uint64_t mstime); @@ -739,15 +730,7 @@ public: class FWorldTexture : public FTexture { protected: - uint8_t *Pixeldata[2] = { nullptr, nullptr }; - uint8_t PixelsAreStatic = 0; // can be set by subclasses which provide static pixel buffers. - FWorldTexture(const char *name = nullptr, int lumpnum = -1); - ~FWorldTexture(); - - void Unload() override; - const uint8_t *Get8BitPixels(FRenderStyle style) override; - virtual uint8_t *MakeTexture(FRenderStyle style) = 0; }; // A texture that doesn't really exist @@ -767,20 +750,17 @@ class FCanvasTexture : public FTexture { public: FCanvasTexture (const char *name, int width, int height); - ~FCanvasTexture (); //const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); //const uint32_t *GetPixelsBgra() override; - const uint8_t *Get8BitPixels (FRenderStyle style); - void Unload (); + //const uint8_t *Get8BitPixels(bool alphatex); bool CheckModified (FRenderStyle) /*override*/; void NeedUpdate() { bNeedsUpdate=true; } void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; } DCanvas *GetCanvas() { return Canvas; } DCanvas *GetCanvasBgra() { return CanvasBgra; } bool Mipmapped() override { return false; } - void MakeTexture (FRenderStyle style); void MakeTextureBgra (); protected: @@ -838,6 +818,7 @@ struct FTexCoordInfo }; + #endif diff --git a/src/v_font.cpp b/src/v_font.cpp index c2d56717c..bd9efebde 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -171,16 +171,12 @@ class FFontChar1 : public FTexture { public: FFontChar1 (FTexture *sourcelump); - const uint8_t *Get8BitPixels (FRenderStyle style); + TArray Get8BitPixels(bool alphatex) override; void SetSourceRemap(const uint8_t *sourceremap); - void Unload (); - ~FFontChar1 (); protected: - void MakeTexture (); FTexture *BaseTexture; - uint8_t *Pixels; const uint8_t *SourceRemap; }; @@ -189,16 +185,13 @@ class FFontChar2 : public FTexture { public: FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); - ~FFontChar2 (); - const uint8_t *Get8BitPixels (FRenderStyle style); + TArray Get8BitPixels(bool alphatex) override; void SetSourceRemap(const uint8_t *sourceremap); - void Unload (); protected: int SourceLump; int SourcePos; - uint8_t *Pixels; const uint8_t *SourceRemap; void MakeTexture (); @@ -365,6 +358,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, FirstFont = this; Cursor = '_'; ActiveColors = 0; + translateUntranslated = false; maxyoffs = 0; @@ -530,14 +524,13 @@ void RecordTextureColors (FTexture *pic, uint8_t *usedcolors) { int x; - auto pixels = pic->Get8BitPixels(DefaultRenderStyle()); + auto pixels = pic->Get8BitPixels(false); auto size = pic->GetWidth() * pic->GetHeight(); for(x = 0;x < size; x++) { usedcolors[pixels[x]]++; } - pic->Unload(); } //========================================================================== @@ -738,6 +731,7 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range, PalEntry *color) con return NULL; else if (range >= NumTextColors) range = CR_UNTRANSLATED; + //if (range == CR_UNTRANSLATED && !translateUntranslated) return nullptr; return &Ranges[range]; } @@ -913,6 +907,8 @@ void FFont::LoadTranslations() } } + // Fixme: This needs to build a translation based on the source palette, not some intermediate 'ordered' table. + ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); for (unsigned int i = 0; i < count; i++) @@ -1078,6 +1074,7 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data) FirstChar = 0; LastChar = 255; GlobalKerning = 0; + translateUntranslated = true; PatchRemap = new uint8_t[256]; for(unsigned int i = 0;i < 256;++i) @@ -1558,7 +1555,6 @@ FFontChar1::FFontChar1 (FTexture *sourcelump) // now copy all the properties from the base texture assert(BaseTexture != NULL); CopySize(BaseTexture); - Pixels = NULL; } //========================================================================== @@ -1569,39 +1565,21 @@ FFontChar1::FFontChar1 (FTexture *sourcelump) // //========================================================================== -const uint8_t *FFontChar1::Get8BitPixels (FRenderStyle) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// FFontChar1 :: MakeTexture -// -//========================================================================== - -void FFontChar1::MakeTexture () +TArray FFontChar1::Get8BitPixels (bool) { // Make the texture as normal, then remap it so that all the colors // are at the low end of the palette - Pixels = new uint8_t[Width*Height]; - const uint8_t *pix = BaseTexture->Get8BitPixels(DefaultRenderStyle()); + // Why? It only creates unnecessary work! + auto Pixels = BaseTexture->Get8BitPixels(false); - if (!SourceRemap) - { - memcpy(Pixels, pix, Width*Height); - } - else + if (SourceRemap) { for (int x = 0; x < Width*Height; ++x) { - Pixels[x] = SourceRemap[pix[x]]; + Pixels[x] = SourceRemap[Pixels[x]]; } } + return Pixels; } //========================================================================== @@ -1612,37 +1590,9 @@ void FFontChar1::MakeTexture () void FFontChar1::SetSourceRemap(const uint8_t *sourceremap) { - Unload(); SourceRemap = sourceremap; } -//========================================================================== -// -// FFontChar1 :: Unload -// -//========================================================================== - -void FFontChar1::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); -} - -//========================================================================== -// -// FFontChar1 :: ~FFontChar1 -// -//========================================================================== - -FFontChar1::~FFontChar1 () -{ - Unload (); -} - //========================================================================== // // FFontChar2 :: FFontChar2 @@ -1652,7 +1602,7 @@ FFontChar1::~FFontChar1 () //========================================================================== FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs) -: SourceLump (sourcelump), SourcePos (sourcepos), Pixels (0), SourceRemap(NULL) +: SourceLump (sourcelump), SourcePos (sourcepos), SourceRemap(NULL) { UseType = ETextureType::FontChar; Width = width; @@ -1663,29 +1613,13 @@ FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, in //========================================================================== // -// FFontChar2 :: ~FFontChar2 +// FFontChar2 :: SetSourceRemap // //========================================================================== -FFontChar2::~FFontChar2 () +void FFontChar2::SetSourceRemap(const uint8_t *sourceremap) { - Unload (); -} - -//========================================================================== -// -// FFontChar2 :: Unload -// -//========================================================================== - -void FFontChar2::Unload () -{ - if (Pixels != NULL) - { - delete[] Pixels; - Pixels = NULL; - } - FTexture::Unload(); + SourceRemap = sourceremap; } //========================================================================== @@ -1696,34 +1630,7 @@ void FFontChar2::Unload () // //========================================================================== -const uint8_t *FFontChar2::Get8BitPixels (FRenderStyle) -{ - if (Pixels == NULL) - { - MakeTexture (); - } - return Pixels; -} - -//========================================================================== -// -// FFontChar2 :: SetSourceRemap -// -//========================================================================== - -void FFontChar2::SetSourceRemap(const uint8_t *sourceremap) -{ - Unload(); - SourceRemap = sourceremap; -} - -//========================================================================== -// -// FFontChar2 :: MakeTexture -// -//========================================================================== - -void FFontChar2::MakeTexture () +TArray FFontChar2::Get8BitPixels(bool) { auto lump = Wads.OpenLumpReader (SourceLump); int destSize = Width * Height; @@ -1753,11 +1660,11 @@ void FFontChar2::MakeTexture () } } - Pixels = new uint8_t[destSize]; + TArray Pixels(destSize, true); int runlen = 0, setlen = 0; uint8_t setval = 0; // Shut up, GCC! - uint8_t *dest_p = Pixels; + uint8_t *dest_p = Pixels.Data(); int dest_adv = Height; int dest_rew = destSize - 1; @@ -1838,6 +1745,7 @@ void FFontChar2::MakeTexture () name[8] = 0; I_FatalError ("The font %s is corrupt", name); } + return Pixels; } //========================================================================== diff --git a/src/v_font.h b/src/v_font.h index 383363ce8..907c3e1f8 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -120,6 +120,7 @@ protected: int GlobalKerning; char Cursor; bool noTranslate; + bool translateUntranslated; struct CharData { FTexture *Pic; From 1e070d27bd4ae70933d08442ea8662d9dd736323 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 8 Dec 2018 14:06:16 +0100 Subject: [PATCH 16/66] - replaced FTexture::FillBuffer --- src/textures/bitmap.h | 30 ++++++++++ src/textures/formats/multipatchtexture.cpp | 7 +-- src/textures/texture.cpp | 68 ++++------------------ src/textures/textures.h | 3 +- 4 files changed, 45 insertions(+), 63 deletions(-) diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index 51d857ac4..3219ecf34 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -90,6 +90,36 @@ public: ClipRect.height = height; } + FBitmap(const FBitmap &other) = delete; // disallow because in nearly all cases this creates an unwanted copy. + + FBitmap(FBitmap &&other) + { + data = other.data; + Pitch = other.Pitch; + Width = other.Width; + Height = other.Height; + FreeBuffer = other.FreeBuffer; + ClipRect = other.ClipRect; + other.data = nullptr; + other.FreeBuffer = false; + } + + FBitmap &operator=(const FBitmap &other) = delete; // disallow because in nearly all cases this creates an unwanted copy. + + FBitmap &operator=(FBitmap &&other) + { + if (data != nullptr && FreeBuffer) delete[] data; + data = other.data; + Pitch = other.Pitch; + Width = other.Width; + Height = other.Height; + FreeBuffer = other.FreeBuffer; + ClipRect = other.ClipRect; + other.data = nullptr; + other.FreeBuffer = false; + return *this; + } + virtual ~FBitmap() { Destroy(); diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index b546b44ac..7b0432bff 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -441,12 +441,10 @@ TArray FMultiPatchTexture::MakeTexture (bool alphatex) { // In case there are translucent patches let's do the composition in // True color to keep as much precision as possible before downconverting to the palette. - uint8_t *buffer = new uint8_t[Width * Height * 4]; - memset(buffer, 0, Width * Height * 4); - FillBuffer(buffer, Width * 4, Height, TEX_RGB); + auto buffer = GetBgraBitmap(nullptr); for(int y = 0; y < Height; y++) { - uint8_t *in = buffer + Width * y * 4; + uint8_t *in = buffer.GetPixels() + Width * y * 4; uint8_t *out = Pixels.Data() + y; for (int x = 0; x < Width; x++) { @@ -458,7 +456,6 @@ TArray FMultiPatchTexture::MakeTexture (bool alphatex) in += 4; } } - delete [] buffer; } return Pixels; } diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index da2c0de03..e1630a11c 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -47,6 +47,7 @@ #include "m_fixed.h" #include "hwrenderer/textures/hw_material.h" #include "hwrenderer/textures/hw_ihwtexture.h" +#include "swrenderer/textures/r_swtexture.h" FTexture *CreateBrightmapTexture(FTexture*); @@ -418,54 +419,6 @@ void FTexture::FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x, } } -//========================================================================== -// -// -// -//========================================================================== - -void FTexture::FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt) -{ - int x, y, w, h, stride; - - w = GetWidth(); - h = GetHeight(); - - switch (fmt) - { - case TEX_Pal: - case TEX_Gray: - { - auto ppix = Get8BitPixels(fmt == TEX_Gray); // should use composition cache - auto pix = ppix.Data(); - stride = pitch - w; - for (y = 0; y < h; ++y) - { - const uint8_t *pix2 = pix; - for (x = 0; x < w; ++x) - { - *buff++ = *pix2; - pix2 += h; - } - pix++; - buff += stride; - } - break; - } - - case TEX_RGB: - { - FCopyInfo inf = {OP_OVERWRITE, BLEND_NONE, {0}, 0, 0}; - FBitmap bmp(buff, pitch, pitch/4, height); - CopyTrueColorPixels(&bmp, 0, 0, 0, &inf); - break; - } - - default: - I_Error("FTexture::FillBuffer: Unsupported format %d", fmt); - } -} - //=========================================================================== // // FTexture::CopyTrueColorPixels @@ -495,6 +448,15 @@ int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, Pa return 0; } +FBitmap FTexture::GetBgraBitmap(PalEntry *remap) +{ + FBitmap bmp; + bmp.Create(GetWidth(), GetHeight()); + if (!remap) CopyTrueColorPixels(&bmp, 0, 0, 0, nullptr); + else CopyTrueColorTranslated(&bmp, 0, 0, 0, remap, nullptr); + return bmp; +} + //========================================================================== // // @@ -729,14 +691,8 @@ void FTexture::GetGlowColor(float *data) { if (bGlowing && GlowColor == 0) { - int w = Width, h = Height; - auto buffer = new uint8_t[w * h * 4]; - if (buffer) - { - FillBuffer(buffer, w * 4, h, TEX_RGB); - GlowColor = averageColor((uint32_t *)buffer, w*h, 153); - delete[] buffer; - } + auto buffer = GetBgraBitmap(nullptr); + GlowColor = averageColor((uint32_t*)buffer.GetPixels(), buffer.GetWidth() * buffer.GetHeight(), 153); // Black glow equals nothing so switch glowing off if (GlowColor == 0) bGlowing = false; diff --git a/src/textures/textures.h b/src/textures/textures.h index 811c9bede..10caf1bac 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -301,6 +301,7 @@ public: // Returns the whole texture, stored in column-major order virtual TArray Get8BitPixels(bool alphatex); + /*virtual*/ FBitmap GetBgraBitmap(PalEntry *remap); public: static void FlipSquareBlock (uint8_t *block, int x, int y); @@ -395,8 +396,6 @@ protected: // Returns the native pixel format for this image virtual FTextureFormat GetFormat(); - // Fill the native texture buffer with pixel data for this image - virtual void FillBuffer(uint8_t *buff, int pitch, int height, FTextureFormat fmt); void SetSpeed(float fac) { shaderspeed = fac; } int GetWidth () { return Width; } From 03626107eb423c99e26b31f41c24aedd452c7eaf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 8 Dec 2018 17:23:15 +0100 Subject: [PATCH 17/66] - changed multipatch texture composition to always composite off full source images and not do it recursively. Previously it tried to copy all patches of composite sub-images directly onto the main image. This caused massive complications throughout the entire true color texture code and made any attempt of caching the source data for composition next to impossible because the entire composition process operated on the raw data read from the texture and not some cacheable image. While this may cause more pixel data to be processed, this will be easily offset by being able to reuse patches for multiple textures, once a caching system is in place, which even for the IWADs happens quite frequently. Removing the now unneeded arguments from the implementation also makes things a lot easier to handle. --- src/f_wipe.cpp | 4 +- src/posix/sdl/i_gui.cpp | 7 +-- src/r_data/models/models_voxel.cpp | 8 ++-- src/swrenderer/r_swscene.cpp | 2 +- src/swrenderer/textures/r_swtexture.cpp | 4 +- src/textures/bitmap.h | 41 +++++++++++------ src/textures/formats/brightmaptexture.cpp | 6 +-- src/textures/formats/buildtexture.cpp | 6 +-- src/textures/formats/ddstexture.cpp | 27 +++++------ src/textures/formats/imgztexture.cpp | 8 ++-- src/textures/formats/jpegtexture.cpp | 22 ++++----- src/textures/formats/multipatchtexture.cpp | 41 ++--------------- src/textures/formats/patchtexture.cpp | 8 ++-- src/textures/formats/pcxtexture.cpp | 10 ++-- src/textures/formats/pngtexture.cpp | 16 +++---- src/textures/formats/rawpagetexture.cpp | 8 ++-- src/textures/formats/shadertexture.cpp | 4 +- src/textures/formats/tgatexture.cpp | 20 ++++---- src/textures/hires/hirestex.cpp | 4 +- src/textures/skyboxtexture.cpp | 4 +- src/textures/skyboxtexture.h | 2 +- src/textures/texture.cpp | 41 +++++++++-------- src/textures/textures.h | 7 +-- src/win32/i_system.cpp | 53 +++++++++------------- 24 files changed, 161 insertions(+), 192 deletions(-) diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index cd8c48f40..6cfc737d1 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -41,9 +41,9 @@ public: Height = h; } - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override + int CopyPixels(FBitmap *bmp) override { - bmp->CopyPixelDataRGB(x, y, (uint8_t*)WorkBuffer.Data(), Width, Height, 4, Width*4, rotate, CF_RGBA, inf); + bmp->CopyPixelDataRGB(0, 0, (uint8_t*)WorkBuffer.Data(), Width, Height, 4, Width*4, 0, CF_RGBA, nullptr); return 0; } diff --git a/src/posix/sdl/i_gui.cpp b/src/posix/sdl/i_gui.cpp index 1a895a676..8ad9c8b92 100644 --- a/src/posix/sdl/i_gui.cpp +++ b/src/posix/sdl/i_gui.cpp @@ -44,10 +44,11 @@ bool I_SetCursor(FTexture *cursorpic) static SDL_Cursor *cursor; static SDL_Surface *cursorSurface; - if (cursorpic != NULL && cursorpic->UseType != ETextureType::Null) + if (cursorpic != NULL && cursorpic->isValid()) { + auto src = cursorpic->GetBgraBitmap(nullptr); // Must be no larger than 32x32. - if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32) + if (src.GetWidth() > 32 || src.GetHeight() > 32) { return false; } @@ -59,7 +60,7 @@ bool I_SetCursor(FTexture *cursorpic) uint8_t buffer[32*32*4]; memset(buffer, 0, 32*32*4); FBitmap bmp(buffer, 32*4, 32, 32); - cursorpic->CopyTrueColorPixels(&bmp, 0, 0); + bmp.Blit(0, 0, src); // expand to 32*32 memcpy(cursorSurface->pixels, bmp.GetPixels(), 32*32*4); SDL_UnlockSurface(cursorSurface); diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index dca6a4cd8..5b8e82571 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -51,7 +51,7 @@ class FVoxelTexture : public FWorldTexture public: FVoxelTexture(FVoxel *voxel); - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; + int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override { return false; } TArray Get8BitPixels(bool alphatex) override; @@ -109,14 +109,14 @@ TArray FVoxelTexture::Get8BitPixels(bool alphatex) //=========================================================================== // -// FVoxelTexture::CopyTrueColorPixels +// FVoxelTexture::CopyPixels // // This creates a dummy 16x16 paletted bitmap and converts that using the // voxel palette // //=========================================================================== -int FVoxelTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FVoxelTexture::CopyPixels(FBitmap *bmp) { PalEntry pe[256]; uint8_t bitmap[256]; @@ -142,7 +142,7 @@ int FVoxelTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, F pe[i].a = 255; } } - bmp->CopyPixelData(x, y, bitmap, Width, Height, 1, 16, rotate, pe, inf); + bmp->CopyPixelData(0, 0, bitmap, Width, Height, 1, 16, 0, pe); return 0; } diff --git a/src/swrenderer/r_swscene.cpp b/src/swrenderer/r_swscene.cpp index c8b8da57c..bfdf86a11 100644 --- a/src/swrenderer/r_swscene.cpp +++ b/src/swrenderer/r_swscene.cpp @@ -51,7 +51,7 @@ public: UseType = ETextureType::MiscPatch; } - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) + int CopyPixels(FBitmap *bmp) { PalEntry *pe = (PalEntry*)bmp->GetPixels(); for (int i = 0; i < 256; i++) diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index 8470227ce..ae8c0d1ce 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -108,9 +108,7 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra() { if (PixelsBgra.Size() == 0 || CheckModified(2)) { - FBitmap bitmap; - bitmap.Create(GetWidth(), GetHeight()); - mTexture->CopyTrueColorPixels(&bitmap, 0, 0); + FBitmap bitmap = mTexture->GetBgraBitmap(nullptr); GenerateBgraFromBitmap(bitmap); } return PixelsBgra.Data(); diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index 3219ecf34..1c86623ed 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -56,6 +56,22 @@ enum BLENDUNIT = (1<>8; } }; -enum ColorType -{ - CF_RGB, - CF_RGBT, - CF_RGBA, - CF_IA, - CF_CMYK, - CF_YCbCr, - CF_BGR, - CF_BGRA, - CF_I16, - CF_RGB555, - CF_PalEntry -}; - enum EBlend { BLEND_NONE = 0, diff --git a/src/textures/formats/brightmaptexture.cpp b/src/textures/formats/brightmaptexture.cpp index 314ac6f74..06cc29e90 100644 --- a/src/textures/formats/brightmaptexture.cpp +++ b/src/textures/formats/brightmaptexture.cpp @@ -45,7 +45,7 @@ class FBrightmapTexture : public FWorldTexture public: FBrightmapTexture (FTexture *source); - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; + int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override { return false; } protected: @@ -73,9 +73,9 @@ FBrightmapTexture::FBrightmapTexture (FTexture *source) SourceLump = -1; } -int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FBrightmapTexture::CopyPixels(FBitmap *bmp) { - SourcePic->CopyTrueColorTranslated(bmp, x, y, rotate, TexMan.GlobalBrightmap.Palette); + SourcePic->CopyTranslatedPixels(bmp, TexMan.GlobalBrightmap.Palette); return 0; } diff --git a/src/textures/formats/buildtexture.cpp b/src/textures/formats/buildtexture.cpp index 9d4fa2fdc..ed7bbe1f8 100644 --- a/src/textures/formats/buildtexture.cpp +++ b/src/textures/formats/buildtexture.cpp @@ -57,7 +57,7 @@ class FBuildTexture : public FWorldTexture public: FBuildTexture (const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top); TArray Get8BitPixels(bool alphatex) override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override { return false; } FTextureFormat GetFormat() override { return TEX_RGB; } @@ -96,10 +96,10 @@ TArray FBuildTexture::Get8BitPixels(bool alphatex) return Pixels; } -int FBuildTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FBuildTexture::CopyPixels(FBitmap *bmp) { PalEntry *Remap = translationtables[TRANSLATION_Standard][Translation]->Palette; - bmp->CopyPixelData(x, y, RawPixels, Width, Height, Height, 1, rotate, Remap, inf); + bmp->CopyPixelData(0, 0, RawPixels, Width, Height, Height, 1, 0, Remap); return -1; } diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index 5a2007e66..d13733ccf 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -182,7 +182,7 @@ protected: void DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); void DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL); + int CopyPixels(FBitmap *bmp) override; bool UseBasePalette(); friend class FTexture; @@ -485,9 +485,9 @@ void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *buffer, int pixelmode) uint32_t g = (c & GMask) << GShiftL; g |= g >> GShiftR; uint32_t b = (c & BMask) << BShiftL; b |= b >> BShiftR; uint32_t a = (c & AMask) << AShiftL; a |= a >> AShiftR; - pixelp[0] = (uint8_t)(r>>24); + pixelp[0] = (uint8_t)(b>>24); pixelp[1] = (uint8_t)(g>>24); - pixelp[2] = (uint8_t)(b>>24); + pixelp[2] = (uint8_t)(r>>24); pixelp[3] = (uint8_t)(a>>24); pixelp+=4; } @@ -580,9 +580,9 @@ void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *buffer, int pixelmo else { uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4]; - tcp[0] = color[ci].r; + tcp[0] = color[ci].b; tcp[1] = color[ci].g; - tcp[2] = color[ci].b; + tcp[2] = color[ci].r; tcp[3] = color[ci].a; } } @@ -669,9 +669,9 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t { uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4]; int c = (yslice >> (x + x)) & 3; - tcp[0] = color[c].r; + tcp[0] = color[c].b; tcp[1] = color[c].g; - tcp[2] = color[c].b; + tcp[2] = color[c].r; tcp[3] = ((yalphaslice >> (x * 4)) & 15) * 0x11; } } @@ -788,9 +788,9 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t { uint8_t * tcp = &buffer[(ox + x)*4 + (oy + y) * Width*4]; int c = (yslice >> (x + x)) & 3; - tcp[0] = color[c].r; + tcp[0] = color[c].b; tcp[1] = color[c].g; - tcp[2] = color[c].b; + tcp[2] = color[c].r; tcp[3] = alpha[((yalphaslice >> (x*3)) & 7)]; } } @@ -803,15 +803,15 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t //=========================================================================== // -// FDDSTexture::CopyTrueColorPixels +// FDDSTexture::CopyPixels // //=========================================================================== -int FDDSTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FDDSTexture::CopyPixels(FBitmap *bmp) { auto lump = Wads.OpenLumpReader (SourceLump); - uint8_t *TexBuffer = new uint8_t[4*Width*Height]; + uint8_t *TexBuffer = bmp->GetPixels(); lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet); @@ -832,9 +832,6 @@ int FDDSTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo DecompressDXT5 (lump, Format == ID_DXT4, TexBuffer, PIX_ARGB); } - // All formats decompress to RGBA. - bmp->CopyPixelDataRGB(x, y, TexBuffer, Width, Height, 4, Width*4, rotate, CF_RGBA, inf); - delete [] TexBuffer; return -1; } diff --git a/src/textures/formats/imgztexture.cpp b/src/textures/formats/imgztexture.cpp index 108baf4b9..1486fdedc 100644 --- a/src/textures/formats/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -67,7 +67,7 @@ class FIMGZTexture : public FWorldTexture public: FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool isalpha); TArray Get8BitPixels(bool alphatex) override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; + int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override { return !isalpha; } FTextureFormat GetFormat() override { return isalpha ? TEX_RGB : TEX_Pal; } // should be TEX_Gray instead of TEX_RGB. Maybe later when all is working. @@ -201,9 +201,9 @@ TArray FIMGZTexture::Get8BitPixels(bool alphatex) // //========================================================================== -int FIMGZTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FIMGZTexture::CopyPixels(FBitmap *bmp) { - if (!isalpha) return FTexture::CopyTrueColorPixels(bmp, x, y, rotate, inf); - else return CopyTrueColorTranslated(bmp, x, y, rotate, translationtables[TRANSLATION_Standard][STD_Grayscale]->Palette, inf); + if (!isalpha) return FTexture::CopyPixels(bmp); + else return CopyTranslatedPixels(bmp, translationtables[TRANSLATION_Standard][STD_Grayscale]->Palette); } diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index 8da8a6729..fd8a7beb7 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -184,7 +184,7 @@ public: FJPEGTexture (int lumpnum, int width, int height); FTextureFormat GetFormat () override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override; TArray Get8BitPixels(bool alphatex) override; }; @@ -387,13 +387,13 @@ TArray FJPEGTexture::Get8BitPixels(bool doalpha) //=========================================================================== // -// FJPEGTexture::CopyTrueColorPixels +// FJPEGTexture::CopyPixels // // Preserves the full color information (unlike software mode) // //=========================================================================== -int FJPEGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FJPEGTexture::CopyPixels(FBitmap *bmp) { PalEntry pe[256]; @@ -438,24 +438,24 @@ int FJPEGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FC switch (cinfo.out_color_space) { case JCS_RGB: - bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height, - 3, cinfo.output_width * cinfo.output_components, rotate, CF_RGB, inf); + bmp->CopyPixelDataRGB(0, 0, buff, cinfo.output_width, cinfo.output_height, + 3, cinfo.output_width * cinfo.output_components, 0, CF_RGB); break; case JCS_GRAYSCALE: for (int i = 0; i < 256; i++) pe[i] = PalEntry(255, i, i, i); // default to a gray map - bmp->CopyPixelData(x, y, buff, cinfo.output_width, cinfo.output_height, - 1, cinfo.output_width, rotate, pe, inf); + bmp->CopyPixelData(0, 0, buff, cinfo.output_width, cinfo.output_height, + 1, cinfo.output_width, 0, pe); break; case JCS_CMYK: - bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height, - 4, cinfo.output_width * cinfo.output_components, rotate, CF_CMYK, inf); + bmp->CopyPixelDataRGB(0, 0, buff, cinfo.output_width, cinfo.output_height, + 4, cinfo.output_width * cinfo.output_components, 0, CF_CMYK); break; case JCS_YCbCr: - bmp->CopyPixelDataRGB(x, y, buff, cinfo.output_width, cinfo.output_height, - 4, cinfo.output_width * cinfo.output_components, rotate, CF_YCbCr, inf); + bmp->CopyPixelDataRGB(0, 0, buff, cinfo.output_width, cinfo.output_height, + 4, cinfo.output_width * cinfo.output_components, 0, CF_YCbCr); break; default: diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index 7b0432bff..1def77b5b 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -156,7 +156,7 @@ public: bool UseBasePalette() override; virtual void SetFrontSkyLayer () override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + int CopyPixels(FBitmap *bmp) override; int GetSourceLump() override { return DefinitionLump; } FTexture *GetRedirect() override; FTexture *GetRawTexture() override; @@ -468,36 +468,13 @@ TArray FMultiPatchTexture::MakeTexture (bool alphatex) // //=========================================================================== -int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FMultiPatchTexture::CopyPixels(FBitmap *bmp) { int retv = -1; if (bRedirect) { // Redirect straight to the real texture's routine. - return Parts[0].Texture->CopyTrueColorPixels(bmp, x, y, rotate, inf); - } - - if (rotate != 0 || (inf != NULL && ((inf->op != OP_OVERWRITE && inf->op != OP_COPY) || inf->blend != BLEND_NONE))) - { // We are doing some sort of fancy stuff to the destination bitmap, so composite to - // a temporary bitmap, and copy that. - FBitmap tbmp; - if (tbmp.Create(Width, Height)) - { - retv = MAX(retv, CopyTrueColorPixels(&tbmp, 0, 0, 0)); - bmp->CopyPixelDataRGB(x, y, tbmp.GetPixels(), Width, Height, - 4, tbmp.GetPitch(), rotate, CF_BGRA, inf); - } - return retv; - } - - // When compositing a multipatch texture with multipatch parts, - // drawing must be restricted to the actual area which is covered by this texture. - FClipRect saved_cr = bmp->GetClipRect(); - bmp->IntersectClipRect(x, y, Width, Height); - - if (inf != NULL && inf->op == OP_OVERWRITE) - { - bmp->Zero(); + return Parts[0].Texture->CopyPixels(bmp); } for(int i = 0; i < NumParts; i++) @@ -536,20 +513,12 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota } } - if (Parts[i].Translation != NULL) - { // Using a translation forces downconversion to the base palette - ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation->Palette, &info); - } - else - { - ret = Parts[i].Texture->CopyTrueColorPixels(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, &info); - } + auto Pixels = Parts[i].Texture->GetBgraBitmap(Parts[i].Translation ? Parts[i].Translation->Palette : nullptr, &ret); + bmp->Blit(Parts[i].OriginX, Parts[i].OriginY, Pixels, &info); // treat -1 (i.e. unknown) as absolute. We have no idea if this may have overwritten previous info so a real check needs to be done. if (ret == -1) retv = ret; else if (retv != -1 && ret > retv) retv = ret; } - // Restore previous clipping rectangle. - bmp->SetClipRect(saved_cr); return retv; } diff --git a/src/textures/formats/patchtexture.cpp b/src/textures/formats/patchtexture.cpp index 0b18f837f..5748bbce4 100644 --- a/src/textures/formats/patchtexture.cpp +++ b/src/textures/formats/patchtexture.cpp @@ -63,7 +63,7 @@ class FPatchTexture : public FWorldTexture public: FPatchTexture (int lumpnum, patch_t *header, bool isalphatex); TArray Get8BitPixels(bool alphatex) override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; + int CopyPixels(FBitmap *bmp) override; void DetectBadPatches(); bool UseBasePalette() override { return !isalpha; } @@ -264,10 +264,10 @@ TArray FPatchTexture::Get8BitPixels(bool alphatex) // //========================================================================== -int FPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FPatchTexture::CopyPixels(FBitmap *bmp) { - if (!isalpha) return FTexture::CopyTrueColorPixels(bmp, x, y, rotate, inf); - else return CopyTrueColorTranslated(bmp, x, y, rotate, translationtables[TRANSLATION_Standard][STD_Grayscale]->Palette, inf); + if (!isalpha) return FTexture::CopyPixels(bmp); + else return CopyTranslatedPixels(bmp, translationtables[TRANSLATION_Standard][STD_Grayscale]->Palette); } //========================================================================== diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index f144e7d8f..fc9863f24 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -85,7 +85,7 @@ public: FTextureFormat GetFormat () override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override; protected: @@ -452,13 +452,13 @@ TArray FPCXTexture::Get8BitPixels(bool alphatex) //=========================================================================== // -// FPCXTexture::CopyTrueColorPixels +// FPCXTexture::CopyPixels // // Preserves the full color information (unlike software mode) // //=========================================================================== -int FPCXTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FPCXTexture::CopyPixels(FBitmap *bmp) { PalEntry pe[256]; PCXHeader header; @@ -513,13 +513,13 @@ int FPCXTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo lump.Seek(sizeof(header), FileReader::SeekSet); ReadPCX8bits (Pixels, lump, &header); } - bmp->CopyPixelData(x, y, Pixels, Width, Height, 1, Width, rotate, pe, inf); + bmp->CopyPixelData(0, 0, Pixels, Width, Height, 1, Width, 0, pe); } else { Pixels = new uint8_t[Width*Height * 3]; ReadPCX24bits (Pixels, lump, &header, 3); - bmp->CopyPixelDataRGB(x, y, Pixels, Width, Height, 3, Width*3, rotate, CF_RGB, inf); + bmp->CopyPixelDataRGB(0, 0, Pixels, Width, Height, 3, Width*3, 0, CF_RGB); } delete [] Pixels; return 0; diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index 5c77ce5de..0d1cd661c 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -53,7 +53,7 @@ public: ~FPNGTexture(); FTextureFormat GetFormat () override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override; TArray Get8BitPixels(bool alphatex) override; @@ -529,11 +529,11 @@ TArray FPNGTexture::Get8BitPixels(bool alphatex) //=========================================================================== // -// FPNGTexture::CopyTrueColorPixels +// FPNGTexture::CopyPixels // //=========================================================================== -int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FPNGTexture::CopyPixels(FBitmap *bmp) { // Parse pre-IDAT chunks. I skip the CRCs. Is that bad? PalEntry pe[256]; @@ -618,29 +618,29 @@ int FPNGTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo { case 0: case 3: - bmp->CopyPixelData(x, y, Pixels, Width, Height, 1, Width, rotate, pe, inf); + bmp->CopyPixelData(0, 0, Pixels, Width, Height, 1, Width, 0, pe); break; case 2: if (!HaveTrans) { - bmp->CopyPixelDataRGB(x, y, Pixels, Width, Height, 3, pixwidth, rotate, CF_RGB, inf); + bmp->CopyPixelDataRGB(0, 0, Pixels, Width, Height, 3, pixwidth, 0, CF_RGB); } else { - bmp->CopyPixelDataRGB(x, y, Pixels, Width, Height, 3, pixwidth, rotate, CF_RGBT, inf, + bmp->CopyPixelDataRGB(0, 0, Pixels, Width, Height, 3, pixwidth, 0, CF_RGBT, nullptr, NonPaletteTrans[0], NonPaletteTrans[1], NonPaletteTrans[2]); transpal = true; } break; case 4: - bmp->CopyPixelDataRGB(x, y, Pixels, Width, Height, 2, pixwidth, rotate, CF_IA, inf); + bmp->CopyPixelDataRGB(0, 0, Pixels, Width, Height, 2, pixwidth, 0, CF_IA); transpal = -1; break; case 6: - bmp->CopyPixelDataRGB(x, y, Pixels, Width, Height, 4, pixwidth, rotate, CF_RGBA, inf); + bmp->CopyPixelDataRGB(0, 0, Pixels, Width, Height, 4, pixwidth, 0, CF_RGBA); transpal = -1; break; diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index 78b48cfac..901f23a41 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -53,7 +53,7 @@ class FRawPageTexture : public FWorldTexture public: FRawPageTexture (int lumpnum); TArray Get8BitPixels(bool alphatex) override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) override; + int CopyPixels(FBitmap *bmp) override; }; //========================================================================== @@ -203,9 +203,9 @@ TArray FRawPageTexture::Get8BitPixels(bool alphatex) return Pixels; } -int FRawPageTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FRawPageTexture::CopyPixels(FBitmap *bmp) { - if (mPaletteLump < 0) return FTexture::CopyTrueColorPixels(bmp, x, y, rotate, inf); + if (mPaletteLump < 0) return FTexture::CopyPixels(bmp); else { FMemLump lump = Wads.ReadLump(SourceLump); @@ -220,7 +220,7 @@ int FRawPageTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, pe.b = *psource++; pe.a = 255; } - bmp->CopyPixelData(x, y, source, 320, 200, 1, 320, 0, paldata, inf); + bmp->CopyPixelData(0, 0, source, 320, 200, 1, 320, 0, paldata); } return 0; } diff --git a/src/textures/formats/shadertexture.cpp b/src/textures/formats/shadertexture.cpp index e21bf4f24..9b5eddce1 100644 --- a/src/textures/formats/shadertexture.cpp +++ b/src/textures/formats/shadertexture.cpp @@ -119,9 +119,9 @@ public: return Pix; } - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override + int CopyPixels(FBitmap *bmp) override { - bmp->CopyPixelData(x, y, Pixels, Width, Height, Height, 1, rotate, translationtables[TRANSLATION_Standard][8]->Palette, inf); + bmp->CopyPixelData(0, 0, Pixels, Width, Height, Height, 1, 0, translationtables[TRANSLATION_Standard][8]->Palette); return 0; } diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index 9416f6398..111e3e473 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -80,7 +80,7 @@ public: FTGATexture (int lumpnum, TGAHeader *); FTextureFormat GetFormat () override; - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf = NULL) override; + int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override; protected: @@ -396,11 +396,11 @@ TArray FTGATexture::Get8BitPixels(bool alphatex) //=========================================================================== // -// FTGATexture::CopyTrueColorPixels +// FTGATexture::CopyPixels // //=========================================================================== -int FTGATexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FTGATexture::CopyPixels(FBitmap *bmp) { PalEntry pe[256]; auto lump = Wads.OpenLumpReader (SourceLump); @@ -490,7 +490,7 @@ int FTGATexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo switch (hdr.img_type & 7) { case 1: // paletted - bmp->CopyPixelData(x, y, ptr, Width, Height, step_x, Pitch, rotate, pe, inf); + bmp->CopyPixelData(0, 0, ptr, Width, Height, step_x, Pitch, 0, pe); break; case 2: // RGB @@ -498,21 +498,21 @@ int FTGATexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo { case 15: case 16: - bmp->CopyPixelDataRGB(x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_RGB555, inf); + bmp->CopyPixelDataRGB(0, 0, ptr, Width, Height, step_x, Pitch, 0, CF_RGB555); break; case 24: - bmp->CopyPixelDataRGB(x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_BGR, inf); + bmp->CopyPixelDataRGB(0, 0, ptr, Width, Height, step_x, Pitch, 0, CF_BGR); break; case 32: if ((hdr.img_desc&15)!=8) // 32 bits without a valid alpha channel { - bmp->CopyPixelDataRGB(x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_BGR, inf); + bmp->CopyPixelDataRGB(0, 0, ptr, Width, Height, step_x, Pitch, 0, CF_BGR); } else { - bmp->CopyPixelDataRGB(x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_BGRA, inf); + bmp->CopyPixelDataRGB(0, 0, ptr, Width, Height, step_x, Pitch, 9, CF_BGRA); transval = -1; } break; @@ -527,11 +527,11 @@ int FTGATexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCo { case 8: for(int i=0;i<256;i++) pe[i]=PalEntry(255,i,i,i); // gray map - bmp->CopyPixelData(x, y, ptr, Width, Height, step_x, Pitch, rotate, pe, inf); + bmp->CopyPixelData(0, 0, ptr, Width, Height, step_x, Pitch, 0, pe); break; case 16: - bmp->CopyPixelDataRGB(x, y, ptr, Width, Height, step_x, Pitch, rotate, CF_I16, inf); + bmp->CopyPixelDataRGB(0, 0, ptr, Width, Height, step_x, Pitch, 0, CF_I16); break; default: diff --git a/src/textures/hires/hirestex.cpp b/src/textures/hires/hirestex.cpp index dae7654a0..7f65341ea 100644 --- a/src/textures/hires/hirestex.cpp +++ b/src/textures/hires/hirestex.cpp @@ -381,8 +381,10 @@ unsigned char *FTexture::LoadHiresTexture(int *width, int *height) memset(buffer, 0, w * (h + 1) * 4); FBitmap bmp(buffer, w * 4, w, h); + int trans; + auto Pixels = HiresTexture->GetBgraBitmap(nullptr, &trans); + bmp.Blit(0, 0, Pixels); - int trans = HiresTexture->CopyTrueColorPixels(&bmp, 0, 0); HiresTexture->CheckTrans(buffer, w*h, trans); if (bHiresHasColorKey) diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 6a3572b03..2d165d46c 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -60,9 +60,9 @@ TArray FSkyBox::Get8BitPixels(bool alphatex) // //----------------------------------------------------------------------------- -int FSkyBox::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FSkyBox::CopyPixels(FBitmap *bmp) { - if (faces[0]) return faces[0]->CopyTrueColorPixels(bmp, x, y, rotate, inf); + if (faces[0]) return faces[0]->CopyPixels(bmp); return 0; } diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index 0dec6aa54..cbdbdb0e6 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -17,7 +17,7 @@ public: FSkyBox(const char *name = nullptr); TArray Get8BitPixels(bool alphatex); - int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf); + int CopyPixels(FBitmap *bmp); bool UseBasePalette(); void Unload (); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index e1630a11c..87aa95c19 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -421,7 +421,7 @@ void FTexture::FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x, //=========================================================================== // -// FTexture::CopyTrueColorPixels +// FTexture::CopyPixels // // this is the generic case that can handle // any properly implemented texture for software rendering. @@ -431,29 +431,32 @@ void FTexture::FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x, // //=========================================================================== -int FTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) +int FTexture::CopyPixels(FBitmap *bmp) { PalEntry *palette = screen->GetPalette(); for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values auto ppix = Get8BitPixels(false); // should use composition cache - bmp->CopyPixelData(x, y, ppix.Data(), Width, Height, Height, 1, rotate, palette, inf); + bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); for(int i=1;i<256;i++) palette[i].a = 0; return 0; } -int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf) +int FTexture::CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap) { auto ppix = Get8BitPixels(false); // should use composition cache - bmp->CopyPixelData(x, y, ppix.Data(), Width, Height, Height, 1, rotate, remap, inf); + bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, remap, nullptr); return 0; } -FBitmap FTexture::GetBgraBitmap(PalEntry *remap) +FBitmap FTexture::GetBgraBitmap(PalEntry *remap, int *ptrans) { FBitmap bmp; + int trans; + bmp.Create(GetWidth(), GetHeight()); - if (!remap) CopyTrueColorPixels(&bmp, 0, 0, 0, nullptr); - else CopyTrueColorTranslated(&bmp, 0, 0, 0, remap, nullptr); + if (!remap) trans = CopyPixels(&bmp); + else trans = CopyTranslatedPixels(&bmp, remap); + if (ptrans) *ptrans = trans; return bmp; } @@ -532,11 +535,9 @@ PalEntry FTexture::GetSkyCapColor(bool bottom) { bSWSkyColorDone = true; - FBitmap bitmap; - bitmap.Create(GetWidth(), GetHeight()); - CopyTrueColorPixels(&bitmap, 0, 0); - int w = GetWidth(); - int h = GetHeight(); + FBitmap bitmap = GetBgraBitmap(nullptr); + int w = bitmap.GetWidth(); + int h = bitmap.GetHeight(); const uint32_t *buffer = (const uint32_t *)bitmap.GetPixels(); if (buffer) @@ -938,25 +939,25 @@ unsigned char * FTexture::CreateTexBuffer(int translation, int & w, int & h, int W = w = GetWidth() + 2 * exx; H = h = GetHeight() + 2 * exx; - buffer = new unsigned char[W*(H + 1) * 4]; memset(buffer, 0, W * (H + 1) * 4); + auto remap = translation <= 0? nullptr : FUniquePalette::GetPalette(translation); FBitmap bmp(buffer, W * 4, W, H); - if (translation <= 0) + int trans; + auto Pixels = GetBgraBitmap(remap, &trans); + bmp.Blit(exx, exx, Pixels); + + if (remap == nullptr) { - int trans = CopyTrueColorPixels(&bmp, exx, exx, 0, nullptr); CheckTrans(buffer, W*H, trans); isTransparent = bTranslucent; } else { - // When using translations everything must be mapped to the base palette. - // so use CopyTrueColorTranslated - CopyTrueColorTranslated(&bmp, exx, exx, 0, FUniquePalette::GetPalette(translation)); isTransparent = 0; - // This is not conclusive for setting the texture's transparency info. + // A translated image is not conclusive for setting the texture's transparency info. } if (flags & CTF_ProcessData) diff --git a/src/textures/textures.h b/src/textures/textures.h index 10caf1bac..ec609e641 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -301,7 +301,7 @@ public: // Returns the whole texture, stored in column-major order virtual TArray Get8BitPixels(bool alphatex); - /*virtual*/ FBitmap GetBgraBitmap(PalEntry *remap); + /*virtual*/ FBitmap GetBgraBitmap(PalEntry *remap, int *trans = nullptr); public: static void FlipSquareBlock (uint8_t *block, int x, int y); @@ -388,8 +388,9 @@ protected: // Returns true if GetPixelsBgra includes mipmaps virtual bool Mipmapped() { return true; } - virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL); - virtual int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf = NULL); + virtual int CopyPixels(FBitmap *bmp); + int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); + virtual bool UseBasePalette(); virtual FTexture *GetRedirect(); diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 6b6ce6aef..23876289e 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -105,8 +105,8 @@ extern void LayoutMainWindow(HWND hWnd, HWND pane); static void CalculateCPUSpeed(); -static HCURSOR CreateCompatibleCursor(FTexture *cursorpic); -static HCURSOR CreateAlphaCursor(FTexture *cursorpic); +static HCURSOR CreateCompatibleCursor(FBitmap &cursorpic, int leftofs, int topofs); +static HCURSOR CreateAlphaCursor(FBitmap &cursorpic, int leftofs, int topofs); static HCURSOR CreateBitmapCursor(int xhot, int yhot, HBITMAP and_mask, HBITMAP color_mask); static void DestroyCustomCursor(); @@ -917,19 +917,22 @@ bool I_SetCursor(FTexture *cursorpic) { HCURSOR cursor; -#if 0 - if (cursorpic != NULL && cursorpic->UseType != ETextureType::Null) + if (cursorpic != NULL && cursorpic->isValid()) { - // Must be no larger than 32x32. - if (cursorpic->GetWidth() > 32 || cursorpic->GetHeight() > 32) + auto image = cursorpic->GetBgraBitmap(nullptr); + // Must be no larger than 32x32. (is this still necessary? + if (image.GetWidth() > 32 || image.GetHeight() > 32) { return false; } + // Fixme: This should get a raw image, not a texture. (Once raw images get implemented.) + int lo = cursorpic->GetDisplayLeftOffset(); + int to = cursorpic->GetDisplayTopOffset(); - cursor = CreateAlphaCursor(cursorpic); + cursor = CreateAlphaCursor(image, lo, to); if (cursor == NULL) { - cursor = CreateCompatibleCursor(cursorpic); + cursor = CreateCompatibleCursor(image, lo, to); } if (cursor == NULL) { @@ -941,7 +944,6 @@ bool I_SetCursor(FTexture *cursorpic) atterm(DestroyCustomCursor); } else -#endif { DestroyCustomCursor(); cursor = LoadCursor(NULL, IDC_ARROW); @@ -975,11 +977,10 @@ bool I_SetCursor(FTexture *cursorpic) // //========================================================================== -static HCURSOR CreateCompatibleCursor(FTexture *cursorpic) +static HCURSOR CreateCompatibleCursor(FBitmap &bmp, int leftofs, int topofs) { -#if 0 - int picwidth = cursorpic->GetWidth(); - int picheight = cursorpic->GetHeight(); + int picwidth = bmp.GetWidth(); + int picheight = bmp.GetHeight(); // Create bitmap masks for the cursor from the texture. HDC dc = GetDC(NULL); @@ -1004,12 +1005,7 @@ static HCURSOR CreateCompatibleCursor(FTexture *cursorpic) SelectObject(xor_mask_dc, GetStockObject(BLACK_BRUSH)); Rectangle(xor_mask_dc, 0, 0, 32, 32); - FBitmap bmp; - const uint8_t *pixels; - - bmp.Create(picwidth, picheight); - cursorpic->CopyTrueColorPixels(&bmp, 0, 0); - pixels = bmp.GetPixels(); + const uint8_t *pixels = bmp.GetPixels(); // Copy color data from the source texture to the cursor bitmaps. for (int y = 0; y < picheight; ++y) @@ -1028,10 +1024,7 @@ static HCURSOR CreateCompatibleCursor(FTexture *cursorpic) DeleteDC(xor_mask_dc); // Create the cursor from the bitmaps. - return CreateBitmapCursor(cursorpic->GetLeftOffset(0), cursorpic->GetTopOffset(0), and_mask, xor_mask); -#else - return nullptr; -#endif + return CreateBitmapCursor(leftofs, topofs, and_mask, xor_mask); } //========================================================================== @@ -1042,9 +1035,8 @@ static HCURSOR CreateCompatibleCursor(FTexture *cursorpic) // //========================================================================== -static HCURSOR CreateAlphaCursor(FTexture *cursorpic) +static HCURSOR CreateAlphaCursor(FBitmap &source, int leftofs, int topofs) { -#if 0 HDC dc; BITMAPV5HEADER bi; HBITMAP color, mono; @@ -1093,11 +1085,11 @@ static HCURSOR CreateAlphaCursor(FTexture *cursorpic) // Copy cursor to the color bitmap. Note that GDI bitmaps are upside down compared // to normal conventions, so we create the FBitmap pointing at the last row and use - // a negative pitch so that CopyTrueColorPixels will use GDI's orientation. + // a negative pitch so that Blit will use GDI's orientation. if (scale == 1) { FBitmap bmp((uint8_t *)bits + 31 * 32 * 4, -32 * 4, 32, 32); - cursorpic->CopyTrueColorPixels(&bmp, 0, 0); + bmp.Blit(0, 0, source); } else { @@ -1105,7 +1097,7 @@ static HCURSOR CreateAlphaCursor(FTexture *cursorpic) unscaled.Resize(32 * 32); for (int i = 0; i < 32 * 32; i++) unscaled[i] = 0; FBitmap bmp((uint8_t *)&unscaled[0] + 31 * 32 * 4, -32 * 4, 32, 32); - cursorpic->CopyTrueColorPixels(&bmp, 0, 0); + bmp.Blit(0, 0, source); uint32_t *scaled = (uint32_t*)bits; for (int y = 0; y < 32 * scale; y++) { @@ -1116,10 +1108,7 @@ static HCURSOR CreateAlphaCursor(FTexture *cursorpic) } } - return CreateBitmapCursor(cursorpic->GetLeftOffset(0) * scale, cursorpic->GetTopOffset(0) * scale, mono, color); -#else - return nullptr; -#endif + return CreateBitmapCursor(leftofs * scale, topofs * scale, mono, color); } //========================================================================== From e35d88e0397282e4cda941f18837ec92fb23047e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 8 Dec 2018 20:44:28 +0100 Subject: [PATCH 18/66] - moved some utility code out of FTexture. --- src/textures/formats/automaptexture.cpp | 3 +- src/textures/formats/ddstexture.cpp | 9 +- src/textures/formats/flattexture.cpp | 3 +- src/textures/formats/imgztexture.cpp | 3 +- src/textures/formats/jpegtexture.cpp | 9 +- src/textures/formats/multipatchtexture.cpp | 3 +- src/textures/formats/patchtexture.cpp | 3 +- src/textures/formats/pcxtexture.cpp | 15 +- src/textures/formats/pngtexture.cpp | 23 +-- src/textures/formats/rawpagetexture.cpp | 3 +- src/textures/formats/shadertexture.cpp | 3 +- src/textures/formats/tgatexture.cpp | 13 +- src/textures/imagehelpers.h | 154 +++++++++++++++++++++ src/textures/texture.cpp | 127 +---------------- src/textures/textures.h | 56 +------- 15 files changed, 210 insertions(+), 217 deletions(-) create mode 100644 src/textures/imagehelpers.h diff --git a/src/textures/formats/automaptexture.cpp b/src/textures/formats/automaptexture.cpp index 4eb4ec353..3c3763678 100644 --- a/src/textures/formats/automaptexture.cpp +++ b/src/textures/formats/automaptexture.cpp @@ -39,6 +39,7 @@ #include "files.h" #include "w_wad.h" #include "textures/textures.h" +#include "imagehelpers.h" //========================================================================== // @@ -96,7 +97,7 @@ TArray FAutomapTexture::Get8BitPixels(bool alphatex) TArray Pixels(Width * Height, true); - const uint8_t *remap = GetRemap(alphatex); + const uint8_t *remap = ImageHelpers::GetRemap(alphatex); for (x = 0; x < Width; ++x) { for (y = 0; y < Height; ++y) diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index d13733ccf..cbcb1b562 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -53,6 +53,7 @@ #include "w_wad.h" #include "bitmap.h" #include "v_video.h" +#include "imagehelpers.h" // Since we want this to compile under Linux too, we need to define this // stuff ourselves instead of including a DirectX header. @@ -470,7 +471,7 @@ void FDDSTexture::ReadRGB (FileReader &lump, uint8_t *buffer, int pixelmode) uint32_t g = (c & GMask) << GShiftL; g |= g >> GShiftR; uint32_t b = (c & BMask) << BShiftL; b |= b >> BShiftR; uint32_t a = (c & AMask) << AShiftL; a |= a >> AShiftR; - *pixelp = RGBToPalette(pixelmode == PIX_Alphatex, r >> 24, g >> 24, b >> 24, a >> 24); + *pixelp = ImageHelpers::RGBToPalette(pixelmode == PIX_Alphatex, r >> 24, g >> 24, b >> 24, a >> 24); } else { @@ -556,7 +557,7 @@ void FDDSTexture::DecompressDXT1 (FileReader &lump, uint8_t *buffer, int pixelmo // Pick colors from the palette for each of the four colors. if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i) { - palcol[i] = RGBToPalette(pixelmode == PIX_Alphatex, color[i]); + palcol[i] = ImageHelpers::RGBToPalette(pixelmode == PIX_Alphatex, color[i]); } // Now decode this 4x4 block to the pixel buffer. for (y = 0; y < 4; ++y) @@ -636,7 +637,7 @@ void FDDSTexture::DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t // Pick colors from the palette for each of the four colors. if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i) { - palcol[i] = RGBToPalette(pixelmode == PIX_Alphatex, color[i], false); + palcol[i] = ImageHelpers::RGBToPalette(pixelmode == PIX_Alphatex, color[i], false); } // Now decode this 4x4 block to the pixel buffer. @@ -748,7 +749,7 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t // Pick colors from the palette for each of the four colors. if (pixelmode != PIX_ARGB) for (i = 3; i >= 0; --i) { - palcol[i] = RGBToPalette(pixelmode == PIX_Alphatex, color[i], false); + palcol[i] = ImageHelpers::RGBToPalette(pixelmode == PIX_Alphatex, color[i], false); } // Now decode this 4x4 block to the pixel buffer. for (y = 0; y < 4; ++y) diff --git a/src/textures/formats/flattexture.cpp b/src/textures/formats/flattexture.cpp index 7f1dfbd52..44a814d71 100644 --- a/src/textures/formats/flattexture.cpp +++ b/src/textures/formats/flattexture.cpp @@ -37,6 +37,7 @@ #include "files.h" #include "w_wad.h" #include "textures/textures.h" +#include "imagehelpers.h" //========================================================================== // @@ -110,7 +111,7 @@ TArray FFlatTexture::Get8BitPixels(bool alphatex) { memset (Pixels.Data() + numread, 0xBB, Width*Height - numread); } - FTexture::FlipSquareBlockRemap(Pixels.Data(), Width, Height, GetRemap(alphatex)); + ImageHelpers::FlipSquareBlockRemap(Pixels.Data(), Width, ImageHelpers::GetRemap(alphatex)); return Pixels; } diff --git a/src/textures/formats/imgztexture.cpp b/src/textures/formats/imgztexture.cpp index 1486fdedc..7523d2080 100644 --- a/src/textures/formats/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -38,6 +38,7 @@ #include "w_wad.h" #include "v_video.h" #include "bitmap.h" +#include "imagehelpers.h" bool checkIMGZPalette(FileReader &file); @@ -134,7 +135,7 @@ TArray FIMGZTexture::Get8BitPixels(bool alphatex) TArray Pixels(Width*Height, true); dest_p = Pixels.Data(); - const uint8_t *remap = GetRemap(alphatex, isalpha); + const uint8_t *remap = ImageHelpers::GetRemap(alphatex, isalpha); // Convert the source image from row-major to column-major format and remap it if (!imgz->Compression) diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index fd8a7beb7..647fc139c 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -45,6 +45,7 @@ extern "C" #include "v_text.h" #include "bitmap.h" #include "v_video.h" +#include "imagehelpers.h" struct FLumpSourceMgr : public jpeg_source_mgr @@ -316,7 +317,7 @@ TArray FJPEGTexture::Get8BitPixels(bool doalpha) case JCS_RGB: for (int x = Width; x > 0; --x) { - *out = RGBToPalette(doalpha, in[0], in[1], in[2]); + *out = ImageHelpers::RGBToPalette(doalpha, in[0], in[1], in[2]); out += Height; in += 3; } @@ -324,7 +325,7 @@ TArray FJPEGTexture::Get8BitPixels(bool doalpha) case JCS_GRAYSCALE: { - auto remap = GetRemap(doalpha, true); + auto remap = ImageHelpers::GetRemap(doalpha, true); for (int x = Width; x > 0; --x) { *out = remap[in[0]]; @@ -342,7 +343,7 @@ TArray FJPEGTexture::Get8BitPixels(bool doalpha) int r = in[3] - (((256 - in[0])*in[3]) >> 8); int g = in[3] - (((256 - in[1])*in[3]) >> 8); int b = in[3] - (((256 - in[2])*in[3]) >> 8); - *out = RGBToPalette(doalpha, r, g, b); + *out = ImageHelpers::RGBToPalette(doalpha, r, g, b); out += Height; in += 4; } @@ -356,7 +357,7 @@ TArray FJPEGTexture::Get8BitPixels(bool doalpha) int r = clamp((int)(Y + 1.40200 * (Cr - 0x80)), 0, 255); int g = clamp((int)(Y - 0.34414 * (Cb - 0x80) - 0.71414 * (Cr - 0x80)), 0, 255); int b = clamp((int)(Y + 1.77200 * (Cb - 0x80)), 0, 255); - *out = RGBToPalette(doalpha, r, g, b); + *out = ImageHelpers::RGBToPalette(doalpha, r, g, b); out += Height; in += 4; } diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index 1def77b5b..f8e7078d8 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -49,6 +49,7 @@ #include "v_video.h" #include "v_text.h" #include "cmdlib.h" +#include "imagehelpers.h" // On the Alpha, accessing the shorts directly if they aren't aligned on a // 4-byte boundary causes unaligned access warnings. Why it does this at @@ -450,7 +451,7 @@ TArray FMultiPatchTexture::MakeTexture (bool alphatex) { if (*out == 0 && in[3] != 0) { - *out = RGBToPalette(alphatex, in[2], in[1], in[0]); + *out = ImageHelpers::RGBToPalette(alphatex, in[2], in[1], in[0]); } out += Height; in += 4; diff --git a/src/textures/formats/patchtexture.cpp b/src/textures/formats/patchtexture.cpp index 5748bbce4..25492916b 100644 --- a/src/textures/formats/patchtexture.cpp +++ b/src/textures/formats/patchtexture.cpp @@ -39,6 +39,7 @@ #include "v_palette.h" #include "v_video.h" #include "bitmap.h" +#include "imagehelpers.h" // posts are runs of non masked source pixels @@ -179,7 +180,7 @@ TArray FPatchTexture::Get8BitPixels(bool alphatex) maxcol = (const column_t *)((const uint8_t *)patch + Wads.LumpLength (SourceLump) - 3); - remap = GetRemap(alphatex, isalpha); + remap = ImageHelpers::GetRemap(alphatex, isalpha); // Special case for skies if (bNoRemap0 && remap == GPalette.Remap) { diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index fc9863f24..14531c5c6 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -39,6 +39,7 @@ #include "w_wad.h" #include "bitmap.h" #include "v_video.h" +#include "imagehelpers.h" //========================================================================== // @@ -391,15 +392,15 @@ TArray FPCXTexture::Get8BitPixels(bool alphatex) { default: case 1: - PaletteMap[0] = alphatex? 0 : GrayMap[0]; - PaletteMap[1] = alphatex? 255 : GrayMap[255]; + PaletteMap[0] = alphatex? 0 : ImageHelpers::GrayMap[0]; + PaletteMap[1] = alphatex? 255 : ImageHelpers::GrayMap[255]; ReadPCX1bit (Pixels.Data(), lump, &header); break; case 4: for (int i = 0; i < 16; i++) { - PaletteMap[i] = RGBToPalettePrecise(alphatex, header.palette[i * 3], header.palette[i * 3 + 1], header.palette[i * 3 + 2]); + PaletteMap[i] = ImageHelpers::RGBToPalettePrecise(alphatex, header.palette[i * 3], header.palette[i * 3 + 1], header.palette[i * 3 + 2]); } ReadPCX4bits (Pixels.Data(), lump, &header); break; @@ -416,19 +417,19 @@ TArray FPCXTexture::Get8BitPixels(bool alphatex) uint8_t r = lump.ReadUInt8(); uint8_t g = lump.ReadUInt8(); uint8_t b = lump.ReadUInt8(); - PaletteMap[i] = RGBToPalettePrecise(alphatex, r, g, b); + PaletteMap[i] = ImageHelpers::RGBToPalettePrecise(alphatex, r, g, b); } lump.Seek(sizeof(header), FileReader::SeekSet); ReadPCX8bits (Pixels.Data(), lump, &header); } if (Width == Height) { - FlipSquareBlockRemap(Pixels.Data(), Width, Height, PaletteMap); + ImageHelpers::FlipSquareBlockRemap(Pixels.Data(), Width, PaletteMap); } else { TArray newpix(Width*Height, true); - FlipNonSquareBlockRemap (newpix.Data(), Pixels.Data(), Width, Height, Width, PaletteMap); + ImageHelpers::FlipNonSquareBlockRemap (newpix.Data(), Pixels.Data(), Width, Height, Width, PaletteMap); return newpix; } } @@ -441,7 +442,7 @@ TArray FPCXTexture::Get8BitPixels(bool alphatex) { for(int x=0; x < Width; x++) { - Pixels[y + Height * x] = RGBToPalette(alphatex, row[0], row[1], row[2]); + Pixels[y + Height * x] = ImageHelpers::RGBToPalette(alphatex, row[0], row[1], row[2]); row+=3; } } diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index 0d1cd661c..75ae9f5d7 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -39,6 +39,7 @@ #include "templates.h" #include "m_png.h" #include "bitmap.h" +#include "imagehelpers.h" //========================================================================== // @@ -293,12 +294,12 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename bMasked = true; PaletteSize = 256; PaletteMap = new uint8_t[256]; - memcpy (PaletteMap, GrayMap, 256); + memcpy (PaletteMap, ImageHelpers::GrayMap, 256); PaletteMap[NonPaletteTrans[0]] = 0; } else { - PaletteMap = GrayMap; + PaletteMap = ImageHelpers::GrayMap; } break; @@ -335,7 +336,7 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename FPNGTexture::~FPNGTexture () { - if (PaletteMap != nullptr && PaletteMap != FTexture::GrayMap) + if (PaletteMap != nullptr && PaletteMap != ImageHelpers::GrayMap) { delete[] PaletteMap; PaletteMap = nullptr; @@ -424,17 +425,17 @@ TArray FPNGTexture::Get8BitPixels(bool alphatex) { if (!alphatex) { - FTexture::FlipSquareBlockRemap (Pixels.Data(), Width, Height, PaletteMap); + ImageHelpers::FlipSquareBlockRemap (Pixels.Data(), Width, PaletteMap); } else if (ColorType == 0) { - FTexture::FlipSquareBlock (Pixels.Data(), Width, Height); + ImageHelpers::FlipSquareBlock (Pixels.Data(), Width); } else { uint8_t alpharemap[256]; ReadAlphaRemap(lump, alpharemap); - FTexture::FlipSquareBlockRemap(Pixels.Data(), Width, Height, alpharemap); + ImageHelpers::FlipSquareBlockRemap(Pixels.Data(), Width, alpharemap); } } else @@ -442,17 +443,17 @@ TArray FPNGTexture::Get8BitPixels(bool alphatex) TArray newpix(Width*Height, true); if (!alphatex) { - FTexture::FlipNonSquareBlockRemap (newpix.Data(), Pixels.Data(), Width, Height, Width, PaletteMap); + ImageHelpers::FlipNonSquareBlockRemap (newpix.Data(), Pixels.Data(), Width, Height, Width, PaletteMap); } else if (ColorType == 0) { - FTexture::FlipNonSquareBlock (newpix.Data(), Pixels.Data(), Width, Height, Width); + ImageHelpers::FlipNonSquareBlock (newpix.Data(), Pixels.Data(), Width, Height, Width); } else { uint8_t alpharemap[256]; ReadAlphaRemap(lump, alpharemap); - FTexture::FlipNonSquareBlockRemap(newpix.Data(), Pixels.Data(), Width, Height, Width, alpharemap); + ImageHelpers::FlipNonSquareBlockRemap(newpix.Data(), Pixels.Data(), Width, Height, Width, alpharemap); } return newpix; } @@ -485,7 +486,7 @@ TArray FPNGTexture::Get8BitPixels(bool alphatex) } else { - *out++ = RGBToPalette(alphatex, in[0], in[1], in[2]); + *out++ = ImageHelpers::RGBToPalette(alphatex, in[0], in[1], in[2]); } in += pitch; } @@ -514,7 +515,7 @@ TArray FPNGTexture::Get8BitPixels(bool alphatex) { for (y = Height; y > 0; --y) { - *out++ = RGBToPalette(alphatex, in[0], in[1], in[2], in[3]); + *out++ = ImageHelpers::RGBToPalette(alphatex, in[0], in[1], in[2], in[3]); in += pitch; } in -= backstep; diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index 901f23a41..72ccecf26 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -39,6 +39,7 @@ #include "gi.h" #include "bitmap.h" #include "textures/textures.h" +#include "imagehelpers.h" //========================================================================== @@ -184,7 +185,7 @@ TArray FRawPageTexture::Get8BitPixels(bool alphatex) TArray Pixels(Width*Height, true); dest_p = Pixels.Data(); - const uint8_t *remap = GetRemap(alphatex); + const uint8_t *remap = ImageHelpers::GetRemap(alphatex); // This does not handle the custom palette. // User maps are encouraged to use a real image format when replacing E2END and the original could never be used anywhere else. diff --git a/src/textures/formats/shadertexture.cpp b/src/textures/formats/shadertexture.cpp index 9b5eddce1..e68fdf7e5 100644 --- a/src/textures/formats/shadertexture.cpp +++ b/src/textures/formats/shadertexture.cpp @@ -39,6 +39,7 @@ #include "menu/menu.h" #include "w_wad.h" #include "bitmap.h" +#include "imagehelpers.h" class FBarShader : public FWorldTexture @@ -113,7 +114,7 @@ public: // even if it makes little sense. for (int i = 0; i < 512; i++) { - Pix[i] = GrayMap[Pixels[i]]; + Pix[i] = ImageHelpers::GrayMap[Pixels[i]]; } } return Pix; diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index 111e3e473..12b420e19 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -39,6 +39,7 @@ #include "templates.h" #include "bitmap.h" #include "v_video.h" +#include "imagehelpers.h" //========================================================================== @@ -244,7 +245,7 @@ TArray FTGATexture::Get8BitPixels(bool alphatex) r=g=b=a=0; break; } - PaletteMap[i] = RGBToPalettePrecise(alphatex, r, g, b, a); + PaletteMap[i] = ImageHelpers::RGBToPalettePrecise(alphatex, r, g, b, a); } } @@ -303,7 +304,7 @@ TArray FTGATexture::Get8BitPixels(bool alphatex) for(int x=0;x> 10) & 0x1f) * 8, ((v >> 5) & 0x1f) * 8, (v & 0x1f) * 8); + Pixels[x*Height + y] = ImageHelpers::RGBToPalette(alphatex, ((v >> 10) & 0x1f) * 8, ((v >> 5) & 0x1f) * 8, (v & 0x1f) * 8); p+=step_x; } } @@ -315,7 +316,7 @@ TArray FTGATexture::Get8BitPixels(bool alphatex) uint8_t * p = ptr + y * Pitch; for(int x=0;x FTGATexture::Get8BitPixels(bool alphatex) uint8_t * p = ptr + y * Pitch; for(int x=0;x FTGATexture::Get8BitPixels(bool alphatex) uint8_t * p = ptr + y * Pitch; for(int x=0;x FTGATexture::Get8BitPixels(bool alphatex) case 3: // Grayscale { - auto remap = GetRemap(alphatex, true); + auto remap = ImageHelpers::GetRemap(alphatex, true); switch (hdr.bpp) { case 8: diff --git a/src/textures/imagehelpers.h b/src/textures/imagehelpers.h new file mode 100644 index 000000000..16b5e1876 --- /dev/null +++ b/src/textures/imagehelpers.h @@ -0,0 +1,154 @@ +#pragma once + +/* + ** imagehelpers.h + ** Utilities for image conversion - mostly 8 bit paletted baggage + ** + **--------------------------------------------------------------------------- + ** Copyright 2004-2007 Randy Heit + ** Copyright 2006-2018 Christoph Oelckers + ** All rights reserved. + ** + ** Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions + ** are met: + ** + ** 1. Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** 2. Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in the + ** documentation and/or other materials provided with the distribution. + ** 3. The name of the author may not be used to endorse or promote products + ** derived from this software without specific prior written permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + **--------------------------------------------------------------------------- + ** + ** + */ + + +#include +#include "tarray.h" +#include "colormatcher.h" +#include "v_palette.h" +#include "textures/bitmap.h" +#include "r_data/renderstyle.h" +#include "r_data/r_translate.h" + +namespace ImageHelpers +{ + extern uint8_t GrayMap[256]; + + // Helpers for creating paletted images. + inline uint8_t *GetRemap(bool wantluminance, bool srcisgrayscale = false) + { + if (wantluminance) + { + return translationtables[TRANSLATION_Standard][srcisgrayscale ? STD_Gray : STD_Grayscale]->Remap; + } + else + { + return srcisgrayscale ? GrayMap : GPalette.Remap; + } + } + + inline uint8_t RGBToPalettePrecise(bool wantluminance, int r, int g, int b, int a = 255) + { + if (wantluminance) + { + return (uint8_t)Luminance(r, g, b) * a / 255; + } + else + { + return ColorMatcher.Pick(r, g, b); + } + } + + inline uint8_t RGBToPalette(bool wantluminance, int r, int g, int b, int a = 255) + { + if (wantluminance) + { + // This is the same formula the OpenGL renderer uses for grayscale textures with an alpha channel. + return (uint8_t)(Luminance(r, g, b) * a / 255); + } + else + { + return a < 128? 0 : RGB256k.RGB[r >> 2][g >> 2][b >> 2]; + } + } + + inline uint8_t RGBToPalette(bool wantluminance, PalEntry pe, bool hasalpha = true) + { + return RGBToPalette(wantluminance, pe.r, pe.g, pe.b, hasalpha? pe.a : 255); + } + + //========================================================================== + // + // Converts a texture between row-major and column-major format + // by flipping it about the X=Y axis. + // + //========================================================================== + + template + void FlipSquareBlock (T *block, int x) + { + for (int i = 0; i < x; ++i) + { + uint8_t *corner = block + x*i + i; + int count = x - i; + for (int j = 0; j < count; j++) + { + std::swap(corner[j], corner[j*x]); + } + } + } + + inline void FlipSquareBlockRemap (uint8_t *block, int x, const uint8_t *remap) + { + for (int i = 0; i < x; ++i) + { + uint8_t *corner = block + x*i + i; + int count = x - i; + for (int j = 0; j < count; j++) + { + auto t = remap[corner[j]]; + corner[j] = remap[corner[j*x]]; + corner[j*x] = t; + } + } + } + + template + void FlipNonSquareBlock (T *dst, const T *src, int x, int y, int srcpitch) + { + for (int i = 0; i < x; ++i) + { + for (int j = 0; j < y; ++j) + { + dst[i*y+j] = src[i+j*srcpitch]; + } + } + } + + inline void FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x, int y, int srcpitch, const uint8_t *remap) + { + for (int i = 0; i < x; ++i) + { + for (int j = 0; j < y; ++j) + { + dst[i*y+j] = remap[src[i+j*srcpitch]]; + } + } + } + +} diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 87aa95c19..06e73a6d8 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -48,6 +48,7 @@ #include "hwrenderer/textures/hw_material.h" #include "hwrenderer/textures/hw_ihwtexture.h" #include "swrenderer/textures/r_swtexture.h" +#include "imagehelpers.h" FTexture *CreateBrightmapTexture(FTexture*); @@ -66,13 +67,13 @@ CUSTOM_CVAR(Int, r_spriteadjust, 2, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // //========================================================================== -uint8_t FTexture::GrayMap[256]; +uint8_t ImageHelpers::GrayMap[256]; void FTexture::InitGrayMap() { for (int i = 0; i < 256; ++i) { - GrayMap[i] = ColorMatcher.Pick(i, i, i); + ImageHelpers::GrayMap[i] = ColorMatcher.Pick(i, i, i); } } @@ -297,128 +298,6 @@ void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, in } } -//========================================================================== -// -// Converts a texture between row-major and column-major format -// by flipping it about the X=Y axis. -// -//========================================================================== - -void FTexture::FlipSquareBlock (uint8_t *block, int x, int y) -{ - int i, j; - - if (x != y) return; - - for (i = 0; i < x; ++i) - { - uint8_t *corner = block + x*i + i; - int count = x - i; - if (count & 1) - { - count--; - swapvalues (corner[count], corner[count*x]); - } - for (j = 0; j < count; j += 2) - { - swapvalues (corner[j], corner[j*x]); - swapvalues (corner[j+1], corner[(j+1)*x]); - } - } -} - -void FTexture::FlipSquareBlockBgra(uint32_t *block, int x, int y) -{ - int i, j; - - if (x != y) return; - - for (i = 0; i < x; ++i) - { - uint32_t *corner = block + x*i + i; - int count = x - i; - if (count & 1) - { - count--; - swapvalues(corner[count], corner[count*x]); - } - for (j = 0; j < count; j += 2) - { - swapvalues(corner[j], corner[j*x]); - swapvalues(corner[j + 1], corner[(j + 1)*x]); - } - } -} - -void FTexture::FlipSquareBlockRemap (uint8_t *block, int x, int y, const uint8_t *remap) -{ - int i, j; - uint8_t t; - - if (x != y) return; - - for (i = 0; i < x; ++i) - { - uint8_t *corner = block + x*i + i; - int count = x - i; - if (count & 1) - { - count--; - t = remap[corner[count]]; - corner[count] = remap[corner[count*x]]; - corner[count*x] = t; - } - for (j = 0; j < count; j += 2) - { - t = remap[corner[j]]; - corner[j] = remap[corner[j*x]]; - corner[j*x] = t; - t = remap[corner[j+1]]; - corner[j+1] = remap[corner[(j+1)*x]]; - corner[(j+1)*x] = t; - } - } -} - -void FTexture::FlipNonSquareBlock (uint8_t *dst, const uint8_t *src, int x, int y, int srcpitch) -{ - int i, j; - - for (i = 0; i < x; ++i) - { - for (j = 0; j < y; ++j) - { - dst[i*y+j] = src[i+j*srcpitch]; - } - } -} - -void FTexture::FlipNonSquareBlockBgra(uint32_t *dst, const uint32_t *src, int x, int y, int srcpitch) -{ - int i, j; - - for (i = 0; i < x; ++i) - { - for (j = 0; j < y; ++j) - { - dst[i*y + j] = src[i + j*srcpitch]; - } - } -} - -void FTexture::FlipNonSquareBlockRemap (uint8_t *dst, const uint8_t *src, int x, int y, int srcpitch, const uint8_t *remap) -{ - int i, j; - - for (i = 0; i < x; ++i) - { - for (j = 0; j < y; ++j) - { - dst[i*y+j] = remap[src[i+j*srcpitch]]; - } - } -} - //=========================================================================== // // FTexture::CopyPixels diff --git a/src/textures/textures.h b/src/textures/textures.h index ec609e641..3541f432f 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -304,12 +304,14 @@ public: /*virtual*/ FBitmap GetBgraBitmap(PalEntry *remap, int *trans = nullptr); public: + /* static void FlipSquareBlock (uint8_t *block, int x, int y); static void FlipSquareBlockBgra (uint32_t *block, int x, int y); static void FlipSquareBlockRemap (uint8_t *block, int x, int y, const uint8_t *remap); static void FlipNonSquareBlock (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch); static void FlipNonSquareBlockBgra (uint32_t *blockto, const uint32_t *blockfrom, int x, int y, int srcpitch); static void FlipNonSquareBlockRemap (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch, const uint8_t *remap); + */ static bool SmoothEdges(unsigned char * buffer,int w, int h); static PalEntry averageColor(const uint32_t *data, int size, int maxout); @@ -459,53 +461,6 @@ protected: protected: uint16_t Width, Height; int16_t _LeftOffset[2], _TopOffset[2]; - static uint8_t GrayMap[256]; - uint8_t *GetRemap(bool wantluminance, bool srcisgrayscale = false) - { - if (wantluminance) - { - return translationtables[TRANSLATION_Standard][srcisgrayscale ? STD_Gray : STD_Grayscale]->Remap; - } - else - { - return srcisgrayscale ? GrayMap : GPalette.Remap; - } - } - - uint8_t RGBToPalettePrecise(bool wantluminance, int r, int g, int b, int a = 255) - { - if (wantluminance) - { - return (uint8_t)Luminance(r, g, b) * a / 255; - } - else - { - return ColorMatcher.Pick(r, g, b); - } - } - - uint8_t RGBToPalette(bool wantluminance, int r, int g, int b, int a = 255) - { - if (wantluminance) - { - // This is the same formula the OpenGL renderer uses for grayscale textures with an alpha channel. - return (uint8_t)(Luminance(r, g, b) * a / 255); - } - else - { - return a < 128? 0 : RGB256k.RGB[r >> 2][g >> 2][b >> 2]; - } - } - - uint8_t RGBToPalette(bool wantluminance, PalEntry pe, bool hasalpha = true) - { - return RGBToPalette(wantluminance, pe.r, pe.g, pe.b, hasalpha? pe.a : 255); - } - - uint8_t RGBToPalette(FRenderStyle style, int r, int g, int b, int a = 255) - { - return RGBToPalette(!!(style.Flags & STYLEF_RedIsAlpha), r, g, b, a); - } FTexture (const char *name = NULL, int lumpnum = -1); @@ -635,13 +590,6 @@ public: void DeleteAll(); void SpriteAdjustChanged(); - // Replaces one texture with another. The new texture will be assigned - // the same name, slot, and use type as the texture it is replacing. - // The old texture will no longer be managed. Set free true if you want - // the old texture to be deleted or set it false if you want it to - // be left alone in memory. You will still need to delete it at some - // point, because the texture manager no longer knows about it. - // This function can be used for such things as warping textures. void ReplaceTexture (FTextureID picnum, FTexture *newtexture, bool free); int NumTextures () const { return (int)Textures.Size(); } From 5eab9441573c8f9b34d8a68a3a730d0a327252f0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 8 Dec 2018 23:28:35 +0100 Subject: [PATCH 19/66] - started separating the texture class from the image format handlers. --- src/CMakeLists.txt | 2 + src/polyrenderer/scene/poly_playersprite.cpp | 3 + src/textures/formats/buildtexture.cpp | 1 - src/textures/formats/ddstexture.cpp | 25 ----- src/textures/formats/imgztexture.cpp | 1 - src/textures/formats/jpegtexture.cpp | 12 --- src/textures/formats/multipatchtexture.cpp | 17 ---- src/textures/formats/patchtexture.cpp | 32 +++---- src/textures/formats/pcxtexture.cpp | 13 --- src/textures/formats/pngtexture.cpp | 22 ----- src/textures/formats/tgatexture.cpp | 12 --- src/textures/image.cpp | 84 +++++++++++++++++ src/textures/image.h | 97 ++++++++++++++++++++ src/textures/imagetexture.cpp | 97 ++++++++++++++++++++ src/textures/texture.cpp | 5 - src/textures/textures.h | 3 - 16 files changed, 297 insertions(+), 129 deletions(-) create mode 100644 src/textures/image.cpp create mode 100644 src/textures/image.h create mode 100644 src/textures/imagetexture.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 035e2016c..6166ea2fe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1098,6 +1098,8 @@ set (PCH_SOURCES textures/anim_switches.cpp textures/bitmap.cpp textures/texture.cpp + textures/image.cpp + textures/imagetexture.cpp textures/texturemanager.cpp textures/skyboxtexture.cpp textures/formats/automaptexture.cpp diff --git a/src/polyrenderer/scene/poly_playersprite.cpp b/src/polyrenderer/scene/poly_playersprite.cpp index 64a115290..93cfca926 100644 --- a/src/polyrenderer/scene/poly_playersprite.cpp +++ b/src/polyrenderer/scene/poly_playersprite.cpp @@ -386,6 +386,8 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p { noaccel = true; } +#if 0 + // The HW 2D drawer should be able to handle this without problems // If the main colormap has fixed lights, and this sprite is being drawn with that // colormap, disable acceleration so that the lights can remain fixed. PolyCameraLight *cameraLight = PolyCameraLight::Instance(); @@ -395,6 +397,7 @@ void RenderPolyPlayerSprites::RenderSprite(PolyRenderThread *thread, DPSprite *p { noaccel = true; } +#endif } else { diff --git a/src/textures/formats/buildtexture.cpp b/src/textures/formats/buildtexture.cpp index ed7bbe1f8..ede4a5a76 100644 --- a/src/textures/formats/buildtexture.cpp +++ b/src/textures/formats/buildtexture.cpp @@ -59,7 +59,6 @@ public: TArray Get8BitPixels(bool alphatex) override; int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override { return false; } - FTextureFormat GetFormat() override { return TEX_RGB; } protected: const uint8_t *RawPixels; diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index cbcb1b562..4d84c365a 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -163,7 +163,6 @@ class FDDSTexture : public FWorldTexture public: FDDSTexture (FileReader &lump, int lumpnum, void *surfdesc); - FTextureFormat GetFormat () override; TArray Get8BitPixels(bool alphatex) override; protected: @@ -375,30 +374,6 @@ void FDDSTexture::CalcBitShift (uint32_t mask, uint8_t *lshiftp, uint8_t *rshift // //========================================================================== -FTextureFormat FDDSTexture::GetFormat() -{ -#if 0 - switch (Format) - { - case ID_DXT1: return TEX_DXT1; - case ID_DXT2: return TEX_DXT2; - case ID_DXT3: return TEX_DXT3; - case ID_DXT4: return TEX_DXT4; - case ID_DXT5: return TEX_DXT5; - default: return TEX_RGB; - } -#else - // For now, create a true color texture to preserve all colors. - return TEX_RGB; -#endif -} - -//========================================================================== -// -// -// -//========================================================================== - TArray FDDSTexture::Get8BitPixels(bool alphatex) { auto lump = Wads.OpenLumpReader (SourceLump); diff --git a/src/textures/formats/imgztexture.cpp b/src/textures/formats/imgztexture.cpp index 7523d2080..bc70f5e67 100644 --- a/src/textures/formats/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -71,7 +71,6 @@ public: int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override { return !isalpha; } - FTextureFormat GetFormat() override { return isalpha ? TEX_RGB : TEX_Pal; } // should be TEX_Gray instead of TEX_RGB. Maybe later when all is working. }; diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index 647fc139c..5a39dc9e8 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -184,7 +184,6 @@ class FJPEGTexture : public FWorldTexture public: FJPEGTexture (int lumpnum, int width, int height); - FTextureFormat GetFormat () override; int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override; TArray Get8BitPixels(bool alphatex) override; @@ -262,17 +261,6 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) // //========================================================================== -FTextureFormat FJPEGTexture::GetFormat() -{ - return TEX_RGB; -} - -//========================================================================== -// -// -// -//========================================================================== - TArray FJPEGTexture::Get8BitPixels(bool doalpha) { auto lump = Wads.OpenLumpReader (SourceLump); diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index f8e7078d8..63cffb95d 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -153,7 +153,6 @@ public: FMultiPatchTexture (FScanner &sc, ETextureType usetype); ~FMultiPatchTexture (); - FTextureFormat GetFormat() override; bool UseBasePalette() override; virtual void SetFrontSkyLayer () override; @@ -523,22 +522,6 @@ int FMultiPatchTexture::CopyPixels(FBitmap *bmp) return retv; } -//========================================================================== -// -// FMultiPatchTexture :: GetFormat -// -// only returns 'paletted' if all patches use the base palette. -// -//========================================================================== - -FTextureFormat FMultiPatchTexture::GetFormat() -{ - if (bComplex) return TEX_RGB; - if (NumParts == 1) return Parts[0].Texture->GetFormat(); - return UseBasePalette() ? TEX_Pal : TEX_RGB; -} - - //=========================================================================== // // FMultipatchTexture::UseBasePalette diff --git a/src/textures/formats/patchtexture.cpp b/src/textures/formats/patchtexture.cpp index 25492916b..f988b9c02 100644 --- a/src/textures/formats/patchtexture.cpp +++ b/src/textures/formats/patchtexture.cpp @@ -39,6 +39,7 @@ #include "v_palette.h" #include "v_video.h" #include "bitmap.h" +#include "image.h" #include "imagehelpers.h" @@ -57,18 +58,16 @@ bool checkPatchForAlpha(const void *buffer, uint32_t length); // //========================================================================== -class FPatchTexture : public FWorldTexture +class FPatchTexture : public FImageSource { bool badflag = false; bool isalpha = false; + bool bNoRemap0 = false; // Unfortunately this was done as a very bad hack in ZDoom and will need impovement public: FPatchTexture (int lumpnum, patch_t *header, bool isalphatex); TArray Get8BitPixels(bool alphatex) override; int CopyPixels(FBitmap *bmp) override; void DetectBadPatches(); - - bool UseBasePalette() override { return !isalpha; } - FTextureFormat GetFormat() override { return isalpha ? TEX_RGB : TEX_Pal; } // should be TEX_Gray instead of TEX_RGB. Maybe later when all is working. }; //========================================================================== @@ -81,11 +80,10 @@ static bool CheckIfPatch(FileReader & file, bool &isalpha) { if (file.GetLength() < 13) return false; // minimum length of a valid Doom patch - uint8_t *data = new uint8_t[file.GetLength()]; file.Seek(0, FileReader::SeekSet); - file.Read(data, file.GetLength()); + auto data = file.Read(file.GetLength()); - const patch_t *foo = (const patch_t *)data; + const patch_t *foo = (const patch_t *)data.Data(); int height = LittleShort(foo->height); int width = LittleShort(foo->width); @@ -108,7 +106,6 @@ static bool CheckIfPatch(FileReader & file, bool &isalpha) } else if (ofs >= (uint32_t)(file.GetLength())) // Need one byte for an empty column (but there's patches that don't know that!) { - delete [] data; return false; } } @@ -116,12 +113,10 @@ static bool CheckIfPatch(FileReader & file, bool &isalpha) { // only check this if the texture passed validation. // Here is a good point because we already have a valid buffer of the lump's data. - isalpha = checkPatchForAlpha(data, (uint32_t)file.GetLength()); + isalpha = checkPatchForAlpha(data.Data(), (uint32_t)file.GetLength()); } - delete[] data; return !gapAtStart; } - delete [] data; return false; } @@ -142,7 +137,7 @@ FTexture *PatchTexture_TryCreate(FileReader & file, int lumpnum) header.height = file.ReadUInt16(); header.leftoffset = file.ReadInt16(); header.topoffset = file.ReadInt16(); - return new FPatchTexture(lumpnum, &header, isalpha); + return new FImageTexture(new FPatchTexture(lumpnum, &header, isalpha)); } //========================================================================== @@ -152,13 +147,14 @@ FTexture *PatchTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FPatchTexture::FPatchTexture (int lumpnum, patch_t * header, bool isalphatex) -: FWorldTexture(NULL, lumpnum) +: FImageSource(lumpnum) { + bUseGamePalette = !isalphatex; isalpha = isalphatex; Width = header->width; Height = header->height; - _LeftOffset[1] = _LeftOffset[0] = header->leftoffset; - _TopOffset[1] = _TopOffset[0] = header->topoffset; + LeftOffset = header->leftoffset; + TopOffset = header->topoffset; DetectBadPatches(); } @@ -267,7 +263,7 @@ TArray FPatchTexture::Get8BitPixels(bool alphatex) int FPatchTexture::CopyPixels(FBitmap *bmp) { - if (!isalpha) return FTexture::CopyPixels(bmp); + if (!isalpha) return FImageSource::CopyPixels(bmp); else return CopyTranslatedPixels(bmp, translationtables[TRANSLATION_Standard][STD_Grayscale]->Palette); } @@ -305,8 +301,8 @@ void FPatchTexture::DetectBadPatches () return; // More than one post in a column! } } - _LeftOffset[1] = _LeftOffset[0] = 0; - _TopOffset[1] = _TopOffset[0] = 0; + LeftOffset = 0; + TopOffset = 0; badflag = true; bMasked = false; // Hacked textures don't have transparent parts. } diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index 14531c5c6..7a28dffb0 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -84,8 +84,6 @@ class FPCXTexture : public FWorldTexture public: FPCXTexture (int lumpnum, PCXHeader &); - FTextureFormat GetFormat () override; - int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override; @@ -157,17 +155,6 @@ FPCXTexture::FPCXTexture(int lumpnum, PCXHeader & hdr) // //========================================================================== -FTextureFormat FPCXTexture::GetFormat() -{ - return TEX_RGB; -} - -//========================================================================== -// -// -// -//========================================================================== - void FPCXTexture::ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr) { int y, i, bytes; diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index 75ae9f5d7..cbdf6f3aa 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -53,7 +53,6 @@ public: FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, uint8_t bitdepth, uint8_t colortype, uint8_t interlace); ~FPNGTexture(); - FTextureFormat GetFormat () override; int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override; TArray Get8BitPixels(bool alphatex) override; @@ -349,27 +348,6 @@ FPNGTexture::~FPNGTexture () // //========================================================================== -FTextureFormat FPNGTexture::GetFormat() -{ -#if 0 - switch (ColorType) - { - case 3: return TEX_Pal; - case 0: return TEX_Gray; - default: return TEX_RGB; - } -#else - // For now, create a true color texture to preserve all colors. - return TEX_RGB; -#endif -} - -//========================================================================== -// -// -// -//========================================================================== - void FPNGTexture::ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap) { auto p = lump->Tell(); diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index 12b420e19..a97d26dba 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -80,7 +80,6 @@ class FTGATexture : public FWorldTexture public: FTGATexture (int lumpnum, TGAHeader *); - FTextureFormat GetFormat () override; int CopyPixels(FBitmap *bmp) override; bool UseBasePalette() override; @@ -145,17 +144,6 @@ FTGATexture::FTGATexture (int lumpnum, TGAHeader * hdr) // //========================================================================== -FTextureFormat FTGATexture::GetFormat() -{ - return TEX_RGB; -} - -//========================================================================== -// -// -// -//========================================================================== - void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel) { uint8_t data[4]; diff --git a/src/textures/image.cpp b/src/textures/image.cpp new file mode 100644 index 000000000..ac217d171 --- /dev/null +++ b/src/textures/image.cpp @@ -0,0 +1,84 @@ +/* +** texture.cpp +** The base texture class +** +**--------------------------------------------------------------------------- +** Copyright 2004-2007 Randy Heit +** Copyright 2006-2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "v_video.h" +#include "bitmap.h" +#include "image.h" + + +//=========================================================================== +// +// the default just returns an empty texture. +// +//=========================================================================== + +TArray FImageSource::Get8BitPixels(bool alphatex) +{ + TArray Pixels(Width * Height, true); + memset(Pixels.Data(), 0, Width * Height); + return Pixels; +} + + +//=========================================================================== +// +// FImageSource::CopyPixels +// +// this is the generic case that can handle +// any properly implemented texture for software rendering. +// Its drawback is that it is limited to the base palette which is +// why all classes that handle different palettes should subclass this +// method +// +//=========================================================================== + +int FImageSource::CopyPixels(FBitmap *bmp) +{ + PalEntry *palette = screen->GetPalette(); + for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values + auto ppix = Get8BitPixels(false); // should use composition cache + bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); + for(int i=1;i<256;i++) palette[i].a = 0; + return 0; +} + +int FImageSource::CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap) +{ + auto ppix = Get8BitPixels(false); // should use composition cache + bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, remap, nullptr); + return 0; +} + diff --git a/src/textures/image.h b/src/textures/image.h new file mode 100644 index 000000000..e868c557d --- /dev/null +++ b/src/textures/image.h @@ -0,0 +1,97 @@ +#pragma once + +#include +#include "tarray.h" +#include "textures/bitmap.h" + + +// This represents a naked image. It has no high level logic attached to it. +// All it can do is provide raw image data to its users. +class FImageSource +{ + friend class FBrightmapImage; +protected: + int SourceLump; + int Width = 0, Height = 0; + int LeftOffset = 0, TopOffset = 0; // Offsets stored in the image. + bool bUseGamePalette = false; // true if this is an image without its own color set. + + // internal builder functions for true color textures. + +public: + + bool bMasked = true; // Image (might) have holes (Assume true unless proven otherwise!) + int8_t bTranslucent = -1; // Image has pixels with a non-0/1 value. (-1 means the user needs to do a real check) + + // Returns the whole texture, paletted and true color versions respectively. + virtual TArray Get8BitPixels(bool alphatex); + virtual int CopyPixels(FBitmap *bmp); + int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); + + // Conversion option + enum EType + { + normal = 0, + luminance = 1, + noremap0 = 2 + }; + + FImageSource(int sourcelump = -1) : SourceLump(sourcelump) {} + virtual ~FImageSource() {} + + // Creates an image from the given lump. + static FImageSource *CreateImageSource(int lumpnum); + + int GetWidth() const + { + return Width; + } + + int GetHeight() const + { + return Height; + } + + std::pair GetSize() const + { + return std::make_pair(Width, Height); + } + + std::pair GetOffsets() const + { + return std::make_pair(LeftOffset, TopOffset); + } + + int LumpNum() const + { + return SourceLump; + } + + bool UseGamePalette() const + { + return bUseGamePalette; + } + + bool UseBasePalette() = delete; +}; + +//========================================================================== +// +// a TGA texture +// +//========================================================================== + +class FImageTexture : public FWorldTexture +{ + FImageSource *mImage; +public: + FImageTexture (FImageSource *image); + virtual TArray Get8BitPixels(bool alphatex); + + bool UseBasePalette() override; + +protected: + int CopyPixels(FBitmap *bmp) override; + +}; + diff --git a/src/textures/imagetexture.cpp b/src/textures/imagetexture.cpp new file mode 100644 index 000000000..00326664c --- /dev/null +++ b/src/textures/imagetexture.cpp @@ -0,0 +1,97 @@ +/* +** imagetexture.cpp +** Texture class based on FImageSource +** +**--------------------------------------------------------------------------- +** Copyright 2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "doomtype.h" +#include "files.h" +#include "w_wad.h" +#include "templates.h" +#include "bitmap.h" +#include "v_video.h" +#include "image.h" + + +//========================================================================== +// +// +// +//========================================================================== + +FImageTexture::FImageTexture(FImageSource *img) +: FWorldTexture(nullptr, img->LumpNum()) +{ + mImage = img; + Wads.GetLumpName (Name, img->LumpNum()); + Width = img->GetWidth(); + Height = img->GetHeight(); + + auto offsets = img->GetOffsets(); + _LeftOffset[1] = _LeftOffset[0] = offsets.first;; + _TopOffset[1] = _TopOffset[0] = offsets.second; + + bMasked = img->bMasked; + bTranslucent = img->bTranslucent; +} + +//=========================================================================== +// +// +// +//=========================================================================== + +int FImageTexture::CopyPixels(FBitmap *bmp) +{ + return mImage->CopyPixels(bmp); +} + +//=========================================================================== +// +// +// +//=========================================================================== + +TArray FImageTexture::Get8BitPixels(bool alpha) +{ + return mImage->Get8BitPixels(alpha); +} + +//=========================================================================== +// +// +//=========================================================================== + +bool FImageTexture::UseBasePalette() +{ + return mImage->UseGamePalette(); +} diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 06e73a6d8..c8969d978 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -240,11 +240,6 @@ FTexture::~FTexture () // //========================================================================== -FTextureFormat FTexture::GetFormat() -{ - return TEX_Pal; -} - void FTexture::SetFrontSkyLayer () { bNoRemap0 = true; diff --git a/src/textures/textures.h b/src/textures/textures.h index 3541f432f..46ef35601 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -396,9 +396,6 @@ protected: virtual bool UseBasePalette(); virtual FTexture *GetRedirect(); - // Returns the native pixel format for this image - virtual FTextureFormat GetFormat(); - void SetSpeed(float fac) { shaderspeed = fac; } int GetWidth () { return Width; } From 583a740441e62b5c4c011557e007032a1049640c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 9 Dec 2018 07:39:05 +0100 Subject: [PATCH 20/66] - separated the image converters from the texture offsets. Mostly done, except for FMultiPatchTexture and FFontChar1 + 2. Note that this commit leaks those image objects! --- src/CMakeLists.txt | 1 - src/r_data/models/models_voxel.cpp | 8 ++-- src/textures/formats/automaptexture.cpp | 12 +++--- src/textures/formats/brightmaptexture.cpp | 23 ++++------ src/textures/formats/buildtexture.cpp | 15 +++---- src/textures/formats/ddstexture.cpp | 9 ++-- src/textures/formats/emptytexture.cpp | 8 ++-- src/textures/formats/flattexture.cpp | 8 ++-- src/textures/formats/imgztexture.cpp | 17 ++++---- src/textures/formats/jpegtexture.cpp | 19 ++------- src/textures/formats/multipatchtexture.cpp | 2 +- src/textures/formats/pcxtexture.cpp | 18 ++------ src/textures/formats/pngtexture.cpp | 5 ++- src/textures/formats/rawpagetexture.cpp | 26 ++++++------ src/textures/formats/shadertexture.cpp | 13 ++---- src/textures/formats/tgatexture.cpp | 19 ++------- src/textures/formats/worldtexture.cpp | 49 ---------------------- src/textures/image.h | 5 ++- src/textures/imagetexture.cpp | 4 +- src/textures/texture.cpp | 5 ++- src/textures/textures.h | 8 ---- 21 files changed, 90 insertions(+), 184 deletions(-) delete mode 100644 src/textures/formats/worldtexture.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6166ea2fe..7d6b7f4eb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1119,7 +1119,6 @@ set (PCH_SOURCES textures/formats/emptytexture.cpp textures/formats/shadertexture.cpp textures/formats/tgatexture.cpp - textures/formats/worldtexture.cpp textures/hires/hqresize.cpp textures/hires/hirestex.cpp xlat/parse_xlat.cpp diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index 5b8e82571..6be9d0355 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -32,6 +32,7 @@ #include "textures/bitmap.h" #include "g_levellocals.h" #include "models.h" +#include "image.h" #ifdef _MSC_VER #pragma warning(disable:4244) // warning C4244: conversion from 'double' to 'float', possible loss of data @@ -46,13 +47,12 @@ // //=========================================================================== -class FVoxelTexture : public FWorldTexture +class FVoxelTexture : public FImageSource { public: FVoxelTexture(FVoxel *voxel); int CopyPixels(FBitmap *bmp) override; - bool UseBasePalette() override { return false; } TArray Get8BitPixels(bool alphatex) override; protected: @@ -70,7 +70,7 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) SourceVox = vox; Width = 16; Height = 16; - bNoCompress = true; + //bNoCompress = true; } //=========================================================================== @@ -156,7 +156,7 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned) { mVoxel = voxel; mOwningVoxel = owned; - mPalette = TexMan.AddTexture(new FVoxelTexture(voxel)); + mPalette = TexMan.AddTexture(new FImageTexture(new FVoxelTexture(voxel))); } //=========================================================================== diff --git a/src/textures/formats/automaptexture.cpp b/src/textures/formats/automaptexture.cpp index 3c3763678..39285d280 100644 --- a/src/textures/formats/automaptexture.cpp +++ b/src/textures/formats/automaptexture.cpp @@ -40,6 +40,7 @@ #include "w_wad.h" #include "textures/textures.h" #include "imagehelpers.h" +#include "image.h" //========================================================================== // @@ -47,7 +48,7 @@ // //========================================================================== -class FAutomapTexture : public FWorldTexture +class FAutomapTexture : public FImageSource { public: FAutomapTexture(int lumpnum); @@ -65,9 +66,9 @@ public: FTexture *AutomapTexture_TryCreate(FileReader &data, int lumpnum) { - if (data.GetLength() < 320) return NULL; - if (!Wads.CheckLumpName(lumpnum, "AUTOPAGE")) return NULL; - return new FAutomapTexture(lumpnum); + if (data.GetLength() < 320) return nullptr; + if (!Wads.CheckLumpName(lumpnum, "AUTOPAGE")) return nullptr; + return new FImageTexture(new FAutomapTexture(lumpnum)); } //========================================================================== @@ -77,10 +78,11 @@ FTexture *AutomapTexture_TryCreate(FileReader &data, int lumpnum) //========================================================================== FAutomapTexture::FAutomapTexture (int lumpnum) -: FWorldTexture(NULL, lumpnum) +: FImageSource(lumpnum) { Width = 320; Height = uint16_t(Wads.LumpLength(lumpnum) / 320); + bUseGamePalette = true; } //========================================================================== diff --git a/src/textures/formats/brightmaptexture.cpp b/src/textures/formats/brightmaptexture.cpp index 06cc29e90..1277cf527 100644 --- a/src/textures/formats/brightmaptexture.cpp +++ b/src/textures/formats/brightmaptexture.cpp @@ -39,17 +39,17 @@ #include "r_data/r_translate.h" #include "bitmap.h" #include "v_video.h" +#include "image.h" -class FBrightmapTexture : public FWorldTexture +class FBrightmapTexture : public FImageSource { public: - FBrightmapTexture (FTexture *source); + FBrightmapTexture (FImageSource *source); int CopyPixels(FBitmap *bmp) override; - bool UseBasePalette() override { return false; } protected: - FTexture *SourcePic; + FImageSource *SourcePic; }; //=========================================================================== @@ -60,17 +60,12 @@ protected: // //=========================================================================== -FBrightmapTexture::FBrightmapTexture (FTexture *source) +FBrightmapTexture::FBrightmapTexture (FImageSource *source) { - Name = ""; SourcePic = source; - CopySize(source); - bNoDecals = true; - Rotations = 0xffff; - UseType = ETextureType::Override; + Width = source->GetWidth(); + Height = source->GetHeight(); bMasked = false; - id.SetInvalid(); - SourceLump = -1; } int FBrightmapTexture::CopyPixels(FBitmap *bmp) @@ -79,7 +74,7 @@ int FBrightmapTexture::CopyPixels(FBitmap *bmp) return 0; } -FTexture *CreateBrightmapTexture(FTexture *tex) +FTexture *CreateBrightmapTexture(FImageSource *tex) { - return new FBrightmapTexture(tex); + return new FImageTexture(new FBrightmapTexture(tex)); } \ No newline at end of file diff --git a/src/textures/formats/buildtexture.cpp b/src/textures/formats/buildtexture.cpp index ede4a5a76..8900d5400 100644 --- a/src/textures/formats/buildtexture.cpp +++ b/src/textures/formats/buildtexture.cpp @@ -44,6 +44,7 @@ #include "textures/textures.h" #include "r_data/sprites.h" #include "resourcefiles/resourcefile.h" +#include "image.h" //========================================================================== @@ -52,13 +53,12 @@ // //========================================================================== -class FBuildTexture : public FWorldTexture +class FBuildTexture : public FImageSource { public: FBuildTexture (const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top); TArray Get8BitPixels(bool alphatex) override; int CopyPixels(FBitmap *bmp) override; - bool UseBasePalette() override { return false; } protected: const uint8_t *RawPixels; @@ -77,10 +77,8 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8 { Width = width; Height = height; - _LeftOffset[1] = _LeftOffset[0] = left; - _TopOffset[1] = _TopOffset[0] = top; - Name.Format("%sBTIL%04d", pathprefix.GetChars(), tilenum); - UseType = ETextureType::Override; + LeftOffset = left; + TopOffset = top; } TArray FBuildTexture::Get8BitPixels(bool alphatex) @@ -136,9 +134,12 @@ void FTextureManager::AddTiles (const FString &pathprefix, const void *tiles, in if (width <= 0 || height <= 0) continue; - tex = new FBuildTexture (pathprefix, i, tiledata, translation, width, height, xoffs, yoffs); + tex = new FImageTexture(new FBuildTexture (pathprefix, i, tiledata, translation, width, height, xoffs, yoffs)); texnum = AddTexture (tex); tiledata += size; + tex->Name.Format("%sBTIL%04d", pathprefix.GetChars(), i); + tex->UseType = ETextureType::Override; + // reactivate only if the texture counter works here. //StartScreen->Progress(); diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index 4d84c365a..f00a14172 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -54,6 +54,7 @@ #include "bitmap.h" #include "v_video.h" #include "imagehelpers.h" +#include "image.h" // Since we want this to compile under Linux too, we need to define this // stuff ourselves instead of including a DirectX header. @@ -152,7 +153,7 @@ struct DDSFileHeader // //========================================================================== -class FDDSTexture : public FWorldTexture +class FDDSTexture : public FImageSource { enum { @@ -273,7 +274,7 @@ FTexture *DDSTexture_TryCreate (FileReader &data, int lumpnum) { return NULL; } - return new FDDSTexture (data, lumpnum, &surfdesc); + return new FImageTexture(new FDDSTexture (data, lumpnum, &surfdesc)); } //========================================================================== @@ -283,13 +284,11 @@ FTexture *DDSTexture_TryCreate (FileReader &data, int lumpnum) //========================================================================== FDDSTexture::FDDSTexture (FileReader &lump, int lumpnum, void *vsurfdesc) -: FWorldTexture(NULL, lumpnum) +: FImageSource(lumpnum) { DDSURFACEDESC2 *surf = (DDSURFACEDESC2 *)vsurfdesc; - UseType = ETextureType::MiscPatch; bMasked = false; - Width = uint16_t(surf->Width); Height = uint16_t(surf->Height); diff --git a/src/textures/formats/emptytexture.cpp b/src/textures/formats/emptytexture.cpp index d793c9fb3..1246760b3 100644 --- a/src/textures/formats/emptytexture.cpp +++ b/src/textures/formats/emptytexture.cpp @@ -39,6 +39,7 @@ #include "files.h" #include "w_wad.h" #include "textures/textures.h" +#include "image.h" //========================================================================== // @@ -46,7 +47,7 @@ // //========================================================================== -class FEmptyTexture : public FWorldTexture +class FEmptyTexture : public FImageSource { public: FEmptyTexture (int lumpnum); @@ -67,7 +68,7 @@ FTexture *EmptyTexture_TryCreate(FileReader & file, int lumpnum) if (file.Read(check, 8) != 8) return NULL; if (memcmp(check, "\0\0\0\0\0\0\0\0", 8)) return NULL; - return new FEmptyTexture(lumpnum); + return new FImageTexture(new FEmptyTexture(lumpnum)); } //========================================================================== @@ -77,10 +78,11 @@ FTexture *EmptyTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FEmptyTexture::FEmptyTexture (int lumpnum) -: FWorldTexture(NULL, lumpnum) +: FImageSource(lumpnum) { bMasked = true; Width = Height = 1; + bUseGamePalette = true; } //========================================================================== diff --git a/src/textures/formats/flattexture.cpp b/src/textures/formats/flattexture.cpp index 44a814d71..46b9e43fc 100644 --- a/src/textures/formats/flattexture.cpp +++ b/src/textures/formats/flattexture.cpp @@ -38,6 +38,7 @@ #include "w_wad.h" #include "textures/textures.h" #include "imagehelpers.h" +#include "image.h" //========================================================================== // @@ -45,7 +46,7 @@ // //========================================================================== -class FFlatTexture : public FWorldTexture +class FFlatTexture : public FImageSource { public: FFlatTexture (int lumpnum); @@ -63,7 +64,7 @@ public: FTexture *FlatTexture_TryCreate(FileReader & file, int lumpnum) { - return new FFlatTexture(lumpnum); + return new FImageTexture(new FFlatTexture(lumpnum)); } //========================================================================== @@ -73,7 +74,7 @@ FTexture *FlatTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FFlatTexture::FFlatTexture (int lumpnum) -: FWorldTexture(NULL, lumpnum) +: FImageSource(lumpnum) { int area; int bits; @@ -91,6 +92,7 @@ FFlatTexture::FFlatTexture (int lumpnum) case 256*256: bits = 8; break; } + bUseGamePalette = true; bMasked = false; bTranslucent = false; Width = Height = 1 << bits; diff --git a/src/textures/formats/imgztexture.cpp b/src/textures/formats/imgztexture.cpp index bc70f5e67..b87f4b63d 100644 --- a/src/textures/formats/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -39,6 +39,7 @@ #include "v_video.h" #include "bitmap.h" #include "imagehelpers.h" +#include "image.h" bool checkIMGZPalette(FileReader &file); @@ -50,7 +51,7 @@ bool checkIMGZPalette(FileReader &file); // //========================================================================== -class FIMGZTexture : public FWorldTexture +class FIMGZTexture : public FImageSource { struct ImageHeader { @@ -69,8 +70,6 @@ public: FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool isalpha); TArray Get8BitPixels(bool alphatex) override; int CopyPixels(FBitmap *bmp) override; - - bool UseBasePalette() override { return !isalpha; } }; @@ -95,7 +94,7 @@ FTexture *IMGZTexture_TryCreate(FileReader & file, int lumpnum) l = file.ReadInt16(); t = file.ReadInt16(); ispalette = checkIMGZPalette(file); - return new FIMGZTexture(lumpnum, w, h, l, t, !ispalette); + return new FImageTexture(new FIMGZTexture(lumpnum, w, h, l, t, !ispalette)); } //========================================================================== @@ -105,14 +104,14 @@ FTexture *IMGZTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool _isalpha) - : FWorldTexture(NULL, lumpnum) + : FImageSource(lumpnum) { - Wads.GetLumpName (Name, lumpnum); Width = w; Height = h; - _LeftOffset[1] = _LeftOffset[0] = l; - _TopOffset[1] = _TopOffset[0] = t; + LeftOffset = l; + TopOffset = t; isalpha = _isalpha; + bUseGamePalette = !isalpha; } //========================================================================== @@ -203,7 +202,7 @@ TArray FIMGZTexture::Get8BitPixels(bool alphatex) int FIMGZTexture::CopyPixels(FBitmap *bmp) { - if (!isalpha) return FTexture::CopyPixels(bmp); + if (!isalpha) return FImageSource::CopyPixels(bmp); else return CopyTranslatedPixels(bmp, translationtables[TRANSLATION_Standard][STD_Grayscale]->Palette); } diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index 5a39dc9e8..06b093e95 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -46,6 +46,7 @@ extern "C" #include "bitmap.h" #include "v_video.h" #include "imagehelpers.h" +#include "image.h" struct FLumpSourceMgr : public jpeg_source_mgr @@ -179,13 +180,12 @@ void JPEG_OutputMessage (j_common_ptr cinfo) // //========================================================================== -class FJPEGTexture : public FWorldTexture +class FJPEGTexture : public FImageSource { public: FJPEGTexture (int lumpnum, int width, int height); int CopyPixels(FBitmap *bmp) override; - bool UseBasePalette() override; TArray Get8BitPixels(bool alphatex) override; }; @@ -236,7 +236,7 @@ FTexture *JPEGTexture_TryCreate(FileReader & data, int lumpnum) { return NULL; } - return new FJPEGTexture (lumpnum, BigShort(first4bytes.w[1]), BigShort(first4bytes.w[0])); + return new FImageTexture(new FJPEGTexture (lumpnum, BigShort(first4bytes.w[1]), BigShort(first4bytes.w[0]))); } //========================================================================== @@ -246,9 +246,8 @@ FTexture *JPEGTexture_TryCreate(FileReader & data, int lumpnum) //========================================================================== FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) -: FWorldTexture(NULL, lumpnum) +: FImageSource(lumpnum) { - UseType = ETextureType::MiscPatch; bMasked = false; Width = width; @@ -463,13 +462,3 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp) return 0; } - -//=========================================================================== -// -// -//=========================================================================== - -bool FJPEGTexture::UseBasePalette() -{ - return false; -} diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index 63cffb95d..42a9d7802 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -146,7 +146,7 @@ struct FPatchLookup // //========================================================================== -class FMultiPatchTexture : public FWorldTexture +class FMultiPatchTexture : public FTexture { public: FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflump); diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index 7a28dffb0..c755723e4 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -40,6 +40,7 @@ #include "bitmap.h" #include "v_video.h" #include "imagehelpers.h" +#include "image.h" //========================================================================== // @@ -79,13 +80,12 @@ struct PCXHeader // //========================================================================== -class FPCXTexture : public FWorldTexture +class FPCXTexture : public FImageSource { public: FPCXTexture (int lumpnum, PCXHeader &); int CopyPixels(FBitmap *bmp) override; - bool UseBasePalette() override; protected: void ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr); @@ -132,7 +132,7 @@ FTexture * PCXTexture_TryCreate(FileReader & file, int lumpnum) file.Seek(0, FileReader::SeekSet); file.Read(&hdr, sizeof(hdr)); - return new FPCXTexture(lumpnum, hdr); + return new FImageTexture(new FPCXTexture(lumpnum, hdr)); } //========================================================================== @@ -142,7 +142,7 @@ FTexture * PCXTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FPCXTexture::FPCXTexture(int lumpnum, PCXHeader & hdr) -: FWorldTexture(NULL, lumpnum) +: FImageSource(lumpnum) { bMasked = false; Width = LittleShort(hdr.xmax) - LittleShort(hdr.xmin) + 1; @@ -513,13 +513,3 @@ int FPCXTexture::CopyPixels(FBitmap *bmp) return 0; } - -//=========================================================================== -// -// -//=========================================================================== - -bool FPCXTexture::UseBasePalette() -{ - return false; -} diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index cbdf6f3aa..91b70b745 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -40,6 +40,7 @@ #include "m_png.h" #include "bitmap.h" #include "imagehelpers.h" +#include "image.h" //========================================================================== // @@ -47,7 +48,7 @@ // //========================================================================== -class FPNGTexture : public FWorldTexture +class FPNGTexture : public FImageSource { public: FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, uint8_t bitdepth, uint8_t colortype, uint8_t interlace); @@ -141,7 +142,7 @@ FTexture *PNGTexture_TryCreate(FileReader & data, int lumpnum) } } - return new FPNGTexture (data, lumpnum, FString(), width, height, bitdepth, colortype, interlace); + return new FImageTexture(new FPNGTexture (data, lumpnum, FString(), width, height, bitdepth, colortype, interlace)); } //========================================================================== diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index 72ccecf26..9c38748e2 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -40,6 +40,7 @@ #include "bitmap.h" #include "textures/textures.h" #include "imagehelpers.h" +#include "image.h" //========================================================================== @@ -48,7 +49,7 @@ // //========================================================================== -class FRawPageTexture : public FWorldTexture +class FRawPageTexture : public FImageSource { int mPaletteLump = -1; public: @@ -73,9 +74,9 @@ static bool CheckIfRaw(FileReader & data) int height; int width; - foo = (patch_t *)M_Malloc (data.GetLength()); - data.Seek (0, FileReader::SeekSet); - data.Read (foo, data.GetLength()); + data.Seek(0, FileReader::SeekSet); + auto bits = data.Read(data.GetLength()); + foo = (patch_t *)bits.Data();; height = LittleShort(foo->height); width = LittleShort(foo->width); @@ -98,7 +99,6 @@ static bool CheckIfRaw(FileReader & data) } else if (ofs >= 64000-1) // Need one byte for an empty column { - M_Free (foo); return true; } else @@ -109,29 +109,24 @@ static bool CheckIfRaw(FileReader & data) { if (foo2[ofs] == 255) { - M_Free (foo); return true; } ofs += foo2[ofs+1] + 4; } if (ofs >= 64000) { - M_Free (foo); return true; } } } if (gapAtStart || (x != width)) { - M_Free (foo); return true; } - M_Free(foo); return false; } else { - M_Free (foo); return true; } } @@ -144,8 +139,8 @@ static bool CheckIfRaw(FileReader & data) FTexture *RawPageTexture_TryCreate(FileReader & file, int lumpnum) { - if (!CheckIfRaw(file)) return NULL; - return new FRawPageTexture(lumpnum); + if (!CheckIfRaw(file)) return nullptr; + return new FImageTexture(new FRawPageTexture(lumpnum)); } @@ -156,17 +151,20 @@ FTexture *RawPageTexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FRawPageTexture::FRawPageTexture (int lumpnum) -: FWorldTexture(NULL, lumpnum) +: FImageSource(lumpnum) { Width = 320; Height = 200; // Special case hack for Heretic's E2 end pic. This is not going to be exposed as an editing feature because the implications would be horrible. + FString Name; + Wads.GetLumpName(Name, lumpnum); if (Name.CompareNoCase("E2END") == 0 && gameinfo.gametype == GAME_Heretic) { mPaletteLump = Wads.CheckNumForName("E2PAL"); if (Wads.LumpLength(mPaletteLump) < 768) mPaletteLump = -1; } + else bUseGamePalette = true; } //========================================================================== @@ -206,7 +204,7 @@ TArray FRawPageTexture::Get8BitPixels(bool alphatex) int FRawPageTexture::CopyPixels(FBitmap *bmp) { - if (mPaletteLump < 0) return FTexture::CopyPixels(bmp); + if (mPaletteLump < 0) return FImageSource::CopyPixels(bmp); else { FMemLump lump = Wads.ReadLump(SourceLump); diff --git a/src/textures/formats/shadertexture.cpp b/src/textures/formats/shadertexture.cpp index e68fdf7e5..6f3443798 100644 --- a/src/textures/formats/shadertexture.cpp +++ b/src/textures/formats/shadertexture.cpp @@ -40,16 +40,16 @@ #include "w_wad.h" #include "bitmap.h" #include "imagehelpers.h" +#include "image.h" -class FBarShader : public FWorldTexture +class FBarShader : public FImageSource { public: FBarShader(bool vertical, bool reverse) { int i; - Name.Format("BarShader%c%c", vertical ? 'v' : 'h', reverse ? 'r' : 'f'); Width = vertical ? 2 : 256; Height = vertical ? 256 : 2; bMasked = false; @@ -126,12 +126,6 @@ public: return 0; } - bool UseBasePalette() override - { - return false; - } - - private: uint8_t Pixels[512]; }; @@ -139,5 +133,6 @@ private: FTexture *CreateShaderTexture(bool vertical, bool reverse) { - return new FBarShader(vertical, reverse); + FStringf name("BarShader%c%c", vertical ? 'v' : 'h', reverse ? 'r' : 'f'); + auto tex = new FImageTexture(new FBarShader(vertical, reverse), name.GetChars()); } diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index a97d26dba..9725fe6d1 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -40,6 +40,7 @@ #include "bitmap.h" #include "v_video.h" #include "imagehelpers.h" +#include "image.h" //========================================================================== @@ -75,13 +76,12 @@ struct TGAHeader // //========================================================================== -class FTGATexture : public FWorldTexture +class FTGATexture : public FImageSource { public: FTGATexture (int lumpnum, TGAHeader *); int CopyPixels(FBitmap *bmp) override; - bool UseBasePalette() override; protected: void ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel); @@ -119,7 +119,7 @@ FTexture *TGATexture_TryCreate(FileReader & file, int lumpnum) hdr.width = LittleShort(hdr.width); hdr.height = LittleShort(hdr.height); - return new FTGATexture(lumpnum, &hdr); + return new FImageTexture(new FTGATexture(lumpnum, &hdr)); } //========================================================================== @@ -129,9 +129,8 @@ FTexture *TGATexture_TryCreate(FileReader & file, int lumpnum) //========================================================================== FTGATexture::FTGATexture (int lumpnum, TGAHeader * hdr) -: FWorldTexture(NULL, lumpnum) +: FImageSource(lumpnum) { - Wads.GetLumpName (Name, lumpnum); Width = hdr->width; Height = hdr->height; // Alpha channel is used only for 32 bit RGBA and paletted images with RGBA palettes. @@ -534,13 +533,3 @@ int FTGATexture::CopyPixels(FBitmap *bmp) delete [] sbuffer; return transval; } - -//=========================================================================== -// -// -//=========================================================================== - -bool FTGATexture::UseBasePalette() -{ - return false; -} diff --git a/src/textures/formats/worldtexture.cpp b/src/textures/formats/worldtexture.cpp deleted file mode 100644 index 66b9ec3b4..000000000 --- a/src/textures/formats/worldtexture.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* -** worldtexture.cpp -** Intermediate class for some common code for several classes -** -**--------------------------------------------------------------------------- -** Copyright 2018 Christoph Oelckers -** All rights reserved. -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions -** are met: -** -** 1. Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** 2. Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in the -** documentation and/or other materials provided with the distribution. -** 3. The name of the author may not be used to endorse or promote products -** derived from this software without specific prior written permission. -** -** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -**--------------------------------------------------------------------------- -** -** -*/ - -#include "textures.h" - - -//========================================================================== -// -// -// -//========================================================================== - -FWorldTexture::FWorldTexture(const char *name, int lumpnum) - : FTexture(name, lumpnum) -{ -} - diff --git a/src/textures/image.h b/src/textures/image.h index e868c557d..7bcdb0510 100644 --- a/src/textures/image.h +++ b/src/textures/image.h @@ -81,12 +81,13 @@ public: // //========================================================================== -class FImageTexture : public FWorldTexture +class FImageTexture : public FTexture { FImageSource *mImage; public: - FImageTexture (FImageSource *image); + FImageTexture (FImageSource *image, const char *name = nullptr); virtual TArray Get8BitPixels(bool alphatex); + FImageSource *GetImage() const { return mImage; } bool UseBasePalette() override; diff --git a/src/textures/imagetexture.cpp b/src/textures/imagetexture.cpp index 00326664c..7cb45887e 100644 --- a/src/textures/imagetexture.cpp +++ b/src/textures/imagetexture.cpp @@ -48,8 +48,8 @@ // //========================================================================== -FImageTexture::FImageTexture(FImageSource *img) -: FWorldTexture(nullptr, img->LumpNum()) +FImageTexture::FImageTexture(FImageSource *img, const char *name) +: FWorldTexture(name, img->LumpNum()) { mImage = img; Wads.GetLumpName (Name, img->LumpNum()); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index c8969d978..0aec9d106 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -49,8 +49,9 @@ #include "hwrenderer/textures/hw_ihwtexture.h" #include "swrenderer/textures/r_swtexture.h" #include "imagehelpers.h" +#include "image.h" -FTexture *CreateBrightmapTexture(FTexture*); +FTexture *CreateBrightmapTexture(FImageSource*); // Make sprite offset adjustment user-configurable per renderer. int r_spriteadjustSW, r_spriteadjustHW; @@ -537,7 +538,7 @@ void FTexture::CreateDefaultBrightmap() { // Create a brightmap DPrintf(DMSG_NOTIFY, "brightmap created for texture '%s'\n", Name.GetChars()); - Brightmap = CreateBrightmapTexture(this); + Brightmap = CreateBrightmapTexture(static_cast(this)->GetImage()); bBrightmapChecked = true; TexMan.AddTexture(Brightmap); return; diff --git a/src/textures/textures.h b/src/textures/textures.h index 46ef35601..199b7389d 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -670,14 +670,6 @@ public: }; -// base class for everything that can be used as a world texture. -// This intermediate class encapsulates the buffers for the software renderer. -class FWorldTexture : public FTexture -{ -protected: - FWorldTexture(const char *name = nullptr, int lumpnum = -1); -}; - // A texture that doesn't really exist class FDummyTexture : public FTexture { From 91f712145231a5ef9ed6483c61c34becea52ccc3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 9 Dec 2018 08:15:05 +0100 Subject: [PATCH 21/66] - made some changes to the FImageSource interface that allows forwarding the bRemap0 flag, but do it so that it doesn't permanently alter how the image looks. In ZDoom this would affect everything using a patch that got used in a front sky layer, even if the texture was totally unrelated. It is only owed to the low usability of such patches for other purposes that this hasn't caused problems. --- src/r_data/models/models_voxel.cpp | 10 +++--- src/textures/formats/automaptexture.cpp | 6 ++-- src/textures/formats/brightmaptexture.cpp | 4 +-- src/textures/formats/buildtexture.cpp | 10 +++--- src/textures/formats/ddstexture.cpp | 10 +++--- src/textures/formats/emptytexture.cpp | 4 +-- src/textures/formats/flattexture.cpp | 6 ++-- src/textures/formats/imgztexture.cpp | 12 ++++---- src/textures/formats/jpegtexture.cpp | 9 +++--- src/textures/formats/patchtexture.cpp | 15 +++++---- src/textures/formats/pcxtexture.cpp | 9 +++--- src/textures/formats/pngtexture.cpp | 37 +++++++---------------- src/textures/formats/rawpagetexture.cpp | 12 ++++---- src/textures/formats/shadertexture.cpp | 9 +++--- src/textures/formats/tgatexture.cpp | 20 ++++++------ src/textures/image.cpp | 10 +++--- src/textures/image.h | 6 ++-- src/textures/imagetexture.cpp | 6 ++-- 18 files changed, 90 insertions(+), 105 deletions(-) diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index 6be9d0355..1774354bf 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -52,8 +52,8 @@ class FVoxelTexture : public FImageSource public: FVoxelTexture(FVoxel *voxel); - int CopyPixels(FBitmap *bmp) override; - TArray Get8BitPixels(bool alphatex) override; + int CopyPixels(FBitmap *bmp, int conversion) override; + TArray GetPalettedPixels(int conversion) override; protected: FVoxel *SourceVox; @@ -79,7 +79,7 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) // //=========================================================================== -TArray FVoxelTexture::Get8BitPixels(bool alphatex) +TArray FVoxelTexture::GetPalettedPixels(int conversion) { // GetPixels gets called when a translated palette is used so we still need to implement it here. TArray Pixels(256, true); @@ -94,7 +94,7 @@ TArray FVoxelTexture::Get8BitPixels(bool alphatex) pe.g = (pp[1] << 2) | (pp[1] >> 4); pe.b = (pp[2] << 2) | (pp[2] >> 4); // Alphatexture handling is just for completeness, but rather unlikely to be used ever. - Pixels[i] = alphatex? pe.r : ColorMatcher.Pick(pe); + Pixels[i] = conversion == luminance ? pe.r : ColorMatcher.Pick(pe); } } else @@ -116,7 +116,7 @@ TArray FVoxelTexture::Get8BitPixels(bool alphatex) // //=========================================================================== -int FVoxelTexture::CopyPixels(FBitmap *bmp) +int FVoxelTexture::CopyPixels(FBitmap *bmp, int conversion) { PalEntry pe[256]; uint8_t bitmap[256]; diff --git a/src/textures/formats/automaptexture.cpp b/src/textures/formats/automaptexture.cpp index 39285d280..80395b8ee 100644 --- a/src/textures/formats/automaptexture.cpp +++ b/src/textures/formats/automaptexture.cpp @@ -52,7 +52,7 @@ class FAutomapTexture : public FImageSource { public: FAutomapTexture(int lumpnum); - TArray Get8BitPixels(bool alphatex); + TArray GetPalettedPixels(int conversion) override; }; @@ -91,7 +91,7 @@ FAutomapTexture::FAutomapTexture (int lumpnum) // //========================================================================== -TArray FAutomapTexture::Get8BitPixels(bool alphatex) +TArray FAutomapTexture::GetPalettedPixels(int conversion) { int x, y; FMemLump data = Wads.ReadLump (SourceLump); @@ -99,7 +99,7 @@ TArray FAutomapTexture::Get8BitPixels(bool alphatex) TArray Pixels(Width * Height, true); - const uint8_t *remap = ImageHelpers::GetRemap(alphatex); + const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); for (x = 0; x < Width; ++x) { for (y = 0; y < Height; ++y) diff --git a/src/textures/formats/brightmaptexture.cpp b/src/textures/formats/brightmaptexture.cpp index 1277cf527..5d2f48ae0 100644 --- a/src/textures/formats/brightmaptexture.cpp +++ b/src/textures/formats/brightmaptexture.cpp @@ -46,7 +46,7 @@ class FBrightmapTexture : public FImageSource public: FBrightmapTexture (FImageSource *source); - int CopyPixels(FBitmap *bmp) override; + int CopyPixels(FBitmap *bmp, int conversion) override; protected: FImageSource *SourcePic; @@ -68,7 +68,7 @@ FBrightmapTexture::FBrightmapTexture (FImageSource *source) bMasked = false; } -int FBrightmapTexture::CopyPixels(FBitmap *bmp) +int FBrightmapTexture::CopyPixels(FBitmap *bmp, int conversion) { SourcePic->CopyTranslatedPixels(bmp, TexMan.GlobalBrightmap.Palette); return 0; diff --git a/src/textures/formats/buildtexture.cpp b/src/textures/formats/buildtexture.cpp index 8900d5400..a76e1666e 100644 --- a/src/textures/formats/buildtexture.cpp +++ b/src/textures/formats/buildtexture.cpp @@ -57,8 +57,8 @@ class FBuildTexture : public FImageSource { public: FBuildTexture (const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top); - TArray Get8BitPixels(bool alphatex) override; - int CopyPixels(FBitmap *bmp) override; + TArray GetPalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion) override; protected: const uint8_t *RawPixels; @@ -81,19 +81,19 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8 TopOffset = top; } -TArray FBuildTexture::Get8BitPixels(bool alphatex) +TArray FBuildTexture::GetPalettedPixels(int conversion) { TArray Pixels(Width * Height, true); FRemapTable *Remap = translationtables[TRANSLATION_Standard][Translation]; for (int i = 0; i < Width*Height; i++) { auto c = RawPixels[i]; - Pixels[i] = alphatex ? Remap->Palette[c].Luminance() : Remap->Remap[c]; + Pixels[i] = conversion == luminance ? Remap->Palette[c].Luminance() : Remap->Remap[c]; } return Pixels; } -int FBuildTexture::CopyPixels(FBitmap *bmp) +int FBuildTexture::CopyPixels(FBitmap *bmp, int conversion) { PalEntry *Remap = translationtables[TRANSLATION_Standard][Translation]->Palette; bmp->CopyPixelData(0, 0, RawPixels, Width, Height, Height, 1, 0, Remap); diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index f00a14172..2672d7b2d 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -164,7 +164,7 @@ class FDDSTexture : public FImageSource public: FDDSTexture (FileReader &lump, int lumpnum, void *surfdesc); - TArray Get8BitPixels(bool alphatex) override; + TArray GetPalettedPixels(int conversion) override; protected: uint32_t Format; @@ -183,7 +183,7 @@ protected: void DecompressDXT3 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); void DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); - int CopyPixels(FBitmap *bmp) override; + int CopyPixels(FBitmap *bmp, int conversion) override; bool UseBasePalette(); friend class FTexture; @@ -373,7 +373,7 @@ void FDDSTexture::CalcBitShift (uint32_t mask, uint8_t *lshiftp, uint8_t *rshift // //========================================================================== -TArray FDDSTexture::Get8BitPixels(bool alphatex) +TArray FDDSTexture::GetPalettedPixels(int conversion) { auto lump = Wads.OpenLumpReader (SourceLump); @@ -381,7 +381,7 @@ TArray FDDSTexture::Get8BitPixels(bool alphatex) lump.Seek (sizeof(DDSURFACEDESC2) + 4, FileReader::SeekSet); - int pmode = alphatex ? PIX_Alphatex : PIX_Palette; + int pmode = conversion == luminance ? PIX_Alphatex : PIX_Palette; if (Format >= 1 && Format <= 4) // RGB: Format is # of bytes per pixel { ReadRGB (lump, Pixels.Data(), pmode); @@ -782,7 +782,7 @@ void FDDSTexture::DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t // //=========================================================================== -int FDDSTexture::CopyPixels(FBitmap *bmp) +int FDDSTexture::CopyPixels(FBitmap *bmp, int conversion) { auto lump = Wads.OpenLumpReader (SourceLump); diff --git a/src/textures/formats/emptytexture.cpp b/src/textures/formats/emptytexture.cpp index 1246760b3..fe8c1e901 100644 --- a/src/textures/formats/emptytexture.cpp +++ b/src/textures/formats/emptytexture.cpp @@ -51,7 +51,7 @@ class FEmptyTexture : public FImageSource { public: FEmptyTexture (int lumpnum); - TArray Get8BitPixels(bool alphatex) override; + TArray GetPalettedPixels(int conversion) override; }; //========================================================================== @@ -91,7 +91,7 @@ FEmptyTexture::FEmptyTexture (int lumpnum) // //========================================================================== -TArray FEmptyTexture::Get8BitPixels(bool alphatex) +TArray FEmptyTexture::GetPalettedPixels(int conversion) { TArray Pixel(1, true); Pixel[0] = 0; diff --git a/src/textures/formats/flattexture.cpp b/src/textures/formats/flattexture.cpp index 46b9e43fc..c6ce44fb8 100644 --- a/src/textures/formats/flattexture.cpp +++ b/src/textures/formats/flattexture.cpp @@ -50,7 +50,7 @@ class FFlatTexture : public FImageSource { public: FFlatTexture (int lumpnum); - TArray Get8BitPixels(bool alphatex) override; + TArray GetPalettedPixels(int conversion) override; }; @@ -104,7 +104,7 @@ FFlatTexture::FFlatTexture (int lumpnum) // //========================================================================== -TArray FFlatTexture::Get8BitPixels(bool alphatex) +TArray FFlatTexture::GetPalettedPixels(int conversion) { auto lump = Wads.OpenLumpReader (SourceLump); TArray Pixels(Width*Height, true); @@ -113,7 +113,7 @@ TArray FFlatTexture::Get8BitPixels(bool alphatex) { memset (Pixels.Data() + numread, 0xBB, Width*Height - numread); } - ImageHelpers::FlipSquareBlockRemap(Pixels.Data(), Width, ImageHelpers::GetRemap(alphatex)); + ImageHelpers::FlipSquareBlockRemap(Pixels.Data(), Width, ImageHelpers::GetRemap(conversion == luminance)); return Pixels; } diff --git a/src/textures/formats/imgztexture.cpp b/src/textures/formats/imgztexture.cpp index b87f4b63d..e505c0714 100644 --- a/src/textures/formats/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -68,8 +68,8 @@ class FIMGZTexture : public FImageSource public: FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool isalpha); - TArray Get8BitPixels(bool alphatex) override; - int CopyPixels(FBitmap *bmp) override; + TArray GetPalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion) override; }; @@ -120,7 +120,7 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 // //========================================================================== -TArray FIMGZTexture::Get8BitPixels(bool alphatex) +TArray FIMGZTexture::GetPalettedPixels(int conversion) { FMemLump lump = Wads.ReadLump (SourceLump); const ImageHeader *imgz = (const ImageHeader *)lump.GetMem(); @@ -133,7 +133,7 @@ TArray FIMGZTexture::Get8BitPixels(bool alphatex) TArray Pixels(Width*Height, true); dest_p = Pixels.Data(); - const uint8_t *remap = ImageHelpers::GetRemap(alphatex, isalpha); + const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance, isalpha); // Convert the source image from row-major to column-major format and remap it if (!imgz->Compression) @@ -200,9 +200,9 @@ TArray FIMGZTexture::Get8BitPixels(bool alphatex) // //========================================================================== -int FIMGZTexture::CopyPixels(FBitmap *bmp) +int FIMGZTexture::CopyPixels(FBitmap *bmp, int conversion) { - if (!isalpha) return FImageSource::CopyPixels(bmp); + if (!isalpha) return FImageSource::CopyPixels(bmp, conversion); else return CopyTranslatedPixels(bmp, translationtables[TRANSLATION_Standard][STD_Grayscale]->Palette); } diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index 06b093e95..b41549c02 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -185,8 +185,8 @@ class FJPEGTexture : public FImageSource public: FJPEGTexture (int lumpnum, int width, int height); - int CopyPixels(FBitmap *bmp) override; - TArray Get8BitPixels(bool alphatex) override; + int CopyPixels(FBitmap *bmp, int conversion) override; + TArray GetPalettedPixels(int conversion) override; }; //========================================================================== @@ -260,7 +260,7 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) // //========================================================================== -TArray FJPEGTexture::Get8BitPixels(bool doalpha) +TArray FJPEGTexture::GetPalettedPixels(int conversion) { auto lump = Wads.OpenLumpReader (SourceLump); JSAMPLE *buff = NULL; @@ -279,6 +279,7 @@ TArray FJPEGTexture::Get8BitPixels(bool doalpha) FLumpSourceMgr sourcemgr(&lump, &cinfo); try { + bool doalpha = conversion == luminance; jpeg_read_header(&cinfo, TRUE); if (!((cinfo.out_color_space == JCS_RGB && cinfo.num_components == 3) || (cinfo.out_color_space == JCS_CMYK && cinfo.num_components == 4) || @@ -381,7 +382,7 @@ TArray FJPEGTexture::Get8BitPixels(bool doalpha) // //=========================================================================== -int FJPEGTexture::CopyPixels(FBitmap *bmp) +int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) { PalEntry pe[256]; diff --git a/src/textures/formats/patchtexture.cpp b/src/textures/formats/patchtexture.cpp index f988b9c02..ca6e54755 100644 --- a/src/textures/formats/patchtexture.cpp +++ b/src/textures/formats/patchtexture.cpp @@ -62,11 +62,10 @@ class FPatchTexture : public FImageSource { bool badflag = false; bool isalpha = false; - bool bNoRemap0 = false; // Unfortunately this was done as a very bad hack in ZDoom and will need impovement public: FPatchTexture (int lumpnum, patch_t *header, bool isalphatex); - TArray Get8BitPixels(bool alphatex) override; - int CopyPixels(FBitmap *bmp) override; + TArray GetPalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion) override; void DetectBadPatches(); }; @@ -164,7 +163,7 @@ FPatchTexture::FPatchTexture (int lumpnum, patch_t * header, bool isalphatex) // //========================================================================== -TArray FPatchTexture::Get8BitPixels(bool alphatex) +TArray FPatchTexture::GetPalettedPixels(int conversion) { uint8_t *remap, remaptable[256]; int numspans; @@ -176,9 +175,9 @@ TArray FPatchTexture::Get8BitPixels(bool alphatex) maxcol = (const column_t *)((const uint8_t *)patch + Wads.LumpLength (SourceLump) - 3); - remap = ImageHelpers::GetRemap(alphatex, isalpha); + remap = ImageHelpers::GetRemap(conversion == luminance, isalpha); // Special case for skies - if (bNoRemap0 && remap == GPalette.Remap) + if (conversion == noremap0 && remap == GPalette.Remap) { memcpy(remaptable, GPalette.Remap, 256); remaptable[0] = 0; @@ -261,9 +260,9 @@ TArray FPatchTexture::Get8BitPixels(bool alphatex) // //========================================================================== -int FPatchTexture::CopyPixels(FBitmap *bmp) +int FPatchTexture::CopyPixels(FBitmap *bmp, int conversion) { - if (!isalpha) return FImageSource::CopyPixels(bmp); + if (!isalpha) return FImageSource::CopyPixels(bmp, conversion); else return CopyTranslatedPixels(bmp, translationtables[TRANSLATION_Standard][STD_Grayscale]->Palette); } diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index c755723e4..f2e9f828d 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -85,7 +85,7 @@ class FPCXTexture : public FImageSource public: FPCXTexture (int lumpnum, PCXHeader &); - int CopyPixels(FBitmap *bmp) override; + int CopyPixels(FBitmap *bmp, int conversion) override; protected: void ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr); @@ -93,7 +93,7 @@ protected: void ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr); void ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr, int planes); - TArray Get8BitPixels(bool alphatex) override; + TArray GetPalettedPixels(int conversion) override; }; @@ -358,7 +358,7 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr // //========================================================================== -TArray FPCXTexture::Get8BitPixels(bool alphatex) +TArray FPCXTexture::GetPalettedPixels(int conversion) { uint8_t PaletteMap[256]; PCXHeader header; @@ -371,6 +371,7 @@ TArray FPCXTexture::Get8BitPixels(bool alphatex) bitcount = header.bitsPerPixel * header.numColorPlanes; TArray Pixels(Width*Height, true); + bool alphatex = conversion == luminance; if (bitcount < 24) { if (bitcount < 8) @@ -446,7 +447,7 @@ TArray FPCXTexture::Get8BitPixels(bool alphatex) // //=========================================================================== -int FPCXTexture::CopyPixels(FBitmap *bmp) +int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion) { PalEntry pe[256]; PCXHeader header; diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index 91b70b745..1990aa6cb 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -54,9 +54,8 @@ public: FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, uint8_t bitdepth, uint8_t colortype, uint8_t interlace); ~FPNGTexture(); - int CopyPixels(FBitmap *bmp) override; - bool UseBasePalette() override; - TArray Get8BitPixels(bool alphatex) override; + int CopyPixels(FBitmap *bmp, int conversion) override; + TArray GetPalettedPixels(int conversion) override; protected: void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap); @@ -182,7 +181,7 @@ FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename) return NULL; } - return new FPNGTexture (png->File, -1, filename, width, height, bitdepth, colortype, interlace); + return new FImageTexture(new FPNGTexture (png->File, -1, filename, width, height, bitdepth, colortype, interlace)); } //========================================================================== @@ -193,7 +192,7 @@ FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename) FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, uint8_t depth, uint8_t colortype, uint8_t interlace) -: FWorldTexture(NULL, lumpnum), SourceFile(filename), +: FImageSource(lumpnum), SourceFile(filename), BitDepth(depth), ColorType(colortype), Interlace(interlace), HaveTrans(false) { union @@ -205,7 +204,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename uint32_t len, id; int i; - UseType = ETextureType::MiscPatch; bMasked = false; Width = width; @@ -247,8 +245,8 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename Printf ("Y-Offset for PNG texture %s is bad: %d (0x%08x)\n", Wads.GetLumpFullName (lumpnum), ihoty, ihoty); ihoty = 0; } - _LeftOffset[1] = _LeftOffset[0] = ihotx; - _TopOffset[1] = _TopOffset[0] = ihoty; + LeftOffset = ihotx; + TopOffset = ihoty; } break; @@ -369,7 +367,7 @@ void FPNGTexture::ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap) // //========================================================================== -TArray FPNGTexture::Get8BitPixels(bool alphatex) +TArray FPNGTexture::GetPalettedPixels(int conversion) { FileReader *lump; FileReader lfr; @@ -396,13 +394,14 @@ TArray FPNGTexture::Get8BitPixels(bool alphatex) lump->Read(&len, 4); lump->Read(&id, 4); + bool alphatex = conversion == luminance; if (ColorType == 0 || ColorType == 3) /* Grayscale and paletted */ { M_ReadIDAT (*lump, Pixels.Data(), Width, Height, Width, BitDepth, ColorType, Interlace, BigLong((unsigned int)len)); if (Width == Height) { - if (!alphatex) + if (conversion != luminance) { ImageHelpers::FlipSquareBlockRemap (Pixels.Data(), Width, PaletteMap); } @@ -420,7 +419,7 @@ TArray FPNGTexture::Get8BitPixels(bool alphatex) else { TArray newpix(Width*Height, true); - if (!alphatex) + if (conversion != luminance) { ImageHelpers::FlipNonSquareBlockRemap (newpix.Data(), Pixels.Data(), Width, Height, Width, PaletteMap); } @@ -513,7 +512,7 @@ TArray FPNGTexture::Get8BitPixels(bool alphatex) // //=========================================================================== -int FPNGTexture::CopyPixels(FBitmap *bmp) +int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion) { // Parse pre-IDAT chunks. I skip the CRCs. Is that bad? PalEntry pe[256]; @@ -631,17 +630,3 @@ int FPNGTexture::CopyPixels(FBitmap *bmp) delete[] Pixels; return transpal; } - - -//=========================================================================== -// -// This doesn't check if the palette is identical with the base palette -// I don't think it's worth the hassle because it's only of importance -// when compositing multipatch textures. -// -//=========================================================================== - -bool FPNGTexture::UseBasePalette() -{ - return false; -} diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index 9c38748e2..6fd805ff5 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -54,8 +54,8 @@ class FRawPageTexture : public FImageSource int mPaletteLump = -1; public: FRawPageTexture (int lumpnum); - TArray Get8BitPixels(bool alphatex) override; - int CopyPixels(FBitmap *bmp) override; + TArray GetPalettedPixels(int conversion) override; + int CopyPixels(FBitmap *bmp, int conversion) override; }; //========================================================================== @@ -173,7 +173,7 @@ FRawPageTexture::FRawPageTexture (int lumpnum) // //========================================================================== -TArray FRawPageTexture::Get8BitPixels(bool alphatex) +TArray FRawPageTexture::GetPalettedPixels(int conversion) { FMemLump lump = Wads.ReadLump (SourceLump); const uint8_t *source = (const uint8_t *)lump.GetMem(); @@ -183,7 +183,7 @@ TArray FRawPageTexture::Get8BitPixels(bool alphatex) TArray Pixels(Width*Height, true); dest_p = Pixels.Data(); - const uint8_t *remap = ImageHelpers::GetRemap(alphatex); + const uint8_t *remap = ImageHelpers::GetRemap(conversion == luminance); // This does not handle the custom palette. // User maps are encouraged to use a real image format when replacing E2END and the original could never be used anywhere else. @@ -202,9 +202,9 @@ TArray FRawPageTexture::Get8BitPixels(bool alphatex) return Pixels; } -int FRawPageTexture::CopyPixels(FBitmap *bmp) +int FRawPageTexture::CopyPixels(FBitmap *bmp, int conversion) { - if (mPaletteLump < 0) return FImageSource::CopyPixels(bmp); + if (mPaletteLump < 0) return FImageSource::CopyPixels(bmp, conversion); else { FMemLump lump = Wads.ReadLump(SourceLump); diff --git a/src/textures/formats/shadertexture.cpp b/src/textures/formats/shadertexture.cpp index 6f3443798..0e79ad8c7 100644 --- a/src/textures/formats/shadertexture.cpp +++ b/src/textures/formats/shadertexture.cpp @@ -100,10 +100,10 @@ public: } } - TArray Get8BitPixels(bool alphatex) override + TArray GetPalettedPixels(int conversion) override { TArray Pix(512, true); - if (alphatex) + if (conversion == luminance) { memcpy(Pix.Data(), Pixels, 512); } @@ -120,7 +120,7 @@ public: return Pix; } - int CopyPixels(FBitmap *bmp) override + int CopyPixels(FBitmap *bmp, int conversion) override { bmp->CopyPixelData(0, 0, Pixels, Width, Height, Height, 1, 0, translationtables[TRANSLATION_Standard][8]->Palette); return 0; @@ -134,5 +134,6 @@ private: FTexture *CreateShaderTexture(bool vertical, bool reverse) { FStringf name("BarShader%c%c", vertical ? 'v' : 'h', reverse ? 'r' : 'f'); - auto tex = new FImageTexture(new FBarShader(vertical, reverse), name.GetChars()); + return new FImageTexture(new FBarShader(vertical, reverse), name.GetChars()); + } diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index 9725fe6d1..9bc8500f8 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -81,11 +81,11 @@ class FTGATexture : public FImageSource public: FTGATexture (int lumpnum, TGAHeader *); - int CopyPixels(FBitmap *bmp) override; + int CopyPixels(FBitmap *bmp, int conversion) override; protected: void ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel); - TArray Get8BitPixels(bool alphatex) override; + TArray GetPalettedPixels(int conversion) override; }; //========================================================================== @@ -179,7 +179,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe // //========================================================================== -TArray FTGATexture::Get8BitPixels(bool alphatex) +TArray FTGATexture::GetPalettedPixels(int conversion) { uint8_t PaletteMap[256]; auto lump = Wads.OpenLumpReader (SourceLump); @@ -232,7 +232,7 @@ TArray FTGATexture::Get8BitPixels(bool alphatex) r=g=b=a=0; break; } - PaletteMap[i] = ImageHelpers::RGBToPalettePrecise(alphatex, r, g, b, a); + PaletteMap[i] = ImageHelpers::RGBToPalettePrecise(conversion == luminance, r, g, b, a); } } @@ -291,7 +291,7 @@ TArray FTGATexture::Get8BitPixels(bool alphatex) for(int x=0;x> 10) & 0x1f) * 8, ((v >> 5) & 0x1f) * 8, (v & 0x1f) * 8); + Pixels[x*Height + y] = ImageHelpers::RGBToPalette(conversion == luminance, ((v >> 10) & 0x1f) * 8, ((v >> 5) & 0x1f) * 8, (v & 0x1f) * 8); p+=step_x; } } @@ -303,7 +303,7 @@ TArray FTGATexture::Get8BitPixels(bool alphatex) uint8_t * p = ptr + y * Pitch; for(int x=0;x FTGATexture::Get8BitPixels(bool alphatex) uint8_t * p = ptr + y * Pitch; for(int x=0;x FTGATexture::Get8BitPixels(bool alphatex) uint8_t * p = ptr + y * Pitch; for(int x=0;x FTGATexture::Get8BitPixels(bool alphatex) case 3: // Grayscale { - auto remap = ImageHelpers::GetRemap(alphatex, true); + auto remap = ImageHelpers::GetRemap(conversion == luminance, true); switch (hdr.bpp) { case 8: @@ -388,7 +388,7 @@ TArray FTGATexture::Get8BitPixels(bool alphatex) // //=========================================================================== -int FTGATexture::CopyPixels(FBitmap *bmp) +int FTGATexture::CopyPixels(FBitmap *bmp, int conversion) { PalEntry pe[256]; auto lump = Wads.OpenLumpReader (SourceLump); diff --git a/src/textures/image.cpp b/src/textures/image.cpp index ac217d171..20c457a96 100644 --- a/src/textures/image.cpp +++ b/src/textures/image.cpp @@ -45,7 +45,7 @@ // //=========================================================================== -TArray FImageSource::Get8BitPixels(bool alphatex) +TArray FImageSource::GetPalettedPixels(int conversion) { TArray Pixels(Width * Height, true); memset(Pixels.Data(), 0, Width * Height); @@ -65,11 +65,12 @@ TArray FImageSource::Get8BitPixels(bool alphatex) // //=========================================================================== -int FImageSource::CopyPixels(FBitmap *bmp) +int FImageSource::CopyPixels(FBitmap *bmp, int conversion) { + if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. PalEntry *palette = screen->GetPalette(); for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values - auto ppix = Get8BitPixels(false); // should use composition cache + auto ppix = GetPalettedPixels(conversion); // should use composition cache bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); for(int i=1;i<256;i++) palette[i].a = 0; return 0; @@ -77,8 +78,7 @@ int FImageSource::CopyPixels(FBitmap *bmp) int FImageSource::CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap) { - auto ppix = Get8BitPixels(false); // should use composition cache + auto ppix = GetPalettedPixels(false); // should use composition cache bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, remap, nullptr); return 0; } - diff --git a/src/textures/image.h b/src/textures/image.h index 7bcdb0510..88a04b0fb 100644 --- a/src/textures/image.h +++ b/src/textures/image.h @@ -16,16 +16,14 @@ protected: int LeftOffset = 0, TopOffset = 0; // Offsets stored in the image. bool bUseGamePalette = false; // true if this is an image without its own color set. - // internal builder functions for true color textures. - public: bool bMasked = true; // Image (might) have holes (Assume true unless proven otherwise!) int8_t bTranslucent = -1; // Image has pixels with a non-0/1 value. (-1 means the user needs to do a real check) // Returns the whole texture, paletted and true color versions respectively. - virtual TArray Get8BitPixels(bool alphatex); - virtual int CopyPixels(FBitmap *bmp); + virtual TArray GetPalettedPixels(int conversion); // 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture. + virtual int CopyPixels(FBitmap *bmp, int conversion); // This will always ignore 'luminance'. int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); // Conversion option diff --git a/src/textures/imagetexture.cpp b/src/textures/imagetexture.cpp index 7cb45887e..6a376551c 100644 --- a/src/textures/imagetexture.cpp +++ b/src/textures/imagetexture.cpp @@ -49,7 +49,7 @@ //========================================================================== FImageTexture::FImageTexture(FImageSource *img, const char *name) -: FWorldTexture(name, img->LumpNum()) +: FTexture(name, img->LumpNum()) { mImage = img; Wads.GetLumpName (Name, img->LumpNum()); @@ -72,7 +72,7 @@ FImageTexture::FImageTexture(FImageSource *img, const char *name) int FImageTexture::CopyPixels(FBitmap *bmp) { - return mImage->CopyPixels(bmp); + return mImage->CopyPixels(bmp, bNoRemap0? FImageSource::noremap0 : FImageSource::normal); } //=========================================================================== @@ -83,7 +83,7 @@ int FImageTexture::CopyPixels(FBitmap *bmp) TArray FImageTexture::Get8BitPixels(bool alpha) { - return mImage->Get8BitPixels(alpha); + return mImage->GetPalettedPixels(alpha? alpha : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal); } //=========================================================================== From 4cedbf6cc28108c1bf89abf5c31d057916af74de Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 9 Dec 2018 15:25:56 +0100 Subject: [PATCH 22/66] - split between textures and images is complete now. * split up FMultiPatchTexture into a builder class and the actual image source. * since images can now be referenced by multiple textures the old redirection mechanism has been removed. It can be done better and less intrusive now. Simple single patch textures already directly reference the underlying patch image now. * allocate all image source related data from a memory arena. Since this is all static this makes it a lot easier to free this in bulk. --- src/CMakeLists.txt | 1 + src/hwrenderer/textures/hw_material.cpp | 8 - src/swrenderer/textures/r_swtexture.cpp | 1 - src/swrenderer/textures/r_swtexture.h | 1 - src/swrenderer/things/r_playersprite.cpp | 2 + src/textures/formats/ddstexture.cpp | 11 - src/textures/formats/multipatchtexture.cpp | 1119 ++------------------ src/textures/image.cpp | 2 +- src/textures/image.h | 18 +- src/textures/imagetexture.cpp | 34 +- src/textures/multipatchtexturebuilder.cpp | 975 +++++++++++++++++ src/textures/skyboxtexture.cpp | 11 - src/textures/skyboxtexture.h | 9 +- src/textures/texture.cpp | 66 +- src/textures/texturemanager.cpp | 43 +- src/textures/textures.h | 20 +- 16 files changed, 1137 insertions(+), 1184 deletions(-) create mode 100644 src/textures/multipatchtexturebuilder.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7d6b7f4eb..98d220e9d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1101,6 +1101,7 @@ set (PCH_SOURCES textures/image.cpp textures/imagetexture.cpp textures/texturemanager.cpp + textures/multipatchtexturebuilder.cpp textures/skyboxtexture.cpp textures/formats/automaptexture.cpp textures/formats/brightmaptexture.cpp diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index ab833a715..712a8e7af 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -237,14 +237,6 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) mSpriteU[0] = mSpriteV[0] = 0.f; mSpriteU[1] = mSpriteV[1] = 1.f; - FTexture *basetex = tx->GetRedirect(); - // allow the redirect only if the texture is not expanded or the scale matches. - if (!expanded || (tx->Scale.X == basetex->Scale.X && tx->Scale.Y == basetex->Scale.Y)) - { - sourcetex = basetex; - mBaseLayer = ValidateSysTexture(basetex, expanded); - } - mExpanded = expanded; if (expanded) { diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index ae8c0d1ce..5e3721fe9 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -44,7 +44,6 @@ FSoftwareTexture *FTexture::GetSoftwareTexture() if (!SoftwareTexture) { if (bWarped) SoftwareTexture = new FWarpTexture(this, bWarped); - // else if (GetRedirect() != this) ... must be decided later. The current data structures make it hard to do this without creating a mess. else SoftwareTexture = new FSoftwareTexture(this); } return SoftwareTexture; diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index af65003bf..3dd534624 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -55,7 +55,6 @@ public: return mTexture->bMasked; } - bool UseBasePalette() const { return mTexture->UseBasePalette(); } int GetSkyOffset() const { return mTexture->GetSkyOffset(); } PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); } diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 548bb5c8a..ac99bee93 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -385,6 +385,7 @@ namespace swrenderer { noaccel = true; } +#if 0 // If the main colormap has fixed lights, and this sprite is being drawn with that // colormap, disable acceleration so that the lights can remain fixed. CameraLight *cameraLight = CameraLight::Instance(); @@ -394,6 +395,7 @@ namespace swrenderer { noaccel = true; } +#endif } else { diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index 2672d7b2d..31ec4f01f 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -184,7 +184,6 @@ protected: void DecompressDXT5 (FileReader &lump, bool premultiplied, uint8_t *buffer, int pixelmode); int CopyPixels(FBitmap *bmp, int conversion) override; - bool UseBasePalette(); friend class FTexture; }; @@ -809,13 +808,3 @@ int FDDSTexture::CopyPixels(FBitmap *bmp, int conversion) return -1; } - -//=========================================================================== -// -// -//=========================================================================== - -bool FDDSTexture::UseBasePalette() -{ - return false; -} diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index 42a9d7802..cd50d555c 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -50,161 +50,8 @@ #include "v_text.h" #include "cmdlib.h" #include "imagehelpers.h" - -// On the Alpha, accessing the shorts directly if they aren't aligned on a -// 4-byte boundary causes unaligned access warnings. Why it does this at -// all and only while initing the textures is beyond me. - -#ifdef ALPHA -#define SAFESHORT(s) ((short)(((uint8_t *)&(s))[0] + ((uint8_t *)&(s))[1] * 256)) -#else -#define SAFESHORT(s) LittleShort(s) -#endif - - - -//-------------------------------------------------------------------------- -// -// Data structures for the TEXTUREx lumps -// -//-------------------------------------------------------------------------- - -// -// Each texture is composed of one or more patches, with patches being lumps -// stored in the WAD. The lumps are referenced by number, and patched into -// the rectangular texture space using origin and possibly other attributes. -// -struct mappatch_t -{ - int16_t originx; - int16_t originy; - int16_t patch; - int16_t stepdir; - int16_t colormap; -}; - -// -// A wall texture is a list of patches which are to be combined in a -// predefined order. -// -struct maptexture_t -{ - uint8_t name[8]; - uint16_t Flags; // [RH] Was unused - uint8_t ScaleX; // [RH] Scaling (8 is normal) - uint8_t ScaleY; // [RH] Same as above - int16_t width; - int16_t height; - uint8_t columndirectory[4]; // OBSOLETE - int16_t patchcount; - mappatch_t patches[1]; -}; - -#define MAPTEXF_WORLDPANNING 0x8000 - -// Strife uses versions of the above structures that remove all unused fields - -struct strifemappatch_t -{ - int16_t originx; - int16_t originy; - int16_t patch; -}; - -// -// A wall texture is a list of patches which are to be combined in a -// predefined order. -// -struct strifemaptexture_t -{ - uint8_t name[8]; - uint16_t Flags; // [RH] Was unused - uint8_t ScaleX; // [RH] Scaling (8 is normal) - uint8_t ScaleY; // [RH] Same as above - int16_t width; - int16_t height; - int16_t patchcount; - strifemappatch_t patches[1]; -}; - - -//========================================================================== -// -// In-memory representation of a single PNAMES lump entry -// -//========================================================================== - -struct FPatchLookup -{ - FString Name; -}; - - -//========================================================================== -// -// A texture defined in a TEXTURE1 or TEXTURE2 lump -// -//========================================================================== - -class FMultiPatchTexture : public FTexture -{ -public: - FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflump); - FMultiPatchTexture (FScanner &sc, ETextureType usetype); - ~FMultiPatchTexture (); - - bool UseBasePalette() override; - virtual void SetFrontSkyLayer () override; - - int CopyPixels(FBitmap *bmp) override; - int GetSourceLump() override { return DefinitionLump; } - FTexture *GetRedirect() override; - FTexture *GetRawTexture() override; - void ResolvePatches(); - -protected: - uint8_t *Pixels; - //FSoftwareTextureSpan **Spans; - int DefinitionLump; - - struct TexPart - { - FRemapTable *Translation = nullptr; - FTexture *Texture = nullptr; - PalEntry Blend = 0; - blend_t Alpha = FRACUNIT; - int16_t OriginX = 0; - int16_t OriginY = 0; - uint8_t Rotate = 0; - uint8_t op = OP_COPY; - }; - - struct TexInit - { - FString TexName; - ETextureType UseType = ETextureType::Null; - bool Silent = false; - bool HasLine = false; - bool UseOffsets = false; - FScriptPosition sc; - }; - - int NumParts; - TexPart *Parts; - TexInit *Inits; - bool bRedirect; - bool bTranslucentPatches; - - TArray MakeTexture (bool alphatex); - - // The getters must optionally redirect if it's a simple one-patch texture. - TArray Get8BitPixels(bool alphatex) override { return bRedirect ? Parts->Texture->Get8BitPixels(alphatex) : MakeTexture(alphatex); } - - -private: - void CheckForHacks (); - void ParsePatch(FScanner &sc, TexPart & part, TexInit &init); -}; +#include "image.h" +#include "multipatchtexture.h" //========================================================================== // @@ -212,128 +59,25 @@ private: // //========================================================================== -FMultiPatchTexture::FMultiPatchTexture (const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum) -: Pixels (0), Parts(nullptr), Inits(nullptr), bRedirect(false), bTranslucentPatches(false) +FMultiPatchTexture::FMultiPatchTexture(int w, int h, const TArray &parts, bool complex, bool textual) { - union + Width = w; + Height = h; + bComplex = complex; + bTextual = textual; + Parts = (TexPart*)ImageArena.Alloc(sizeof(TexPart) * parts.Size()); + NumParts = parts.Size(); + memcpy(Parts, parts.Data(), sizeof(TexPart) * parts.Size()); + + bUseGamePalette = false; + if (!bComplex) { - const maptexture_t *d; - const strifemaptexture_t *s; - } - mtexture; - - union - { - const mappatch_t *d; - const strifemappatch_t *s; - } - mpatch; - - int i; - - mtexture.d = (const maptexture_t *)texdef; - bMultiPatch = 1; - - if (strife) - { - NumParts = SAFESHORT(mtexture.s->patchcount); - } - else - { - NumParts = SAFESHORT(mtexture.d->patchcount); - } - - if (NumParts < 0) - { - I_FatalError ("Bad texture directory"); - } - - UseType = ETextureType::Wall; - Parts = NumParts > 0 ? new TexPart[NumParts] : nullptr; - Inits = NumParts > 0 ? new TexInit[NumParts] : nullptr; - Width = SAFESHORT(mtexture.d->width); - Height = SAFESHORT(mtexture.d->height); - Name = (char *)mtexture.d->name; - - Scale.X = mtexture.d->ScaleX ? mtexture.d->ScaleX / 8. : 1.; - Scale.Y = mtexture.d->ScaleY ? mtexture.d->ScaleY / 8. : 1.; - - if (mtexture.d->Flags & MAPTEXF_WORLDPANNING) - { - bWorldPanning = true; - } - - if (strife) - { - mpatch.s = &mtexture.s->patches[0]; - } - else - { - mpatch.d = &mtexture.d->patches[0]; - } - - for (i = 0; i < NumParts; ++i) - { - if (unsigned(LittleShort(mpatch.d->patch)) >= unsigned(maxpatchnum)) + for (int i = 0; i < NumParts; i++) { - I_FatalError ("Bad PNAMES and/or texture directory:\n\nPNAMES has %d entries, but\n%s wants to use entry %d.", - maxpatchnum, Name.GetChars(), LittleShort(mpatch.d->patch)+1); + if (!Parts[i].Image->UseGamePalette()) return; } - Parts[i].OriginX = LittleShort(mpatch.d->originx); - Parts[i].OriginY = LittleShort(mpatch.d->originy); - Parts[i].Texture = nullptr; - Inits[i].TexName = patchlookup[LittleShort(mpatch.d->patch)].Name; - Inits[i].UseType = ETextureType::WallPatch; - if (strife) - mpatch.s++; - else - mpatch.d++; + bUseGamePalette = true; // only if all patches use the game palette. } - if (NumParts == 0) - { - Printf ("Texture %s is left without any patches\n", Name.GetChars()); - } - - DefinitionLump = deflumpnum; -} - -//========================================================================== -// -// FMultiPatchTexture :: ~FMultiPatchTexture -// -//========================================================================== - -FMultiPatchTexture::~FMultiPatchTexture () -{ - if (Parts != NULL) - { - for(int i=0; iSetFrontSkyLayer (); - } - bNoRemap0 = true; } //========================================================================== @@ -342,7 +86,7 @@ void FMultiPatchTexture::SetFrontSkyLayer () // //========================================================================== -uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork) +static uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork) { switch (blend.a==0 ? int(blend) : -1) { @@ -387,7 +131,55 @@ uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork) } } } - return NULL; + return nullptr; +} + +//========================================================================== +// +// +// +//========================================================================== + +void FMultiPatchTexture::CopyToBlock(uint8_t *dest, int dwidth, int dheight, FImageSource *source, int xpos, int ypos, int rotate, const uint8_t *translation, int style) +{ + auto image = source->GetPalettedPixels(style); // should use composition cache + const uint8_t *pixels = image.Data(); + int srcwidth = source->GetWidth(); + int srcheight = source->GetHeight(); + int step_x = source->GetHeight(); + int step_y = 1; + FClipRect cr = { 0, 0, dwidth, dheight }; + if (style) translation = nullptr; // do not apply translations to alpha textures. + + if (ClipCopyPixelRect(&cr, xpos, ypos, pixels, srcwidth, srcheight, step_x, step_y, rotate)) + { + dest += ypos + dheight * xpos; + if (translation == NULL) + { + for (int x = 0; x < srcwidth; x++) + { + int pos = x * dheight; + for (int y = 0; y < srcheight; y++, pos++) + { + // the optimizer is doing a good enough job here so there's no need to optimize this by hand + uint8_t v = pixels[y * step_y + x * step_x]; + if (v != 0) dest[pos] = v; + } + } + } + else + { + for (int x = 0; x < srcwidth; x++) + { + int pos = x * dheight; + for (int y = 0; y < srcheight; y++, pos++) + { + uint8_t v = pixels[y * step_y + x * step_x]; + if (v != 0) dest[pos] = translation[v]; + } + } + } + } } //========================================================================== @@ -396,7 +188,7 @@ uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork) // //========================================================================== -TArray FMultiPatchTexture::MakeTexture (bool alphatex) +TArray FMultiPatchTexture::GetPalettedPixels(int conversion) { int numpix = Width * Height; uint8_t blendwork[256]; @@ -405,9 +197,10 @@ TArray FMultiPatchTexture::MakeTexture (bool alphatex) TArray Pixels(numpix, true); memset (Pixels.Data(), 0, numpix); - if (alphatex) + if (conversion == luminance) { - buildrgb = !UseBasePalette(); + // For alpha textures, downconversion to the palette would lose too much precision if not all patches use the palette. + buildrgb = !UseGamePalette(); } else { @@ -420,20 +213,27 @@ TArray FMultiPatchTexture::MakeTexture (bool alphatex) } } } + if (conversion == noremap0) + { + // sky remapping will only happen if + // - the texture was defined through a TEXTUREx lump (this implies only trivial copies) + // - all patches use the base palette. + // All other cases would not be able to properly deal with this special case. + // For textual definitions this hack isn't necessary. + if (bTextual || !UseGamePalette()) conversion = normal; + } if (!buildrgb) { for (int i = 0; i < NumParts; ++i) { - if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. - uint8_t *trans = Parts[i].Translation? Parts[i].Translation->Remap : nullptr; { if (Parts[i].Blend != 0) { trans = GetBlendMap(Parts[i].Blend, blendwork); } - Parts[i].Texture->CopyToBlock (Pixels.Data(), Width, Height, Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, alphatex); + CopyToBlock (Pixels.Data(), Width, Height, Parts[i].Image, Parts[i].OriginX, Parts[i].OriginY, Parts[i].Rotate, trans, conversion); } } } @@ -441,16 +241,18 @@ TArray FMultiPatchTexture::MakeTexture (bool alphatex) { // In case there are translucent patches let's do the composition in // True color to keep as much precision as possible before downconverting to the palette. - auto buffer = GetBgraBitmap(nullptr); + FBitmap PixelsIn; + PixelsIn.Create(Width, Height); + CopyPixels(&PixelsIn, normal); for(int y = 0; y < Height; y++) { - uint8_t *in = buffer.GetPixels() + Width * y * 4; + uint8_t *in = PixelsIn.GetPixels() + Width * y * 4; uint8_t *out = Pixels.Data() + y; for (int x = 0; x < Width; x++) { if (*out == 0 && in[3] != 0) { - *out = ImageHelpers::RGBToPalette(alphatex, in[2], in[1], in[0]); + *out = ImageHelpers::RGBToPalette(conversion == luminance, in[2], in[1], in[0]); } out += Height; in += 4; @@ -468,13 +270,13 @@ TArray FMultiPatchTexture::MakeTexture (bool alphatex) // //=========================================================================== -int FMultiPatchTexture::CopyPixels(FBitmap *bmp) +int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion) { int retv = -1; - if (bRedirect) - { // Redirect straight to the real texture's routine. - return Parts[0].Texture->CopyPixels(bmp); + if (conversion == noremap0) + { + if (bTextual || !UseGamePalette()) conversion = normal; } for(int i = 0; i < NumParts; i++) @@ -482,8 +284,6 @@ int FMultiPatchTexture::CopyPixels(FBitmap *bmp) int ret = -1; FCopyInfo info; - if (Parts[i].Texture->bHasCanvas) continue; // cannot use camera textures as patch. - memset (&info, 0, sizeof(info)); info.alpha = Parts[i].Alpha; info.invalpha = BLENDUNIT - info.alpha; @@ -513,7 +313,9 @@ int FMultiPatchTexture::CopyPixels(FBitmap *bmp) } } - auto Pixels = Parts[i].Texture->GetBgraBitmap(Parts[i].Translation ? Parts[i].Translation->Palette : nullptr, &ret); + FBitmap Pixels; + Pixels.Create(Width, Height); + ret = Parts[i].Image->CopyPixels(&Pixels, conversion); bmp->Blit(Parts[i].OriginX, Parts[i].OriginY, Pixels, &info); // treat -1 (i.e. unknown) as absolute. We have no idea if this may have overwritten previous info so a real check needs to be done. if (ret == -1) retv = ret; @@ -522,740 +324,3 @@ int FMultiPatchTexture::CopyPixels(FBitmap *bmp) return retv; } -//=========================================================================== -// -// FMultipatchTexture::UseBasePalette -// -// returns true if all patches in the texture use the unmodified base -// palette. -// -//=========================================================================== - -bool FMultiPatchTexture::UseBasePalette() -{ - if (bComplex) return false; - for(int i=0;iUseBasePalette()) return false; - } - return true; -} - -//========================================================================== -// -// FMultiPatchTexture :: CheckForHacks -// -//========================================================================== - -void FMultiPatchTexture::CheckForHacks () -{ - if (NumParts <= 0) - { - return; - } - - // Heretic sky textures are marked as only 128 pixels tall, - // even though they are really 200 pixels tall. - if (gameinfo.gametype == GAME_Heretic && - Name[0] == 'S' && - Name[1] == 'K' && - Name[2] == 'Y' && - Name[4] == 0 && - Name[3] >= '1' && - Name[3] <= '3' && - Height == 128) - { - Height = 200; - return; - } - - // The Doom E1 sky has its patch's y offset at -8 instead of 0. - if (gameinfo.gametype == GAME_Doom && - !(gameinfo.flags & GI_MAPxx) && - NumParts == 1 && - Height == 128 && - Parts->OriginY == -8 && - Name[0] == 'S' && - Name[1] == 'K' && - Name[2] == 'Y' && - Name[3] == '1' && - Name[4] == 0) - { - Parts->OriginY = 0; - return; - } - - // BIGDOOR7 in Doom also has patches at y offset -4 instead of 0. - if (gameinfo.gametype == GAME_Doom && - !(gameinfo.flags & GI_MAPxx) && - NumParts == 2 && - Height == 128 && - Parts[0].OriginY == -4 && - Parts[1].OriginY == -4 && - Name[0] == 'B' && - Name[1] == 'I' && - Name[2] == 'G' && - Name[3] == 'D' && - Name[4] == 'O' && - Name[5] == 'O' && - Name[6] == 'R' && - Name[7] == '7') - { - Parts[0].OriginY = 0; - Parts[1].OriginY = 0; - return; - } - - // [RH] Some wads (I forget which!) have single-patch textures 256 - // pixels tall that have patch lengths recorded as 0. I can't think of - // any good reason for them to do this, and since I didn't make note - // of which wad made me hack in support for them, the hack is gone - // because I've added support for DeePsea's true tall patches. - // - // Okay, I found a wad with crap patches: Pleiades.wad's sky patches almost - // fit this description and are a big mess, but they're not single patch! - if (Height == 256) - { - int i; - - // All patches must be at the top of the texture for this fix - for (i = 0; i < NumParts; ++i) - { - if (Parts[i].OriginY != 0) - { - break; - } - } - } -} - -//========================================================================== -// -// FMultiPatchTexture :: GetRedirect -// -//========================================================================== - -FTexture *FMultiPatchTexture::GetRedirect() -{ - return bRedirect ? Parts->Texture : this; -} - -//========================================================================== -// -// FMultiPatchTexture :: GetRawTexture -// -// Doom ignored all compositing of mid-sided textures on two-sided lines. -// Since these textures had to be single-patch in Doom, that essentially -// means it ignores their Y offsets. -// -// If this texture is composed of only one patch, return that patch. -// Otherwise, return this texture, since Doom wouldn't have been able to -// draw it anyway. -// -//========================================================================== - -FTexture *FMultiPatchTexture::GetRawTexture() -{ - return NumParts == 1 && UseType == ETextureType::Wall && bMultiPatch == 1 && Scale == Parts->Texture->Scale ? Parts->Texture : this; -} - -//========================================================================== -// -// FTextureManager :: AddTexturesLump -// -//========================================================================== - -void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup, bool texture1) -{ - FPatchLookup *patchlookup = NULL; - int i; - uint32_t numpatches; - - if (firstdup == 0) - { - firstdup = (int)Textures.Size(); - } - - { - auto pnames = Wads.OpenLumpReader(patcheslump); - numpatches = pnames.ReadUInt32(); - - // Check whether the amount of names reported is correct. - if ((signed)numpatches < 0) - { - Printf("Corrupt PNAMES lump found (negative amount of entries reported)\n"); - return; - } - - // Check whether the amount of names reported is correct. - int lumplength = Wads.LumpLength(patcheslump); - if (numpatches > uint32_t((lumplength-4)/8)) - { - Printf("PNAMES lump is shorter than required (%u entries reported but only %d bytes (%d entries) long\n", - numpatches, lumplength, (lumplength-4)/8); - // Truncate but continue reading. Who knows how many such lumps exist? - numpatches = (lumplength-4)/8; - } - - // Catalog the patches these textures use so we know which - // textures they represent. - patchlookup = new FPatchLookup[numpatches]; - for (uint32_t i = 0; i < numpatches; ++i) - { - char pname[9]; - pnames.Read(pname, 8); - pname[8] = '\0'; - patchlookup[i].Name = pname; - } - } - - bool isStrife = false; - const uint32_t *maptex, *directory; - uint32_t maxoff; - int numtextures; - uint32_t offset = 0; // Shut up, GCC! - - maptex = (const uint32_t *)lumpdata; - numtextures = LittleLong(*maptex); - maxoff = lumpsize; - - if (maxoff < uint32_t(numtextures+1)*4) - { - Printf ("Texture directory is too short\n"); - delete[] patchlookup; - return; - } - - // Scan the texture lump to decide if it contains Doom or Strife textures - for (i = 0, directory = maptex+1; i < numtextures; ++i) - { - offset = LittleLong(directory[i]); - if (offset > maxoff) - { - Printf ("Bad texture directory\n"); - delete[] patchlookup; - return; - } - - maptexture_t *tex = (maptexture_t *)((uint8_t *)maptex + offset); - - // There is bizzarely a Doom editing tool that writes to the - // first two elements of columndirectory, so I can't check those. - if (SAFESHORT(tex->patchcount) < 0 || - tex->columndirectory[2] != 0 || - tex->columndirectory[3] != 0) - { - isStrife = true; - break; - } - } - - - // Textures defined earlier in the lump take precedence over those defined later, - // but later TEXTUREx lumps take precedence over earlier ones. - for (i = 1, directory = maptex; i <= numtextures; ++i) - { - if (i == 1 && texture1) - { - // The very first texture is just a dummy. Copy its dimensions to texture 0. - // It still needs to be created in case someone uses it by name. - offset = LittleLong(directory[1]); - const maptexture_t *tex = (const maptexture_t *)((const uint8_t *)maptex + offset); - FDummyTexture *tex0 = static_cast(Textures[0].Texture); - tex0->SetSize (SAFESHORT(tex->width), SAFESHORT(tex->height)); - } - - offset = LittleLong(directory[i]); - if (offset > maxoff) - { - Printf ("Bad texture directory\n"); - delete[] patchlookup; - return; - } - - // If this texture was defined already in this lump, skip it - // This could cause problems with animations that use the same name for intermediate - // textures. Should I be worried? - int j; - for (j = (int)Textures.Size() - 1; j >= firstdup; --j) - { - if (strnicmp (Textures[j].Texture->Name, (const char *)maptex + offset, 8) == 0) - break; - } - if (j + 1 == firstdup) - { - FMultiPatchTexture *tex = new FMultiPatchTexture ((const uint8_t *)maptex + offset, patchlookup, numpatches, isStrife, deflumpnum); - if (i == 1 && texture1) - { - tex->UseType = ETextureType::FirstDefined; - } - TexMan.AddTexture (tex); - StartScreen->Progress(); - } - } - delete[] patchlookup; -} - - -//========================================================================== -// -// FTextureManager :: AddTexturesLumps -// -//========================================================================== - -void FTextureManager::AddTexturesLumps (int lump1, int lump2, int patcheslump) -{ - int firstdup = (int)Textures.Size(); - - if (lump1 >= 0) - { - FMemLump texdir = Wads.ReadLump (lump1); - AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump1), lump1, patcheslump, firstdup, true); - } - if (lump2 >= 0) - { - FMemLump texdir = Wads.ReadLump (lump2); - AddTexturesLump (texdir.GetMem(), Wads.LumpLength (lump2), lump2, patcheslump, firstdup, false); - } -} - - -//========================================================================== -// -// -// -//========================================================================== - -void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init) -{ - FString patchname; - int Mirror = 0; - sc.MustGetString(); - - init.TexName = sc.String; - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.OriginX = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.OriginY = sc.Number; - - if (sc.CheckString("{")) - { - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("flipx")) - { - Mirror |= 1; - } - else if (sc.Compare("flipy")) - { - Mirror |= 2; - } - else if (sc.Compare("rotate")) - { - sc.MustGetNumber(); - sc.Number = (((sc.Number + 90)%360)-90); - if (sc.Number != 0 && sc.Number !=90 && sc.Number != 180 && sc.Number != -90) - { - sc.ScriptError("Rotation must be a multiple of 90 degrees."); - } - part.Rotate = (sc.Number / 90) & 3; - } - else if (sc.Compare("Translation")) - { - int match; - - bComplex = true; - if (part.Translation != NULL) delete part.Translation; - part.Translation = NULL; - part.Blend = 0; - static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; - sc.MustGetString(); - - match = sc.MatchString(maps); - if (match >= 0) - { - part.Blend = BLEND_SPECIALCOLORMAP1 + match; - } - else if (sc.Compare("ICE")) - { - part.Blend = BLEND_ICEMAP; - } - else if (sc.Compare("DESATURATE")) - { - sc.MustGetStringName(","); - sc.MustGetNumber(); - part.Blend = BLEND_DESATURATE1 + clamp(sc.Number-1, 0, 30); - } - else - { - sc.UnGet(); - part.Translation = new FRemapTable; - part.Translation->MakeIdentity(); - do - { - sc.MustGetString(); - part.Translation->AddToTranslation(sc.String); - } - while (sc.CheckString(",")); - } - - } - else if (sc.Compare("Colormap")) - { - float r1,g1,b1; - float r2,g2,b2; - - sc.MustGetFloat(); - r1 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - g1 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - b1 = (float)sc.Float; - if (!sc.CheckString(",")) - { - part.Blend = AddSpecialColormap(0,0,0, r1, g1, b1); - } - else - { - sc.MustGetFloat(); - r2 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - g2 = (float)sc.Float; - sc.MustGetStringName(","); - sc.MustGetFloat(); - b2 = (float)sc.Float; - part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); - } - } - else if (sc.Compare("Blend")) - { - bComplex = true; - if (part.Translation != NULL) delete part.Translation; - part.Translation = NULL; - part.Blend = 0; - - if (!sc.CheckNumber()) - { - sc.MustGetString(); - part.Blend = V_GetColor(NULL, sc); - } - else - { - int r,g,b; - - r = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - g = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - b = sc.Number; - //sc.MustGetStringName(","); This was never supposed to be here. - part.Blend = MAKERGB(r, g, b); - } - // Blend.a may never be 0 here. - if (sc.CheckString(",")) - { - sc.MustGetFloat(); - if (sc.Float > 0.f) - part.Blend.a = clamp(int(sc.Float*255), 1, 254); - else - part.Blend = 0; - } - else part.Blend.a = 255; - } - else if (sc.Compare("alpha")) - { - sc.MustGetFloat(); - part.Alpha = clamp(int(sc.Float * BLENDUNIT), 0, BLENDUNIT); - // bComplex is not set because it is only needed when the style is not OP_COPY. - } - else if (sc.Compare("style")) - { - static const char *styles[] = {"copy", "translucent", "add", "subtract", "reversesubtract", "modulate", "copyalpha", "copynewalpha", "overlay", NULL }; - sc.MustGetString(); - part.op = sc.MustMatchString(styles); - bComplex |= (part.op != OP_COPY); - bTranslucentPatches = bComplex; - } - else if (sc.Compare("useoffsets")) - { - init.UseOffsets = true; - } - } - } - if (Mirror & 2) - { - part.Rotate = (part.Rotate + 2) & 3; - Mirror ^= 1; - } - if (Mirror & 1) - { - part.Rotate |= 4; - } -} - -//========================================================================== -// -// Constructor for text based multipatch definitions -// -//========================================================================== - -FMultiPatchTexture::FMultiPatchTexture (FScanner &sc, ETextureType usetype) -: Pixels (0), Parts(0), bRedirect(false), bTranslucentPatches(false) -{ - TArray parts; - TArray inits; - bool bSilent = false; - - bMultiPatch = 2; - sc.SetCMode(true); - sc.MustGetString(); - const char* textureName = NULL; - if (sc.Compare("optional")) - { - bSilent = true; - sc.MustGetString(); - if (sc.Compare(",")) - { - // this is not right. Apparently a texture named 'optional' is being defined right now... - sc.UnGet(); - textureName = "optional"; - bSilent = false; - } - } - Name = !textureName ? sc.String : textureName; - Name.ToUpper(); - sc.MustGetStringName(","); - sc.MustGetNumber(); - Width = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - Height = sc.Number; - UseType = usetype; - - bool offset2set = false; - if (sc.CheckString("{")) - { - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("XScale")) - { - sc.MustGetFloat(); - Scale.X = sc.Float; - if (Scale.X == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", Name.GetChars()); - } - else if (sc.Compare("YScale")) - { - sc.MustGetFloat(); - Scale.Y = sc.Float; - if (Scale.Y == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", Name.GetChars()); - } - else if (sc.Compare("WorldPanning")) - { - bWorldPanning = true; - } - else if (sc.Compare("NullTexture")) - { - UseType = ETextureType::Null; - } - else if (sc.Compare("NoDecals")) - { - bNoDecals = true; - } - else if (sc.Compare("Patch")) - { - TexPart part; - TexInit init; - ParsePatch(sc, part, init); - if (init.TexName.IsNotEmpty()) - { - parts.Push(part); - init.UseType = ETextureType::WallPatch; - init.Silent = bSilent; - init.HasLine = true; - init.sc = sc; - inits.Push(init); - } - part.Texture = NULL; - part.Translation = NULL; - } - else if (sc.Compare("Sprite")) - { - TexPart part; - TexInit init; - ParsePatch(sc, part, init); - if (init.TexName.IsNotEmpty()) - { - parts.Push(part); - init.UseType = ETextureType::Sprite; - init.Silent = bSilent; - init.HasLine = true; - init.sc = sc; - inits.Push(init); - } - part.Texture = NULL; - part.Translation = NULL; - } - else if (sc.Compare("Graphic")) - { - TexPart part; - TexInit init; - ParsePatch(sc, part, init); - if (init.TexName.IsNotEmpty()) - { - parts.Push(part); - init.UseType = ETextureType::MiscPatch; - init.Silent = bSilent; - init.HasLine = true; - init.sc = sc; - inits.Push(init); - } - part.Texture = NULL; - part.Translation = NULL; - } - else if (sc.Compare("Offset")) - { - sc.MustGetNumber(); - _LeftOffset[0] = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - _TopOffset[0] = sc.Number; - if (!offset2set) - { - _LeftOffset[1] = _LeftOffset[0]; - _TopOffset[1] = _TopOffset[0]; - } - } - else if (sc.Compare("Offset2")) - { - sc.MustGetNumber(); - _LeftOffset[1] = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - _TopOffset[1] = sc.Number; - offset2set = true; - } - else - { - sc.ScriptError("Unknown texture property '%s'", sc.String); - } - } - - NumParts = parts.Size(); - Parts = new TexPart[NumParts]; - memcpy(Parts, &parts[0], NumParts * sizeof(*Parts)); - Inits = new TexInit[NumParts]; - for (int i = 0; i < NumParts; i++) - { - Inits[i] = inits[i]; - } - } - - if (Width <= 0 || Height <= 0) - { - UseType = ETextureType::Null; - Printf("Texture %s has invalid dimensions (%d, %d)\n", Name.GetChars(), Width, Height); - Width = Height = 1; - } - - sc.SetCMode(false); -} - - -void FMultiPatchTexture::ResolvePatches() -{ - if (Inits != nullptr) - { - for (int i = 0; i < NumParts; i++) - { - FTextureID texno = TexMan.CheckForTexture(Inits[i].TexName, Inits[i].UseType); - if (texno == id) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself. - { - TArray list; - TexMan.ListTextures(Inits[i].TexName, list, true); - for (int i = list.Size() - 1; i >= 0; i--) - { - if (list[i] != id && !TexMan.GetTexture(list[i])->bMultiPatch) - { - texno = list[i]; - break; - } - } - if (texno == id) - { - if (Inits[i].HasLine) Inits[i].sc.Message(MSG_WARNING, "Texture '%s' references itself as patch\n", Inits[i].TexName.GetChars()); - else Printf(TEXTCOLOR_YELLOW "Texture '%s' references itself as patch\n", Inits[i].TexName.GetChars()); - continue; - } - else - { - // If it could be resolved, just print a developer warning. - DPrintf(DMSG_WARNING, "Resolved self-referencing texture by picking an older entry for %s\n", Inits[i].TexName.GetChars()); - } - } - - if (!texno.isValid()) - { - if (!Inits[i].Silent) - { - if (Inits[i].HasLine) Inits[i].sc.Message(MSG_WARNING, "Unknown patch '%s' in texture '%s'\n", Inits[i].TexName.GetChars(), Name.GetChars()); - else Printf(TEXTCOLOR_YELLOW "Unknown patch '%s' in texture '%s'\n", Inits[i].TexName.GetChars(), Name.GetChars()); - } - } - else - { - Parts[i].Texture = TexMan.GetTexture(texno); - bComplex |= Parts[i].Texture->bComplex; - Parts[i].Texture->bKeepAround = true; - if (Inits[i].UseOffsets) - { - Parts[i].OriginX -= Parts[i].Texture->GetLeftOffset(0); - Parts[i].OriginY -= Parts[i].Texture->GetTopOffset(0); - } - } - } - for (int i = 0; i < NumParts; i++) - { - if (Parts[i].Texture == nullptr) - { - memmove(&Parts[i], &Parts[i + 1], (NumParts - i - 1) * sizeof(TexPart)); - i--; - NumParts--; - } - } - } - delete[] Inits; - Inits = nullptr; - - CheckForHacks(); - - // If this texture is just a wrapper around a single patch, we can simply - // forward getter calls to that patch. - - if (NumParts == 1) - { - if (Parts->OriginX == 0 && Parts->OriginY == 0 && - Parts->Texture->GetWidth() == Width && - Parts->Texture->GetHeight() == Height && - Parts->Rotate == 0 && - !bComplex) - { - bRedirect = true; - } - } -} - - -void FTextureManager::ParseXTexture(FScanner &sc, ETextureType usetype) -{ - FTexture *tex = new FMultiPatchTexture(sc, usetype); - TexMan.AddTexture (tex); -} diff --git a/src/textures/image.cpp b/src/textures/image.cpp index 20c457a96..7f246ba02 100644 --- a/src/textures/image.cpp +++ b/src/textures/image.cpp @@ -38,7 +38,7 @@ #include "bitmap.h" #include "image.h" - +FMemArena FImageSource::ImageArena(32768); //=========================================================================== // // the default just returns an empty texture. diff --git a/src/textures/image.h b/src/textures/image.h index 88a04b0fb..e53505acb 100644 --- a/src/textures/image.h +++ b/src/textures/image.h @@ -3,6 +3,7 @@ #include #include "tarray.h" #include "textures/bitmap.h" +#include "memarena.h" // This represents a naked image. It has no high level logic attached to it. @@ -11,6 +12,8 @@ class FImageSource { friend class FBrightmapImage; protected: + + static FMemArena ImageArena; int SourceLump; int Width = 0, Height = 0; int LeftOffset = 0, TopOffset = 0; // Offsets stored in the image. @@ -18,6 +21,10 @@ protected: public: + // Images are statically allocated and freed in bulk. None of the subclasses may hold any destructible data. + void *operator new(size_t block) { return ImageArena.Alloc(block); } + void operator delete(void *block) {} + bool bMasked = true; // Image (might) have holes (Assume true unless proven otherwise!) int8_t bTranslucent = -1; // Image has pixels with a non-0/1 value. (-1 means the user needs to do a real check) @@ -25,6 +32,7 @@ public: virtual TArray GetPalettedPixels(int conversion); // 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture. virtual int CopyPixels(FBitmap *bmp, int conversion); // This will always ignore 'luminance'. int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); + static void ClearImages() { ImageArena.FreeAll(); } // Conversion option enum EType @@ -69,8 +77,6 @@ public: { return bUseGamePalette; } - - bool UseBasePalette() = delete; }; //========================================================================== @@ -85,9 +91,13 @@ class FImageTexture : public FTexture public: FImageTexture (FImageSource *image, const char *name = nullptr); virtual TArray Get8BitPixels(bool alphatex); - FImageSource *GetImage() const { return mImage; } - bool UseBasePalette() override; + void SetImage(FImageSource *img) // This is only for the multipatch texture builder! + { + mImage = img; + } + + FImageSource *GetImage() const override { return mImage; } protected: int CopyPixels(FBitmap *bmp) override; diff --git a/src/textures/imagetexture.cpp b/src/textures/imagetexture.cpp index 6a376551c..9afdec41a 100644 --- a/src/textures/imagetexture.cpp +++ b/src/textures/imagetexture.cpp @@ -49,19 +49,22 @@ //========================================================================== FImageTexture::FImageTexture(FImageSource *img, const char *name) -: FTexture(name, img->LumpNum()) +: FTexture(name, img? img->LumpNum() : 0) { mImage = img; - Wads.GetLumpName (Name, img->LumpNum()); - Width = img->GetWidth(); - Height = img->GetHeight(); - - auto offsets = img->GetOffsets(); - _LeftOffset[1] = _LeftOffset[0] = offsets.first;; - _TopOffset[1] = _TopOffset[0] = offsets.second; - - bMasked = img->bMasked; - bTranslucent = img->bTranslucent; + if (img != nullptr) + { + if (name == nullptr) Wads.GetLumpName(Name, img->LumpNum()); + Width = img->GetWidth(); + Height = img->GetHeight(); + + auto offsets = img->GetOffsets(); + _LeftOffset[1] = _LeftOffset[0] = offsets.first; + _TopOffset[1] = _TopOffset[0] = offsets.second; + + bMasked = img->bMasked; + bTranslucent = img->bTranslucent; + } } //=========================================================================== @@ -86,12 +89,3 @@ TArray FImageTexture::Get8BitPixels(bool alpha) return mImage->GetPalettedPixels(alpha? alpha : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal); } -//=========================================================================== -// -// -//=========================================================================== - -bool FImageTexture::UseBasePalette() -{ - return mImage->UseGamePalette(); -} diff --git a/src/textures/multipatchtexturebuilder.cpp b/src/textures/multipatchtexturebuilder.cpp new file mode 100644 index 000000000..ac2b06917 --- /dev/null +++ b/src/textures/multipatchtexturebuilder.cpp @@ -0,0 +1,975 @@ +/* +** multipatchtexturebuilder.cpp +** Texture class for standard Doom multipatch textures +** +**--------------------------------------------------------------------------- +** Copyright 2004-2006 Randy Heit +** Copyright 2006-2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include +#include "doomtype.h" +#include "files.h" +#include "w_wad.h" +#include "i_system.h" +#include "gi.h" +#include "st_start.h" +#include "sc_man.h" +#include "templates.h" +#include "r_data/r_translate.h" +#include "bitmap.h" +#include "colormatcher.h" +#include "v_palette.h" +#include "v_video.h" +#include "v_text.h" +#include "cmdlib.h" +#include "imagehelpers.h" +#include "image.h" +#include "formats/multipatchtexture.h" + +// On the Alpha, accessing the shorts directly if they aren't aligned on a +// 4-byte boundary causes unaligned access warnings. Why it does this at +// all and only while initing the textures is beyond me. + +#ifdef ALPHA +#define SAFESHORT(s) ((short)(((uint8_t *)&(s))[0] + ((uint8_t *)&(s))[1] * 256)) +#else +#define SAFESHORT(s) LittleShort(s) +#endif + + + +//-------------------------------------------------------------------------- +// +// Data structures for the TEXTUREx lumps +// +//-------------------------------------------------------------------------- + +// +// Each texture is composed of one or more patches, with patches being lumps +// stored in the WAD. The lumps are referenced by number, and patched into +// the rectangular texture space using origin and possibly other attributes. +// +struct mappatch_t +{ + int16_t originx; + int16_t originy; + int16_t patch; + int16_t stepdir; + int16_t colormap; +}; + +// +// A wall texture is a list of patches which are to be combined in a +// predefined order. +// +struct maptexture_t +{ + uint8_t name[8]; + uint16_t Flags; // [RH] Was unused + uint8_t ScaleX; // [RH] Scaling (8 is normal) + uint8_t ScaleY; // [RH] Same as above + int16_t width; + int16_t height; + uint8_t columndirectory[4]; // OBSOLETE + int16_t patchcount; + mappatch_t patches[1]; +}; + +#define MAPTEXF_WORLDPANNING 0x8000 + +// Strife uses versions of the above structures that remove all unused fields + +struct strifemappatch_t +{ + int16_t originx; + int16_t originy; + int16_t patch; +}; + +// +// A wall texture is a list of patches which are to be combined in a +// predefined order. +// +struct strifemaptexture_t +{ + uint8_t name[8]; + uint16_t Flags; // [RH] Was unused + uint8_t ScaleX; // [RH] Scaling (8 is normal) + uint8_t ScaleY; // [RH] Same as above + int16_t width; + int16_t height; + int16_t patchcount; + strifemappatch_t patches[1]; +}; + + +//========================================================================== +// +// In-memory representation of a single PNAMES lump entry +// +//========================================================================== + +struct FPatchLookup +{ + FString Name; +}; + + +void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType usetype) +{ + FImageTexture *tex = new FImageTexture(nullptr, buildinfo.Name); + tex->SetUseType(usetype); + tex->bMultiPatch = true; + tex->Width = buildinfo.Width; + tex->Height = buildinfo.Height; + tex->_LeftOffset[0] = buildinfo.LeftOffset[0]; + tex->_LeftOffset[1] = buildinfo.LeftOffset[1]; + tex->_TopOffset[0] = buildinfo.TopOffset[0]; + tex->_TopOffset[1] = buildinfo.TopOffset[1]; + tex->Scale = buildinfo.Scale; + tex->bMasked = true; // we do not really know yet. + tex->bTranslucent = -1; + tex->bWorldPanning = buildinfo.bWorldPanning; + tex->bNoDecals = buildinfo.bNoDecals; + tex->SourceLump = buildinfo.DefinitionLump; + buildinfo.id = TexMan.AddTexture(tex); + buildinfo.tex = tex; +} + +//========================================================================== +// +// The reader for TEXTUREx +// +//========================================================================== + + +//========================================================================== +// +// FMultiPatchTexture :: FMultiPatchTexture +// +//========================================================================== + +void FMultipatchTextureBuilder::BuildTexture(const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum, ETextureType usetype) +{ + BuildInfo &buildinfo = BuiltTextures[BuiltTextures.Reserve(1)]; + + union + { + const maptexture_t *d; + const strifemaptexture_t *s; + } + mtexture; + + union + { + const mappatch_t *d; + const strifemappatch_t *s; + } + mpatch; + + int i; + + mtexture.d = (const maptexture_t *)texdef; + int NumParts; + + if (strife) + { + NumParts = SAFESHORT(mtexture.s->patchcount); + } + else + { + NumParts = SAFESHORT(mtexture.d->patchcount); + } + + if (NumParts < 0) + { + I_Error("Bad texture directory"); + } + + buildinfo.Parts.Resize(NumParts); + buildinfo.Inits.Resize(NumParts); + buildinfo.Width = SAFESHORT(mtexture.d->width); + buildinfo.Height = SAFESHORT(mtexture.d->height); + buildinfo.Name = (char *)mtexture.d->name; + + buildinfo.Scale.X = mtexture.d->ScaleX ? mtexture.d->ScaleX / 8. : 1.; + buildinfo.Scale.Y = mtexture.d->ScaleY ? mtexture.d->ScaleY / 8. : 1.; + + if (mtexture.d->Flags & MAPTEXF_WORLDPANNING) + { + buildinfo.bWorldPanning = true; + } + + if (strife) + { + mpatch.s = &mtexture.s->patches[0]; + } + else + { + mpatch.d = &mtexture.d->patches[0]; + } + + for (i = 0; i < NumParts; ++i) + { + if (unsigned(LittleShort(mpatch.d->patch)) >= unsigned(maxpatchnum)) + { + I_Error("Bad PNAMES and/or texture directory:\n\nPNAMES has %d entries, but\n%s wants to use entry %d.", + maxpatchnum, buildinfo.Name.GetChars(), LittleShort(mpatch.d->patch) + 1); + } + buildinfo.Parts[i].OriginX = LittleShort(mpatch.d->originx); + buildinfo.Parts[i].OriginY = LittleShort(mpatch.d->originy); + buildinfo.Parts[i].Image = nullptr; + buildinfo.Inits[i].TexName = patchlookup[LittleShort(mpatch.d->patch)].Name; + buildinfo.Inits[i].UseType = ETextureType::WallPatch; + if (strife) + mpatch.s++; + else + mpatch.d++; + } + if (NumParts == 0) + { + Printf("Texture %s is left without any patches\n", buildinfo.Name.GetChars()); + } + + // Insert the incomplete texture right here so that it's in the correct place. + MakeTexture(buildinfo, usetype); + buildinfo.DefinitionLump = deflumpnum; +} + +//========================================================================== +// +// FTextureManager :: AddTexturesLump +// +//========================================================================== + +void FMultipatchTextureBuilder::AddTexturesLump(const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup, bool texture1) +{ + TArray patchlookup; + int i; + uint32_t numpatches; + + if (firstdup == 0) + { + firstdup = (int)TexMan.NumTextures(); + } + + { + auto pnames = Wads.OpenLumpReader(patcheslump); + numpatches = pnames.ReadUInt32(); + + // Check whether the amount of names reported is correct. + if ((signed)numpatches < 0) + { + Printf("Corrupt PNAMES lump found (negative amount of entries reported)\n"); + return; + } + + // Check whether the amount of names reported is correct. + int lumplength = Wads.LumpLength(patcheslump); + if (numpatches > uint32_t((lumplength - 4) / 8)) + { + Printf("PNAMES lump is shorter than required (%u entries reported but only %d bytes (%d entries) long\n", + numpatches, lumplength, (lumplength - 4) / 8); + // Truncate but continue reading. Who knows how many such lumps exist? + numpatches = (lumplength - 4) / 8; + } + + // Catalog the patches these textures use so we know which + // textures they represent. + patchlookup.Resize(numpatches); + for (uint32_t i = 0; i < numpatches; ++i) + { + char pname[9]; + pnames.Read(pname, 8); + pname[8] = '\0'; + patchlookup[i].Name = pname; + } + } + + bool isStrife = false; + const uint32_t *maptex, *directory; + uint32_t maxoff; + int numtextures; + uint32_t offset = 0; // Shut up, GCC! + + maptex = (const uint32_t *)lumpdata; + numtextures = LittleLong(*maptex); + maxoff = lumpsize; + + if (maxoff < uint32_t(numtextures + 1) * 4) + { + Printf("Texture directory is too short\n"); + return; + } + + // Scan the texture lump to decide if it contains Doom or Strife textures + for (i = 0, directory = maptex + 1; i < numtextures; ++i) + { + offset = LittleLong(directory[i]); + if (offset > maxoff) + { + Printf("Bad texture directory\n"); + return; + } + + maptexture_t *tex = (maptexture_t *)((uint8_t *)maptex + offset); + + // There is bizzarely a Doom editing tool that writes to the + // first two elements of columndirectory, so I can't check those. + if (SAFESHORT(tex->patchcount) < 0 || + tex->columndirectory[2] != 0 || + tex->columndirectory[3] != 0) + { + isStrife = true; + break; + } + } + + + // Textures defined earlier in the lump take precedence over those defined later, + // but later TEXTUREx lumps take precedence over earlier ones. + for (i = 1, directory = maptex; i <= numtextures; ++i) + { + if (i == 1 && texture1) + { + // The very first texture is just a dummy. Copy its dimensions to texture 0. + // It still needs to be created in case someone uses it by name. + offset = LittleLong(directory[1]); + const maptexture_t *tex = (const maptexture_t *)((const uint8_t *)maptex + offset); + FDummyTexture *tex0 = static_cast(TexMan.ByIndex(0)); + tex0->SetSize(SAFESHORT(tex->width), SAFESHORT(tex->height)); + } + + offset = LittleLong(directory[i]); + if (offset > maxoff) + { + Printf("Bad texture directory\n"); + return; + } + + // If this texture was defined already in this lump, skip it + // This could cause problems with animations that use the same name for intermediate + // textures. Should I be worried? + int j; + for (j = (int)TexMan.NumTextures() - 1; j >= firstdup; --j) + { + if (strnicmp(TexMan.ByIndex(j)->GetName(), (const char *)maptex + offset, 8) == 0) + break; + } + if (j + 1 == firstdup) + { + BuildTexture((const uint8_t *)maptex + offset, patchlookup.Data(), numpatches, isStrife, deflumpnum, (i == 1 && texture1) ? ETextureType::FirstDefined : ETextureType::Wall); + StartScreen->Progress(); + } + } +} + + +//========================================================================== +// +// FTextureManager :: AddTexturesLumps +// +//========================================================================== + +void FMultipatchTextureBuilder::AddTexturesLumps(int lump1, int lump2, int patcheslump) +{ + int firstdup = (int)TexMan.NumTextures(); + + if (lump1 >= 0) + { + FMemLump texdir = Wads.ReadLump(lump1); + AddTexturesLump(texdir.GetMem(), Wads.LumpLength(lump1), lump1, patcheslump, firstdup, true); + } + if (lump2 >= 0) + { + FMemLump texdir = Wads.ReadLump(lump2); + AddTexturesLump(texdir.GetMem(), Wads.LumpLength(lump2), lump2, patcheslump, firstdup, false); + } +} + +//========================================================================== +// +// THe reader for the textual format +// +//========================================================================== + + +//========================================================================== +// +// +// +//========================================================================== + +void FMultipatchTextureBuilder::ParsePatch(FScanner &sc, BuildInfo &info, TexPart & part, TexInit &init) +{ + FString patchname; + int Mirror = 0; + sc.MustGetString(); + + init.TexName = sc.String; + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.OriginX = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.OriginY = sc.Number; + + if (sc.CheckString("{")) + { + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("flipx")) + { + Mirror |= 1; + } + else if (sc.Compare("flipy")) + { + Mirror |= 2; + } + else if (sc.Compare("rotate")) + { + sc.MustGetNumber(); + sc.Number = (((sc.Number + 90) % 360) - 90); + if (sc.Number != 0 && sc.Number != 90 && sc.Number != 180 && sc.Number != -90) + { + sc.ScriptError("Rotation must be a multiple of 90 degrees."); + } + part.Rotate = (sc.Number / 90) & 3; + } + else if (sc.Compare("Translation")) + { + int match; + + info.bComplex = true; + if (part.Translation != NULL) delete part.Translation; + part.Translation = NULL; + part.Blend = 0; + static const char *maps[] = { "inverse", "gold", "red", "green", "blue", NULL }; + sc.MustGetString(); + + match = sc.MatchString(maps); + if (match >= 0) + { + part.Blend = BLEND_SPECIALCOLORMAP1 + match; + } + else if (sc.Compare("ICE")) + { + part.Blend = BLEND_ICEMAP; + } + else if (sc.Compare("DESATURATE")) + { + sc.MustGetStringName(","); + sc.MustGetNumber(); + part.Blend = BLEND_DESATURATE1 + clamp(sc.Number - 1, 0, 30); + } + else + { + sc.UnGet(); + part.Translation = new FRemapTable; + part.Translation->MakeIdentity(); + do + { + sc.MustGetString(); + part.Translation->AddToTranslation(sc.String); + } while (sc.CheckString(",")); + } + + } + else if (sc.Compare("Colormap")) + { + float r1, g1, b1; + float r2, g2, b2; + + sc.MustGetFloat(); + r1 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + g1 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + b1 = (float)sc.Float; + if (!sc.CheckString(",")) + { + part.Blend = AddSpecialColormap(0, 0, 0, r1, g1, b1); + } + else + { + sc.MustGetFloat(); + r2 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + g2 = (float)sc.Float; + sc.MustGetStringName(","); + sc.MustGetFloat(); + b2 = (float)sc.Float; + part.Blend = AddSpecialColormap(r1, g1, b1, r2, g2, b2); + } + } + else if (sc.Compare("Blend")) + { + info.bComplex = true; + if (part.Translation != NULL) delete part.Translation; + part.Translation = NULL; + part.Blend = 0; + + if (!sc.CheckNumber()) + { + sc.MustGetString(); + part.Blend = V_GetColor(NULL, sc); + } + else + { + int r, g, b; + + r = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + g = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + b = sc.Number; + //sc.MustGetStringName(","); This was never supposed to be here. + part.Blend = MAKERGB(r, g, b); + } + // Blend.a may never be 0 here. + if (sc.CheckString(",")) + { + sc.MustGetFloat(); + if (sc.Float > 0.f) + part.Blend.a = clamp(int(sc.Float * 255), 1, 254); + else + part.Blend = 0; + } + else part.Blend.a = 255; + } + else if (sc.Compare("alpha")) + { + sc.MustGetFloat(); + part.Alpha = clamp(int(sc.Float * BLENDUNIT), 0, BLENDUNIT); + // bComplex is not set because it is only needed when the style is not OP_COPY. + } + else if (sc.Compare("style")) + { + static const char *styles[] = { "copy", "translucent", "add", "subtract", "reversesubtract", "modulate", "copyalpha", "copynewalpha", "overlay", NULL }; + sc.MustGetString(); + part.op = sc.MustMatchString(styles); + info.bComplex |= (part.op != OP_COPY); + } + else if (sc.Compare("useoffsets")) + { + init.UseOffsets = true; + } + } + } + if (Mirror & 2) + { + part.Rotate = (part.Rotate + 2) & 3; + Mirror ^= 1; + } + if (Mirror & 1) + { + part.Rotate |= 4; + } +} + + +//========================================================================== +// +// Constructor for text based multipatch definitions +// +//========================================================================== + +void FMultipatchTextureBuilder::ParseTexture(FScanner &sc, ETextureType UseType) +{ + BuildInfo &buildinfo = BuiltTextures[BuiltTextures.Reserve(1)]; + + bool bSilent = false; + + buildinfo.textual = true; + sc.SetCMode(true); + sc.MustGetString(); + + const char *textureName = nullptr; + if (sc.Compare("optional")) + { + bSilent = true; + sc.MustGetString(); + if (sc.Compare(",")) + { + // this is not right. Apparently a texture named 'optional' is being defined right now... + sc.UnGet(); + textureName = "optional"; + bSilent = false; + } + } + buildinfo.Name = !textureName ? sc.String : textureName; + buildinfo.Name.ToUpper(); + sc.MustGetStringName(","); + sc.MustGetNumber(); + buildinfo.Width = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + buildinfo.Height = sc.Number; + + bool offset2set = false; + if (sc.CheckString("{")) + { + while (!sc.CheckString("}")) + { + sc.MustGetString(); + if (sc.Compare("XScale")) + { + sc.MustGetFloat(); + buildinfo.Scale.X = sc.Float; + if (buildinfo.Scale.X == 0) sc.ScriptError("Texture %s is defined with null x-scale\n", buildinfo.Name.GetChars()); + } + else if (sc.Compare("YScale")) + { + sc.MustGetFloat(); + buildinfo.Scale.Y = sc.Float; + if (buildinfo.Scale.Y == 0) sc.ScriptError("Texture %s is defined with null y-scale\n", buildinfo.Name.GetChars()); + } + else if (sc.Compare("WorldPanning")) + { + buildinfo.bWorldPanning = true; + } + else if (sc.Compare("NullTexture")) + { + UseType = ETextureType::Null; + } + else if (sc.Compare("NoDecals")) + { + buildinfo.bNoDecals = true; + } + else if (sc.Compare("Patch")) + { + TexPart part; + TexInit init; + ParsePatch(sc, buildinfo, part, init); + if (init.TexName.IsNotEmpty()) + { + buildinfo.Parts.Push(part); + init.UseType = ETextureType::WallPatch; + init.Silent = bSilent; + init.HasLine = true; + init.sc = sc; + buildinfo.Inits.Push(init); + } + part.Image = nullptr; + part.Translation = nullptr; + } + else if (sc.Compare("Sprite")) + { + TexPart part; + TexInit init; + ParsePatch(sc, buildinfo, part, init); + if (init.TexName.IsNotEmpty()) + { + buildinfo.Parts.Push(part); + init.UseType = ETextureType::Sprite; + init.Silent = bSilent; + init.HasLine = true; + init.sc = sc; + buildinfo.Inits.Push(init); + } + part.Image = nullptr; + part.Translation = nullptr; + } + else if (sc.Compare("Graphic")) + { + TexPart part; + TexInit init; + ParsePatch(sc, buildinfo, part, init); + if (init.TexName.IsNotEmpty()) + { + buildinfo.Parts.Push(part); + init.UseType = ETextureType::MiscPatch; + init.Silent = bSilent; + init.HasLine = true; + init.sc = sc; + buildinfo.Inits.Push(init); + } + part.Image = nullptr; + part.Translation = nullptr; + } + else if (sc.Compare("Offset")) + { + sc.MustGetNumber(); + buildinfo.LeftOffset[0] = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + buildinfo.TopOffset[0] = sc.Number; + if (!offset2set) + { + buildinfo.LeftOffset[1] = buildinfo.LeftOffset[0]; + buildinfo.TopOffset[1] = buildinfo.TopOffset[0]; + } + } + else if (sc.Compare("Offset2")) + { + sc.MustGetNumber(); + buildinfo.LeftOffset[1] = sc.Number; + sc.MustGetStringName(","); + sc.MustGetNumber(); + buildinfo.TopOffset[1] = sc.Number; + offset2set = true; + } + else + { + sc.ScriptError("Unknown texture property '%s'", sc.String); + } + } + } + + if (buildinfo.Width <= 0 || buildinfo.Height <= 0) + { + UseType = ETextureType::Null; + Printf("Texture %s has invalid dimensions (%d, %d)\n", buildinfo.Name.GetChars(), buildinfo.Width, buildinfo.Height); + buildinfo.Width = buildinfo.Height = 1; + } + + MakeTexture(buildinfo, UseType); + sc.SetCMode(false); +} + + + +//========================================================================== +// +// FMultiPatchTexture :: CheckForHacks +// +//========================================================================== + +void FMultipatchTextureBuilder::CheckForHacks(BuildInfo &buildinfo) +{ + if (buildinfo.Parts.Size() == 0) + { + return; + } + + // Heretic sky textures are marked as only 128 pixels tall, + // even though they are really 200 pixels tall. + if (gameinfo.gametype == GAME_Heretic && + buildinfo.Name.Len() == 4 && + buildinfo.Name[0] == 'S' && + buildinfo.Name[1] == 'K' && + buildinfo.Name[2] == 'Y' && + buildinfo.Name[3] >= '1' && + buildinfo.Name[3] <= '3' && + buildinfo.Height == 128) + { + buildinfo.Height = 200; + return; + } + + // The Doom E1 sky has its patch's y offset at -8 instead of 0. + if (gameinfo.gametype == GAME_Doom && + !(gameinfo.flags & GI_MAPxx) && + buildinfo.Name.Len() == 4 && + buildinfo.Parts.Size() == 1 && + buildinfo.Height == 128 && + buildinfo.Parts[0].OriginY == -8 && + buildinfo.Name[0] == 'S' && + buildinfo.Name[1] == 'K' && + buildinfo.Name[2] == 'Y' && + buildinfo.Name[3] == '1') + { + buildinfo.Parts[0].OriginY = 0; + return; + } + + // BIGDOOR7 in Doom also has patches at y offset -4 instead of 0. + if (gameinfo.gametype == GAME_Doom && + !(gameinfo.flags & GI_MAPxx) && + buildinfo.Name.CompareNoCase("BIGDOOR7") == 0 && + buildinfo.Parts.Size() == 2 && + buildinfo.Height == 128 && + buildinfo.Parts[0].OriginY == -4 && + buildinfo.Parts[1].OriginY == -4) + { + buildinfo.Parts[0].OriginY = 0; + buildinfo.Parts[1].OriginY = 0; + return; + } +} + +//========================================================================== +// +// +// +//========================================================================== + +void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo) +{ + for (unsigned i = 0; i < buildinfo.Inits.Size(); i++) + { + FTextureID texno = TexMan.CheckForTexture(buildinfo.Inits[i].TexName, buildinfo.Inits[i].UseType); + if (texno == buildinfo.id) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself. + { + TArray list; + TexMan.ListTextures(buildinfo.Inits[i].TexName, list, true); + for (int i = list.Size() - 1; i >= 0; i--) + { + if (list[i] != buildinfo.id && !TexMan.GetTexture(list[i])->bMultiPatch) + { + texno = list[i]; + break; + } + } + if (texno == buildinfo.id) + { + if (buildinfo.Inits[i].HasLine) buildinfo.Inits[i].sc.Message(MSG_WARNING, "Texture '%s' references itself as patch\n", buildinfo.Inits[i].TexName.GetChars()); + else Printf(TEXTCOLOR_YELLOW "Texture '%s' references itself as patch\n", buildinfo.Inits[i].TexName.GetChars()); + continue; + } + else + { + // If it could be resolved, just print a developer warning. + DPrintf(DMSG_WARNING, "Resolved self-referencing texture by picking an older entry for %s\n", buildinfo.Inits[i].TexName.GetChars()); + } + } + + if (!texno.isValid()) + { + if (!buildinfo.Inits[i].Silent) + { + if (buildinfo.Inits[i].HasLine) buildinfo.Inits[i].sc.Message(MSG_WARNING, "Unknown patch '%s' in texture '%s'\n", buildinfo.Inits[i].TexName.GetChars(), buildinfo.Name.GetChars()); + else Printf(TEXTCOLOR_YELLOW "Unknown patch '%s' in texture '%s'\n", buildinfo.Inits[i].TexName.GetChars(), buildinfo.Name.GetChars()); + } + } + else + { + FTexture *tex = TexMan.GetTexture(texno); + + if (tex != nullptr && tex->isValid()) + { + //We cannot set the image source yet. First all textures need to be resolved. + buildinfo.Inits[i].Texture = tex; + buildinfo.tex->bComplex |= tex->bComplex; + buildinfo.bComplex |= tex->bComplex; + if (buildinfo.Inits[i].UseOffsets) + { + buildinfo.Parts[i].OriginX -= tex->GetLeftOffset(0); + buildinfo.Parts[i].OriginY -= tex->GetTopOffset(0); + } + } + else + { + // The patch is bogus. Remove it. + if (buildinfo.Inits[i].HasLine) buildinfo.Inits[i].sc.Message(MSG_WARNING, "Invalid patch '%s' in texture '%s'\n", buildinfo.Inits[i].TexName.GetChars(), buildinfo.Name.GetChars()); + else Printf(TEXTCOLOR_YELLOW "Invalid patch '%s' in texture '%s'\n", buildinfo.Inits[i].TexName.GetChars(), buildinfo.Name.GetChars()); + i--; + } + } + } + for (unsigned i = 0; i < buildinfo.Inits.Size(); i++) + { + if (buildinfo.Inits[i].Texture == nullptr) + { + buildinfo.Inits.Delete(i); + buildinfo.Parts.Delete(i); + i--; + } + } + + CheckForHacks(buildinfo); +} + +void FMultipatchTextureBuilder::ResolveAllPatches() +{ + for (auto &bi : BuiltTextures) + { + ResolvePatches(bi); + } + // Now try to resolve the images. We only can do this at the end when all multipatch textures are set up. + int i = 0; + while (BuiltTextures.Size() > 0) + { + bool donesomething = false; + for (unsigned i = 0; i < BuiltTextures.Size(); i++) + { + auto &buildinfo = BuiltTextures[i]; + bool hasEmpty = false; + + for (unsigned j = 0; j < buildinfo.Inits.Size(); j++) + { + if (buildinfo.Parts[j].Image == nullptr) + { + auto image = buildinfo.Inits[j].Texture->GetImage(); + if (image != nullptr) + { + buildinfo.Parts[j].Image = image; + donesomething = true; + } + else hasEmpty = true; + } + } + if (!hasEmpty) + { + // If this texture is just a wrapper around a single patch, we can simply + // use that patch's image directly here. + + bool done = false; + if (buildinfo.Parts.Size() == 1) + { + if (buildinfo.Parts[0].OriginX == 0 && buildinfo.Parts[0].OriginY == 0 && + buildinfo.Parts[0].Image->GetWidth() == buildinfo.Width && + buildinfo.Parts[0].Image->GetHeight() == buildinfo.Height && + buildinfo.Parts[0].Rotate == 0 && + !buildinfo.bComplex) + { + buildinfo.tex->SetImage(buildinfo.Parts[0].Image); + done = true; + } + } + if (!done) + { + auto img = new FMultiPatchTexture(buildinfo.Width, buildinfo.Height, buildinfo.Parts, buildinfo.bComplex, buildinfo.textual); + buildinfo.tex->SetImage(img); + } + + BuiltTextures.Delete(i); + i--; + donesomething = true; + } + } + if (!donesomething) + { + Printf(PRINT_LOG, "%d Unresolved textures remain\n", BuiltTextures.Size()); + for (auto &b : BuiltTextures) + { + Printf(PRINT_LOG, "%s\n", b.Name.GetChars()); + } + break; + } + } +} diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 2d165d46c..6e063be62 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -66,14 +66,3 @@ int FSkyBox::CopyPixels(FBitmap *bmp) return 0; } -//----------------------------------------------------------------------------- -// -// -// -//----------------------------------------------------------------------------- - -bool FSkyBox::UseBasePalette() -{ - return false; // not really but here it's not important. -} - diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index cbdbdb0e6..80f9b9c72 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -18,8 +18,6 @@ public: FSkyBox(const char *name = nullptr); TArray Get8BitPixels(bool alphatex); int CopyPixels(FBitmap *bmp); - bool UseBasePalette(); - void Unload (); void SetSize() { @@ -31,11 +29,16 @@ public: bool Is3Face() const { - return faces[5]==NULL; + return faces[5] == nullptr; } bool IsFlipped() const { return fliptop; } + + FImageSource *GetImage() const override + { + return faces[0] ? faces[0]->GetImage() : nullptr; + } }; diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 0aec9d106..934f585b3 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -246,54 +246,6 @@ void FTexture::SetFrontSkyLayer () bNoRemap0 = true; } -//========================================================================== -// -// -// -//========================================================================== - -void FTexture::CopyToBlock (uint8_t *dest, int dwidth, int dheight, int xpos, int ypos, int rotate, const uint8_t *translation, bool style) -{ - auto image = Get8BitPixels(style); // should use composition cache - const uint8_t *pixels = image.Data(); - int srcwidth = Width; - int srcheight = Height; - int step_x = Height; - int step_y = 1; - FClipRect cr = {0, 0, dwidth, dheight}; - if (style) translation = nullptr; // do not apply translations to alpha textures. - - if (ClipCopyPixelRect(&cr, xpos, ypos, pixels, srcwidth, srcheight, step_x, step_y, rotate)) - { - dest += ypos + dheight * xpos; - if (translation == NULL) - { - for (int x = 0; x < srcwidth; x++) - { - int pos = x * dheight; - for (int y = 0; y < srcheight; y++, pos++) - { - // the optimizer is doing a good enough job here so there's no need to optimize this by hand - uint8_t v = pixels[y * step_y + x * step_x]; - if (v != 0) dest[pos] = v; - } - } - } - else - { - for (int x = 0; x < srcwidth; x++) - { - int pos = x * dheight; - for (int y = 0; y < srcheight; y++, pos++) - { - uint8_t v = pixels[y * step_y + x * step_x]; - if (v != 0) dest[pos] = translation[v]; - } - } - } - } -} - //=========================================================================== // // FTexture::CopyPixels @@ -341,16 +293,6 @@ FBitmap FTexture::GetBgraBitmap(PalEntry *remap, int *ptrans) // //========================================================================== -bool FTexture::UseBasePalette() -{ - return true; -} - -FTexture *FTexture::GetRedirect() -{ - return this; -} - FTexture *FTexture::GetRawTexture() { return this; @@ -523,7 +465,7 @@ void FTexture::CreateDefaultBrightmap() if (!bBrightmapChecked) { // Check for brightmaps - if (UseBasePalette() && TexMan.HasGlobalBrightmap && + if (GetImage() && GetImage()->UseGamePalette() && TexMan.HasGlobalBrightmap && UseType != ETextureType::Decal && UseType != ETextureType::MiscPatch && UseType != ETextureType::FontChar && Brightmap == NULL && bWarped == 0) { @@ -779,11 +721,6 @@ bool FTexture::ProcessData(unsigned char * buffer, int w, int h, bool ispatch) if (bMasked) { bMasked = SmoothEdges(buffer, w, h); - if (!bMasked) - { - auto stex = GetRedirect(); - stex->bMasked = false; // also clear in the base texture if there is a redirection. - } if (bMasked && !ispatch) FindHoles(buffer, w, h); } return true; @@ -801,7 +738,6 @@ unsigned char * FTexture::CreateTexBuffer(int translation, int & w, int & h, int int W, H; int isTransparent = -1; - if (flags & CTF_CheckHires) { buffer = LoadHiresTexture(&w, &h); diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 85221b11e..c21d9c623 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -52,6 +52,8 @@ #include "r_renderer.h" #include "r_sky.h" #include "vm.h" +#include "image.h" +#include "formats/multipatchtexture.h" FTextureManager TexMan; @@ -96,6 +98,7 @@ FTextureManager::~FTextureManager () void FTextureManager::DeleteAll() { + FImageSource::ClearImages(); for (unsigned int i = 0; i < Textures.Size(); ++i) { delete Textures[i].Texture; @@ -595,7 +598,7 @@ void FTextureManager::AddHiresTextures (int wadnum) // //========================================================================== -void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) +void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname, FMultipatchTextureBuilder &build) { int remapLump, lastLump; @@ -605,12 +608,12 @@ void FTextureManager::LoadTextureDefs(int wadnum, const char *lumpname) { if (Wads.GetLumpFile(remapLump) == wadnum) { - ParseTextureDef(remapLump); + ParseTextureDef(remapLump, build); } } } -void FTextureManager::ParseTextureDef(int lump) +void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build) { TArray tlist; @@ -728,23 +731,23 @@ void FTextureManager::ParseTextureDef(int lump) } else if (sc.Compare("texture")) { - ParseXTexture(sc, ETextureType::Override); + build.ParseTexture(sc, ETextureType::Override); } else if (sc.Compare("sprite")) { - ParseXTexture(sc, ETextureType::Sprite); + build.ParseTexture(sc, ETextureType::Sprite); } else if (sc.Compare("walltexture")) { - ParseXTexture(sc, ETextureType::Wall); + build.ParseTexture(sc, ETextureType::Wall); } else if (sc.Compare("flat")) { - ParseXTexture(sc, ETextureType::Flat); + build.ParseTexture(sc, ETextureType::Flat); } else if (sc.Compare("graphic")) { - ParseXTexture(sc, ETextureType::MiscPatch); + build.ParseTexture(sc, ETextureType::MiscPatch); } else if (sc.Compare("#include")) { @@ -758,7 +761,7 @@ void FTextureManager::ParseTextureDef(int lump) } else { - ParseTextureDef(includelump); + ParseTextureDef(includelump, build); } } else @@ -804,7 +807,7 @@ void FTextureManager::AddPatches (int lumpnum) // //========================================================================== -void FTextureManager::LoadTextureX(int wadnum) +void FTextureManager::LoadTextureX(int wadnum, FMultipatchTextureBuilder &build) { // Use the most recent PNAMES for this WAD. // Multiple PNAMES in a WAD will be ignored. @@ -822,7 +825,7 @@ void FTextureManager::LoadTextureX(int wadnum) int texlump1 = Wads.CheckNumForName ("TEXTURE1", ns_global, wadnum); int texlump2 = Wads.CheckNumForName ("TEXTURE2", ns_global, wadnum); - AddTexturesLumps (texlump1, texlump2, pnames); + build.AddTexturesLumps (texlump1, texlump2, pnames); } //========================================================================== @@ -831,7 +834,7 @@ void FTextureManager::LoadTextureX(int wadnum) // //========================================================================== -void FTextureManager::AddTexturesForWad(int wadnum) +void FTextureManager::AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &build) { int firsttexture = Textures.Size(); int lumpcount = Wads.GetNumLumps(); @@ -846,7 +849,7 @@ void FTextureManager::AddTexturesForWad(int wadnum) AddGroup(wadnum, ns_patches, ETextureType::WallPatch); // Second step: TEXTUREx lumps - LoadTextureX(wadnum); + LoadTextureX(wadnum, build); // Third step: Flats AddGroup(wadnum, ns_flats, ETextureType::Flat); @@ -917,8 +920,8 @@ void FTextureManager::AddTexturesForWad(int wadnum) } // Check for text based texture definitions - LoadTextureDefs(wadnum, "TEXTURES"); - LoadTextureDefs(wadnum, "HIRESTEX"); + LoadTextureDefs(wadnum, "TEXTURES", build); + LoadTextureDefs(wadnum, "HIRESTEX", build); // Seventh step: Check for hires replacements. AddHiresTextures(wadnum); @@ -1007,14 +1010,14 @@ void FTextureManager::Init() AddTexture(CreateShaderTexture(true, true)); int wadcnt = Wads.GetNumWads(); + + FMultipatchTextureBuilder build(*this); + for(int i = 0; i< wadcnt; i++) { - AddTexturesForWad(i); - } - for (unsigned i = 0; i < Textures.Size(); i++) - { - Textures[i].Texture->ResolvePatches(); + AddTexturesForWad(i, build); } + build.ResolveAllPatches(); // Add one marker so that the last WAD is easier to handle and treat // Build tiles as a completely separate block. diff --git a/src/textures/textures.h b/src/textures/textures.h index 199b7389d..c1a08abca 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -48,6 +48,7 @@ #define MAX_CUSTOM_HW_SHADER_TEXTURES 15 typedef TMap SpriteHits; +class FImageSource; enum MaterialShaderIndex { @@ -230,6 +231,7 @@ class FTexture friend void R_InitSpriteDefs (); friend void R_InstallSprite (int num, spriteframewithrotate *sprtemp, int &maxframe); friend class GLDefsParser; + friend class FMultipatchTextureBuilder; // The serializer also needs access to more specific info that shouldn't be accessible through the interface. friend FSerializer &Serialize(FSerializer &arc, const char *key, FTextureID &value, FTextureID *defval); @@ -252,6 +254,7 @@ public: static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype); static FTexture *CreateTexture(int lumpnum, ETextureType usetype); virtual ~FTexture (); + virtual FImageSource *GetImage() const { return nullptr; } void AddAutoMaterials(); unsigned char *CreateUpsampledTextureBuffer(unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight, bool hasAlpha); @@ -298,6 +301,7 @@ public: bool isFullbright() const { return bFullbright; } void CreateDefaultBrightmap(); bool FindHoles(const unsigned char * buffer, int w, int h); + void SetUseType(ETextureType type) { UseType = type; } // Returns the whole texture, stored in column-major order virtual TArray Get8BitPixels(bool alphatex); @@ -393,9 +397,6 @@ protected: virtual int CopyPixels(FBitmap *bmp); int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); - virtual bool UseBasePalette(); - virtual FTexture *GetRedirect(); - void SetSpeed(float fac) { shaderspeed = fac; } int GetWidth () { return Width; } @@ -438,8 +439,6 @@ protected: virtual void SetFrontSkyLayer(); - void CopyToBlock (uint8_t *dest, int dwidth, int dheight, int x, int y, int rotate, const uint8_t *translation, bool style); - static void InitGrayMap(); void CopySize(FTexture *BaseTexture) @@ -566,14 +565,11 @@ public: FTextureID GetTextureID (const char *name, ETextureType usetype, BITFIELD flags=0); int ListTextures (const char *name, TArray &list, bool listall = false); - void AddTexturesLump (const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup=0, bool texture1=false); - void AddTexturesLumps (int lump1, int lump2, int patcheslump); void AddGroup(int wadnum, int ns, ETextureType usetype); void AddPatches (int lumpnum); void AddHiresTextures (int wadnum); - void LoadTextureDefs(int wadnum, const char *lumpname); - void ParseTextureDef(int remapLump); - void ParseXTexture(FScanner &sc, ETextureType usetype); + void LoadTextureDefs(int wadnum, const char *lumpname, FMultipatchTextureBuilder &build); + void ParseTextureDef(int remapLump, FMultipatchTextureBuilder &build); void SortTexturesByType(int start, int end); bool AreTexturesCompatible (FTextureID picnum1, FTextureID picnum2); @@ -581,8 +577,8 @@ public: FTextureID AddTexture (FTexture *texture); FTextureID GetDefaultTexture() const { return DefaultTexture; } - void LoadTextureX(int wadnum); - void AddTexturesForWad(int wadnum); + void LoadTextureX(int wadnum, FMultipatchTextureBuilder &build); + void AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &build); void Init(); void DeleteAll(); void SpriteAdjustChanged(); From 9e250253150f8a98338b1ea8e5756f7734d5564f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 9 Dec 2018 15:41:02 +0100 Subject: [PATCH 23/66] - missed this new file. --- src/textures/formats/multipatchtexture.h | 113 +++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 src/textures/formats/multipatchtexture.h diff --git a/src/textures/formats/multipatchtexture.h b/src/textures/formats/multipatchtexture.h new file mode 100644 index 000000000..28ff8dcc3 --- /dev/null +++ b/src/textures/formats/multipatchtexture.h @@ -0,0 +1,113 @@ +#pragma once + +//========================================================================== +// +// TexPart is the data that will get passed to the final texture. +// +//========================================================================== + +struct TexPart +{ + FRemapTable *Translation = nullptr; + FImageSource *Image = nullptr; + PalEntry Blend = 0; + blend_t Alpha = FRACUNIT; + int16_t OriginX = 0; + int16_t OriginY = 0; + uint8_t Rotate = 0; + uint8_t op = OP_COPY; +}; + + + +//========================================================================== +// +// A texture defined in a TEXTURE1 or TEXTURE2 lump +// +//========================================================================== + +class FMultiPatchTexture : public FImageSource +{ +public: + FMultiPatchTexture(int w, int h, const TArray &parts, bool complex, bool textual); + +protected: + int NumParts; + bool bComplex; + bool bTextual; + TexPart *Parts; + + // The getters must optionally redirect if it's a simple one-patch texture. + int CopyPixels(FBitmap *bmp, int conversion) override; + TArray GetPalettedPixels(int conversion) override; + void CopyToBlock(uint8_t *dest, int dwidth, int dheight, FImageSource *source, int xpos, int ypos, int rotate, const uint8_t *translation, int style); +}; + + +//========================================================================== +// +// Additional data per patch which is needed for initialization +// +//========================================================================== + +struct TexInit +{ + FString TexName; + ETextureType UseType = ETextureType::Null; + FTexture *Texture = nullptr; + bool Silent = false; + bool HasLine = false; + bool UseOffsets = false; + FScriptPosition sc; +}; + +//========================================================================== +// +// All build info only needed to construct the multipatch textures +// +//========================================================================== + +struct FPatchLookup; + +struct BuildInfo +{ + FString Name; + TArray Parts; + TArray Inits; + int Width = 0; + int Height = 0; + DVector2 Scale = { 1, 1 }; + bool bWorldPanning = false; // This sucks! + int DefinitionLump = 0; + bool bComplex = false; + bool textual = false; + bool bNoDecals = false; + int LeftOffset[2] = {}; + int TopOffset[2] = {}; + FTextureID id = {}; + FImageTexture *tex = nullptr; +}; + +class FMultipatchTextureBuilder +{ + FTextureManager &TexMan; + TArray BuiltTextures; + + void MakeTexture(BuildInfo &buildinfo, ETextureType usetype); + + void BuildTexture(const void *texdef, FPatchLookup *patchlookup, int maxpatchnum, bool strife, int deflumpnum, ETextureType usetyoe); + void AddTexturesLump(const void *lumpdata, int lumpsize, int deflumpnum, int patcheslump, int firstdup, bool texture1); + + void ParsePatch(FScanner &sc, BuildInfo &info, TexPart &part, TexInit &init); + void CheckForHacks(BuildInfo &buildinfo); + void ResolvePatches(BuildInfo &buildinfo); + +public: + FMultipatchTextureBuilder(FTextureManager &texMan) : TexMan(texMan) + { + } + + void AddTexturesLumps(int lump1, int lump2, int patcheslump); + void ParseTexture(FScanner &sc, ETextureType usetype); + void ResolveAllPatches(); +}; From 34884e2756058950a7df3d940244ee5918a64d77 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 9 Dec 2018 16:00:27 +0100 Subject: [PATCH 24/66] - base FFontChar1 and FFontChar2 on FImageSource as well. Now the only textures not being backed by an image source that are actually getting used during normal rendering are the canvas textures. --- src/CMakeLists.txt | 1 + src/textures/formats/fontchars.cpp | 252 +++++++++++++++++++++++++ src/textures/formats/fontchars.h | 30 +++ src/textures/image.h | 9 + src/textures/imagetexture.cpp | 21 +++ src/v_font.cpp | 289 +++-------------------------- 6 files changed, 341 insertions(+), 261 deletions(-) create mode 100644 src/textures/formats/fontchars.cpp create mode 100644 src/textures/formats/fontchars.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 98d220e9d..d43c03f36 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1109,6 +1109,7 @@ set (PCH_SOURCES textures/formats/canvastexture.cpp textures/formats/ddstexture.cpp textures/formats/flattexture.cpp + textures/formats/fontchars.cpp textures/formats/imgztexture.cpp textures/formats/jpegtexture.cpp textures/formats/md5check.cpp diff --git a/src/textures/formats/fontchars.cpp b/src/textures/formats/fontchars.cpp new file mode 100644 index 000000000..3573ab892 --- /dev/null +++ b/src/textures/formats/fontchars.cpp @@ -0,0 +1,252 @@ +/* +** fontchars.cpp +** Texture class for font characters +** +**--------------------------------------------------------------------------- +** Copyright 2004-2006 Randy Heit +** Copyright 2006-2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "doomtype.h" +#include "w_wad.h" +#include "v_palette.h" +#include "v_video.h" +#include "bitmap.h" +#include "image.h" +#include "imagehelpers.h" +#include "fontchars.h" + +//========================================================================== +// +// FFontChar1 :: FFontChar1 +// +// Used by fonts made from textures. +// +//========================================================================== + +FFontChar1::FFontChar1 (FImageSource *sourcelump) +: BaseTexture(sourcelump), SourceRemap (nullptr) +{ + // now copy all the properties from the base texture + assert(BaseTexture != nullptr); + CopySize(*BaseTexture); + bUseGamePalette = false; +} + +//========================================================================== +// +// FFontChar1 :: GetPixels +// +// Render style is not relevant for fonts. This must not use it! +// +//========================================================================== + +TArray FFontChar1::GetPalettedPixels (int) +{ + // Make the texture as normal, then remap it so that all the colors + // are at the low end of the palette + // Why? It only creates unnecessary work! + auto Pixels = BaseTexture->GetPalettedPixels(normal); + + if (SourceRemap) + { + for (int x = 0; x < Width*Height; ++x) + { + Pixels[x] = SourceRemap[Pixels[x]]; + } + } + return Pixels; +} + +//========================================================================== +// +// FFontChar1 :: SetSourceRemap +// +//========================================================================== + +void FFontChar1::SetSourceRemap(const uint8_t *sourceremap) +{ + SourceRemap = sourceremap; +} + +//========================================================================== +// +// FFontChar2 :: FFontChar2 +// +// Used by FON1 and FON2 fonts. +// +//========================================================================== + +FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs) +: SourceLump (sourcelump), SourcePos (sourcepos), SourceRemap(nullptr) +{ + Width = width; + Height = height; + LeftOffset = leftofs; + TopOffset = topofs; +} + +//========================================================================== +// +// FFontChar2 :: SetSourceRemap +// +//========================================================================== + +void FFontChar2::SetSourceRemap(const uint8_t *sourceremap) +{ + SourceRemap = sourceremap; +} + +//========================================================================== +// +// FFontChar2 :: Get8BitPixels +// +// Like for FontChar1, the render style has no relevance here as well. +// +//========================================================================== + +TArray FFontChar2::GetPalettedPixels(int) +{ + auto lump = Wads.OpenLumpReader (SourceLump); + int destSize = Width * Height; + uint8_t max = 255; + bool rle = true; + + // This is to "fix" bad fonts + { + uint8_t buff[16]; + lump.Read (buff, 4); + if (buff[3] == '2') + { + lump.Read (buff, 7); + max = buff[6]; + lump.Seek (SourcePos - 11, FileReader::SeekCur); + } + else if (buff[3] == 0x1A) + { + lump.Read(buff, 13); + max = buff[12] - 1; + lump.Seek (SourcePos - 17, FileReader::SeekCur); + rle = false; + } + else + { + lump.Seek (SourcePos - 4, FileReader::SeekCur); + } + } + + TArray Pixels(destSize, true); + + int runlen = 0, setlen = 0; + uint8_t setval = 0; // Shut up, GCC! + uint8_t *dest_p = Pixels.Data(); + int dest_adv = Height; + int dest_rew = destSize - 1; + + if (rle) + { + for (int y = Height; y != 0; --y) + { + for (int x = Width; x != 0; ) + { + if (runlen != 0) + { + uint8_t color = lump.ReadUInt8(); + color = MIN (color, max); + if (SourceRemap != nullptr) + { + color = SourceRemap[color]; + } + *dest_p = color; + dest_p += dest_adv; + x--; + runlen--; + } + else if (setlen != 0) + { + *dest_p = setval; + dest_p += dest_adv; + x--; + setlen--; + } + else + { + int8_t code = lump.ReadInt8(); + if (code >= 0) + { + runlen = code + 1; + } + else if (code != -128) + { + uint8_t color = lump.ReadUInt8(); + setlen = (-code) + 1; + setval = MIN (color, max); + if (SourceRemap != nullptr) + { + setval = SourceRemap[setval]; + } + } + } + } + dest_p -= dest_rew; + } + } + else + { + for (int y = Height; y != 0; --y) + { + for (int x = Width; x != 0; --x) + { + uint8_t color = lump.ReadUInt8(); + if (color > max) + { + color = max; + } + if (SourceRemap != nullptr) + { + color = SourceRemap[color]; + } + *dest_p = color; + dest_p += dest_adv; + } + dest_p -= dest_rew; + } + } + + if (destSize < 0) + { + char name[9]; + Wads.GetLumpName (name, SourceLump); + name[8] = 0; + I_FatalError ("The font %s is corrupt", name); + } + return Pixels; +} + diff --git a/src/textures/formats/fontchars.h b/src/textures/formats/fontchars.h new file mode 100644 index 000000000..644372b77 --- /dev/null +++ b/src/textures/formats/fontchars.h @@ -0,0 +1,30 @@ + + +// This is a font character that loads a texture and recolors it. +class FFontChar1 : public FImageSource +{ +public: + FFontChar1 (FImageSource *sourcelump); + TArray GetPalettedPixels(int conversion) override; + void SetSourceRemap(const uint8_t *sourceremap); + +protected: + + FImageSource *BaseTexture; + const uint8_t *SourceRemap; +}; + +// This is a font character that reads RLE compressed data. +class FFontChar2 : public FImageSource +{ +public: + FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); + + TArray GetPalettedPixels(int conversion) override; + void SetSourceRemap(const uint8_t *sourceremap); + +protected: + int SourceLump; + int SourcePos; + const uint8_t *SourceRemap; +}; diff --git a/src/textures/image.h b/src/textures/image.h index e53505acb..8c9b314b6 100644 --- a/src/textures/image.h +++ b/src/textures/image.h @@ -21,6 +21,15 @@ protected: public: + void CopySize(FImageSource &other) + { + Width = other.Width; + Height = other.Height; + LeftOffset = other.LeftOffset; + TopOffset = other.TopOffset; + SourceLump = other.SourceLump; + } + // Images are statically allocated and freed in bulk. None of the subclasses may hold any destructible data. void *operator new(size_t block) { return ImageArena.Alloc(block); } void operator delete(void *block) {} diff --git a/src/textures/imagetexture.cpp b/src/textures/imagetexture.cpp index 9afdec41a..d4e8ce953 100644 --- a/src/textures/imagetexture.cpp +++ b/src/textures/imagetexture.cpp @@ -89,3 +89,24 @@ TArray FImageTexture::Get8BitPixels(bool alpha) return mImage->GetPalettedPixels(alpha? alpha : bNoRemap0 ? FImageSource::noremap0 : FImageSource::normal); } +//========================================================================== +// +// FMultiPatchTexture :: GetRawTexture +// +// Doom ignored all compositing of mid-sided textures on two-sided lines. +// Since these textures had to be single-patch in Doom, that essentially +// means it ignores their Y offsets. +// +// If this texture is composed of only one patch, return that patch. +// Otherwise, return this texture, since Doom wouldn't have been able to +// draw it anyway. +// +//========================================================================== + +/* todo: this needs to be reimplemented without assuming that the underlying patch will be usable as-is. +FTexture *FMultiPatchTexture::GetRawTexture() +{ + return NumParts == 1 && UseType == ETextureType::Wall && bMultiPatch == 1 && Scale == Parts->Texture->Scale ? Parts->Texture : this; +} +*/ + diff --git a/src/v_font.cpp b/src/v_font.cpp index bd9efebde..ffcb0bec4 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -90,13 +90,15 @@ The FON2 header is followed by variable length data: #include "gstrings.h" #include "v_text.h" #include "vm.h" +#include "image.h" +#include "textures/formats/fontchars.h" // MACROS ------------------------------------------------------------------ #define DEFAULT_LOG_COLOR PalEntry(223,223,223) // TYPES ------------------------------------------------------------------- -void RecordTextureColors (FTexture *pic, uint8_t *colorsused); +void RecordTextureColors (FImageSource *pic, uint8_t *colorsused); // This structure is used by BuildTranslations() to hold color information. struct TranslationParm @@ -166,37 +168,6 @@ protected: bool notranslate[256]; }; -// This is a font character that loads a texture and recolors it. -class FFontChar1 : public FTexture -{ -public: - FFontChar1 (FTexture *sourcelump); - TArray Get8BitPixels(bool alphatex) override; - void SetSourceRemap(const uint8_t *sourceremap); - -protected: - - FTexture *BaseTexture; - const uint8_t *SourceRemap; -}; - -// This is a font character that reads RLE compressed data. -class FFontChar2 : public FTexture -{ -public: - FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); - - TArray Get8BitPixels(bool alphatex) override; - void SetSourceRemap(const uint8_t *sourceremap); - -protected: - int SourceLump; - int SourcePos; - const uint8_t *SourceRemap; - - void MakeTexture (); -}; - struct TempParmInfo { unsigned int StartParm[2]; @@ -410,7 +381,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, if (charLumps[i] != nullptr) { - if (!noTranslate) Chars[i].Pic = new FFontChar1 (charLumps[i]); + if (!noTranslate) Chars[i].Pic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage())); else Chars[i].Pic = charLumps[i]; Chars[i].XMove = Chars[i].Pic->GetDisplayWidth(); } @@ -520,11 +491,11 @@ FFont *FFont::FindFont (FName name) // //========================================================================== -void RecordTextureColors (FTexture *pic, uint8_t *usedcolors) +void RecordTextureColors (FImageSource *pic, uint8_t *usedcolors) { int x; - auto pixels = pic->Get8BitPixels(false); + auto pixels = pic->GetPalettedPixels(false); auto size = pic->GetWidth() * pic->GetHeight(); for(x = 0;x < size; x++) @@ -899,11 +870,14 @@ void FFont::LoadTranslations() memset (usedcolors, 0, 256); for (unsigned int i = 0; i < count; i++) { - FFontChar1 *pic = static_cast(Chars[i].Pic); - if(pic) + if (Chars[i].Pic) { - pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture - RecordTextureColors (pic, usedcolors); + FFontChar1 *pic = static_cast(Chars[i].Pic->GetImage()); + if (pic) + { + pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture + RecordTextureColors(pic, usedcolors); + } } } @@ -914,7 +888,7 @@ void FFont::LoadTranslations() for (unsigned int i = 0; i < count; i++) { if(Chars[i].Pic) - static_cast(Chars[i].Pic)->SetSourceRemap(PatchRemap); + static_cast(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); } BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL); @@ -1045,7 +1019,7 @@ void FSingleLumpFont::LoadTranslations() for(unsigned int i = 0;i < count;++i) { if(Chars[i].Pic) - static_cast(Chars[i].Pic)->SetSourceRemap(PatchRemap); + static_cast(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); } BuildTranslations (luminosity, useidentity ? identity : NULL, ranges, ActiveColors, usepalette ? local_palette : NULL); @@ -1170,7 +1144,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data) } else { - Chars[i].Pic = new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight); + Chars[i].Pic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)); do { int8_t code = *data_p++; @@ -1306,12 +1280,12 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) { // Empty character: skip it. continue; } - Chars[chardata[chari] - FirstChar].Pic = new FFontChar2(lump, int(chardata + chari + 6 - data), + Chars[chardata[chari] - FirstChar].Pic = new FImageTexture(new FFontChar2(lump, int(chardata + chari + 6 - data), chardata[chari+1], // width chardata[chari+2], // height -(int8_t)chardata[chari+3], // x offset -(int8_t)chardata[chari+4] // y offset - ); + )); } // If the font did not define a space character, determine a suitable space width now. @@ -1376,7 +1350,7 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity) if(!Chars[i].Pic) { - Chars[i].Pic = new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight); + Chars[i].Pic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)); Chars[i].XMove = SpaceWidth; } @@ -1538,216 +1512,6 @@ int FSinglePicFont::GetCharWidth (int code) const return SpaceWidth; } -//========================================================================== -// -// FFontChar1 :: FFontChar1 -// -// Used by fonts made from textures. -// -//========================================================================== - -FFontChar1::FFontChar1 (FTexture *sourcelump) -: SourceRemap (NULL) -{ - UseType = ETextureType::FontChar; - BaseTexture = sourcelump; - - // now copy all the properties from the base texture - assert(BaseTexture != NULL); - CopySize(BaseTexture); -} - -//========================================================================== -// -// FFontChar1 :: GetPixels -// -// Render style is not relevant for fonts. This must not use it! -// -//========================================================================== - -TArray FFontChar1::Get8BitPixels (bool) -{ - // Make the texture as normal, then remap it so that all the colors - // are at the low end of the palette - // Why? It only creates unnecessary work! - auto Pixels = BaseTexture->Get8BitPixels(false); - - if (SourceRemap) - { - for (int x = 0; x < Width*Height; ++x) - { - Pixels[x] = SourceRemap[Pixels[x]]; - } - } - return Pixels; -} - -//========================================================================== -// -// FFontChar1 :: SetSourceRemap -// -//========================================================================== - -void FFontChar1::SetSourceRemap(const uint8_t *sourceremap) -{ - SourceRemap = sourceremap; -} - -//========================================================================== -// -// FFontChar2 :: FFontChar2 -// -// Used by FON1 and FON2 fonts. -// -//========================================================================== - -FFontChar2::FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs, int topofs) -: SourceLump (sourcelump), SourcePos (sourcepos), SourceRemap(NULL) -{ - UseType = ETextureType::FontChar; - Width = width; - Height = height; - _LeftOffset[1] = _LeftOffset[0] = leftofs; - _TopOffset[1] = _TopOffset[0] = topofs; -} - -//========================================================================== -// -// FFontChar2 :: SetSourceRemap -// -//========================================================================== - -void FFontChar2::SetSourceRemap(const uint8_t *sourceremap) -{ - SourceRemap = sourceremap; -} - -//========================================================================== -// -// FFontChar2 :: Get8BitPixels -// -// Like for FontChar1, the render style has no relevance here as well. -// -//========================================================================== - -TArray FFontChar2::Get8BitPixels(bool) -{ - auto lump = Wads.OpenLumpReader (SourceLump); - int destSize = Width * Height; - uint8_t max = 255; - bool rle = true; - - // This is to "fix" bad fonts - { - uint8_t buff[16]; - lump.Read (buff, 4); - if (buff[3] == '2') - { - lump.Read (buff, 7); - max = buff[6]; - lump.Seek (SourcePos - 11, FileReader::SeekCur); - } - else if (buff[3] == 0x1A) - { - lump.Read(buff, 13); - max = buff[12] - 1; - lump.Seek (SourcePos - 17, FileReader::SeekCur); - rle = false; - } - else - { - lump.Seek (SourcePos - 4, FileReader::SeekCur); - } - } - - TArray Pixels(destSize, true); - - int runlen = 0, setlen = 0; - uint8_t setval = 0; // Shut up, GCC! - uint8_t *dest_p = Pixels.Data(); - int dest_adv = Height; - int dest_rew = destSize - 1; - - if (rle) - { - for (int y = Height; y != 0; --y) - { - for (int x = Width; x != 0; ) - { - if (runlen != 0) - { - uint8_t color = lump.ReadUInt8(); - color = MIN (color, max); - if (SourceRemap != NULL) - { - color = SourceRemap[color]; - } - *dest_p = color; - dest_p += dest_adv; - x--; - runlen--; - } - else if (setlen != 0) - { - *dest_p = setval; - dest_p += dest_adv; - x--; - setlen--; - } - else - { - int8_t code = lump.ReadInt8(); - if (code >= 0) - { - runlen = code + 1; - } - else if (code != -128) - { - uint8_t color = lump.ReadUInt8(); - setlen = (-code) + 1; - setval = MIN (color, max); - if (SourceRemap != NULL) - { - setval = SourceRemap[setval]; - } - } - } - } - dest_p -= dest_rew; - } - } - else - { - for (int y = Height; y != 0; --y) - { - for (int x = Width; x != 0; --x) - { - uint8_t color = lump.ReadUInt8(); - if (color > max) - { - color = max; - } - if (SourceRemap != NULL) - { - color = SourceRemap[color]; - } - *dest_p = color; - dest_p += dest_adv; - } - dest_p -= dest_rew; - } - } - - if (destSize < 0) - { - char name[9]; - Wads.GetLumpName (name, SourceLump); - name[8] = 0; - I_FatalError ("The font %s is corrupt", name); - } - return Pixels; -} - //========================================================================== // // FSpecialFont :: FSpecialFont @@ -1798,7 +1562,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l if (charlumps[i] != NULL) { - if (!noTranslate) Chars[i].Pic = new FFontChar1 (charlumps[i]); + if (!noTranslate) Chars[i].Pic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage())); else Chars[i].Pic = charlumps[i]; Chars[i].XMove = Chars[i].Pic->GetDisplayWidth(); } @@ -1850,11 +1614,14 @@ void FSpecialFont::LoadTranslations() memset (usedcolors, 0, 256); for (i = 0; i < count; i++) { - FFontChar1 *pic = static_cast(Chars[i].Pic); - if(pic) + if (Chars[i].Pic) { - pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture - RecordTextureColors (pic, usedcolors); + FFontChar1 *pic = static_cast(Chars[i].Pic->GetImage()); + if (pic) + { + pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture + RecordTextureColors(pic, usedcolors); + } } } @@ -1879,7 +1646,7 @@ void FSpecialFont::LoadTranslations() for (i = 0; i < count; i++) { if(Chars[i].Pic) - static_cast(Chars[i].Pic)->SetSourceRemap(PatchRemap); + static_cast(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); } BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL); From 5448874c6eb4b9fbe6405ea320fd048b9fa9e6df Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 9 Dec 2018 17:10:51 +0100 Subject: [PATCH 25/66] - moved image format detection logic from FTexture to FImageSource. --- src/textures/formats/automaptexture.cpp | 4 +- src/textures/formats/ddstexture.cpp | 4 +- src/textures/formats/emptytexture.cpp | 4 +- src/textures/formats/flattexture.cpp | 4 +- src/textures/formats/imgztexture.cpp | 4 +- src/textures/formats/jpegtexture.cpp | 4 +- src/textures/formats/patchtexture.cpp | 4 +- src/textures/formats/pcxtexture.cpp | 4 +- src/textures/formats/pngtexture.cpp | 4 +- src/textures/formats/rawpagetexture.cpp | 4 +- src/textures/formats/tgatexture.cpp | 4 +- src/textures/hires/hirestex.cpp | 3 +- src/textures/image.cpp | 80 ++++++++++++++++++++ src/textures/image.h | 11 ++- src/textures/texture.cpp | 98 +++++++------------------ src/textures/texturemanager.cpp | 15 ++-- src/textures/textures.h | 1 - src/w_wad.h | 1 - 18 files changed, 145 insertions(+), 108 deletions(-) diff --git a/src/textures/formats/automaptexture.cpp b/src/textures/formats/automaptexture.cpp index 80395b8ee..299727d83 100644 --- a/src/textures/formats/automaptexture.cpp +++ b/src/textures/formats/automaptexture.cpp @@ -64,11 +64,11 @@ public: // //========================================================================== -FTexture *AutomapTexture_TryCreate(FileReader &data, int lumpnum) +FImageSource *AutomapImage_TryCreate(FileReader &data, int lumpnum) { if (data.GetLength() < 320) return nullptr; if (!Wads.CheckLumpName(lumpnum, "AUTOPAGE")) return nullptr; - return new FImageTexture(new FAutomapTexture(lumpnum)); + return new FAutomapTexture(lumpnum); } //========================================================================== diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index 31ec4f01f..810f91fe2 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -218,7 +218,7 @@ static bool CheckDDS (FileReader &file) // //========================================================================== -FTexture *DDSTexture_TryCreate (FileReader &data, int lumpnum) +FImageSource *DDSImage_TryCreate (FileReader &data, int lumpnum) { union { @@ -273,7 +273,7 @@ FTexture *DDSTexture_TryCreate (FileReader &data, int lumpnum) { return NULL; } - return new FImageTexture(new FDDSTexture (data, lumpnum, &surfdesc)); + return new FDDSTexture (data, lumpnum, &surfdesc); } //========================================================================== diff --git a/src/textures/formats/emptytexture.cpp b/src/textures/formats/emptytexture.cpp index fe8c1e901..11710f226 100644 --- a/src/textures/formats/emptytexture.cpp +++ b/src/textures/formats/emptytexture.cpp @@ -60,7 +60,7 @@ public: // //========================================================================== -FTexture *EmptyTexture_TryCreate(FileReader & file, int lumpnum) +FImageSource *EmptyImage_TryCreate(FileReader & file, int lumpnum) { char check[8]; if (file.GetLength() != 8) return NULL; @@ -68,7 +68,7 @@ FTexture *EmptyTexture_TryCreate(FileReader & file, int lumpnum) if (file.Read(check, 8) != 8) return NULL; if (memcmp(check, "\0\0\0\0\0\0\0\0", 8)) return NULL; - return new FImageTexture(new FEmptyTexture(lumpnum)); + return new FEmptyTexture(lumpnum); } //========================================================================== diff --git a/src/textures/formats/flattexture.cpp b/src/textures/formats/flattexture.cpp index c6ce44fb8..a0982645f 100644 --- a/src/textures/formats/flattexture.cpp +++ b/src/textures/formats/flattexture.cpp @@ -62,9 +62,9 @@ public: // //========================================================================== -FTexture *FlatTexture_TryCreate(FileReader & file, int lumpnum) +FImageSource *FlatImage_TryCreate(FileReader & file, int lumpnum) { - return new FImageTexture(new FFlatTexture(lumpnum)); + return new FFlatTexture(lumpnum); } //========================================================================== diff --git a/src/textures/formats/imgztexture.cpp b/src/textures/formats/imgztexture.cpp index e505c0714..681f39d97 100644 --- a/src/textures/formats/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -79,7 +79,7 @@ public: // //========================================================================== -FTexture *IMGZTexture_TryCreate(FileReader & file, int lumpnum) +FImageSource *IMGZImage_TryCreate(FileReader & file, int lumpnum) { uint32_t magic = 0; uint16_t w, h; @@ -94,7 +94,7 @@ FTexture *IMGZTexture_TryCreate(FileReader & file, int lumpnum) l = file.ReadInt16(); t = file.ReadInt16(); ispalette = checkIMGZPalette(file); - return new FImageTexture(new FIMGZTexture(lumpnum, w, h, l, t, !ispalette)); + return new FIMGZTexture(lumpnum, w, h, l, t, !ispalette); } //========================================================================== diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index b41549c02..451f91f15 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -195,7 +195,7 @@ public: // //========================================================================== -FTexture *JPEGTexture_TryCreate(FileReader & data, int lumpnum) +FImageSource *JPEGImage_TryCreate(FileReader & data, int lumpnum) { union { @@ -236,7 +236,7 @@ FTexture *JPEGTexture_TryCreate(FileReader & data, int lumpnum) { return NULL; } - return new FImageTexture(new FJPEGTexture (lumpnum, BigShort(first4bytes.w[1]), BigShort(first4bytes.w[0]))); + return new FJPEGTexture (lumpnum, BigShort(first4bytes.w[1]), BigShort(first4bytes.w[0])); } //========================================================================== diff --git a/src/textures/formats/patchtexture.cpp b/src/textures/formats/patchtexture.cpp index ca6e54755..7a5de9c31 100644 --- a/src/textures/formats/patchtexture.cpp +++ b/src/textures/formats/patchtexture.cpp @@ -125,7 +125,7 @@ static bool CheckIfPatch(FileReader & file, bool &isalpha) // //========================================================================== -FTexture *PatchTexture_TryCreate(FileReader & file, int lumpnum) +FImageSource *PatchImage_TryCreate(FileReader & file, int lumpnum) { patch_t header; bool isalpha; @@ -136,7 +136,7 @@ FTexture *PatchTexture_TryCreate(FileReader & file, int lumpnum) header.height = file.ReadUInt16(); header.leftoffset = file.ReadInt16(); header.topoffset = file.ReadInt16(); - return new FImageTexture(new FPatchTexture(lumpnum, &header, isalpha)); + return new FPatchTexture(lumpnum, &header, isalpha); } //========================================================================== diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index f2e9f828d..708f36d81 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -103,7 +103,7 @@ protected: // //========================================================================== -FTexture * PCXTexture_TryCreate(FileReader & file, int lumpnum) +FImageSource * PCXImage_TryCreate(FileReader & file, int lumpnum) { PCXHeader hdr; @@ -132,7 +132,7 @@ FTexture * PCXTexture_TryCreate(FileReader & file, int lumpnum) file.Seek(0, FileReader::SeekSet); file.Read(&hdr, sizeof(hdr)); - return new FImageTexture(new FPCXTexture(lumpnum, hdr)); + return new FPCXTexture(lumpnum, hdr); } //========================================================================== diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index 1990aa6cb..37272125e 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -82,7 +82,7 @@ protected: // //========================================================================== -FTexture *PNGTexture_TryCreate(FileReader & data, int lumpnum) +FImageSource *PNGImage_TryCreate(FileReader & data, int lumpnum) { union { @@ -141,7 +141,7 @@ FTexture *PNGTexture_TryCreate(FileReader & data, int lumpnum) } } - return new FImageTexture(new FPNGTexture (data, lumpnum, FString(), width, height, bitdepth, colortype, interlace)); + return new FPNGTexture (data, lumpnum, FString(), width, height, bitdepth, colortype, interlace); } //========================================================================== diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index 6fd805ff5..0edaa9497 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -137,10 +137,10 @@ static bool CheckIfRaw(FileReader & data) // //========================================================================== -FTexture *RawPageTexture_TryCreate(FileReader & file, int lumpnum) +FImageSource *RawPageImage_TryCreate(FileReader & file, int lumpnum) { if (!CheckIfRaw(file)) return nullptr; - return new FImageTexture(new FRawPageTexture(lumpnum)); + return new FRawPageTexture(lumpnum); } diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index 9bc8500f8..cfb0f4890 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -94,7 +94,7 @@ protected: // //========================================================================== -FTexture *TGATexture_TryCreate(FileReader & file, int lumpnum) +FImageSource *TGAImage_TryCreate(FileReader & file, int lumpnum) { TGAHeader hdr; @@ -119,7 +119,7 @@ FTexture *TGATexture_TryCreate(FileReader & file, int lumpnum) hdr.width = LittleShort(hdr.width); hdr.height = LittleShort(hdr.height); - return new FImageTexture(new FTGATexture(lumpnum, &hdr)); + return new FTGATexture(lumpnum, &hdr); } //========================================================================== diff --git a/src/textures/hires/hirestex.cpp b/src/textures/hires/hirestex.cpp index 7f65341ea..b2edce48c 100644 --- a/src/textures/hires/hirestex.cpp +++ b/src/textures/hires/hirestex.cpp @@ -367,8 +367,7 @@ unsigned char *FTexture::LoadHiresTexture(int *width, int *height) if (HiresLump >= 0) { - HiresTexture = FTexture::CreateTexture(HiresLump, ETextureType::Any); - HiresTexture->Name = ""; + HiresTexture = FTexture::CreateTexture("", HiresLump, ETextureType::Any); TexMan.AddTexture(HiresTexture); // let the texture manager manage this. } } diff --git a/src/textures/image.cpp b/src/textures/image.cpp index 7f246ba02..c5d29ae5f 100644 --- a/src/textures/image.cpp +++ b/src/textures/image.cpp @@ -37,8 +37,13 @@ #include "v_video.h" #include "bitmap.h" #include "image.h" +#include "w_wad.h" +#include "files.h" FMemArena FImageSource::ImageArena(32768); +TArrayFImageSource::ImageForLump; +int FImageSource::NextID; + //=========================================================================== // // the default just returns an empty texture. @@ -82,3 +87,78 @@ int FImageSource::CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap) bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, remap, nullptr); return 0; } + + +//========================================================================== +// +// +// +//========================================================================== + +typedef FImageSource * (*CreateFunc)(FileReader & file, int lumpnum); + +struct TexCreateInfo +{ + CreateFunc TryCreate; + ETextureType usetype; +}; + +FImageSource *IMGZImage_TryCreate(FileReader &, int lumpnum); +FImageSource *PNGImage_TryCreate(FileReader &, int lumpnum); +FImageSource *JPEGImage_TryCreate(FileReader &, int lumpnum); +FImageSource *DDSImage_TryCreate(FileReader &, int lumpnum); +FImageSource *PCXImage_TryCreate(FileReader &, int lumpnum); +FImageSource *TGAImage_TryCreate(FileReader &, int lumpnum); +FImageSource *RawPageImage_TryCreate(FileReader &, int lumpnum); +FImageSource *FlatImage_TryCreate(FileReader &, int lumpnum); +FImageSource *PatchImage_TryCreate(FileReader &, int lumpnum); +FImageSource *EmptyImage_TryCreate(FileReader &, int lumpnum); +FImageSource *AutomapImage_TryCreate(FileReader &, int lumpnum); + + +// Examines the lump contents to decide what type of texture to create, +// and creates the texture. +FImageSource * FImageSource::GetImage(int lumpnum, ETextureType usetype) +{ + static TexCreateInfo CreateInfo[] = { + { IMGZImage_TryCreate, ETextureType::Any }, + { PNGImage_TryCreate, ETextureType::Any }, + { JPEGImage_TryCreate, ETextureType::Any }, + { DDSImage_TryCreate, ETextureType::Any }, + { PCXImage_TryCreate, ETextureType::Any }, + { TGAImage_TryCreate, ETextureType::Any }, + { RawPageImage_TryCreate, ETextureType::MiscPatch }, + { FlatImage_TryCreate, ETextureType::Flat }, + { PatchImage_TryCreate, ETextureType::Any }, + { EmptyImage_TryCreate, ETextureType::Any }, + { AutomapImage_TryCreate, ETextureType::MiscPatch }, + }; + + if (lumpnum == -1) return nullptr; + + unsigned size = ImageForLump.Size(); + if (size <= (unsigned)lumpnum) + { + // Hires textures can be added dynamically to the end of the lump array, so this must be checked each time. + ImageForLump.Resize(lumpnum + 1); + for (; size < ImageForLump.Size(); size++) ImageForLump[size] = nullptr; + } + // An image for this lump already exists. We do not need another one. + if (ImageForLump[lumpnum] != nullptr) return ImageForLump[lumpnum]; + + auto data = Wads.OpenLumpReader(lumpnum); + + for (size_t i = 0; i < countof(CreateInfo); i++) + { + if ((CreateInfo[i].usetype == usetype || CreateInfo[i].usetype == ETextureType::Any)) + { + auto image = CreateInfo[i].TryCreate(data, lumpnum); + if (image != nullptr) + { + ImageForLump[lumpnum] = image; + return image; + } + } + } + return nullptr; +} diff --git a/src/textures/image.h b/src/textures/image.h index 8c9b314b6..7101c2816 100644 --- a/src/textures/image.h +++ b/src/textures/image.h @@ -14,10 +14,14 @@ class FImageSource protected: static FMemArena ImageArena; + static TArrayImageForLump; + static int NextID; + int SourceLump; int Width = 0, Height = 0; int LeftOffset = 0, TopOffset = 0; // Offsets stored in the image. bool bUseGamePalette = false; // true if this is an image without its own color set. + int ImageID = -1; public: @@ -41,8 +45,9 @@ public: virtual TArray GetPalettedPixels(int conversion); // 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture. virtual int CopyPixels(FBitmap *bmp, int conversion); // This will always ignore 'luminance'. int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); - static void ClearImages() { ImageArena.FreeAll(); } - + static void ClearImages() { ImageArena.FreeAll(); ImageForLump.Clear(); NextID = 0; } + static FImageSource * FImageSource::GetImage(int lumpnum, ETextureType usetype); + // Conversion option enum EType { @@ -51,7 +56,7 @@ public: noremap0 = 2 }; - FImageSource(int sourcelump = -1) : SourceLump(sourcelump) {} + FImageSource(int sourcelump = -1) : SourceLump(sourcelump) { ImageID = ++NextID; } virtual ~FImageSource() {} // Creates an image from the given lump. diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 934f585b3..55fe8334e 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -85,91 +85,45 @@ void FTexture::InitGrayMap() // //========================================================================== -typedef FTexture * (*CreateFunc)(FileReader & file, int lumpnum); - -struct TexCreateInfo -{ - CreateFunc TryCreate; - ETextureType usetype; -}; - -FTexture *IMGZTexture_TryCreate(FileReader &, int lumpnum); -FTexture *PNGTexture_TryCreate(FileReader &, int lumpnum); -FTexture *JPEGTexture_TryCreate(FileReader &, int lumpnum); -FTexture *DDSTexture_TryCreate(FileReader &, int lumpnum); -FTexture *PCXTexture_TryCreate(FileReader &, int lumpnum); -FTexture *TGATexture_TryCreate(FileReader &, int lumpnum); -FTexture *RawPageTexture_TryCreate(FileReader &, int lumpnum); -FTexture *FlatTexture_TryCreate(FileReader &, int lumpnum); -FTexture *PatchTexture_TryCreate(FileReader &, int lumpnum); -FTexture *EmptyTexture_TryCreate(FileReader &, int lumpnum); -FTexture *AutomapTexture_TryCreate(FileReader &, int lumpnum); - // Examines the lump contents to decide what type of texture to create, // and creates the texture. -FTexture * FTexture::CreateTexture (int lumpnum, ETextureType usetype) +FTexture * FTexture::CreateTexture(const char *name, int lumpnum, ETextureType usetype) { - static TexCreateInfo CreateInfo[]={ - { IMGZTexture_TryCreate, ETextureType::Any }, - { PNGTexture_TryCreate, ETextureType::Any }, - { JPEGTexture_TryCreate, ETextureType::Any }, - { DDSTexture_TryCreate, ETextureType::Any }, - { PCXTexture_TryCreate, ETextureType::Any }, - { TGATexture_TryCreate, ETextureType::Any }, - { RawPageTexture_TryCreate, ETextureType::MiscPatch }, - { FlatTexture_TryCreate, ETextureType::Flat }, - { PatchTexture_TryCreate, ETextureType::Any }, - { EmptyTexture_TryCreate, ETextureType::Any }, - { AutomapTexture_TryCreate, ETextureType::MiscPatch }, - }; + if (lumpnum == -1) return nullptr; - if (lumpnum == -1) return NULL; - - auto data = Wads.OpenLumpReader (lumpnum); - - for(size_t i = 0; i < countof(CreateInfo); i++) + auto image = FImageSource::GetImage(lumpnum, usetype); + if (image != nullptr) { - if ((CreateInfo[i].usetype == usetype || CreateInfo[i].usetype == ETextureType::Any)) + FTexture *tex = new FImageTexture(image); + if (tex != nullptr) { - FTexture * tex = CreateInfo[i].TryCreate(data, lumpnum); - if (tex != NULL) + tex->UseType = usetype; + if (usetype == ETextureType::Flat) { - tex->UseType = usetype; - if (usetype == ETextureType::Flat) - { - int w = tex->GetWidth(); - int h = tex->GetHeight(); + int w = tex->GetWidth(); + int h = tex->GetHeight(); - // Auto-scale flats with dimensions 128x128 and 256x256. - // In hindsight, a bad idea, but RandomLag made it sound better than it really is. - // Now we're stuck with this stupid behaviour. - if (w==128 && h==128) - { - tex->Scale.X = tex->Scale.Y = 2; - tex->bWorldPanning = true; - } - else if (w==256 && h==256) - { - tex->Scale.X = tex->Scale.Y = 4; - tex->bWorldPanning = true; - } + // Auto-scale flats with dimensions 128x128 and 256x256. + // In hindsight, a bad idea, but RandomLag made it sound better than it really is. + // Now we're stuck with this stupid behaviour. + if (w==128 && h==128) + { + tex->Scale.X = tex->Scale.Y = 2; + tex->bWorldPanning = true; + } + else if (w==256 && h==256) + { + tex->Scale.X = tex->Scale.Y = 4; + tex->bWorldPanning = true; } - return tex; } + tex->Name = name; + tex->Name.ToUpper(); + return tex; } } - return NULL; -} - -FTexture * FTexture::CreateTexture (const char *name, int lumpnum, ETextureType usetype) -{ - FTexture *tex = CreateTexture(lumpnum, usetype); - if (tex != NULL && name != NULL) { - tex->Name = name; - tex->Name.ToUpper(); - } - return tex; + return nullptr; } //========================================================================== diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index c21d9c623..66c43ac62 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -412,7 +412,9 @@ FTextureID FTextureManager::CreateTexture (int lumpnum, ETextureType usetype) { if (lumpnum != -1) { - FTexture *out = FTexture::CreateTexture(lumpnum, usetype); + FString str; + Wads.GetLumpName(str, lumpnum); + FTexture *out = FTexture::CreateTexture(str, lumpnum, usetype); if (out != NULL) return AddTexture (out); else @@ -559,7 +561,7 @@ void FTextureManager::AddHiresTextures (int wadnum) if (amount == 0) { // A texture with this name does not yet exist - FTexture * newtex = FTexture::CreateTexture (firsttx, ETextureType::Any); + FTexture * newtex = FTexture::CreateTexture (Name, firsttx, ETextureType::Any); if (newtex != NULL) { newtex->UseType=ETextureType::Override; @@ -570,7 +572,7 @@ void FTextureManager::AddHiresTextures (int wadnum) { for(unsigned int i = 0; i < tlist.Size(); i++) { - FTexture * newtex = FTexture::CreateTexture (firsttx, ETextureType::Any); + FTexture * newtex = FTexture::CreateTexture ("", firsttx, ETextureType::Any); if (newtex != NULL) { FTexture * oldtex = Textures[tlist[i].GetIndex()].Texture; @@ -669,7 +671,7 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build (sl=oldtex->GetSourceLump()) >= 0 && Wads.GetLumpNamespace(sl) == ns_sprites) ) { - FTexture * newtex = FTexture::CreateTexture (lumpnum, ETextureType::Any); + FTexture * newtex = FTexture::CreateTexture ("", lumpnum, ETextureType::Any); if (newtex != NULL) { // Replace the entire texture and adjust the scaling and offset factors. @@ -708,14 +710,13 @@ void FTextureManager::ParseTextureDef(int lump, FMultipatchTextureBuilder &build if (lumpnum>=0) { - FTexture *newtex = FTexture::CreateTexture(lumpnum, ETextureType::Override); + FTexture *newtex = FTexture::CreateTexture(src, lumpnum, ETextureType::Override); if (newtex != NULL) { // Replace the entire texture and adjust the scaling and offset factors. newtex->bWorldPanning = true; newtex->SetScaledSize(width, height); - newtex->Name = src; FTextureID oldtex = TexMan.CheckForTexture(src, ETextureType::MiscPatch); if (oldtex.isValid()) @@ -911,7 +912,7 @@ void FTextureManager::AddTexturesForWad(int wadnum, FMultipatchTextureBuilder &b // Try to create a texture from this lump and add it. // Unfortunately we have to look at everything that comes through here... - FTexture *out = FTexture::CreateTexture(i, skin ? ETextureType::SkinGraphic : ETextureType::MiscPatch); + FTexture *out = FTexture::CreateTexture(Name, i, skin ? ETextureType::SkinGraphic : ETextureType::MiscPatch); if (out != NULL) { diff --git a/src/textures/textures.h b/src/textures/textures.h index c1a08abca..ef154a9f6 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -252,7 +252,6 @@ class FTexture public: static FTexture *CreateTexture(const char *name, int lumpnum, ETextureType usetype); - static FTexture *CreateTexture(int lumpnum, ETextureType usetype); virtual ~FTexture (); virtual FImageSource *GetImage() const { return nullptr; } void AddAutoMaterials(); diff --git a/src/w_wad.h b/src/w_wad.h index a7009d65e..c223a6bd0 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -180,7 +180,6 @@ public: int GetNumWads () const; int AddExternalFile(const char *filename); - int AddData(const char *filename, int length); protected: From 796c0fe931dff1a5c10f5dc1259e80b8a3e1eda8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 10 Dec 2018 01:13:44 +0100 Subject: [PATCH 26/66] - fixed precaching to consider animations and switches --- src/p_setup.cpp | 57 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index b7489bf92..fa7de9d7f 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3408,6 +3408,45 @@ void P_GetPolySpots (MapData * map, TArray &spots, TAr //=========================================================================== void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitlist); +static void AddToList(uint8_t *hitlist, FTextureID texid, int bitmask) +{ + if (hitlist[texid.GetIndex()] & bitmask) return; // already done, no need to process everything again. + hitlist[texid.GetIndex()] |= (uint8_t)bitmask; + + for (auto anim : TexMan.mAnimations) + { + if (texid == anim->BasePic || (!anim->bDiscrete && anim->BasePic < texid && texid < anim->BasePic + anim->NumFrames)) + { + for (int i = anim->BasePic.GetIndex(); i < anim->BasePic.GetIndex() + anim->NumFrames; i++) + { + hitlist[i] |= (uint8_t)bitmask; + } + } + } + + auto switchdef = TexMan.FindSwitch(texid); + if (switchdef) + { + for (int i = 0; i < switchdef->NumFrames; i++) + { + hitlist[switchdef->frames[i].Texture.GetIndex()] |= (uint8_t)bitmask; + } + for (int i = 0; i < switchdef->PairDef->NumFrames; i++) + { + hitlist[switchdef->frames[i].Texture.GetIndex()] |= (uint8_t)bitmask; + } + } + + auto adoor = TexMan.FindAnimatedDoor(texid); + if (adoor) + { + for (int i = 0; i < adoor->NumTextureFrames; i++) + { + hitlist[adoor->TextureFrames[i].GetIndex()] |= (uint8_t)bitmask; + } + } +} + static void P_PrecacheLevel() { int i; @@ -3443,15 +3482,15 @@ static void P_PrecacheLevel() for (i = level.sectors.Size() - 1; i >= 0; i--) { - hitlist[level.sectors[i].GetTexture(sector_t::floor).GetIndex()] |= FTextureManager::HIT_Flat; - hitlist[level.sectors[i].GetTexture(sector_t::ceiling).GetIndex()] |= FTextureManager::HIT_Flat; + AddToList(hitlist, level.sectors[i].GetTexture(sector_t::floor), FTextureManager::HIT_Flat); + AddToList(hitlist, level.sectors[i].GetTexture(sector_t::ceiling), FTextureManager::HIT_Flat); } for (i = level.sides.Size() - 1; i >= 0; i--) { - hitlist[level.sides[i].GetTexture(side_t::top).GetIndex()] |= FTextureManager::HIT_Wall; - hitlist[level.sides[i].GetTexture(side_t::mid).GetIndex()] |= FTextureManager::HIT_Wall; - hitlist[level.sides[i].GetTexture(side_t::bottom).GetIndex()] |= FTextureManager::HIT_Wall; + AddToList(hitlist, level.sides[i].GetTexture(side_t::top), FTextureManager::HIT_Wall); + AddToList(hitlist, level.sides[i].GetTexture(side_t::mid), FTextureManager::HIT_Wall); + AddToList(hitlist, level.sides[i].GetTexture(side_t::bottom), FTextureManager::HIT_Wall); } // Sky texture is always present. @@ -3463,22 +3502,22 @@ static void P_PrecacheLevel() if (sky1texture.isValid()) { - hitlist[sky1texture.GetIndex()] |= FTextureManager::HIT_Sky; + AddToList(hitlist, sky1texture, FTextureManager::HIT_Sky); } if (sky2texture.isValid()) { - hitlist[sky2texture.GetIndex()] |= FTextureManager::HIT_Sky; + AddToList(hitlist, sky2texture, FTextureManager::HIT_Sky); } for (auto n : gameinfo.PrecachedTextures) { FTextureID tex = TexMan.CheckForTexture(n, ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ReturnFirst); - if (tex.Exists()) hitlist[tex.GetIndex()] |= FTextureManager::HIT_Wall; + if (tex.Exists()) AddToList(hitlist, tex, FTextureManager::HIT_Wall); } for (unsigned i = 0; i < level.info->PrecacheTextures.Size(); i++) { FTextureID tex = TexMan.CheckForTexture(level.info->PrecacheTextures[i], ETextureType::Wall, FTextureManager::TEXMAN_Overridable | FTextureManager::TEXMAN_TryAny | FTextureManager::TEXMAN_ReturnFirst); - if (tex.Exists()) hitlist[tex.GetIndex()] |= FTextureManager::HIT_Wall; + if (tex.Exists()) AddToList(hitlist, tex, FTextureManager::HIT_Wall); } // This is just a temporary solution, until the hardware renderer's texture manager is in a better state. From 2e7bcf9e415a2d4fbe2bda3c0f337de835edf04d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 10 Dec 2018 01:17:39 +0100 Subject: [PATCH 27/66] - implemented a proper texture composition cache. This will mostly ensure that each patch used for composition is only loaded once and automatically unloaded once no longer needed. So far only for paletted rendering, but the same logic can be used for true color as well. --- src/gl/system/gl_framebuffer.cpp | 9 +- src/gl/system/gl_framebuffer.h | 1 + src/gl/textures/gl_hwtexture.cpp | 25 ++++ src/gl/textures/gl_hwtexture.h | 1 + src/hwrenderer/textures/hw_precache.cpp | 29 ++++ src/r_data/models/models_voxel.cpp | 4 +- src/swrenderer/line/r_line.cpp | 1 + src/swrenderer/r_swrenderer.cpp | 32 ++++- src/swrenderer/r_swrenderer.h | 1 + src/swrenderer/textures/r_swtexture.h | 8 +- src/tarray.h | 14 +- src/textures/formats/automaptexture.cpp | 4 +- src/textures/formats/buildtexture.cpp | 4 +- src/textures/formats/ddstexture.cpp | 4 +- src/textures/formats/emptytexture.cpp | 4 +- src/textures/formats/flattexture.cpp | 4 +- src/textures/formats/fontchars.cpp | 6 +- src/textures/formats/fontchars.h | 4 +- src/textures/formats/imgztexture.cpp | 4 +- src/textures/formats/jpegtexture.cpp | 4 +- src/textures/formats/multipatchtexture.cpp | 32 ++++- src/textures/formats/multipatchtexture.h | 4 +- src/textures/formats/patchtexture.cpp | 4 +- src/textures/formats/pcxtexture.cpp | 4 +- src/textures/formats/pngtexture.cpp | 4 +- src/textures/formats/rawpagetexture.cpp | 4 +- src/textures/formats/shadertexture.cpp | 2 +- src/textures/formats/tgatexture.cpp | 4 +- src/textures/image.cpp | 151 ++++++++++++++++++++- src/textures/image.h | 41 +++++- src/textures/textures.h | 13 +- src/v_video.h | 1 + 32 files changed, 367 insertions(+), 60 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 314426ff0..050ff41ff 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -373,7 +373,14 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) FHardwareTexture::UnbindAll(); } -FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli) +bool OpenGLFrameBuffer::CheckPrecacheMaterial(FMaterial *mat) +{ + if (!mat->tex->GetImage()) return true; + auto base = static_cast(mat->GetLayer(0)); + return base->Exists(0); +} + +FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli) { return new FGLModelRenderer(nullptr, gl_RenderState, mli); } diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index c2a26650f..72ec2a9c2 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -36,6 +36,7 @@ public: void SetTextureFilterMode() override; IHardwareTexture *CreateHardwareTexture(FTexture *tex) override; void PrecacheMaterial(FMaterial *mat, int translation) override; + bool CheckPrecacheMaterial(FMaterial *mat) override; FModelRenderer *CreateModelRenderer(int mli) override; void TextureFilterChanged() override; void BeginFrame() override; diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index f6cdc8415..f3c78b6e6 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -467,4 +467,29 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i return true; } +//=========================================================================== +// +// Binds a texture to the renderer +// +//=========================================================================== + +bool FHardwareTexture::Exists(int translation) +{ + int usebright = false; + + if (translation <= 0) + { + translation = -translation; + } + else + { + auto remap = TranslationToTable(translation); + translation = remap == nullptr ? 0 : remap->GetUniqueIndex(); + } + + TranslatedTexture *pTex = GetTexID(translation); + return (pTex->glTexID != 0); +} + + } diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 6c693a998..f864d073b 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -81,6 +81,7 @@ public: unsigned int Bind(int texunit, int translation, bool needmipmap); bool BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags); + bool Exists(int translation); void AllocateBuffer(int w, int h, int texelsize); uint8_t *MapBuffer(); diff --git a/src/hwrenderer/textures/hw_precache.cpp b/src/hwrenderer/textures/hw_precache.cpp index 492610a7c..b927463a2 100644 --- a/src/hwrenderer/textures/hw_precache.cpp +++ b/src/hwrenderer/textures/hw_precache.cpp @@ -33,6 +33,7 @@ #include "r_data/models/models.h" #include "textures/skyboxtexture.h" #include "hwrenderer/textures/hw_material.h" +#include "image.h" //========================================================================== @@ -189,6 +190,31 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl if (gl_precache) { + FImageSource::BeginPrecaching(); + + // cache all used textures + for (int i = cnt - 1; i >= 0; i--) + { + FTexture *tex = TexMan.ByIndex(i); + if (tex != nullptr && tex->GetImage() != nullptr) + { + if (texhitlist[i] & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky)) + { + FMaterial * gltex = FMaterial::ValidateTexture(tex, false); + if (gltex && !screen->CheckPrecacheMaterial(gltex)) + { + FImageSource::RegisterForPrecache(tex->GetImage()); + } + } + + // Only register untranslated sprites. Translated ones are very unlikely to require data that can be reused. + if (spritehitlist[i] != nullptr && (*spritehitlist[i]).CheckKey(0)) + { + FImageSource::RegisterForPrecache(tex->GetImage()); + } + } + } + // cache all used textures for (int i = cnt - 1; i >= 0; i--) { @@ -203,6 +229,9 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl } } + + FImageSource::EndPrecaching(); + // cache all used models FModelRenderer *renderer = screen->CreateModelRenderer(-1); for (unsigned i = 0; i < Models.Size(); i++) diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index 1774354bf..8cda437bc 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -53,7 +53,7 @@ public: FVoxelTexture(FVoxel *voxel); int CopyPixels(FBitmap *bmp, int conversion) override; - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; protected: FVoxel *SourceVox; @@ -79,7 +79,7 @@ FVoxelTexture::FVoxelTexture(FVoxel *vox) // //=========================================================================== -TArray FVoxelTexture::GetPalettedPixels(int conversion) +TArray FVoxelTexture::CreatePalettedPixels(int conversion) { // GetPixels gets called when a translated palette is used so we still need to implement it here. TArray Pixels(256, true); diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index c3bc08d9f..0a376c791 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -818,6 +818,7 @@ namespace swrenderer FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::top), true); mTopPart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; + if (mTopPart.Texture == nullptr) return; mTopPart.TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::top)); double rowoffset = sidedef->GetTextureYOffset(side_t::top); diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index 721873da1..9cd3fb309 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -51,6 +51,7 @@ #include "polyrenderer/poly_renderer.h" #include "p_setup.h" #include "g_levellocals.h" +#include "image.h" // [BB] Use ZDoom's freelook limit for the sotfware renderer. // Note: ZDoom's limit is chosen such that the sky is rendered properly. @@ -80,6 +81,25 @@ FRenderer *CreateSWRenderer() return new FSoftwareRenderer; } +void FSoftwareRenderer::PreparePrecache(FTexture *ttex, int cache) +{ + bool isbgra = V_IsTrueColor(); + + if (ttex != NULL && ttex->isValid()) + { + FSoftwareTexture *tex = ttex->GetSoftwareTexture(); + + if (tex->CheckPixels()) + { + if (cache == 0) tex->Unload(); + } + else if (cache != 0) + { + FImageSource::RegisterForPrecache(ttex->GetImage()); + } + } +} + void FSoftwareRenderer::PrecacheTexture(FTexture *ttex, int cache) { bool isbgra = V_IsTrueColor(); @@ -102,10 +122,6 @@ void FSoftwareRenderer::PrecacheTexture(FTexture *ttex, int cache) else tex->GetPixels (DefaultRenderStyle()); } - else - { - tex->Unload (); - } } } @@ -152,10 +168,18 @@ void FSoftwareRenderer::Precache(uint8_t *texhitlist, TMap & delete[] spritelist; int cnt = TexMan.NumTextures(); + + FImageSource::BeginPrecaching(); + for (int i = cnt - 1; i >= 0; i--) + { + PreparePrecache(TexMan.ByIndex(i), texhitlist[i]); + } + for (int i = cnt - 1; i >= 0; i--) { PrecacheTexture(TexMan.ByIndex(i), texhitlist[i]); } + FImageSource::EndPrecaching(); } void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target, void *videobuffer) diff --git a/src/swrenderer/r_swrenderer.h b/src/swrenderer/r_swrenderer.h index 864cbb665..b9bb28019 100644 --- a/src/swrenderer/r_swrenderer.h +++ b/src/swrenderer/r_swrenderer.h @@ -27,6 +27,7 @@ struct FSoftwareRenderer : public FRenderer void Init() override; private: + void PreparePrecache(FTexture *tex, int cache); void PrecacheTexture(FTexture *tex, int cache); swrenderer::RenderScene mScene; diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index 3dd534624..791619e77 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -1,6 +1,6 @@ #pragma once #include "textures/textures.h" - +#include "v_video.h" struct FSoftwareTextureSpan { @@ -130,6 +130,12 @@ public: return GetPixels(alpha); } + // Checks if the pixel data is loaded. + bool CheckPixels() const + { + return V_IsTrueColor() ? PixelsBgra.Size() > 0 : Pixels.Size() > 0; + } + const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out) { bool alpha = !!(style.Flags & STYLEF_RedIsAlpha); diff --git a/src/tarray.h b/src/tarray.h index bdbb7bb82..f580ae3e4 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -272,6 +272,18 @@ public: return i; } + template const + unsigned int FindEx(Func compare) const + { + unsigned int i; + for (i = 0; i < Count; ++i) + { + if (compare(Array[i])) + break; + } + return i; + } + unsigned int Push (const T &item) { Grow (1); @@ -1019,7 +1031,7 @@ protected: if (!nold[i].IsNil()) { Node *n = NewKey(nold[i].Pair.Key); - ::new(&n->Pair.Value) VT(nold[i].Pair.Value); + ::new(&n->Pair.Value) VT(std::move(nold[i].Pair.Value)); nold[i].~Node(); } } diff --git a/src/textures/formats/automaptexture.cpp b/src/textures/formats/automaptexture.cpp index 299727d83..81205291b 100644 --- a/src/textures/formats/automaptexture.cpp +++ b/src/textures/formats/automaptexture.cpp @@ -52,7 +52,7 @@ class FAutomapTexture : public FImageSource { public: FAutomapTexture(int lumpnum); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; }; @@ -91,7 +91,7 @@ FAutomapTexture::FAutomapTexture (int lumpnum) // //========================================================================== -TArray FAutomapTexture::GetPalettedPixels(int conversion) +TArray FAutomapTexture::CreatePalettedPixels(int conversion) { int x, y; FMemLump data = Wads.ReadLump (SourceLump); diff --git a/src/textures/formats/buildtexture.cpp b/src/textures/formats/buildtexture.cpp index a76e1666e..1b5be6543 100644 --- a/src/textures/formats/buildtexture.cpp +++ b/src/textures/formats/buildtexture.cpp @@ -57,7 +57,7 @@ class FBuildTexture : public FImageSource { public: FBuildTexture (const FString &pathprefix, int tilenum, const uint8_t *pixels, int translation, int width, int height, int left, int top); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; int CopyPixels(FBitmap *bmp, int conversion) override; protected: @@ -81,7 +81,7 @@ FBuildTexture::FBuildTexture(const FString &pathprefix, int tilenum, const uint8 TopOffset = top; } -TArray FBuildTexture::GetPalettedPixels(int conversion) +TArray FBuildTexture::CreatePalettedPixels(int conversion) { TArray Pixels(Width * Height, true); FRemapTable *Remap = translationtables[TRANSLATION_Standard][Translation]; diff --git a/src/textures/formats/ddstexture.cpp b/src/textures/formats/ddstexture.cpp index 810f91fe2..f5ae1f056 100644 --- a/src/textures/formats/ddstexture.cpp +++ b/src/textures/formats/ddstexture.cpp @@ -164,7 +164,7 @@ class FDDSTexture : public FImageSource public: FDDSTexture (FileReader &lump, int lumpnum, void *surfdesc); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; protected: uint32_t Format; @@ -372,7 +372,7 @@ void FDDSTexture::CalcBitShift (uint32_t mask, uint8_t *lshiftp, uint8_t *rshift // //========================================================================== -TArray FDDSTexture::GetPalettedPixels(int conversion) +TArray FDDSTexture::CreatePalettedPixels(int conversion) { auto lump = Wads.OpenLumpReader (SourceLump); diff --git a/src/textures/formats/emptytexture.cpp b/src/textures/formats/emptytexture.cpp index 11710f226..1073de660 100644 --- a/src/textures/formats/emptytexture.cpp +++ b/src/textures/formats/emptytexture.cpp @@ -51,7 +51,7 @@ class FEmptyTexture : public FImageSource { public: FEmptyTexture (int lumpnum); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; }; //========================================================================== @@ -91,7 +91,7 @@ FEmptyTexture::FEmptyTexture (int lumpnum) // //========================================================================== -TArray FEmptyTexture::GetPalettedPixels(int conversion) +TArray FEmptyTexture::CreatePalettedPixels(int conversion) { TArray Pixel(1, true); Pixel[0] = 0; diff --git a/src/textures/formats/flattexture.cpp b/src/textures/formats/flattexture.cpp index a0982645f..7654b2b35 100644 --- a/src/textures/formats/flattexture.cpp +++ b/src/textures/formats/flattexture.cpp @@ -50,7 +50,7 @@ class FFlatTexture : public FImageSource { public: FFlatTexture (int lumpnum); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; }; @@ -104,7 +104,7 @@ FFlatTexture::FFlatTexture (int lumpnum) // //========================================================================== -TArray FFlatTexture::GetPalettedPixels(int conversion) +TArray FFlatTexture::CreatePalettedPixels(int conversion) { auto lump = Wads.OpenLumpReader (SourceLump); TArray Pixels(Width*Height, true); diff --git a/src/textures/formats/fontchars.cpp b/src/textures/formats/fontchars.cpp index 3573ab892..93f460b3d 100644 --- a/src/textures/formats/fontchars.cpp +++ b/src/textures/formats/fontchars.cpp @@ -68,12 +68,12 @@ FFontChar1::FFontChar1 (FImageSource *sourcelump) // //========================================================================== -TArray FFontChar1::GetPalettedPixels (int) +TArray FFontChar1::CreatePalettedPixels (int) { // Make the texture as normal, then remap it so that all the colors // are at the low end of the palette // Why? It only creates unnecessary work! - auto Pixels = BaseTexture->GetPalettedPixels(normal); + auto Pixels = BaseTexture->CreatePalettedPixels(normal); if (SourceRemap) { @@ -132,7 +132,7 @@ void FFontChar2::SetSourceRemap(const uint8_t *sourceremap) // //========================================================================== -TArray FFontChar2::GetPalettedPixels(int) +TArray FFontChar2::CreatePalettedPixels(int) { auto lump = Wads.OpenLumpReader (SourceLump); int destSize = Width * Height; diff --git a/src/textures/formats/fontchars.h b/src/textures/formats/fontchars.h index 644372b77..96437f3a8 100644 --- a/src/textures/formats/fontchars.h +++ b/src/textures/formats/fontchars.h @@ -5,7 +5,7 @@ class FFontChar1 : public FImageSource { public: FFontChar1 (FImageSource *sourcelump); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; void SetSourceRemap(const uint8_t *sourceremap); protected: @@ -20,7 +20,7 @@ class FFontChar2 : public FImageSource public: FFontChar2 (int sourcelump, int sourcepos, int width, int height, int leftofs=0, int topofs=0); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; void SetSourceRemap(const uint8_t *sourceremap); protected: diff --git a/src/textures/formats/imgztexture.cpp b/src/textures/formats/imgztexture.cpp index 681f39d97..2f466c5e2 100644 --- a/src/textures/formats/imgztexture.cpp +++ b/src/textures/formats/imgztexture.cpp @@ -68,7 +68,7 @@ class FIMGZTexture : public FImageSource public: FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int16_t t, bool isalpha); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; int CopyPixels(FBitmap *bmp, int conversion) override; }; @@ -120,7 +120,7 @@ FIMGZTexture::FIMGZTexture (int lumpnum, uint16_t w, uint16_t h, int16_t l, int1 // //========================================================================== -TArray FIMGZTexture::GetPalettedPixels(int conversion) +TArray FIMGZTexture::CreatePalettedPixels(int conversion) { FMemLump lump = Wads.ReadLump (SourceLump); const ImageHeader *imgz = (const ImageHeader *)lump.GetMem(); diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index 451f91f15..a441c585b 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -186,7 +186,7 @@ public: FJPEGTexture (int lumpnum, int width, int height); int CopyPixels(FBitmap *bmp, int conversion) override; - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; }; //========================================================================== @@ -260,7 +260,7 @@ FJPEGTexture::FJPEGTexture (int lumpnum, int width, int height) // //========================================================================== -TArray FJPEGTexture::GetPalettedPixels(int conversion) +TArray FJPEGTexture::CreatePalettedPixels(int conversion) { auto lump = Wads.OpenLumpReader (SourceLump); JSAMPLE *buff = NULL; diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index cd50d555c..fe960923b 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -53,6 +53,7 @@ #include "image.h" #include "multipatchtexture.h" + //========================================================================== // // FMultiPatchTexture :: FMultiPatchTexture @@ -142,7 +143,8 @@ static uint8_t *GetBlendMap(PalEntry blend, uint8_t *blendwork) void FMultiPatchTexture::CopyToBlock(uint8_t *dest, int dwidth, int dheight, FImageSource *source, int xpos, int ypos, int rotate, const uint8_t *translation, int style) { - auto image = source->GetPalettedPixels(style); // should use composition cache + auto cimage = source->GetCachedPalettedPixels(style); // should use composition cache + auto &image = cimage.Pixels; const uint8_t *pixels = image.Data(); int srcwidth = source->GetWidth(); int srcheight = source->GetHeight(); @@ -188,7 +190,7 @@ void FMultiPatchTexture::CopyToBlock(uint8_t *dest, int dwidth, int dheight, FIm // //========================================================================== -TArray FMultiPatchTexture::GetPalettedPixels(int conversion) +TArray FMultiPatchTexture::CreatePalettedPixels(int conversion) { int numpix = Width * Height; uint8_t blendwork[256]; @@ -324,3 +326,29 @@ int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion) return retv; } +//========================================================================== +// +// +// +//========================================================================== + +void FMultiPatchTexture::CollectForPrecache(PrecacheInfo &info, bool requiretruecolor) +{ + FImageSource::CollectForPrecache(info, requiretruecolor); + + if (!requiretruecolor) + { + requiretruecolor = bComplex; + + if (!requiretruecolor) for (int i = 0; i < NumParts; ++i) + { + if (Parts[i].op != OP_COPY) requiretruecolor = true; + } + } + for (int i = 0; i < NumParts; ++i) + { + Parts[i].Image->CollectForPrecache(info, requiretruecolor); + } +} + + diff --git a/src/textures/formats/multipatchtexture.h b/src/textures/formats/multipatchtexture.h index 28ff8dcc3..bda492b84 100644 --- a/src/textures/formats/multipatchtexture.h +++ b/src/textures/formats/multipatchtexture.h @@ -39,8 +39,10 @@ protected: // The getters must optionally redirect if it's a simple one-patch texture. int CopyPixels(FBitmap *bmp, int conversion) override; - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; void CopyToBlock(uint8_t *dest, int dwidth, int dheight, FImageSource *source, int xpos, int ypos, int rotate, const uint8_t *translation, int style); + void CollectForPrecache(PrecacheInfo &info, bool requiretruecolor); + }; diff --git a/src/textures/formats/patchtexture.cpp b/src/textures/formats/patchtexture.cpp index 7a5de9c31..705da984a 100644 --- a/src/textures/formats/patchtexture.cpp +++ b/src/textures/formats/patchtexture.cpp @@ -64,7 +64,7 @@ class FPatchTexture : public FImageSource bool isalpha = false; public: FPatchTexture (int lumpnum, patch_t *header, bool isalphatex); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; int CopyPixels(FBitmap *bmp, int conversion) override; void DetectBadPatches(); }; @@ -163,7 +163,7 @@ FPatchTexture::FPatchTexture (int lumpnum, patch_t * header, bool isalphatex) // //========================================================================== -TArray FPatchTexture::GetPalettedPixels(int conversion) +TArray FPatchTexture::CreatePalettedPixels(int conversion) { uint8_t *remap, remaptable[256]; int numspans; diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index 708f36d81..ff37ce8aa 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -93,7 +93,7 @@ protected: void ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr); void ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr, int planes); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; }; @@ -358,7 +358,7 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr // //========================================================================== -TArray FPCXTexture::GetPalettedPixels(int conversion) +TArray FPCXTexture::CreatePalettedPixels(int conversion) { uint8_t PaletteMap[256]; PCXHeader header; diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index 37272125e..3cdfc3a6a 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -55,7 +55,7 @@ public: ~FPNGTexture(); int CopyPixels(FBitmap *bmp, int conversion) override; - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; protected: void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap); @@ -367,7 +367,7 @@ void FPNGTexture::ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap) // //========================================================================== -TArray FPNGTexture::GetPalettedPixels(int conversion) +TArray FPNGTexture::CreatePalettedPixels(int conversion) { FileReader *lump; FileReader lfr; diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index 0edaa9497..3cc136dfc 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -54,7 +54,7 @@ class FRawPageTexture : public FImageSource int mPaletteLump = -1; public: FRawPageTexture (int lumpnum); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; int CopyPixels(FBitmap *bmp, int conversion) override; }; @@ -173,7 +173,7 @@ FRawPageTexture::FRawPageTexture (int lumpnum) // //========================================================================== -TArray FRawPageTexture::GetPalettedPixels(int conversion) +TArray FRawPageTexture::CreatePalettedPixels(int conversion) { FMemLump lump = Wads.ReadLump (SourceLump); const uint8_t *source = (const uint8_t *)lump.GetMem(); diff --git a/src/textures/formats/shadertexture.cpp b/src/textures/formats/shadertexture.cpp index 0e79ad8c7..8f817d9bc 100644 --- a/src/textures/formats/shadertexture.cpp +++ b/src/textures/formats/shadertexture.cpp @@ -100,7 +100,7 @@ public: } } - TArray GetPalettedPixels(int conversion) override + TArray CreatePalettedPixels(int conversion) override { TArray Pix(512, true); if (conversion == luminance) diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index cfb0f4890..1a26f6036 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -85,7 +85,7 @@ public: protected: void ReadCompressed(FileReader &lump, uint8_t * buffer, int bytesperpixel); - TArray GetPalettedPixels(int conversion) override; + TArray CreatePalettedPixels(int conversion) override; }; //========================================================================== @@ -179,7 +179,7 @@ void FTGATexture::ReadCompressed(FileReader &lump, uint8_t * buffer, int bytespe // //========================================================================== -TArray FTGATexture::GetPalettedPixels(int conversion) +TArray FTGATexture::CreatePalettedPixels(int conversion) { uint8_t PaletteMap[256]; auto lump = Wads.OpenLumpReader (SourceLump); diff --git a/src/textures/image.cpp b/src/textures/image.cpp index c5d29ae5f..859021770 100644 --- a/src/textures/image.cpp +++ b/src/textures/image.cpp @@ -43,6 +43,24 @@ FMemArena FImageSource::ImageArena(32768); TArrayFImageSource::ImageForLump; int FImageSource::NextID; +static PrecacheInfo precacheInfo; + +struct PrecacheDataPaletted +{ + TArray Pixels; + int RefCount; + int ImageID; +}; + +struct PrecacheDataRgba +{ + FBitmap Pixels; + int ImageID; +}; + +// TMap doesn't handle this kind of data well. std::map neither. The linear search is still faster, even for a few 100 entries because it doesn't have to access the heap as often.. +TArray precacheDataPaletted; +TArray precacheDataRgba; //=========================================================================== // @@ -50,13 +68,97 @@ int FImageSource::NextID; // //=========================================================================== -TArray FImageSource::GetPalettedPixels(int conversion) +TArray FImageSource::CreatePalettedPixels(int conversion) { TArray Pixels(Width * Height, true); memset(Pixels.Data(), 0, Width * Height); return Pixels; } +PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion) +{ + PalettedPixels ret; + + FString name; + Wads.GetLumpName(name, SourceLump); + if (name.CompareNoCase("W_136") == 0) + { + int a = 0; + } + + std::pair *info = nullptr; + auto imageID = ImageID; + + // Do we have this image in the cache? + unsigned index = precacheDataPaletted.FindEx([=](PrecacheDataPaletted &entry) { return entry.ImageID == imageID; }); + if (index < precacheDataPaletted.Size()) + { + auto cache = &precacheDataPaletted[index]; + + if (cache->RefCount > 1) + { + Printf("returning reference to %s, refcount = %d\n", name.GetChars(), cache->RefCount); + ret.Pixels.Set(cache->Pixels.Data(), cache->Pixels.Size()); + cache->RefCount--; + } + else if (cache->Pixels.Size() > 0) + { + Printf("returning contents of %s, refcount = %d\n", name.GetChars(), cache->RefCount); + ret.PixelStore = std::move(cache->Pixels); + ret.Pixels.Set(ret.PixelStore.Data(), ret.PixelStore.Size()); + precacheDataPaletted.Delete(index); + } + else + { + Printf("something bad happened for %s, refcount = %d\n", name.GetChars(), cache->RefCount); + } + } + else + { + // The image wasn't cached. Now there's two possibilities: + auto info = precacheInfo.CheckKey(ImageID); + if (!info || info->second <= 1 || conversion != normal) + { + // This is either the only copy needed or some access outside the caching block. In these cases create a new one and directly return it. + Printf("returning fresh copy of %s\n", name.GetChars()); + ret.PixelStore = CreatePalettedPixels(conversion); + ret.Pixels.Set(ret.PixelStore.Data(), ret.PixelStore.Size()); + } + else + { + Printf("creating cached entry for %s, refcount = %d\n", name.GetChars(), info->second); + // This is the first time it gets accessed and needs to be placed in the cache. + PrecacheDataPaletted *pdp = &precacheDataPaletted[precacheDataPaletted.Reserve(1)]; + + pdp->ImageID = imageID; + pdp->RefCount = info->second - 1; + info->second = 0; + pdp->Pixels = CreatePalettedPixels(normal); + ret.Pixels.Set(pdp->Pixels.Data(), pdp->Pixels.Size()); + } + } + return ret; +} + +TArray FImageSource::GetPalettedPixels(int conversion) +{ + auto pix = GetCachedPalettedPixels(conversion); + if (pix.ownsPixels()) + { + // return the pixel store of the returned data directly if this was the last reference. + auto array = std::move(pix.PixelStore); + return array; + } + else + { + // If there are pending references, make a copy. + TArray array(pix.Pixels.Size(), true); + memcpy(array.Data(), pix.Pixels.Data(), array.Size()); + return array; + } +} + + //=========================================================================== // @@ -75,7 +177,7 @@ int FImageSource::CopyPixels(FBitmap *bmp, int conversion) if (conversion == luminance) conversion = normal; // luminance images have no use as an RGB source. PalEntry *palette = screen->GetPalette(); for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values - auto ppix = GetPalettedPixels(conversion); // should use composition cache + auto ppix = CreatePalettedPixels(conversion); bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); for(int i=1;i<256;i++) palette[i].a = 0; return 0; @@ -83,11 +185,54 @@ int FImageSource::CopyPixels(FBitmap *bmp, int conversion) int FImageSource::CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap) { - auto ppix = GetPalettedPixels(false); // should use composition cache + auto ppix = CreatePalettedPixels(false); bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, remap, nullptr); return 0; } +//========================================================================== +// +// +// +//========================================================================== + +void FImageSource::CollectForPrecache(PrecacheInfo &info, bool requiretruecolor) +{ + auto val = info.CheckKey(ImageID); + bool tc = requiretruecolor || V_IsTrueColor(); + if (val) + { + val->first += tc; + val->second += !tc; + } + else + { + auto pair = std::make_pair(tc, !tc); + info.Insert(ImageID, pair); + } +} + +void FImageSource::BeginPrecaching() +{ + precacheInfo.Clear(); +} + +void FImageSource::EndPrecaching() +{ + precacheDataPaletted.Clear(); + precacheDataRgba.Clear(); +} + +void FImageSource::RegisterForPrecache(FImageSource *img) +{ + img->CollectForPrecache(precacheInfo); +} + +FBitmap FImageSource::GetPixelsWithCache(int conversion) +{ + return FBitmap(); +} + //========================================================================== // diff --git a/src/textures/image.h b/src/textures/image.h index 7101c2816..7c976f451 100644 --- a/src/textures/image.h +++ b/src/textures/image.h @@ -5,6 +5,21 @@ #include "textures/bitmap.h" #include "memarena.h" +class FImageSource; +using PrecacheInfo = TMap>; + +struct PalettedPixels +{ + friend class FImageSource; + TArrayView Pixels; +private: + TArray PixelStore; + + bool ownsPixels() const + { + return Pixels.Data() == PixelStore.Data(); + } +}; // This represents a naked image. It has no high level logic attached to it. // All it can do is provide raw image data to its users. @@ -41,13 +56,27 @@ public: bool bMasked = true; // Image (might) have holes (Assume true unless proven otherwise!) int8_t bTranslucent = -1; // Image has pixels with a non-0/1 value. (-1 means the user needs to do a real check) - // Returns the whole texture, paletted and true color versions respectively. - virtual TArray GetPalettedPixels(int conversion); // 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture. + + // 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture. + + // Always creates a new pixel buffer for the texture + virtual TArray CreatePalettedPixels(int conversion); + + // Either returns a reference to the cache, or a newly created item. The return of this has to be considered transient. If you need to store the result, use GetPalettedPixels + PalettedPixels GetCachedPalettedPixels(int conversion); + + // tries to get a buffer from the cache. If not available, create a new one. If further references are pending, create a copy. + TArray GetPalettedPixels(int conversion); + virtual int CopyPixels(FBitmap *bmp, int conversion); // This will always ignore 'luminance'. int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); static void ClearImages() { ImageArena.FreeAll(); ImageForLump.Clear(); NextID = 0; } static FImageSource * FImageSource::GetImage(int lumpnum, ETextureType usetype); + // These functions either allocate a new buffer or reuse the last one, if its reference count was greater than 1 when last used. + FBitmap GetPixelsWithCache(int conversion); + + // Conversion option enum EType { @@ -59,9 +88,6 @@ public: FImageSource(int sourcelump = -1) : SourceLump(sourcelump) { ImageID = ++NextID; } virtual ~FImageSource() {} - // Creates an image from the given lump. - static FImageSource *CreateImageSource(int lumpnum); - int GetWidth() const { return Width; @@ -91,6 +117,11 @@ public: { return bUseGamePalette; } + + virtual void CollectForPrecache(PrecacheInfo &info, bool requiretruecolor = false); + static void BeginPrecaching(); + static void EndPrecaching(); + static void RegisterForPrecache(FImageSource *img); }; //========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index ef154a9f6..72bef46ea 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -307,14 +307,6 @@ public: /*virtual*/ FBitmap GetBgraBitmap(PalEntry *remap, int *trans = nullptr); public: - /* - static void FlipSquareBlock (uint8_t *block, int x, int y); - static void FlipSquareBlockBgra (uint32_t *block, int x, int y); - static void FlipSquareBlockRemap (uint8_t *block, int x, int y, const uint8_t *remap); - static void FlipNonSquareBlock (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch); - static void FlipNonSquareBlockBgra (uint32_t *blockto, const uint32_t *blockfrom, int x, int y, int srcpitch); - static void FlipNonSquareBlockRemap (uint8_t *blockto, const uint8_t *blockfrom, int x, int y, int srcpitch, const uint8_t *remap); - */ static bool SmoothEdges(unsigned char * buffer,int w, int h); static PalEntry averageColor(const uint32_t *data, int size, int maxout); @@ -436,7 +428,7 @@ protected: virtual void ResolvePatches() {} - virtual void SetFrontSkyLayer(); + void SetFrontSkyLayer(); static void InitGrayMap(); @@ -645,11 +637,12 @@ private: TArray FirstTextureForFile; TArray > BuildTileData; - TArray mAnimations; TArray mSwitchDefs; TArray mAnimatedDoors; public: + TArray mAnimations; + bool HasGlobalBrightmap; FRemapTable GlobalBrightmap; short sintable[2048]; // for texture warping diff --git a/src/v_video.h b/src/v_video.h index 1cba846f0..918c572e3 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -428,6 +428,7 @@ public: virtual void CleanForRestart() {} virtual void SetTextureFilterMode() {} virtual IHardwareTexture *CreateHardwareTexture(FTexture *tex) { return nullptr; } + virtual bool CheckPrecacheMaterial(FMaterial *mat) { return true; } virtual void PrecacheMaterial(FMaterial *mat, int translation) {} virtual FModelRenderer *CreateModelRenderer(int mli) { return nullptr; } virtual void UnbindTexUnit(int no) {} From 4cd60fbe9927171ca20b77f515f240f2db637b13 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 10 Dec 2018 02:35:10 +0100 Subject: [PATCH 28/66] - added caching for true color images as well --- src/f_wipe.cpp | 9 +- src/swrenderer/r_swscene.cpp | 9 +- src/textures/bitmap.h | 28 +++++- src/textures/formats/brightmaptexture.cpp | 2 +- src/textures/formats/fontchars.cpp | 2 +- src/textures/formats/multipatchtexture.cpp | 4 +- src/textures/image.cpp | 110 +++++++++++++++++---- src/textures/image.h | 29 +++--- src/textures/imagetexture.cpp | 4 +- src/textures/skyboxtexture.cpp | 7 +- src/textures/skyboxtexture.h | 2 +- src/textures/texture.cpp | 33 +------ src/textures/textures.h | 7 +- 13 files changed, 162 insertions(+), 84 deletions(-) diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index 6cfc737d1..cb5544b68 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -41,10 +41,13 @@ public: Height = h; } - int CopyPixels(FBitmap *bmp) override + FBitmap GetBgraBitmap(PalEntry*, int *trans) override { - bmp->CopyPixelDataRGB(0, 0, (uint8_t*)WorkBuffer.Data(), Width, Height, 4, Width*4, 0, CF_RGBA, nullptr); - return 0; + FBitmap bmp; + bmp.Create(Width, Height); + bmp.CopyPixelDataRGB(0, 0, (uint8_t*)WorkBuffer.Data(), Width, Height, 4, Width*4, 0, CF_RGBA, nullptr); + if (trans) *trans = 0; + return bmp; } uint32_t *GetBuffer() diff --git a/src/swrenderer/r_swscene.cpp b/src/swrenderer/r_swscene.cpp index bfdf86a11..177efb711 100644 --- a/src/swrenderer/r_swscene.cpp +++ b/src/swrenderer/r_swscene.cpp @@ -51,14 +51,17 @@ public: UseType = ETextureType::MiscPatch; } - int CopyPixels(FBitmap *bmp) + FBitmap GetBgraBitmap(PalEntry *, int *trans) override { - PalEntry *pe = (PalEntry*)bmp->GetPixels(); + FBitmap bmp; + bmp.Create(256, 1); + PalEntry *pe = (PalEntry*)bmp.GetPixels(); for (int i = 0; i < 256; i++) { pe[i] = GPalette.BaseColors[i].d | 0xff000000; } - return 0; + if (trans) *trans = 0; + return bmp; } }; diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index 1c86623ed..7b09fb21b 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -120,7 +120,7 @@ public: other.FreeBuffer = false; } - FBitmap &operator=(const FBitmap &other) = delete; // disallow because in nearly all cases this creates an unwanted copy. + FBitmap &operator=(const FBitmap &other) = delete; // disallow because in nearly all cases this creates an unwanted copy. Use Copy instead. FBitmap &operator=(FBitmap &&other) { @@ -136,7 +136,27 @@ public: return *this; } - virtual ~FBitmap() + void Copy(const FBitmap &other, bool deep = true) + { + if (data != nullptr && FreeBuffer) delete[] data; + Pitch = other.Pitch; + Width = other.Width; + Height = other.Height; + FreeBuffer = deep; + ClipRect = other.ClipRect; + if (deep) + { + data = new uint8_t[Pitch * Height]; + memcpy(data, other.data, Pitch * Height); + } + else + { + data = other.data; + } + } + + + ~FBitmap() { Destroy(); } @@ -210,10 +230,10 @@ public: void Zero(); - virtual void CopyPixelDataRGB(int originx, int originy, const uint8_t *patch, int srcwidth, + void CopyPixelDataRGB(int originx, int originy, const uint8_t *patch, int srcwidth, int srcheight, int step_x, int step_y, int rotate, int ct, FCopyInfo *inf = NULL, /* for PNG tRNS */ int r=0, int g=0, int b=0); - virtual void CopyPixelData(int originx, int originy, const uint8_t * patch, int srcwidth, int srcheight, + void CopyPixelData(int originx, int originy, const uint8_t * patch, int srcwidth, int srcheight, int step_x, int step_y, int rotate, PalEntry * palette, FCopyInfo *inf = NULL); diff --git a/src/textures/formats/brightmaptexture.cpp b/src/textures/formats/brightmaptexture.cpp index 5d2f48ae0..d56f06010 100644 --- a/src/textures/formats/brightmaptexture.cpp +++ b/src/textures/formats/brightmaptexture.cpp @@ -77,4 +77,4 @@ int FBrightmapTexture::CopyPixels(FBitmap *bmp, int conversion) FTexture *CreateBrightmapTexture(FImageSource *tex) { return new FImageTexture(new FBrightmapTexture(tex)); -} \ No newline at end of file +} diff --git a/src/textures/formats/fontchars.cpp b/src/textures/formats/fontchars.cpp index 93f460b3d..afb643487 100644 --- a/src/textures/formats/fontchars.cpp +++ b/src/textures/formats/fontchars.cpp @@ -73,7 +73,7 @@ TArray FFontChar1::CreatePalettedPixels (int) // Make the texture as normal, then remap it so that all the colors // are at the low end of the palette // Why? It only creates unnecessary work! - auto Pixels = BaseTexture->CreatePalettedPixels(normal); + auto Pixels = BaseTexture->GetPalettedPixels(normal); if (SourceRemap) { diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index fe960923b..2bfc0fc40 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -315,9 +315,7 @@ int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion) } } - FBitmap Pixels; - Pixels.Create(Width, Height); - ret = Parts[i].Image->CopyPixels(&Pixels, conversion); + FBitmap Pixels = Parts[i].Image->GetCachedBitmap(nullptr, conversion, &ret); bmp->Blit(Parts[i].OriginX, Parts[i].OriginY, Pixels, &info); // treat -1 (i.e. unknown) as absolute. We have no idea if this may have overwritten previous info so a real check needs to be done. if (ret == -1) retv = ret; diff --git a/src/textures/image.cpp b/src/textures/image.cpp index 859021770..c08ef0931 100644 --- a/src/textures/image.cpp +++ b/src/textures/image.cpp @@ -55,6 +55,8 @@ struct PrecacheDataPaletted struct PrecacheDataRgba { FBitmap Pixels; + int TransInfo; + int RefCount; int ImageID; }; @@ -81,36 +83,32 @@ PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion) FString name; Wads.GetLumpName(name, SourceLump); - if (name.CompareNoCase("W_136") == 0) - { - int a = 0; - } std::pair *info = nullptr; auto imageID = ImageID; // Do we have this image in the cache? - unsigned index = precacheDataPaletted.FindEx([=](PrecacheDataPaletted &entry) { return entry.ImageID == imageID; }); + unsigned index = conversion != normal? UINT_MAX : precacheDataPaletted.FindEx([=](PrecacheDataPaletted &entry) { return entry.ImageID == imageID; }); if (index < precacheDataPaletted.Size()) { auto cache = &precacheDataPaletted[index]; if (cache->RefCount > 1) { - Printf("returning reference to %s, refcount = %d\n", name.GetChars(), cache->RefCount); + //Printf("returning reference to %s, refcount = %d\n", name.GetChars(), cache->RefCount); ret.Pixels.Set(cache->Pixels.Data(), cache->Pixels.Size()); cache->RefCount--; } else if (cache->Pixels.Size() > 0) { - Printf("returning contents of %s, refcount = %d\n", name.GetChars(), cache->RefCount); + //Printf("returning contents of %s, refcount = %d\n", name.GetChars(), cache->RefCount); ret.PixelStore = std::move(cache->Pixels); ret.Pixels.Set(ret.PixelStore.Data(), ret.PixelStore.Size()); precacheDataPaletted.Delete(index); } else { - Printf("something bad happened for %s, refcount = %d\n", name.GetChars(), cache->RefCount); + //Printf("something bad happened for %s, refcount = %d\n", name.GetChars(), cache->RefCount); } } else @@ -120,13 +118,13 @@ PalettedPixels FImageSource::GetCachedPalettedPixels(int conversion) if (!info || info->second <= 1 || conversion != normal) { // This is either the only copy needed or some access outside the caching block. In these cases create a new one and directly return it. - Printf("returning fresh copy of %s\n", name.GetChars()); + //Printf("returning fresh copy of %s\n", name.GetChars()); ret.PixelStore = CreatePalettedPixels(conversion); ret.Pixels.Set(ret.PixelStore.Data(), ret.PixelStore.Size()); } else { - Printf("creating cached entry for %s, refcount = %d\n", name.GetChars(), info->second); + //Printf("creating cached entry for %s, refcount = %d\n", name.GetChars(), info->second); // This is the first time it gets accessed and needs to be placed in the cache. PrecacheDataPaletted *pdp = &precacheDataPaletted[precacheDataPaletted.Reserve(1)]; @@ -162,7 +160,7 @@ TArray FImageSource::GetPalettedPixels(int conversion) //=========================================================================== // -// FImageSource::CopyPixels +// FImageSource::CopyPixels // // this is the generic case that can handle // any properly implemented texture for software rendering. @@ -196,6 +194,90 @@ int FImageSource::CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap) // //========================================================================== +FBitmap FImageSource::GetCachedBitmap(PalEntry *remap, int conversion, int *ptrans) +{ + FBitmap ret; + + FString name; + int trans = -1; + Wads.GetLumpName(name, SourceLump); + + std::pair *info = nullptr; + auto imageID = ImageID; + + if (remap != nullptr) + { + // Remapped images are never run through the cache because they would complicate matters too much for very little gain. + // Translated images are normally sprites which normally just consist of a single image and use no composition. + // Additionally, since translation requires the base palette, the really time consuming stuff will never be subjected to it. + ret.Create(Width, Height); + trans = CopyTranslatedPixels(&ret, remap); + } + else + { + if (conversion == luminance) conversion = normal; // luminance has no meaning for true color. + // Do we have this image in the cache? + unsigned index = conversion != normal? UINT_MAX : precacheDataRgba.FindEx([=](PrecacheDataRgba &entry) { return entry.ImageID == imageID; }); + if (index < precacheDataRgba.Size()) + { + auto cache = &precacheDataRgba[index]; + + trans = cache->TransInfo; + if (cache->RefCount > 1) + { + Printf("returning reference to %s, refcount = %d\n", name.GetChars(), cache->RefCount); + ret.Copy(cache->Pixels, false); + cache->RefCount--; + } + else if (cache->Pixels.GetPixels()) + { + Printf("returning contents of %s, refcount = %d\n", name.GetChars(), cache->RefCount); + ret = std::move(cache->Pixels); + precacheDataRgba.Delete(index); + } + else + { + // This should never happen if the function is implemented correctly + Printf("something bad happened for %s, refcount = %d\n", name.GetChars(), cache->RefCount); + ret.Create(Width, Height); + trans = CopyPixels(&ret, normal); + } + } + else + { + // The image wasn't cached. Now there's two possibilities: + auto info = precacheInfo.CheckKey(ImageID); + if (!info || info->first <= 1 || conversion != normal) + { + // This is either the only copy needed or some access outside the caching block. In these cases create a new one and directly return it. + Printf("returning fresh copy of %s\n", name.GetChars()); + ret.Create(Width, Height); + trans = CopyPixels(&ret, conversion); + } + else + { + Printf("creating cached entry for %s, refcount = %d\n", name.GetChars(), info->first); + // This is the first time it gets accessed and needs to be placed in the cache. + PrecacheDataRgba *pdr = &precacheDataRgba[precacheDataRgba.Reserve(1)]; + + pdr->ImageID = imageID; + pdr->RefCount = info->first - 1; + info->first = 0; + pdr->Pixels.Create(Width, Height); + trans = pdr->TransInfo = CopyPixels(&pdr->Pixels, normal); + ret.Copy(pdr->Pixels, false); + } + } + } + return ret; +} + +//========================================================================== +// +// +// +//========================================================================== + void FImageSource::CollectForPrecache(PrecacheInfo &info, bool requiretruecolor) { auto val = info.CheckKey(ImageID); @@ -228,12 +310,6 @@ void FImageSource::RegisterForPrecache(FImageSource *img) img->CollectForPrecache(precacheInfo); } -FBitmap FImageSource::GetPixelsWithCache(int conversion) -{ - return FBitmap(); -} - - //========================================================================== // // diff --git a/src/textures/image.h b/src/textures/image.h index 7c976f451..e53fc2035 100644 --- a/src/textures/image.h +++ b/src/textures/image.h @@ -25,7 +25,7 @@ private: // All it can do is provide raw image data to its users. class FImageSource { - friend class FBrightmapImage; + friend class FBrightmapTexture; protected: static FMemArena ImageArena; @@ -38,6 +38,14 @@ protected: bool bUseGamePalette = false; // true if this is an image without its own color set. int ImageID = -1; + // Internal image creation functions. All external access should go through the cache interface, + // so that all code can benefit from future improvements to that. + + virtual TArray CreatePalettedPixels(int conversion); + virtual int CopyPixels(FBitmap *bmp, int conversion); // This will always ignore 'luminance'. + int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); + + public: void CopySize(FImageSource &other) @@ -59,22 +67,19 @@ public: // 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture. - // Always creates a new pixel buffer for the texture - virtual TArray CreatePalettedPixels(int conversion); - // Either returns a reference to the cache, or a newly created item. The return of this has to be considered transient. If you need to store the result, use GetPalettedPixels PalettedPixels GetCachedPalettedPixels(int conversion); // tries to get a buffer from the cache. If not available, create a new one. If further references are pending, create a copy. TArray GetPalettedPixels(int conversion); - virtual int CopyPixels(FBitmap *bmp, int conversion); // This will always ignore 'luminance'. - int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); - static void ClearImages() { ImageArena.FreeAll(); ImageForLump.Clear(); NextID = 0; } - static FImageSource * FImageSource::GetImage(int lumpnum, ETextureType usetype); + + // Unlile for paletted images there is no variant here that returns a persistent bitmap, because all users have to process the returned image into another format. + FBitmap GetCachedBitmap(PalEntry *remap, int conversion, int *trans = nullptr); + + static void ClearImages() { ImageArena.FreeAll(); ImageForLump.Clear(); NextID = 0; } + static FImageSource * GetImage(int lumpnum, ETextureType usetype); - // These functions either allocate a new buffer or reuse the last one, if its reference count was greater than 1 when last used. - FBitmap GetPixelsWithCache(int conversion); // Conversion option @@ -143,9 +148,7 @@ public: } FImageSource *GetImage() const override { return mImage; } + FBitmap GetBgraBitmap(PalEntry *p, int *trans) override; -protected: - int CopyPixels(FBitmap *bmp) override; - }; diff --git a/src/textures/imagetexture.cpp b/src/textures/imagetexture.cpp index d4e8ce953..43adee19a 100644 --- a/src/textures/imagetexture.cpp +++ b/src/textures/imagetexture.cpp @@ -73,9 +73,9 @@ FImageTexture::FImageTexture(FImageSource *img, const char *name) // //=========================================================================== -int FImageTexture::CopyPixels(FBitmap *bmp) +FBitmap FImageTexture::GetBgraBitmap(PalEntry *p, int *trans) { - return mImage->CopyPixels(bmp, bNoRemap0? FImageSource::noremap0 : FImageSource::normal); + return mImage->GetCachedBitmap(p, bNoRemap0? FImageSource::noremap0 : FImageSource::normal, trans); } //=========================================================================== diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 6e063be62..2aed8d3e7 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -24,6 +24,7 @@ #include "w_wad.h" #include "textures.h" #include "skyboxtexture.h" +#include "bitmap.h" @@ -60,9 +61,9 @@ TArray FSkyBox::Get8BitPixels(bool alphatex) // //----------------------------------------------------------------------------- -int FSkyBox::CopyPixels(FBitmap *bmp) +FBitmap FSkyBox::GetBgraBitmap(PalEntry *p, int *trans) { - if (faces[0]) return faces[0]->CopyPixels(bmp); - return 0; + if (faces[0]) return faces[0]->GetBgraBitmap(p, trans); + return FTexture::GetBgraBitmap(p, trans); } diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index 80f9b9c72..996681063 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -17,7 +17,7 @@ public: FSkyBox(const char *name = nullptr); TArray Get8BitPixels(bool alphatex); - int CopyPixels(FBitmap *bmp); + FBitmap GetBgraBitmap(PalEntry *, int *trans) override; void SetSize() { diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 55fe8334e..4f6257f24 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -202,42 +202,17 @@ void FTexture::SetFrontSkyLayer () //=========================================================================== // -// FTexture::CopyPixels +// FTexture::GetBgraBitmap // -// this is the generic case that can handle -// any properly implemented texture for software rendering. -// Its drawback is that it is limited to the base palette which is -// why all classes that handle different palettes should subclass this -// method +// Default returns just an empty bitmap. This needs to be overridden by +// any subclass that actually does return a software pixel buffer. // //=========================================================================== -int FTexture::CopyPixels(FBitmap *bmp) -{ - PalEntry *palette = screen->GetPalette(); - for(int i=1;i<256;i++) palette[i].a = 255; // set proper alpha values - auto ppix = Get8BitPixels(false); // should use composition cache - bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, palette, nullptr); - for(int i=1;i<256;i++) palette[i].a = 0; - return 0; -} - -int FTexture::CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap) -{ - auto ppix = Get8BitPixels(false); // should use composition cache - bmp->CopyPixelData(0, 0, ppix.Data(), Width, Height, Height, 1, 0, remap, nullptr); - return 0; -} - FBitmap FTexture::GetBgraBitmap(PalEntry *remap, int *ptrans) { FBitmap bmp; - int trans; - - bmp.Create(GetWidth(), GetHeight()); - if (!remap) trans = CopyPixels(&bmp); - else trans = CopyTranslatedPixels(&bmp, remap); - if (ptrans) *ptrans = trans; + bmp.Create(Width, Height); return bmp; } diff --git a/src/textures/textures.h b/src/textures/textures.h index 72bef46ea..54c10aab1 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -123,6 +123,8 @@ class FTextureManager; class FTerrainTypeArray; class IHardwareTexture; class FMaterial; +class FMultipatchTextureBuilder; + extern int r_spriteadjustSW, r_spriteadjustHW; class FNullTextureID : public FTextureID @@ -304,7 +306,7 @@ public: // Returns the whole texture, stored in column-major order virtual TArray Get8BitPixels(bool alphatex); - /*virtual*/ FBitmap GetBgraBitmap(PalEntry *remap, int *trans = nullptr); + virtual FBitmap GetBgraBitmap(PalEntry *remap, int *trans = nullptr); public: static bool SmoothEdges(unsigned char * buffer,int w, int h); @@ -385,9 +387,6 @@ protected: // Returns true if GetPixelsBgra includes mipmaps virtual bool Mipmapped() { return true; } - virtual int CopyPixels(FBitmap *bmp); - int CopyTranslatedPixels(FBitmap *bmp, PalEntry *remap); - void SetSpeed(float fac) { shaderspeed = fac; } int GetWidth () { return Width; } From b32aa60760a7108e2b135807995a7545e90a1bf2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 10 Dec 2018 02:43:37 +0100 Subject: [PATCH 29/66] Made SWPaletteTexture an ImageSource and let it be managed by the texture manager. This is a lot easier to manage because the palette is just static data that can easily mimic an image. --- src/swrenderer/r_swscene.cpp | 23 +++++++++++++---------- src/swrenderer/r_swscene.h | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/swrenderer/r_swscene.cpp b/src/swrenderer/r_swscene.cpp index 177efb711..88a5417b6 100644 --- a/src/swrenderer/r_swscene.cpp +++ b/src/swrenderer/r_swscene.cpp @@ -33,6 +33,7 @@ #include "d_player.h" #include "textures/bitmap.h" #include "swrenderer/scene/r_light.h" +#include "image.h" // [RH] Base blending values (for e.g. underwater) int BaseBlendR, BaseBlendG, BaseBlendB; @@ -41,27 +42,23 @@ void InitSoftwareSky(); -class FSWPaletteTexture : public FTexture +class FSWPaletteTexture : public FImageSource { public: FSWPaletteTexture() { Width = 256; Height = 1; - UseType = ETextureType::MiscPatch; } - FBitmap GetBgraBitmap(PalEntry *, int *trans) override + int CopyPixels(FBitmap *bmp, int conversion) override { - FBitmap bmp; - bmp.Create(256, 1); - PalEntry *pe = (PalEntry*)bmp.GetPixels(); + PalEntry *pe = (PalEntry*)bmp->GetPixels(); for (int i = 0; i < 256; i++) { pe[i] = GPalette.BaseColors[i].d | 0xff000000; } - if (trans) *trans = 0; - return bmp; + return 0; } }; @@ -74,7 +71,13 @@ public: SWSceneDrawer::SWSceneDrawer() { - PaletteTexture.reset(new FSWPaletteTexture); + auto texid = TexMan.CheckForTexture("@@palette@@", ETextureType::Any); + if (!texid.Exists()) + { + auto tex = new FImageTexture(new FSWPaletteTexture, "@@palette@@"); + texid = TexMan.AddTexture(tex); + } + PaletteTexture = TexMan.GetTexture(texid); } SWSceneDrawer::~SWSceneDrawer() @@ -98,7 +101,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) fbtex.reset(new FWrapperTexture(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor())); fbtex->GetSystemTexture(0)->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor() ? 4 : 1); auto mat = FMaterial::ValidateTexture(fbtex.get(), false); - mat->AddTextureLayer(PaletteTexture.get()); + mat->AddTextureLayer(PaletteTexture); Canvas.reset(); Canvas.reset(new DCanvas(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor())); diff --git a/src/swrenderer/r_swscene.h b/src/swrenderer/r_swscene.h index 47757a334..7dc12488d 100644 --- a/src/swrenderer/r_swscene.h +++ b/src/swrenderer/r_swscene.h @@ -12,7 +12,7 @@ class FWrapperTexture; class SWSceneDrawer { - std::unique_ptr PaletteTexture; + FTexture *PaletteTexture; std::unique_ptr FBTexture[2]; int FBTextureIndex = 0; bool FBIsTruecolor = false; From 0d07fb255033c881409e25990192e345fb34c3d2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 10 Dec 2018 02:50:22 +0100 Subject: [PATCH 30/66] Use FImageTexture for thre null texture FDummyTexture had a big problem: Whenever it was accessed by accident it crashed the app because it wasn't fully implemented. What it should do is return empty pixels of the given size, and an unextended FImageTexture is doing just that. --- src/textures/multipatchtexturebuilder.cpp | 2 +- src/textures/texture.cpp | 20 -------------------- src/textures/texturemanager.cpp | 4 +++- src/textures/textures.h | 18 +++++++++--------- 4 files changed, 13 insertions(+), 31 deletions(-) diff --git a/src/textures/multipatchtexturebuilder.cpp b/src/textures/multipatchtexturebuilder.cpp index ac2b06917..aa727bef1 100644 --- a/src/textures/multipatchtexturebuilder.cpp +++ b/src/textures/multipatchtexturebuilder.cpp @@ -364,7 +364,7 @@ void FMultipatchTextureBuilder::AddTexturesLump(const void *lumpdata, int lumpsi // It still needs to be created in case someone uses it by name. offset = LittleLong(directory[1]); const maptexture_t *tex = (const maptexture_t *)((const uint8_t *)maptex + offset); - FDummyTexture *tex0 = static_cast(TexMan.ByIndex(0)); + FTexture *tex0 = TexMan.ByIndex(0); tex0->SetSize(SAFESHORT(tex->width), SAFESHORT(tex->height)); } diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 4f6257f24..0b22866ef 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -761,26 +761,6 @@ TArray FTexture::Get8BitPixels(bool alphatex) return Pixels; } -//=========================================================================== -// -// Dummy texture for the 0-entry. -// -//=========================================================================== - -FDummyTexture::FDummyTexture () -{ - Width = 64; - Height = 64; - UseType = ETextureType::Null; -} - -void FDummyTexture::SetSize (int width, int height) -{ - Width = width; - Height = height; -} - - //========================================================================== // // diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 66c43ac62..558a6243c 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -1003,7 +1003,9 @@ void FTextureManager::Init() FTexture::InitGrayMap(); // Texture 0 is a dummy texture used to indicate "no texture" - AddTexture (new FDummyTexture); + auto nulltex = new FImageTexture(nullptr); + nulltex->SetUseType(ETextureType::Null); + AddTexture (nulltex); // some special textures used in the game. AddTexture(CreateShaderTexture(false, false)); AddTexture(CreateShaderTexture(false, true)); diff --git a/src/textures/textures.h b/src/textures/textures.h index 54c10aab1..56a90608b 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -382,7 +382,15 @@ protected: float shaderspeed = 1.f; int shaderindex = 0; - + // This is only legal for the null texture! + void SetSize(int w, int h) + { + if (UseType == ETextureType::Null) + { + Width = w; + Height = h; + } + } // Returns true if GetPixelsBgra includes mipmaps virtual bool Mipmapped() { return true; } @@ -657,14 +665,6 @@ public: }; -// A texture that doesn't really exist -class FDummyTexture : public FTexture -{ -public: - FDummyTexture (); - void SetSize (int width, int height); -}; - // A texture that can be drawn to. class DCanvas; From 91bb7c0641e4fcef47f8c9231a0986d0e2413889 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 10 Dec 2018 02:56:49 +0100 Subject: [PATCH 31/66] Let FSkyboxTexture map to the last defined regular texture of the same name instead of its first face This is normally a better fallback for the software renderer. --- src/r_data/gldefs.cpp | 8 +++++--- src/textures/skyboxtexture.cpp | 26 ++++++++++++++++++++------ src/textures/skyboxtexture.h | 15 +++++++-------- 3 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index fa67b9c55..513d51094 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -102,7 +102,10 @@ static void ParseVavoomSkybox() sc.ScriptError("%s: Skybox definition requires 6 faces", sb->GetName().GetChars()); } sb->SetSize(); - if (!error) TexMan.AddTexture(sb); + if (!error) + { + TexMan.AddTexture(sb); + } } } @@ -964,8 +967,7 @@ class GLDefsParser sc.MustGetString(); - FSkyBox * sb = new FSkyBox; - sb->Name = sc.String; + FSkyBox * sb = new FSkyBox(sc.String); sb->Name.ToUpper(); if (sc.CheckString("fliptop")) { diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 2aed8d3e7..6b5346ac2 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -36,8 +36,14 @@ FSkyBox::FSkyBox(const char *name) : FTexture(name) -{ - faces[0]=faces[1]=faces[2]=faces[3]=faces[4]=faces[5]=NULL; +{ + FTextureID texid = TexMan.CheckForTexture(name, ETextureType::Wall); + if (texid.isValid()) + { + previous = TexMan.GetTexture(texid); + CopySize(previous); + } + faces[0]=faces[1]=faces[2]=faces[3]=faces[4]=faces[5] = nullptr; UseType = ETextureType::Override; bSkybox = true; fliptop = false; @@ -51,8 +57,7 @@ FSkyBox::FSkyBox(const char *name) TArray FSkyBox::Get8BitPixels(bool alphatex) { - if (faces[0]) return faces[0]->Get8BitPixels(alphatex); - return FTexture::Get8BitPixels(alphatex); + return previous->Get8BitPixels(alphatex); } //----------------------------------------------------------------------------- @@ -63,7 +68,16 @@ TArray FSkyBox::Get8BitPixels(bool alphatex) FBitmap FSkyBox::GetBgraBitmap(PalEntry *p, int *trans) { - if (faces[0]) return faces[0]->GetBgraBitmap(p, trans); - return FTexture::GetBgraBitmap(p, trans); + return previous->GetBgraBitmap(p, trans); } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + +FImageSource *FSkyBox::GetImage() const +{ + return previous->GetImage(); +} diff --git a/src/textures/skyboxtexture.h b/src/textures/skyboxtexture.h index 996681063..2288a4094 100644 --- a/src/textures/skyboxtexture.h +++ b/src/textures/skyboxtexture.h @@ -12,18 +12,22 @@ class FSkyBox : public FTexture { public: + FTexture *previous; FTexture * faces[6]; bool fliptop; - FSkyBox(const char *name = nullptr); + FSkyBox(const char *name); TArray Get8BitPixels(bool alphatex); FBitmap GetBgraBitmap(PalEntry *, int *trans) override; + FImageSource *GetImage() const override; + void SetSize() { - if (faces[0]) + if (!previous && faces[0]) previous = faces[0]; + if (previous) { - CopySize(faces[0]); + CopySize(previous); } } @@ -36,9 +40,4 @@ public: { return fliptop; } - - FImageSource *GetImage() const override - { - return faces[0] ? faces[0]->GetImage() : nullptr; - } }; From 5666e4c805a27fba3d5c8c5239b60861e5b6e939 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Dec 2018 00:01:45 +0100 Subject: [PATCH 32/66] - made camera textures operational again. Now with proper separation of software rendering logic from the main part of the class. --- src/CMakeLists.txt | 2 + src/dobjgc.cpp | 1 - src/g_level.cpp | 1 + src/g_levellocals.h | 2 + src/gl/renderer/gl_renderer.cpp | 8 +- src/gl/system/gl_framebuffer.cpp | 19 -- src/gl/system/gl_framebuffer.h | 3 +- src/p_acs.cpp | 2 +- src/p_saveg.cpp | 2 +- src/p_setup.cpp | 2 +- src/r_data/r_canvastexture.cpp | 210 ++++++++++++++++++++ src/r_data/r_canvastexture.h | 25 +++ src/r_renderer.h | 3 - src/r_utility.cpp | 192 ------------------ src/r_utility.h | 20 -- src/scripting/vmthunks.cpp | 13 ++ src/swrenderer/r_swrenderer.cpp | 65 +----- src/swrenderer/r_swrenderer.h | 2 +- src/swrenderer/textures/r_swtexture.cpp | 3 +- src/swrenderer/textures/r_swtexture.h | 33 ++- src/swrenderer/textures/swcanvastexture.cpp | 189 ++++++++++++++++++ src/textures/formats/canvastexture.cpp | 119 ----------- src/textures/image.cpp | 10 +- src/textures/imagehelpers.h | 2 +- src/textures/textures.h | 38 ++-- src/v_framebuffer.cpp | 5 - src/v_video.h | 4 - 27 files changed, 517 insertions(+), 458 deletions(-) create mode 100644 src/r_data/r_canvastexture.cpp create mode 100644 src/r_data/r_canvastexture.h create mode 100644 src/swrenderer/textures/swcanvastexture.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d43c03f36..2f3a94d49 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1144,6 +1144,7 @@ set (PCH_SOURCES r_data/voxels.cpp r_data/renderinfo.cpp r_data/renderstyle.cpp + r_data/r_canvastexture.cpp r_data/r_interpolate.cpp r_data/r_vanillatrans.cpp r_data/r_sections.cpp @@ -1249,6 +1250,7 @@ set (PCH_SOURCES sound/wildmidi/wm_error.cpp swrenderer/textures/r_swtexture.cpp swrenderer/textures/warptexture.cpp + swrenderer/textures/swcanvastexture.cpp events.cpp ) diff --git a/src/dobjgc.cpp b/src/dobjgc.cpp index cd1b49a10..51e95313d 100644 --- a/src/dobjgc.cpp +++ b/src/dobjgc.cpp @@ -322,7 +322,6 @@ static void MarkRoot() M_MarkMenus(); Mark(DIntermissionController::CurrentIntermission); DThinker::MarkRoots(); - FCanvasTextureInfo::Mark(); Mark(E_FirstEventHandler); Mark(E_LastEventHandler); level.Mark(); diff --git a/src/g_level.cpp b/src/g_level.cpp index 873bcf97d..a0e380b08 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -1959,6 +1959,7 @@ void FLevelLocals::Tick () void FLevelLocals::Mark() { + canvasTextureInfo.Mark(); for (auto &s : sectorPortals) { GC::Mark(s.mSkybox); diff --git a/src/g_levellocals.h b/src/g_levellocals.h index c39da9250..2d76c39b2 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -44,6 +44,7 @@ #include "p_local.h" #include "p_destructible.h" #include "r_data/r_sections.h" +#include "r_data/r_canvastexture.h" struct FLevelLocals { @@ -103,6 +104,7 @@ struct FLevelLocals TArray portalGroups; TArray linePortalSpans; FSectionContainer sections; + FCanvasTextureInfo canvasTextureInfo; int NumMapSections; diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index af6a3acac..79ae7655f 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -254,7 +254,10 @@ sector_t *FGLRenderer::RenderView(player_t* player) bool saved_niv = NoInterpolateView; NoInterpolateView = false; // prepare all camera textures that have been used in the last frame - FCanvasTextureInfo::UpdateAll(); + level.canvasTextureInfo.UpdateAll([&](AActor *camera, FCanvasTexture *camtex, double fov) + { + RenderTextureView(camtex, camera, fov); + }); NoInterpolateView = saved_niv; @@ -324,7 +327,8 @@ void FGLRenderer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, doub EndOffscreen(); - tex->SetUpdated(); + tex->SetUpdated(true); + static_cast(screen)->camtexcount++; } //=========================================================================== diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 050ff41ff..58cc8be22 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -186,25 +186,6 @@ void OpenGLFrameBuffer::Update() Super::Update(); } -//=========================================================================== -// -// -// -//=========================================================================== - -void OpenGLFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) -{ - if (!V_IsHardwareRenderer()) - { - Super::RenderTextureView(tex, Viewpoint, FOV); - } - else if (GLRenderer != nullptr) - { - GLRenderer->RenderTextureView(tex, Viewpoint, FOV); - camtexcount++; - } -} - //=========================================================================== // // Render the view to a savegame picture diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 72ec2a9c2..60929d947 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -30,7 +30,6 @@ public: void CleanForRestart() override; void UpdatePalette() override; uint32_t GetCaps() override; - void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) override; void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override; sector_t *RenderView(player_t *player) override; void SetTextureFilterMode() override; @@ -65,7 +64,7 @@ public: FTexture *WipeStartScreen() override; FTexture *WipeEndScreen() override; -private: + int camtexcount = 0; }; diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 2456e4a8f..ab7ca86b8 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -9900,7 +9900,7 @@ scriptwait: } else { - FCanvasTextureInfo::Add (camera, picnum, STACK(1)); + level.canvasTextureInfo.Add(camera, picnum, STACK(1)); } } sp -= 3; diff --git a/src/p_saveg.cpp b/src/p_saveg.cpp index 5436cfbe7..68f642c78 100644 --- a/src/p_saveg.cpp +++ b/src/p_saveg.cpp @@ -1012,7 +1012,7 @@ void G_SerializeLevel(FSerializer &arc, bool hubload) StatusBar->SerializeMessages(arc); AM_SerializeMarkers(arc); FRemapTable::StaticSerializeTranslations(arc); - FCanvasTextureInfo::Serialize(arc); + level.canvasTextureInfo.Serialize(arc); P_SerializePlayers(arc, hubload); P_SerializeSounds(arc); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index fa7de9d7f..16f609152 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3555,7 +3555,6 @@ void P_FreeLevelData () MapThingsUserDataIndex.Clear(); MapThingsUserData.Clear(); linemap.Clear(); - FCanvasTextureInfo::EmptyList(); R_FreePastViewers(); P_ClearUDMFKeys(); @@ -3594,6 +3593,7 @@ void P_FreeLevelData () FBehavior::StaticUnloadModules (); + level.canvasTextureInfo.EmptyList(); level.sections.Clear(); level.segs.Clear(); level.sectors.Clear(); diff --git a/src/r_data/r_canvastexture.cpp b/src/r_data/r_canvastexture.cpp new file mode 100644 index 000000000..a64f50b87 --- /dev/null +++ b/src/r_data/r_canvastexture.cpp @@ -0,0 +1,210 @@ +/* +** r_canvastexture.cpp +** Maintenance data for camera textures +** +**--------------------------------------------------------------------------- +** Copyright 2004-2006 Randy Heit +** Copyright 2006-2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "actor.h" +#include "r_canvastexture.h" +#include "g_levellocals.h" +#include "serializer.h" + +//========================================================================== +// +// FCanvasTextureInfo :: Add +// +// Assigns a camera to a canvas texture. +// +//========================================================================== + +void FCanvasTextureInfo::Add (AActor *viewpoint, FTextureID picnum, double fov) +{ + FCanvasTexture *texture; + + if (!picnum.isValid()) + { + return; + } + texture = static_cast(TexMan.GetTexture(picnum)); + if (!texture->bHasCanvas) + { + Printf ("%s is not a valid target for a camera\n", texture->Name.GetChars()); + return; + } + + // Is this texture already assigned to a camera? + unsigned index = List.FindEx([=](auto &entry) { return entry.Texture == texture; }); + if (index < List.Size()) + { + auto probe = &List[index]; + // Yes, change its assignment to this new camera + if (probe->Viewpoint != viewpoint || probe->FOV != fov) + { + texture->bFirstUpdate = true; + } + probe->Viewpoint = viewpoint; + probe->FOV = fov; + return; + } + // No, create a new assignment + auto probe = &List[List.Reserve(1)]; + probe->Viewpoint = viewpoint; + probe->Texture = texture; + probe->PicNum = picnum; + probe->FOV = fov; + texture->bFirstUpdate = true; +} + +//========================================================================== +// +// SetCameraToTexture +// +// [ZZ] expose this to ZScript +// +//========================================================================== + +void SetCameraToTexture(AActor *viewpoint, const FString &texturename, double fov) +{ + FTextureID textureid = TexMan.CheckForTexture(texturename, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); + if (textureid.isValid()) + { + // Only proceed if the texture actually has a canvas. + FTexture *tex = TexMan.GetTexture(textureid); + if (tex && tex->isCanvas()) + { + level.canvasTextureInfo.Add(viewpoint, textureid, fov); + } + } +} + +//========================================================================== +// +// FCanvasTextureInfo :: UpdateAll +// +// Updates all canvas textures that were visible in the last frame. +// +//========================================================================== + +void FCanvasTextureInfo::UpdateAll(std::function callback) +{ + for (auto &probe : List) + { + if (probe.Viewpoint != nullptr && probe.Texture->bNeedsUpdate) + { + callback(probe.Viewpoint, probe.Texture, probe.FOV); + } + } +} + +//========================================================================== +// +// FCanvasTextureInfo :: EmptyList +// +// Removes all camera->texture assignments. +// +//========================================================================== + +void FCanvasTextureInfo::EmptyList () +{ + List.Clear(); +} + +//========================================================================== +// +// FCanvasTextureInfo :: Serialize +// +// Reads or writes the current set of mappings in an archive. +// +//========================================================================== + +void FCanvasTextureInfo::Serialize(FSerializer &arc) +{ + if (arc.isWriting()) + { + if (List.Size() > 0) + { + if (arc.BeginArray("canvastextures")) + { + for (auto &probe : List) + { + if (probe.Texture != nullptr && probe.Viewpoint != nullptr) + { + if (arc.BeginObject(nullptr)) + { + arc("viewpoint", probe.Viewpoint) + ("fov", probe.FOV) + ("texture", probe.PicNum) + .EndObject(); + } + } + } + arc.EndArray(); + } + } + } + else + { + if (arc.BeginArray("canvastextures")) + { + AActor *viewpoint = nullptr; + double fov; + FTextureID picnum; + while (arc.BeginObject(nullptr)) + { + arc("viewpoint", viewpoint) + ("fov", fov) + ("texture", picnum) + .EndObject(); + Add(viewpoint, picnum, fov); + } + arc.EndArray(); + } + } +} + +//========================================================================== +// +// FCanvasTextureInfo :: Mark +// +// Marks all viewpoints in the list for the collector. +// +//========================================================================== + +void FCanvasTextureInfo::Mark() +{ + for (auto & info : List) + { + GC::Mark(info.Viewpoint); + } +} + diff --git a/src/r_data/r_canvastexture.h b/src/r_data/r_canvastexture.h new file mode 100644 index 000000000..8a82eb6e7 --- /dev/null +++ b/src/r_data/r_canvastexture.h @@ -0,0 +1,25 @@ +#pragma once + +class FCanvasTexture; +// This list keeps track of the cameras that draw into canvas textures. +struct FCanvasTextureEntry +{ + FCanvasTextureInfo *Next; + TObjPtr Viewpoint; + FCanvasTexture *Texture; + FTextureID PicNum; + double FOV; +}; + + +struct FCanvasTextureInfo +{ + TArray List; + + void Add (AActor *viewpoint, FTextureID picnum, double fov); + void UpdateAll (std::function callback); + void EmptyList (); + void Serialize(FSerializer &arc); + void Mark(); + +}; \ No newline at end of file diff --git a/src/r_renderer.h b/src/r_renderer.h index 225d57740..46fd9a430 100644 --- a/src/r_renderer.h +++ b/src/r_renderer.h @@ -28,9 +28,6 @@ struct FRenderer // renders view to a savegame picture virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height) = 0; - // render to a camera texture - virtual void RenderTextureView(FCanvasTexture *tex, AActor *viewpoint, double fov) = 0; - // draws player sprites with hardware acceleration (only useful for software rendering) virtual void DrawRemainingPlayerSprites() = 0; diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 6adfbc5ac..9117fc01f 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -146,8 +146,6 @@ int validcount = 1; // increment every time a check is made int dl_validcount = 1; // increment every time a check is made int freelookviewheight; -FCanvasTextureInfo *FCanvasTextureInfo::List; - DVector3a view; DAngle viewpitch; @@ -433,7 +431,6 @@ static void R_Shutdown () SWRenderer = nullptr; R_DeinitTranslationTables(); R_DeinitColormaps (); - FCanvasTextureInfo::EmptyList(); } //========================================================================== @@ -1052,195 +1049,6 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor } -//========================================================================== -// -// FCanvasTextureInfo :: Add -// -// Assigns a camera to a canvas texture. -// -//========================================================================== - -void FCanvasTextureInfo::Add (AActor *viewpoint, FTextureID picnum, double fov) -{ - FCanvasTextureInfo *probe; - FCanvasTexture *texture; - - if (!picnum.isValid()) - { - return; - } - texture = static_cast(TexMan.GetTexture(picnum)); - if (!texture->bHasCanvas) - { - Printf ("%s is not a valid target for a camera\n", texture->Name.GetChars()); - return; - } - - // Is this texture already assigned to a camera? - for (probe = List; probe != NULL; probe = probe->Next) - { - if (probe->Texture == texture) - { - // Yes, change its assignment to this new camera - if (probe->Viewpoint != viewpoint || probe->FOV != fov) - { - texture->bFirstUpdate = true; - } - probe->Viewpoint = viewpoint; - probe->FOV = fov; - return; - } - } - // No, create a new assignment - probe = new FCanvasTextureInfo; - probe->Viewpoint = viewpoint; - probe->Texture = texture; - probe->PicNum = picnum; - probe->FOV = fov; - probe->Next = List; - texture->bFirstUpdate = true; - List = probe; -} - -// [ZZ] expose this to ZScript -void SetCameraToTexture(AActor *viewpoint, const FString &texturename, double fov) -{ - FTextureID textureid = TexMan.CheckForTexture(texturename, ETextureType::Wall, FTextureManager::TEXMAN_Overridable); - if (textureid.isValid()) - { - // Only proceed if the texture actually has a canvas. - FTexture *tex = TexMan.GetTexture(textureid); - if (tex && tex->isCanvas()) - { - FCanvasTextureInfo::Add(viewpoint, textureid, fov); - } - } -} - -DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, SetCameraToTexture, SetCameraToTexture) -{ - PARAM_PROLOGUE; - PARAM_OBJECT(viewpoint, AActor); - PARAM_STRING(texturename); // [ZZ] there is no point in having this as FTextureID because it's easier to refer to a cameratexture by name and it isn't executed too often to cache it. - PARAM_FLOAT(fov); - SetCameraToTexture(viewpoint, texturename, fov); - return 0; -} - -//========================================================================== -// -// FCanvasTextureInfo :: UpdateAll -// -// Updates all canvas textures that were visible in the last frame. -// -//========================================================================== - -void FCanvasTextureInfo::UpdateAll () -{ - FCanvasTextureInfo *probe; - - for (probe = List; probe != NULL; probe = probe->Next) - { - if (probe->Viewpoint != NULL && probe->Texture->bNeedsUpdate) - { - screen->RenderTextureView(probe->Texture, probe->Viewpoint, probe->FOV); - } - } -} - -//========================================================================== -// -// FCanvasTextureInfo :: EmptyList -// -// Removes all camera->texture assignments. -// -//========================================================================== - -void FCanvasTextureInfo::EmptyList () -{ - FCanvasTextureInfo *probe, *next; - - for (probe = List; probe != NULL; probe = next) - { - next = probe->Next; - //probe->Texture->Unload(); - delete probe; - } - List = NULL; -} - -//========================================================================== -// -// FCanvasTextureInfo :: Serialize -// -// Reads or writes the current set of mappings in an archive. -// -//========================================================================== - -void FCanvasTextureInfo::Serialize(FSerializer &arc) -{ - if (arc.isWriting()) - { - if (List != nullptr) - { - if (arc.BeginArray("canvastextures")) - { - FCanvasTextureInfo *probe; - - for (probe = List; probe != nullptr; probe = probe->Next) - { - if (probe->Texture != nullptr && probe->Viewpoint != nullptr) - { - if (arc.BeginObject(nullptr)) - { - arc("viewpoint", probe->Viewpoint) - ("fov", probe->FOV) - ("texture", probe->PicNum) - .EndObject(); - } - } - } - arc.EndArray(); - } - } - } - else - { - if (arc.BeginArray("canvastextures")) - { - AActor *viewpoint = nullptr; - double fov; - FTextureID picnum; - while (arc.BeginObject(nullptr)) - { - arc("viewpoint", viewpoint) - ("fov", fov) - ("texture", picnum) - .EndObject(); - Add(viewpoint, picnum, fov); - } - arc.EndArray(); - } - } -} - -//========================================================================== -// -// FCanvasTextureInfo :: Mark -// -// Marks all viewpoints in the list for the collector. -// -//========================================================================== - -void FCanvasTextureInfo::Mark() -{ - for (FCanvasTextureInfo *probe = List; probe != NULL; probe = probe->Next) - { - GC::Mark(probe->Viewpoint); - } -} - - //========================================================================== // // CVAR transsouls diff --git a/src/r_utility.h b/src/r_utility.h index e5ac4a2b8..1eb93096a 100644 --- a/src/r_utility.h +++ b/src/r_utility.h @@ -138,25 +138,5 @@ double R_ClampVisibility(double vis); extern void R_FreePastViewers (); extern void R_ClearPastViewer (AActor *actor); -class FCanvasTexture; -// This list keeps track of the cameras that draw into canvas textures. -struct FCanvasTextureInfo -{ - FCanvasTextureInfo *Next; - TObjPtr Viewpoint; - FCanvasTexture *Texture; - FTextureID PicNum; - double FOV; - - static void Add (AActor *viewpoint, FTextureID picnum, double fov); - static void UpdateAll (); - static void EmptyList (); - static void Serialize(FSerializer &arc); - static void Mark(); - -private: - static FCanvasTextureInfo *List; -}; - #endif diff --git a/src/scripting/vmthunks.cpp b/src/scripting/vmthunks.cpp index 737d2f81b..ad44203b1 100644 --- a/src/scripting/vmthunks.cpp +++ b/src/scripting/vmthunks.cpp @@ -1584,6 +1584,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, ReplaceTextures, ReplaceTextures) return 0; } +void SetCameraToTexture(AActor *viewpoint, const FString &texturename, double fov); + +DEFINE_ACTION_FUNCTION_NATIVE(_TexMan, SetCameraToTexture, SetCameraToTexture) +{ + PARAM_PROLOGUE; + PARAM_OBJECT(viewpoint, AActor); + PARAM_STRING(texturename); // [ZZ] there is no point in having this as FTextureID because it's easier to refer to a cameratexture by name and it isn't executed too often to cache it. + PARAM_FLOAT(fov); + SetCameraToTexture(viewpoint, texturename, fov); + return 0; +} + + //===================================================================================== // // secplane_t exports diff --git a/src/swrenderer/r_swrenderer.cpp b/src/swrenderer/r_swrenderer.cpp index 9cd3fb309..873f5c85d 100644 --- a/src/swrenderer/r_swrenderer.cpp +++ b/src/swrenderer/r_swrenderer.cpp @@ -52,6 +52,7 @@ #include "p_setup.h" #include "g_levellocals.h" #include "image.h" +#include "imagehelpers.h" // [BB] Use ZDoom's freelook limit for the sotfware renderer. // Note: ZDoom's limit is chosen such that the sky is rendered properly. @@ -201,7 +202,10 @@ void FSoftwareRenderer::RenderView(player_t *player, DCanvas *target, void *vide r_viewwindow = mScene.MainThread()->Viewport->viewwindow; } - FCanvasTextureInfo::UpdateAll(); + level.canvasTextureInfo.UpdateAll([&](AActor *camera, FCanvasTexture *camtex, double fov) + { + RenderTextureView(camtex, camera, fov); + }); } void FSoftwareRenderer::WriteSavePic (player_t *player, FileWriter *file, int width, int height) @@ -255,9 +259,8 @@ void FSoftwareRenderer::SetClearColor(int color) mScene.SetClearColor(color); } -void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, double fov) +void FSoftwareRenderer::RenderTextureView (FCanvasTexture *camtex, AActor *viewpoint, double fov) { -#if 0 // This will require a complete redesign. auto renderTarget = V_IsPolyRenderer() ? PolyRenderer::Instance()->RenderTarget : mScene.MainThread()->Viewport->RenderTarget; auto &cameraViewpoint = V_IsPolyRenderer() ? PolyRenderer::Instance()->Viewpoint : mScene.MainThread()->Viewport->viewpoint; auto &cameraViewwindow = V_IsPolyRenderer() ? PolyRenderer::Instance()->Viewwindow : mScene.MainThread()->Viewport->viewwindow; @@ -265,8 +268,9 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin // Grab global state shared with rest of zdoom cameraViewpoint = r_viewpoint; cameraViewwindow = r_viewwindow; + + auto tex = static_cast(camtex->GetSoftwareTexture()); - uint8_t *Pixels = renderTarget->IsBgra() ? (uint8_t*)tex->GetPixelsBgra() : (uint8_t*)tex->GetPixels(DefaultRenderStyle()); DCanvas *Canvas = renderTarget->IsBgra() ? tex->GetCanvasBgra() : tex->GetCanvas(); // curse Doom's overuse of global variables in the renderer. @@ -277,66 +281,19 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin R_SetFOV (cameraViewpoint, fov); if (V_IsPolyRenderer()) - PolyRenderer::Instance()->RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate); + PolyRenderer::Instance()->RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), camtex->bFirstUpdate); else - mScene.RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), tex->bFirstUpdate); + mScene.RenderViewToCanvas(viewpoint, Canvas, 0, 0, tex->GetWidth(), tex->GetHeight(), camtex->bFirstUpdate); R_SetFOV (cameraViewpoint, savedfov); - if (Canvas->IsBgra()) - { - if (Pixels == Canvas->GetPixels()) - { - FTexture::FlipSquareBlockBgra((uint32_t*)Pixels, tex->GetWidth(), tex->GetHeight()); - } - else - { - FTexture::FlipNonSquareBlockBgra((uint32_t*)Pixels, (const uint32_t*)Canvas->GetPixels(), tex->GetWidth(), tex->GetHeight(), Canvas->GetPitch()); - } - } - else - { - if (Pixels == Canvas->GetPixels()) - { - FTexture::FlipSquareBlockRemap(Pixels, tex->GetWidth(), tex->GetHeight(), GPalette.Remap); - } - else - { - FTexture::FlipNonSquareBlockRemap(Pixels, Canvas->GetPixels(), tex->GetWidth(), tex->GetHeight(), Canvas->GetPitch(), GPalette.Remap); - } - } - - if (renderTarget->IsBgra()) - { - // True color render still sometimes uses palette textures (for sprites, mostly). - // We need to make sure that both pixel buffers contain data: - int width = tex->GetWidth(); - int height = tex->GetHeight(); - uint8_t *palbuffer = (uint8_t *)tex->GetPixels(DefaultRenderStyle()); - uint32_t *bgrabuffer = (uint32_t*)tex->GetPixelsBgra(); - for (int x = 0; x < width; x++) - { - for (int y = 0; y < height; y++) - { - uint32_t color = bgrabuffer[y]; - int r = RPART(color); - int g = GPART(color); - int b = BPART(color); - palbuffer[y] = RGB32k.RGB[r >> 3][g >> 3][b >> 3]; - } - palbuffer += height; - bgrabuffer += height; - } - } - - tex->SetUpdated(); + tex->UpdatePixels(renderTarget->IsBgra()); *CameraLight::Instance() = savedCameraLight; // Sync state back to zdoom r_viewpoint = cameraViewpoint; r_viewwindow = cameraViewwindow; -#endif } void FSoftwareRenderer::SetColormap() diff --git a/src/swrenderer/r_swrenderer.h b/src/swrenderer/r_swrenderer.h index b9bb28019..61d0044ff 100644 --- a/src/swrenderer/r_swrenderer.h +++ b/src/swrenderer/r_swrenderer.h @@ -21,7 +21,7 @@ struct FSoftwareRenderer : public FRenderer void DrawRemainingPlayerSprites() override; void SetClearColor(int color) override; - void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, double fov) override; + void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, double fov); void SetColormap() override; void Init() override; diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index 5e3721fe9..100825252 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -43,7 +43,8 @@ FSoftwareTexture *FTexture::GetSoftwareTexture() { if (!SoftwareTexture) { - if (bWarped) SoftwareTexture = new FWarpTexture(this, bWarped); + if (bHasCanvas) SoftwareTexture = new FSWCanvasTexture(this); + else if (bWarped) SoftwareTexture = new FWarpTexture(this, bWarped); else SoftwareTexture = new FSoftwareTexture(this); } return SoftwareTexture; diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index 791619e77..14810b071 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -2,6 +2,7 @@ #include "textures/textures.h" #include "v_video.h" + struct FSoftwareTextureSpan { uint16_t TopOffset; @@ -62,7 +63,6 @@ public: int GetHeight () { return mTexture->GetHeight(); } int GetWidthBits() { return WidthBits; } int GetHeightBits() { return HeightBits; } - bool Mipmapped() { return mTexture->Mipmapped(); } int GetScaledWidth () { return mTexture->GetScaledWidth(); } int GetScaledHeight () { return mTexture->GetScaledHeight(); } @@ -95,7 +95,7 @@ public: DVector2 GetScale() const { return mTexture->Scale; } - void Unload() + virtual void Unload() { Pixels.Reset(); PixelsBgra.Reset(); @@ -112,6 +112,9 @@ public: void GenerateBgraMipmapsFast(); int MipmapLevels(); + // Returns true if GetPixelsBgra includes mipmaps + virtual bool Mipmapped() { return true; } + // Returns a single column of the texture virtual const uint8_t *GetColumn(int style, unsigned int column, const FSoftwareTextureSpan **spans_out); @@ -166,3 +169,29 @@ private: int NextPo2 (int v); // [mxd] void SetupMultipliers (int width, int height); // [mxd] }; + +class FSWCanvasTexture : public FSoftwareTexture +{ + void MakeTexture(); + void MakeTextureBgra(); + + DCanvas *Canvas = nullptr; + DCanvas *CanvasBgra = nullptr; + +public: + + FSWCanvasTexture(FTexture *source) : FSoftwareTexture(source) {} + ~FSWCanvasTexture(); + + // Returns the whole texture, stored in column-major order + const uint32_t *GetPixelsBgra() override; + const uint8_t *GetPixels(int style) override; + + virtual void Unload() override; + void UpdatePixels(bool truecolor); + + DCanvas *GetCanvas() { return Canvas; } + DCanvas *GetCanvasBgra() { return CanvasBgra; } + bool Mipmapped() override { return false; } + +}; \ No newline at end of file diff --git a/src/swrenderer/textures/swcanvastexture.cpp b/src/swrenderer/textures/swcanvastexture.cpp new file mode 100644 index 000000000..8c47ad152 --- /dev/null +++ b/src/swrenderer/textures/swcanvastexture.cpp @@ -0,0 +1,189 @@ +/* +** texture.cpp +** The base texture class +** +**--------------------------------------------------------------------------- +** Copyright 2004-2007 Randy Heit +** Copyright 2006-2018 Christoph Oelckers +** All rights reserved. +** +** Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions +** are met: +** +** 1. Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** 2. Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in the +** documentation and/or other materials provided with the distribution. +** 3. The name of the author may not be used to endorse or promote products +** derived from this software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +**--------------------------------------------------------------------------- +** +** +*/ + +#include "r_swtexture.h" +#include "bitmap.h" +#include "m_alloc.h" +#include "imagehelpers.h" + + +FSWCanvasTexture::~FSWCanvasTexture() +{ + if (Canvas != nullptr) + { + delete Canvas; + Canvas = nullptr; + } + + if (CanvasBgra != nullptr) + { + delete CanvasBgra; + CanvasBgra = nullptr; + } +} + + +//========================================================================== +// +// +// +//========================================================================== + +const uint8_t *FSWCanvasTexture::GetPixels(int style) +{ + static_cast(mTexture)->NeedUpdate(); + if (Canvas == nullptr) + { + MakeTexture(); + } + return Pixels.Data(); + +} + +//========================================================================== +// +// +// +//========================================================================== + +const uint32_t *FSWCanvasTexture::GetPixelsBgra() +{ + static_cast(mTexture)->NeedUpdate(); + if (CanvasBgra == nullptr) + { + MakeTextureBgra(); + } + return PixelsBgra.Data(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSWCanvasTexture::MakeTexture () +{ + Canvas = new DCanvas (GetWidth(), GetHeight(), false); + Pixels.Resize(GetWidth() * GetHeight()); + + // Draw a special "unrendered" initial texture into the buffer. + memset (Pixels.Data(), 0, GetWidth() * GetHeight() / 2); + memset (Pixels.Data() + GetWidth() * GetHeight() / 2, 255, GetWidth() * GetHeight() / 2); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSWCanvasTexture::MakeTextureBgra() +{ + CanvasBgra = new DCanvas(GetWidth(), GetHeight(), true); + PixelsBgra.Resize(GetWidth() * GetHeight()); + + // Draw a special "unrendered" initial texture into the buffer. + memset(PixelsBgra.Data(), 0, 4* GetWidth() * GetHeight() / 2); + memset(PixelsBgra.Data() + GetWidth() * GetHeight() / 2, 255, 4* GetWidth() * GetHeight() / 2); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSWCanvasTexture::Unload () +{ + if (Canvas != nullptr) + { + delete Canvas; + Canvas = nullptr; + } + + if (CanvasBgra != nullptr) + { + delete CanvasBgra; + CanvasBgra = nullptr; + } + + FSoftwareTexture::Unload(); +} + +//========================================================================== +// +// +// +//========================================================================== + +void FSWCanvasTexture::UpdatePixels(bool truecolor) +{ + + if (Canvas->IsBgra()) + { + ImageHelpers::FlipNonSquareBlock(PixelsBgra.Data(), (const uint32_t*)Canvas->GetPixels(), GetWidth(), GetHeight(), Canvas->GetPitch()); + } + else + { + ImageHelpers::FlipNonSquareBlockRemap(Pixels.Data(), Canvas->GetPixels(), GetWidth(), GetHeight(), Canvas->GetPitch(), GPalette.Remap); + } + + if (truecolor) + { + // True color render still sometimes uses palette textures (for sprites, mostly). + // We need to make sure that both pixel buffers contain data: + int width = GetWidth(); + int height = GetHeight(); + uint8_t *palbuffer = const_cast(GetPixels(0)); + const uint32_t *bgrabuffer = GetPixelsBgra(); + for (int x = 0; x < width; x++) + { + for (int y = 0; y < height; y++) + { + uint32_t color = bgrabuffer[y]; + int r = RPART(color); + int g = GPART(color); + int b = BPART(color); + palbuffer[y] = RGB32k.RGB[r >> 3][g >> 3][b >> 3]; + } + palbuffer += height; + bgrabuffer += height; + } + } + + static_cast(mTexture)->SetUpdated(false); +} \ No newline at end of file diff --git a/src/textures/formats/canvastexture.cpp b/src/textures/formats/canvastexture.cpp index da6358928..d2ddcea95 100644 --- a/src/textures/formats/canvastexture.cpp +++ b/src/textures/formats/canvastexture.cpp @@ -36,123 +36,4 @@ #include "doomtype.h" #include "v_video.h" -FCanvasTexture::FCanvasTexture (const char *name, int width, int height) -{ - Name = name; - Width = width; - Height = height; - bMasked = false; - UseType = ETextureType::Wall; - bNeedsUpdate = true; - bDidUpdate = false; - bHasCanvas = true; - bFirstUpdate = true; - bPixelsAllocated = false; -} - - -#if 0 -const uint8_t *FCanvasTexture::Get8BitPixels(bool alphatex) -{ - bNeedsUpdate = true; - if (Canvas == NULL) - { - MakeTexture (style); - } - return Pixels; -} - -const uint32_t *FCanvasTexture::GetPixelsBgra() -{ - bNeedsUpdate = true; - if (CanvasBgra == NULL) - { - MakeTextureBgra(); - } - return PixelsBgra; -} - -void FCanvasTexture::MakeTexture (FRenderStyle) // This ignores the render style because making it work as alpha texture is impractical. -{ - Canvas = new DCanvas (Width, Height, false); - - if (Width != Height || Width != Canvas->GetPitch()) - { - Pixels = new uint8_t[Width*Height]; - bPixelsAllocated = true; - } - else - { - Pixels = (uint8_t*)Canvas->GetPixels(); - bPixelsAllocated = false; - } - - // Draw a special "unrendered" initial texture into the buffer. - memset (Pixels, 0, Width*Height/2); - memset (Pixels+Width*Height/2, 255, Width*Height/2); -} -#endif - -void FCanvasTexture::MakeTextureBgra() -{ - CanvasBgra = new DCanvas(Width, Height, true); - - if (Width != Height || Width != CanvasBgra->GetPitch()) - { - PixelsBgra = new uint32_t[Width*Height]; - bPixelsAllocatedBgra = true; - } - else - { - PixelsBgra = (uint32_t*)CanvasBgra->GetPixels(); - bPixelsAllocatedBgra = false; - } - - // Draw a special "unrendered" initial texture into the buffer. - memset(PixelsBgra, 0, Width*Height / 2 * 4); - memset(PixelsBgra + Width*Height / 2, 255, Width*Height / 2 * 4); -} - -#if 0 -void FCanvasTexture::Unload () -{ - if (bPixelsAllocated) - { - if (Pixels != NULL) delete[] Pixels; - bPixelsAllocated = false; - Pixels = NULL; - } - - if (bPixelsAllocatedBgra) - { - if (PixelsBgra != NULL) delete[] PixelsBgra; - bPixelsAllocatedBgra = false; - PixelsBgra = NULL; - } - - if (Canvas != NULL) - { - delete Canvas; - Canvas = nullptr; - } - - if (CanvasBgra != NULL) - { - delete CanvasBgra; - CanvasBgra = nullptr; - } - - FTexture::Unload(); -} -#endif - -bool FCanvasTexture::CheckModified (FRenderStyle) -{ - if (bDidUpdate) - { - bDidUpdate = false; - return true; - } - return false; -} diff --git a/src/textures/image.cpp b/src/textures/image.cpp index c08ef0931..04d0833c0 100644 --- a/src/textures/image.cpp +++ b/src/textures/image.cpp @@ -225,20 +225,20 @@ FBitmap FImageSource::GetCachedBitmap(PalEntry *remap, int conversion, int *ptra trans = cache->TransInfo; if (cache->RefCount > 1) { - Printf("returning reference to %s, refcount = %d\n", name.GetChars(), cache->RefCount); + //Printf("returning reference to %s, refcount = %d\n", name.GetChars(), cache->RefCount); ret.Copy(cache->Pixels, false); cache->RefCount--; } else if (cache->Pixels.GetPixels()) { - Printf("returning contents of %s, refcount = %d\n", name.GetChars(), cache->RefCount); + //Printf("returning contents of %s, refcount = %d\n", name.GetChars(), cache->RefCount); ret = std::move(cache->Pixels); precacheDataRgba.Delete(index); } else { // This should never happen if the function is implemented correctly - Printf("something bad happened for %s, refcount = %d\n", name.GetChars(), cache->RefCount); + //Printf("something bad happened for %s, refcount = %d\n", name.GetChars(), cache->RefCount); ret.Create(Width, Height); trans = CopyPixels(&ret, normal); } @@ -250,13 +250,13 @@ FBitmap FImageSource::GetCachedBitmap(PalEntry *remap, int conversion, int *ptra if (!info || info->first <= 1 || conversion != normal) { // This is either the only copy needed or some access outside the caching block. In these cases create a new one and directly return it. - Printf("returning fresh copy of %s\n", name.GetChars()); + //Printf("returning fresh copy of %s\n", name.GetChars()); ret.Create(Width, Height); trans = CopyPixels(&ret, conversion); } else { - Printf("creating cached entry for %s, refcount = %d\n", name.GetChars(), info->first); + //Printf("creating cached entry for %s, refcount = %d\n", name.GetChars(), info->first); // This is the first time it gets accessed and needs to be placed in the cache. PrecacheDataRgba *pdr = &precacheDataRgba[precacheDataRgba.Reserve(1)]; diff --git a/src/textures/imagehelpers.h b/src/textures/imagehelpers.h index 16b5e1876..39cd83e67 100644 --- a/src/textures/imagehelpers.h +++ b/src/textures/imagehelpers.h @@ -104,7 +104,7 @@ namespace ImageHelpers { for (int i = 0; i < x; ++i) { - uint8_t *corner = block + x*i + i; + T *corner = block + x*i + i; int count = x - i; for (int j = 0; j < count; j++) { diff --git a/src/textures/textures.h b/src/textures/textures.h index 56a90608b..c5249cd15 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -392,9 +392,6 @@ protected: } } - // Returns true if GetPixelsBgra includes mipmaps - virtual bool Mipmapped() { return true; } - void SetSpeed(float fac) { shaderspeed = fac; } int GetWidth () { return Width; } @@ -673,34 +670,27 @@ class AActor; class FCanvasTexture : public FTexture { public: - FCanvasTexture (const char *name, int width, int height); + FCanvasTexture(const char *name, int width, int height) + { + Name = name; + Width = width; + Height = height; - //const uint8_t *GetColumn(FRenderStyle style, unsigned int column, const FSoftwareTextureSpan **spans_out); - //const uint32_t *GetPixelsBgra() override; + bMasked = false; + bHasCanvas = true; + bTranslucent = false; + UseType = ETextureType::Wall; + } - //const uint8_t *Get8BitPixels(bool alphatex); - bool CheckModified (FRenderStyle) /*override*/; - void NeedUpdate() { bNeedsUpdate=true; } - void SetUpdated() { bNeedsUpdate = false; bDidUpdate = true; bFirstUpdate = false; } - DCanvas *GetCanvas() { return Canvas; } - DCanvas *GetCanvasBgra() { return CanvasBgra; } - bool Mipmapped() override { return false; } - void MakeTextureBgra (); + void NeedUpdate() { bNeedsUpdate = true; } + void SetUpdated(bool rendertype) { bNeedsUpdate = false; bFirstUpdate = false; bLastUpdateType = rendertype; } protected: - DCanvas *Canvas = nullptr; - DCanvas *CanvasBgra = nullptr; - uint8_t *Pixels = nullptr; - uint32_t *PixelsBgra = nullptr; - //FSoftwareTextureSpan DummySpans[2]; + bool bLastUpdateType = false; bool bNeedsUpdate = true; - bool bDidUpdate = false; - bool bPixelsAllocated = false; - bool bPixelsAllocatedBgra = false; public: - bool bFirstUpdate; - + bool bFirstUpdate = true; friend struct FCanvasTextureInfo; }; diff --git a/src/v_framebuffer.cpp b/src/v_framebuffer.cpp index dd697d943..43204c8be 100644 --- a/src/v_framebuffer.cpp +++ b/src/v_framebuffer.cpp @@ -359,11 +359,6 @@ uint32_t DFrameBuffer::GetCaps() return (uint32_t)FlagSet; } -void DFrameBuffer::RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV) -{ - SWRenderer->RenderTextureView(tex, Viewpoint, FOV); -} - void DFrameBuffer::WriteSavePic(player_t *player, FileWriter *file, int width, int height) { SWRenderer->WriteSavePic(player, file, width, height); diff --git a/src/v_video.h b/src/v_video.h index 918c572e3..bdf556edd 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -318,9 +318,6 @@ class FUniquePalette; class IHardwareTexture; class FTexture; -// A canvas that represents the actual display. The video code is responsible -// for actually implementing this. Built on top of SimpleCanvas, because it -// needs a system memory buffer when buffered output is enabled. class DFrameBuffer { @@ -472,7 +469,6 @@ public: void InitPalette(); void SetClearColor(int color); virtual uint32_t GetCaps(); - virtual void RenderTextureView(FCanvasTexture *tex, AActor *Viewpoint, double FOV); virtual void WriteSavePic(player_t *player, FileWriter *file, int width, int height); virtual sector_t *RenderView(player_t *player) { return nullptr; } From 86d851bc5c5cbb791c0bf4e86f0fb6586534e53c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Dec 2018 19:56:23 +0100 Subject: [PATCH 33/66] - minor cleanup and allow FHardwareTexture to restore the old bindings after creating a texture. --- src/gl/textures/gl_hwtexture.cpp | 11 ++++++++--- src/hwrenderer/textures/hw_material.cpp | 2 +- src/textures/texture.cpp | 2 +- src/textures/textures.h | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index f3c78b6e6..7018e61c9 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -99,10 +99,14 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int TranslatedTexture * glTex=GetTexID(translation); bool firstCall = glTex->glTexID == 0; if (firstCall) glGenTextures(1,&glTex->glTexID); - if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit); + + unsigned textureBinding = UINT_MAX; + if (texunit == -1) glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); + if (texunit > 0) glActiveTexture(GL_TEXTURE0+texunit); + if (texunit >= 0) lastbound[texunit] = glTex->glTexID; glBindTexture(GL_TEXTURE_2D, glTex->glTexID); + FGLDebug::LabelObject(GL_TEXTURE, glTex->glTexID, name); - lastbound[texunit] = glTex->glTexID; rw = GetTexDimension(w); rh = GetTexDimension(h); @@ -168,7 +172,8 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int glTex->mipmapped = true; } - if (texunit != 0) glActiveTexture(GL_TEXTURE0); + if (texunit > 0) glActiveTexture(GL_TEXTURE0); + else if (texunit == -1) glBindTexture(GL_TEXTURE_2D, textureBinding); return glTex->glTexID; } diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 712a8e7af..0ee2f3bb9 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -140,7 +140,7 @@ IHardwareTexture * FMaterial::ValidateSysTexture(FTexture * tex, bool expand) IHardwareTexture *gltex = tex->SystemTexture[expand]; if (gltex == nullptr) { - gltex = tex->SystemTexture[expand] = screen->CreateHardwareTexture(tex); + gltex = tex->SystemTexture[expand] = screen->CreateHardwareTexture(); } return gltex; } diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 0b22866ef..f91f7acc9 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -774,7 +774,7 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits) Format = bits; UseType = ETextureType::SWCanvas; bNoCompress = true; - SystemTexture[0] = screen->CreateHardwareTexture(this); + SystemTexture[0] = screen->CreateHardwareTexture(); } //=========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index c5249cd15..52cf9b97a 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -42,6 +42,7 @@ #include "colormatcher.h" #include "r_data/renderstyle.h" #include "r_data/r_translate.h" +#include "hwrenderer/textures/hw_texmanager.h" #include // 15 because 0th texture is our texture From f01d1ec072cf22899a62fa50dfd086fda14f306d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Dec 2018 20:26:33 +0100 Subject: [PATCH 34/66] - must merge before continuing... --- src/gl/system/gl_framebuffer.cpp | 2 +- src/gl/system/gl_framebuffer.h | 2 +- src/textures/hires/hirestex.cpp | 16 +++++++++----- src/textures/hires/hqresize.cpp | 26 +++++++++++------------ src/textures/image.h | 1 + src/textures/texture.cpp | 30 +++++++++++++++++--------- src/textures/textures.h | 36 +++++++++++++++++++++++++------- src/v_video.h | 2 +- 8 files changed, 75 insertions(+), 40 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 58cc8be22..ca2616cfd 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -326,7 +326,7 @@ void OpenGLFrameBuffer::SetTextureFilterMode() if (GLRenderer != nullptr && GLRenderer->mSamplerManager != nullptr) GLRenderer->mSamplerManager->SetTextureFilterMode(); } -IHardwareTexture *OpenGLFrameBuffer::CreateHardwareTexture(FTexture *tex) +IHardwareTexture *OpenGLFrameBuffer::CreateHardwareTexture() { return new FHardwareTexture(true/*tex->bNoCompress*/); } diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 60929d947..5ebc586b0 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -33,7 +33,7 @@ public: void WriteSavePic(player_t *player, FileWriter *file, int width, int height) override; sector_t *RenderView(player_t *player) override; void SetTextureFilterMode() override; - IHardwareTexture *CreateHardwareTexture(FTexture *tex) override; + IHardwareTexture *CreateHardwareTexture() override; void PrecacheMaterial(FMaterial *mat, int translation) override; bool CheckPrecacheMaterial(FMaterial *mat) override; FModelRenderer *CreateModelRenderer(int mli) override; diff --git a/src/textures/hires/hirestex.cpp b/src/textures/hires/hirestex.cpp index b2edce48c..824e61d5e 100644 --- a/src/textures/hires/hirestex.cpp +++ b/src/textures/hires/hirestex.cpp @@ -36,6 +36,7 @@ #include "gi.h" #include "cmdlib.h" #include "bitmap.h" +#include "image.h" #ifndef _WIN32 #define _access(a,b) access(a,b) @@ -357,7 +358,7 @@ int FTexture::CheckExternalFile(bool & hascolorkey) // //========================================================================== -unsigned char *FTexture::LoadHiresTexture(int *width, int *height) +bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer) { if (HiresLump == -1) { @@ -396,10 +397,15 @@ unsigned char *FTexture::LoadHiresTexture(int *width, int *height) if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0; } } - *width = w; - *height = h; - return buffer; + FContentId contentId; + contentId.id = 0; + contentId.imageID = HiresTexture->GetImage()->GetId(); + texbuffer.mBuffer = buffer; + texbuffer.mWidth = w; + texbuffer.mHeight = h; + texbuffer.mContentId = contentId.id; + return true; } - return nullptr; + return false; } diff --git a/src/textures/hires/hqresize.cpp b/src/textures/hires/hqresize.cpp index 01f310ed2..0ba4b247b 100644 --- a/src/textures/hires/hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -348,46 +348,44 @@ static void xbrzOldScale(size_t factor, const uint32_t* src, uint32_t* trg, int // the upsampled buffer. // //=========================================================================== -unsigned char *FTexture::CreateUpsampledTextureBuffer (unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight, bool hasAlpha ) +void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha) { // [BB] Make sure that outWidth and outHeight denote the size of // the returned buffer even if we don't upsample the input buffer. - outWidth = inWidth; - outHeight = inHeight; + int outWidth = texbuffer.mWidth; + int outHeight = texbuffer.mHeight; // [BB] Don't resample if the width or height of the input texture is bigger than gl_texture_hqresize_maxinputsize. - if ( ( inWidth > gl_texture_hqresize_maxinputsize ) || ( inHeight > gl_texture_hqresize_maxinputsize ) ) - return inputBuffer; + if ( ( outWidth > gl_texture_hqresize_maxinputsize ) || ( outHeight > gl_texture_hqresize_maxinputsize ) ) + return; - // [BB] Don't try to upsample textures based off FCanvasTexture. + // [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!) if ( bHasCanvas ) - return inputBuffer; + return; // already scaled? if (Scale.X >= 2 && Scale.Y >= 2) - return inputBuffer; + return; switch (UseType) { case ETextureType::Sprite: case ETextureType::SkinSprite: - if (!(gl_texture_hqresize_targets & 2)) return inputBuffer; + if (!(gl_texture_hqresize_targets & 2)) return; break; case ETextureType::FontChar: - if (!(gl_texture_hqresize_targets & 4)) return inputBuffer; + if (!(gl_texture_hqresize_targets & 4)) return; break; default: - if (!(gl_texture_hqresize_targets & 1)) return inputBuffer; + if (!(gl_texture_hqresize_targets & 1)) return; break; } - if (inputBuffer) + if (texbuffer.mBuffer) { int type = gl_texture_hqresize; - outWidth = inWidth; - outHeight = inHeight; #ifdef HAVE_MMX // hqNx MMX does not preserve the alpha channel so fall back to C-version for such textures if (hasAlpha && type > 6 && type <= 9) diff --git a/src/textures/image.h b/src/textures/image.h index e53fc2035..7e0db353f 100644 --- a/src/textures/image.h +++ b/src/textures/image.h @@ -64,6 +64,7 @@ public: bool bMasked = true; // Image (might) have holes (Assume true unless proven otherwise!) int8_t bTranslucent = -1; // Image has pixels with a non-0/1 value. (-1 means the user needs to do a real check) + int GetId() const { return ImageID; } // 'noremap0' will only be looked at by FPatchTexture and forwarded by FMultipatchTexture. diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index f91f7acc9..538ece45c 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -661,23 +661,22 @@ bool FTexture::ProcessData(unsigned char * buffer, int w, int h, bool ispatch) // //=========================================================================== -unsigned char * FTexture::CreateTexBuffer(int translation, int & w, int & h, int flags) +FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) { + FTextureBuffer result; + unsigned char * buffer = nullptr; int W, H; int isTransparent = -1; if (flags & CTF_CheckHires) { - buffer = LoadHiresTexture(&w, &h); - if (buffer != nullptr) - return buffer; + if (LoadHiresTexture(result)) return result; } - int exx = !!(flags & CTF_Expand); - W = w = GetWidth() + 2 * exx; - H = h = GetHeight() + 2 * exx; + W = GetWidth() + 2 * exx; + H = GetHeight() + 2 * exx; buffer = new unsigned char[W*(H + 1) * 4]; memset(buffer, 0, W * (H + 1) * 4); @@ -700,13 +699,24 @@ unsigned char * FTexture::CreateTexBuffer(int translation, int & w, int & h, int // A translated image is not conclusive for setting the texture's transparency info. } + FContentId builder; + builder.id = 0; + builder.imageID = GetImage()->GetId(); + builder.translation = MAX(0, translation); + builder.expand = exx; + + result.mBuffer = buffer; + result.mWidth = W; + result.mHeight = H; + result.mContentId = builder.id; + if (flags & CTF_ProcessData) { - buffer = CreateUpsampledTextureBuffer(buffer, W, H, w, h, !!isTransparent); - ProcessData(buffer, w, h, false); + CreateUpsampledTextureBuffer(result, !!isTransparent); + ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); } - return buffer; + return result; } //=========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index 52cf9b97a..47e4da28f 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -226,6 +226,31 @@ namespace OpenGLRenderer class FHardwareTexture; } +union FContentId +{ + uint64_t id; + struct + { + unsigned imageID : 24; + unsigned translation : 16; + unsigned expand : 1; + unsigned scaler : 4; + unsigned scalefactor : 4; + }; +}; + +struct FTextureBuffer +{ + uint8_t *mBuffer = nullptr; + int mWidth = 0; + int mHeight = 0; + uint64_t mContentId = 0; // unique content identifier. (Two images created from the same image source with the same settings will return the same value.) + + FTextureBuffer() + { + if (mBuffer) delete[] mBuffer; + } +}; // Base texture class class FTexture @@ -258,12 +283,7 @@ public: virtual ~FTexture (); virtual FImageSource *GetImage() const { return nullptr; } void AddAutoMaterials(); - unsigned char *CreateUpsampledTextureBuffer(unsigned char *inputBuffer, const int inWidth, const int inHeight, int &outWidth, int &outHeight, bool hasAlpha); - - // These should only be used in places where the texture scaling must be ignored and absolutely nowhere else! - // Preferably all code depending on the physical texture size should be rewritten, unless it is part of the software rasterizer. - //int GetPixelWidth() { return GetWidth(); } - //int GetPixelHeight() { return GetHeight(); } + void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha); // These are mainly meant for 2D code which only needs logical information about the texture to position it properly. int GetDisplayWidth() { return GetScaledWidth(); } @@ -466,13 +486,13 @@ protected: public: - unsigned char * CreateTexBuffer(int translation, int & w, int & h, int flags = 0); + FTextureBuffer CreateTexBuffer(int translation, int flags = 0); bool GetTranslucency(); private: int CheckDDPK3(); int CheckExternalFile(bool & hascolorkey); - unsigned char *LoadHiresTexture(int *width, int *height); + bool LoadHiresTexture(FTextureBuffer &texbuffer); bool bSWSkyColorDone = false; PalEntry FloorSkyColor; diff --git a/src/v_video.h b/src/v_video.h index bdf556edd..bbbcb71f9 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -424,7 +424,7 @@ public: // Delete any resources that need to be deleted after restarting with a different IWAD virtual void CleanForRestart() {} virtual void SetTextureFilterMode() {} - virtual IHardwareTexture *CreateHardwareTexture(FTexture *tex) { return nullptr; } + virtual IHardwareTexture *CreateHardwareTexture() { return nullptr; } virtual bool CheckPrecacheMaterial(FMaterial *mat) { return true; } virtual void PrecacheMaterial(FMaterial *mat, int translation) {} virtual FModelRenderer *CreateModelRenderer(int mli) { return nullptr; } From 07f87e2542ffce63c48eb8a621298052b82e4427 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Dec 2018 21:06:34 +0100 Subject: [PATCH 35/66] - changed CreateTexBuffer to return its info in a structure and not as a naked pointer. --- src/gl/shaders/gl_postprocessshader.cpp | 7 +- src/gl/textures/gl_hwtexture.cpp | 13 ++-- src/hwrenderer/textures/hw_material.cpp | 20 ++--- src/posix/cocoa/i_video.mm | 12 ++- src/textures/hires/hirestex.cpp | 2 +- src/textures/hires/hqresize.cpp | 98 +++++++++++++------------ src/textures/texture.cpp | 27 ++++--- src/textures/textures.h | 3 +- 8 files changed, 93 insertions(+), 89 deletions(-) diff --git a/src/gl/shaders/gl_postprocessshader.cpp b/src/gl/shaders/gl_postprocessshader.cpp index e57196462..0e87275e0 100644 --- a/src/gl/shaders/gl_postprocessshader.cpp +++ b/src/gl/shaders/gl_postprocessshader.cpp @@ -226,16 +226,15 @@ void PostProcessShaderInstance::BindTextures() if (it == mTextureHandles.end()) { // Why does this completely circumvent the normal way of handling textures? - int width, height; - auto buffer = tex->CreateTexBuffer(0, width, height); + // This absolutely needs fixing because it will also circumvent any potential caching system that may get implemented. + auto buffer = tex->CreateTexBuffer(0); GLuint handle = 0; glGenTextures(1, &handle); glBindTexture(GL_TEXTURE_2D, handle); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, buffer.mWidth, buffer.mHeight, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer.mBuffer); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - delete[] buffer; mTextureHandles[tex] = handle; } else diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 7018e61c9..7f4093af8 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -100,7 +100,7 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int bool firstCall = glTex->glTexID == 0; if (firstCall) glGenTextures(1,&glTex->glTexID); - unsigned textureBinding = UINT_MAX; + int textureBinding = UINT_MAX; if (texunit == -1) glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); if (texunit > 0) glActiveTexture(GL_TEXTURE0+texunit); if (texunit >= 0) lastbound[texunit] = glTex->glTexID; @@ -448,24 +448,25 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i int w = 0, h = 0; // Create this texture - unsigned char * buffer = nullptr; + + FTextureBuffer texbuffer; if (!tex->isHardwareCanvas()) { - buffer = tex->CreateTexBuffer(translation, w, h, flags | CTF_ProcessData); + texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData); + w = texbuffer.mWidth; + h = texbuffer.mHeight; } else { w = tex->GetWidth(); h = tex->GetHeight(); } - if (!CreateTexture(buffer, w, h, texunit, needmipmap, translation, "FHardwareTexture.BindOrCreate")) + if (!CreateTexture(texbuffer.mBuffer, w, h, texunit, needmipmap, translation, "FHardwareTexture.BindOrCreate")) { // could not create texture - delete[] buffer; return false; } - delete[] buffer; } if (tex->isHardwareCanvas()) static_cast(tex)->NeedUpdate(); GLRenderer->mSamplerManager->Bind(texunit, clampmode, 255); diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 0ee2f3bb9..30d22a7ec 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -341,19 +341,19 @@ void FMaterial::SetSpriteRect() bool FMaterial::TrimBorders(uint16_t *rect) { - int w; - int h; - unsigned char *buffer = sourcetex->CreateTexBuffer(0, w, h); + auto texbuffer = sourcetex->CreateTexBuffer(0); + int w = texbuffer.mWidth; + int h = texbuffer.mHeight; + auto Buffer = texbuffer.mBuffer; - if (buffer == NULL) + if (texbuffer.mBuffer == nullptr) { return false; } if (w != mWidth || h != mHeight) { // external Hires replacements cannot be trimmed. - delete [] buffer; return false; } @@ -365,14 +365,13 @@ bool FMaterial::TrimBorders(uint16_t *rect) rect[1] = 0; rect[2] = 1; rect[3] = 1; - delete[] buffer; return true; } int first, last; for(first = 0; first < size; first++) { - if (buffer[first*4+3] != 0) break; + if (Buffer[first*4+3] != 0) break; } if (first >= size) { @@ -381,13 +380,12 @@ bool FMaterial::TrimBorders(uint16_t *rect) rect[1] = 0; rect[2] = 1; rect[3] = 1; - delete [] buffer; return true; } for(last = size-1; last >= first; last--) { - if (buffer[last*4+3] != 0) break; + if (Buffer[last*4+3] != 0) break; } rect[1] = first / w; @@ -396,7 +394,7 @@ bool FMaterial::TrimBorders(uint16_t *rect) rect[0] = 0; rect[2] = w; - unsigned char *bufferoff = buffer + (rect[1] * w * 4); + unsigned char *bufferoff = Buffer + (rect[1] * w * 4); h = rect[3]; for(int x = 0; x < w; x++) @@ -416,13 +414,11 @@ outl: { if (bufferoff[(x+y*w)*4+3] != 0) { - delete [] buffer; return true; } } rect[2]--; } - delete [] buffer; return true; } diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index d10c590b2..f5fd5b00b 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -656,12 +656,11 @@ bool I_SetCursor(FTexture *cursorpic) { // Create bitmap image representation - int w, h; - auto sbuffer = cursorpic->CreateTexBuffer(0, w, h); + auto sbuffer = cursorpic->CreateTexBuffer(0); - const NSInteger imageWidth = w; - const NSInteger imageHeight = h; - const NSInteger imagePitch = w * 4; + const NSInteger imageWidth = sbuffer.mWidth; + const NSInteger imageHeight = sbuffer.mHeight; + const NSInteger imagePitch = sbuffer.mWidth * 4; NSBitmapImageRep* bitmapImageRep = [NSBitmapImageRep alloc]; [bitmapImageRep initWithBitmapDataPlanes:NULL @@ -678,8 +677,7 @@ bool I_SetCursor(FTexture *cursorpic) // Load bitmap data to representation uint8_t* buffer = [bitmapImageRep bitmapData]; - memcpy(buffer, sbuffer, imagePitch * imageHeight); - delete [] sbuffer; + memcpy(buffer, sbuffer.mBuffer, imagePitch * imageHeight); // Swap red and blue components in each pixel diff --git a/src/textures/hires/hirestex.cpp b/src/textures/hires/hirestex.cpp index 824e61d5e..1e05d22bd 100644 --- a/src/textures/hires/hirestex.cpp +++ b/src/textures/hires/hirestex.cpp @@ -397,7 +397,7 @@ bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer) if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0; } } - FContentId contentId; + FContentIdBuilder contentId; contentId.id = 0; contentId.imageID = HiresTexture->GetImage()->GetId(); texbuffer.mBuffer = buffer; diff --git a/src/textures/hires/hqresize.cpp b/src/textures/hires/hqresize.cpp index 31bcbfa15..b9da15ad4 100644 --- a/src/textures/hires/hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -348,23 +348,23 @@ static void xbrzOldScale(size_t factor, const uint32_t* src, uint32_t* trg, int //=========================================================================== // -// [BB] Upsamples the texture in inputBuffer, frees inputBuffer and returns +// [BB] Upsamples the texture in texbuffer.mBuffer, frees texbuffer.mBuffer and returns // the upsampled buffer. // //=========================================================================== void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha) { - // [BB] Make sure that outWidth and outHeight denote the size of + // [BB] Make sure that inWidth and inHeight denote the size of // the returned buffer even if we don't upsample the input buffer. - int outWidth = texbuffer.mWidth; - int outHeight = texbuffer.mHeight; + int inWidth = texbuffer.mWidth; + int inHeight = texbuffer.mHeight; // [BB] Don't resample if the width or height of the input texture is bigger than gl_texture_hqresize_maxinputsize. - if ( ( outWidth > gl_texture_hqresize_maxinputsize ) || ( outHeight > gl_texture_hqresize_maxinputsize ) ) + if ((inWidth > gl_texture_hqresize_maxinputsize) || (inHeight > gl_texture_hqresize_maxinputsize)) return; // [BB] Don't try to upsample textures based off FCanvasTexture. (This should never get here in the first place!) - if ( bHasCanvas ) + if (bHasCanvas) return; // already scaled? @@ -401,47 +401,53 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA if (mult < 2) type = 0; - switch (type) + + if (type == 1) { - case 1: - switch(mult) - { - case 2: - return scaleNxHelper( &scale2x, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 3: - return scaleNxHelper( &scale3x, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - default: - return scaleNxHelper( &scale4x, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - } - case 2: - switch(mult) - { - case 2: - return hqNxHelper( &hq2x_32, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 3: - return hqNxHelper( &hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - default: - return hqNxHelper( &hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - } -#ifdef HAVE_MMX - case 3: - switch(mult) - { - case 2: - return hqNxAsmHelper( &HQnX_asm::hq2x_32, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 3: - return hqNxAsmHelper( &HQnX_asm::hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - default: - return hqNxAsmHelper( &HQnX_asm::hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - } -#endif - case 4: - return xbrzHelper(xbrz::scale, mult, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 5: - return xbrzHelper(xbrzOldScale, mult, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 6: - return normalNxHelper( &normalNx, mult, inputBuffer, inWidth, inHeight, outWidth, outHeight ); + if (mult == 2) + texbuffer.mBuffer = scaleNxHelper(&scale2x, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 3) + texbuffer.mBuffer = scaleNxHelper(&scale3x, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 4) + texbuffer.mBuffer = scaleNxHelper(&scale4x, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else return; } + else if (type == 2) + { + if (mult == 2) + texbuffer.mBuffer = hqNxHelper(&hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 3) + texbuffer.mBuffer = hqNxHelper(&hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 4) + texbuffer.mBuffer = hqNxHelper(&hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else return; + } +#ifdef HAVE_MMX + else if (type == 3) + { + if (mult == 2) + texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 3) + texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 4) + texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else return; + } +#endif + else if (type == 4) + texbuffer.mBuffer = xbrzHelper(xbrz::scale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (type == 5) + texbuffer.mBuffer = xbrzHelper(xbrzOldScale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (type == 6) + texbuffer.mBuffer = normalNxHelper(&normalNx, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else + return; + + // Encode the scaling method in the content ID. + FContentIdBuilder contentId; + contentId.id = texbuffer.mContentId; + contentId.scaler = type; + contentId.scalefactor = mult; + texbuffer.mContentId = contentId.id; } - return inputBuffer; } diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 538ece45c..eb8f48f96 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -671,7 +671,8 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) if (flags & CTF_CheckHires) { - if (LoadHiresTexture(result)) return result; + // No image means that this cannot be checked, + if (GetImage() && LoadHiresTexture(result)) return result; } int exx = !!(flags & CTF_Expand); @@ -699,18 +700,23 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) // A translated image is not conclusive for setting the texture's transparency info. } - FContentId builder; - builder.id = 0; - builder.imageID = GetImage()->GetId(); - builder.translation = MAX(0, translation); - builder.expand = exx; + if (GetImage()) + { + FContentIdBuilder builder; + builder.id = 0; + builder.imageID = GetImage()->GetId(); + builder.translation = MAX(0, translation); + builder.expand = exx; + result.mContentId = builder.id; + } + else result.mContentId = 0; // for non-image backed textures this has no meaning so leave it at 0. result.mBuffer = buffer; result.mWidth = W; result.mHeight = H; - result.mContentId = builder.id; - if (flags & CTF_ProcessData) + // Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.) + if (GetImage() && flags & CTF_ProcessData) { CreateUpsampledTextureBuffer(result, !!isTransparent); ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); @@ -731,9 +737,8 @@ bool FTexture::GetTranslucency() { if (!bHasCanvas) { - int w, h; - unsigned char *buffer = CreateTexBuffer(0, w, h); - delete[] buffer; + // This will calculate all we need, so just discard the result. + CreateTexBuffer(0); } else { diff --git a/src/textures/textures.h b/src/textures/textures.h index 47e4da28f..b96fc5b07 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -42,7 +42,6 @@ #include "colormatcher.h" #include "r_data/renderstyle.h" #include "r_data/r_translate.h" -#include "hwrenderer/textures/hw_texmanager.h" #include // 15 because 0th texture is our texture @@ -226,7 +225,7 @@ namespace OpenGLRenderer class FHardwareTexture; } -union FContentId +union FContentIdBuilder { uint64_t id; struct From 200188b3a4f5e7f4cd3b732cd0a6f7f825df7b37 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 00:34:37 +0100 Subject: [PATCH 36/66] - FHardwareTextureContainer. This is essentially a stripped down version of FHardwareTexture, which can exist on the API independent size, and which stores pointers to hardware textures instead of OpenGL texture handles. --- src/hwrenderer/textures/hw_texcontainer.h | 123 ++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/hwrenderer/textures/hw_texcontainer.h diff --git a/src/hwrenderer/textures/hw_texcontainer.h b/src/hwrenderer/textures/hw_texcontainer.h new file mode 100644 index 000000000..d5836d82b --- /dev/null +++ b/src/hwrenderer/textures/hw_texcontainer.h @@ -0,0 +1,123 @@ +#pragma once + +#include "tarray.h" + +struct FTextureBuffer; + +class FHardwareTextureContainer +{ +public: + enum + { + MAX_TEXTURES = 16 + }; + +private: + struct TranslatedTexture + { + IHardwareTexture *hwTexture = nullptr; + int translation = 0; + + void Delete() + { + if (hwTexture) delete hwTexture; + hwTexture = nullptr; + } + + ~TranslatedTexture() + { + Delete(); + } + }; + +private: + + TranslatedTexture hwDefTex[2]; + TArray hwTex_Translated; + + TranslatedTexture * GetTexID(int translation, bool expanded) + { + translation = TranslationToIndex(translation); + if (translation == 0) + { + return &hwDefTex[expanded]; + } + + if (expanded) translation = -translation; + // normally there aren't more than very few different + // translations here so this isn't performance critical. + unsigned index = hwTex_Translated.FindEx([=](auto &element) + { + return element.translation == translation; + } + if (index < hwTex_Translated.Size()) + { + return &hwTex_Translated[i]; + } + + int add = hwTex_Translated.Reserve(1); + auto item = &hwTex_Translated[add]; + item->translation = translation; + return item; + } + +public: + + void Clean(bool all) + { + if (all) hwDefTex.Delete(); + hwTex_Translated.Clear(); + + } + + IHardwareTexture * GetHardwareTexture(int translation, bool expanded) + { + auto tt = GetTexID(translation, expanded); + return tt->hwTexture; + } + + void AddHardwareTexture(int translation, bool expanded, IHardwareTexture *tex) + { + auto tt = GetTexID(translation, expanded); + tt->Delete(); + tt->hwTexture =tex; + } + + //=========================================================================== + // + // Deletes all allocated resources and considers translations + // This will only be called for sprites + // + //=========================================================================== + + void FHardwareTexture::CleanUnused(SpriteHits &usedtranslations, bool expanded) + { + if (usedtranslations.CheckKey(0) == nullptr) + { + hwDefTex[expanded].Delete(); + } + for (int i = hwTex_Translated.Size()-1; i>= 0; i--) + { + if (usedtranslations.CheckKey(hwTex_Translated[i].translation) == nullptr) + { + hwTex_Translated.Delete(i); + } + } + } + + static int TranslationToIndex(int translation) + { + if (translation <= 0) + { + return -translation; + } + else + { + auto remap = TranslationToTable(translation); + return remap == nullptr ? 0 : remap->GetUniqueIndex(); + } + } + + +}; + From 368c78878925bb0f68aa339f0c246cfb986d4715 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 00:46:58 +0100 Subject: [PATCH 37/66] - added a 'check only' option to CreateTexBuffer. This is meant to calculate the content ID without constructing the texture buffer. --- src/textures/hires/hirestex.cpp | 37 +++++++------- src/textures/hires/hqresize.cpp | 86 +++++++++++++++++---------------- src/textures/texture.cpp | 44 +++++++++-------- src/textures/textures.h | 5 +- 4 files changed, 91 insertions(+), 81 deletions(-) diff --git a/src/textures/hires/hirestex.cpp b/src/textures/hires/hirestex.cpp index 1e05d22bd..d18735fa7 100644 --- a/src/textures/hires/hirestex.cpp +++ b/src/textures/hires/hirestex.cpp @@ -358,7 +358,7 @@ int FTexture::CheckExternalFile(bool & hascolorkey) // //========================================================================== -bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer) +bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer, bool checkonly) { if (HiresLump == -1) { @@ -377,24 +377,27 @@ bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer) int w = HiresTexture->GetWidth(); int h = HiresTexture->GetHeight(); - unsigned char * buffer = new unsigned char[w*(h + 1) * 4]; - memset(buffer, 0, w * (h + 1) * 4); - - FBitmap bmp(buffer, w * 4, w, h); - int trans; - auto Pixels = HiresTexture->GetBgraBitmap(nullptr, &trans); - bmp.Blit(0, 0, Pixels); - - HiresTexture->CheckTrans(buffer, w*h, trans); - - if (bHiresHasColorKey) + if (!checkonly) { - // This is a crappy Doomsday color keyed image - // We have to remove the key manually. :( - uint32_t * dwdata = (uint32_t*)buffer; - for (int i = (w*h); i>0; i--) + unsigned char * buffer = new unsigned char[w*(h + 1) * 4]; + memset(buffer, 0, w * (h + 1) * 4); + + FBitmap bmp(buffer, w * 4, w, h); + int trans; + auto Pixels = HiresTexture->GetBgraBitmap(nullptr, &trans); + bmp.Blit(0, 0, Pixels); + + HiresTexture->CheckTrans(buffer, w*h, trans); + + if (bHiresHasColorKey) { - if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0; + // This is a crappy Doomsday color keyed image + // We have to remove the key manually. :( + uint32_t * dwdata = (uint32_t*)buffer; + for (int i = (w*h); i > 0; i--) + { + if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0; + } } } FContentIdBuilder contentId; diff --git a/src/textures/hires/hqresize.cpp b/src/textures/hires/hqresize.cpp index b9da15ad4..cc8a65678 100644 --- a/src/textures/hires/hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -352,7 +352,7 @@ static void xbrzOldScale(size_t factor, const uint32_t* src, uint32_t* trg, int // the upsampled buffer. // //=========================================================================== -void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha) +void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly) { // [BB] Make sure that inWidth and inHeight denote the size of // the returned buffer even if we don't upsample the input buffer. @@ -398,51 +398,53 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA type = 2; } #endif - if (mult < 2) - type = 0; + // These checks are to ensure consistency of the content ID. + if (mult < 2 || mult > 6 || type < 1 || type > 6) return; + if (type < 4 && mult > 4) mult = 4; - - if (type == 1) + if (!checkonly) { - if (mult == 2) - texbuffer.mBuffer = scaleNxHelper(&scale2x, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else if (mult == 3) - texbuffer.mBuffer = scaleNxHelper(&scale3x, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else if (mult == 4) - texbuffer.mBuffer = scaleNxHelper(&scale4x, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else return; - } - else if (type == 2) - { - if (mult == 2) - texbuffer.mBuffer = hqNxHelper(&hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else if (mult == 3) - texbuffer.mBuffer = hqNxHelper(&hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else if (mult == 4) - texbuffer.mBuffer = hqNxHelper(&hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else return; - } + if (type == 1) + { + if (mult == 2) + texbuffer.mBuffer = scaleNxHelper(&scale2x, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 3) + texbuffer.mBuffer = scaleNxHelper(&scale3x, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 4) + texbuffer.mBuffer = scaleNxHelper(&scale4x, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else return; + } + else if (type == 2) + { + if (mult == 2) + texbuffer.mBuffer = hqNxHelper(&hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 3) + texbuffer.mBuffer = hqNxHelper(&hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 4) + texbuffer.mBuffer = hqNxHelper(&hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else return; + } #ifdef HAVE_MMX - else if (type == 3) - { - if (mult == 2) - texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else if (mult == 3) - texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else if (mult == 4) - texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else return; - } + else if (type == 3) + { + if (mult == 2) + texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq2x_32, 2, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 3) + texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq3x_32, 3, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (mult == 4) + texbuffer.mBuffer = hqNxAsmHelper(&HQnX_asm::hq4x_32, 4, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else return; + } #endif - else if (type == 4) - texbuffer.mBuffer = xbrzHelper(xbrz::scale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else if (type == 5) - texbuffer.mBuffer = xbrzHelper(xbrzOldScale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else if (type == 6) - texbuffer.mBuffer = normalNxHelper(&normalNx, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); - else - return; - + else if (type == 4) + texbuffer.mBuffer = xbrzHelper(xbrz::scale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (type == 5) + texbuffer.mBuffer = xbrzHelper(xbrzOldScale, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else if (type == 6) + texbuffer.mBuffer = normalNxHelper(&normalNx, mult, texbuffer.mBuffer, inWidth, inHeight, texbuffer.mWidth, texbuffer.mHeight); + else + return; + } // Encode the scaling method in the content ID. FContentIdBuilder contentId; contentId.id = texbuffer.mContentId; diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index eb8f48f96..f6ee5a8da 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -668,6 +668,7 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) unsigned char * buffer = nullptr; int W, H; int isTransparent = -1; + bool checkonly = !!(flags & CTF_CheckOnly); if (flags & CTF_CheckHires) { @@ -679,25 +680,28 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) W = GetWidth() + 2 * exx; H = GetHeight() + 2 * exx; - buffer = new unsigned char[W*(H + 1) * 4]; - memset(buffer, 0, W * (H + 1) * 4); - - auto remap = translation <= 0? nullptr : FUniquePalette::GetPalette(translation); - FBitmap bmp(buffer, W * 4, W, H); - - int trans; - auto Pixels = GetBgraBitmap(remap, &trans); - bmp.Blit(exx, exx, Pixels); - - if (remap == nullptr) + if (!checkonly) { - CheckTrans(buffer, W*H, trans); - isTransparent = bTranslucent; - } - else - { - isTransparent = 0; - // A translated image is not conclusive for setting the texture's transparency info. + buffer = new unsigned char[W*(H + 1) * 4]; + memset(buffer, 0, W * (H + 1) * 4); + + auto remap = translation <= 0 ? nullptr : FUniquePalette::GetPalette(translation); + FBitmap bmp(buffer, W * 4, W, H); + + int trans; + auto Pixels = GetBgraBitmap(remap, &trans); + bmp.Blit(exx, exx, Pixels); + + if (remap == nullptr) + { + CheckTrans(buffer, W*H, trans); + isTransparent = bTranslucent; + } + else + { + isTransparent = 0; + // A translated image is not conclusive for setting the texture's transparency info. + } } if (GetImage()) @@ -718,8 +722,8 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) // Only do postprocessing for image-backed textures. (i.e. not for the burn texture which can also pass through here.) if (GetImage() && flags & CTF_ProcessData) { - CreateUpsampledTextureBuffer(result, !!isTransparent); - ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); + CreateUpsampledTextureBuffer(result, !!isTransparent, checkonly); + if (!checkonly) ProcessData(result.mBuffer, result.mWidth, result.mHeight, false); } return result; diff --git a/src/textures/textures.h b/src/textures/textures.h index b96fc5b07..6fdf6dbc2 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -109,6 +109,7 @@ enum ECreateTexBufferFlags CTF_CheckHires = 1, // use external hires replacement if found CTF_Expand = 2, // create buffer with a one-pixel wide border CTF_ProcessData = 4, // run postprocessing on the generated buffer. This is only needed when using the data for a hardware texture. + CTF_CheckOnly = 8, // Only runs the code to get a content ID but does not create a texture. Can be used to access a caching system for the hardware textures. }; @@ -282,7 +283,7 @@ public: virtual ~FTexture (); virtual FImageSource *GetImage() const { return nullptr; } void AddAutoMaterials(); - void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha); + void CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasAlpha, bool checkonly); // These are mainly meant for 2D code which only needs logical information about the texture to position it properly. int GetDisplayWidth() { return GetScaledWidth(); } @@ -491,7 +492,7 @@ public: private: int CheckDDPK3(); int CheckExternalFile(bool & hascolorkey); - bool LoadHiresTexture(FTextureBuffer &texbuffer); + bool LoadHiresTexture(FTextureBuffer &texbuffer, bool checkonly); bool bSWSkyColorDone = false; PalEntry FloorSkyColor; From 8fcc170e8fa71b69fafefce7b4fe7b8465174cbe Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 01:25:25 +0100 Subject: [PATCH 38/66] - add font characters to the texture manager for easier management These were the only non-transient textures not being handled by the texture manager which complicarted operations that require itrer --- src/v_font.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index ffcb0bec4..560a47f57 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -381,7 +381,11 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, if (charLumps[i] != nullptr) { - if (!noTranslate) Chars[i].Pic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage())); + if (!noTranslate) + { + Chars[i].Pic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage())); + TexMan.AddTexture(Chars[i].Pic); + } else Chars[i].Pic = charLumps[i]; Chars[i].XMove = Chars[i].Pic->GetDisplayWidth(); } @@ -422,17 +426,6 @@ FFont::~FFont () { int count = LastChar - FirstChar + 1; - // A noTranslate font directly references the original textures. - if (!noTranslate) - { - for (int i = 0; i < count; ++i) - { - if (Chars[i].Pic != nullptr && Chars[i].Pic->GetName().IsEmpty()) - { - delete Chars[i].Pic; - } - } - } delete[] Chars; Chars = NULL; } @@ -1145,6 +1138,7 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data) else { Chars[i].Pic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)); + TexMan.AddTexture(Chars[i].Pic); do { int8_t code = *data_p++; @@ -1280,12 +1274,14 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) { // Empty character: skip it. continue; } - Chars[chardata[chari] - FirstChar].Pic = new FImageTexture(new FFontChar2(lump, int(chardata + chari + 6 - data), + auto tex = new FImageTexture(new FFontChar2(lump, int(chardata + chari + 6 - data), chardata[chari+1], // width chardata[chari+2], // height -(int8_t)chardata[chari+3], // x offset -(int8_t)chardata[chari+4] // y offset )); + Chars[chardata[chari] - FirstChar].Pic = tex; + TexMan.AddTexture(tex); } // If the font did not define a space character, determine a suitable space width now. @@ -1352,6 +1348,7 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity) { Chars[i].Pic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)); Chars[i].XMove = SpaceWidth; + TexMan.AddTexture(Chars[i].Pic); } // Advance to next char's data and count the used colors. @@ -1562,7 +1559,11 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l if (charlumps[i] != NULL) { - if (!noTranslate) Chars[i].Pic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage())); + if (!noTranslate) + { + Chars[i].Pic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage())); + TexMan.AddTexture(Chars[i].Pic); + } else Chars[i].Pic = charlumps[i]; Chars[i].XMove = Chars[i].Pic->GetDisplayWidth(); } From 2cf6d213e26c134ef4411e57608954ddd2aa5b73 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 01:27:04 +0100 Subject: [PATCH 39/66] - fixed compile bugs --- src/r_data/r_canvastexture.h | 3 +-- src/tarray.h | 2 +- src/textures/hires/hirestex.cpp | 2 +- src/textures/texture.cpp | 2 +- src/textures/textures.h | 15 +-------------- 5 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/r_data/r_canvastexture.h b/src/r_data/r_canvastexture.h index 8a82eb6e7..b69c46687 100644 --- a/src/r_data/r_canvastexture.h +++ b/src/r_data/r_canvastexture.h @@ -4,7 +4,6 @@ class FCanvasTexture; // This list keeps track of the cameras that draw into canvas textures. struct FCanvasTextureEntry { - FCanvasTextureInfo *Next; TObjPtr Viewpoint; FCanvasTexture *Texture; FTextureID PicNum; @@ -22,4 +21,4 @@ struct FCanvasTextureInfo void Serialize(FSerializer &arc); void Mark(); -}; \ No newline at end of file +}; diff --git a/src/tarray.h b/src/tarray.h index f580ae3e4..524c0942e 100644 --- a/src/tarray.h +++ b/src/tarray.h @@ -272,7 +272,7 @@ public: return i; } - template const + template unsigned int FindEx(Func compare) const { unsigned int i; diff --git a/src/textures/hires/hirestex.cpp b/src/textures/hires/hirestex.cpp index d18735fa7..3ba988eda 100644 --- a/src/textures/hires/hirestex.cpp +++ b/src/textures/hires/hirestex.cpp @@ -399,11 +399,11 @@ bool FTexture::LoadHiresTexture(FTextureBuffer &texbuffer, bool checkonly) if (dwdata[i] == 0xffffff00 || dwdata[i] == 0xffff00ff) dwdata[i] = 0; } } + texbuffer.mBuffer = buffer; } FContentIdBuilder contentId; contentId.id = 0; contentId.imageID = HiresTexture->GetImage()->GetId(); - texbuffer.mBuffer = buffer; texbuffer.mWidth = w; texbuffer.mHeight = h; texbuffer.mContentId = contentId.id; diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index f6ee5a8da..d760296ec 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -673,7 +673,7 @@ FTextureBuffer FTexture::CreateTexBuffer(int translation, int flags) if (flags & CTF_CheckHires) { // No image means that this cannot be checked, - if (GetImage() && LoadHiresTexture(result)) return result; + if (GetImage() && LoadHiresTexture(result, checkonly)) return result; } int exx = !!(flags & CTF_Expand); diff --git a/src/textures/textures.h b/src/textures/textures.h index 6fdf6dbc2..279fe9bac 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -337,7 +337,6 @@ public: FSoftwareTexture *GetSoftwareTexture(); protected: - //int16_t LeftOffset, TopOffset; DVector2 Scale; @@ -435,19 +434,7 @@ protected: // Interfaces for the different renderers. Everything that needs to check renderer-dependent offsets // should use these, so that if changes are needed, this is the only place to edit. - // For the original software renderer - int GetLeftOffsetSW() { return _LeftOffset[r_spriteadjustSW]; } - int GetTopOffsetSW() { return _TopOffset[r_spriteadjustSW]; } - int GetScaledLeftOffsetSW() { return GetScaledLeftOffset(r_spriteadjustSW); } - int GetScaledTopOffsetSW() { return GetScaledTopOffset(r_spriteadjustSW); } - - // For the softpoly renderer, in case it wants adjustment - int GetLeftOffsetPo() { return _LeftOffset[r_spriteadjustSW]; } - int GetTopOffsetPo() { return _TopOffset[r_spriteadjustSW]; } - int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); } - int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); } - - // For the hardware renderer + // For the hardware renderer. The software renderer's have been offloaded to FSoftwareTexture int GetLeftOffsetHW() { return _LeftOffset[r_spriteadjustHW]; } int GetTopOffsetHW() { return _TopOffset[r_spriteadjustHW]; } From 245a8243b0fee4cb6d5e715a64e5c7dcda98d7b3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 02:03:54 +0100 Subject: [PATCH 40/66] - separated the savepic texture handler from the regular PNG texture This was leaking memory with being handled like a regular image texture and also would prevent further changes to the in-game texture handling because the savegame picture was imposing some limitations on FPNGTexture's implementation --- src/textures/formats/pngtexture.cpp | 223 +++++++++++++++++----------- src/textures/textures.h | 1 + 2 files changed, 139 insertions(+), 85 deletions(-) diff --git a/src/textures/formats/pngtexture.cpp b/src/textures/formats/pngtexture.cpp index 3cdfc3a6a..6f42eee41 100644 --- a/src/textures/formats/pngtexture.cpp +++ b/src/textures/formats/pngtexture.cpp @@ -51,8 +51,7 @@ class FPNGTexture : public FImageSource { public: - FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, uint8_t bitdepth, uint8_t colortype, uint8_t interlace); - ~FPNGTexture(); + FPNGTexture (FileReader &lump, int lumpnum, int width, int height, uint8_t bitdepth, uint8_t colortype, uint8_t interlace); int CopyPixels(FBitmap *bmp, int conversion) override; TArray CreatePalettedPixels(int conversion) override; @@ -60,9 +59,6 @@ public: protected: void ReadAlphaRemap(FileReader *lump, uint8_t *alpharemap); - FString SourceFile; - FileReader fr; - uint8_t BitDepth; uint8_t ColorType; uint8_t Interlace; @@ -141,7 +137,7 @@ FImageSource *PNGImage_TryCreate(FileReader & data, int lumpnum) } } - return new FPNGTexture (data, lumpnum, FString(), width, height, bitdepth, colortype, interlace); + return new FPNGTexture (data, lumpnum, width, height, bitdepth, colortype, interlace); } //========================================================================== @@ -150,49 +146,9 @@ FImageSource *PNGImage_TryCreate(FileReader & data, int lumpnum) // //========================================================================== -FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename) -{ - - if (M_FindPNGChunk(png, MAKE_ID('I','H','D','R')) == 0) - { - return NULL; - } - - // Check the IHDR to make sure it's a type of PNG we support. - auto &data = png->File; - int width = data.ReadInt32BE(); - int height = data.ReadInt32BE(); - uint8_t bitdepth = data.ReadUInt8(); - uint8_t colortype = data.ReadUInt8(); - uint8_t compression = data.ReadUInt8(); - uint8_t filter = data.ReadUInt8(); - uint8_t interlace = data.ReadUInt8(); - - if (compression != 0 || filter != 0 || interlace > 1) - { - return NULL; - } - if (!((1 << colortype) & 0x5D)) - { - return NULL; - } - if (!((1 << bitdepth) & 0x116)) - { - return NULL; - } - - return new FImageTexture(new FPNGTexture (png->File, -1, filename, width, height, bitdepth, colortype, interlace)); -} - -//========================================================================== -// -// -// -//========================================================================== - -FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename, int width, int height, +FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, int width, int height, uint8_t depth, uint8_t colortype, uint8_t interlace) -: FImageSource(lumpnum), SourceFile(filename), +: FImageSource(lumpnum), BitDepth(depth), ColorType(colortype), Interlace(interlace), HaveTrans(false) { union @@ -291,7 +247,7 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename { bMasked = true; PaletteSize = 256; - PaletteMap = new uint8_t[256]; + PaletteMap = (uint8_t*)ImageArena.Alloc(PaletteSize); memcpy (PaletteMap, ImageHelpers::GrayMap, 256); PaletteMap[NonPaletteTrans[0]] = 0; } @@ -302,7 +258,7 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename break; case 3: // Paletted - PaletteMap = new uint8_t[PaletteSize]; + PaletteMap = (uint8_t*)ImageArena.Alloc(PaletteSize); GPalette.MakeRemap (p.palette, PaletteMap, trans, PaletteSize); for (i = 0; i < PaletteSize; ++i) { @@ -322,23 +278,6 @@ FPNGTexture::FPNGTexture (FileReader &lump, int lumpnum, const FString &filename bMasked = HaveTrans; break; } - // If this is a savegame we must keep the reader. - if (lumpnum == -1) fr = std::move(lump); -} - -//========================================================================== -// -// -// -//========================================================================== - -FPNGTexture::~FPNGTexture () -{ - if (PaletteMap != nullptr && PaletteMap != ImageHelpers::GrayMap) - { - delete[] PaletteMap; - PaletteMap = nullptr; - } } //========================================================================== @@ -372,15 +311,8 @@ TArray FPNGTexture::CreatePalettedPixels(int conversion) FileReader *lump; FileReader lfr; - if (SourceLump >= 0) - { - lfr = Wads.OpenLumpReader(SourceLump); - lump = 𝔩 - } - else - { - lump = &fr; - } + lfr = Wads.OpenLumpReader(SourceLump); + lump = 𝔩 TArray Pixels(Width*Height, true); if (StartOfIDAT == 0) @@ -524,15 +456,8 @@ int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion) FileReader *lump; FileReader lfr; - if (SourceLump >= 0) - { - lfr = Wads.OpenLumpReader(SourceLump); - lump = 𝔩 - } - else - { - lump = &fr; - } + lfr = Wads.OpenLumpReader(SourceLump); + lump = 𝔩 lump->Seek(33, FileReader::SeekSet); for(int i = 0; i < 256; i++) // default to a gray map @@ -630,3 +555,131 @@ int FPNGTexture::CopyPixels(FBitmap *bmp, int conversion) delete[] Pixels; return transpal; } + + + +//========================================================================== +// +// A savegame picture +// This is essentially a stripped down version of the PNG texture +// only supporting the features actually present in a savegame +// that does not use an image source, because image sources are not +// meant to be transient data like the savegame picture. +// +//========================================================================== + +class FPNGFileTexture : public FTexture +{ +public: + FPNGFileTexture (FileReader &lump, int width, int height, uint8_t colortype); + virtual FBitmap GetBgraBitmap(PalEntry *remap, int *trans); + +protected: + + FileReader fr; + uint8_t ColorType; + int PaletteSize; +}; + + +//========================================================================== +// +// +// +//========================================================================== + +FTexture *PNGTexture_CreateFromFile(PNGHandle *png, const FString &filename) +{ + if (M_FindPNGChunk(png, MAKE_ID('I','H','D','R')) == 0) + { + return nullptr; + } + + // Savegame images can only be either 8 bit paletted or 24 bit RGB + auto &data = png->File; + int width = data.ReadInt32BE(); + int height = data.ReadInt32BE(); + uint8_t bitdepth = data.ReadUInt8(); + uint8_t colortype = data.ReadUInt8(); + uint8_t compression = data.ReadUInt8(); + uint8_t filter = data.ReadUInt8(); + uint8_t interlace = data.ReadUInt8(); + + // Reject anything that cannot be put into a savegame picture by GZDoom itself. + if (compression != 0 || filter != 0 || interlace > 0 || bitdepth != 8 || (colortype != 2 && colortype != 3)) return nullptr; + else return new FPNGFileTexture (png->File, width, height, colortype); +} + +//========================================================================== +// +// +// +//========================================================================== + +FPNGFileTexture::FPNGFileTexture (FileReader &lump, int width, int height, uint8_t colortype) +: ColorType(colortype) +{ + Width = width; + Height = height; + fr = std::move(lump); +} + +//=========================================================================== +// +// FPNGTexture::CopyPixels +// +//=========================================================================== + +FBitmap FPNGFileTexture::GetBgraBitmap(PalEntry *remap, int *trans) +{ + FBitmap bmp; + // Parse pre-IDAT chunks. I skip the CRCs. Is that bad? + PalEntry pe[256]; + uint32_t len, id; + int pixwidth = Width * (ColorType == 2? 3:1); + + FileReader *lump = &fr; + + bmp.Create(Width, Height); + lump->Seek(33, FileReader::SeekSet); + lump->Read(&len, 4); + lump->Read(&id, 4); + while (id != MAKE_ID('I','D','A','T') && id != MAKE_ID('I','E','N','D')) + { + len = BigLong((unsigned int)len); + if (id != MAKE_ID('P','L','T','E')) + lump->Seek (len, FileReader::SeekCur); + else + { + PaletteSize = MIN (len / 3, 256); + for(int i = 0; i < PaletteSize; i++) + { + pe[i].r = lump->ReadUInt8(); + pe[i].g = lump->ReadUInt8(); + pe[i].b = lump->ReadUInt8(); + } + } + lump->Seek(4, FileReader::SeekCur); // Skip CRC + lump->Read(&len, 4); + id = MAKE_ID('I','E','N','D'); + lump->Read(&id, 4); + } + auto StartOfIDAT = (uint32_t)lump->Tell() - 8; + + TArray Pixels(pixwidth * Height); + + lump->Seek (StartOfIDAT, FileReader::SeekSet); + lump->Read(&len, 4); + lump->Read(&id, 4); + M_ReadIDAT (*lump, Pixels.Data(), Width, Height, pixwidth, 8, ColorType, 0, BigLong((unsigned int)len)); + + if (ColorType == 3) + { + bmp.CopyPixelData(0, 0, Pixels.Data(), Width, Height, 1, Width, 0, pe); + } + else + { + bmp.CopyPixelDataRGB(0, 0, Pixels.Data(), Width, Height, 3, pixwidth, 0, CF_RGB); + } + return bmp; +} diff --git a/src/textures/textures.h b/src/textures/textures.h index 279fe9bac..366e3ecc3 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -687,6 +687,7 @@ public: bMasked = false; bHasCanvas = true; bTranslucent = false; + bNoExpand = true; UseType = ETextureType::Wall; } From e6b4c63b99683194fa4cf738defda0bb7cda9d0e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 02:52:27 +0100 Subject: [PATCH 41/66] - More adjustments --- src/hwrenderer/textures/hw_material.cpp | 31 +++++++++++-------------- src/hwrenderer/textures/hw_material.h | 4 ++-- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 30d22a7ec..9c0769b22 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -133,14 +133,15 @@ void IHardwareTexture::Resize(int swidth, int sheight, int width, int height, un // // //=========================================================================== -IHardwareTexture * FMaterial::ValidateSysTexture(FTexture * tex, bool expand) +IHardwareTexture * FMaterial::ValidateSysTexture(FTexture * tex, int translation, bool expand) { if (tex && tex->UseType!=ETextureType::Null) { - IHardwareTexture *gltex = tex->SystemTexture[expand]; + IHardwareTexture *gltex = tex->SystemTextures.GetHardwareTexture(0, expand); if (gltex == nullptr) { - gltex = tex->SystemTexture[expand] = screen->CreateHardwareTexture(); + tex->SystemTextures.AddHardwareTexture(0, expand, screen->CreateHardwareTexture()); + gltex = tex->SystemTextures.GetHardwareTexture(0, expand); } return gltex; } @@ -182,7 +183,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { for (auto &texture : { tx->Normal, tx->Specular }) { - ValidateSysTexture(texture, expanded); + ValidateSysTexture(texture, 0, expanded); mTextureLayers.Push(texture); } mShaderIndex = SHADER_Specular; @@ -191,7 +192,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { for (auto &texture : { tx->Normal, tx->Metallic, tx->Roughness, tx->AmbientOcclusion }) { - ValidateSysTexture(texture, expanded); + ValidateSysTexture(texture, 0, expanded); mTextureLayers.Push(texture); } mShaderIndex = SHADER_PBR; @@ -200,7 +201,7 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) tx->CreateDefaultBrightmap(); if (tx->Brightmap) { - ValidateSysTexture(tx->Brightmap, expanded); + ValidateSysTexture(tx->Brightmap, 0, expanded); mTextureLayers.Push(tx->Brightmap); if (mShaderIndex == SHADER_Specular) mShaderIndex = SHADER_SpecularBrightmap; @@ -218,14 +219,14 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) for (auto &texture : tx->CustomShaderTextures) { if (texture == nullptr) continue; - ValidateSysTexture(texture, expanded); + ValidateSysTexture(texture, 0, expanded); mTextureLayers.Push(texture); } mShaderIndex = tx->shaderindex; } } } - mBaseLayer = ValidateSysTexture(tx, expanded); + mBaseLayer = ValidateSysTexture(tx, 0, expanded); mWidth = tx->GetWidth(); @@ -513,26 +514,22 @@ FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translat //========================================================================== // -// Flushes all hardware dependent data +// Flushes all hardware dependent data. +// Thia must not, under any circumstances, delete the wipe textures, because +// all CCMDs triggering a flush can be executed while a wipe is in progress // //========================================================================== void FMaterial::FlushAll() { - for(int i=mMaterials.Size()-1;i>=0;i--) - { - mMaterials[i]->mBaseLayer->Clean(true); - } - // This is for shader layers. All shader layers must be managed by the texture manager - // so this will catch everything. for(int i=TexMan.NumTextures()-1;i>=0;i--) { for (int j = 0; j < 2; j++) { - auto gltex = TexMan.ByIndex(i)->SystemTexture[j]; - if (gltex != nullptr) gltex->Clean(true); + TexMan.ByIndex(i)->SystemTextures.Clean(true); } } + // This must also delete the software renderer's canvas. } void FMaterial::Clean(bool f) diff --git a/src/hwrenderer/textures/hw_material.h b/src/hwrenderer/textures/hw_material.h index e16c8059f..b4d24d8a8 100644 --- a/src/hwrenderer/textures/hw_material.h +++ b/src/hwrenderer/textures/hw_material.h @@ -68,7 +68,7 @@ public: void Precache(); void PrecacheList(SpriteHits &translations); int GetShaderIndex() const { return mShaderIndex; } - IHardwareTexture * ValidateSysTexture(FTexture * tex, bool expand); + IHardwareTexture * ValidateSysTexture(FTexture * tex, int translation, bool expand); void AddTextureLayer(FTexture *tex) { ValidateTexture(tex, false); @@ -105,7 +105,7 @@ public: i--; FTexture *layer = mTextureLayers[i]; if (pLayer) *pLayer = layer; - return ValidateSysTexture(layer, isExpanded()); + return ValidateSysTexture(layer, 0, isExpanded()); } } From fb6ee5046c5aba89d1321fa59acf21d20b0ee4af Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 02:28:42 +0100 Subject: [PATCH 42/66] - add the hardware texture container to FTexture. Currently it does not use the translated entries yet. # Conflicts: # src/hwrenderer/textures/hw_material.cpp --- src/gl/system/gl_framebuffer.cpp | 8 ++++---- src/hwrenderer/textures/hw_texcontainer.h | 14 ++++++++++---- src/swrenderer/r_swscene.cpp | 8 ++++---- src/textures/texture.cpp | 5 +---- src/textures/textures.h | 8 +++++--- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index ca2616cfd..fda8ae9df 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -515,9 +515,9 @@ FTexture *OpenGLFrameBuffer::WipeStartScreen() const auto &viewport = screen->mScreenViewport; auto tex = new FWrapperTexture(viewport.width, viewport.height, 1); - tex->GetSystemTexture(0)->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen"); + tex->GetSystemTexture()->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen"); glFinish(); - static_cast(tex->GetSystemTexture(0))->Bind(0, false, false); + static_cast(tex->GetSystemTexture())->Bind(0, false, false); GLRenderer->mBuffers->BindCurrentFB(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height); @@ -537,9 +537,9 @@ FTexture *OpenGLFrameBuffer::WipeEndScreen() GLRenderer->Flush(); const auto &viewport = screen->mScreenViewport; auto tex = new FWrapperTexture(viewport.width, viewport.height, 1); - tex->GetSystemTexture(0)->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen"); + tex->GetSystemTexture()->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen"); glFinish(); - static_cast(tex->GetSystemTexture(0))->Bind(0, false, false); + static_cast(tex->GetSystemTexture())->Bind(0, false, false); GLRenderer->mBuffers->BindCurrentFB(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height); return tex; diff --git a/src/hwrenderer/textures/hw_texcontainer.h b/src/hwrenderer/textures/hw_texcontainer.h index d5836d82b..96cd8fa3c 100644 --- a/src/hwrenderer/textures/hw_texcontainer.h +++ b/src/hwrenderer/textures/hw_texcontainer.h @@ -1,8 +1,10 @@ #pragma once #include "tarray.h" +#include "hwrenderer/textures/hw_ihwtexture.h" struct FTextureBuffer; +class IHardwareTexture; class FHardwareTextureContainer { @@ -49,10 +51,10 @@ private: unsigned index = hwTex_Translated.FindEx([=](auto &element) { return element.translation == translation; - } + }); if (index < hwTex_Translated.Size()) { - return &hwTex_Translated[i]; + return &hwTex_Translated[index]; } int add = hwTex_Translated.Reserve(1); @@ -65,7 +67,11 @@ public: void Clean(bool all) { - if (all) hwDefTex.Delete(); + if (all) + { + hwDefTex[0].Delete(); + hwDefTex[1].Delete(); + } hwTex_Translated.Clear(); } @@ -90,7 +96,7 @@ public: // //=========================================================================== - void FHardwareTexture::CleanUnused(SpriteHits &usedtranslations, bool expanded) + void CleanUnused(SpriteHits &usedtranslations, bool expanded) { if (usedtranslations.CheckKey(0) == nullptr) { diff --git a/src/swrenderer/r_swscene.cpp b/src/swrenderer/r_swscene.cpp index 88a5417b6..807a3126e 100644 --- a/src/swrenderer/r_swscene.cpp +++ b/src/swrenderer/r_swscene.cpp @@ -91,7 +91,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) FBTextureIndex = (FBTextureIndex + 1) % 2; auto &fbtex = FBTexture[FBTextureIndex]; - if (fbtex == nullptr || fbtex->GetSystemTexture(0) == nullptr || + if (fbtex == nullptr || fbtex->GetSystemTexture() == nullptr || fbtex->GetDisplayWidth() != screen->GetWidth() || fbtex->GetDisplayHeight() != screen->GetHeight() || (V_IsTrueColor() ? 1:0) != fbtex->GetColorFormat()) @@ -99,7 +99,7 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) // This manually constructs its own material here. fbtex.reset(); fbtex.reset(new FWrapperTexture(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor())); - fbtex->GetSystemTexture(0)->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor() ? 4 : 1); + fbtex->GetSystemTexture()->AllocateBuffer(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor() ? 4 : 1); auto mat = FMaterial::ValidateTexture(fbtex.get(), false); mat->AddTextureLayer(PaletteTexture); @@ -107,10 +107,10 @@ sector_t *SWSceneDrawer::RenderView(player_t *player) Canvas.reset(new DCanvas(screen->GetWidth(), screen->GetHeight(), V_IsTrueColor())); } - auto buf = fbtex->GetSystemTexture(0)->MapBuffer(); + auto buf = fbtex->GetSystemTexture()->MapBuffer(); if (!buf) I_FatalError("Unable to map buffer for software rendering"); SWRenderer->RenderView(player, Canvas.get(), buf); - fbtex->GetSystemTexture(0)->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer"); + fbtex->GetSystemTexture()->CreateTexture(nullptr, screen->GetWidth(), screen->GetHeight(), 0, false, 0, "swbuffer"); auto map = swrenderer::CameraLight::Instance()->ShaderColormap(); screen->DrawTexture(fbtex.get(), 0, 0, DTA_SpecialColormap, map, TAG_DONE); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index d760296ec..7dfd00484 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -178,9 +178,6 @@ FTexture::~FTexture () { if (Material[i] != nullptr) delete Material[i]; Material[i] = nullptr; - - if (SystemTexture[i] != nullptr) delete SystemTexture[i]; - SystemTexture[i] = nullptr; } if (SoftwareTexture != nullptr) { @@ -793,7 +790,7 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits) Format = bits; UseType = ETextureType::SWCanvas; bNoCompress = true; - SystemTexture[0] = screen->CreateHardwareTexture(); + SystemTextures.AddHardwareTexture(0, false, screen->CreateHardwareTexture()); } //=========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index 366e3ecc3..199ce0be8 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -42,6 +42,7 @@ #include "colormatcher.h" #include "r_data/renderstyle.h" #include "r_data/r_translate.h" +#include "hwrenderer/textures/hw_texcontainer.h" #include // 15 because 0th texture is our texture @@ -344,7 +345,8 @@ protected: FTextureID id; FMaterial *Material[2] = { nullptr, nullptr }; - IHardwareTexture *SystemTexture[2] = { nullptr, nullptr }; + FHardwareTextureContainer SystemTextures; + //IHardwareTexture *SystemTexture[2] = { nullptr, nullptr }; FSoftwareTexture *SoftwareTexture = nullptr; // None of the following pointers are owned by this texture, they are all controlled by the texture manager. @@ -710,9 +712,9 @@ class FWrapperTexture : public FTexture int Format; public: FWrapperTexture(int w, int h, int bits = 1); - IHardwareTexture *GetSystemTexture(int slot) + IHardwareTexture *GetSystemTexture() { - return SystemTexture[slot]; + return SystemTextures.GetHardwareTexture(0, false); } int GetColorFormat() const From c5447f0cddab41462c4d8be23803970ea09666cc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 18:39:38 +0100 Subject: [PATCH 43/66] - continued work on texture management. --- src/f_wipe.cpp | 5 +- src/gl/renderer/gl_renderer.cpp | 4 +- src/gl/renderer/gl_renderstate.cpp | 4 +- src/gl/system/gl_framebuffer.cpp | 11 +--- src/gl/system/gl_framebuffer.h | 1 - src/gl/textures/gl_hwtexture.cpp | 23 ------- src/gl/textures/gl_hwtexture.h | 1 - src/hwrenderer/textures/hw_ihwtexture.h | 1 - src/hwrenderer/textures/hw_material.cpp | 78 +++++++---------------- src/hwrenderer/textures/hw_material.h | 22 +------ src/hwrenderer/textures/hw_precache.cpp | 9 +-- src/hwrenderer/textures/hw_texcontainer.h | 15 +++-- src/hwrenderer/utility/hw_cvars.cpp | 4 +- src/textures/hires/hqresize.cpp | 8 +-- src/textures/texture.cpp | 4 +- src/textures/texturemanager.cpp | 25 ++++++++ src/textures/textures.h | 3 + src/v_video.h | 1 - 18 files changed, 79 insertions(+), 140 deletions(-) diff --git a/src/f_wipe.cpp b/src/f_wipe.cpp index cb5544b68..80e576100 100644 --- a/src/f_wipe.cpp +++ b/src/f_wipe.cpp @@ -372,9 +372,8 @@ bool Wiper_Burn::Run(int ticks) Density = wipe_CalcBurn(BurnArray, WIDTH, HEIGHT, Density); done = (Density < 0); } - - auto mat = FMaterial::ValidateTexture(BurnTexture, false); - mat->Clean(true); + + BurnTexture->SystemTextures.Clean(true, true); const uint8_t *src = BurnArray; uint32_t *dest = (uint32_t *)BurnTexture->GetBuffer(); for (int y = HEIGHT; y != 0; --y) diff --git a/src/gl/renderer/gl_renderer.cpp b/src/gl/renderer/gl_renderer.cpp index 79ae7655f..44422ad2d 100644 --- a/src/gl/renderer/gl_renderer.cpp +++ b/src/gl/renderer/gl_renderer.cpp @@ -117,7 +117,7 @@ FGLRenderer::~FGLRenderer() { FlushModels(); AActor::DeleteAllAttachedLights(); - FMaterial::FlushAll(); + TexMan.FlushAll(); if (mShaderManager != nullptr) delete mShaderManager; if (mSamplerManager != nullptr) delete mSamplerManager; if (mFBID != 0) glDeleteFramebuffers(1, &mFBID); @@ -288,7 +288,7 @@ sector_t *FGLRenderer::RenderView(player_t* player) void FGLRenderer::BindToFrameBuffer(FMaterial *mat) { - auto BaseLayer = static_cast(mat->GetLayer(0)); + auto BaseLayer = static_cast(mat->GetLayer(0, 0)); if (BaseLayer == nullptr) { diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index 30a291899..0cc80d073 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -332,14 +332,14 @@ void FGLRenderState::ApplyMaterial(FMaterial *mat, int clampmode, int translatio // Textures that are already scaled in the texture lump will not get replaced by hires textures. int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled() && clampmode <= CLAMP_XY) ? CTF_CheckHires : 0; int numLayers = mat->GetLayers(); - auto base = static_cast(mat->GetLayer(0)); + auto base = static_cast(mat->GetLayer(0, translation)); if (base->BindOrCreate(tex, 0, clampmode, translation, flags)) { for (int i = 1; i(mat->GetLayer(i, &layer)); + auto systex = static_cast(mat->GetLayer(i, 0, &layer)); systex->BindOrCreate(layer, i, clampmode, 0, mat->isExpanded() ? CTF_Expand : 0); maxbound = i; } diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index fda8ae9df..8573a21dd 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -339,14 +339,14 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) // Textures that are already scaled in the texture lump will not get replaced by hires textures. int flags = mat->isExpanded() ? CTF_Expand : (gl_texture_usehires && !tex->isScaled()) ? CTF_CheckHires : 0; int numLayers = mat->GetLayers(); - auto base = static_cast(mat->GetLayer(0)); + auto base = static_cast(mat->GetLayer(0, translation)); if (base->BindOrCreate(tex, 0, CLAMP_NONE, translation, flags)) { for (int i = 1; i < numLayers; i++) { FTexture *layer; - auto systex = static_cast(mat->GetLayer(i, &layer)); + auto systex = static_cast(mat->GetLayer(i, 0, &layer)); systex->BindOrCreate(layer, i, CLAMP_NONE, 0, mat->isExpanded() ? CTF_Expand : 0); } } @@ -354,13 +354,6 @@ void OpenGLFrameBuffer::PrecacheMaterial(FMaterial *mat, int translation) FHardwareTexture::UnbindAll(); } -bool OpenGLFrameBuffer::CheckPrecacheMaterial(FMaterial *mat) -{ - if (!mat->tex->GetImage()) return true; - auto base = static_cast(mat->GetLayer(0)); - return base->Exists(0); -} - FModelRenderer *OpenGLFrameBuffer::CreateModelRenderer(int mli) { return new FGLModelRenderer(nullptr, gl_RenderState, mli); diff --git a/src/gl/system/gl_framebuffer.h b/src/gl/system/gl_framebuffer.h index 5ebc586b0..c77b3af67 100644 --- a/src/gl/system/gl_framebuffer.h +++ b/src/gl/system/gl_framebuffer.h @@ -35,7 +35,6 @@ public: void SetTextureFilterMode() override; IHardwareTexture *CreateHardwareTexture() override; void PrecacheMaterial(FMaterial *mat, int translation) override; - bool CheckPrecacheMaterial(FMaterial *mat) override; FModelRenderer *CreateModelRenderer(int mli) override; void TextureFilterChanged() override; void BeginFrame() override; diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 7f4093af8..b9034b101 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -265,29 +265,6 @@ void FHardwareTexture::Clean(bool all) glDepthID = 0; } -//=========================================================================== -// -// Deletes all allocated resources and considers translations -// This will only be called for sprites -// -//=========================================================================== - -void FHardwareTexture::CleanUnused(SpriteHits &usedtranslations) -{ - if (usedtranslations.CheckKey(0) == nullptr) - { - glDefTex.Delete(); - } - for (int i = glTex_Translated.Size()-1; i>= 0; i--) - { - if (usedtranslations.CheckKey(glTex_Translated[i].translation) == nullptr) - { - glTex_Translated[i].Delete(); - glTex_Translated.Delete(i); - } - } -} - //=========================================================================== // // Destroys the texture diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index f864d073b..46e9cfde4 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -91,7 +91,6 @@ public: unsigned int GetTextureHandle(int translation); void Clean(bool all); - void CleanUnused(SpriteHits &usedtranslations); }; } diff --git a/src/hwrenderer/textures/hw_ihwtexture.h b/src/hwrenderer/textures/hw_ihwtexture.h index 10447e5b1..07486e147 100644 --- a/src/hwrenderer/textures/hw_ihwtexture.h +++ b/src/hwrenderer/textures/hw_ihwtexture.h @@ -26,7 +26,6 @@ public: virtual unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) = 0; virtual void Clean(bool all) = 0; - virtual void CleanUnused(SpriteHits &usedtranslations) = 0; void Resize(int swidth, int sheight, int width, int height, unsigned char *src_data, unsigned char *dst_data); }; diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 9c0769b22..13cd9298e 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -128,26 +128,6 @@ void IHardwareTexture::Resize(int swidth, int sheight, int width, int height, un } } -//=========================================================================== -// -// -// -//=========================================================================== -IHardwareTexture * FMaterial::ValidateSysTexture(FTexture * tex, int translation, bool expand) -{ - if (tex && tex->UseType!=ETextureType::Null) - { - IHardwareTexture *gltex = tex->SystemTextures.GetHardwareTexture(0, expand); - if (gltex == nullptr) - { - tex->SystemTextures.AddHardwareTexture(0, expand, screen->CreateHardwareTexture()); - gltex = tex->SystemTextures.GetHardwareTexture(0, expand); - } - return gltex; - } - return nullptr; -} - //=========================================================================== // // Constructor @@ -183,7 +163,6 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { for (auto &texture : { tx->Normal, tx->Specular }) { - ValidateSysTexture(texture, 0, expanded); mTextureLayers.Push(texture); } mShaderIndex = SHADER_Specular; @@ -192,7 +171,6 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) { for (auto &texture : { tx->Normal, tx->Metallic, tx->Roughness, tx->AmbientOcclusion }) { - ValidateSysTexture(texture, 0, expanded); mTextureLayers.Push(texture); } mShaderIndex = SHADER_PBR; @@ -201,7 +179,6 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) tx->CreateDefaultBrightmap(); if (tx->Brightmap) { - ValidateSysTexture(tx->Brightmap, 0, expanded); mTextureLayers.Push(tx->Brightmap); if (mShaderIndex == SHADER_Specular) mShaderIndex = SHADER_SpecularBrightmap; @@ -219,16 +196,12 @@ FMaterial::FMaterial(FTexture * tx, bool expanded) for (auto &texture : tx->CustomShaderTextures) { if (texture == nullptr) continue; - ValidateSysTexture(texture, 0, expanded); mTextureLayers.Push(texture); } mShaderIndex = tx->shaderindex; } } } - mBaseLayer = ValidateSysTexture(tx, 0, expanded); - - mWidth = tx->GetWidth(); mHeight = tx->GetHeight(); mLeftOffset = tx->GetLeftOffset(0); // These only get used by decals and decals should not use renderer-specific offsets. @@ -423,6 +396,27 @@ outl: return true; } +//=========================================================================== +// +// +// +//=========================================================================== + +IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) +{ + FTexture *texture = i == 0 ? tex : mTextureLayers[i - 1]; + if (pLayer) *pLayer = tex; + + auto hwtex = tex->SystemTextures.GetHardwareTexture(translation, mExpanded); + if (hwtex == nullptr) + { + hwtex = screen->CreateHardwareTexture(); + // Fixme: This needs to create the texture here and not implicitly in BindOrCreate! + tex->SystemTextures.AddHardwareTexture(translation, mExpanded, hwtex); + } + return hwtex; +} + //=========================================================================== // // @@ -440,7 +434,7 @@ void FMaterial::Precache() //=========================================================================== void FMaterial::PrecacheList(SpriteHits &translations) { - if (mBaseLayer != nullptr) mBaseLayer->CleanUnused(translations); + tex->SystemTextures.CleanUnused(translations, mExpanded); SpriteHits::Iterator it(translations); SpriteHits::Pair *pair; while(it.NextPair(pair)) screen->PrecacheMaterial(this, pair->Key); @@ -510,31 +504,3 @@ FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translat { return ValidateTexture(TexMan.GetTexture(no, translate), expand, create); } - - -//========================================================================== -// -// Flushes all hardware dependent data. -// Thia must not, under any circumstances, delete the wipe textures, because -// all CCMDs triggering a flush can be executed while a wipe is in progress -// -//========================================================================== - -void FMaterial::FlushAll() -{ - for(int i=TexMan.NumTextures()-1;i>=0;i--) - { - for (int j = 0; j < 2; j++) - { - TexMan.ByIndex(i)->SystemTextures.Clean(true); - } - } - // This must also delete the software renderer's canvas. -} - -void FMaterial::Clean(bool f) -{ - // This somehow needs to deal with the other layers as well, but they probably need some form of reference counting to work properly... - mBaseLayer->Clean(f); -} - diff --git a/src/hwrenderer/textures/hw_material.h b/src/hwrenderer/textures/hw_material.h index b4d24d8a8..33bf0f9d3 100644 --- a/src/hwrenderer/textures/hw_material.h +++ b/src/hwrenderer/textures/hw_material.h @@ -39,7 +39,6 @@ class FMaterial static TArray mMaterials; static int mMaxBound; - IHardwareTexture *mBaseLayer; TArray mTextureLayers; int mShaderIndex; @@ -68,7 +67,6 @@ public: void Precache(); void PrecacheList(SpriteHits &translations); int GetShaderIndex() const { return mShaderIndex; } - IHardwareTexture * ValidateSysTexture(FTexture * tex, int translation, bool expand); void AddTextureLayer(FTexture *tex) { ValidateTexture(tex, false); @@ -93,23 +91,7 @@ public: return tex->isHardwareCanvas(); } - IHardwareTexture *GetLayer(int i, FTexture **pLayer = nullptr) - { - if (i == 0) - { - if (pLayer) *pLayer = tex; - return mBaseLayer; - } - else - { - i--; - FTexture *layer = mTextureLayers[i]; - if (pLayer) *pLayer = layer; - return ValidateSysTexture(layer, 0, isExpanded()); - } - } - - void Clean(bool f); + IHardwareTexture *GetLayer(int i, int translation, FTexture **pLayer = nullptr); // Patch drawing utilities @@ -168,8 +150,6 @@ public: float GetSpriteVB() const { return mSpriteV[1]; } - static void DeleteAll(); - static void FlushAll(); static FMaterial *ValidateTexture(FTexture * tex, bool expand, bool create = true); static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans, bool create = true); }; diff --git a/src/hwrenderer/textures/hw_precache.cpp b/src/hwrenderer/textures/hw_precache.cpp index b927463a2..dc6829dd6 100644 --- a/src/hwrenderer/textures/hw_precache.cpp +++ b/src/hwrenderer/textures/hw_precache.cpp @@ -177,13 +177,11 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl { if (!texhitlist[i]) { - auto mat = FMaterial::ValidateTexture(tex, false, false); - if (mat) mat->Clean(true); + tex->SystemTextures.Clean(true, false); } if (spritehitlist[i] == nullptr || (*spritehitlist[i]).CountUsed() == 0) { - auto mat = FMaterial::ValidateTexture(tex, true, false); - if (mat) mat->Clean(true); + tex->SystemTextures.Clean(false, true); } } } @@ -200,8 +198,7 @@ void hw_PrecacheTexture(uint8_t *texhitlist, TMap &actorhitl { if (texhitlist[i] & (FTextureManager::HIT_Wall | FTextureManager::HIT_Flat | FTextureManager::HIT_Sky)) { - FMaterial * gltex = FMaterial::ValidateTexture(tex, false); - if (gltex && !screen->CheckPrecacheMaterial(gltex)) + if (tex->GetImage() && tex->SystemTextures.GetHardwareTexture(0, false) == nullptr) { FImageSource::RegisterForPrecache(tex->GetImage()); } diff --git a/src/hwrenderer/textures/hw_texcontainer.h b/src/hwrenderer/textures/hw_texcontainer.h index 96cd8fa3c..65f356115 100644 --- a/src/hwrenderer/textures/hw_texcontainer.h +++ b/src/hwrenderer/textures/hw_texcontainer.h @@ -65,15 +65,15 @@ private: public: - void Clean(bool all) + void Clean(bool cleannormal, bool cleanexpanded) { - if (all) + if (cleannormal) hwDefTex[0].Delete(); + if (cleanexpanded) hwDefTex[1].Delete(); + for (int i = hwTex_Translated.Size() - 1; i >= 0; i--) { - hwDefTex[0].Delete(); - hwDefTex[1].Delete(); + if (cleannormal && hwTex_Translated[i].translation > 0) hwTex_Translated.Delete(i); + else if (cleanexpanded && hwTex_Translated[i].translation < 0) hwTex_Translated.Delete(i); } - hwTex_Translated.Clear(); - } IHardwareTexture * GetHardwareTexture(int translation, bool expanded) @@ -102,9 +102,10 @@ public: { hwDefTex[expanded].Delete(); } + int fac = expanded ? -1 : 1; for (int i = hwTex_Translated.Size()-1; i>= 0; i--) { - if (usedtranslations.CheckKey(hwTex_Translated[i].translation) == nullptr) + if (usedtranslations.CheckKey(hwTex_Translated[i].translation * fac) == nullptr) { hwTex_Translated.Delete(i); } diff --git a/src/hwrenderer/utility/hw_cvars.cpp b/src/hwrenderer/utility/hw_cvars.cpp index f0a0f8c83..1d11e24b1 100644 --- a/src/hwrenderer/utility/hw_cvars.cpp +++ b/src/hwrenderer/utility/hw_cvars.cpp @@ -92,7 +92,7 @@ CUSTOM_CVAR(Float,gl_texture_filter_anisotropic,8.0f,CVAR_ARCHIVE|CVAR_GLOBALCON CCMD(gl_flush) { - FMaterial::FlushAll(); + TexMan.FlushAll(); } CUSTOM_CVAR(Int, gl_texture_filter, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL) @@ -103,7 +103,7 @@ CUSTOM_CVAR(Int, gl_texture_filter, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINI CUSTOM_CVAR(Bool, gl_texture_usehires, true, CVAR_ARCHIVE|CVAR_NOINITCALL) { - FMaterial::FlushAll(); + TexMan.FlushAll(); } CVAR(Bool, gl_precache, false, CVAR_ARCHIVE) diff --git a/src/textures/hires/hqresize.cpp b/src/textures/hires/hqresize.cpp index cc8a65678..e6acb4911 100644 --- a/src/textures/hires/hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -52,7 +52,7 @@ CUSTOM_CVAR(Int, gl_texture_hqresizemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | self = 0; if ((gl_texture_hqresizemult > 4) && (self < 4) && (self > 0)) gl_texture_hqresizemult = 4; - FMaterial::FlushAll(); + TexMan.FlushAll(); } CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) @@ -61,18 +61,18 @@ CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | self = 1; if ((self > 4) && (gl_texture_hqresizemode < 4) && (gl_texture_hqresizemode > 0)) self = 4; - FMaterial::FlushAll(); + TexMan.FlushAll(); } CUSTOM_CVAR(Int, gl_texture_hqresize_maxinputsize, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { if (self > 1024) self = 1024; - FMaterial::FlushAll(); + TexMan.FlushAll(); } CUSTOM_CVAR(Int, gl_texture_hqresize_targets, 7, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { - FMaterial::FlushAll(); + TexMan.FlushAll(); } CVAR (Flag, gl_texture_hqresize_textures, gl_texture_hqresize_targets, 1); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 7dfd00484..f8069393e 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -790,7 +790,9 @@ FWrapperTexture::FWrapperTexture(int w, int h, int bits) Format = bits; UseType = ETextureType::SWCanvas; bNoCompress = true; - SystemTextures.AddHardwareTexture(0, false, screen->CreateHardwareTexture()); + auto hwtex = screen->CreateHardwareTexture(); + // todo: Initialize here. + SystemTextures.AddHardwareTexture(0, false, hwtex); } //=========================================================================== diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 558a6243c..bb2fe50f2 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -141,6 +141,31 @@ void FTextureManager::DeleteAll() BuildTileData.Clear(); } +//========================================================================== +// +// Flushes all hardware dependent data. +// Thia must not, under any circumstances, delete the wipe textures, because +// all CCMDs triggering a flush can be executed while a wipe is in progress +// +// This now also deletes the software textures because having the software +// renderer use the texture scalers is a planned feature and that is the +// main reason to call this outside of the destruction code. +// +//========================================================================== + +void FTextureManager::FlushAll() +{ + for (int i = TexMan.NumTextures() - 1; i >= 0; i--) + { + for (int j = 0; j < 2; j++) + { + TexMan.ByIndex(i)->SystemTextures.Clean(true, true); + delete TexMan.ByIndex(i)->SoftwareTexture; + } + } + // This must also delete the software renderer's canvas. +} + //========================================================================== // // FTextureManager :: CheckForTexture diff --git a/src/textures/textures.h b/src/textures/textures.h index 199ce0be8..90d12c0c2 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -345,7 +345,9 @@ protected: FTextureID id; FMaterial *Material[2] = { nullptr, nullptr }; +public: FHardwareTextureContainer SystemTextures; +protected: //IHardwareTexture *SystemTexture[2] = { nullptr, nullptr }; FSoftwareTexture *SoftwareTexture = nullptr; @@ -540,6 +542,7 @@ public: } FTexture *FindTexture(const char *texname, ETextureType usetype = ETextureType::MiscPatch, BITFIELD flags = TEXMAN_TryAny); + void FlushAll(); //public: diff --git a/src/v_video.h b/src/v_video.h index bbbcb71f9..216fa2d31 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -425,7 +425,6 @@ public: virtual void CleanForRestart() {} virtual void SetTextureFilterMode() {} virtual IHardwareTexture *CreateHardwareTexture() { return nullptr; } - virtual bool CheckPrecacheMaterial(FMaterial *mat) { return true; } virtual void PrecacheMaterial(FMaterial *mat, int translation) {} virtual FModelRenderer *CreateModelRenderer(int mli) { return nullptr; } virtual void UnbindTexUnit(int no) {} From 173b8beb3364d69eec8231aff8fdc118bef604f4 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 18:55:55 +0100 Subject: [PATCH 44/66] - cleaned out the FHardwareTexture class, now that the translations are finally handled on a higher level. --- src/gl/system/gl_framebuffer.cpp | 4 +- src/gl/textures/gl_hwtexture.cpp | 158 +++--------------------- src/gl/textures/gl_hwtexture.h | 43 ++----- src/hwrenderer/textures/hw_ihwtexture.h | 2 - 4 files changed, 30 insertions(+), 177 deletions(-) diff --git a/src/gl/system/gl_framebuffer.cpp b/src/gl/system/gl_framebuffer.cpp index 8573a21dd..08a9cc030 100644 --- a/src/gl/system/gl_framebuffer.cpp +++ b/src/gl/system/gl_framebuffer.cpp @@ -510,7 +510,7 @@ FTexture *OpenGLFrameBuffer::WipeStartScreen() auto tex = new FWrapperTexture(viewport.width, viewport.height, 1); tex->GetSystemTexture()->CreateTexture(nullptr, viewport.width, viewport.height, 0, false, 0, "WipeStartScreen"); glFinish(); - static_cast(tex->GetSystemTexture())->Bind(0, false, false); + static_cast(tex->GetSystemTexture())->Bind(0, false); GLRenderer->mBuffers->BindCurrentFB(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height); @@ -532,7 +532,7 @@ FTexture *OpenGLFrameBuffer::WipeEndScreen() auto tex = new FWrapperTexture(viewport.width, viewport.height, 1); tex->GetSystemTexture()->CreateTexture(NULL, viewport.width, viewport.height, 0, false, 0, "WipeEndScreen"); glFinish(); - static_cast(tex->GetSystemTexture())->Bind(0, false, false); + static_cast(tex->GetSystemTexture())->Bind(0, false); GLRenderer->mBuffers->BindCurrentFB(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, viewport.left, viewport.top, viewport.width, viewport.height); return tex; diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index b9034b101..9c5f7b894 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -96,17 +96,16 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int texformat = GL_RGBA8; } */ - TranslatedTexture * glTex=GetTexID(translation); - bool firstCall = glTex->glTexID == 0; - if (firstCall) glGenTextures(1,&glTex->glTexID); + bool firstCall = glTexID == 0; + if (firstCall) glGenTextures(1,&glTexID); int textureBinding = UINT_MAX; if (texunit == -1) glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); if (texunit > 0) glActiveTexture(GL_TEXTURE0+texunit); - if (texunit >= 0) lastbound[texunit] = glTex->glTexID; - glBindTexture(GL_TEXTURE_2D, glTex->glTexID); + if (texunit >= 0) lastbound[texunit] = glTexID; + glBindTexture(GL_TEXTURE_2D, glTexID); - FGLDebug::LabelObject(GL_TEXTURE, glTex->glTexID, name); + FGLDebug::LabelObject(GL_TEXTURE, glTexID, name); rw = GetTexDimension(w); rh = GetTexDimension(h); @@ -118,7 +117,7 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int else if (!buffer) { // The texture must at least be initialized if no data is present. - glTex->mipmapped = false; + mipmapped = false; buffer=(unsigned char *)calloc(4,rw * (rh+1)); deletebuffer=true; //texheight=-h; @@ -169,12 +168,12 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int if (mipmap && TexFilter[gl_texture_filter].mipmapping) { glGenerateMipmap(GL_TEXTURE_2D); - glTex->mipmapped = true; + mipmapped = true; } if (texunit > 0) glActiveTexture(GL_TEXTURE0); else if (texunit == -1) glBindTexture(GL_TEXTURE_2D, textureBinding); - return glTex->glTexID; + return glTexID; } @@ -205,66 +204,6 @@ uint8_t *FHardwareTexture::MapBuffer() return (uint8_t*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY); } -//=========================================================================== -// -// Creates a texture -// -//=========================================================================== -FHardwareTexture::FHardwareTexture(bool nocompression) -{ - forcenocompression = nocompression; - - glDefTex.glTexID = 0; - glDefTex.translation = 0; - glDefTex.mipmapped = false; - glDepthID = 0; -} - - -//=========================================================================== -// -// Deletes a texture id and unbinds it from the texture units -// -//=========================================================================== -void FHardwareTexture::TranslatedTexture::Delete() -{ - if (glTexID != 0) - { - for(int i = 0; i < MAX_TEXTURES; i++) - { - if (lastbound[i] == glTexID) - { - lastbound[i] = 0; - } - } - glDeleteTextures(1, &glTexID); - glTexID = 0; - mipmapped = false; - } -} - -//=========================================================================== -// -// Frees all associated resources -// -//=========================================================================== -void FHardwareTexture::Clean(bool all) -{ - int cm_arraysize = CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size(); - - if (all) - { - glDefTex.Delete(); - } - for(unsigned int i=0;iglTexID != 0) + if (glTexID != 0) { - if (lastbound[texunit] == pTex->glTexID) return pTex->glTexID; - lastbound[texunit] = pTex->glTexID; + if (lastbound[texunit] == glTexID) return glTexID; + lastbound[texunit] = glTexID; if (texunit != 0) glActiveTexture(GL_TEXTURE0 + texunit); - glBindTexture(GL_TEXTURE_2D, pTex->glTexID); + glBindTexture(GL_TEXTURE_2D, glTexID); // Check if we need mipmaps on a texture that was creted without them. - if (needmipmap && !pTex->mipmapped && TexFilter[gl_texture_filter].mipmapping) + if (needmipmap && !mipmapped && TexFilter[gl_texture_filter].mipmapping) { glGenerateMipmap(GL_TEXTURE_2D); - pTex->mipmapped = true; + mipmapped = true; } if (texunit != 0) glActiveTexture(GL_TEXTURE0); - return pTex->glTexID; + return glTexID; } return 0; } unsigned int FHardwareTexture::GetTextureHandle(int translation) { - TranslatedTexture *pTex = GetTexID(translation); - return pTex->glTexID; + return glTexID; } void FHardwareTexture::Unbind(int texunit) @@ -390,7 +295,7 @@ void FHardwareTexture::BindToFrameBuffer(int width, int height) { width = GetTexDimension(width); height = GetTexDimension(height); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTex.glTexID, 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glTexID, 0); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer(width, height)); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer(width, height)); } @@ -419,7 +324,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i bool needmipmap = (clampmode <= CLAMP_XY); // Bind it to the system. - if (!Bind(texunit, translation, needmipmap)) + if (!Bind(texunit, needmipmap)) { int w = 0, h = 0; @@ -450,29 +355,4 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i return true; } -//=========================================================================== -// -// Binds a texture to the renderer -// -//=========================================================================== - -bool FHardwareTexture::Exists(int translation) -{ - int usebright = false; - - if (translation <= 0) - { - translation = -translation; - } - else - { - auto remap = TranslationToTable(translation); - translation = remap == nullptr ? 0 : remap->GetUniqueIndex(); - } - - TranslatedTexture *pTex = GetTexID(translation); - return (pTex->glTexID != 0); -} - - } diff --git a/src/gl/textures/gl_hwtexture.h b/src/gl/textures/gl_hwtexture.h index 46e9cfde4..db01f3637 100644 --- a/src/gl/textures/gl_hwtexture.h +++ b/src/gl/textures/gl_hwtexture.h @@ -19,31 +19,8 @@ class AActor; namespace OpenGLRenderer { - -// For error catching while changing parameters. -enum EInvalid -{ - Invalid = 0 -}; - class FHardwareTexture : public IHardwareTexture { -public: - enum - { - MAX_TEXTURES = 16 - }; - -private: - struct TranslatedTexture - { - unsigned int glTexID; - int translation; - bool mipmapped; - - void Delete(); - }; - public: static unsigned int lastbound[MAX_TEXTURES]; @@ -60,18 +37,20 @@ private: bool forcenocompression; - TranslatedTexture glDefTex; - TArray glTex_Translated; - unsigned int glDepthID; // only used by camera textures + unsigned int glTexID = 0; + unsigned int glDepthID = 0; // only used by camera textures unsigned int glBufferID = 0; int glTextureBytes = 4; - - TranslatedTexture * GetTexID(int translation); + bool mipmapped = false; int GetDepthBuffer(int w, int h); public: - FHardwareTexture(bool nocompress); + FHardwareTexture(bool nocompress) + { + forcenocompression = nocompress; + } + ~FHardwareTexture(); static void Unbind(int texunit); @@ -79,18 +58,14 @@ public: void BindToFrameBuffer(int w, int h); - unsigned int Bind(int texunit, int translation, bool needmipmap); + unsigned int Bind(int texunit, bool needmipmap); bool BindOrCreate(FTexture *tex, int texunit, int clampmode, int translation, int flags); - bool Exists(int translation); void AllocateBuffer(int w, int h, int texelsize); uint8_t *MapBuffer(); - unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const FString &name) = delete; unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name); unsigned int GetTextureHandle(int translation); - - void Clean(bool all); }; } diff --git a/src/hwrenderer/textures/hw_ihwtexture.h b/src/hwrenderer/textures/hw_ihwtexture.h index 07486e147..f05baf47d 100644 --- a/src/hwrenderer/textures/hw_ihwtexture.h +++ b/src/hwrenderer/textures/hw_ihwtexture.h @@ -25,8 +25,6 @@ public: virtual uint8_t *MapBuffer() = 0; virtual unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation, const char *name) = 0; - virtual void Clean(bool all) = 0; - void Resize(int swidth, int sheight, int width, int height, unsigned char *src_data, unsigned char *dst_data); }; From 7ea1e8acee344559542b78fb165d056982d07c02 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 20:07:46 +0100 Subject: [PATCH 45/66] - fixed layer creation. --- src/hwrenderer/textures/hw_material.cpp | 30 ++++++++++++++----------- src/textures/texturemanager.cpp | 7 +++--- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index 13cd9298e..b33efc190 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -404,17 +404,21 @@ outl: IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) { - FTexture *texture = i == 0 ? tex : mTextureLayers[i - 1]; - if (pLayer) *pLayer = tex; - - auto hwtex = tex->SystemTextures.GetHardwareTexture(translation, mExpanded); - if (hwtex == nullptr) + FTexture *layer = i == 0 ? tex : mTextureLayers[i - 1]; + if (pLayer) *pLayer = layer; + + if (layer && layer->UseType!=ETextureType::Null) { - hwtex = screen->CreateHardwareTexture(); - // Fixme: This needs to create the texture here and not implicitly in BindOrCreate! - tex->SystemTextures.AddHardwareTexture(translation, mExpanded, hwtex); + IHardwareTexture *hwtex = layer->SystemTextures.GetHardwareTexture(0, mExpanded); + if (hwtex == nullptr) + { + hwtex = screen->CreateHardwareTexture(); + layer->SystemTextures.AddHardwareTexture(0, mExpanded, hwtex); + hwtex = tex->SystemTextures.GetHardwareTexture(0, mExpanded); + } + return hwtex; } - return hwtex; + return nullptr; } //=========================================================================== @@ -473,8 +477,8 @@ again: { if (tex->bNoExpand) expand = false; - FMaterial *gltex = tex->Material[expand]; - if (gltex == NULL && create) + FMaterial *hwtex = tex->Material[expand]; + if (hwtex == NULL && create) { if (expand) { @@ -493,9 +497,9 @@ again: goto again; } } - gltex = new FMaterial(tex, expand); + hwtex = new FMaterial(tex, expand); } - return gltex; + return hwtex; } return NULL; } diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index bb2fe50f2..799edb4aa 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -54,6 +54,7 @@ #include "vm.h" #include "image.h" #include "formats/multipatchtexture.h" +#include "swrenderer/textures/r_swtexture.h" FTextureManager TexMan; @@ -159,11 +160,11 @@ void FTextureManager::FlushAll() { for (int j = 0; j < 2; j++) { - TexMan.ByIndex(i)->SystemTextures.Clean(true, true); - delete TexMan.ByIndex(i)->SoftwareTexture; + Textures[i].Texture->SystemTextures.Clean(true, true); + delete Textures[i].Texture->SoftwareTexture; + Textures[i].Texture->SoftwareTexture = nullptr; } } - // This must also delete the software renderer's canvas. } //========================================================================== From 01e05c9b70c4f67be901254f2ed6fa77740b834d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 20:11:09 +0100 Subject: [PATCH 46/66] - now it's correct. --- src/hwrenderer/textures/hw_material.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index b33efc190..fc2e3fa9b 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -409,12 +409,12 @@ IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) if (layer && layer->UseType!=ETextureType::Null) { - IHardwareTexture *hwtex = layer->SystemTextures.GetHardwareTexture(0, mExpanded); + IHardwareTexture *hwtex = layer->SystemTextures.GetHardwareTexture(translation, mExpanded); if (hwtex == nullptr) { hwtex = screen->CreateHardwareTexture(); - layer->SystemTextures.AddHardwareTexture(0, mExpanded, hwtex); - hwtex = tex->SystemTextures.GetHardwareTexture(0, mExpanded); + layer->SystemTextures.AddHardwareTexture(translation, mExpanded, hwtex); + hwtex = tex->SystemTextures.GetHardwareTexture(translation, mExpanded); } return hwtex; } From 134460bae6ee0b40316c85aff87e0f989db78a85 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 20:16:02 +0100 Subject: [PATCH 47/66] - one final fix. --- src/hwrenderer/textures/hw_material.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hwrenderer/textures/hw_material.cpp b/src/hwrenderer/textures/hw_material.cpp index fc2e3fa9b..d24f0d69a 100644 --- a/src/hwrenderer/textures/hw_material.cpp +++ b/src/hwrenderer/textures/hw_material.cpp @@ -414,8 +414,7 @@ IHardwareTexture *FMaterial::GetLayer(int i, int translation, FTexture **pLayer) { hwtex = screen->CreateHardwareTexture(); layer->SystemTextures.AddHardwareTexture(translation, mExpanded, hwtex); - hwtex = tex->SystemTextures.GetHardwareTexture(translation, mExpanded); - } + } return hwtex; } return nullptr; From 7ffc2f12753eae3222ddeb77aa66328b189644e7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 13 Dec 2018 23:25:55 +0100 Subject: [PATCH 48/66] - fixed invalid texture accesses in the software renderer. --- src/swrenderer/line/r_line.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 0a376c791..a72b697b1 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -453,10 +453,10 @@ namespace swrenderer swal = draw_segment->swall; FTexture *tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true); FSoftwareTexture *pic = tex && tex->isValid()? tex->GetSoftwareTexture() : nullptr; - double yscale = pic->GetScale().Y * sidedef->GetTextureYScale(side_t::mid); + double yscale = (pic? pic->GetScale().Y : 1.0) * sidedef->GetTextureYScale(side_t::mid); fixed_t xoffset = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); - if (pic->useWorldPanning()) + if (pic && pic->useWorldPanning()) { xoffset = xs_RoundToInt(xoffset * lwallscale); } @@ -877,6 +877,7 @@ namespace swrenderer auto tex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true); mMiddlePart.Texture = tex && tex->isValid() ? tex->GetSoftwareTexture() : nullptr; + if (mMiddlePart.Texture == nullptr) return; mMiddlePart.TextureOffsetU = FLOAT2FIXED(sidedef->GetTextureXOffset(side_t::mid)); double rowoffset = sidedef->GetTextureYOffset(side_t::mid); mMiddlePart.TextureScaleU = sidedef->GetTextureXScale(side_t::mid); From fc5dd17d772bee0f849b5206850320839596e793 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 14 Dec 2018 01:31:40 +0100 Subject: [PATCH 49/66] - fixed 3D floor texture setup. This code really makes zero sense, it looks like the cases for upper and lower texture should never be entered ever. --- src/swrenderer/line/r_line.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index a72b697b1..9083f9ec4 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -773,13 +773,13 @@ namespace swrenderer FTexture *ftex = TexMan.GetPalettedTexture(sidedef->GetTexture(side_t::mid), true); FSoftwareTexture *midtex = ftex && ftex->isValid() ? ftex->GetSoftwareTexture() : nullptr; - bool segtextured = midtex != NULL || mTopPart.Texture != NULL || mBottomPart.Texture != NULL; + bool segtextured = ftex != NULL || mTopPart.Texture != NULL || mBottomPart.Texture != NULL; // calculate light table if (needlights && (segtextured || (mBackSector && IsFogBoundary(mFrontSector, mBackSector)))) { lwallscale = - midtex ? (midtex->GetScale().X * sidedef->GetTextureXScale(side_t::mid)) : + ftex ? ((midtex? midtex->GetScale().X : 1.0) * sidedef->GetTextureXScale(side_t::mid)) : mTopPart.Texture ? (mTopPart.Texture->GetScale().X * sidedef->GetTextureXScale(side_t::top)) : mBottomPart.Texture ? (mBottomPart.Texture->GetScale().X * sidedef->GetTextureXScale(side_t::bottom)) : 1.; From 1e844336b91c9b6c551aba17e2d536518968c191 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 14 Dec 2018 01:46:26 +0100 Subject: [PATCH 50/66] - fixed memory leak with texture creation. --- src/gl/textures/gl_hwtexture.cpp | 2 +- src/textures/textures.h | 25 ++++++++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 9c5f7b894..01bfdf1b6 100644 --- a/src/gl/textures/gl_hwtexture.cpp +++ b/src/gl/textures/gl_hwtexture.cpp @@ -335,7 +335,7 @@ bool FHardwareTexture::BindOrCreate(FTexture *tex, int texunit, int clampmode, i if (!tex->isHardwareCanvas()) { - texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData); + texbuffer = std::move(tex->CreateTexBuffer(translation, flags | CTF_ProcessData)); w = texbuffer.mWidth; h = texbuffer.mHeight; } diff --git a/src/textures/textures.h b/src/textures/textures.h index 90d12c0c2..d25026634 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -247,10 +247,33 @@ struct FTextureBuffer int mHeight = 0; uint64_t mContentId = 0; // unique content identifier. (Two images created from the same image source with the same settings will return the same value.) - FTextureBuffer() + FTextureBuffer() = default; + + ~FTextureBuffer() { if (mBuffer) delete[] mBuffer; } + + FTextureBuffer(const FTextureBuffer &other) = delete; + FTextureBuffer(FTextureBuffer &&other) + { + mBuffer = other.mBuffer; + mWidth = other.mWidth; + mHeight = other.mHeight; + mContentId = other.mContentId; + other.mBuffer = nullptr; + } + + FTextureBuffer& operator=(FTextureBuffer &&other) + { + mBuffer = other.mBuffer; + mWidth = other.mWidth; + mHeight = other.mHeight; + mContentId = other.mContentId; + other.mBuffer = nullptr; + return *this; + } + }; // Base texture class From bd6ba47d63b19d572aac30e746161daaf217968e Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 13 Dec 2018 22:29:08 +0100 Subject: [PATCH 51/66] - fixed: The multipatch texture builder may not store the texture IDs on assignment. Between creation and resolving the texture manager will resort the textures and after that the old ids are no longer valid. The textures themselves have the correct one, so that should be used. --- src/textures/formats/multipatchtexture.h | 1 - src/textures/multipatchtexturebuilder.cpp | 11 +++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/textures/formats/multipatchtexture.h b/src/textures/formats/multipatchtexture.h index bda492b84..f1284e0a9 100644 --- a/src/textures/formats/multipatchtexture.h +++ b/src/textures/formats/multipatchtexture.h @@ -86,7 +86,6 @@ struct BuildInfo bool bNoDecals = false; int LeftOffset[2] = {}; int TopOffset[2] = {}; - FTextureID id = {}; FImageTexture *tex = nullptr; }; diff --git a/src/textures/multipatchtexturebuilder.cpp b/src/textures/multipatchtexturebuilder.cpp index aa727bef1..1ccb99026 100644 --- a/src/textures/multipatchtexturebuilder.cpp +++ b/src/textures/multipatchtexturebuilder.cpp @@ -160,7 +160,6 @@ void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType u tex->bWorldPanning = buildinfo.bWorldPanning; tex->bNoDecals = buildinfo.bNoDecals; tex->SourceLump = buildinfo.DefinitionLump; - buildinfo.id = TexMan.AddTexture(tex); buildinfo.tex = tex; } @@ -833,19 +832,19 @@ void FMultipatchTextureBuilder::ResolvePatches(BuildInfo &buildinfo) for (unsigned i = 0; i < buildinfo.Inits.Size(); i++) { FTextureID texno = TexMan.CheckForTexture(buildinfo.Inits[i].TexName, buildinfo.Inits[i].UseType); - if (texno == buildinfo.id) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself. + if (texno == buildinfo.tex->id) // we found ourselves. Try looking for another one with the same name which is not a multipatch texture itself. { TArray list; TexMan.ListTextures(buildinfo.Inits[i].TexName, list, true); for (int i = list.Size() - 1; i >= 0; i--) { - if (list[i] != buildinfo.id && !TexMan.GetTexture(list[i])->bMultiPatch) + if (list[i] != buildinfo.tex->id && !TexMan.GetTexture(list[i])->bMultiPatch) { texno = list[i]; break; } } - if (texno == buildinfo.id) + if (texno == buildinfo.tex->id) { if (buildinfo.Inits[i].HasLine) buildinfo.Inits[i].sc.Message(MSG_WARNING, "Texture '%s' references itself as patch\n", buildinfo.Inits[i].TexName.GetChars()); else Printf(TEXTCOLOR_YELLOW "Texture '%s' references itself as patch\n", buildinfo.Inits[i].TexName.GetChars()); @@ -964,10 +963,10 @@ void FMultipatchTextureBuilder::ResolveAllPatches() } if (!donesomething) { - Printf(PRINT_LOG, "%d Unresolved textures remain\n", BuiltTextures.Size()); + Printf("%d Unresolved textures remain\n", BuiltTextures.Size()); for (auto &b : BuiltTextures) { - Printf(PRINT_LOG, "%s\n", b.Name.GetChars()); + Printf("%s\n", b.Name.GetChars()); } break; } From e157e36b43bbdec9228bd875c0902632dcf71d28 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 14 Dec 2018 01:48:53 +0100 Subject: [PATCH 52/66] - the texture still needs to be added to the texture manager. --- src/textures/multipatchtexturebuilder.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/textures/multipatchtexturebuilder.cpp b/src/textures/multipatchtexturebuilder.cpp index 1ccb99026..b5dd1518c 100644 --- a/src/textures/multipatchtexturebuilder.cpp +++ b/src/textures/multipatchtexturebuilder.cpp @@ -161,6 +161,7 @@ void FMultipatchTextureBuilder::MakeTexture(BuildInfo &buildinfo, ETextureType u tex->bNoDecals = buildinfo.bNoDecals; tex->SourceLump = buildinfo.DefinitionLump; buildinfo.tex = tex; + TexMan.AddTexture(tex); } //========================================================================== From a19f297ae03e8dc4bd960c3d970a6111be358c0d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 14 Dec 2018 19:59:19 +0100 Subject: [PATCH 53/66] - fixed incorrect alignment of scaled world panned textures combined with per-sidedef scaling in the hardware renderer This particular case incorrectly factored in the sidedef's scaling factor for how to calculate the offset. Fortunately this is a very rare case - a quick check yielded no maps depending on it. Should any map surface that depends on this bug a compatibility option may be needed but it doesn't seem likely that this may be the case. --- src/textures/texture.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index f8069393e..fa23e419b 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -823,7 +823,7 @@ float FTexCoordInfo::RowOffset(float rowoffset) const } else { - if (mWorldPanning) return rowoffset / tscale; + if (mWorldPanning) return rowoffset; else return rowoffset / scale; } } @@ -845,7 +845,7 @@ float FTexCoordInfo::TextureOffset(float textureoffset) const } else { - if (mWorldPanning) return textureoffset / tscale; + if (mWorldPanning) return textureoffset; else return textureoffset / scale; } } From cd25b4be4f4667456f68aa2f3f80b09cf9903f6c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 10:04:49 +0100 Subject: [PATCH 54/66] - use a TArray to store the particles and remove all 16 bit global variables. This means one less exit function to deal with - and these days 16 bit variables are a pointless attempt at saving space. --- src/p_effect.cpp | 45 +++++++++----------------- src/p_effect.h | 2 +- src/polyrenderer/scene/poly_scene.cpp | 2 +- src/swrenderer/scene/r_opaque_pass.cpp | 2 +- 4 files changed, 18 insertions(+), 33 deletions(-) diff --git a/src/p_effect.cpp b/src/p_effect.cpp index aeb5b0ec8..da43890c5 100644 --- a/src/p_effect.cpp +++ b/src/p_effect.cpp @@ -59,10 +59,9 @@ FRandom pr_railtrail("RailTrail"); #define FADEFROMTTL(a) (1.f/(a)) // [RH] particle globals -uint16_t NumParticles; -uint16_t ActiveParticles; -uint16_t InactiveParticles; -particle_t *Particles; +uint32_t ActiveParticles; +uint32_t InactiveParticles; +TArray Particles; TArray ParticlesInSubsec; static int grey1, grey2, grey3, grey4, red, green, blue, yellow, black, @@ -105,13 +104,13 @@ static const struct ColorList { inline particle_t *NewParticle (void) { - particle_t *result = NULL; + particle_t *result = nullptr; if (InactiveParticles != NO_PARTICLE) { - result = Particles + InactiveParticles; + result = &Particles[InactiveParticles]; InactiveParticles = result->tnext; result->tnext = ActiveParticles; - ActiveParticles = uint16_t(result - Particles); + ActiveParticles = uint32_t(result - Particles.Data()); } return result; } @@ -120,7 +119,6 @@ inline particle_t *NewParticle (void) // [RH] Particle functions // void P_InitParticles (); -void P_DeinitParticles (); // [BC] Allow the maximum number of particles to be specified by a cvar (so people // with lots of nice hardware can have lots of particles!). @@ -135,7 +133,6 @@ CUSTOM_CVAR( Int, r_maxparticles, 4000, CVAR_ARCHIVE ) if ( gamestate != GS_STARTUP ) { - P_DeinitParticles( ); P_InitParticles( ); } } @@ -152,33 +149,21 @@ void P_InitParticles () num = r_maxparticles; // This should be good, but eh... - NumParticles = (uint16_t)clamp(num, 100, 65535); + int NumParticles = clamp(num, 100, 65535); - P_DeinitParticles(); - Particles = new particle_t[NumParticles]; + Particles.Resize(NumParticles); P_ClearParticles (); - atterm (P_DeinitParticles); -} - -void P_DeinitParticles() -{ - if (Particles != NULL) - { - delete[] Particles; - Particles = NULL; - } } void P_ClearParticles () { - int i; - - memset (Particles, 0, NumParticles * sizeof(particle_t)); + int i = 0; + memset (Particles.Data(), 0, Particles.Size() * sizeof(particle_t)); ActiveParticles = NO_PARTICLE; InactiveParticles = 0; - for (i = 0; i < NumParticles-1; i++) - Particles[i].tnext = i + 1; - Particles[i].tnext = NO_PARTICLE; + for (auto &p : Particles) + p.tnext = ++i; + Particles.Last().tnext = NO_PARTICLE; } // Group particles by subsectors. Because particles are always @@ -255,7 +240,7 @@ void P_ThinkParticles () prev = NULL; while (i != NO_PARTICLE) { - particle = Particles + i; + particle = &Particles[i]; i = particle->tnext; if (!particle->notimefreeze && ((bglobal.freeze) || (level.flags2 & LEVEL2_FROZEN))) { @@ -274,7 +259,7 @@ void P_ThinkParticles () else ActiveParticles = i; particle->tnext = InactiveParticles; - InactiveParticles = (int)(particle - Particles); + InactiveParticles = (int)(particle - Particles.Data()); continue; } diff --git a/src/p_effect.h b/src/p_effect.h index 4620bfa5a..00689118a 100644 --- a/src/p_effect.h +++ b/src/p_effect.h @@ -62,7 +62,7 @@ struct particle_t uint16_t snext; }; -extern particle_t *Particles; +extern TArray Particles; extern TArray ParticlesInSubsec; const uint16_t NO_PARTICLE = 0xffff; diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index 2f5e36702..f92c73762 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -189,7 +189,7 @@ void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub int subsectorIndex = sub->Index(); for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext) { - particle_t *particle = Particles + i; + particle_t *particle = &Particles[i]; thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject(particle, sub, subsectorDepth, CurrentViewpoint->StencilValue)); } } diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index 1b03361ef..cff29cbb4 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -616,7 +616,7 @@ namespace swrenderer int shade = LightVisibility::LightLevelToShade((floorlightlevel + ceilinglightlevel) / 2 + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); for (int i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext) { - RenderParticle::Project(Thread, Particles + i, sub->sector, shade, FakeSide, foggy); + RenderParticle::Project(Thread, &Particles[i], sub->sector, shade, FakeSide, foggy); } } From 48d87e3dcf961d2643d7ed618c7689786355c4d3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 11:55:21 +0100 Subject: [PATCH 55/66] - use TArrays for most buffers being used in the font class. --- src/v_font.cpp | 89 +++++++++++++++++--------------------------------- src/v_font.h | 9 ++--- 2 files changed, 35 insertions(+), 63 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index 560a47f57..4cccf32a4 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -310,16 +310,14 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, int i; FTextureID lump; char buffer[12]; - TArray charLumps; + TArray charLumps(count, true); int maxyoffs; bool doomtemplate = gameinfo.gametype & GAME_DoomChex ? strncmp (nametemplate, "STCFN", 5) == 0 : false; bool stcfn121 = false; noTranslate = notranslate; Lump = fdlump; - Chars = new CharData[count]; - charLumps.Resize(count); - PatchRemap = new uint8_t[256]; + Chars.Resize(count); FirstChar = first; LastChar = first + count - 1; FontHeight = 0; @@ -422,19 +420,6 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, FFont::~FFont () { - if (Chars) - { - int count = LastChar - FirstChar + 1; - - delete[] Chars; - Chars = NULL; - } - if (PatchRemap) - { - delete[] PatchRemap; - PatchRemap = NULL; - } - FFont **prev = &FirstFont; FFont *font = *prev; @@ -537,7 +522,7 @@ static int compare (const void *arg1, const void *arg2) // //========================================================================== -int FFont::SimpleTranslation (uint8_t *colorsused, uint8_t *translation, uint8_t *reverse, double **luminosity) +int FFont::SimpleTranslation (uint8_t *colorsused, uint8_t *translation, uint8_t *reverse, TArray &Luminosity) { double min, max, diver; int i, j; @@ -555,26 +540,26 @@ int FFont::SimpleTranslation (uint8_t *colorsused, uint8_t *translation, uint8_t qsort (reverse+1, j-1, 1, compare); - *luminosity = new double[j]; - (*luminosity)[0] = 0.0; // [BL] Prevent uninitalized memory + Luminosity.Resize(j); + Luminosity[0] = 0.0; // [BL] Prevent uninitalized memory max = 0.0; min = 100000000.0; for (i = 1; i < j; i++) { translation[reverse[i]] = i; - (*luminosity)[i] = RPART(GPalette.BaseColors[reverse[i]]) * 0.299 + + Luminosity[i] = RPART(GPalette.BaseColors[reverse[i]]) * 0.299 + GPART(GPalette.BaseColors[reverse[i]]) * 0.587 + BPART(GPalette.BaseColors[reverse[i]]) * 0.114; - if ((*luminosity)[i] > max) - max = (*luminosity)[i]; - if ((*luminosity)[i] < min) - min = (*luminosity)[i]; + if (Luminosity[i] > max) + max = Luminosity[i]; + if (Luminosity[i] < min) + min = Luminosity[i]; } diver = 1.0 / (max - min); for (i = 1; i < j; i++) { - (*luminosity)[i] = ((*luminosity)[i] - min) * diver; + Luminosity[i] = (Luminosity[i] - min) * diver; } return j; @@ -858,7 +843,7 @@ void FFont::LoadTranslations() { unsigned int count = LastChar - FirstChar + 1; uint8_t usedcolors[256], identity[256]; - double *luminosity; + TArray Luminosity; memset (usedcolors, 0, 256); for (unsigned int i = 0; i < count; i++) @@ -876,7 +861,7 @@ void FFont::LoadTranslations() // Fixme: This needs to build a translation based on the source palette, not some intermediate 'ordered' table. - ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); + ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, Luminosity); for (unsigned int i = 0; i < count; i++) { @@ -884,9 +869,7 @@ void FFont::LoadTranslations() static_cast(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); } - BuildTranslations (luminosity, identity, &TranslationParms[0][0], ActiveColors, NULL); - - delete[] luminosity; + BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], ActiveColors, NULL); } //========================================================================== @@ -898,8 +881,6 @@ void FFont::LoadTranslations() FFont::FFont (int lump) { Lump = lump; - Chars = NULL; - PatchRemap = NULL; FontName = NAME_None; Cursor = '_'; noTranslate = false; @@ -964,8 +945,8 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) GlobalKerning = 0; FirstChar = LastChar = 'A'; - Chars = new CharData[1]; - Chars->Pic = pic; + Chars.Resize(1); + Chars[0].Pic = pic; // Only one color range. Don't bother with the others. ActiveColors = 0; @@ -1030,7 +1011,7 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data) { int w, h; - Chars = new CharData[256]; + Chars.Resize(256); w = data[4] + data[5]*256; h = data[6] + data[7]*256; @@ -1042,10 +1023,9 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data) LastChar = 255; GlobalKerning = 0; translateUntranslated = true; - PatchRemap = new uint8_t[256]; for(unsigned int i = 0;i < 256;++i) - Chars[i].Pic = NULL; + Chars[i].Pic = nullptr; LoadTranslations(); } @@ -1062,7 +1042,6 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data) void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data) { int count, i, totalwidth; - int *widths2; uint16_t *widths; const uint8_t *palette; const uint8_t *data_p; @@ -1072,12 +1051,11 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data) FirstChar = data[6]; LastChar = data[7]; ActiveColors = data[10]+1; - PatchRemap = NULL; RescalePalette = data[9] == 0; count = LastChar - FirstChar + 1; - Chars = new CharData[count]; - widths2 = new int[count]; + Chars.Resize(count); + TArray widths2(count, true); if (data[11] & 1) { // Font specifies a kerning value. GlobalKerning = LittleShort(*(int16_t *)&data[12]); @@ -1162,7 +1140,6 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data) } LoadTranslations(); - delete[] widths2; } //========================================================================== @@ -1221,7 +1198,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) I_FatalError("BMF font defines no characters"); } count = LastChar - FirstChar + 1; - Chars = new CharData[count]; + Chars.Resize(count); for (i = 0; i < count; ++i) { Chars[i].Pic = NULL; @@ -1247,7 +1224,6 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) qsort(sort_palette + 1, ActiveColors - 1, sizeof(PalEntry), BMFCompare); // Create the PatchRemap table from the sorted "alpha" values. - PatchRemap = new uint8_t[ActiveColors]; PatchRemap[0] = 0; for (i = 1; i < ActiveColors; ++i) { @@ -1515,10 +1491,11 @@ int FSinglePicFont::GetCharWidth (int code) const // //========================================================================== -FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate) : FFont(lump) +FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **lumplist, const bool *notranslate, int lump, bool donttranslate) + : FFont(lump) { int i; - FTexture **charlumps; + TArray charlumps(count, true); int maxyoffs; FTexture *pic; @@ -1526,9 +1503,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l noTranslate = donttranslate; FontName = name; - Chars = new CharData[count]; - charlumps = new FTexture*[count]; - PatchRemap = new uint8_t[256]; + Chars.Resize(count); FirstChar = first; LastChar = first + count - 1; FontHeight = 0; @@ -1541,7 +1516,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l for (i = 0; i < count; i++) { pic = charlumps[i] = lumplist[i]; - if (pic != NULL) + if (pic != nullptr) { int height = pic->GetDisplayHeight(); int yoffs = pic->GetDisplayTopOffset(); @@ -1557,7 +1532,7 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l } } - if (charlumps[i] != NULL) + if (charlumps[i] != nullptr) { if (!noTranslate) { @@ -1594,8 +1569,6 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l { LoadTranslations(); } - - delete[] charlumps; } //========================================================================== @@ -1608,7 +1581,7 @@ void FSpecialFont::LoadTranslations() { int count = LastChar - FirstChar + 1; uint8_t usedcolors[256], identity[256]; - double *luminosity; + TArray Luminosity; int TotalColors; int i, j; @@ -1631,7 +1604,7 @@ void FSpecialFont::LoadTranslations() if (notranslate[i]) usedcolors[i] = false; - TotalColors = ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, &luminosity); + TotalColors = ActiveColors = SimpleTranslation (usedcolors, PatchRemap, identity, Luminosity); // Map all untranslated colors into the table of used colors for (i = 0; i < 256; i++) @@ -1650,7 +1623,7 @@ void FSpecialFont::LoadTranslations() static_cast(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); } - BuildTranslations (luminosity, identity, &TranslationParms[0][0], TotalColors, NULL); + BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], TotalColors, NULL); // add the untranslated colors to the Ranges tables if (ActiveColors < TotalColors) @@ -1667,8 +1640,6 @@ void FSpecialFont::LoadTranslations() } } ActiveColors = TotalColors; - - delete[] luminosity; } //========================================================================== diff --git a/src/v_font.h b/src/v_font.h index 907c3e1f8..4bc20884e 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -82,7 +82,7 @@ public: FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false); virtual ~FFont (); - virtual FTexture *GetChar (int code, int *const width) const; + FTexture *GetChar (int code, int *const width) const; virtual int GetCharWidth (int code) const; FRemapTable *GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const; int GetLump() const { return Lump; } @@ -112,7 +112,7 @@ protected: void FixXMoves(); static int SimpleTranslation (uint8_t *colorsused, uint8_t *translation, - uint8_t *identity, double **luminosity); + uint8_t *identity, TArray &Luminosity); int FirstChar, LastChar; int SpaceWidth; @@ -125,10 +125,11 @@ protected: { FTexture *Pic; int XMove; - } *Chars; + }; + TArray Chars; int ActiveColors; TArray Ranges; - uint8_t *PatchRemap; + uint8_t PatchRemap[256]; int Lump; FName FontName = NAME_None; From 056b2c3a800cc9155379e578bb7608466d105bf3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 14:25:30 +0100 Subject: [PATCH 56/66] - handle CR_UNTRANSLATED so that it doesn't force CR_UNTRANSLATED to the palette. Since the entire font setup is very much incapable of handling this during rendering, short of a complete rewrite, it was necessary to put the relevant code into the places which process the characters for drawing so that it can disable the translation table (which needs to be passed as raw data to the draw functions) and keep track of both the translatable and the original variant of the character graphics. --- src/g_statusbar/sbarinfo.cpp | 3 +- src/g_statusbar/shared_sbar.cpp | 2 +- src/intermission/intermission.cpp | 2 +- src/v_font.cpp | 151 +++++++++++++++++------------- src/v_font.h | 5 +- src/v_text.cpp | 14 ++- 6 files changed, 100 insertions(+), 77 deletions(-) diff --git a/src/g_statusbar/sbarinfo.cpp b/src/g_statusbar/sbarinfo.cpp index aade1b1f9..7b1184cec 100644 --- a/src/g_statusbar/sbarinfo.cpp +++ b/src/g_statusbar/sbarinfo.cpp @@ -1379,7 +1379,8 @@ public: width = font->GetCharWidth((unsigned char) *str); else width = font->GetCharWidth((unsigned char) script->spacingCharacter); - FTexture* c = font->GetChar((unsigned char) *str, &width); + bool redirected = false; + FTexture* c = font->GetChar((unsigned char) *str, fontcolor, &width); if(c == NULL) //missing character. { str++; diff --git a/src/g_statusbar/shared_sbar.cpp b/src/g_statusbar/shared_sbar.cpp index 1ed349d3a..12b66bf88 100644 --- a/src/g_statusbar/shared_sbar.cpp +++ b/src/g_statusbar/shared_sbar.cpp @@ -1513,7 +1513,7 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d } int width; - FTexture* c = font->GetChar((unsigned char)ch, &width); + FTexture* c = font->GetChar((unsigned char)ch, fontcolor, &width); if (c == NULL) //missing character. { continue; diff --git a/src/intermission/intermission.cpp b/src/intermission/intermission.cpp index e4cd6ac30..4b3826261 100644 --- a/src/intermission/intermission.cpp +++ b/src/intermission/intermission.cpp @@ -337,7 +337,7 @@ void DIntermissionScreenText::Drawer () continue; } - pic = SmallFont->GetChar (c, &w); + pic = SmallFont->GetChar (c, mTextColor, &w); w += kerning; w *= CleanXfac; if (cx + w > SCREENWIDTH) diff --git a/src/v_font.cpp b/src/v_font.cpp index 4cccf32a4..e1e5998ba 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -195,7 +195,7 @@ extern int PrintColors[]; // PUBLIC DATA DEFINITIONS ------------------------------------------------- -FFont *FFont::FirstFont = NULL; +FFont *FFont::FirstFont = nullptr; int NumTextColors; // PRIVATE DATA DEFINITIONS ------------------------------------------------ @@ -266,7 +266,7 @@ static int stripaccent(int code) FFont *V_GetFont(const char *name) { FFont *font = FFont::FindFont (name); - if (font == NULL) + if (font == nullptr) { int lump = -1; @@ -285,7 +285,7 @@ FFont *V_GetFont(const char *name) font = new FSingleLumpFont (name, lump); } } - if (font == NULL) + if (font == nullptr) { FTextureID picnum = TexMan.CheckForTexture (name, ETextureType::Any); if (picnum.isValid()) @@ -327,13 +327,15 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, FirstFont = this; Cursor = '_'; ActiveColors = 0; + uint8_t pp = 0; + for (auto &p : PatchRemap) p = pp++; translateUntranslated = false; maxyoffs = 0; for (i = 0; i < count; i++) { - charLumps[i] = NULL; + charLumps[i] = nullptr; mysnprintf (buffer, countof(buffer), nametemplate, i + start); lump = TexMan.CheckForTexture(buffer, ETextureType::MiscPatch); @@ -356,7 +358,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, if (lump.isValid()) { FTexture *pic = TexMan.GetTexture(lump); - if (pic != NULL) + if (pic != nullptr) { // set the lump here only if it represents a valid texture if (i != 124-start || !stcfn121) @@ -379,17 +381,20 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, if (charLumps[i] != nullptr) { + Chars[i].OriginalPic = charLumps[i]; + if (!noTranslate) { - Chars[i].Pic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage())); - TexMan.AddTexture(Chars[i].Pic); + Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()), ""); + TexMan.AddTexture(Chars[i].TranslatedPic); } - else Chars[i].Pic = charLumps[i]; - Chars[i].XMove = Chars[i].Pic->GetDisplayWidth(); + else Chars[i].TranslatedPic = charLumps[i]; + + Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); } else { - Chars[i].Pic = NULL; + Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; Chars[i].XMove = INT_MIN; } } @@ -398,7 +403,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, { SpaceWidth = spacewidth; } - else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL) + else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr) { SpaceWidth = (Chars['N' - first].XMove + 1) / 2; } @@ -423,13 +428,13 @@ FFont::~FFont () FFont **prev = &FirstFont; FFont *font = *prev; - while (font != NULL && font != this) + while (font != nullptr && font != this) { prev = &font->Next; font = *prev; } - if (font != NULL) + if (font != nullptr) { *prev = font->Next; } @@ -593,10 +598,10 @@ void FFont::BuildTranslations (const double *luminosity, const uint8_t *identity { if (i == CR_UNTRANSLATED) { - if (identity != NULL) + if (identity != nullptr) { memcpy (remap.Remap, identity, ActiveColors); - if (palette != NULL) + if (palette != nullptr) { memcpy (remap.Palette, palette, ActiveColors*sizeof(PalEntry)); } @@ -677,7 +682,7 @@ FRemapTable *FFont::GetColorTranslation (EColorRange range, PalEntry *color) con if (color != nullptr) *color = retcolor; } if (ActiveColors == 0) - return NULL; + return nullptr; else if (range >= NumTextColors) range = CR_UNTRANSLATED; //if (range == CR_UNTRANSLATED && !translateUntranslated) return nullptr; @@ -701,7 +706,7 @@ int FFont::GetCharCode(int code, bool needpic) const // regular chars turn negative when the 8th bit is set. code &= 255; } - if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL)) + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) { return code; } @@ -709,7 +714,7 @@ int FFont::GetCharCode(int code, bool needpic) const if (myislower(code)) { code -= 32; - if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL)) + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) { return code; } @@ -719,7 +724,7 @@ int FFont::GetCharCode(int code, bool needpic) const if (newcode != code) { code = newcode; - if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].Pic != NULL)) + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) { return code; } @@ -733,7 +738,7 @@ int FFont::GetCharCode(int code, bool needpic) const // //========================================================================== -FTexture *FFont::GetChar (int code, int *const width) const +FTexture *FFont::GetChar (int code, int translation, int *const width, bool *redirected) const { code = GetCharCode(code, false); int xmove = SpaceWidth; @@ -742,7 +747,7 @@ FTexture *FFont::GetChar (int code, int *const width) const { code -= FirstChar; xmove = Chars[code].XMove; - if (Chars[code].Pic == NULL) + if (Chars[code].OriginalPic == nullptr) { code = GetCharCode(code + FirstChar, true); if (code >= 0) @@ -752,11 +757,21 @@ FTexture *FFont::GetChar (int code, int *const width) const } } } - if (width != NULL) + if (width != nullptr) { *width = xmove; } - return (code < 0) ? NULL : Chars[code].Pic; + if (code < 0) return nullptr; + + + if (translation == CR_UNTRANSLATED) + { + if (redirected) + *redirected = Chars[code].OriginalPic != Chars[code].TranslatedPic; + return Chars[code].OriginalPic; + } + if (redirected) *redirected = false; + return Chars[code].TranslatedPic; } //========================================================================== @@ -780,8 +795,8 @@ int FFont::GetCharWidth (int code) const double GetBottomAlignOffset(FFont *font, int c) { int w; - FTexture *tex_zero = font->GetChar('0', &w); - FTexture *texc = font->GetChar(c, &w); + FTexture *tex_zero = font->GetChar('0', CR_UNDEFINED, &w); + FTexture *texc = font->GetChar(c, CR_UNDEFINED, &w); double offset = 0; if (texc) offset += texc->GetDisplayTopOffsetDouble(); if (tex_zero) offset += -tex_zero->GetDisplayTopOffsetDouble() + tex_zero->GetDisplayHeightDouble(); @@ -848,12 +863,12 @@ void FFont::LoadTranslations() memset (usedcolors, 0, 256); for (unsigned int i = 0; i < count; i++) { - if (Chars[i].Pic) + if (Chars[i].TranslatedPic) { - FFontChar1 *pic = static_cast(Chars[i].Pic->GetImage()); + FFontChar1 *pic = static_cast(Chars[i].TranslatedPic->GetImage()); if (pic) { - pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture + pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture RecordTextureColors(pic, usedcolors); } } @@ -865,11 +880,11 @@ void FFont::LoadTranslations() for (unsigned int i = 0; i < count; i++) { - if(Chars[i].Pic) - static_cast(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); + if(Chars[i].TranslatedPic) + static_cast(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap); } - BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], ActiveColors, NULL); + BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], ActiveColors, nullptr); } //========================================================================== @@ -946,7 +961,7 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) FirstChar = LastChar = 'A'; Chars.Resize(1); - Chars[0].Pic = pic; + Chars[0].TranslatedPic = Chars[0].OriginalPic = pic; // Only one color range. Don't bother with the others. ActiveColors = 0; @@ -992,11 +1007,11 @@ void FSingleLumpFont::LoadTranslations() for(unsigned int i = 0;i < count;++i) { - if(Chars[i].Pic) - static_cast(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); + if(Chars[i].TranslatedPic) + static_cast(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap); } - BuildTranslations (luminosity, useidentity ? identity : NULL, ranges, ActiveColors, usepalette ? local_palette : NULL); + BuildTranslations (luminosity, useidentity ? identity : nullptr, ranges, ActiveColors, usepalette ? local_palette : nullptr); } //========================================================================== @@ -1025,7 +1040,7 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data) translateUntranslated = true; for(unsigned int i = 0;i < 256;++i) - Chars[i].Pic = nullptr; + Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; LoadTranslations(); } @@ -1111,12 +1126,12 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data) Chars[i].XMove = widths2[i]; if (destSize <= 0) { - Chars[i].Pic = NULL; + Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; } else { - Chars[i].Pic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)); - TexMan.AddTexture(Chars[i].Pic); + Chars[i].TranslatedPic = Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)); + TexMan.AddTexture(Chars[i].OriginalPic); do { int8_t code = *data_p++; @@ -1201,7 +1216,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) Chars.Resize(count); for (i = 0; i < count; ++i) { - Chars[i].Pic = NULL; + Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; Chars[i].XMove = INT_MIN; } @@ -1256,7 +1271,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) -(int8_t)chardata[chari+3], // x offset -(int8_t)chardata[chari+4] // y offset )); - Chars[chardata[chari] - FirstChar].Pic = tex; + Chars[chardata[chari] - FirstChar].TranslatedPic = Chars[chardata[chari] - FirstChar].OriginalPic = tex; TexMan.AddTexture(tex); } @@ -1320,12 +1335,13 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity) { int destSize = SpaceWidth * FontHeight; - if(!Chars[i].Pic) + if(!Chars[i].OriginalPic) { - Chars[i].Pic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)); + Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)); Chars[i].XMove = SpaceWidth; - TexMan.AddTexture(Chars[i].Pic); + TexMan.AddTexture(Chars[i].OriginalPic); } + Chars[i].TranslatedPic = Chars[i].OriginalPic; // Advance to next char's data and count the used colors. do @@ -1454,7 +1470,7 @@ FSinglePicFont::FSinglePicFont(const char *picname) : // // FSinglePicFont :: GetChar // -// Returns the texture if code is 'a' or 'A', otherwise NULL. +// Returns the texture if code is 'a' or 'A', otherwise nullptr. // //========================================================================== @@ -1467,7 +1483,7 @@ FTexture *FSinglePicFont::GetChar (int code, int *const width) const } else { - return NULL; + return nullptr; } } @@ -1534,23 +1550,24 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l if (charlumps[i] != nullptr) { + Chars[i].OriginalPic = charlumps[i]; if (!noTranslate) { - Chars[i].Pic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage())); - TexMan.AddTexture(Chars[i].Pic); + Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), ""); + TexMan.AddTexture(Chars[i].TranslatedPic); } - else Chars[i].Pic = charlumps[i]; - Chars[i].XMove = Chars[i].Pic->GetDisplayWidth(); + else Chars[i].TranslatedPic = charlumps[i]; + Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); } else { - Chars[i].Pic = NULL; + Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; Chars[i].XMove = INT_MIN; } } // Special fonts normally don't have all characters so be careful here! - if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].Pic != NULL) + if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr) { SpaceWidth = (Chars['N' - first].XMove + 1) / 2; } @@ -1588,12 +1605,12 @@ void FSpecialFont::LoadTranslations() memset (usedcolors, 0, 256); for (i = 0; i < count; i++) { - if (Chars[i].Pic) + if (Chars[i].TranslatedPic) { - FFontChar1 *pic = static_cast(Chars[i].Pic->GetImage()); + FFontChar1 *pic = static_cast(Chars[i].TranslatedPic->GetImage()); if (pic) { - pic->SetSourceRemap(NULL); // Force the FFontChar1 to return the same pixels as the base texture + pic->SetSourceRemap(nullptr); // Force the FFontChar1 to return the same pixels as the base texture RecordTextureColors(pic, usedcolors); } } @@ -1619,11 +1636,11 @@ void FSpecialFont::LoadTranslations() for (i = 0; i < count; i++) { - if(Chars[i].Pic) - static_cast(Chars[i].Pic->GetImage())->SetSourceRemap(PatchRemap); + if(Chars[i].TranslatedPic) + static_cast(Chars[i].TranslatedPic->GetImage())->SetSourceRemap(PatchRemap); } - BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], TotalColors, NULL); + BuildTranslations (Luminosity.Data(), identity, &TranslationParms[0][0], TotalColors, nullptr); // add the untranslated colors to the Ranges tables if (ActiveColors < TotalColors) @@ -1809,7 +1826,7 @@ void V_InitCustomFonts() { for (i = 0; i < 256; i++) { - if (lumplist[i] != NULL) + if (lumplist[i] != nullptr) { first = i; break; @@ -1817,7 +1834,7 @@ void V_InitCustomFonts() } for (i = 255; i >= 0; i--) { - if (lumplist[i] != NULL) + if (lumplist[i] != nullptr) { count = i - first + 1; break; @@ -1921,19 +1938,19 @@ void V_InitFontColors () else if (sc.Compare ("Flat:")) { sc.MustGetString(); - logcolor = V_GetColor (NULL, sc); + logcolor = V_GetColor (nullptr, sc); } else { // Get first color - c = V_GetColor (NULL, sc); + c = V_GetColor (nullptr, sc); tparm.Start[0] = RPART(c); tparm.Start[1] = GPART(c); tparm.Start[2] = BPART(c); // Get second color sc.MustGetString(); - c = V_GetColor (NULL, sc); + c = V_GetColor (nullptr, sc); tparm.End[0] = RPART(c); tparm.End[1] = GPART(c); tparm.End[2] = BPART(c); @@ -2261,7 +2278,7 @@ void V_InitFonts() { IntermissionFont = FFont::FindFont("IntermissionFont_Doom"); } - if (IntermissionFont == NULL) + if (IntermissionFont == nullptr) { IntermissionFont = BigFont; } @@ -2270,11 +2287,11 @@ void V_InitFonts() void V_ClearFonts() { - while (FFont::FirstFont != NULL) + while (FFont::FirstFont != nullptr) { delete FFont::FirstFont; } - FFont::FirstFont = NULL; - SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = NULL; + FFont::FirstFont = nullptr; + SmallFont = SmallFont2 = BigFont = ConFont = IntermissionFont = nullptr; } diff --git a/src/v_font.h b/src/v_font.h index 4bc20884e..b15790844 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -82,7 +82,7 @@ public: FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false); virtual ~FFont (); - FTexture *GetChar (int code, int *const width) const; + FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const; virtual int GetCharWidth (int code) const; FRemapTable *GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const; int GetLump() const { return Lump; } @@ -123,7 +123,8 @@ protected: bool translateUntranslated; struct CharData { - FTexture *Pic; + FTexture *TranslatedPic; // Texture for use with font translations. + FTexture *OriginalPic; // Texture for use with CR_UNTRANSLATED or font colorization. int XMove; }; TArray Chars; diff --git a/src/v_text.cpp b/src/v_text.cpp index e9a78bee4..ea977168f 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -139,8 +139,9 @@ void DFrameBuffer::DrawChar (FFont *font, int normalcolor, double x, double y, i FTexture *pic; int dummy; + bool redirected; - if (NULL != (pic = font->GetChar (character, &dummy))) + if (NULL != (pic = font->GetChar (character, normalcolor, &dummy, &redirected))) { DrawParms parms; Va_List tags; @@ -152,7 +153,7 @@ void DFrameBuffer::DrawChar (FFont *font, int normalcolor, double x, double y, i return; } PalEntry color = 0xffffffff; - parms.remap = font->GetColorTranslation((EColorRange)normalcolor, &color); + parms.remap = redirected? nullptr : font->GetColorTranslation((EColorRange)normalcolor, &color); parms.color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255); DrawTextureParms(pic, parms); } @@ -169,7 +170,7 @@ void DFrameBuffer::DrawChar(FFont *font, int normalcolor, double x, double y, in FTexture *pic; int dummy; - if (NULL != (pic = font->GetChar(character, &dummy))) + if (NULL != (pic = font->GetChar(character, normalcolor, &dummy))) { DrawParms parms; uint32_t tag = ListGetInt(args); @@ -238,6 +239,7 @@ void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double cy = y; + auto currentcolor = normalcolor; while ((const char *)ch - string < parms.maxstrlen) { c = GetCharFromString(ch); @@ -251,6 +253,7 @@ void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double { range = font->GetColorTranslation(newcolor, &color); parms.color = PalEntry(colorparm.a, (color.r * colorparm.r) / 255, (color.g * colorparm.g) / 255, (color.b * colorparm.b) / 255); + currentcolor = newcolor; } continue; } @@ -262,9 +265,10 @@ void DFrameBuffer::DrawTextCommon(FFont *font, int normalcolor, double x, double continue; } - if (NULL != (pic = font->GetChar(c, &w))) + bool redirected = false; + if (NULL != (pic = font->GetChar(c, currentcolor, &w, &redirected))) { - parms.remap = range; + parms.remap = redirected? nullptr : range; SetTextureParms(&parms, pic, cx, cy); if (parms.cellx) { From d937c50726a196fd13553467e15f67a705098fcd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 14:59:49 +0100 Subject: [PATCH 57/66] - use a TArray in PPUniforms. This makes the vast majority of code in that class just go away --- src/gl/renderer/gl_renderbuffers.cpp | 4 +- .../postprocessing/hw_postprocess.h | 42 ++++--------------- 2 files changed, 9 insertions(+), 37 deletions(-) diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index d5c78f116..67d083a31 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -966,11 +966,11 @@ void FGLRenderBuffers::RenderEffect(const FString &name) auto &shader = GLShaders[step.ShaderName]; // Set uniforms - if (step.Uniforms.Size > 0) + if (step.Uniforms.Data.Size() > 0) { if (!shader->Uniforms) shader->Uniforms.reset(screen->CreateDataBuffer(POSTPROCESS_BINDINGPOINT, false)); - shader->Uniforms->SetData(step.Uniforms.Size, step.Uniforms.Data); + shader->Uniforms->SetData(step.Uniforms.Data.Size(), step.Uniforms.Data.Data()); shader->Uniforms->BindBase(); } diff --git a/src/hwrenderer/postprocessing/hw_postprocess.h b/src/hwrenderer/postprocessing/hw_postprocess.h index c94a89b81..0b11ec124 100644 --- a/src/hwrenderer/postprocessing/hw_postprocess.h +++ b/src/hwrenderer/postprocessing/hw_postprocess.h @@ -38,12 +38,7 @@ public: PPUniforms(const PPUniforms &src) { - if (src.Size > 0) - { - Data = new uint8_t[src.Size]; - Size = src.Size; - memcpy(Data, src.Data, Size); - } + Data = src.Data; } ~PPUniforms() @@ -53,49 +48,26 @@ public: PPUniforms &operator=(const PPUniforms &src) { - if (this != &src) - { - if (src.Size > 0) - { - Data = new uint8_t[src.Size]; - Size = src.Size; - memcpy(Data, src.Data, Size); - } - else - { - delete[] Data; - Data = nullptr; - Size = 0; - } - } - + Data = src.Data; return *this; } void Clear() { - delete[] Data; - Data = nullptr; - Size = 0; + Data.Clear(); } template void Set(const T &v) { - if (Size != (int)sizeof(T)) + if (Data.Size() != (int)sizeof(T)) { - delete[] Data; - Data = nullptr; - Size = 0; - - Data = new uint8_t[sizeof(T)]; - Size = sizeof(T); - memcpy(Data, &v, Size); + Data.Resize(sizeof(T)); + memcpy(Data.Data(), &v, Data.Size()); } } - uint8_t *Data = nullptr; - int Size = 0; + TArray Data; }; class PPStep From faa4bb45c92db405981cf3dbe0fac2d4f4b4943b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 15:36:33 +0100 Subject: [PATCH 58/66] - store UnchangedSpriteNames in Dehacked in a less hacky manner. --- src/d_dehacked.cpp | 64 ++++++++++++++-------------------------------- 1 file changed, 19 insertions(+), 45 deletions(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 2e11c5ff2..2562d8e63 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -223,8 +223,7 @@ DEFINE_FIELD_X(DehInfo, DehInfo, BlueAC) TArray TouchedActors; -char *UnchangedSpriteNames; -int NumUnchangedSprites; +TArray UnchangedSpriteNames; bool changedStates; // Sprite<->Class map for DehackedPickup::DetermineType @@ -395,17 +394,10 @@ static bool HandleKey (const struct Key *keys, void *structure, const char *key, static int FindSprite (const char *sprname) { - int i; - uint32_t nameint = *((uint32_t *)sprname); - - for (i = 0; i < NumUnchangedSprites; ++i) - { - if (*((uint32_t *)&UnchangedSpriteNames[i*4]) == nameint) - { - return i; - } - } - return -1; + uint32_t nameint; + memcpy(&nameint, sprname, 4); + auto f = UnchangedSpriteNames.Find(nameint); + return f == UnchangedSpriteNames.Size() ? -1 : f; } static FState *FindState (int statenum) @@ -2665,31 +2657,16 @@ static void UnloadDehSupp () // that was altered by the first. So we need to keep the // StateMap around until all patches have been applied. DehUseCount = 0; - Actions.Clear(); - Actions.ShrinkToFit(); - OrgHeights.Clear(); - OrgHeights.ShrinkToFit(); - CodePConv.Clear(); - CodePConv.ShrinkToFit(); - OrgSprNames.Clear(); - OrgSprNames.ShrinkToFit(); - SoundMap.Clear(); - SoundMap.ShrinkToFit(); - InfoNames.Clear(); - InfoNames.ShrinkToFit(); - BitNames.Clear(); - BitNames.ShrinkToFit(); - StyleNames.Clear(); - StyleNames.ShrinkToFit(); - AmmoNames.Clear(); - AmmoNames.ShrinkToFit(); - - if (UnchangedSpriteNames != NULL) - { - delete[] UnchangedSpriteNames; - UnchangedSpriteNames = NULL; - NumUnchangedSprites = 0; - } + Actions.Reset(); + OrgHeights.Reset(); + CodePConv.Reset(); + OrgSprNames.Reset(); + SoundMap.Reset(); + InfoNames.Reset(); + BitNames.Reset(); + StyleNames.Reset(); + AmmoNames.Reset(); + UnchangedSpriteNames.Reset(); if (EnglishStrings != NULL) { delete EnglishStrings; @@ -2731,14 +2708,11 @@ static bool LoadDehSupp () EnglishStrings->LoadStrings (true); } - if (UnchangedSpriteNames == NULL) + + UnchangedSpriteNames.Resize(sprites.Size()); + for (unsigned i = 0; i < UnchangedSpriteNames.Size(); ++i) { - UnchangedSpriteNames = new char[sprites.Size()*4]; - NumUnchangedSprites = sprites.Size(); - for (i = 0; i < NumUnchangedSprites; ++i) - { - memcpy (UnchangedSpriteNames+i*4, &sprites[i].name, 4); - } + memcpy (&UnchangedSpriteNames[i], &sprites[i].name, 4); } FScanner sc; From 1aba33122b8c80874c17fc446742de2b7ceace66 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 15:36:43 +0100 Subject: [PATCH 59/66] - fixed: The light defaults were not fully deleted on an engine restart. --- src/d_main.cpp | 2 +- src/g_shared/a_dynlight.h | 2 +- src/r_data/gldefs.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index b4f4c5b35..a7a0ef46a 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -2709,7 +2709,7 @@ void D_DoomMain (void) DestroyCVarsFlagged(CVAR_MOD); // Delete any cvar left by mods FS_Close(); // destroy the global FraggleScript. DeinitMenus(); - LightDefaults.Clear(); // this can leak heap memory if it isn't cleared. + LightDefaults.DeleteAndClear(); // this can leak heap memory if it isn't cleared. // delete DoomStartupInfo data DoomStartupInfo.Name = (const char*)0; diff --git a/src/g_shared/a_dynlight.h b/src/g_shared/a_dynlight.h index 369b826e3..685c3a39c 100644 --- a/src/g_shared/a_dynlight.h +++ b/src/g_shared/a_dynlight.h @@ -85,7 +85,7 @@ public: } protected: - FName m_Name; + FName m_Name = NAME_None; int m_Args[5] = { 0,0,0,0,0 }; double m_Param = 0; DVector3 m_Pos = { 0,0,0 }; diff --git a/src/r_data/gldefs.cpp b/src/r_data/gldefs.cpp index 513d51094..8552ad77d 100644 --- a/src/r_data/gldefs.cpp +++ b/src/r_data/gldefs.cpp @@ -1758,7 +1758,7 @@ void ParseGLDefs() { const char *defsLump = NULL; - LightDefaults.Clear(); + LightDefaults.DeleteAndClear(); //gl_DestroyUserShaders(); function says 'todo' switch (gameinfo.gametype) { From dc9c7afa246f1e318e2b03cd17e6d9e39b3b2694 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 16:05:48 +0100 Subject: [PATCH 60/66] - reimplemented the GetRawTexture redirect. --- src/textures/formats/multipatchtexture.h | 2 ++ src/textures/texture.cpp | 16 +++++++++++++++- src/textures/textures.h | 5 +++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/textures/formats/multipatchtexture.h b/src/textures/formats/multipatchtexture.h index f1284e0a9..3d7800832 100644 --- a/src/textures/formats/multipatchtexture.h +++ b/src/textures/formats/multipatchtexture.h @@ -1,4 +1,5 @@ #pragma once +#include "sc_man.h" //========================================================================== // @@ -28,6 +29,7 @@ struct TexPart class FMultiPatchTexture : public FImageSource { + friend class FTexture; public: FMultiPatchTexture(int w, int h, const TArray &parts, bool complex, bool textual); diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index ec09c3898..6f01f0e4f 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -50,6 +50,7 @@ #include "swrenderer/textures/r_swtexture.h" #include "imagehelpers.h" #include "image.h" +#include "formats/multipatchtexture.h" FTexture *CreateBrightmapTexture(FImageSource*); @@ -221,7 +222,20 @@ FBitmap FTexture::GetBgraBitmap(PalEntry *remap, int *ptrans) FTexture *FTexture::GetRawTexture() { - return this; + if (OffsetLess) return OffsetLess; + // Reject anything that cannot have been a single-patch multipatch texture in vanilla. + auto image = static_cast(GetImage()); + if (bMultiPatch != 1 || UseType != ETextureType::Wall || Scale.X != 1 || Scale.Y != 1 || bWorldPanning || image == nullptr || image->NumParts != 1) + { + OffsetLess = this; + return this; + } + // Set up a new texture that directly references the underlying patch. + // From here we cannot retrieve the original texture made for it, so just create a new one. + FImageSource *source = image->Parts[0].Image; + OffsetLess = new FImageTexture(source, ""); + TexMan.AddTexture(OffsetLess); + return OffsetLess; } void FTexture::SetScaledSize(int fitwidth, int fitheight) diff --git a/src/textures/textures.h b/src/textures/textures.h index d25026634..e40b9fc0a 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -338,7 +338,7 @@ public: int GetSkyOffset() const { return SkyOffset; } FTextureID GetID() const { return id; } PalEntry GetSkyCapColor(bool bottom); - virtual FTexture *GetRawTexture(); // for FMultiPatchTexture to override + FTexture *GetRawTexture(); virtual int GetSourceLump() { return SourceLump; } // needed by the scripted GetName method. void GetGlowColor(float *data); bool isGlowing() const { return bGlowing; } @@ -371,11 +371,12 @@ protected: public: FHardwareTextureContainer SystemTextures; protected: - //IHardwareTexture *SystemTexture[2] = { nullptr, nullptr }; FSoftwareTexture *SoftwareTexture = nullptr; // None of the following pointers are owned by this texture, they are all controlled by the texture manager. + // Offset-less version for COMPATF_MASKEDMIDTEX + FTexture *OffsetLess = nullptr; // Paletted variant FTexture *PalVersion = nullptr; // External hires texture From 74ea9143ee2f7b79eb399bb4571be2d36c3830dc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 16:29:37 +0100 Subject: [PATCH 61/66] - added a 'forceworldpanning' map flag. Since unfortunately this cannot be set as a general default, let's at least make it as easy as possible to disable that panning+scaling madness without having to edit the texture data. --- src/g_level.h | 1 + src/g_mapinfo.cpp | 1 + src/swrenderer/textures/r_swtexture.h | 3 ++- src/textures/texture.cpp | 3 ++- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/g_level.h b/src/g_level.h index f512287d3..46ffbf795 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -247,6 +247,7 @@ enum ELevelFlags : unsigned int LEVEL3_NOCOLOREDSPRITELIGHTING = 0x00000010, // draw sprites only with color-less light LEVEL3_EXITNORMALUSED = 0x00000020, LEVEL3_EXITSECRETUSED = 0x00000040, + LEVEL3_FORCEWORLDPANNING = 0x00000080, // Forces the world panning flag for all textures, even those without it explicitly set. }; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index e79abf0c8..4595afff0 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1553,6 +1553,7 @@ MapFlagHandlers[] = { "forcefakecontrast", MITYPE_SETFLAG3, LEVEL3_FORCEFAKECONTRAST, 0 }, { "nolightfade", MITYPE_SETFLAG3, LEVEL3_NOLIGHTFADE, 0 }, { "nocoloredspritelighting", MITYPE_SETFLAG3, LEVEL3_NOCOLOREDSPRITELIGHTING, 0 }, + { "forceworldpanning", MITYPE_SETFLAG3, LEVEL3_FORCEWORLDPANNING, 0 }, { "nobotnodes", MITYPE_IGNORE, 0, 0 }, // Skulltag option: nobotnodes { "compat_shorttex", MITYPE_COMPATFLAG, COMPATF_SHORTTEX, 0 }, { "compat_stairs", MITYPE_COMPATFLAG, COMPATF_STAIRINDEX, 0 }, diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index 14810b071..f03f8c86a 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -1,6 +1,7 @@ #pragma once #include "textures/textures.h" #include "v_video.h" +#include "g_levellocals.h" struct FSoftwareTextureSpan @@ -48,7 +49,7 @@ public: // The feature from hell... :( bool useWorldPanning() const { - return mTexture->bWorldPanning; + return mTexture->bWorldPanning || (level.flags3 & LEVEL3_FORCEWORLDPANNING); } bool isMasked() diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 6f01f0e4f..44203413a 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -51,6 +51,7 @@ #include "imagehelpers.h" #include "image.h" #include "formats/multipatchtexture.h" +#include "g_levellocals.h" FTexture *CreateBrightmapTexture(FImageSource*); @@ -903,7 +904,7 @@ void FTexCoordInfo::GetFromTexture(FTexture *tex, float x, float y) mScale.Y = -mScale.Y; mRenderHeight = -mRenderHeight; } - mWorldPanning = tex->bWorldPanning; + mWorldPanning = tex->bWorldPanning || (level.flags3 & LEVEL3_FORCEWORLDPANNING); mWidth = tex->GetWidth(); } From c105a1f670d1a9e90b4e6614296b8e9493bafd38 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 16:57:20 +0100 Subject: [PATCH 62/66] - fixed two broken ScriptUtil calls in FraggleScript. --- src/fragglescript/t_func.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fragglescript/t_func.cpp b/src/fragglescript/t_func.cpp index 87858f91f..fe1559991 100644 --- a/src/fragglescript/t_func.cpp +++ b/src/fragglescript/t_func.cpp @@ -2453,7 +2453,7 @@ void FParser::SF_PlayerKeys(void) else { givetake = intvalue(t_argv[2]); - ScriptUtil::Exec(givetake?NAME_GiveInventory : NAME_TakeInventory, players[playernum].mo, keyname.GetIndex(), 1); + ScriptUtil::Exec(givetake?NAME_GiveInventory : NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, keyname.GetIndex(), ScriptUtil::Int, 1, ScriptUtil::End); t_return.type = svt_int; t_return.value.i = 0; } @@ -2648,7 +2648,7 @@ void FParser::SF_GiveInventory(void) if(t_argc == 2) count=1; else count=intvalue(t_argv[2]); - ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, players[playernum].mo, FName(stringvalue(t_argv[1])).GetIndex(), count); + ScriptUtil::Exec(NAME_GiveInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End); t_return.type = svt_int; t_return.value.i = 0; } @@ -2671,7 +2671,7 @@ void FParser::SF_TakeInventory(void) if(t_argc == 2) count=32767; else count=intvalue(t_argv[2]); - ScriptUtil::Exec(NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, FName(stringvalue(t_argv[1])).GetIndex(), count); + ScriptUtil::Exec(NAME_TakeInventory, ScriptUtil::Pointer, players[playernum].mo, ScriptUtil::Int, FName(stringvalue(t_argv[1])).GetIndex(), ScriptUtil::Int, count, ScriptUtil::End); t_return.type = svt_int; t_return.value.i = 0; } From d1ca2a91f38a6d93c275da148f0c6f6c8bab9493 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 17:49:12 +0100 Subject: [PATCH 63/66] - fixed: ThePatchRemap table was only initialized in one of FFont's constructors. --- src/d_dehacked.cpp | 1 - src/v_font.cpp | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 2562d8e63..ad7a3f891 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -2694,7 +2694,6 @@ static bool LoadDehSupp () return false; } bool gotnames = false; - int i; if (++DehUseCount > 1) diff --git a/src/v_font.cpp b/src/v_font.cpp index e1e5998ba..ccbe56c41 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -899,6 +899,8 @@ FFont::FFont (int lump) FontName = NAME_None; Cursor = '_'; noTranslate = false; + uint8_t pp = 0; + for (auto &p : PatchRemap) p = pp++; } //========================================================================== From e6e4f0f305e17cbd4da9b50d29b91560d1392bd7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 19:15:05 +0100 Subject: [PATCH 64/66] - disabled redirection to the original patch for FSpecialFont. Using the same code as for the standard font does not work as intended, the reason still needs to be investigated. --- src/v_font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index ccbe56c41..b42de72d3 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -1552,13 +1552,13 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l if (charlumps[i] != nullptr) { - Chars[i].OriginalPic = charlumps[i]; if (!noTranslate) { Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), ""); TexMan.AddTexture(Chars[i].TranslatedPic); } else Chars[i].TranslatedPic = charlumps[i]; + Chars[i].OriginalPic = Chars[i].TranslatedPic; Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); } else From 87b0567cd75ad5d1ed7086359bda4d9fd3790312 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 23:32:49 +0100 Subject: [PATCH 65/66] - the font character substitution logic needed more fixes. The ZScript DrawChar function was incomplete and FFont::GetChar did not always return the proper texture. To make things clearer the OriginalPic is now only used in the few cases where substitution takes place and nothing else. --- src/v_font.cpp | 59 ++++++++++++++++++++------------------------------ src/v_font.h | 6 ++--- src/v_text.cpp | 5 +++-- 3 files changed, 30 insertions(+), 40 deletions(-) diff --git a/src/v_font.cpp b/src/v_font.cpp index b42de72d3..aaf450725 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -381,20 +381,19 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, if (charLumps[i] != nullptr) { - Chars[i].OriginalPic = charLumps[i]; - if (!noTranslate) { + Chars[i].OriginalPic = charLumps[i]; Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charLumps[i]->GetImage()), ""); TexMan.AddTexture(Chars[i].TranslatedPic); } else Chars[i].TranslatedPic = charLumps[i]; - Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); + Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth(); } else { - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; + Chars[i].TranslatedPic = nullptr; Chars[i].XMove = INT_MIN; } } @@ -403,7 +402,7 @@ FFont::FFont (const char *name, const char *nametemplate, int first, int count, { SpaceWidth = spacewidth; } - else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr) + else if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].TranslatedPic != nullptr) { SpaceWidth = (Chars['N' - first].XMove + 1) / 2; } @@ -706,7 +705,7 @@ int FFont::GetCharCode(int code, bool needpic) const // regular chars turn negative when the 8th bit is set. code &= 255; } - if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr)) { return code; } @@ -714,7 +713,7 @@ int FFont::GetCharCode(int code, bool needpic) const if (myislower(code)) { code -= 32; - if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr)) { return code; } @@ -724,7 +723,7 @@ int FFont::GetCharCode(int code, bool needpic) const if (newcode != code) { code = newcode; - if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].OriginalPic != nullptr)) + if (code >= FirstChar && code <= LastChar && (!needpic || Chars[code - FirstChar].TranslatedPic != nullptr)) { return code; } @@ -747,7 +746,7 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red { code -= FirstChar; xmove = Chars[code].XMove; - if (Chars[code].OriginalPic == nullptr) + if (Chars[code].TranslatedPic == nullptr) { code = GetCharCode(code + FirstChar, true); if (code >= 0) @@ -766,9 +765,10 @@ FTexture *FFont::GetChar (int code, int translation, int *const width, bool *red if (translation == CR_UNTRANSLATED) { - if (redirected) - *redirected = Chars[code].OriginalPic != Chars[code].TranslatedPic; - return Chars[code].OriginalPic; + bool redirect = Chars[code].OriginalPic && Chars[code].OriginalPic != Chars[code].TranslatedPic; + if (redirected) *redirected = redirect; + if (redirect) + return Chars[code].OriginalPic; } if (redirected) *redirected = false; return Chars[code].TranslatedPic; @@ -963,7 +963,7 @@ void FSingleLumpFont::CreateFontFromPic (FTextureID picnum) FirstChar = LastChar = 'A'; Chars.Resize(1); - Chars[0].TranslatedPic = Chars[0].OriginalPic = pic; + Chars[0].TranslatedPic = pic; // Only one color range. Don't bother with the others. ActiveColors = 0; @@ -1040,10 +1040,6 @@ void FSingleLumpFont::LoadFON1 (int lump, const uint8_t *data) LastChar = 255; GlobalKerning = 0; translateUntranslated = true; - - for(unsigned int i = 0;i < 256;++i) - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; - LoadTranslations(); } @@ -1128,12 +1124,12 @@ void FSingleLumpFont::LoadFON2 (int lump, const uint8_t *data) Chars[i].XMove = widths2[i]; if (destSize <= 0) { - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; + Chars[i].TranslatedPic = nullptr; } else { - Chars[i].TranslatedPic = Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)); - TexMan.AddTexture(Chars[i].OriginalPic); + Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (lump, int(data_p - data), widths2[i], FontHeight)); + TexMan.AddTexture(Chars[i].TranslatedPic); do { int8_t code = *data_p++; @@ -1216,12 +1212,6 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) } count = LastChar - FirstChar + 1; Chars.Resize(count); - for (i = 0; i < count; ++i) - { - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; - Chars[i].XMove = INT_MIN; - } - // BMF palettes are only six bits per component. Fix that. for (i = 0; i < ActiveColors*3; ++i) { @@ -1273,7 +1263,7 @@ void FSingleLumpFont::LoadBMF(int lump, const uint8_t *data) -(int8_t)chardata[chari+3], // x offset -(int8_t)chardata[chari+4] // y offset )); - Chars[chardata[chari] - FirstChar].TranslatedPic = Chars[chardata[chari] - FirstChar].OriginalPic = tex; + Chars[chardata[chari] - FirstChar].TranslatedPic = tex; TexMan.AddTexture(tex); } @@ -1337,13 +1327,12 @@ void FSingleLumpFont::CheckFON1Chars (double *luminosity) { int destSize = SpaceWidth * FontHeight; - if(!Chars[i].OriginalPic) + if(!Chars[i].TranslatedPic) { - Chars[i].OriginalPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)); + Chars[i].TranslatedPic = new FImageTexture(new FFontChar2 (Lump, int(data_p - data), SpaceWidth, FontHeight)); Chars[i].XMove = SpaceWidth; - TexMan.AddTexture(Chars[i].OriginalPic); + TexMan.AddTexture(Chars[i].TranslatedPic); } - Chars[i].TranslatedPic = Chars[i].OriginalPic; // Advance to next char's data and count the used colors. do @@ -1552,24 +1541,24 @@ FSpecialFont::FSpecialFont (const char *name, int first, int count, FTexture **l if (charlumps[i] != nullptr) { + Chars[i].OriginalPic = charlumps[i]; if (!noTranslate) { Chars[i].TranslatedPic = new FImageTexture(new FFontChar1 (charlumps[i]->GetImage()), ""); TexMan.AddTexture(Chars[i].TranslatedPic); } else Chars[i].TranslatedPic = charlumps[i]; - Chars[i].OriginalPic = Chars[i].TranslatedPic; - Chars[i].XMove = Chars[i].OriginalPic->GetDisplayWidth(); + Chars[i].XMove = Chars[i].TranslatedPic->GetDisplayWidth(); } else { - Chars[i].TranslatedPic = Chars[i].OriginalPic = nullptr; + Chars[i].TranslatedPic = nullptr; Chars[i].XMove = INT_MIN; } } // Special fonts normally don't have all characters so be careful here! - if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].OriginalPic != nullptr) + if ('N'-first >= 0 && 'N'-first < count && Chars['N' - first].TranslatedPic != nullptr) { SpaceWidth = (Chars['N' - first].XMove + 1) / 2; } diff --git a/src/v_font.h b/src/v_font.h index b15790844..96283947a 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -123,9 +123,9 @@ protected: bool translateUntranslated; struct CharData { - FTexture *TranslatedPic; // Texture for use with font translations. - FTexture *OriginalPic; // Texture for use with CR_UNTRANSLATED or font colorization. - int XMove; + FTexture *TranslatedPic = nullptr; // Texture for use with font translations. + FTexture *OriginalPic = nullptr; // Texture for use with CR_UNTRANSLATED or font colorization. + int XMove = INT_MIN; }; TArray Chars; int ActiveColors; diff --git a/src/v_text.cpp b/src/v_text.cpp index ea977168f..a6d57399b 100644 --- a/src/v_text.cpp +++ b/src/v_text.cpp @@ -169,15 +169,16 @@ void DFrameBuffer::DrawChar(FFont *font, int normalcolor, double x, double y, in FTexture *pic; int dummy; + bool redirected; - if (NULL != (pic = font->GetChar(character, normalcolor, &dummy))) + if (NULL != (pic = font->GetChar(character, normalcolor, &dummy, &redirected))) { DrawParms parms; uint32_t tag = ListGetInt(args); bool res = ParseDrawTextureTags(pic, x, y, tag, args, &parms, false); if (!res) return; PalEntry color = 0xffffffff; - parms.remap = font->GetColorTranslation((EColorRange)normalcolor, &color); + parms.remap = redirected ? nullptr : font->GetColorTranslation((EColorRange)normalcolor, &color); parms.color = PalEntry((color.a * parms.color.a) / 255, (color.r * parms.color.r) / 255, (color.g * parms.color.g) / 255, (color.b * parms.color.b) / 255); DrawTextureParms(pic, parms); } From 51f03c8215c35116eca4bc1ef9060724512a1e87 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 00:37:34 +0100 Subject: [PATCH 66/66] - a few more fixes. --- src/textures/skyboxtexture.cpp | 1 + src/v_font.cpp | 5 +++-- src/v_font.h | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/textures/skyboxtexture.cpp b/src/textures/skyboxtexture.cpp index 6b5346ac2..45e79bf74 100644 --- a/src/textures/skyboxtexture.cpp +++ b/src/textures/skyboxtexture.cpp @@ -38,6 +38,7 @@ FSkyBox::FSkyBox(const char *name) : FTexture(name) { FTextureID texid = TexMan.CheckForTexture(name, ETextureType::Wall); + previous = nullptr; if (texid.isValid()) { previous = TexMan.GetTexture(texid); diff --git a/src/v_font.cpp b/src/v_font.cpp index aaf450725..da3335236 100644 --- a/src/v_font.cpp +++ b/src/v_font.cpp @@ -149,7 +149,7 @@ public: FSinglePicFont(const char *picname); // FFont interface - FTexture *GetChar (int code, int *const width) const; + FTexture *GetChar(int code, int translation, int *const width, bool *redirected = nullptr) const override; int GetCharWidth (int code) const; protected: @@ -1465,9 +1465,10 @@ FSinglePicFont::FSinglePicFont(const char *picname) : // //========================================================================== -FTexture *FSinglePicFont::GetChar (int code, int *const width) const +FTexture *FSinglePicFont::GetChar (int code, int translation, int *const width, bool *redirected) const { *width = SpaceWidth; + if (redirected) *redirected = false; if (code == 'a' || code == 'A') { return TexMan.GetPalettedTexture(PicNum, true); diff --git a/src/v_font.h b/src/v_font.h index 96283947a..7e8373532 100644 --- a/src/v_font.h +++ b/src/v_font.h @@ -82,7 +82,7 @@ public: FFont (const char *fontname, const char *nametemplate, int first, int count, int base, int fdlump, int spacewidth=-1, bool notranslate = false); virtual ~FFont (); - FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const; + virtual FTexture *GetChar (int code, int translation, int *const width, bool *redirected = nullptr) const; virtual int GetCharWidth (int code) const; FRemapTable *GetColorTranslation (EColorRange range, PalEntry *color = nullptr) const; int GetLump() const { return Lump; }