From 6eab4a882ce7d49612f41ae85788baa4274ac4ed Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 6 Dec 2018 01:11:04 +0100 Subject: [PATCH 001/113] - 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 002/113] - 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 003/113] - 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 004/113] - 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 005/113] - 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 006/113] - 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 007/113] - 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 008/113] - 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 009/113] 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 010/113] 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 011/113] - 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 012/113] - 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 013/113] - 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 014/113] 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 015/113] - 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 016/113] - 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 017/113] - 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 018/113] - 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 019/113] - 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 020/113] - 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 021/113] - 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 022/113] - 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 023/113] - 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 024/113] - 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 025/113] - 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 f0ce453d47c7f747d6a2c129f66e96932cfccca1 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 9 Dec 2018 17:36:43 +0100 Subject: [PATCH 026/113] - workaround pointer truncation bug in asmjit --- src/scripting/vm/jit_flow.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/scripting/vm/jit_flow.cpp b/src/scripting/vm/jit_flow.cpp index 08e7b0660..0ca8bf437 100644 --- a/src/scripting/vm/jit_flow.cpp +++ b/src/scripting/vm/jit_flow.cpp @@ -169,16 +169,28 @@ void JitCompiler::EmitRET() if (cc.is64Bit()) { if (regtype & REGT_KONST) - cc.mov(x86::qword_ptr(location), asmjit::imm_ptr(konsta[regnum].v)); + { + auto ptr = newTempIntPtr(); + cc.mov(ptr, asmjit::imm_ptr(konsta[regnum].v)); + cc.mov(x86::qword_ptr(location), ptr); + } else + { cc.mov(x86::qword_ptr(location), regA[regnum]); + } } else { if (regtype & REGT_KONST) - cc.mov(x86::dword_ptr(location), asmjit::imm_ptr(konsta[regnum].v)); + { + auto ptr = newTempIntPtr(); + cc.mov(ptr, asmjit::imm_ptr(konsta[regnum].v)); + cc.mov(x86::dword_ptr(location), ptr); + } else + { cc.mov(x86::dword_ptr(location), regA[regnum]); + } } break; } From 796c0fe931dff1a5c10f5dc1259e80b8a3e1eda8 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 10 Dec 2018 01:13:44 +0100 Subject: [PATCH 027/113] - 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 028/113] - 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 029/113] - 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 030/113] 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 031/113] 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 032/113] 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 8a4b8cc2ca3f77cd40a61ef58ba4e6483b9abbaf Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 10 Dec 2018 10:36:40 +0200 Subject: [PATCH 033/113] - server CVARs can be changed only by settings controller Initially, settings controller flag was false by default It was not touched during construction and destruction of player_t instances though Now, with all members initialized in class definition, this flag must be saved and restored manually https://forum.zdoom.org/viewtopic.php?t=62830 --- src/d_player.h | 2 +- src/g_game.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/d_player.h b/src/d_player.h index 4eb207fa9..4acae8ac8 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -453,7 +453,7 @@ public: TObjPtr MUSINFOactor = nullptr; // For MUSINFO purposes int8_t MUSINFOtics = 0; - bool settings_controller = true; // Player can control game settings. + bool settings_controller = false; // Player can control game settings. int8_t crouching = 0; int8_t crouchdir = 0; diff --git a/src/g_game.cpp b/src/g_game.cpp index b0c09d993..56ccd46b2 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -1285,6 +1285,7 @@ void G_PlayerReborn (int player) log = p->LogText; chasecam = p->cheats & CF_CHASECAM; Bot = p->Bot; //Added by MC: + const bool settings_controller = p->settings_controller; // Reset player structure to its defaults p->~player_t(); @@ -1303,6 +1304,7 @@ void G_PlayerReborn (int player) p->LogText = log; p->cheats |= chasecam; p->Bot = Bot; //Added by MC: + p->settings_controller = settings_controller; p->oldbuttons = ~0, p->attackdown = true; p->usedown = true; // don't do anything immediately p->original_oldbuttons = ~0; From 6362415054bd3092ed01938be7dbb74fb85df1b4 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 10 Dec 2018 11:26:46 +0200 Subject: [PATCH 034/113] - fixed return value of native call to dynamic array's Reserve() https://forum.zdoom.org/viewtopic.php?t=62841 --- src/scripting/backend/dynarrays.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/scripting/backend/dynarrays.cpp b/src/scripting/backend/dynarrays.cpp index 15b016166..147ab89f8 100644 --- a/src/scripting/backend/dynarrays.cpp +++ b/src/scripting/backend/dynarrays.cpp @@ -121,9 +121,9 @@ template void ArrayResize(T *self, int amount) } } -template void ArrayReserve(T *self, int amount) +template unsigned int ArrayReserve(T *self, int amount) { - self->Reserve(amount); + return self->Reserve(amount); } template int ArrayMax(T *self) From cbb5f8a0dc7c3b7facfb348672d09310b41bd289 Mon Sep 17 00:00:00 2001 From: drfrag666 Date: Thu, 6 Dec 2018 14:50:03 +0100 Subject: [PATCH 035/113] - Fixed: the vid_rendermode CVAR could get wrong values. --- src/v_video.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/v_video.cpp b/src/v_video.cpp index b9efcf6a1..658e70fe9 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -93,6 +93,11 @@ CUSTOM_CVAR(Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CUSTOM_CVAR(Int, vid_rendermode, 4, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { + if (self < 0 || self > 4) + { + self = 4; + } + if (usergame) { // [SP] Update pitch limits to the netgame/gamesim. From 28516c2defb94f62593a43f573f64fc3b6594532 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Mon, 10 Dec 2018 14:25:29 -0500 Subject: [PATCH 036/113] - split gl_texture_hqresize into two variables - one for mode, one for multiplier. --- src/gameconfigfile.cpp | 89 ++++++++++++++++++ src/r_videoscale.cpp | 2 +- src/textures/hires/hqresize.cpp | 108 +++++++++++----------- src/version.h | 2 +- wadsrc/static/language.enu | 33 ++----- wadsrc/static/menudef.txt | 66 +++++-------- wadsrc/static/zscript/menu/optionmenu.txt | 42 +-------- 7 files changed, 179 insertions(+), 163 deletions(-) diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 2979420f9..3bd34fd15 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -60,6 +60,8 @@ EXTERN_CVAR (Color, am_fdwallcolor) EXTERN_CVAR (Color, am_cdwallcolor) EXTERN_CVAR (Float, spc_amp) EXTERN_CVAR (Bool, wi_percents) +EXTERN_CVAR (Int, gl_texture_hqresizemode) +EXTERN_CVAR (Int, gl_texture_hqresizemult) FGameConfigFile::FGameConfigFile () { @@ -395,6 +397,93 @@ void FGameConfigFile::DoGlobalSetup () FBaseCVar *var = FindCVar("snd_hrtf", NULL); if (var != NULL) var->ResetToDefault(); } + if (last < 216) + { + FBaseCVar *var = FindCVar("gl_texture_hqresize", NULL); + if (var != NULL) + { + auto v = var->GetGenericRep(CVAR_Int); + switch (v.Int) + { + case 1: + gl_texture_hqresizemode = 1; gl_texture_hqresizemult = 2; + break; + case 2: + gl_texture_hqresizemode = 1; gl_texture_hqresizemult = 3; + break; + case 3: + gl_texture_hqresizemode = 1; gl_texture_hqresizemult = 4; + break; + case 4: + gl_texture_hqresizemode = 2; gl_texture_hqresizemult = 2; + break; + case 5: + gl_texture_hqresizemode = 2; gl_texture_hqresizemult = 3; + break; + case 6: + gl_texture_hqresizemode = 2; gl_texture_hqresizemult = 4; + break; + case 7: + gl_texture_hqresizemode = 3; gl_texture_hqresizemult = 2; + break; + case 8: + gl_texture_hqresizemode = 3; gl_texture_hqresizemult = 3; + break; + case 9: + gl_texture_hqresizemode = 3; gl_texture_hqresizemult = 4; + break; + case 10: + gl_texture_hqresizemode = 4; gl_texture_hqresizemult = 2; + break; + case 11: + gl_texture_hqresizemode = 4; gl_texture_hqresizemult = 3; + break; + case 12: + gl_texture_hqresizemode = 4; gl_texture_hqresizemult = 4; + break; + case 18: + gl_texture_hqresizemode = 4; gl_texture_hqresizemult = 5; + break; + case 19: + gl_texture_hqresizemode = 4; gl_texture_hqresizemult = 6; + break; + case 13: + gl_texture_hqresizemode = 5; gl_texture_hqresizemult = 2; + break; + case 14: + gl_texture_hqresizemode = 5; gl_texture_hqresizemult = 3; + break; + case 15: + gl_texture_hqresizemode = 5; gl_texture_hqresizemult = 4; + break; + case 16: + gl_texture_hqresizemode = 5; gl_texture_hqresizemult = 5; + break; + case 17: + gl_texture_hqresizemode = 5; gl_texture_hqresizemult = 6; + break; + case 20: + gl_texture_hqresizemode = 6; gl_texture_hqresizemult = 2; + break; + case 21: + gl_texture_hqresizemode = 6; gl_texture_hqresizemult = 3; + break; + case 22: + gl_texture_hqresizemode = 6; gl_texture_hqresizemult = 4; + break; + case 23: + gl_texture_hqresizemode = 6; gl_texture_hqresizemult = 5; + break; + case 24: + gl_texture_hqresizemode = 6; gl_texture_hqresizemult = 6; + break; + case 0: + default: + gl_texture_hqresizemode = 0; gl_texture_hqresizemult = 1; + break; + } + } + } } } } diff --git a/src/r_videoscale.cpp b/src/r_videoscale.cpp index 9918def62..95f788135 100644 --- a/src/r_videoscale.cpp +++ b/src/r_videoscale.cpp @@ -78,7 +78,7 @@ namespace } void R_ShowCurrentScaling(); -CUSTOM_CVAR(Float, vid_scalefactor, 1.0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Float, vid_scalefactor, 1.0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { setsizeneeded = true; if (self < 0.05 || self > 2.0) diff --git a/src/textures/hires/hqresize.cpp b/src/textures/hires/hqresize.cpp index 01f310ed2..7512be703 100644 --- a/src/textures/hires/hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -45,18 +45,22 @@ #include "parallel_for.h" #include "hwrenderer/textures/hw_material.h" -CUSTOM_CVAR(Int, gl_texture_hqresize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +EXTERN_CVAR(Int, gl_texture_hqresizemult) +CUSTOM_CVAR(Int, gl_texture_hqresizemode, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) { - if (self < 0 || self > 24) - { + if (self < 0 || self > 6) self = 0; - } - #ifndef HAVE_MMX - // This is to allow the menu option to work properly so that these filters can be skipped while cycling through them. - if (self == 7) self = 10; - if (self == 8) self = 10; - if (self == 9) self = 6; - #endif + if ((gl_texture_hqresizemult > 4) && (self < 4) && (self > 0)) + gl_texture_hqresizemult = 4; + FMaterial::FlushAll(); +} + +CUSTOM_CVAR(Int, gl_texture_hqresizemult, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL) +{ + if (self < 1 || self > 6) + self = 1; + if ((self > 4) && (gl_texture_hqresizemode < 4) && (gl_texture_hqresizemode > 0)) + self = 4; FMaterial::FlushAll(); } @@ -385,64 +389,60 @@ unsigned char *FTexture::CreateUpsampledTextureBuffer (unsigned char *inputBuffe if (inputBuffer) { - int type = gl_texture_hqresize; + int type = gl_texture_hqresizemode; + int mult = gl_texture_hqresizemult; 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) + if (hasAlpha && type == 3) { - type -= 3; + type = 2; } #endif + if (mult < 2) + type = 0; switch (type) { case 1: - return scaleNxHelper( &scale2x, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); + 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: - return scaleNxHelper( &scale3x, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 3: - return scaleNxHelper( &scale4x, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 4: - return hqNxHelper( &hq2x_32, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 5: - return hqNxHelper( &hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 6: - return hqNxHelper( &hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); + 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 7: - return hqNxAsmHelper( &HQnX_asm::hq2x_32, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 8: - return hqNxAsmHelper( &HQnX_asm::hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 9: - return hqNxAsmHelper( &HQnX_asm::hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); + 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 10: - case 11: - case 12: - return xbrzHelper(xbrz::scale, type - 8, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - - case 13: - case 14: - case 15: - case 16: - case 17: - return xbrzHelper(xbrzOldScale, type - 11, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - - case 18: - case 19: - return xbrzHelper(xbrz::scale, type - 13, inputBuffer, inWidth, inHeight, outWidth, outHeight); - case 20: - return normalNxHelper( &normalNx, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 21: - return normalNxHelper( &normalNx, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 22: - return normalNxHelper( &normalNx, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 23: - return normalNxHelper( &normalNx, 5, inputBuffer, inWidth, inHeight, outWidth, outHeight ); - case 24: - return normalNxHelper( &normalNx, 6, inputBuffer, inWidth, inHeight, outWidth, outHeight ); + 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 ); } } return inputBuffer; diff --git a/src/version.h b/src/version.h index 7ee00c950..7cd576e3a 100644 --- a/src/version.h +++ b/src/version.h @@ -68,7 +68,7 @@ const char *GetVersionString(); // Version stored in the ini's [LastRun] section. // Bump it if you made some configuration change that you want to // be able to migrate in FGameConfigFile::DoGlobalSetup(). -#define LASTRUNVERSION "215" +#define LASTRUNVERSION "216" // Protocol version used in demos. // Bump it if you change existing DEM_ commands or add new ones. diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 2b49fe55f..81b7d17f2 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -2783,7 +2783,8 @@ GLTEXMNU_ANISOTROPIC = "Anisotropic filter"; GLTEXMNU_TEXFORMAT = "Texture Format"; GLTEXMNU_ENABLEHIRES = "Enable hires textures"; GLTEXMNU_HQRESIZE = "High Quality Resize mode"; -GLTEXMNU_HQRESIZEWARN = "This mode requires %d times more video memory"; +GLTEXMNU_HQRESIZEMULT = "High Quality Resize multiplier"; +GLTEXMNU_HQRESIZEWARN = "This mode requires %d times more video memory"; GLTEXMNU_RESIZETEX = "Resize textures"; GLTEXMNU_RESIZESPR = "Resize sprites"; GLTEXMNU_RESIZEFNT = "Resize fonts"; @@ -2881,30 +2882,12 @@ OPTVAL_YAXIS = "Y Axis"; OPTVAL_XYAXIS = "X/Y Axis"; OPTVAL_SQUARE = "Square"; OPTVAL_ROUND = "Round"; -OPTVAL_SCALE2X = "Scale2x"; -OPTVAL_SCALE3X = "Scale3x"; -OPTVAL_SCALE4X = "Scale4x"; -OPTVAL_NORMAL2X = "Normal2x"; -OPTVAL_NORMAL3X = "Normal3x"; -OPTVAL_NORMAL4X = "Normal4x"; -OPTVAL_NORMAL5X = "Normal5x"; -OPTVAL_NORMAL6X = "Normal6x"; -OPTVAL_HQ2X = "hq2x"; -OPTVAL_HQ3X = "hq3x"; -OPTVAL_HQ4X = "hq4x"; -OPTVAL_HQ2XMMX = "hq2x MMX"; -OPTVAL_HQ3XMMX = "hq3x MMX"; -OPTVAL_HQ4XMMX = "hq4x MMX"; -OPTVAL_2XBRZ = "2xBRZ"; -OPTVAL_3XBRZ = "3xBRZ"; -OPTVAL_4XBRZ = "4xBRZ"; -OPTVAL_5XBRZ = "5xBRZ"; -OPTVAL_6XBRZ = "6xBRZ"; -OPTVAL_OLD_2XBRZ = "Old 2xBRZ"; -OPTVAL_OLD_3XBRZ = "Old 3xBRZ"; -OPTVAL_OLD_4XBRZ = "Old 4xBRZ"; -OPTVAL_OLD_5XBRZ = "Old 5xBRZ"; -OPTVAL_OLD_6XBRZ = "Old 6xBRZ"; +OPTVAL_SCALENX = "ScaleNx"; +OPTVAL_NORMALNX = "NormalNx"; +OPTVAL_HQNX = "hqNx"; +OPTVAL_HQNXMMX = "hqNx MMX"; +OPTVAL_NXBRZ = "xBRZ"; +OPTVAL_OLD_NXBRZ = "Old xBRZ"; OPTVAL_RADIAL = "Radial"; OPTVAL_PIXELFUZZ = "Pixel fuzz"; OPTVAL_SMOOTHFUZZ = "Smooth fuzz"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 965f23d0c..4026e2bc0 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -2151,51 +2151,32 @@ OptionValue "Particles" OptionValue "HqResizeModes" { 0, "$OPTVAL_OFF" - 1, "$OPTVAL_SCALE2X" - 2, "$OPTVAL_SCALE3X" - 3, "$OPTVAL_SCALE4X" - 4, "$OPTVAL_HQ2X" - 5, "$OPTVAL_HQ3X" - 6, "$OPTVAL_HQ4X" - 7, "$OPTVAL_HQ2XMMX" - 8, "$OPTVAL_HQ3XMMX" - 9, "$OPTVAL_HQ4XMMX" - 10, "$OPTVAL_2XBRZ" - 11, "$OPTVAL_3XBRZ" - 12, "$OPTVAL_4XBRZ" - 18, "$OPTVAL_5XBRZ" - 19, "$OPTVAL_6XBRZ" - 13, "$OPTVAL_OLD_2XBRZ" - 14, "$OPTVAL_OLD_3XBRZ" - 15, "$OPTVAL_OLD_4XBRZ" - 16, "$OPTVAL_OLD_5XBRZ" - 17, "$OPTVAL_OLD_6XBRZ" - 20, "$OPTVAL_NORMAL2X" - 21, "$OPTVAL_NORMAL3X" - 22, "$OPTVAL_NORMAL4X" - 23, "$OPTVAL_NORMAL5X" - 24, "$OPTVAL_NORMAL6X" + 1, "$OPTVAL_SCALENX" + 2, "$OPTVAL_HQNX" + 3, "$OPTVAL_HQNXMMX" + 4, "$OPTVAL_NXBRZ" + 5, "$OPTVAL_OLD_NXBRZ" + 6, "$OPTVAL_NORMALNX" +} + +OptionValue "HqResizeMultipliers" +{ + 1, "$OPTVAL_OFF" + 2, "2x" + 3, "3x" + 4, "4x" + 5, "5x" + 6, "6x" } OptionValue "HqResizeModesNoMMX" { 0, "$OPTVAL_OFF" - 1, "$OPTVAL_SCALE2X" - 2, "$OPTVAL_SCALE3X" - 3, "$OPTVAL_SCALE4X" - 4, "$OPTVAL_HQ2X" - 5, "$OPTVAL_HQ3X" - 6, "$OPTVAL_HQ4X" - 10, "$OPTVAL_2XBRZ" - 11, "$OPTVAL_3XBRZ" - 12, "$OPTVAL_4XBRZ" - 18, "$OPTVAL_5XBRZ" - 19, "$OPTVAL_6XBRZ" - 13, "$OPTVAL_OLD_2XBRZ" - 14, "$OPTVAL_OLD_3XBRZ" - 15, "$OPTVAL_OLD_4XBRZ" - 16, "$OPTVAL_OLD_5XBRZ" - 17, "$OPTVAL_OLD_6XBRZ" + 1, "$OPTVAL_SCALENX" + 2, "$OPTVAL_HQNX" + 4, "$OPTVAL_NXBRZ" + 5, "$OPTVAL_OLD_NXBRZ" + 6, "$OPTVAL_NORMALNX" } OptionValue "FogMode" @@ -2262,12 +2243,13 @@ OptionMenu "GLTextureGLOptions" protected ifOption(MMX) { - Option "$GLTEXMNU_HQRESIZE", gl_texture_hqresize, "HqResizeModes" + Option "$GLTEXMNU_HQRESIZE", gl_texture_hqresizemode, "HqResizeModes" } else { - Option "$GLTEXMNU_HQRESIZE", gl_texture_hqresize, "HqResizeModesNoMMX" + Option "$GLTEXMNU_HQRESIZE", gl_texture_hqresizemode, "HqResizeModesNoMMX" } + Option "$GLTEXMNU_HQRESIZEMULT", gl_texture_hqresizemult, "HqResizeMultipliers" StaticText "!HQRESIZE_WARNING!" Option "$GLTEXMNU_RESIZETEX", gl_texture_hqresize_textures, "OnOff" diff --git a/wadsrc/static/zscript/menu/optionmenu.txt b/wadsrc/static/zscript/menu/optionmenu.txt index f73035ab0..10bd91140 100644 --- a/wadsrc/static/zscript/menu/optionmenu.txt +++ b/wadsrc/static/zscript/menu/optionmenu.txt @@ -579,47 +579,9 @@ class GLTextureGLOptions : OptionMenu { string message; - if (gl_texture_hqresize > 0) + if (gl_texture_hqresizemult > 1 && gl_texture_hqresizemode > 0) { - int multiplier; - - switch (gl_texture_hqresize) - { - case 1: - case 4: - case 7: - case 10: - case 13: - case 20: - multiplier = 4; - break; - case 2: - case 5: - case 8: - case 11: - case 14: - case 21: - multiplier = 9; - break; - case 3: - case 6: - case 9: - case 12: - case 15: - case 22: - multiplier = 16; - break; - case 16: - case 18: - case 23: - multiplier = 25; - break; - case 17: - case 19: - case 24: - multiplier = 36; - break; - } + int multiplier = gl_texture_hqresizemult * gl_texture_hqresizemult; string localized = StringTable.Localize("$GLTEXMNU_HQRESIZEWARN"); message = String.Format(localized, multiplier); From 5666e4c805a27fba3d5c8c5239b60861e5b6e939 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Dec 2018 00:01:45 +0100 Subject: [PATCH 037/113] - 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 ad8f48483634e27faaecfcfbf9f1c86a95a6a95f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Dec 2018 00:21:37 +0100 Subject: [PATCH 038/113] - fixed: The JIT compiler crashed on missing ArgFlags. For ad-hoc Dehacked state functions no ArgFlags are created, in this case they can just be assumed to not be relevant here, because none of these function produces reference arguments. --- src/scripting/vm/jit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/scripting/vm/jit.cpp b/src/scripting/vm/jit.cpp index 6aacc4bf1..319130aa4 100644 --- a/src/scripting/vm/jit.cpp +++ b/src/scripting/vm/jit.cpp @@ -268,7 +268,7 @@ void JitCompiler::SetupSimpleFrame() for (unsigned int i = 0; i < sfunc->Proto->ArgumentTypes.Size(); i++) { const PType *type = sfunc->Proto->ArgumentTypes[i]; - if (sfunc->ArgFlags[i] & (VARF_Out | VARF_Ref)) + if (sfunc->ArgFlags.Size() && sfunc->ArgFlags[i] & (VARF_Out | VARF_Ref)) { cc.mov(regA[rega++], x86::ptr(args, argsPos++ * sizeof(VMValue) + offsetof(VMValue, a))); } From abd6729d39ccff59fed9b151196183517f0346ef Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Dec 2018 00:35:22 +0100 Subject: [PATCH 039/113] - fixed deprecation warnings for member functions not checking the version. --- src/scripting/backend/codegen.cpp | 6 +++--- src/scripting/thingdef.cpp | 4 ++-- src/scripting/thingdef.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/scripting/backend/codegen.cpp b/src/scripting/backend/codegen.cpp index 0eecab9a9..db87134dd 100644 --- a/src/scripting/backend/codegen.cpp +++ b/src/scripting/backend/codegen.cpp @@ -7600,7 +7600,7 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx) if (ctx.Class != nullptr) { - PFunction *afd = FindClassMemberFunction(ctx.Class, ctx.Class, MethodName, ScriptPosition, &error); + PFunction *afd = FindClassMemberFunction(ctx.Class, ctx.Class, MethodName, ScriptPosition, &error, ctx.Version); if (afd != nullptr) { @@ -8002,7 +8002,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) if (novirtual) { bool error; - PFunction *afd = FindClassMemberFunction(ccls, ctx.Class, MethodName, ScriptPosition, &error); + PFunction *afd = FindClassMemberFunction(ccls, ctx.Class, MethodName, ScriptPosition, &error, ctx.Version); if ((nullptr != afd) && (afd->Variants[0].Flags & VARF_Method) && (afd->Variants[0].Flags & VARF_Virtual)) { staticonly = false; @@ -8309,7 +8309,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx) isresolved: bool error = false; - PFunction *afd = FindClassMemberFunction(cls, ctx.Class, MethodName, ScriptPosition, &error); + PFunction *afd = FindClassMemberFunction(cls, ctx.Class, MethodName, ScriptPosition, &error, ctx.Version); if (error) { delete this; diff --git a/src/scripting/thingdef.cpp b/src/scripting/thingdef.cpp index 928f645a8..439bf8ce8 100644 --- a/src/scripting/thingdef.cpp +++ b/src/scripting/thingdef.cpp @@ -236,7 +236,7 @@ PFunction *CreateAnonymousFunction(PContainerType *containingclass, PType *retur // //========================================================================== -PFunction *FindClassMemberFunction(PContainerType *selfcls, PContainerType *funccls, FName name, FScriptPosition &sc, bool *error) +PFunction *FindClassMemberFunction(PContainerType *selfcls, PContainerType *funccls, FName name, FScriptPosition &sc, bool *error, const VersionInfo &version) { // Skip ACS_NamedExecuteWithResult. Anything calling this should use the builtin instead. if (name == NAME_ACS_NamedExecuteWithResult) return nullptr; @@ -263,7 +263,7 @@ PFunction *FindClassMemberFunction(PContainerType *selfcls, PContainerType *func { sc.Message(MSG_ERROR, "%s is declared protected and not accessible", symbol->SymbolName.GetChars()); } - else if (funcsym->Variants[0].Flags & VARF_Deprecated) + else if ((funcsym->Variants[0].Flags & VARF_Deprecated) && funcsym->mVersion <= version) { sc.Message(MSG_WARNING, "Call to deprecated function %s", symbol->SymbolName.GetChars()); } diff --git a/src/scripting/thingdef.h b/src/scripting/thingdef.h index 844e38957..6e6737282 100644 --- a/src/scripting/thingdef.h +++ b/src/scripting/thingdef.h @@ -204,7 +204,7 @@ class FxVMFunctionCall *ParseAction(FScanner &sc, FState state, FString statestr FName CheckCastKludges(FName in); void SetImplicitArgs(TArray *args, TArray *argflags, TArray *argnames, PContainerType *cls, uint32_t funcflags, int useflags); PFunction *CreateAnonymousFunction(PContainerType *containingclass, PType *returntype, int flags); -PFunction *FindClassMemberFunction(PContainerType *cls, PContainerType *funccls, FName name, FScriptPosition &sc, bool *error); +PFunction *FindClassMemberFunction(PContainerType *cls, PContainerType *funccls, FName name, FScriptPosition &sc, bool *error, const VersionInfo &version); void CreateDamageFunction(PNamespace *ns, const VersionInfo &ver, PClassActor *info, AActor *defaults, FxExpression *id, bool fromDecorate, int lumpnum); //========================================================================== From f6aa16947ac5f15a66c057603aa841dc0b8e3ad1 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Dec 2018 00:35:53 +0100 Subject: [PATCH 040/113] - re-added PlayerInfo.BringUpWeapon. --- wadsrc/static/zscript/shared/player.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index 391ae38a6..9a06f78b4 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -2431,6 +2431,11 @@ struct PlayerInfo native play // self is what internally is known as player_t mo.DropWeapon(); } } + + deprecated("3.7") void BringUpWeapon() + { + if (mo) mo.BringUpWeapon(); + } bool IsTotallyFrozen() { From 8b46be768695674a04c0a66a1e580ef8b06c7c07 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 11 Dec 2018 10:46:56 +0200 Subject: [PATCH 041/113] - print VM stack trace on startup abort exception https://forum.zdoom.org/viewtopic.php?t=62650 --- src/posix/cocoa/i_main_except.cpp | 21 +++++++++++++++++---- src/posix/sdl/i_main.cpp | 24 ++++++++++++++++++++---- src/win32/i_main.cpp | 6 ++++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/posix/cocoa/i_main_except.cpp b/src/posix/cocoa/i_main_except.cpp index a61eca2cc..afb0ba7e4 100644 --- a/src/posix/cocoa/i_main_except.cpp +++ b/src/posix/cocoa/i_main_except.cpp @@ -32,9 +32,11 @@ */ // Workaround for GCC Objective-C++ with C++ exceptions bug. -#include "doomerrors.h" #include +#include "doomerrors.h" +#include "vm.h" + // Import some functions from i_main.mm void call_terms(); void Mac_I_FatalError(const char* const message); @@ -50,10 +52,21 @@ void OriginalMainExcept(int argc, char** argv) { const char* const message = error.what(); - if (NULL != message) + if (strcmp(message, "NoRunExit")) { - if (strcmp(message, "NoRunExit")) fprintf(stderr, "%s\n", message); - Mac_I_FatalError(message); + if (CVMAbortException::stacktrace.IsNotEmpty()) + { + Printf("%s", CVMAbortException::stacktrace.GetChars()); + } + + if (batchrun) + { + Printf("%s\n", message); + } + else + { + Mac_I_FatalError(message); + } } exit(-1); diff --git a/src/posix/sdl/i_main.cpp b/src/posix/sdl/i_main.cpp index 0c2389294..3d7912fc8 100644 --- a/src/posix/sdl/i_main.cpp +++ b/src/posix/sdl/i_main.cpp @@ -52,6 +52,7 @@ #include "cmdlib.h" #include "r_utility.h" #include "doomstat.h" +#include "vm.h" // MACROS ------------------------------------------------------------------ @@ -261,16 +262,31 @@ int main (int argc, char **argv) catch (std::exception &error) { I_ShutdownJoysticks(); - if (error.what () && strcmp(error.what(), "NoRunExit")) - fprintf (stderr, "%s\n", error.what ()); + const char *const message = error.what(); + + if (strcmp(message, "NoRunExit")) + { + if (CVMAbortException::stacktrace.IsNotEmpty()) + { + Printf("%s", CVMAbortException::stacktrace.GetChars()); + } + + if (batchrun) + { + Printf("%s\n", message); + } + else + { #ifdef __APPLE__ - Mac_I_FatalError(error.what()); + Mac_I_FatalError(message); #endif // __APPLE__ #ifdef __linux__ - Linux_I_FatalError(error.what()); + Linux_I_FatalError(message); #endif // __linux__ + } + } exit (-1); } diff --git a/src/win32/i_main.cpp b/src/win32/i_main.cpp index 6a75a597a..4bd3aed66 100644 --- a/src/win32/i_main.cpp +++ b/src/win32/i_main.cpp @@ -71,6 +71,7 @@ #include "r_utility.h" #include "g_levellocals.h" #include "s_sound.h" +#include "vm.h" #include "stats.h" #include "st_start.h" @@ -1057,6 +1058,11 @@ void DoMain (HINSTANCE hInstance) auto msg = error.what(); if (strcmp(msg, "NoRunExit")) { + if (CVMAbortException::stacktrace.IsNotEmpty()) + { + Printf("%s", CVMAbortException::stacktrace.GetChars()); + } + if (!batchrun) { ShowErrorPane(msg); From eb8614fc716818d0603c92eafbac7be62008d92d Mon Sep 17 00:00:00 2001 From: Player701 Date: Tue, 11 Dec 2018 17:07:21 +0300 Subject: [PATCH 042/113] - Force node rebuild for Plutonia 2 MAP25 to fix BSP glitches --- wadsrc/static/compatibility.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 030cea322..03d8b3223 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -175,6 +175,7 @@ AF40D0E49BD1B76D4B1AADD8212ADC46 // MAP01 (the wad that shall not be named =P) D5F64E02679A81B82006AF34A6A8EAC3 // plutonia.wad map32 BA4860C7A2F5D705DB32A1A38DB77EC4 // pl2.wad map10 EDA5CE7C462BD171BF8110AC56B67857 // pl2.wad map11 +A9A9A728E689266939C1B71655F320CA // pl2.wad map25 { rebuildnodes } From 86d851bc5c5cbb791c0bf4e86f0fb6586534e53c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 11 Dec 2018 19:56:23 +0100 Subject: [PATCH 043/113] - 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 044/113] - 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 045/113] - 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 046/113] - 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 047/113] - 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 048/113] - 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 049/113] - 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 050/113] - 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 051/113] - 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 052/113] - 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 14094ebeb941d3d529802290be5d76fcfb299ac2 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 12 Dec 2018 10:15:53 +0200 Subject: [PATCH 053/113] - fixed crash on invoking vid_setsize CCMD with one argument --- src/v_video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_video.cpp b/src/v_video.cpp index 658e70fe9..7c2adec6c 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -924,7 +924,7 @@ void ScaleWithAspect (int &w, int &h, int Width, int Height) CCMD(vid_setsize) { - if (argv.argc() < 2) + if (argv.argc() < 3) { Printf("Usage: vid_setsize width height\n"); } From 172b4bb8466d49c1b09415d1dc4ce48c44dba655 Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Wed, 12 Dec 2018 11:22:53 -0500 Subject: [PATCH 054/113] - added a number of darken2.wad maps to rebuild nodes in compatibility.txt --- wadsrc/static/compatibility.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 03d8b3223..d303967f0 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -167,6 +167,26 @@ AF40D0E49BD1B76D4B1AADD8212ADC46 // MAP01 (the wad that shall not be named =P) pointonline } +920F8D876ECD96D8C2A978FF1AB2B401 // Darken2.wad map01 - Nodes go out of bounds/beyond normal sector boundaries +CFEDB7FA89885E24856CAC9A2FB3CE58 // Darken2.wad map03 - GZDoomBuilder crashes when displaying Nodes +8E961FA7029761D5FAB3932C40F10CD2 // Darken2.wad map04 - Nodes go out of bounds/beyond normal sector boundaries +DEA5E9C6253FFF8FDB2D5E5BADE13A9D // Darken2.wad map06 - Nodes go out of bounds/beyond normal sector boundaries +0E72254C0C26F721333A1C56E3648D68 // Darken2.wad map07 - Nodes go out of bounds/beyond normal sector boundaries +1437B40F2D56DF82346366814E9729D9 // Darken2.wad map08 - Nodes go out of bounds/beyond normal sector boundaries +8B15F89E47E422780FBF2D6CDE3AA050 // Darken2.wad map09 - GZDoomBuilder crashes when displaying Nodes +5A2FD43D23B45191229E5C74E9398D36 // Darken2.wad map10 - Nodes go out of bounds/beyond normal sector boundaries +FA25A78B3DFD7CC44E9B10C7B78EADAE // Darken2.wad map11 - Nodes go out beyond normal sector boundaries +01592ACF001C534076556D9E1B5D85E7 // Darken2.wad map12 - Nodes go out of bounds/beyond normal sector boundaries +16A2ED2917A68B2FD8D264BE4D64EA09 // Darken2.wad map13 - Nodes go out of bounds/beyond normal sector boundaries +F5DA2AA0C7112E090167A6B2F6D4A079 // Darken2.wad map15 - Nodes go out beyond normal sector boundaries +A40A4472AB0FDBE2D55ADADA7D9005C8 // Darken2.wad map16 - Nodes go out of bounds/beyond normal sector boundaries +244701904E6B754A02842415AB183EBE // Darken2.wad map17 - Nodes go out beyond normal sector boundaries +661D3C9221114A1CD16674CBFF239DDF // Darken2.wad map19 - Nodes go out of bounds/beyond normal sector boundaries +1FB559C4C37CCE8C3883057C963952A8 // Darken2.wad map20 - Nodes go out beyond normal sector boundaries +D36E7D121F28F77A3780A5BD88425FB4 // Darken2.wad map21 - Nodes go out beyond normal sector boundaries +3253B280FB7A4A04284FE08A6D9F222D // Darken2.wad map22 - Nodes go out beyond normal sector boundaries +E0E5517B7928E88B88F6A5B77AC449DF // Darken2.wad map23 - Nodes go out of bounds/beyond normal sector boundaries +6DD76422593381E3234FA703C155C493 // Darken2.wad map24 - Nodes go out of bounds/beyond normal sector boundaries 8B2AC8D4DB4A49A5DCCBB067E04434D6 // The Hell Factory Hub One, map04 65A1EB4C87386F290816660A52932FF1 // Master Levels, garrison.wad 3DEE4EFEFAF3260C800A30734F54CE75 // Hellbound, map14 From c5447f0cddab41462c4d8be23803970ea09666cc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Wed, 12 Dec 2018 18:39:38 +0100 Subject: [PATCH 055/113] - 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 056/113] - 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 057/113] - 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 058/113] - 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 059/113] - 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 74ec789d0e3a0c9824985b6a520710415e809904 Mon Sep 17 00:00:00 2001 From: Player701 Date: Thu, 13 Dec 2018 21:35:28 +0300 Subject: [PATCH 060/113] - Force node rebuild for Plutonia 2 MAP29 to fix BSP glitches --- wadsrc/static/compatibility.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index d303967f0..2ab378ba3 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -196,6 +196,7 @@ D5F64E02679A81B82006AF34A6A8EAC3 // plutonia.wad map32 BA4860C7A2F5D705DB32A1A38DB77EC4 // pl2.wad map10 EDA5CE7C462BD171BF8110AC56B67857 // pl2.wad map11 A9A9A728E689266939C1B71655F320CA // pl2.wad map25 +62CA74092FC88C1E7FE2D0B1A8034E29 // pl2.wad map29 { rebuildnodes } From 7ffc2f12753eae3222ddeb77aa66328b189644e7 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 13 Dec 2018 23:25:55 +0100 Subject: [PATCH 061/113] - 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 062/113] - 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 063/113] - 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 064/113] - 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 065/113] - 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 4a83f4d25120927618d410656b99b0b2057fccc9 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Fri, 14 Dec 2018 15:52:40 +0200 Subject: [PATCH 066/113] - disable music playback if WinMM stream cannot be opened https://forum.zdoom.org/viewtopic.php?t=62888 --- src/sound/mididevices/music_win_mididevice.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sound/mididevices/music_win_mididevice.cpp b/src/sound/mididevices/music_win_mididevice.cpp index f9820033f..b6ddd46a2 100644 --- a/src/sound/mididevices/music_win_mididevice.cpp +++ b/src/sound/mididevices/music_win_mididevice.cpp @@ -198,6 +198,10 @@ int WinMIDIDevice::Open(MidiCallback callback, void *userdata) } } } + else + { + return 1; + } } return 0; } From a19f297ae03e8dc4bd960c3d970a6111be358c0d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 14 Dec 2018 19:59:19 +0100 Subject: [PATCH 067/113] - 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 f373752b4fd9d8e14f4e9092121153e84edcbbca Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 14 Dec 2018 19:59:19 +0100 Subject: [PATCH 068/113] - 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 85b57798d..bd2b87054 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -1576,7 +1576,7 @@ float FTexCoordInfo::RowOffset(float rowoffset) const } else { - if (mWorldPanning) return rowoffset / tscale; + if (mWorldPanning) return rowoffset; else return rowoffset / scale; } } @@ -1598,7 +1598,7 @@ float FTexCoordInfo::TextureOffset(float textureoffset) const } else { - if (mWorldPanning) return textureoffset / tscale; + if (mWorldPanning) return textureoffset; else return textureoffset / scale; } } From 013d3e236849d591757e6921e0eda191e820caf2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 14 Dec 2018 22:34:28 +0100 Subject: [PATCH 069/113] - code simplification. --- src/textures/texture.cpp | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index bd2b87054..304be17d5 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -1566,19 +1566,9 @@ CCMD (printspans) float FTexCoordInfo::RowOffset(float rowoffset) const { - float tscale = fabs(mTempScale.Y); float scale = fabs(mScale.Y); - - if (tscale == 1.f) - { - if (scale == 1.f || mWorldPanning) return rowoffset; - else return rowoffset / scale; - } - else - { - if (mWorldPanning) return rowoffset; - else return rowoffset / scale; - } + if (scale == 1.f || mWorldPanning) return rowoffset; + else return rowoffset / scale; } //=========================================================================== @@ -1589,18 +1579,9 @@ float FTexCoordInfo::RowOffset(float rowoffset) const float FTexCoordInfo::TextureOffset(float textureoffset) const { - float tscale = fabs(mTempScale.X); float scale = fabs(mScale.X); - if (tscale == 1.f) - { - if (scale == 1.f || mWorldPanning) return textureoffset; - else return textureoffset / scale; - } - else - { - if (mWorldPanning) return textureoffset; - else return textureoffset / scale; - } + if (scale == 1.f || mWorldPanning) return textureoffset; + else return textureoffset / scale; } //=========================================================================== From 4d8e8e7741901637954cb882e4de4e041b8577d3 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 00:38:27 +0100 Subject: [PATCH 070/113] - enable the texture scalers in software mode. Currently only implemented for 8 bit in the classic renderer. --- src/swrenderer/line/r_line.cpp | 12 +-- src/swrenderer/textures/r_swtexture.cpp | 40 +++++++- src/swrenderer/textures/r_swtexture.h | 32 +++--- src/textures/hires/hqresize.cpp | 128 ++++++++++++------------ src/textures/textures.h | 1 + 5 files changed, 126 insertions(+), 87 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 9083f9ec4..11ce9dc19 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -858,7 +858,7 @@ namespace swrenderer } else { - mTopPart.TextureMid += rowoffset; + mTopPart.TextureMid += rowoffset * mTopPart.Texture->GetPhysicalScale(); } } @@ -918,7 +918,7 @@ namespace swrenderer { // rowoffset is added outside the multiply so that it positions the texture // by texels instead of world units. - mMiddlePart.TextureMid += rowoffset; + mMiddlePart.TextureMid += rowoffset * mMiddlePart.Texture->GetPhysicalScale(); } } @@ -983,7 +983,7 @@ namespace swrenderer } else { - mBottomPart.TextureMid += rowoffset; + mBottomPart.TextureMid += rowoffset * mBottomPart.Texture->GetPhysicalScale(); } } @@ -1158,7 +1158,7 @@ namespace swrenderer } else { - offset = mTopPart.TextureOffsetU; + offset = mTopPart.TextureOffsetU * mTopPart.Texture->GetPhysicalScale(); } if (xscale < 0) { @@ -1205,7 +1205,7 @@ namespace swrenderer } else { - offset = mMiddlePart.TextureOffsetU; + offset = mMiddlePart.TextureOffsetU * mMiddlePart.Texture->GetPhysicalScale(); } if (xscale < 0) { @@ -1253,7 +1253,7 @@ namespace swrenderer } else { - offset = mBottomPart.TextureOffsetU; + offset = mBottomPart.TextureOffsetU * mBottomPart.Texture->GetPhysicalScale(); } if (xscale < 0) { diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index 100825252..43d6405b2 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -37,6 +37,9 @@ #include "r_swtexture.h" #include "bitmap.h" #include "m_alloc.h" +#include "imagehelpers.h" + +EXTERN_CVAR(Bool, gl_texture_usehires) FSoftwareTexture *FTexture::GetSoftwareTexture() @@ -56,6 +59,25 @@ FSoftwareTexture *FTexture::GetSoftwareTexture() // //========================================================================== +FSoftwareTexture::FSoftwareTexture(FTexture *tex) +{ + mTexture = tex; + mSource = tex; + + mBufferFlags = (gl_texture_usehires && !tex->isScaled() && tex->GetImage() && !tex->isSprite() ) ? CTF_CheckHires|CTF_ProcessData : CTF_ProcessData; + auto info = tex->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags); + mPhysicalWidth = info.mWidth; + mPhysicalHeight = info.mHeight; + mPhysicalScale = mPhysicalWidth / tex->Width;; + CalcBitSize(); +} + +//========================================================================== +// +// +// +//========================================================================== + void FSoftwareTexture::CalcBitSize () { // WidthBits is rounded down, and HeightBits is rounded up @@ -93,7 +115,23 @@ const uint8_t *FSoftwareTexture::GetPixels(int style) { if (Pixels.Size() == 0 || CheckModified(style)) { - Pixels = mSource->Get8BitPixels(style); + if (mPhysicalScale == 1) + { + Pixels = mSource->Get8BitPixels(style); + } + else + { + auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags); + Pixels.Resize(GetWidth()*GetHeight()); + PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; + for (int y = 0; y < GetHeight(); y++) + { + for (int x = 0; x < GetWidth(); x++) + { + Pixels[y + x * GetHeight()] = ImageHelpers::RGBToPalette(false, pe[x + y * GetWidth()], true); + } + } + } } return Pixels.Data(); } diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index 14810b071..97729e2c6 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -21,19 +21,17 @@ protected: FSoftwareTextureSpan **Spandata[3] = { }; uint8_t WidthBits = 0, HeightBits = 0; uint16_t WidthMask = 0; - + int mPhysicalWidth, mPhysicalHeight; + int mPhysicalScale; + int mBufferFlags; + void FreeAllSpans(); template FSoftwareTextureSpan **CreateSpans(const T *pixels); void FreeSpans(FSoftwareTextureSpan **spans); void CalcBitSize(); public: - FSoftwareTexture(FTexture *tex) - { - mTexture = tex; - mSource = tex; - CalcBitSize(); - } + FSoftwareTexture(FTexture *tex); virtual ~FSoftwareTexture() { @@ -59,8 +57,8 @@ public: 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 GetWidth () { return mPhysicalWidth; } + int GetHeight () { return mPhysicalHeight; } int GetWidthBits() { return WidthBits; } int GetHeightBits() { return HeightBits; } @@ -68,15 +66,14 @@ public: 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); } + int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted) * mPhysicalScale; } + int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted) * mPhysicalScale; } + int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted) * mPhysicalScale; } + int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted) * mPhysicalScale; } + double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted) * mPhysicalScale; } + double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted) * mPhysicalScale; } // 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. @@ -93,7 +90,8 @@ public: int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); } int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); } - DVector2 GetScale() const { return mTexture->Scale; } + DVector2 GetScale() const { return mTexture->Scale * mPhysicalScale; } + int GetPhysicalScale() const { return mPhysicalScale; } virtual void Unload() { diff --git a/src/textures/hires/hqresize.cpp b/src/textures/hires/hqresize.cpp index e6acb4911..82a4d8817 100644 --- a/src/textures/hires/hqresize.cpp +++ b/src/textures/hires/hqresize.cpp @@ -387,69 +387,71 @@ void FTexture::CreateUpsampledTextureBuffer(FTextureBuffer &texbuffer, bool hasA break; } - if (texbuffer.mBuffer) + int type = gl_texture_hqresizemode; + int mult = gl_texture_hqresizemult; +#ifdef HAVE_MMX + // hqNx MMX does not preserve the alpha channel so fall back to C-version for such textures + if (hasAlpha && type == 3) { - int type = gl_texture_hqresizemode; - int mult = gl_texture_hqresizemult; -#ifdef HAVE_MMX - // hqNx MMX does not preserve the alpha channel so fall back to C-version for such textures - if (hasAlpha && type == 3) - { - type = 2; - } -#endif - // 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 (!checkonly) - { - 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; - } -#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; + type = 2; } +#endif + // 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 (!checkonly) + { + 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; + } +#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 + { + texbuffer.mWidth *= mult; + texbuffer.mHeight *= mult; + } + // Encode the scaling method in the content ID. + FContentIdBuilder contentId; + contentId.id = texbuffer.mContentId; + contentId.scaler = type; + contentId.scalefactor = mult; + texbuffer.mContentId = contentId.id; } diff --git a/src/textures/textures.h b/src/textures/textures.h index d25026634..778909be5 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -330,6 +330,7 @@ public: int isWarped() const { return bWarped; } int GetRotations() const { return Rotations; } void SetRotations(int rot) { Rotations = int16_t(rot); } + bool isSprite() const { return UseType == ETextureType::Sprite || UseType == ETextureType::SkinSprite || UseType == ETextureType::Decal; } const FString &GetName() const { return Name; } bool allowNoDecals() const { return bNoDecals; } From 3af6ae4b377bde0f386593337020139587b90410 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 15 Dec 2018 07:11:28 +0100 Subject: [PATCH 071/113] - add vanilla lightmode that behaves exactly as Doom's original light did --- src/g_level.cpp | 5 +- src/hwrenderer/scene/hw_drawinfo.cpp | 2 +- src/hwrenderer/scene/hw_renderstate.cpp | 4 +- src/hwrenderer/scene/hw_renderstate.h | 2 +- src/hwrenderer/scene/hw_skyportal.cpp | 2 +- src/hwrenderer/scene/hw_weapon.cpp | 6 +- src/hwrenderer/utility/hw_lighting.cpp | 8 +-- wadsrc/static/menudef.txt | 1 + wadsrc/static/shaders/glsl/main.fp | 91 +++++++++++++++++++++---- 9 files changed, 93 insertions(+), 28 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index fe5477bf6..a5dc609ec 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -123,8 +123,9 @@ CUSTOM_CVAR(Bool, gl_notexturefill, false, CVAR_NOINITCALL) CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL) { int newself = self; - if (newself > 4) newself = 8; // use 8 for software lighting to avoid conflicts with the bit mask - if (newself < 0) newself = 0; + if (newself > 8) newself = 16; // use 8 and 16 for software lighting to avoid conflicts with the bit mask + else if (newself > 4) newself = 8; + else if (newself < 0) newself = 0; if (self != newself) self = newself; else if ((level.info == nullptr || level.info->lightmode == -1)) level.lightmode = self; } diff --git a/src/hwrenderer/scene/hw_drawinfo.cpp b/src/hwrenderer/scene/hw_drawinfo.cpp index 35b1836e0..06e962fff 100644 --- a/src/hwrenderer/scene/hw_drawinfo.cpp +++ b/src/hwrenderer/scene/hw_drawinfo.cpp @@ -388,7 +388,7 @@ void HWViewpointUniforms::SetDefaults() mNormalViewMatrix.loadIdentity(); mViewHeight = viewheight; mGlobVis = (float)R_GetGlobVis(r_viewwindow, r_visibility) / 32.f; - mPalLightLevels = static_cast(gl_bandedswlight) | (static_cast(gl_fogmode) << 8); + mPalLightLevels = static_cast(gl_bandedswlight) | (static_cast(gl_fogmode) << 8) | (static_cast(gl_lightmode) << 16); mClipLine.X = -10000000.0f; mShadowmapFilter = gl_shadowmap_filter; diff --git a/src/hwrenderer/scene/hw_renderstate.cpp b/src/hwrenderer/scene/hw_renderstate.cpp index 5aa8d9c3c..3ead6232d 100644 --- a/src/hwrenderer/scene/hw_renderstate.cpp +++ b/src/hwrenderer/scene/hw_renderstate.cpp @@ -127,7 +127,7 @@ void FRenderState::SetFog(int lightlevel, int rellight, bool fullbright, const F } else { - if ((level.lightmode == 2 || (level.lightmode == 8 && cmap->BlendFactor > 0)) && fogcolor == 0) + if ((level.lightmode == 2 || (level.lightmode >= 8 && cmap->BlendFactor > 0)) && fogcolor == 0) { float light = (float)hw_CalcLightLevel(lightlevel, rellight, false, cmap->BlendFactor); SetShaderLight(light, lightlevel); @@ -148,7 +148,7 @@ void FRenderState::SetFog(int lightlevel, int rellight, bool fullbright, const F SetFog(fogcolor, fogdensity); // Korshun: fullbright fog like in software renderer. - if (level.lightmode == 8 && cmap->BlendFactor == 0 && level.brightfog && fogdensity != 0 && fogcolor != 0) + if (level.lightmode >= 8 && cmap->BlendFactor == 0 && level.brightfog && fogdensity != 0 && fogcolor != 0) { SetSoftLightLevel(255); } diff --git a/src/hwrenderer/scene/hw_renderstate.h b/src/hwrenderer/scene/hw_renderstate.h index f494df34a..e39d25b26 100644 --- a/src/hwrenderer/scene/hw_renderstate.h +++ b/src/hwrenderer/scene/hw_renderstate.h @@ -326,7 +326,7 @@ public: void SetSoftLightLevel(int llevel, int blendfactor = 0) { - if (level.lightmode == 8 && blendfactor == 0) mLightParms[3] = llevel / 255.f; + if (level.lightmode >= 8 && blendfactor == 0) mLightParms[3] = llevel / 255.f; else mLightParms[3] = -1.f; } diff --git a/src/hwrenderer/scene/hw_skyportal.cpp b/src/hwrenderer/scene/hw_skyportal.cpp index cb04c1e86..83bd7de57 100644 --- a/src/hwrenderer/scene/hw_skyportal.cpp +++ b/src/hwrenderer/scene/hw_skyportal.cpp @@ -165,7 +165,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state) // We have no use for Doom lighting special handling here, so disable it for this function. int oldlightmode = ::level.lightmode; - if (::level.lightmode == 8) + if (::level.lightmode >= 8) { ::level.lightmode = 2; state.SetSoftLightLevel(-1); diff --git a/src/hwrenderer/scene/hw_weapon.cpp b/src/hwrenderer/scene/hw_weapon.cpp index 171c28647..7d0a1f3d1 100644 --- a/src/hwrenderer/scene/hw_weapon.cpp +++ b/src/hwrenderer/scene/hw_weapon.cpp @@ -107,7 +107,7 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state) void HWDrawInfo::DrawPlayerSprites(bool hudModelStep, FRenderState &state) { int oldlightmode = level.lightmode; - if (!hudModelStep && level.lightmode == 8) level.lightmode = 2; // Software lighting cannot handle 2D content so revert to lightmode 2 for that. + if (!hudModelStep && level.lightmode >= 8) level.lightmode = 2; // Software lighting cannot handle 2D content so revert to lightmode 2 for that. for (auto &hudsprite : hudsprites) { if ((!!hudsprite.mframe) == hudModelStep) @@ -260,7 +260,7 @@ static WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &po l.lightlevel = hw_CalcLightLevel(l.lightlevel, getExtraLight(), true, 0); - if (level.lightmode == 8 || l.lightlevel < 92) + if (level.lightmode >= 8 || l.lightlevel < 92) { // Korshun: the way based on max possible light level for sector like in software renderer. double min_L = 36.0 / 31.0 - ((l.lightlevel / 255.0) * (63.0 / 31.0)); // Lightlevel in range 0-63 @@ -499,7 +499,7 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area) // hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change // light mode here to draw the weapon sprite. int oldlightmode = level.lightmode; - if (level.lightmode == 8) level.lightmode = 2; + if (level.lightmode >= 8) level.lightmode = 2; for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { diff --git a/src/hwrenderer/utility/hw_lighting.cpp b/src/hwrenderer/utility/hw_lighting.cpp index 83e2acd7d..cee925b68 100644 --- a/src/hwrenderer/utility/hw_lighting.cpp +++ b/src/hwrenderer/utility/hw_lighting.cpp @@ -88,7 +88,7 @@ int hw_CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor if (lightlevel == 0) return 0; - bool darklightmode = (level.lightmode & 2) || (level.lightmode == 8 && blendfactor > 0); + bool darklightmode = (level.lightmode & 2) || (level.lightmode >= 8 && blendfactor > 0); if (darklightmode && lightlevel < 192 && !weapon) { @@ -130,7 +130,7 @@ PalEntry hw_CalcLightColor(int light, PalEntry pe, int blendfactor) if (blendfactor == 0) { - if (level.lightmode == 8) + if (level.lightmode >= 8) { return pe; } @@ -175,7 +175,7 @@ float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, float density; int lightmode = level.lightmode; - if (lightmode == 8 && blendfactor > 0) lightmode = 2; // The blendfactor feature does not work with software-style lighting. + if (lightmode >= 8 && blendfactor > 0) lightmode = 2; // The blendfactor feature does not work with software-style lighting. if (lightmode & 4) { @@ -190,7 +190,7 @@ float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, else if ((fogcolor.d & 0xffffff) == 0) { // case 2: black fog - if ((lightmode != 8 || blendfactor > 0) && !(level.flags3 & LEVEL3_NOLIGHTFADE)) + if ((lightmode < 8 || blendfactor > 0) && !(level.flags3 & LEVEL3_NOLIGHTFADE)) { density = distfogtable[level.lightmode != 0][hw_ClampLight(lightlevel)]; } diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 4026e2bc0..1ff8697b3 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -2105,6 +2105,7 @@ OptionValue "LightingModes" 3, "$OPTVAL_DARK" 4, "$OPTVAL_LEGACY" 8, "$OPTVAL_SOFTWARE" + 16, "$OPTVAL_VANILLA" } OptionValue "Precision" diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 77855a85a..8f5bb1fb6 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -119,17 +119,84 @@ vec4 getTexel(vec2 st) //=========================================================================== // -// Doom lighting equation exactly as calculated by zdoom. +// Vanilla Doom wall colormap equation +// +//=========================================================================== +float R_WallColormap(float lightnum, float z) +{ + // R_ScaleFromGlobalAngle calculation + float projection = 160.0; // projection depends on SCREENBLOCKS!! 160 is the fullscreen value + vec3 line_v1 = pixelpos.xyz; // in vanilla this is the first curline vertex + vec3 line_normal = vWorldNormal.xyz; + float texscale = projection * clamp(dot(normalize(uCameraPos.xyz - line_v1), line_normal), 0.0, 1.0) / z; + + float lightz = clamp(16.0 * texscale, 0.0, 47.0); + + // scalelight[lightnum][lightz] lookup + float startmap = (15.0 - lightnum) * 4.0; + return startmap - lightz * 0.5; +} + +//=========================================================================== +// +// Vanilla Doom plane colormap equation +// +//=========================================================================== +float R_PlaneColormap(float lightnum, float z) +{ + float lightz = clamp(z / 16.0f, 0.0, 127.0); + + // zlight[lightnum][lightz] lookup + float startmap = (15.0 - lightnum) * 4.0; + float scale = 160.0 / (lightz + 1.0); + return startmap - scale * 0.5; +} + +//=========================================================================== +// +// zdoom colormap equation +// +//=========================================================================== +float R_ZDoomColormap(float light, float z) +{ + float L = light * 255.0; + float vis = min(uGlobVis / z, 24.0 / 32.0); + float shade = 2.0 - (L + 12.0) / 128.0; + float lightscale = shade - vis; + return lightscale * 31.0; +} + +float R_DoomColormap(float light, float z) +{ + if ((uPalLightLevels >> 16) == 16) // gl_lightmode 16 + { + float lightnum = clamp(light * 15.0, 0.0, 15.0); + + if (dot(vWorldNormal.xyz, vWorldNormal.xyz) > 0.5) + { + return mix(R_WallColormap(lightnum, z), R_PlaneColormap(lightnum, z), abs(vWorldNormal.y)); + } + else // vWorldNormal is not set on sprites + { + return R_PlaneColormap(lightnum, z); + } + } + else + { + return R_ZDoomColormap(light, z); + } +} + +//=========================================================================== +// +// Doom software lighting equation // //=========================================================================== float R_DoomLightingEquation(float light) { - // L is the integer light level used in the game - float L = light * 255.0; - - // z is the depth in view/eye space, positive going into the screen + // z is the depth in view space, positive going into the screen float z; - if ((uPalLightLevels >> 8) == 2) + if (((uPalLightLevels >> 8) & 0xff) == 2) { z = distance(pixelpos.xyz, uCameraPos.xyz); } @@ -138,17 +205,13 @@ float R_DoomLightingEquation(float light) z = pixelpos.w; } - // The zdoom light equation - float vis = min(uGlobVis / z, 24.0 / 32.0); - float shade = 2.0 - (L + 12.0) / 128.0; - float lightscale; + float colormap = R_DoomColormap(light, z); + if ((uPalLightLevels & 0xff) != 0) - lightscale = float(-floor(-(shade - vis) * 31.0) - 0.5) / 31.0; - else - lightscale = shade - vis; + colormap = floor(colormap) + 0.5; // Result is the normalized colormap index (0 bright .. 1 dark) - return clamp(lightscale, 1.0 - light, 31.0 / 32.0); + return clamp(colormap, 0.0, 31.0) / 32.0; } //=========================================================================== From 1187906a6166c9f094efe976e5d6f1bdc4e7b04a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 09:40:39 +0100 Subject: [PATCH 072/113] - use symbolic constants for the light modes. --- src/g_level.cpp | 4 ++-- src/g_level.h | 15 ++++++++++++- src/g_levellocals.h | 29 +++++++++++++++++++------ src/g_mapinfo.cpp | 6 ++--- src/hwrenderer/scene/hw_renderstate.cpp | 4 ++-- src/hwrenderer/scene/hw_renderstate.h | 2 +- src/hwrenderer/scene/hw_skyportal.cpp | 6 ++--- src/hwrenderer/scene/hw_weapon.cpp | 10 ++++----- src/hwrenderer/utility/hw_lighting.cpp | 18 +++++++-------- src/v_2ddrawer.cpp | 2 +- 10 files changed, 62 insertions(+), 34 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index a5dc609ec..191d2d7a3 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -127,7 +127,7 @@ CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL) else if (newself > 4) newself = 8; else if (newself < 0) newself = 0; if (self != newself) self = newself; - else if ((level.info == nullptr || level.info->lightmode == -1)) level.lightmode = self; + else if ((level.info == nullptr || level.info->lightmode == ELightMode::NotSet)) level.lightmode = (ELightMode)*self; } @@ -1523,7 +1523,7 @@ void G_InitLevelLocals () level.DefaultEnvironment = info->DefaultEnvironment; - level.lightmode = info->lightmode < 0? gl_lightmode : info->lightmode; + level.lightmode = info->lightmode == ELightMode::NotSet? (ELightMode)*gl_lightmode : info->lightmode; level.brightfog = info->brightfog < 0? gl_brightfog : !!info->brightfog; level.lightadditivesurfaces = info->lightadditivesurfaces < 0 ? gl_lightadditivesurfaces : !!info->lightadditivesurfaces; level.notexturefill = info->notexturefill < 0 ? gl_notexturefill : !!info->notexturefill; diff --git a/src/g_level.h b/src/g_level.h index a98a8d415..f512287d3 100644 --- a/src/g_level.h +++ b/src/g_level.h @@ -314,6 +314,19 @@ struct FExitText } }; +enum class ELightMode : int8_t +{ + NotSet = -1, + LinearStandard = 0, + DoomBright = 1, + Doom = 2, + DoomDark = 3, + DoomLegacy = 4, + ZDoomSoftware = 8, + DoomSoftware = 16 +}; + + struct level_info_t { int levelnum; @@ -395,7 +408,7 @@ struct level_info_t TArray EventHandlers; - int8_t lightmode; + ELightMode lightmode; int8_t brightfog; int8_t lightadditivesurfaces; int8_t notexturefill; diff --git a/src/g_levellocals.h b/src/g_levellocals.h index c39da9250..3eb3e48df 100644 --- a/src/g_levellocals.h +++ b/src/g_levellocals.h @@ -47,9 +47,9 @@ struct FLevelLocals { - void Tick (); + void Tick(); void Mark(); - void AddScroller (int secnum); + void AddScroller(int secnum); void SetInterMusic(const char *nextmap); void SetMusicVolume(float v); @@ -87,7 +87,7 @@ struct FLevelLocals TArray gamenodes; node_t *headgamenode; TArray rejectmatrix; - + static const int BODYQUESIZE = 32; TObjPtr bodyque[BODYQUESIZE]; int bodyqueslot; @@ -100,7 +100,7 @@ struct FLevelLocals FDisplacementTable Displacements; FPortalBlockmap PortalBlockmap; TArray linkedPortals; // only the linked portals, this is used to speed up looking for them in P_CollectConnectedGroups. - TArray portalGroups; + TArray portalGroups; TArray linePortalSpans; FSectionContainer sections; @@ -181,7 +181,7 @@ struct FLevelLocals float MusicVolume; // Hardware render stuff that can either be set via CVAR or MAPINFO - int lightmode; + ELightMode lightmode; bool brightfog; bool lightadditivesurfaces; bool notexturefill; @@ -192,7 +192,7 @@ struct FLevelLocals node_t *HeadNode() const { - return nodes.Size() == 0? nullptr : &nodes[nodes.Size() - 1]; + return nodes.Size() == 0 ? nullptr : &nodes[nodes.Size() - 1]; } node_t *HeadGamenode() const { @@ -202,9 +202,24 @@ struct FLevelLocals // Returns true if level is loaded from saved game or is being revisited as a part of a hub bool IsReentering() const { - return savegamerestore + return savegamerestore || (info != nullptr && info->Snapshot.mBuffer != nullptr && info->isValid()); } + + bool isSoftwareLighting() const + { + return lightmode >= ELightMode::ZDoomSoftware; + } + + bool isDarkLightMode() const + { + return !!((int)lightmode & (int)ELightMode::Doom); + } + + void SetFallbackLightMode() + { + lightmode = ELightMode::Doom; + } }; extern FLevelLocals level; diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index d621b231c..e79abf0c8 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -284,7 +284,7 @@ void level_info_t::Reset() PrecacheSounds.Clear(); brightfog = -1; - lightmode = -1; + lightmode = ELightMode::NotSet; notexturefill = -1; lightadditivesurfaces = -1; skyrotatevector = FVector3(0, 0, 1); @@ -1381,9 +1381,9 @@ DEFINE_MAP_OPTION(lightmode, false) parse.ParseAssign(); parse.sc.MustGetNumber(); - if ((parse.sc.Number >= 0 && parse.sc.Number <= 4) || parse.sc.Number == 8) + if ((parse.sc.Number >= 0 && parse.sc.Number <= 4) || parse.sc.Number == 8 || parse.sc.Number == 16) { - info->lightmode = uint8_t(parse.sc.Number); + info->lightmode = ELightMode(parse.sc.Number); } else { diff --git a/src/hwrenderer/scene/hw_renderstate.cpp b/src/hwrenderer/scene/hw_renderstate.cpp index 3ead6232d..721b87fd5 100644 --- a/src/hwrenderer/scene/hw_renderstate.cpp +++ b/src/hwrenderer/scene/hw_renderstate.cpp @@ -127,7 +127,7 @@ void FRenderState::SetFog(int lightlevel, int rellight, bool fullbright, const F } else { - if ((level.lightmode == 2 || (level.lightmode >= 8 && cmap->BlendFactor > 0)) && fogcolor == 0) + if ((level.lightmode == ELightMode::Doom || (level.isSoftwareLighting() && cmap->BlendFactor > 0)) && fogcolor == 0) { float light = (float)hw_CalcLightLevel(lightlevel, rellight, false, cmap->BlendFactor); SetShaderLight(light, lightlevel); @@ -148,7 +148,7 @@ void FRenderState::SetFog(int lightlevel, int rellight, bool fullbright, const F SetFog(fogcolor, fogdensity); // Korshun: fullbright fog like in software renderer. - if (level.lightmode >= 8 && cmap->BlendFactor == 0 && level.brightfog && fogdensity != 0 && fogcolor != 0) + if (level.isSoftwareLighting() && cmap->BlendFactor == 0 && level.brightfog && fogdensity != 0 && fogcolor != 0) { SetSoftLightLevel(255); } diff --git a/src/hwrenderer/scene/hw_renderstate.h b/src/hwrenderer/scene/hw_renderstate.h index e39d25b26..d820c07ec 100644 --- a/src/hwrenderer/scene/hw_renderstate.h +++ b/src/hwrenderer/scene/hw_renderstate.h @@ -326,7 +326,7 @@ public: void SetSoftLightLevel(int llevel, int blendfactor = 0) { - if (level.lightmode >= 8 && blendfactor == 0) mLightParms[3] = llevel / 255.f; + if (level.isSoftwareLighting() && blendfactor == 0) mLightParms[3] = llevel / 255.f; else mLightParms[3] = -1.f; } diff --git a/src/hwrenderer/scene/hw_skyportal.cpp b/src/hwrenderer/scene/hw_skyportal.cpp index 83bd7de57..74edb1266 100644 --- a/src/hwrenderer/scene/hw_skyportal.cpp +++ b/src/hwrenderer/scene/hw_skyportal.cpp @@ -164,10 +164,10 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state) auto &vp = di->Viewpoint; // We have no use for Doom lighting special handling here, so disable it for this function. - int oldlightmode = ::level.lightmode; - if (::level.lightmode >= 8) + auto oldlightmode = ::level.lightmode; + if (::level.isSoftwareLighting()) { - ::level.lightmode = 2; + ::level.SetFallbackLightMode(); state.SetSoftLightLevel(-1); } diff --git a/src/hwrenderer/scene/hw_weapon.cpp b/src/hwrenderer/scene/hw_weapon.cpp index 7d0a1f3d1..dec31cc6f 100644 --- a/src/hwrenderer/scene/hw_weapon.cpp +++ b/src/hwrenderer/scene/hw_weapon.cpp @@ -106,8 +106,8 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state) void HWDrawInfo::DrawPlayerSprites(bool hudModelStep, FRenderState &state) { - int oldlightmode = level.lightmode; - if (!hudModelStep && level.lightmode >= 8) level.lightmode = 2; // Software lighting cannot handle 2D content so revert to lightmode 2 for that. + auto oldlightmode = level.lightmode; + if (!hudModelStep && level.isSoftwareLighting()) level.SetFallbackLightMode(); // Software lighting cannot handle 2D content. for (auto &hudsprite : hudsprites) { if ((!!hudsprite.mframe) == hudModelStep) @@ -260,7 +260,7 @@ static WeaponLighting GetWeaponLighting(sector_t *viewsector, const DVector3 &po l.lightlevel = hw_CalcLightLevel(l.lightlevel, getExtraLight(), true, 0); - if (level.lightmode >= 8 || l.lightlevel < 92) + if (level.isSoftwareLighting() || l.lightlevel < 92) { // Korshun: the way based on max possible light level for sector like in software renderer. double min_L = 36.0 / 31.0 - ((l.lightlevel / 255.0) * (63.0 / 31.0)); // Lightlevel in range 0-63 @@ -498,8 +498,8 @@ void HWDrawInfo::PreparePlayerSprites(sector_t * viewsector, area_t in_area) // hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change // light mode here to draw the weapon sprite. - int oldlightmode = level.lightmode; - if (level.lightmode >= 8) level.lightmode = 2; + auto oldlightmode = level.lightmode; + if (level.isSoftwareLighting()) level.SetFallbackLightMode(); for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext()) { diff --git a/src/hwrenderer/utility/hw_lighting.cpp b/src/hwrenderer/utility/hw_lighting.cpp index cee925b68..8d7298b9f 100644 --- a/src/hwrenderer/utility/hw_lighting.cpp +++ b/src/hwrenderer/utility/hw_lighting.cpp @@ -88,7 +88,7 @@ int hw_CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor if (lightlevel == 0) return 0; - bool darklightmode = (level.lightmode & 2) || (level.lightmode >= 8 && blendfactor > 0); + bool darklightmode = (level.isDarkLightMode()) || (level.isSoftwareLighting() && blendfactor > 0); if (darklightmode && lightlevel < 192 && !weapon) { @@ -130,7 +130,7 @@ PalEntry hw_CalcLightColor(int light, PalEntry pe, int blendfactor) if (blendfactor == 0) { - if (level.lightmode >= 8) + if (level.isSoftwareLighting()) { return pe; } @@ -174,10 +174,10 @@ float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, { float density; - int lightmode = level.lightmode; - if (lightmode >= 8 && blendfactor > 0) lightmode = 2; // The blendfactor feature does not work with software-style lighting. + auto lightmode = level.lightmode; + if (level.isSoftwareLighting() && blendfactor > 0) lightmode = ELightMode::Doom; // The blendfactor feature does not work with software-style lighting. - if (lightmode & 4) + if (lightmode == ELightMode::DoomLegacy) { // uses approximations of Legacy's default settings. density = level.fogdensity ? (float)level.fogdensity : 18; @@ -190,9 +190,9 @@ float hw_GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, else if ((fogcolor.d & 0xffffff) == 0) { // case 2: black fog - if ((lightmode < 8 || blendfactor > 0) && !(level.flags3 & LEVEL3_NOLIGHTFADE)) + if ((!level.isSoftwareLighting() || blendfactor > 0) && !(level.flags3 & LEVEL3_NOLIGHTFADE)) { - density = distfogtable[level.lightmode != 0][hw_ClampLight(lightlevel)]; + density = distfogtable[level.lightmode != ELightMode::LinearStandard][hw_ClampLight(lightlevel)]; } else { @@ -250,7 +250,7 @@ bool hw_CheckFog(sector_t *frontsector, sector_t *backsector) else if (level.outsidefogdensity != 0 && APART(level.info->outsidefog) != 0xff && (fogcolor.d & 0xffffff) == (level.info->outsidefog & 0xffffff)) { } - else if (level.fogdensity!=0 || (level.lightmode & 4)) + else if (level.fogdensity!=0 || level.lightmode == ELightMode::DoomLegacy) { // case 3: level has fog density set } @@ -269,7 +269,7 @@ bool hw_CheckFog(sector_t *frontsector, sector_t *backsector) { return false; } - else if (level.fogdensity!=0 || (level.lightmode & 4)) + else if (level.fogdensity!=0 || level.lightmode == ELightMode::DoomLegacy) { // case 3: level has fog density set return false; diff --git a/src/v_2ddrawer.cpp b/src/v_2ddrawer.cpp index 6b4305de9..ed76dbff2 100644 --- a/src/v_2ddrawer.cpp +++ b/src/v_2ddrawer.cpp @@ -430,7 +430,7 @@ void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, double fadelevel; // The hardware renderer's light modes 0, 1 and 4 use a linear light scale which must be used here as well. Otherwise the automap gets too dark. - if (vid_rendermode != 4 || (level.lightmode >= 2 && level.lightmode != 4)) + if (vid_rendermode != 4 || level.isDarkLightMode() || level.isSoftwareLighting()) { double map = (NUMCOLORMAPS * 2.) - ((lightlevel + 12) * (NUMCOLORMAPS / 128.)); fadelevel = clamp((map - 12) / NUMCOLORMAPS, 0.0, 1.0); From f1fe9a0286a3d2db63b4914335bc44a338cee3c1 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 15 Dec 2018 10:02:57 +0100 Subject: [PATCH 073/113] - fix vanilla light mode angle calculation --- wadsrc/static/shaders/glsl/main.fp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 8f5bb1fb6..e6ec4c63f 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -126,9 +126,9 @@ float R_WallColormap(float lightnum, float z) { // R_ScaleFromGlobalAngle calculation float projection = 160.0; // projection depends on SCREENBLOCKS!! 160 is the fullscreen value - vec3 line_v1 = pixelpos.xyz; // in vanilla this is the first curline vertex - vec3 line_normal = vWorldNormal.xyz; - float texscale = projection * clamp(dot(normalize(uCameraPos.xyz - line_v1), line_normal), 0.0, 1.0) / z; + vec2 line_v1 = pixelpos.xz; // in vanilla this is the first curline vertex + vec2 line_normal = vWorldNormal.xz; + float texscale = projection * clamp(dot(normalize(uCameraPos.xz - line_v1), line_normal), 0.0, 1.0) / z; float lightz = clamp(16.0 * texscale, 0.0, 47.0); From cd25b4be4f4667456f68aa2f3f80b09cf9903f6c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 10:04:49 +0100 Subject: [PATCH 074/113] - 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 075/113] - 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 076/113] - 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 077/113] - 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 078/113] - 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 079/113] - 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 080/113] - 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 2e927c7026d25037638c4d77e212486e5f44d6bc Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sat, 15 Dec 2018 10:13:28 -0500 Subject: [PATCH 081/113] - port texture upscaler code to truecolour --- src/swrenderer/textures/r_swtexture.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index 43d6405b2..a778456c0 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -146,8 +146,24 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra() { if (PixelsBgra.Size() == 0 || CheckModified(2)) { - FBitmap bitmap = mTexture->GetBgraBitmap(nullptr); - GenerateBgraFromBitmap(bitmap); + if (mPhysicalScale == 1) + { + FBitmap bitmap = mTexture->GetBgraBitmap(nullptr); + GenerateBgraFromBitmap(bitmap); + } + else + { + auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags); + PixelsBgra.Resize(GetWidth()*GetHeight()); + PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; + for (int y = 0; y < GetHeight(); y++) + { + for (int x = 0; x < GetWidth(); x++) + { + PixelsBgra[y + x * GetHeight()] = pe[x + y * GetWidth()]; + } + } + } } return PixelsBgra.Data(); } From 74ea9143ee2f7b79eb399bb4571be2d36c3830dc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 16:29:37 +0100 Subject: [PATCH 082/113] - 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 14e9e3ac56432632fd7310ac4e1487c97ff1e99c Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sat, 15 Dec 2018 10:50:59 -0500 Subject: [PATCH 083/113] - use software mipmaps for truecolor for scaled textures --- src/swrenderer/textures/r_swtexture.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index a778456c0..6b8814f39 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -154,7 +154,7 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra() else { auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags); - PixelsBgra.Resize(GetWidth()*GetHeight()); + CreatePixelsBgraWithMipmaps(); PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; for (int y = 0; y < GetHeight(); y++) { @@ -163,6 +163,7 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra() PixelsBgra[y + x * GetHeight()] = pe[x + y * GetWidth()]; } } + GenerateBgraMipmaps(); } } return PixelsBgra.Data(); From c105a1f670d1a9e90b4e6614296b8e9493bafd38 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 16:57:20 +0100 Subject: [PATCH 084/113] - 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 085/113] - 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 086/113] - 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 8e24a50b36d8301240e6bb118e78748da246c104 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 20:07:21 +0100 Subject: [PATCH 087/113] - let FxNop have a value type, even if it's just TypeError. --- src/scripting/backend/codegen.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/scripting/backend/codegen.h b/src/scripting/backend/codegen.h index 3876f9626..4140b9d9b 100644 --- a/src/scripting/backend/codegen.h +++ b/src/scripting/backend/codegen.h @@ -2104,6 +2104,7 @@ public: : FxExpression(EFX_Nop, p) { isresolved = true; + ValueType = TypeError; } ExpEmit Emit(VMFunctionBuilder *build) { From 091f73b833d41c5d5dfa597b713df9bbe058cc33 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 20:22:42 +0100 Subject: [PATCH 088/113] - fixed: no sprites were drawn in a sector if it only had ones in its sectorportal_thinglist. --- src/hwrenderer/scene/hw_bsp.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hwrenderer/scene/hw_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp index 39d4145f3..4daadd63f 100644 --- a/src/hwrenderer/scene/hw_bsp.cpp +++ b/src/hwrenderer/scene/hw_bsp.cpp @@ -646,7 +646,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub) sector->validcount = validcount; sector->MoreFlags |= SECMF_DRAWN; - if (gl_render_things && sector->touching_renderthings) + if (gl_render_things && (sector->touching_renderthings || sector->sectorportal_thinglist)) { if (multithread) { From 39f6489ac50d17159745bb51ceb08f729784ed26 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 20:40:17 +0100 Subject: [PATCH 089/113] - two more places where explicit allocations could be replaced. --- src/p_things.cpp | 7 +++---- src/p_user.cpp | 8 ++------ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/p_things.cpp b/src/p_things.cpp index f6d5139f6..0eb7ef5eb 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -572,23 +572,22 @@ static int SpawnableSort(const void *a, const void *b) static void DumpClassMap(FClassMap &themap) { FClassMap::Iterator it(themap); - FClassMap::Pair *pair, **allpairs; + FClassMap::Pair *pair; + TArray allpairs(themap.CountUsed(), true); int i = 0; // Sort into numerical order, since their arrangement in the map can // be in an unspecified order. - allpairs = new FClassMap::Pair *[themap.CountUsed()]; while (it.NextPair(pair)) { allpairs[i++] = pair; } - qsort(allpairs, i, sizeof(*allpairs), SpawnableSort); + qsort(allpairs.Data, i, sizeof(allpairs[0]), SpawnableSort); for (int j = 0; j < i; ++j) { pair = allpairs[j]; Printf ("%d %s\n", pair->Key, pair->Value->TypeName.GetChars()); } - delete[] allpairs; } CCMD(dumpspawnables) diff --git a/src/p_user.cpp b/src/p_user.cpp index 4bae6ee5e..6077d597c 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -429,12 +429,8 @@ void player_t::SetLogNumber (int num) } else { - int length=Wads.LumpLength(lumpnum); - char *data= new char[length+1]; - Wads.ReadLump (lumpnum, data); - data[length]=0; - SetLogText (data); - delete[] data; + auto lump = Wads.ReadLump(lumpnum); + SetLogText (lump.GetString()); } } From c92e6b03ac461ac16c13412ae414332145e60081 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 21:39:00 +0100 Subject: [PATCH 090/113] - why wasn't this saved? --- src/p_things.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_things.cpp b/src/p_things.cpp index 0eb7ef5eb..9728c691e 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -582,7 +582,7 @@ static void DumpClassMap(FClassMap &themap) { allpairs[i++] = pair; } - qsort(allpairs.Data, i, sizeof(allpairs[0]), SpawnableSort); + qsort(allpairs.Data(), i, sizeof(allpairs[0]), SpawnableSort); for (int j = 0; j < i; ++j) { pair = allpairs[j]; From 87b0567cd75ad5d1ed7086359bda4d9fd3790312 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 15 Dec 2018 23:32:49 +0100 Subject: [PATCH 091/113] - 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 092/113] - 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; } From d0ce0218052f44840b1662ff039727a245645a72 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 09:05:02 +0100 Subject: [PATCH 093/113] - fixed: Both main and worker thread were modifying the portal state. The parts in the main thread have been offloaded to a new worker job to avoid having to use a mutex to protect the portal state. --- src/hwrenderer/scene/hw_bsp.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/hwrenderer/scene/hw_bsp.cpp b/src/hwrenderer/scene/hw_bsp.cpp index 4daadd63f..732af5641 100644 --- a/src/hwrenderer/scene/hw_bsp.cpp +++ b/src/hwrenderer/scene/hw_bsp.cpp @@ -56,6 +56,7 @@ struct RenderJob WallJob, SpriteJob, ParticleJob, + PortalJob, TerminateJob // inserted when all work is done so that the worker can return. }; @@ -177,7 +178,12 @@ void HWDrawInfo::WorkerThread() RenderParticles(job->sub, front); SetupSprite.Unclock(); break; + + case RenderJob::PortalJob: + AddSubsectorToPortal((FSectorPortalGroup *)job->seg, job->sub); + break; } + } } @@ -706,16 +712,35 @@ void HWDrawInfo::DoSubsector(subsector_t * sub) // This is for portal coverage. FSectorPortalGroup *portal; + // AddSubsectorToPortal cannot be called here when using multithreaded processing, + // because the wall processing code in the worker can also modify the portal state. + // To avoid costly synchronization for every access to the portal list, + // the call to AddSubsectorToPortal will be deferred to the worker. + // (GetPortalGruop only accesses static sector data so this check can be done here, restricting the new job to the minimum possible extent.) portal = fakesector->GetPortalGroup(sector_t::ceiling); if (portal != nullptr) { - AddSubsectorToPortal(portal, sub); + if (multithread) + { + jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal); + } + else + { + AddSubsectorToPortal(portal, sub); + } } portal = fakesector->GetPortalGroup(sector_t::floor); if (portal != nullptr) { - AddSubsectorToPortal(portal, sub); + if (multithread) + { + jobQueue.AddJob(RenderJob::PortalJob, sub, (seg_t *)portal); + } + else + { + AddSubsectorToPortal(portal, sub); + } } } } From a96b86b13b97148a762f653808c805730d2b0cd0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 09:38:22 +0100 Subject: [PATCH 094/113] - fixed: sidedef-less GLWalls may not apply per-sidedef render properties. These always come from open-sector render hacks where the renderer tries to fill in some gaps --- src/hwrenderer/scene/hw_walls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hwrenderer/scene/hw_walls.cpp b/src/hwrenderer/scene/hw_walls.cpp index 70ca0f633..f50ffbe45 100644 --- a/src/hwrenderer/scene/hw_walls.cpp +++ b/src/hwrenderer/scene/hw_walls.cpp @@ -165,7 +165,7 @@ void GLWall::RenderTexturedWall(HWDrawInfo *di, FRenderState &state, int rflags) } state.SetFog(255, 0, di->isFullbrightScene(), nullptr, false); } - if (type != RENDERWALL_COLOR) + if (type != RENDERWALL_COLOR && seg->sidedef != nullptr) { auto side = seg->sidedef; auto tierndx = renderwalltotier[type]; From a38e75db00c701123251567648d37f7b1f0f89ba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 09:56:53 +0100 Subject: [PATCH 095/113] - improved error reporting for badly defined translations. This needs to be handled by the caller for all use cases because the translation parser lacks the context to do a proper error report. --- src/r_data/r_translate.cpp | 261 +++++++++++---------- src/sc_man.cpp | 2 +- src/scripting/thingdef_properties.cpp | 14 +- src/textures/formats/multipatchtexture.cpp | 11 +- 4 files changed, 150 insertions(+), 138 deletions(-) diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index c11f9be94..5264095e7 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -633,148 +633,140 @@ bool FRemapTable::AddToTranslation(const char *range) sc.OpenMem("translation", range, int(strlen(range))); sc.SetCMode(true); - try + sc.MustGetToken(TK_IntConst); + start = sc.Number; + sc.MustGetToken(':'); + sc.MustGetToken(TK_IntConst); + end = sc.Number; + sc.MustGetToken('='); + if (start < 0 || start > 255 || end < 0 || end > 255) { + sc.ScriptError("Palette index out of range"); + return false; + } + + sc.MustGetAnyToken(); + + if (sc.TokenType == '[') + { + // translation using RGB values + int r1,g1,b1,r2,g2,b2; + sc.MustGetToken(TK_IntConst); - start = sc.Number; + r1 = sc.Number; + sc.MustGetToken(','); + + sc.MustGetToken(TK_IntConst); + g1 = sc.Number; + sc.MustGetToken(','); + + sc.MustGetToken(TK_IntConst); + b1 = sc.Number; + sc.MustGetToken(']'); sc.MustGetToken(':'); + sc.MustGetToken('['); + sc.MustGetToken(TK_IntConst); - end = sc.Number; - sc.MustGetToken('='); - if (start < 0 || start > 255 || end < 0 || end > 255) - { - sc.ScriptError("Palette index out of range"); - return false; - } + r2 = sc.Number; + sc.MustGetToken(','); + + sc.MustGetToken(TK_IntConst); + g2 = sc.Number; + sc.MustGetToken(','); + + sc.MustGetToken(TK_IntConst); + b2 = sc.Number; + sc.MustGetToken(']'); + + return AddColorRange(start, end, r1, g1, b1, r2, g2, b2); + } + else if (sc.TokenType == '%') + { + // translation using RGB values + double r1,g1,b1,r2,g2,b2; + + sc.MustGetToken('['); + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + r1 = sc.Float; + sc.MustGetToken(','); sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + g1 = sc.Float; + sc.MustGetToken(','); - if (sc.TokenType == '[') - { - // translation using RGB values - int r1,g1,b1,r2,g2,b2; + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + b1 = sc.Float; + sc.MustGetToken(']'); + sc.MustGetToken(':'); + sc.MustGetToken('['); - sc.MustGetToken(TK_IntConst); - r1 = sc.Number; - sc.MustGetToken(','); + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + r2 = sc.Float; + sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - g1 = sc.Number; - sc.MustGetToken(','); + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + g2 = sc.Float; + sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - b1 = sc.Number; - sc.MustGetToken(']'); - sc.MustGetToken(':'); - sc.MustGetToken('['); + sc.MustGetAnyToken(); + if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); + b2 = sc.Float; + sc.MustGetToken(']'); - sc.MustGetToken(TK_IntConst); - r2 = sc.Number; - sc.MustGetToken(','); - - sc.MustGetToken(TK_IntConst); - g2 = sc.Number; - sc.MustGetToken(','); - - sc.MustGetToken(TK_IntConst); - b2 = sc.Number; - sc.MustGetToken(']'); - - return AddColorRange(start, end, r1, g1, b1, r2, g2, b2); - } - else if (sc.TokenType == '%') - { - // translation using RGB values - double r1,g1,b1,r2,g2,b2; - - sc.MustGetToken('['); - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - r1 = sc.Float; - sc.MustGetToken(','); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - g1 = sc.Float; - sc.MustGetToken(','); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - b1 = sc.Float; - sc.MustGetToken(']'); - sc.MustGetToken(':'); - sc.MustGetToken('['); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - r2 = sc.Float; - sc.MustGetToken(','); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - g2 = sc.Float; - sc.MustGetToken(','); - - sc.MustGetAnyToken(); - if (sc.TokenType != TK_IntConst) sc.TokenMustBe(TK_FloatConst); - b2 = sc.Float; - sc.MustGetToken(']'); - - return AddDesaturation(start, end, r1, g1, b1, r2, g2, b2); - } - else if (sc.TokenType == '#') - { - // Colourise translation - int r, g, b; - sc.MustGetToken('['); - sc.MustGetToken(TK_IntConst); - r = sc.Number; - sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - g = sc.Number; - sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - b = sc.Number; - sc.MustGetToken(']'); - - return AddColourisation(start, end, r, g, b); - } - else if (sc.TokenType == '@') - { - // Tint translation - int a, r, g, b; - - sc.MustGetToken(TK_IntConst); - a = sc.Number; - sc.MustGetToken('['); - sc.MustGetToken(TK_IntConst); - r = sc.Number; - sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - g = sc.Number; - sc.MustGetToken(','); - sc.MustGetToken(TK_IntConst); - b = sc.Number; - sc.MustGetToken(']'); - - return AddTint(start, end, r, g, b, a); - } - else - { - int pal1, pal2; - - sc.TokenMustBe(TK_IntConst); - pal1 = sc.Number; - sc.MustGetToken(':'); - sc.MustGetToken(TK_IntConst); - pal2 = sc.Number; - return AddIndexRange(start, end, pal1, pal2); - } + return AddDesaturation(start, end, r1, g1, b1, r2, g2, b2); } - catch (CRecoverableError &err) + else if (sc.TokenType == '#') { - Printf("Error in translation '%s':\n%s\n", range, err.GetMessage()); - return false; + // Colourise translation + int r, g, b; + sc.MustGetToken('['); + sc.MustGetToken(TK_IntConst); + r = sc.Number; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + g = sc.Number; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + b = sc.Number; + sc.MustGetToken(']'); + + return AddColourisation(start, end, r, g, b); + } + else if (sc.TokenType == '@') + { + // Tint translation + int a, r, g, b; + + sc.MustGetToken(TK_IntConst); + a = sc.Number; + sc.MustGetToken('['); + sc.MustGetToken(TK_IntConst); + r = sc.Number; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + g = sc.Number; + sc.MustGetToken(','); + sc.MustGetToken(TK_IntConst); + b = sc.Number; + sc.MustGetToken(']'); + + return AddTint(start, end, r, g, b, a); + } + else + { + int pal1, pal2; + + sc.TokenMustBe(TK_IntConst); + pal1 = sc.Number; + sc.MustGetToken(':'); + sc.MustGetToken(TK_IntConst); + pal2 = sc.Number; + return AddIndexRange(start, end, pal1, pal2); } } @@ -1529,7 +1521,16 @@ void R_ParseTrnslate() do { sc.MustGetToken(TK_StringConst); - NewTranslation.AddToTranslation(sc.String); + + try + { + NewTranslation.AddToTranslation(sc.String); + } + catch (CRecoverableError &err) + { + sc.ScriptMessage("Error in translation '%s':\n" TEXTCOLOR_YELLOW "%s\n", sc.String, err.GetMessage()); + } + } while (sc.CheckToken(',')); int trans = NewTranslation.StoreTranslation(TRANSLATION_Custom); diff --git a/src/sc_man.cpp b/src/sc_man.cpp index 7eb6b3c3a..f1b9b9267 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -1120,7 +1120,7 @@ void FScanner::ScriptMessage (const char *message, ...) va_end (arglist); } - Printf (TEXTCOLOR_RED "Script error, \"%s\" line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), + Printf (TEXTCOLOR_RED "Script error, \"%s\"" TEXTCOLOR_RED "line %d:\n" TEXTCOLOR_RED "%s\n", ScriptName.GetChars(), AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); } diff --git a/src/scripting/thingdef_properties.cpp b/src/scripting/thingdef_properties.cpp index f62ad91b7..d54684a48 100644 --- a/src/scripting/thingdef_properties.cpp +++ b/src/scripting/thingdef_properties.cpp @@ -729,7 +729,6 @@ DEFINE_PROPERTY(translation, L, Actor) else { FRemapTable CurrentTranslation; - bool success = true; CurrentTranslation.MakeIdentity(); for(int i = 1; i < PROP_PARM_COUNT; i++) @@ -744,14 +743,17 @@ DEFINE_PROPERTY(translation, L, Actor) else { // parse all ranges to get a complete list of errors, if more than one range fails. - success |= CurrentTranslation.AddToTranslation(str); + try + { + CurrentTranslation.AddToTranslation(str); + } + catch (CRecoverableError &err) + { + bag.ScriptPosition.Message(MSG_WARNING, "Error in translation '%s':\n" TEXTCOLOR_CYAN "%s\n", str, err.GetMessage()); + } } } defaults->Translation = CurrentTranslation.StoreTranslation (TRANSLATION_Decorate); - if (!success) - { - bag.ScriptPosition.Message(MSG_WARNING, "Failed to parse translation"); - } } } diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index fb9381808..78fcca56b 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 "doomerrors.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 @@ -954,7 +955,15 @@ void FMultiPatchTexture::ParsePatch(FScanner &sc, TexPart & part, TexInit &init) do { sc.MustGetString(); - part.Translation->AddToTranslation(sc.String); + + try + { + part.Translation->AddToTranslation(sc.String); + } + catch (CRecoverableError &err) + { + sc.ScriptMessage("Error in translation '%s':\n" TEXTCOLOR_YELLOW "%s\n", sc.String, err.GetMessage()); + } } while (sc.CheckString(",")); } From 881fc89fe8eb14e824933068ed4d70139f735332 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 11:29:22 +0100 Subject: [PATCH 096/113] - removed redundant std::move. --- src/gl/textures/gl_hwtexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/textures/gl_hwtexture.cpp b/src/gl/textures/gl_hwtexture.cpp index 01bfdf1b6..9c5f7b894 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 = std::move(tex->CreateTexBuffer(translation, flags | CTF_ProcessData)); + texbuffer = tex->CreateTexBuffer(translation, flags | CTF_ProcessData); w = texbuffer.mWidth; h = texbuffer.mHeight; } From 88751a320c30088b39dcb1aaccb6412a8378c650 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 16 Dec 2018 11:31:05 +0100 Subject: [PATCH 097/113] - fix sky drawers not staying within their numa node --- src/swrenderer/drawers/r_draw_pal.cpp | 37 +++++++++++----------- src/swrenderer/drawers/r_draw_sky32.h | 37 +++++++++++----------- src/swrenderer/drawers/r_draw_sky32_sse2.h | 37 +++++++++++----------- src/swrenderer/drawers/r_thread.cpp | 9 ++---- 4 files changed, 59 insertions(+), 61 deletions(-) diff --git a/src/swrenderer/drawers/r_draw_pal.cpp b/src/swrenderer/drawers/r_draw_pal.cpp index b9501d157..9af01cffb 100644 --- a/src/swrenderer/drawers/r_draw_pal.cpp +++ b/src/swrenderer/drawers/r_draw_pal.cpp @@ -551,7 +551,6 @@ namespace swrenderer void DrawSingleSky1PalCommand::Execute(DrawerThread *thread) { uint8_t *dest = args.Dest(); - int count = args.Count(); int pitch = args.Viewport()->RenderTarget->GetPitch(); const uint8_t *source0 = args.FrontTexturePixels(); int textureheight0 = args.FrontTextureHeight(); @@ -559,6 +558,25 @@ namespace swrenderer int32_t frac = args.TextureVPos(); int32_t fracstep = args.TextureVStep(); + if (!args.FadeSky()) + { + int count = thread->count_for_thread(args.DestY(), args.Count()); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + *dest = source0[sample_index]; + dest += pitch; + frac += fracstep; + } + + return; + } + + int num_cores = thread->num_cores; + int skipped = thread->skipped_by_thread(args.DestY()); + int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores; + // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: int start_fade = 2; // How fast it should fade out int fade_length = (1 << (24 - start_fade)); @@ -571,28 +589,11 @@ namespace swrenderer start_fadebottom_y = clamp(start_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count); - int num_cores = thread->num_cores; - int skipped = thread->skipped_by_thread(args.DestY()); dest = thread->dest_for_thread(args.DestY(), pitch, dest); frac += fracstep * skipped; fracstep *= num_cores; pitch *= num_cores; - if (!args.FadeSky()) - { - count = thread->count_for_thread(args.DestY(), count); - - for (int index = 0; index < count; index++) - { - uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; - *dest = source0[sample_index]; - dest += pitch; - frac += fracstep; - } - - return; - } - uint32_t solid_top = args.SolidTopColor(); uint32_t solid_bottom = args.SolidBottomColor(); diff --git a/src/swrenderer/drawers/r_draw_sky32.h b/src/swrenderer/drawers/r_draw_sky32.h index 59c8826fa..864002446 100644 --- a/src/swrenderer/drawers/r_draw_sky32.h +++ b/src/swrenderer/drawers/r_draw_sky32.h @@ -39,7 +39,6 @@ namespace swrenderer void Execute(DrawerThread *thread) override { uint32_t *dest = (uint32_t *)args.Dest(); - int count = args.Count(); int pitch = args.Viewport()->RenderTarget->GetPitch(); const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels(); int textureheight0 = args.FrontTextureHeight(); @@ -51,6 +50,25 @@ namespace swrenderer uint32_t solid_bottom = args.SolidBottomColor(); bool fadeSky = args.FadeSky(); + if (!fadeSky) + { + int count = thread->count_for_thread(args.DestY(), args.Count()); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + *dest = source0[sample_index]; + dest += pitch; + frac += fracstep; + } + + return; + } + + int num_cores = thread->num_cores; + int skipped = thread->skipped_by_thread(args.DestY()); + int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores; + // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: int start_fade = 2; // How fast it should fade out int fade_length = (1 << (24 - start_fade)); @@ -63,28 +81,11 @@ namespace swrenderer start_fadebottom_y = clamp(start_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count); - int num_cores = thread->num_cores; - int skipped = thread->skipped_by_thread(args.DestY()); dest = thread->dest_for_thread(args.DestY(), pitch, dest); frac += fracstep * skipped; fracstep *= num_cores; pitch *= num_cores; - if (!fadeSky) - { - count = thread->count_for_thread(args.DestY(), count); - - for (int index = 0; index < count; index++) - { - uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; - *dest = source0[sample_index]; - dest += pitch; - frac += fracstep; - } - - return; - } - BgraColor solid_top_fill = solid_top; BgraColor solid_bottom_fill = solid_bottom; diff --git a/src/swrenderer/drawers/r_draw_sky32_sse2.h b/src/swrenderer/drawers/r_draw_sky32_sse2.h index 401d5bad1..56fd50300 100644 --- a/src/swrenderer/drawers/r_draw_sky32_sse2.h +++ b/src/swrenderer/drawers/r_draw_sky32_sse2.h @@ -38,7 +38,6 @@ namespace swrenderer void Execute(DrawerThread *thread) override { uint32_t *dest = (uint32_t *)args.Dest(); - int count = args.Count(); int pitch = args.Viewport()->RenderTarget->GetPitch(); const uint32_t *source0 = (const uint32_t *)args.FrontTexturePixels(); int textureheight0 = args.FrontTextureHeight(); @@ -50,6 +49,25 @@ namespace swrenderer uint32_t solid_bottom = args.SolidBottomColor(); bool fadeSky = args.FadeSky(); + if (!fadeSky) + { + int count = thread->count_for_thread(args.DestY(), args.Count()); + + for (int index = 0; index < count; index++) + { + uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; + *dest = source0[sample_index]; + dest += pitch; + frac += fracstep; + } + + return; + } + + int num_cores = thread->num_cores; + int skipped = thread->skipped_by_thread(args.DestY()); + int count = skipped + thread->count_for_thread(args.DestY(), args.Count()) * num_cores; + // Find bands for top solid color, top fade, center textured, bottom fade, bottom solid color: int start_fade = 2; // How fast it should fade out int fade_length = (1 << (24 - start_fade)); @@ -62,28 +80,11 @@ namespace swrenderer start_fadebottom_y = clamp(start_fadebottom_y, 0, count); end_fadebottom_y = clamp(end_fadebottom_y, 0, count); - int num_cores = thread->num_cores; - int skipped = thread->skipped_by_thread(args.DestY()); dest = thread->dest_for_thread(args.DestY(), pitch, dest); frac += fracstep * skipped; fracstep *= num_cores; pitch *= num_cores; - if (!fadeSky) - { - count = thread->count_for_thread(args.DestY(), count); - - for (int index = 0; index < count; index++) - { - uint32_t sample_index = (((((uint32_t)frac) << 8) >> FRACBITS) * textureheight0) >> FRACBITS; - *dest = source0[sample_index]; - dest += pitch; - frac += fracstep; - } - - return; - } - __m128i solid_top_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_top), _mm_setzero_si128()); __m128i solid_bottom_fill = _mm_unpacklo_epi8(_mm_cvtsi32_si128(solid_bottom), _mm_setzero_si128()); diff --git a/src/swrenderer/drawers/r_thread.cpp b/src/swrenderer/drawers/r_thread.cpp index 31a6f1915..5aa157f27 100644 --- a/src/swrenderer/drawers/r_thread.cpp +++ b/src/swrenderer/drawers/r_thread.cpp @@ -140,6 +140,8 @@ void DrawerThreads::WorkerMain(DrawerThread *thread) // Grab the commands DrawerCommandQueuePtr list = active_commands[thread->current_queue]; thread->current_queue++; + thread->numa_start_y = thread->numa_node * viewheight / thread->num_numa_nodes; + thread->numa_end_y = (thread->numa_node + 1) * viewheight / thread->num_numa_nodes; start_lock.unlock(); // Do the work: @@ -206,8 +208,6 @@ void DrawerThreads::StartThreads() thread->num_cores = I_GetNumaNodeThreadCount(numaNode); thread->numa_node = numaNode; thread->num_numa_nodes = I_GetNumaNodeCount(); - thread->numa_start_y = numaNode * viewheight / I_GetNumaNodeCount(); - thread->numa_end_y = (numaNode + 1) * viewheight / I_GetNumaNodeCount(); thread->thread = std::thread([=]() { queue->WorkerMain(thread); }); I_SetThreadNumaNode(thread->thread, numaNode); } @@ -223,8 +223,6 @@ void DrawerThreads::StartThreads() thread->num_cores = num_threads; thread->numa_node = 0; thread->num_numa_nodes = 1; - thread->numa_start_y = 0; - thread->numa_end_y = viewheight; thread->thread = std::thread([=]() { queue->WorkerMain(thread); }); I_SetThreadNumaNode(thread->thread, 0); } @@ -288,7 +286,4 @@ void MemcpyCommand::Execute(DrawerThread *thread) d += dstep; s += sstep; } - - thread->numa_start_y = thread->numa_node * viewheight / thread->num_numa_nodes; - thread->numa_end_y = (thread->numa_node + 1) * viewheight / thread->num_numa_nodes; } From cc52f893728b0b4eedacda7cf6ef26cc3618c3bc Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 12:05:28 +0100 Subject: [PATCH 098/113] - fixed: For non-persistent buffers, sprite vertices need to be recalculated in the splitter code of the translucent sorter. --- src/hwrenderer/scene/hw_drawlist.cpp | 14 ++++++++++++-- src/hwrenderer/scene/hw_drawlist.h | 2 +- src/hwrenderer/scene/hw_sprites.cpp | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/hwrenderer/scene/hw_drawlist.cpp b/src/hwrenderer/scene/hw_drawlist.cpp index 067c5dee5..0cf6a8010 100644 --- a/src/hwrenderer/scene/hw_drawlist.cpp +++ b/src/hwrenderer/scene/hw_drawlist.cpp @@ -483,7 +483,7 @@ inline double CalcIntersectionVertex(GLSprite *s, GLWall * w2) return ((ay - cy)*(dx - cx) - (ax - cx)*(dy - cy)) / ((bx - ax)*(dy - cy) - (by - ay)*(dx - cx)); } -void HWDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) +void HWDrawList::SortSpriteIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort) { GLWall *wh= walls[drawitems[head->itemindex].index]; GLSprite * ss= sprites[drawitems[sort->itemindex].index]; @@ -560,6 +560,16 @@ void HWDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort) head->AddToLeft(sort); head->AddToRight(sort2); } + if (screen->BuffersArePersistent()) + { + s->vertexindex = ss->vertexindex = -1; + } + else + { + s->CreateVertices(di); + ss->CreateVertices(di); + } + } } @@ -667,7 +677,7 @@ SortNode * HWDrawList::DoSort(HWDrawInfo *di, SortNode * head) break; case GLDIT_SPRITE: - SortSpriteIntoWall(head,node); + SortSpriteIntoWall(di, head, node); break; case GLDIT_FLAT: break; diff --git a/src/hwrenderer/scene/hw_drawlist.h b/src/hwrenderer/scene/hw_drawlist.h index 303da06fb..66ae468ed 100644 --- a/src/hwrenderer/scene/hw_drawlist.h +++ b/src/hwrenderer/scene/hw_drawlist.h @@ -101,7 +101,7 @@ public: void SortWallIntoPlane(SortNode * head,SortNode * sort); void SortSpriteIntoPlane(SortNode * head,SortNode * sort); void SortWallIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort); - void SortSpriteIntoWall(SortNode * head,SortNode * sort); + void SortSpriteIntoWall(HWDrawInfo *di, SortNode * head,SortNode * sort); int CompareSprites(SortNode * a,SortNode * b); SortNode * SortSpriteList(SortNode * head); SortNode * DoSort(HWDrawInfo *di, SortNode * head); diff --git a/src/hwrenderer/scene/hw_sprites.cpp b/src/hwrenderer/scene/hw_sprites.cpp index c3911b460..f8c716686 100644 --- a/src/hwrenderer/scene/hw_sprites.cpp +++ b/src/hwrenderer/scene/hw_sprites.cpp @@ -244,6 +244,7 @@ void GLSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent) { state.SetNormal(0, 0, 0); + if (screen->BuffersArePersistent()) { CreateVertices(di); From e776dbce556b847560e8da877c25b74f74b101ce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 13:33:42 +0100 Subject: [PATCH 099/113] - use TArrays for MD3 storage. --- src/r_data/models/models.h | 50 ++++--------- src/r_data/models/models_md3.cpp | 124 ++++++++++++++----------------- 2 files changed, 71 insertions(+), 103 deletions(-) diff --git a/src/r_data/models/models.h b/src/r_data/models/models.h index a6b8bf65b..2f917e228 100644 --- a/src/r_data/models/models.h +++ b/src/r_data/models/models.h @@ -309,40 +309,23 @@ class FMD3Model : public FModel struct MD3Surface { - int numVertices; - int numTriangles; - int numSkins; + unsigned numVertices; + unsigned numTriangles; + unsigned numSkins; - FTextureID * skins; - MD3Triangle * tris; - MD3TexCoord * texcoords; - MD3Vertex * vertices; + TArray Skins; + TArray Tris; + TArray Texcoords; + TArray Vertices; - unsigned int vindex; // contains numframes arrays of vertices - unsigned int iindex; - - MD3Surface() - { - tris=NULL; - vertices=NULL; - texcoords=NULL; - vindex = iindex = UINT_MAX; - } - - ~MD3Surface() - { - if (skins) delete [] skins; - UnloadGeometry(); - } + unsigned int vindex = UINT_MAX; // contains numframes arrays of vertices + unsigned int iindex = UINT_MAX; void UnloadGeometry() { - if (tris) delete [] tris; - if (vertices) delete [] vertices; - if (texcoords) delete [] texcoords; - tris = NULL; - vertices = NULL; - texcoords = NULL; + Tris.Reset(); + Vertices.Reset(); + Texcoords.Reset(); } }; @@ -354,17 +337,14 @@ class FMD3Model : public FModel float origin[3]; }; - int numFrames; int numTags; - int numSurfaces; int mLumpNum; - MD3Frame * frames; - MD3Surface * surfaces; + TArray Frames; + TArray Surfaces; public: - FMD3Model() { } - virtual ~FMD3Model(); + FMD3Model() = default; virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length); virtual int FindFrame(const char * name); diff --git a/src/r_data/models/models_md3.cpp b/src/r_data/models/models_md3.cpp index 67fcb38ef..49efceb4f 100644 --- a/src/r_data/models/models_md3.cpp +++ b/src/r_data/models/models_md3.cpp @@ -129,26 +129,27 @@ bool FMD3Model::Load(const char * path, int lumpnum, const char * buffer, int le { md3_header_t * hdr = (md3_header_t *)buffer; - numFrames = LittleLong(hdr->Num_Frames); + auto numFrames = LittleLong(hdr->Num_Frames); + auto numSurfaces = LittleLong(hdr->Num_Surfaces); + numTags = LittleLong(hdr->Num_Tags); - numSurfaces = LittleLong(hdr->Num_Surfaces); md3_frame_t * frm = (md3_frame_t*)(buffer + LittleLong(hdr->Ofs_Frames)); - frames = new MD3Frame[numFrames]; - for (int i = 0; i < numFrames; i++) + Frames.Resize(numFrames); + for (unsigned i = 0; i < numFrames; i++) { - strncpy(frames[i].Name, frm[i].Name, 16); - for (int j = 0; j < 3; j++) frames[i].origin[j] = frm[i].localorigin[j]; + strncpy(Frames[i].Name, frm[i].Name, 16); + for (int j = 0; j < 3; j++) Frames[i].origin[j] = frm[i].localorigin[j]; } md3_surface_t * surf = (md3_surface_t*)(buffer + LittleLong(hdr->Ofs_Surfaces)); - surfaces = new MD3Surface[numSurfaces]; + Surfaces.Resize(numSurfaces); - for (int i = 0; i < numSurfaces; i++) + for (unsigned i = 0; i < numSurfaces; i++) { - MD3Surface * s = &surfaces[i]; + MD3Surface * s = &Surfaces[i]; md3_surface_t * ss = surf; surf = (md3_surface_t *)(((char*)surf) + LittleLong(surf->Ofs_End)); @@ -159,17 +160,17 @@ bool FMD3Model::Load(const char * path, int lumpnum, const char * buffer, int le // copy shaders (skins) md3_shader_t * shader = (md3_shader_t*)(((char*)ss) + LittleLong(ss->Ofs_Shaders)); - s->skins = new FTextureID[s->numSkins]; + s->Skins.Resize(s->numSkins); - for (int i = 0; i < s->numSkins; i++) + for (unsigned i = 0; i < s->numSkins; i++) { // [BB] According to the MD3 spec, Name is supposed to include the full path. // ... and since some tools seem to output backslashes, these need to be replaced with forward slashes to work. FixPathSeperator(shader[i].Name); - s->skins[i] = LoadSkin("", shader[i].Name); + s->Skins[i] = LoadSkin("", shader[i].Name); // [BB] Fall back and check if Name is relative. - if (!s->skins[i].isValid()) - s->skins[i] = LoadSkin(path, shader[i].Name); + if (!s->Skins[i].isValid()) + s->Skins[i] = LoadSkin(path, shader[i].Name); } } mLumpNum = lumpnum; @@ -189,42 +190,42 @@ void FMD3Model::LoadGeometry() md3_header_t * hdr = (md3_header_t *)buffer; md3_surface_t * surf = (md3_surface_t*)(buffer + LittleLong(hdr->Ofs_Surfaces)); - for(int i=0;iOfs_End)); // copy triangle indices - md3_triangle_t * tris = (md3_triangle_t*)(((char*)ss)+LittleLong(ss->Ofs_Triangles)); - s->tris = new MD3Triangle[s->numTriangles]; + md3_triangle_t * tris = (md3_triangle_t*)(((char*)ss) + LittleLong(ss->Ofs_Triangles)); + s->Tris.Resize(s->numTriangles); - for(int i=0;inumTriangles;i++) for (int j=0;j<3;j++) + for (unsigned i = 0; i < s->numTriangles; i++) for (int j = 0; j < 3; j++) { - s->tris[i].VertIndex[j]=LittleLong(tris[i].vt_index[j]); + s->Tris[i].VertIndex[j] = LittleLong(tris[i].vt_index[j]); } // Load texture coordinates - md3_texcoord_t * tc = (md3_texcoord_t*)(((char*)ss)+LittleLong(ss->Ofs_Texcoord)); - s->texcoords = new MD3TexCoord[s->numVertices]; + md3_texcoord_t * tc = (md3_texcoord_t*)(((char*)ss) + LittleLong(ss->Ofs_Texcoord)); + s->Texcoords.Resize(s->numVertices); - for(int i=0;inumVertices;i++) + for (unsigned i = 0; i < s->numVertices; i++) { - s->texcoords[i].s = tc[i].s; - s->texcoords[i].t = tc[i].t; + s->Texcoords[i].s = tc[i].s; + s->Texcoords[i].t = tc[i].t; } // Load vertices and texture coordinates - md3_vertex_t * vt = (md3_vertex_t*)(((char*)ss)+LittleLong(ss->Ofs_XYZNormal)); - s->vertices = new MD3Vertex[s->numVertices * numFrames]; + md3_vertex_t * vt = (md3_vertex_t*)(((char*)ss) + LittleLong(ss->Ofs_XYZNormal)); + s->Vertices.Resize(s->numVertices * Frames.Size()); - for(int i=0;inumVertices * numFrames;i++) + for (unsigned i = 0; i < s->numVertices * Frames.Size(); i++) { - s->vertices[i].x = LittleShort(vt[i].x)/64.f; - s->vertices[i].y = LittleShort(vt[i].y)/64.f; - s->vertices[i].z = LittleShort(vt[i].z)/64.f; - UnpackVector( LittleShort(vt[i].n), s->vertices[i].nx, s->vertices[i].ny, s->vertices[i].nz); + s->Vertices[i].x = LittleShort(vt[i].x) / 64.f; + s->Vertices[i].y = LittleShort(vt[i].y) / 64.f; + s->Vertices[i].z = LittleShort(vt[i].z) / 64.f; + UnpackVector(LittleShort(vt[i].n), s->Vertices[i].nx, s->Vertices[i].ny, s->Vertices[i].nz); } } } @@ -244,14 +245,14 @@ void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer) unsigned int vbufsize = 0; unsigned int ibufsize = 0; - for (int i = 0; i < numSurfaces; i++) + for (unsigned i = 0; i < Surfaces.Size(); i++) { - MD3Surface * surf = &surfaces[i]; - vbufsize += numFrames * surf->numVertices; + MD3Surface * surf = &Surfaces[i]; + vbufsize += Frames.Size() * surf->numVertices; ibufsize += 3 * surf->numTriangles; } - auto vbuf = renderer->CreateVertexBuffer(true, numFrames == 1); + auto vbuf = renderer->CreateVertexBuffer(true, Frames.Size() == 1); SetVertexBuffer(renderer, vbuf); FModelVertex *vertptr = vbuf->LockVertexBuffer(vbufsize); @@ -261,28 +262,28 @@ void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer) unsigned int vindex = 0, iindex = 0; - for (int i = 0; i < numSurfaces; i++) + for (unsigned i = 0; i < Surfaces.Size(); i++) { - MD3Surface * surf = &surfaces[i]; + MD3Surface * surf = &Surfaces[i]; surf->vindex = vindex; surf->iindex = iindex; - for (int j = 0; j < numFrames * surf->numVertices; j++) + for (unsigned j = 0; j < Frames.Size() * surf->numVertices; j++) { - MD3Vertex* vert = surf->vertices + j; + MD3Vertex* vert = &surf->Vertices[j]; FModelVertex *bvert = &vertptr[vindex++]; int tc = j % surf->numVertices; - bvert->Set(vert->x, vert->z, vert->y, surf->texcoords[tc].s, surf->texcoords[tc].t); + bvert->Set(vert->x, vert->z, vert->y, surf->Texcoords[tc].s, surf->Texcoords[tc].t); bvert->SetNormal(vert->nx, vert->nz, vert->ny); } - for (int k = 0; k < surf->numTriangles; k++) + for (unsigned k = 0; k < surf->numTriangles; k++) { for (int l = 0; l < 3; l++) { - indxptr[iindex++] = surf->tris[k].VertIndex[l]; + indxptr[iindex++] = surf->Tris[k].VertIndex[l]; } } surf->UnloadGeometry(); @@ -301,19 +302,19 @@ void FMD3Model::BuildVertexBuffer(FModelRenderer *renderer) void FMD3Model::AddSkins(uint8_t *hitlist) { - for (int i = 0; i < numSurfaces; i++) + for (unsigned i = 0; i < Surfaces.Size(); i++) { if (curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].isValid()) { hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].GetIndex()] |= FTextureManager::HIT_Flat; } - MD3Surface * surf = &surfaces[i]; - for (int j = 0; j < surf->numSkins; j++) + MD3Surface * surf = &Surfaces[i]; + for (unsigned j = 0; j < surf->numSkins; j++) { - if (surf->skins[j].isValid()) + if (surf->Skins[j].isValid()) { - hitlist[surf->skins[j].GetIndex()] |= FTextureManager::HIT_Flat; + hitlist[surf->Skins[j].GetIndex()] |= FTextureManager::HIT_Flat; } } } @@ -327,9 +328,9 @@ void FMD3Model::AddSkins(uint8_t *hitlist) int FMD3Model::FindFrame(const char * name) { - for (int i=0;i=numFrames || frameno2>=numFrames) return; + if ((unsigned)frameno >= Frames.Size() || (unsigned)frameno2 >= Frames.Size()) return; renderer->SetInterpolation(inter); - for(int i=0;isurfaceskinIDs[curMDLIndex][i], true); } - else if(surf->numSkins > 0 && surf->skins[0].isValid()) + else if (surf->numSkins > 0 && surf->Skins[0].isValid()) { - surfaceSkin = TexMan.GetTexture(surf->skins[0], true); + surfaceSkin = TexMan.GetTexture(surf->Skins[0], true); } if (!surfaceSkin) @@ -376,16 +377,3 @@ void FMD3Model::RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame renderer->SetInterpolation(0.f); } -//=========================================================================== -// -// -// -//=========================================================================== - -FMD3Model::~FMD3Model() -{ - if (frames) delete [] frames; - if (surfaces) delete [] surfaces; - frames = nullptr; - surfaces = nullptr; -} From eaf1c4f1e299bd6adebe506b1b014b5907d9fdb5 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 16 Dec 2018 14:34:44 +0100 Subject: [PATCH 100/113] - implement the physical texture scaling at the drawer transition level as the frontend of the software renderers do not even need to know the textures are scaled --- src/swrenderer/line/r_line.cpp | 12 +-- src/swrenderer/line/r_walldraw.cpp | 13 +-- src/swrenderer/plane/r_flatplane.cpp | 10 +- src/swrenderer/plane/r_flatplane.h | 1 + src/swrenderer/plane/r_skyplane.cpp | 12 +-- src/swrenderer/plane/r_slopeplane.cpp | 3 + src/swrenderer/textures/r_swtexture.cpp | 102 ++++++++++----------- src/swrenderer/textures/r_swtexture.h | 20 ++-- src/swrenderer/viewport/r_skydrawer.cpp | 20 ++-- src/swrenderer/viewport/r_skydrawer.h | 4 +- src/swrenderer/viewport/r_spandrawer.cpp | 10 +- src/swrenderer/viewport/r_spritedrawer.cpp | 18 ++-- 12 files changed, 118 insertions(+), 107 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 11ce9dc19..9083f9ec4 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -858,7 +858,7 @@ namespace swrenderer } else { - mTopPart.TextureMid += rowoffset * mTopPart.Texture->GetPhysicalScale(); + mTopPart.TextureMid += rowoffset; } } @@ -918,7 +918,7 @@ namespace swrenderer { // rowoffset is added outside the multiply so that it positions the texture // by texels instead of world units. - mMiddlePart.TextureMid += rowoffset * mMiddlePart.Texture->GetPhysicalScale(); + mMiddlePart.TextureMid += rowoffset; } } @@ -983,7 +983,7 @@ namespace swrenderer } else { - mBottomPart.TextureMid += rowoffset * mBottomPart.Texture->GetPhysicalScale(); + mBottomPart.TextureMid += rowoffset; } } @@ -1158,7 +1158,7 @@ namespace swrenderer } else { - offset = mTopPart.TextureOffsetU * mTopPart.Texture->GetPhysicalScale(); + offset = mTopPart.TextureOffsetU; } if (xscale < 0) { @@ -1205,7 +1205,7 @@ namespace swrenderer } else { - offset = mMiddlePart.TextureOffsetU * mMiddlePart.Texture->GetPhysicalScale(); + offset = mMiddlePart.TextureOffsetU; } if (xscale < 0) { @@ -1253,7 +1253,7 @@ namespace swrenderer } else { - offset = mBottomPart.TextureOffsetU * mBottomPart.Texture->GetPhysicalScale(); + offset = mBottomPart.TextureOffsetU; } if (xscale < 0) { diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 0dce2236e..4b97bd869 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -57,10 +57,11 @@ namespace swrenderer WallSampler::WallSampler(RenderViewport *viewport, int y1, double texturemid, float swal, double yrepeat, fixed_t xoffset, double xmagnitude, FSoftwareTexture *texture) { xoffset += FLOAT2FIXED(xmagnitude * 0.5); + xoffset *= texture->GetPhysicalScale(); if (!viewport->RenderTarget->IsBgra()) { - height = texture->GetHeight(); + height = texture->GetPhysicalHeight(); int uv_fracbits = 32 - texture->GetHeightBits(); if (uv_fracbits != 32) @@ -70,13 +71,13 @@ namespace swrenderer // Find start uv in [0-base_height[ range. // Not using xs_ToFixed because it rounds the result and we need something that always rounds down to stay within the range. double uv_stepd = swal * yrepeat; - double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / height; + double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / texture->GetHeight(); v = v - floor(v); v *= height; v *= (1 << uv_fracbits); uv_pos = (uint32_t)(int64_t)v; - uv_step = xs_ToFixed(uv_fracbits, uv_stepd); + uv_step = xs_ToFixed(uv_fracbits, uv_stepd * texture->GetPhysicalScale()); if (uv_step == 0) // To prevent divide by zero elsewhere uv_step = 1; } @@ -92,7 +93,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->GetWidthBits())) + if (col < 0 && (width = texture->GetPhysicalWidth()) != (1 << texture->GetWidthBits())) { col = width + (col % width); } @@ -129,8 +130,8 @@ namespace swrenderer bool magnifying = lod < 0.0f; int mipmap_offset = 0; - int mip_width = texture->GetWidth(); - int mip_height = texture->GetHeight(); + int mip_width = texture->GetPhysicalWidth(); + int mip_height = texture->GetPhysicalHeight(); if (r_mipmap && texture->Mipmapped() && mip_width > 1 && mip_height > 1) { uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width); diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index d826dbc56..7d27fdaf4 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -67,6 +67,8 @@ namespace swrenderer return; } + tex = texture; + drawerargs.SetSolidColor(3); drawerargs.SetTexture(Thread, texture); @@ -181,11 +183,11 @@ namespace swrenderer float zbufferdepth = (float)(1.0 / fabs(planeheight / Thread->Viewport->ScreenToViewY(y, 1.0))); - drawerargs.SetTextureUStep(distance * xstepscale / drawerargs.TextureWidth()); - drawerargs.SetTextureUPos((distance * curxfrac + pviewx) / drawerargs.TextureWidth()); + drawerargs.SetTextureUStep(distance * xstepscale / tex->GetWidth()); + drawerargs.SetTextureUPos((distance * curxfrac + pviewx) / tex->GetWidth()); - drawerargs.SetTextureVStep(distance * ystepscale / drawerargs.TextureHeight()); - drawerargs.SetTextureVPos((distance * curyfrac + pviewy) / drawerargs.TextureHeight()); + drawerargs.SetTextureVStep(distance * ystepscale / tex->GetHeight()); + drawerargs.SetTextureVPos((distance * curyfrac + pviewy) / tex->GetHeight()); if (viewport->RenderTarget->IsBgra()) { diff --git a/src/swrenderer/plane/r_flatplane.h b/src/swrenderer/plane/r_flatplane.h index 9e01afb94..fad5bdf8f 100644 --- a/src/swrenderer/plane/r_flatplane.h +++ b/src/swrenderer/plane/r_flatplane.h @@ -51,6 +51,7 @@ namespace swrenderer double xstepscale, ystepscale; double basexfrac, baseyfrac; VisiblePlaneLight *light_list; + FSoftwareTexture *tex; SpanDrawerArgs drawerargs; }; diff --git a/src/swrenderer/plane/r_skyplane.cpp b/src/swrenderer/plane/r_skyplane.cpp index 4f444ece5..5b5c4894a 100644 --- a/src/swrenderer/plane/r_skyplane.cpp +++ b/src/swrenderer/plane/r_skyplane.cpp @@ -248,11 +248,9 @@ namespace swrenderer RenderPortal *renderportal = Thread->Portal.get(); auto viewport = Thread->Viewport.get(); - uint32_t height = frontskytex->GetHeight(); - double uv_stepd = skyiscale * yrepeat; - double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / height; - double v_step = uv_stepd / height; + double v = (texturemid + uv_stepd * (y1 - viewport->CenterY + 0.5)) / frontskytex->GetHeight(); + double v_step = uv_stepd / frontskytex->GetHeight(); uint32_t uv_pos = (uint32_t)(int32_t)(v * 0x01000000); uint32_t uv_step = (uint32_t)(int32_t)(v_step * 0x01000000); @@ -272,8 +270,8 @@ namespace swrenderer { ang = (skyangle + viewport->xtoviewangle[x]) ^ skyflip; } - angle1 = (uint32_t)((UMulScale16(ang, frontcyl) + frontpos) >> FRACBITS); - angle2 = (uint32_t)((UMulScale16(ang, backcyl) + backpos) >> FRACBITS); + angle1 = UMulScale16(ang, frontcyl) + frontpos; + angle2 = UMulScale16(ang, backcyl) + backpos; drawerargs.SetFrontTexture(Thread, frontskytex, angle1); drawerargs.SetBackTexture(Thread, backskytex, angle2); @@ -296,7 +294,7 @@ namespace swrenderer void RenderSkyPlane::DrawSkyColumn(int start_x, int y1, int y2) { - if (1 << frontskytex->GetHeightBits() == frontskytex->GetHeight()) + if (1 << frontskytex->GetHeightBits() == frontskytex->GetPhysicalHeight()) { double texturemid = skymid * frontskytex->GetScale().Y + frontskytex->GetHeight(); DrawSkyColumnStripe(start_x, y1, y2, frontskytex->GetScale().Y, texturemid, frontskytex->GetScale().Y); diff --git a/src/swrenderer/plane/r_slopeplane.cpp b/src/swrenderer/plane/r_slopeplane.cpp index fb20f107e..41a30db83 100644 --- a/src/swrenderer/plane/r_slopeplane.cpp +++ b/src/swrenderer/plane/r_slopeplane.cpp @@ -98,6 +98,9 @@ namespace swrenderer drawerargs.SetSolidColor(3); drawerargs.SetTexture(Thread, texture); + _xscale /= texture->GetPhysicalScale(); + _yscale /= texture->GetPhysicalScale(); + lxscale = _xscale * ifloatpow2[drawerargs.TextureWidthBits()]; lyscale = _yscale * ifloatpow2[drawerargs.TextureHeightBits()]; xscale = 64.f / lxscale; diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index 6b8814f39..a53e61d57 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -68,7 +68,7 @@ FSoftwareTexture::FSoftwareTexture(FTexture *tex) auto info = tex->CreateTexBuffer(0, CTF_CheckOnly| mBufferFlags); mPhysicalWidth = info.mWidth; mPhysicalHeight = info.mHeight; - mPhysicalScale = mPhysicalWidth / tex->Width;; + mPhysicalScale = mPhysicalWidth / tex->Width; CalcBitSize(); } @@ -83,7 +83,7 @@ void FSoftwareTexture::CalcBitSize () // WidthBits is rounded down, and HeightBits is rounded up int i; - for (i = 0; (1 << i) < GetWidth(); ++i) + for (i = 0; (1 << i) < GetPhysicalWidth(); ++i) { } WidthBits = i; @@ -91,7 +91,7 @@ void FSoftwareTexture::CalcBitSize () // 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)) + if (GetPhysicalWidth() < (1 << WidthBits)) { WidthBits--; } @@ -99,7 +99,7 @@ void FSoftwareTexture::CalcBitSize () //
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) + for (i = 0; (1 << i) < GetPhysicalHeight(); ++i) { } HeightBits = i; @@ -122,13 +122,13 @@ const uint8_t *FSoftwareTexture::GetPixels(int style) else { auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags); - Pixels.Resize(GetWidth()*GetHeight()); + Pixels.Resize(GetPhysicalWidth()*GetPhysicalHeight()); PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; - for (int y = 0; y < GetHeight(); y++) + for (int y = 0; y < GetPhysicalHeight(); y++) { - for (int x = 0; x < GetWidth(); x++) + for (int x = 0; x < GetPhysicalWidth(); x++) { - Pixels[y + x * GetHeight()] = ImageHelpers::RGBToPalette(false, pe[x + y * GetWidth()], true); + Pixels[y + x * GetPhysicalHeight()] = ImageHelpers::RGBToPalette(false, pe[x + y * GetPhysicalWidth()], true); } } } @@ -156,11 +156,11 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra() auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags); CreatePixelsBgraWithMipmaps(); PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; - for (int y = 0; y < GetHeight(); y++) + for (int y = 0; y < GetPhysicalHeight(); y++) { - for (int x = 0; x < GetWidth(); x++) + for (int x = 0; x < GetPhysicalWidth(); x++) { - PixelsBgra[y + x * GetHeight()] = pe[x + y * GetWidth()]; + PixelsBgra[y + x * GetPhysicalHeight()] = pe[x + y * GetPhysicalWidth()]; } } GenerateBgraMipmaps(); @@ -178,15 +178,15 @@ const uint32_t *FSoftwareTexture::GetPixelsBgra() const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const FSoftwareTextureSpan **spans_out) { auto Pixeldata = GetPixels(index); - if ((unsigned)column >= (unsigned)GetWidth()) + if ((unsigned)column >= (unsigned)GetPhysicalWidth()) { - if (WidthMask + 1 == GetWidth()) + if (WidthMask + 1 == GetPhysicalWidth()) { column &= WidthMask; } else { - column %= GetWidth(); + column %= GetPhysicalWidth(); } } if (spans_out != nullptr) @@ -197,7 +197,7 @@ const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const } *spans_out = Spandata[index][column]; } - return Pixeldata + column * GetHeight(); + return Pixeldata + column * GetPhysicalHeight(); } //========================================================================== @@ -209,15 +209,15 @@ const uint8_t *FSoftwareTexture::GetColumn(int index, unsigned int column, const const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoftwareTextureSpan **spans_out) { auto Pixeldata = GetPixelsBgra(); - if ((unsigned)column >= (unsigned)GetWidth()) + if ((unsigned)column >= (unsigned)GetPhysicalWidth()) { - if (WidthMask + 1 == GetWidth()) + if (WidthMask + 1 == GetPhysicalWidth()) { column &= WidthMask; } else { - column %= GetWidth(); + column %= GetPhysicalWidth(); } } if (spans_out != nullptr) @@ -228,7 +228,7 @@ const uint32_t *FSoftwareTexture::GetColumnBgra(unsigned int column, const FSoft } *spans_out = Spandata[2][column]; } - return Pixeldata + column * GetHeight(); + return Pixeldata + column * GetPhysicalHeight(); } //========================================================================== @@ -254,21 +254,21 @@ FSoftwareTextureSpan **FSoftwareTexture::CreateSpans (const T *pixels) 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 = (FSoftwareTextureSpan **)M_Malloc (sizeof(FSoftwareTextureSpan*)*GetPhysicalWidth() + sizeof(FSoftwareTextureSpan)*2); + span = (FSoftwareTextureSpan *)&spans[GetPhysicalWidth()]; + for (int x = 0; x < GetPhysicalWidth(); ++x) { spans[x] = span; } - span[0].Length = GetHeight(); + span[0].Length = GetPhysicalHeight(); 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 numcols = GetPhysicalWidth(); + int numrows = GetPhysicalHeight(); int numspans = numcols; // One span to terminate each column const T *data_p; bool newspan; @@ -360,11 +360,11 @@ void FSoftwareTexture::GenerateBgraFromBitmap(const FBitmap &bitmap) // Transpose const uint32_t *src = (const uint32_t *)bitmap.GetPixels(); uint32_t *dest = PixelsBgra.Data(); - for (int x = 0; x < GetWidth(); x++) + for (int x = 0; x < GetPhysicalWidth(); x++) { - for (int y = 0; y < GetHeight(); y++) + for (int y = 0; y < GetPhysicalHeight(); y++) { - dest[y + x * GetHeight()] = src[x + y * GetWidth()]; + dest[y + x * GetPhysicalHeight()] = src[x + y * GetPhysicalWidth()]; } } @@ -377,8 +377,8 @@ void FSoftwareTexture::CreatePixelsBgraWithMipmaps() int buffersize = 0; for (int i = 0; i < levels; i++) { - int w = MAX(GetWidth() >> i, 1); - int h = MAX(GetHeight() >> i, 1); + int w = MAX(GetPhysicalWidth() >> i, 1); + int h = MAX(GetPhysicalHeight() >> i, 1); buffersize += w * h; } PixelsBgra.Resize(buffersize); @@ -387,10 +387,10 @@ void FSoftwareTexture::CreatePixelsBgraWithMipmaps() int FSoftwareTexture::MipmapLevels() { int widthbits = 0; - while ((GetWidth() >> widthbits) != 0) widthbits++; + while ((GetPhysicalWidth() >> widthbits) != 0) widthbits++; int heightbits = 0; - while ((GetHeight() >> heightbits) != 0) heightbits++; + while ((GetPhysicalHeight() >> heightbits) != 0) heightbits++; return MAX(widthbits, heightbits); } @@ -421,32 +421,32 @@ void FSoftwareTexture::GenerateBgraMipmaps() // Convert to normalized linear colorspace { - for (int x = 0; x < GetWidth(); x++) + for (int x = 0; x < GetPhysicalWidth(); x++) { - for (int y = 0; y < GetHeight(); y++) + for (int y = 0; y < GetPhysicalHeight(); y++) { - uint32_t c8 = PixelsBgra[x * GetHeight() + y]; + uint32_t c8 = PixelsBgra[x * GetPhysicalHeight() + 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; + image[x * GetPhysicalHeight() + y] = c; } } } // Generate mipmaps { - std::vector smoothed(GetWidth() * GetHeight()); + std::vector smoothed(GetPhysicalWidth() * GetPhysicalHeight()); Color4f *src = image.data(); - Color4f *dest = src + GetWidth() * GetHeight(); + Color4f *dest = src + GetPhysicalWidth() * GetPhysicalHeight(); 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); + int srcw = MAX(GetPhysicalWidth() >> (i - 1), 1); + int srch = MAX(GetPhysicalHeight() >> (i - 1), 1); + int w = MAX(GetPhysicalWidth() >> i, 1); + int h = MAX(GetPhysicalHeight() >> i, 1); // Downscale for (int x = 0; x < w; x++) @@ -502,12 +502,12 @@ void FSoftwareTexture::GenerateBgraMipmaps() // Convert to bgra8 sRGB colorspace { - Color4f *src = image.data() + GetWidth() * GetHeight(); - uint32_t *dest = PixelsBgra.Data() + GetWidth() * GetHeight(); + Color4f *src = image.data() + GetPhysicalWidth() * GetPhysicalHeight(); + uint32_t *dest = PixelsBgra.Data() + GetPhysicalWidth() * GetPhysicalHeight(); for (int i = 1; i < levels; i++) { - int w = MAX(GetWidth() >> i, 1); - int h = MAX(GetHeight() >> i, 1); + int w = MAX(GetPhysicalWidth() >> i, 1); + int h = MAX(GetPhysicalHeight() >> 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); @@ -531,14 +531,14 @@ void FSoftwareTexture::GenerateBgraMipmaps() void FSoftwareTexture::GenerateBgraMipmapsFast() { uint32_t *src = PixelsBgra.Data(); - uint32_t *dest = src + GetWidth() * GetHeight(); + uint32_t *dest = src + GetPhysicalWidth() * GetPhysicalHeight(); 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); + int srcw = MAX(GetPhysicalWidth() >> (i - 1), 1); + int srch = MAX(GetPhysicalHeight() >> (i - 1), 1); + int w = MAX(GetPhysicalWidth() >> i, 1); + int h = MAX(GetPhysicalHeight() >> i, 1); for (int x = 0; x < w; x++) { diff --git a/src/swrenderer/textures/r_swtexture.h b/src/swrenderer/textures/r_swtexture.h index 0ead864ce..f4baeb21b 100644 --- a/src/swrenderer/textures/r_swtexture.h +++ b/src/swrenderer/textures/r_swtexture.h @@ -58,8 +58,8 @@ public: int GetSkyOffset() const { return mTexture->GetSkyOffset(); } PalEntry GetSkyCapColor(bool bottom) const { return mTexture->GetSkyCapColor(bottom); } - int GetWidth () { return mPhysicalWidth; } - int GetHeight () { return mPhysicalHeight; } + int GetWidth () { return mTexture->GetWidth(); } + int GetHeight () { return mTexture->GetHeight(); } int GetWidthBits() { return WidthBits; } int GetHeightBits() { return HeightBits; } @@ -69,12 +69,12 @@ public: double GetScaledHeightDouble () { return mTexture->GetScaledHeightDouble(); } // Now with improved offset adjustment. - int GetLeftOffset(int adjusted) { return mTexture->GetLeftOffset(adjusted) * mPhysicalScale; } - int GetTopOffset(int adjusted) { return mTexture->GetTopOffset(adjusted) * mPhysicalScale; } - int GetScaledLeftOffset (int adjusted) { return mTexture->GetScaledLeftOffset(adjusted) * mPhysicalScale; } - int GetScaledTopOffset (int adjusted) { return mTexture->GetScaledTopOffset(adjusted) * mPhysicalScale; } - double GetScaledLeftOffsetDouble(int adjusted) { return mTexture->GetScaledLeftOffsetDouble(adjusted) * mPhysicalScale; } - double GetScaledTopOffsetDouble(int adjusted) { return mTexture->GetScaledTopOffsetDouble(adjusted) * mPhysicalScale; } + 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. @@ -91,7 +91,9 @@ public: int GetScaledLeftOffsetPo() { return GetScaledLeftOffset(r_spriteadjustSW); } int GetScaledTopOffsetPo() { return GetScaledTopOffset(r_spriteadjustSW); } - DVector2 GetScale() const { return mTexture->Scale * mPhysicalScale; } + DVector2 GetScale() const { return mTexture->Scale; } + int GetPhysicalWidth() { return mPhysicalWidth; } + int GetPhysicalHeight() { return mPhysicalHeight; } int GetPhysicalScale() const { return mPhysicalScale; } virtual void Unload() diff --git a/src/swrenderer/viewport/r_skydrawer.cpp b/src/swrenderer/viewport/r_skydrawer.cpp index 2bbab5abf..2f75e30e2 100644 --- a/src/swrenderer/viewport/r_skydrawer.cpp +++ b/src/swrenderer/viewport/r_skydrawer.cpp @@ -47,21 +47,21 @@ namespace swrenderer dc_viewport = viewport; } - void SkyDrawerArgs::SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column) + void SkyDrawerArgs::SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, fixed_t column) { if (thread->Viewport->RenderTarget->IsBgra()) { - dc_source = (const uint8_t *)texture->GetColumnBgra(column, nullptr); - dc_sourceheight = texture->GetHeight(); + dc_source = (const uint8_t *)texture->GetColumnBgra((column * texture->GetPhysicalScale()) >> FRACBITS, nullptr); + dc_sourceheight = texture->GetPhysicalHeight(); } else { - dc_source = texture->GetColumn(DefaultRenderStyle(), column, nullptr); - dc_sourceheight = texture->GetHeight(); + dc_source = texture->GetColumn(DefaultRenderStyle(), (column * texture->GetPhysicalScale()) >> FRACBITS, nullptr); + dc_sourceheight = texture->GetPhysicalHeight(); } } - void SkyDrawerArgs::SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column) + void SkyDrawerArgs::SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, fixed_t column) { if (texture == nullptr) { @@ -70,13 +70,13 @@ namespace swrenderer } else if (thread->Viewport->RenderTarget->IsBgra()) { - dc_source2 = (const uint8_t *)texture->GetColumnBgra(column, nullptr); - dc_sourceheight2 = texture->GetHeight(); + dc_source2 = (const uint8_t *)texture->GetColumnBgra((column * texture->GetPhysicalScale()) >> FRACBITS, nullptr); + dc_sourceheight2 = texture->GetPhysicalHeight(); } else { - dc_source2 = texture->GetColumn(DefaultRenderStyle(), column, nullptr); - dc_sourceheight2 = texture->GetHeight(); + dc_source2 = texture->GetColumn(DefaultRenderStyle(), (column * texture->GetPhysicalScale()) >> FRACBITS, nullptr); + dc_sourceheight2 = texture->GetPhysicalHeight(); } } } diff --git a/src/swrenderer/viewport/r_skydrawer.h b/src/swrenderer/viewport/r_skydrawer.h index 69ff04d9b..2634c514f 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, FSoftwareTexture *texture, uint32_t column); - void SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, uint32_t column); + void SetFrontTexture(RenderThread *thread, FSoftwareTexture *texture, fixed_t column); + void SetBackTexture(RenderThread *thread, FSoftwareTexture *texture, fixed_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 8c4bb26a7..665d18e89 100644 --- a/src/swrenderer/viewport/r_spandrawer.cpp +++ b/src/swrenderer/viewport/r_spandrawer.cpp @@ -34,21 +34,21 @@ namespace swrenderer { thread->PrepareTexture(tex, DefaultRenderStyle()); - ds_texwidth = tex->GetWidth(); - ds_texheight = tex->GetHeight(); + ds_texwidth = tex->GetPhysicalWidth(); + ds_texheight = tex->GetPhysicalHeight(); ds_xbits = tex->GetWidthBits(); ds_ybits = tex->GetHeightBits(); - if ((1 << ds_xbits) > tex->GetWidth()) + if ((1 << ds_xbits) > tex->GetPhysicalWidth()) { ds_xbits--; } - if ((1 << ds_ybits) > tex->GetHeight()) + if ((1 << ds_ybits) > tex->GetPhysicalHeight()) { ds_ybits--; } ds_source = thread->Viewport->RenderTarget->IsBgra() ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels(DefaultRenderStyle()); // Get correct render style? Shaded won't get here. - ds_source_mipmapped = tex->Mipmapped() && tex->GetWidth() > 1 && tex->GetHeight() > 1; + ds_source_mipmapped = tex->Mipmapped() && tex->GetPhysicalWidth() > 1 && tex->GetPhysicalHeight() > 1; } void SpanDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha) diff --git a/src/swrenderer/viewport/r_spritedrawer.cpp b/src/swrenderer/viewport/r_spritedrawer.cpp index f53fe70b2..f6d870912 100644 --- a/src/swrenderer/viewport/r_spritedrawer.cpp +++ b/src/swrenderer/viewport/r_spritedrawer.cpp @@ -48,6 +48,10 @@ namespace swrenderer if (x < thread->X1 || x >= thread->X2) return; + col *= tex->GetPhysicalScale(); + iscale *= tex->GetPhysicalScale(); + spryscale /= tex->GetPhysicalScale(); + auto viewport = thread->Viewport.get(); // Handle the linear filtered version in a different function to reduce chances of merge conflicts from zdoom. @@ -60,7 +64,7 @@ namespace swrenderer dc_viewport = viewport; dc_x = x; dc_iscale = iscale; - dc_textureheight = tex->GetHeight(); + dc_textureheight = tex->GetPhysicalHeight(); const FSoftwareTextureSpan *span; const uint8_t *column; @@ -74,7 +78,7 @@ namespace swrenderer { span = unmaskedSpan; unmaskedSpan[0].TopOffset = 0; - unmaskedSpan[0].Length = tex->GetHeight(); + unmaskedSpan[0].Length = tex->GetPhysicalHeight(); unmaskedSpan[1].TopOffset = 0; unmaskedSpan[1].Length = 0; } @@ -134,7 +138,7 @@ namespace swrenderer // Normalize to 0-1 range: double uv_stepd = FIXED2DBL(dc_iscale); - double v_step = uv_stepd / tex->GetHeight(); + double v_step = uv_stepd / tex->GetPhysicalHeight(); // Convert to uint32_t: dc_iscale = (uint32_t)(v_step * (1 << 30)); @@ -150,8 +154,8 @@ namespace swrenderer bool magnifying = lod < 0.0f; int mipmap_offset = 0; - int mip_width = tex->GetWidth(); - int mip_height = tex->GetHeight(); + int mip_width = tex->GetPhysicalWidth(); + int mip_height = tex->GetPhysicalHeight(); uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width); if (r_mipmap && tex->Mipmapped() && mip_width > 1 && mip_height > 1) { @@ -199,7 +203,7 @@ namespace swrenderer { span = unmaskedSpan; unmaskedSpan[0].TopOffset = 0; - unmaskedSpan[0].Length = tex->GetHeight(); + unmaskedSpan[0].Length = tex->GetPhysicalHeight(); unmaskedSpan[1].TopOffset = 0; unmaskedSpan[1].Length = 0; } @@ -233,7 +237,7 @@ namespace swrenderer SetDest(dc_viewport, dc_x, dc_yl); dc_count = dc_yh - dc_yl + 1; - double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetHeight(); + double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetPhysicalHeight(); dc_texturefrac = (uint32_t)(v * (1 << 30)); (thread->Drawers(dc_viewport)->*colfunc)(*this); From 15d599813b6c1eaac1b51404fc18f156b3aca6af Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 16 Dec 2018 15:12:45 +0100 Subject: [PATCH 101/113] - add support for scaled textures in softpoly --- src/polyrenderer/drawers/poly_draw_args.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/polyrenderer/drawers/poly_draw_args.cpp b/src/polyrenderer/drawers/poly_draw_args.cpp index c249e2a7e..bb31c1515 100644 --- a/src/polyrenderer/drawers/poly_draw_args.cpp +++ b/src/polyrenderer/drawers/poly_draw_args.cpp @@ -50,8 +50,8 @@ void PolyDrawArgs::SetTexture(const uint8_t *texels, int width, int height) void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, FRenderStyle style) { mTexture = texture; - mTextureWidth = texture->GetWidth(); - mTextureHeight = texture->GetHeight(); + mTextureWidth = texture->GetPhysicalWidth(); + mTextureHeight = texture->GetPhysicalHeight(); if (PolyTriangleDrawer::IsBgra()) mTexturePixels = (const uint8_t *)texture->GetPixelsBgra(); else @@ -73,8 +73,8 @@ void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, uint32_t translationID, mTranslation = table->Remap; mTexture = texture; - mTextureWidth = texture->GetWidth(); - mTextureHeight = texture->GetHeight(); + mTextureWidth = texture->GetPhysicalWidth(); + mTextureHeight = texture->GetPhysicalHeight(); mTexturePixels = texture->GetPixels(style); return; } @@ -83,8 +83,8 @@ void PolyDrawArgs::SetTexture(FSoftwareTexture *texture, uint32_t translationID, if (style.Flags & STYLEF_RedIsAlpha) { mTexture = texture; - mTextureWidth = texture->GetWidth(); - mTextureHeight = texture->GetHeight(); + mTextureWidth = texture->GetPhysicalWidth(); + mTextureHeight = texture->GetPhysicalHeight(); mTexturePixels = texture->GetPixels(style); } else From cce82e99d6d67d93acde911803df8402d4b2225f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 19:03:04 +0100 Subject: [PATCH 102/113] - fixed: The texture compositor did not use a patch's translation. --- src/textures/formats/multipatchtexture.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index 2bfc0fc40..1514b1dea 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -315,7 +315,8 @@ int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion) } } - FBitmap Pixels = Parts[i].Image->GetCachedBitmap(nullptr, conversion, &ret); + auto trans = Parts[i].Translation ? Parts[i].Translation->Palette : nullptr; + FBitmap Pixels = Parts[i].Image->GetCachedBitmap(trans, 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; From 87953020ba21043201787df49be9cd8f9cc526d9 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 16 Dec 2018 19:17:53 +0100 Subject: [PATCH 103/113] - fixed: FImageSource::GetCachedBitmap did not pass the translucency information along to the caller. --- src/textures/image.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/textures/image.cpp b/src/textures/image.cpp index 04d0833c0..f047b8137 100644 --- a/src/textures/image.cpp +++ b/src/textures/image.cpp @@ -269,6 +269,7 @@ FBitmap FImageSource::GetCachedBitmap(PalEntry *remap, int conversion, int *ptra } } } + if (ptrans) *ptrans = trans; return ret; } From 4cd745db48f9e83387bcc8408568518ac2ff31eb Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 17 Dec 2018 00:03:36 +0100 Subject: [PATCH 104/113] - fixed: Patch rotations were not applied during true color texture composition. --- src/textures/formats/multipatchtexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textures/formats/multipatchtexture.cpp b/src/textures/formats/multipatchtexture.cpp index 1514b1dea..165a49344 100644 --- a/src/textures/formats/multipatchtexture.cpp +++ b/src/textures/formats/multipatchtexture.cpp @@ -317,7 +317,7 @@ int FMultiPatchTexture::CopyPixels(FBitmap *bmp, int conversion) auto trans = Parts[i].Translation ? Parts[i].Translation->Palette : nullptr; FBitmap Pixels = Parts[i].Image->GetCachedBitmap(trans, conversion, &ret); - bmp->Blit(Parts[i].OriginX, Parts[i].OriginY, Pixels, &info); + bmp->Blit(Parts[i].OriginX, Parts[i].OriginY, Pixels, Pixels.GetWidth(), Pixels.GetHeight(), Parts[i].Rotate, &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; From 9e15f269235a8e4b4fe33d9589b0557185638dde Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 17 Dec 2018 01:32:15 +0100 Subject: [PATCH 105/113] - fix decal upscaling --- src/swrenderer/textures/r_swtexture.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index a53e61d57..1b6192eee 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -124,11 +124,24 @@ const uint8_t *FSoftwareTexture::GetPixels(int style) auto tempbuffer = mTexture->CreateTexBuffer(0, mBufferFlags); Pixels.Resize(GetPhysicalWidth()*GetPhysicalHeight()); PalEntry *pe = (PalEntry*)tempbuffer.mBuffer; - for (int y = 0; y < GetPhysicalHeight(); y++) + if (!style) { - for (int x = 0; x < GetPhysicalWidth(); x++) + for (int y = 0; y < GetPhysicalHeight(); y++) { - Pixels[y + x * GetPhysicalHeight()] = ImageHelpers::RGBToPalette(false, pe[x + y * GetPhysicalWidth()], true); + for (int x = 0; x < GetPhysicalWidth(); x++) + { + Pixels[y + x * GetPhysicalHeight()] = ImageHelpers::RGBToPalette(false, pe[x + y * GetPhysicalWidth()], true); + } + } + } + else + { + for (int y = 0; y < GetPhysicalHeight(); y++) + { + for (int x = 0; x < GetPhysicalWidth(); x++) + { + Pixels[y + x * GetPhysicalHeight()] = pe[x + y * GetPhysicalWidth()].r; + } } } } From c3477e91978d38efb5f6b9a58aada0071c12ed8e Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 17 Dec 2018 01:32:46 +0100 Subject: [PATCH 106/113] - softpoly decals were upside down --- src/polyrenderer/scene/poly_decal.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/polyrenderer/scene/poly_decal.cpp b/src/polyrenderer/scene/poly_decal.cpp index 442c70de8..54ba76955 100644 --- a/src/polyrenderer/scene/poly_decal.cpp +++ b/src/polyrenderer/scene/poly_decal.cpp @@ -158,25 +158,25 @@ void RenderPolyDecal::Render(PolyRenderThread *thread, DBaseDecal *decal, const vertices[0].z = (float)ztop; vertices[0].w = 1.0f; vertices[0].u = (float)u_left; - vertices[0].v = (float)v_top; + vertices[0].v = 1.0f - (float)v_top; vertices[1].x = (float)decal_right.X; vertices[1].y = (float)decal_right.Y; vertices[1].z = (float)ztop; vertices[1].w = 1.0f; vertices[1].u = (float)u_right; - vertices[1].v = (float)v_top; + vertices[1].v = 1.0f - (float)v_top; vertices[2].x = (float)decal_right.X; vertices[2].y = (float)decal_right.Y; vertices[2].z = (float)zbottom; vertices[2].w = 1.0f; vertices[2].u = (float)u_right; - vertices[2].v = (float)v_bottom; + vertices[2].v = 1.0f - (float)v_bottom; vertices[3].x = (float)decal_left.X; vertices[3].y = (float)decal_left.Y; vertices[3].z = (float)zbottom; vertices[3].w = 1.0f; vertices[3].u = (float)u_left; - vertices[3].v = (float)v_bottom; + vertices[3].v = 1.0f - (float)v_bottom; // Light calculations From f35aeec6c3bb09495e1d6f9a169eab4f53c9fbdc Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 17 Dec 2018 05:10:26 +0100 Subject: [PATCH 107/113] - move visibility calculation to LightVisibility --- src/swrenderer/line/r_line.cpp | 5 ++--- src/swrenderer/plane/r_flatplane.cpp | 6 ++---- src/swrenderer/plane/r_flatplane.h | 2 +- src/swrenderer/scene/r_light.h | 4 ++-- src/swrenderer/scene/r_translucent_pass.h | 2 -- src/swrenderer/things/r_particle.cpp | 2 +- src/swrenderer/things/r_sprite.cpp | 2 +- src/swrenderer/things/r_visiblesprite.cpp | 2 +- src/swrenderer/things/r_voxel.cpp | 2 +- src/swrenderer/things/r_wallsprite.cpp | 2 +- src/swrenderer/viewport/r_viewport.h | 2 ++ 11 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 9083f9ec4..0cfee0dc6 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -790,9 +790,8 @@ namespace swrenderer if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0) { wallshade = LightVisibility::LightLevelToShade(mLineSegment->sidedef->GetLightLevel(foggy, mFrontSector->lightlevel) + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); - double GlobVis = Thread->Light->WallGlobVis(foggy); - rw_lightleft = float(GlobVis / WallC.sz1); - rw_lightstep = float((GlobVis / WallC.sz2 - rw_lightleft) / (WallC.sx2 - WallC.sx1)); + rw_lightleft = float(Thread->Light->WallVis(WallC.sz1, foggy)); + rw_lightstep = float((Thread->Light->WallVis(WallC.sz2, foggy) - rw_lightleft) / (WallC.sx2 - WallC.sx1)); } else { diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index 7d27fdaf4..a9d147089 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -137,9 +137,7 @@ namespace swrenderer basecolormap = colormap; // [RH] set foggy flag - bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); - - GlobVis = Thread->Light->FlatPlaneGlobVis(foggy) / planeheight; + foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() >= 0) @@ -202,7 +200,7 @@ namespace swrenderer if (plane_shade) { // Determine lighting based on the span's distance from the viewer. - drawerargs.SetLight(basecolormap, (float)(GlobVis * fabs(viewport->CenterY - y)), planeshade); + drawerargs.SetLight(basecolormap, (float)Thread->Light->FlatPlaneVis(y, planeheight, foggy, viewport), planeshade); } if (r_dynlights) diff --git a/src/swrenderer/plane/r_flatplane.h b/src/swrenderer/plane/r_flatplane.h index fad5bdf8f..537d8a6d0 100644 --- a/src/swrenderer/plane/r_flatplane.h +++ b/src/swrenderer/plane/r_flatplane.h @@ -45,7 +45,7 @@ namespace swrenderer double planeheight; bool plane_shade; int planeshade; - double GlobVis; + bool foggy; FDynamicColormap *basecolormap; double pviewx, pviewy; double xstepscale, ystepscale; diff --git a/src/swrenderer/scene/r_light.h b/src/swrenderer/scene/r_light.h index ae2a2e671..b10de26f3 100644 --- a/src/swrenderer/scene/r_light.h +++ b/src/swrenderer/scene/r_light.h @@ -88,9 +88,9 @@ namespace swrenderer // The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros double WallVis(double screenZ, bool foggy) const { return WallGlobVis(foggy) / screenZ; } - double SpriteVis(double screenZ, bool foggy) const { return SpriteGlobVis(foggy) / screenZ; } + double SpriteVis(double screenZ, bool foggy) const { return SpriteGlobVis(foggy) / MAX(screenZ, MINZ); } double ParticleVis(double screenZ, bool foggy) const { return ParticleGlobVis(foggy) / screenZ; } - double FlatPlaneVis(int screenY, double planeZ, bool foggy, RenderViewport *viewport) const { return FlatPlaneGlobVis(foggy) / fabs(planeZ - viewport->viewpoint.Pos.Z) * fabs(viewport->CenterY - screenY); } + double FlatPlaneVis(int screenY, double planeheight, bool foggy, RenderViewport *viewport) const { return FlatPlaneGlobVis(foggy) / planeheight * fabs(viewport->CenterY - screenY); } static fixed_t LightLevelToShade(int lightlevel, bool foggy); static int ActualExtraLight(bool fog, RenderViewport *viewport) { return fog ? 0 : viewport->viewpoint.extralight << 4; } diff --git a/src/swrenderer/scene/r_translucent_pass.h b/src/swrenderer/scene/r_translucent_pass.h index 5c28749a7..77344e2f6 100644 --- a/src/swrenderer/scene/r_translucent_pass.h +++ b/src/swrenderer/scene/r_translucent_pass.h @@ -23,8 +23,6 @@ #include "tarray.h" -#define MINZ double((2048*4) / double(1 << 20)) - struct particle_t; struct FVoxel; diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index 0e167f7c4..69c739da9 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -220,7 +220,7 @@ namespace swrenderer vis->floorclip = 0; vis->foggy = foggy; - vis->Light.SetColormap(tiz * thread->Light->ParticleGlobVis(foggy), shade, map, particle->bright != 0, false, false); + vis->Light.SetColormap(thread->Light->ParticleVis(tz, foggy), shade, map, particle->bright != 0, false, false); thread->SpriteList->Push(vis); } diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index 49531337a..c553eb56a 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -300,7 +300,7 @@ namespace swrenderer vis->dynlightcolor = 0; } - vis->Light.SetColormap(thread->Light->SpriteGlobVis(foggy) / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); + vis->Light.SetColormap(thread->Light->SpriteVis(tz, foggy), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); thread->SpriteList->Push(vis); } diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index 5687fe473..d5313495d 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -165,7 +165,7 @@ namespace swrenderer int spriteshade = LightVisibility::LightLevelToShade(sec->lightlevel + LightVisibility::ActualExtraLight(spr->foggy, thread->Viewport.get()), foggy); - Light.SetColormap(thread->Light->SpriteGlobVis(foggy) / MAX(MINZ, (double)spr->depth), spriteshade, mybasecolormap, isFullBright, invertcolormap, fadeToBlack); + Light.SetColormap(thread->Light->SpriteVis(spr->depth, foggy), spriteshade, mybasecolormap, isFullBright, invertcolormap, fadeToBlack); } } diff --git a/src/swrenderer/things/r_voxel.cpp b/src/swrenderer/things/r_voxel.cpp index faab6e785..57f9d1bbf 100644 --- a/src/swrenderer/things/r_voxel.cpp +++ b/src/swrenderer/things/r_voxel.cpp @@ -188,7 +188,7 @@ namespace swrenderer bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)); bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0; - vis->Light.SetColormap(thread->Light->SpriteGlobVis(foggy) / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); + vis->Light.SetColormap(thread->Light->SpriteVis(tz, foggy), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); // Fake a voxel drawing to find its extents.. SpriteDrawerArgs drawerargs; diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index d6cf90d22..56cf603df 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -141,7 +141,7 @@ namespace swrenderer vis->wallc = wallc; vis->foggy = foggy; - vis->Light.SetColormap(thread->Light->SpriteGlobVis(foggy) / MAX(tz, MINZ), spriteshade, basecolormap, false, false, false); + vis->Light.SetColormap(thread->Light->SpriteVis(tz, foggy), spriteshade, basecolormap, false, false, false); thread->SpriteList->Push(vis); } diff --git a/src/swrenderer/viewport/r_viewport.h b/src/swrenderer/viewport/r_viewport.h index 7709e5701..69adc5778 100644 --- a/src/swrenderer/viewport/r_viewport.h +++ b/src/swrenderer/viewport/r_viewport.h @@ -7,6 +7,8 @@ #include "r_defs.h" #include "polyrenderer/math/gpu_types.h" +#define MINZ double((2048*4) / double(1 << 20)) + namespace swrenderer { class RenderThread; From 946f657a372b7aaf51ee1ebf7ffc0eda217da6b4 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 17 Dec 2018 06:13:00 +0100 Subject: [PATCH 108/113] - fix heretic light torch in software renderer and remove some code duplication --- src/swrenderer/line/r_line.cpp | 4 ++-- src/swrenderer/line/r_renderdrawsegment.cpp | 10 +++++----- src/swrenderer/line/r_walldraw.cpp | 6 ++++-- src/swrenderer/plane/r_flatplane.cpp | 2 +- src/swrenderer/plane/r_slopeplane.cpp | 2 +- src/swrenderer/plane/r_visibleplanelist.cpp | 4 +++- src/swrenderer/plane/r_visibleplanelist.h | 2 +- src/swrenderer/scene/r_light.cpp | 2 +- src/swrenderer/scene/r_light.h | 18 +++++++++++------- src/swrenderer/scene/r_opaque_pass.cpp | 14 +++++++------- src/swrenderer/things/r_playersprite.cpp | 4 +--- src/swrenderer/things/r_visiblesprite.cpp | 2 +- src/swrenderer/things/r_wallsprite.cpp | 7 +++---- 13 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index 0cfee0dc6..fe8fa5ea4 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -503,7 +503,7 @@ namespace swrenderer } else { - draw_segment->shade = LightVisibility::LightLevelToShade(mLineSegment->sidedef->GetLightLevel(foggy, mLineSegment->frontsector->lightlevel) + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); + draw_segment->shade = LightVisibility::LightLevelToShade(mLineSegment->sidedef->GetLightLevel(foggy, mLineSegment->frontsector->lightlevel), foggy, Thread->Viewport.get()); } if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr) @@ -789,7 +789,7 @@ namespace swrenderer CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0) { - wallshade = LightVisibility::LightLevelToShade(mLineSegment->sidedef->GetLightLevel(foggy, mFrontSector->lightlevel) + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); + wallshade = LightVisibility::LightLevelToShade(mLineSegment->sidedef->GetLightLevel(foggy, mFrontSector->lightlevel), foggy, Thread->Viewport.get()); rw_lightleft = float(Thread->Light->WallVis(WallC.sz1, foggy)); rw_lightstep = float((Thread->Light->WallVis(WallC.sz2, foggy) - rw_lightleft) / (WallC.sx2 - WallC.sx1)); } diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index eb23daad0..f4350b136 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -114,7 +114,7 @@ namespace swrenderer lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, viewport), foggy); + wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), ds->foggy, viewport); break; } } @@ -732,7 +732,7 @@ namespace swrenderer lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, Thread->Viewport.get()), foggy); + wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), foggy, Thread->Viewport.get()); break; } } @@ -746,7 +746,7 @@ namespace swrenderer lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, Thread->Viewport.get()), foggy); + wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), foggy, Thread->Viewport.get()); break; } } @@ -918,7 +918,7 @@ namespace swrenderer lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, Thread->Viewport.get()), foggy); + wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), foggy, Thread->Viewport.get()); break; } } @@ -932,7 +932,7 @@ namespace swrenderer lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr) + LightVisibility::ActualExtraLight(ds->foggy, Thread->Viewport.get()), foggy); + wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), foggy, Thread->Viewport.get()); break; } } diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 4b97bd869..9c4e41932 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -349,7 +349,9 @@ namespace swrenderer CameraLight *cameraLight = CameraLight::Instance(); bool fixed = (cameraLight->FixedColormap() != NULL || cameraLight->FixedLightLevel() >= 0); - if (cameraLight->FixedColormap()) + if (cameraLight->FixedLightLevel() >= 0) + drawerargs.SetLight(cameraLight->FixedColormap(), 0, cameraLight->FixedLightLevelShade()); + else if (cameraLight->FixedColormap()) drawerargs.SetLight(cameraLight->FixedColormap(), 0, 0); else drawerargs.SetLight(basecolormap, 0, 0); @@ -420,7 +422,7 @@ namespace swrenderer lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != NULL) + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); + wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != NULL), foggy, Thread->Viewport.get()); } ProcessNormalWall(up, dwal, texturemid, swal, lwal); diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index a9d147089..3f86f921f 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -153,7 +153,7 @@ namespace swrenderer else { plane_shade = true; - planeshade = LightVisibility::LightLevelToShade(pl->lightlevel, foggy); + planeshade = LightVisibility::LightLevelToShade(pl->lightlevel, foggy, viewport); } drawerargs.SetStyle(masked, additive, alpha); diff --git a/src/swrenderer/plane/r_slopeplane.cpp b/src/swrenderer/plane/r_slopeplane.cpp index 41a30db83..61e085489 100644 --- a/src/swrenderer/plane/r_slopeplane.cpp +++ b/src/swrenderer/plane/r_slopeplane.cpp @@ -197,7 +197,7 @@ namespace swrenderer { drawerargs.SetLight(basecolormap, 0, 0); plane_shade = true; - planeshade = LightVisibility::LightLevelToShade(pl->lightlevel, foggy); + planeshade = LightVisibility::LightLevelToShade(pl->lightlevel, foggy, viewport); } // Hack in support for 1 x Z and Z x 1 texture sizes diff --git a/src/swrenderer/plane/r_visibleplanelist.cpp b/src/swrenderer/plane/r_visibleplanelist.cpp index 561930cc2..3c65e6386 100644 --- a/src/swrenderer/plane/r_visibleplanelist.cpp +++ b/src/swrenderer/plane/r_visibleplanelist.cpp @@ -99,7 +99,7 @@ namespace swrenderer } } - VisiblePlane *VisiblePlaneList::FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap, Fake3DOpaque::Type fakeFloorType, fixed_t fakeAlpha) + VisiblePlane *VisiblePlaneList::FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, bool foggy, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap, Fake3DOpaque::Type fakeFloorType, fixed_t fakeAlpha) { secplane_t plane; VisiblePlane *check; @@ -113,6 +113,8 @@ namespace swrenderer RenderPortal *renderportal = Thread->Portal.get(); + lightlevel += LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()); + if (picnum == skyflatnum) // killough 10/98 { // most skies map together lightlevel = 0; diff --git a/src/swrenderer/plane/r_visibleplanelist.h b/src/swrenderer/plane/r_visibleplanelist.h index a49479e6c..7c601238c 100644 --- a/src/swrenderer/plane/r_visibleplanelist.h +++ b/src/swrenderer/plane/r_visibleplanelist.h @@ -40,7 +40,7 @@ namespace swrenderer void Clear(); void ClearKeepFakePlanes(); - VisiblePlane *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap, Fake3DOpaque::Type fakeFloorType, fixed_t fakeAlpha); + VisiblePlane *FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, bool foggy, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal, FDynamicColormap *basecolormap, Fake3DOpaque::Type fakeFloorType, fixed_t fakeAlpha); VisiblePlane *GetRange(VisiblePlane *pl, int start, int stop); bool HasPortalPlanes() const; diff --git a/src/swrenderer/scene/r_light.cpp b/src/swrenderer/scene/r_light.cpp index c120c22eb..42468374a 100644 --- a/src/swrenderer/scene/r_light.cpp +++ b/src/swrenderer/scene/r_light.cpp @@ -142,7 +142,7 @@ namespace swrenderer NoLightFade = !!(level.flags3 & LEVEL3_NOLIGHTFADE); } - fixed_t LightVisibility::LightLevelToShade(int lightlevel, bool foggy) + fixed_t LightVisibility::LightLevelToShadeImpl(int lightlevel, bool foggy) { bool nolightfade = !foggy && ((level.flags3 & LEVEL3_NOLIGHTFADE)); if (nolightfade) diff --git a/src/swrenderer/scene/r_light.h b/src/swrenderer/scene/r_light.h index b10de26f3..8d6791e5d 100644 --- a/src/swrenderer/scene/r_light.h +++ b/src/swrenderer/scene/r_light.h @@ -80,22 +80,26 @@ namespace swrenderer void SetVisibility(RenderViewport *viewport, double visibility); double GetVisibility() const { return CurrentVisibility; } - double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; } - double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; } - double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : (WallVisibility * 0.5); } - double FlatPlaneGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : FloorVisibility; } - double SlopePlaneGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : TiltVisibility; } - // The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros double WallVis(double screenZ, bool foggy) const { return WallGlobVis(foggy) / screenZ; } double SpriteVis(double screenZ, bool foggy) const { return SpriteGlobVis(foggy) / MAX(screenZ, MINZ); } double ParticleVis(double screenZ, bool foggy) const { return ParticleGlobVis(foggy) / screenZ; } double FlatPlaneVis(int screenY, double planeheight, bool foggy, RenderViewport *viewport) const { return FlatPlaneGlobVis(foggy) / planeheight * fabs(viewport->CenterY - screenY); } - static fixed_t LightLevelToShade(int lightlevel, bool foggy); + double SlopePlaneGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : TiltVisibility; } + + static fixed_t LightLevelToShade(int lightlevel, bool foggy, RenderViewport *viewport) { return LightLevelToShadeImpl(lightlevel + ActualExtraLight(foggy, viewport), foggy); } + static int ActualExtraLight(bool fog, RenderViewport *viewport) { return fog ? 0 : viewport->viewpoint.extralight << 4; } private: + double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; } + double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; } + double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : (WallVisibility * 0.5); } + double FlatPlaneGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : FloorVisibility; } + + static fixed_t LightLevelToShadeImpl(int lightlevel, bool foggy); + double BaseVisibility = 0.0; double WallVisibility = 0.0; double FloorVisibility = 0.0; diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index cff29cbb4..a940745bd 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -548,7 +548,7 @@ namespace swrenderer ceilingplane = Thread->PlaneList->FindPlane( frontsector->ceilingplane, frontsector->GetTexture(sector_t::ceiling), - adjusted_ceilinglightlevel + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), + adjusted_ceilinglightlevel, foggy, frontsector->GetAlpha(sector_t::ceiling), !!(frontsector->GetFlags(sector_t::ceiling) & PLANEF_ADDITIVE), frontsector->planes[sector_t::ceiling].xform, @@ -588,7 +588,7 @@ namespace swrenderer { floorplane = Thread->PlaneList->FindPlane(frontsector->floorplane, frontsector->GetTexture(sector_t::floor), - adjusted_floorlightlevel + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), + adjusted_floorlightlevel, foggy, frontsector->GetAlpha(sector_t::floor), !!(frontsector->GetFlags(sector_t::floor) & PLANEF_ADDITIVE), frontsector->planes[sector_t::floor].xform, @@ -613,7 +613,7 @@ namespace swrenderer // [RH] Add particles if ((unsigned int)(sub->Index()) < level.subsectors.Size()) { // Only do it for the main BSP. - int shade = LightVisibility::LightLevelToShade((floorlightlevel + ceilinglightlevel) / 2 + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); + int shade = LightVisibility::LightLevelToShade((floorlightlevel + ceilinglightlevel) / 2, foggy, Thread->Viewport.get()); for (int i = ParticlesInSubsec[sub->Index()]; i != NO_PARTICLE; i = Particles[i].snext) { RenderParticle::Project(Thread, &Particles[i], sub->sector, shade, FakeSide, foggy); @@ -732,7 +732,7 @@ namespace swrenderer VisiblePlane *floorplane3d = Thread->PlaneList->FindPlane( tempsec.floorplane, tempsec.GetTexture(sector_t::floor), - floorlightlevel + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), + floorlightlevel, foggy, tempsec.GetAlpha(sector_t::floor), !!(clip3d->fakeFloor->fakeFloor->flags & FF_ADDITIVETRANS), tempsec.planes[position].xform, @@ -800,7 +800,7 @@ namespace swrenderer VisiblePlane *ceilingplane3d = Thread->PlaneList->FindPlane( tempsec.ceilingplane, tempsec.GetTexture(sector_t::ceiling), - ceilinglightlevel + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), + ceilinglightlevel, foggy, tempsec.GetAlpha(sector_t::ceiling), !!(clip3d->fakeFloor->fakeFloor->flags & FF_ADDITIVETRANS), tempsec.planes[position].xform, @@ -891,7 +891,7 @@ namespace swrenderer //sec->validcount = validcount; SeenSpriteSectors.insert(sec); - int spriteshade = LightVisibility::LightLevelToShade(lightlevel + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); + int spriteshade = LightVisibility::LightLevelToShade(lightlevel, foggy, Thread->Viewport.get()); // Handle all things in sector. for (auto p = sec->touching_renderthings; p != nullptr; p = p->m_snext) @@ -951,7 +951,7 @@ namespace swrenderer if (sec->sectornum != thing->Sector->sectornum) // compare sectornums to account for R_FakeFlat copies. { int lightlevel = thing->Sector->GetTexture(sector_t::ceiling) == skyflatnum ? thing->Sector->GetCeilingLight() : thing->Sector->GetFloorLight(); - thingShade = LightVisibility::LightLevelToShade(lightlevel + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()), foggy); + thingShade = LightVisibility::LightLevelToShade(lightlevel, foggy, Thread->Viewport.get()); thingColormap = GetColorTable(thing->Sector->Colormap, thing->Sector->SpecialColors[sector_t::sprites], true); } diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index ac99bee93..853e99e61 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -80,7 +80,6 @@ namespace swrenderer void RenderPlayerSprites::Render() { int i; - int lightnum; DPSprite* psp; DPSprite* weapon; sector_t* sec = NULL; @@ -138,8 +137,7 @@ namespace swrenderer bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // get light level - lightnum = ((floorlight + ceilinglight) >> 1) + LightVisibility::ActualExtraLight(foggy, Thread->Viewport.get()); - int spriteshade = LightVisibility::LightLevelToShade(lightnum, foggy) - 24 * FRACUNIT; + int spriteshade = LightVisibility::LightLevelToShade((floorlight + ceilinglight) >> 1, foggy, Thread->Viewport.get()) - 24 * FRACUNIT; if (Thread->Viewport->viewpoint.camera->player != NULL) { diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index d5313495d..f596ba76d 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -163,7 +163,7 @@ namespace swrenderer bool isFullBright = !foggy && (renderflags & RF_FULLBRIGHT); bool fadeToBlack = spr->RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0; - int spriteshade = LightVisibility::LightLevelToShade(sec->lightlevel + LightVisibility::ActualExtraLight(spr->foggy, thread->Viewport.get()), foggy); + int spriteshade = LightVisibility::LightLevelToShade(sec->lightlevel, foggy, thread->Viewport.get()); Light.SetColormap(thread->Light->SpriteVis(spr->depth, foggy), spriteshade, mybasecolormap, isFullBright, invertcolormap, fadeToBlack); } diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index 56cf603df..296872485 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -190,10 +190,9 @@ namespace swrenderer SpriteDrawerArgs drawerargs; - int shade = LightVisibility::LightLevelToShade(spr->sector->lightlevel + LightVisibility::ActualExtraLight(spr->foggy, thread->Viewport.get()), spr->foggy); - double GlobVis = thread->Light->WallGlobVis(foggy); - float lightleft = float(GlobVis / spr->wallc.sz1); - float lightstep = float((GlobVis / spr->wallc.sz2 - lightleft) / (spr->wallc.sx2 - spr->wallc.sx1)); + int shade = LightVisibility::LightLevelToShade(spr->sector->lightlevel, spr->foggy, thread->Viewport.get()); + float lightleft = float(thread->Light->WallVis(spr->wallc.sz1, foggy)); + float lightstep = float((thread->Light->WallVis(spr->wallc.sz2, foggy) - lightleft) / (spr->wallc.sx2 - spr->wallc.sx1)); float light = lightleft + (x1 - spr->wallc.sx1) * lightstep; CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() >= 0) From 66b5e6e2eeaa5bc72f6b49a06d79c7cb52fa6880 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 17 Dec 2018 06:47:26 +0100 Subject: [PATCH 109/113] - delay converting wall lightlevels to a shade until we hit the drawer --- src/swrenderer/line/r_line.cpp | 16 +++---- src/swrenderer/line/r_line.h | 2 +- src/swrenderer/line/r_renderdrawsegment.cpp | 46 ++++++++++----------- src/swrenderer/line/r_renderdrawsegment.h | 6 +-- src/swrenderer/line/r_walldraw.cpp | 8 ++-- src/swrenderer/line/r_walldraw.h | 4 +- src/swrenderer/segments/r_drawsegment.h | 2 +- src/swrenderer/things/r_decal.cpp | 8 ++-- src/swrenderer/things/r_decal.h | 4 +- src/swrenderer/viewport/r_drawerargs.cpp | 5 +++ src/swrenderer/viewport/r_drawerargs.h | 1 + 11 files changed, 54 insertions(+), 48 deletions(-) diff --git a/src/swrenderer/line/r_line.cpp b/src/swrenderer/line/r_line.cpp index fe8fa5ea4..a3af39bb6 100644 --- a/src/swrenderer/line/r_line.cpp +++ b/src/swrenderer/line/r_line.cpp @@ -494,16 +494,16 @@ namespace swrenderer draw_segment->lightstep = rw_lightstep; // Masked mMiddlePart.Textures should get the light level from the sector they reference, - // not from the current subsector, which is what the current wallshade value + // not from the current subsector, which is what the current lightlevel value // comes from. We make an exeption for polyobjects, however, since their "home" // sector should be whichever one they move into. if (mLineSegment->sidedef->Flags & WALLF_POLYOBJ) { - draw_segment->shade = wallshade; + draw_segment->lightlevel = lightlevel; } else { - draw_segment->shade = LightVisibility::LightLevelToShade(mLineSegment->sidedef->GetLightLevel(foggy, mLineSegment->frontsector->lightlevel), foggy, Thread->Viewport.get()); + draw_segment->lightlevel = mLineSegment->sidedef->GetLightLevel(foggy, mLineSegment->frontsector->lightlevel); } if (draw_segment->bFogBoundary || draw_segment->maskedtexturecol != nullptr) @@ -552,7 +552,7 @@ namespace swrenderer // [ZZ] Only if not an active mirror if (!markportal) { - RenderDecal::RenderDecals(Thread, mLineSegment->sidedef, draw_segment, wallshade, rw_lightleft, rw_lightstep, mLineSegment, WallC, foggy, basecolormap, walltop.ScreenY, wallbottom.ScreenY, false); + RenderDecal::RenderDecals(Thread, mLineSegment->sidedef, draw_segment, lightlevel, rw_lightleft, rw_lightstep, mLineSegment, WallC, foggy, basecolormap, walltop.ScreenY, wallbottom.ScreenY, false); } if (markportal) @@ -789,7 +789,7 @@ namespace swrenderer CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0) { - wallshade = LightVisibility::LightLevelToShade(mLineSegment->sidedef->GetLightLevel(foggy, mFrontSector->lightlevel), foggy, Thread->Viewport.get()); + lightlevel = mLineSegment->sidedef->GetLightLevel(foggy, mFrontSector->lightlevel); rw_lightleft = float(Thread->Light->WallVis(WallC.sz1, foggy)); rw_lightstep = float((Thread->Light->WallVis(WallC.sz2, foggy) - rw_lightleft) / (WallC.sx2 - WallC.sx1)); } @@ -1181,7 +1181,7 @@ namespace swrenderer light_list = nullptr; // [SP] Don't draw dynlights if invul/lightamp active RenderWallPart renderWallpart(Thread); - renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, wallshade, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); + renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, mTopPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mBackCeilingZ1, mBackCeilingZ2), false, lightlevel, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); } void SWRenderLine::RenderMiddleTexture(int x1, int x2) @@ -1228,7 +1228,7 @@ namespace swrenderer light_list = nullptr; // [SP] Don't draw dynlights if invul/lightamp active RenderWallPart renderWallpart(Thread); - renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, wallshade, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); + renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, mMiddlePart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mFrontCeilingZ1, mFrontCeilingZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, lightlevel, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); } void SWRenderLine::RenderBottomTexture(int x1, int x2) @@ -1276,7 +1276,7 @@ namespace swrenderer light_list = nullptr; // [SP] Don't draw dynlights if invul/lightamp active RenderWallPart renderWallpart(Thread); - renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, wallshade, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); + renderWallpart.Render(drawerargs, mFrontSector, mLineSegment, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, mBottomPart.TextureMid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(mBackFloorZ1, mBackFloorZ2), MIN(mFrontFloorZ1, mFrontFloorZ2), false, lightlevel, offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); } //////////////////////////////////////////////////////////////////////////// diff --git a/src/swrenderer/line/r_line.h b/src/swrenderer/line/r_line.h index dbe2cbb60..0b7283fc0 100644 --- a/src/swrenderer/line/r_line.h +++ b/src/swrenderer/line/r_line.h @@ -133,7 +133,7 @@ namespace swrenderer bool rw_prepped; - int wallshade; + int lightlevel; float rw_lightstep; float rw_lightleft; diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index f4350b136..31653cdba 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -97,7 +97,7 @@ namespace swrenderer FDynamicColormap *basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::walltop]); // [RH] Set basecolormap - int wallshade = ds->shade; + int lightlevel = ds->lightlevel; rw_lightstep = ds->lightstep; rw_light = ds->light + (x1 - ds->x1) * rw_lightstep; @@ -113,8 +113,8 @@ namespace swrenderer { lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), ds->foggy, viewport); + //bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag + lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } @@ -129,7 +129,7 @@ namespace swrenderer const short *mceilingclip = ds->sprtopclip - ds->x1; RenderFogBoundary renderfog; - renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, wallshade, rw_light, rw_lightstep, basecolormap); + renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, LightVisibility::LightLevelToShade(lightlevel, ds->foggy, Thread->Viewport.get()), rw_light, rw_lightstep, basecolormap); if (ds->maskedtexturecol == nullptr) renderwall = false; @@ -140,11 +140,11 @@ namespace swrenderer } if (renderwall) - notrelevant = RenderWall(ds, x1, x2, walldrawerargs, columndrawerargs, visible, basecolormap, wallshade); + notrelevant = RenderWall(ds, x1, x2, walldrawerargs, columndrawerargs, visible, basecolormap, lightlevel); if (ds->Has3DFloorFrontSectorWalls() || ds->Has3DFloorBackSectorWalls()) { - RenderFakeWallRange(ds, x1, x2, wallshade); + RenderFakeWallRange(ds, x1, x2); } if (!notrelevant) { @@ -153,7 +153,7 @@ namespace swrenderer } } - bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int wallshade) + bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int lightlevel) { auto renderstyle = DefaultRenderStyle(); auto viewport = Thread->Viewport.get(); @@ -336,7 +336,7 @@ namespace swrenderer { if (cameraLight->FixedColormap() == nullptr && cameraLight->FixedLightLevel() < 0) { - columndrawerargs.SetLight(basecolormap, rw_light, wallshade); + columndrawerargs.SetLight(basecolormap, rw_light, lightlevel, ds->foggy, Thread->Viewport.get()); } fixed_t iscale = xs_Fix<16>::ToFix(MaskedSWall[x] * MaskedScaleY); @@ -413,14 +413,14 @@ namespace swrenderer GetMaskedWallTopBottom(ds, top, bot); RenderWallPart renderWallpart(Thread); - renderWallpart.Render(walldrawerargs, frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); + renderWallpart.Render(walldrawerargs, frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, lightlevel, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); } return false; } // kg3D - render one fake wall - void RenderDrawSegment::RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap, double clipTop, double clipBottom) + void RenderDrawSegment::RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int lightlevel, FDynamicColormap *basecolormap, double clipTop, double clipBottom) { int i; double xscale; @@ -524,13 +524,13 @@ namespace swrenderer GetMaskedWallTopBottom(ds, top, bot); RenderWallPart renderWallpart(Thread); - renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); + renderWallpart.Render(drawerargs, frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, lightlevel, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); - RenderDecal::RenderDecals(Thread, curline->sidedef, ds, wallshade, rw_light, rw_lightstep, curline, WallC, ds->foggy, basecolormap, wallupper.ScreenY, walllower.ScreenY, true); + RenderDecal::RenderDecals(Thread, curline->sidedef, ds, lightlevel, rw_light, rw_lightstep, curline, WallC, ds->foggy, basecolormap, wallupper.ScreenY, walllower.ScreenY, true); } // kg3D - walls of fake floors - void RenderDrawSegment::RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade) + void RenderDrawSegment::RenderFakeWallRange(DrawSegment *ds, int x1, int x2) { FSoftwareTexture *const DONT_DRAW = ((FSoftwareTexture*)(intptr_t)-1); int i, j; @@ -719,7 +719,7 @@ namespace swrenderer } // correct colors now FDynamicColormap *basecolormap = nullptr; - wallshade = ds->shade; + int lightlevel = ds->lightlevel; CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() < 0) { @@ -731,8 +731,8 @@ namespace swrenderer { lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), foggy, Thread->Viewport.get()); + //bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag + lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } @@ -745,8 +745,8 @@ namespace swrenderer { lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), foggy, Thread->Viewport.get()); + //bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag + lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } @@ -756,7 +756,7 @@ namespace swrenderer if (rw_pic != DONT_DRAW) { - RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap, clipTop, clipBottom); + RenderFakeWall(ds, x1, x2, fover ? fover : rover, lightlevel, basecolormap, clipTop, clipBottom); } else rw_pic = nullptr; break; @@ -905,7 +905,7 @@ namespace swrenderer } // correct colors now FDynamicColormap *basecolormap = nullptr; - wallshade = ds->shade; + int lightlevel = ds->lightlevel; CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() < 0) { @@ -918,7 +918,7 @@ namespace swrenderer lightlist_t *lit = &backsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), foggy, Thread->Viewport.get()); + lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } @@ -932,7 +932,7 @@ namespace swrenderer lightlist_t *lit = &frontsector->e->XFloor.lightlist[j]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // [RH] set foggy flag - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr), foggy, Thread->Viewport.get()); + lightlevel = curline->sidedef->GetLightLevel(ds->foggy, *lit->p_lightlevel, lit->lightsource != nullptr); break; } } @@ -942,7 +942,7 @@ namespace swrenderer if (rw_pic != DONT_DRAW) { - RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap, clipTop, clipBottom); + RenderFakeWall(ds, x1, x2, fover ? fover : rover, lightlevel, basecolormap, clipTop, clipBottom); } else { diff --git a/src/swrenderer/line/r_renderdrawsegment.h b/src/swrenderer/line/r_renderdrawsegment.h index 3c45c9ab5..229e8705d 100644 --- a/src/swrenderer/line/r_renderdrawsegment.h +++ b/src/swrenderer/line/r_renderdrawsegment.h @@ -37,10 +37,10 @@ namespace swrenderer RenderThread *Thread = nullptr; private: - bool RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int wallshade); + bool RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int lightlevel); void ClipMidtex(int x1, int x2); - void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap, double clipTop, double clipBottom); - void RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade); + void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int lightlevel, FDynamicColormap *basecolormap, double clipTop, double clipBottom); + void RenderFakeWallRange(DrawSegment *ds, int x1, int x2); void GetMaskedWallTopBottom(DrawSegment *ds, double &top, double &bot); sector_t *frontsector = nullptr; diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index 9c4e41932..fd85413ee 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -374,7 +374,7 @@ namespace swrenderer continue; if (!fixed) - drawerargs.SetLight(basecolormap, curlight, wallshade); + drawerargs.SetLight(basecolormap, curlight, lightlevel, foggy, Thread->Viewport.get()); if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x])); @@ -422,7 +422,7 @@ namespace swrenderer lightlist_t *lit = &frontsector->e->XFloor.lightlist[i]; basecolormap = GetColorTable(lit->extra_colormap, frontsector->SpecialColors[sector_t::walltop]); - wallshade = LightVisibility::LightLevelToShade(curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != NULL), foggy, Thread->Viewport.get()); + lightlevel = curline->sidedef->GetLightLevel(foggy, *lit->p_lightlevel, lit->lightsource != NULL); } ProcessNormalWall(up, dwal, texturemid, swal, lwal); @@ -519,7 +519,7 @@ namespace swrenderer } } - 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) + 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 lightlevel, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap) { this->drawerargs = drawerargs; this->x1 = x1; @@ -528,7 +528,7 @@ namespace swrenderer this->curline = curline; this->WallC = WallC; this->yrepeat = yscale; - this->wallshade = wallshade; + this->lightlevel = lightlevel; this->xoffset = xoffset; this->light = light; this->lightstep = lightstep; diff --git a/src/swrenderer/line/r_walldraw.h b/src/swrenderer/line/r_walldraw.h index b3a47a7d3..b44484b15 100644 --- a/src/swrenderer/line/r_walldraw.h +++ b/src/swrenderer/line/r_walldraw.h @@ -62,7 +62,7 @@ namespace swrenderer double top, double bottom, bool mask, - int wallshade, + int lightlevel, fixed_t xoffset, float light, float lightstep, @@ -88,7 +88,7 @@ namespace swrenderer FWallCoords WallC; double yrepeat = 0.0; - int wallshade = 0; + int lightlevel = 0; fixed_t xoffset = 0; float light = 0.0f; float lightstep = 0.0f; diff --git a/src/swrenderer/segments/r_drawsegment.h b/src/swrenderer/segments/r_drawsegment.h index a43e4dc28..8df4153ca 100644 --- a/src/swrenderer/segments/r_drawsegment.h +++ b/src/swrenderer/segments/r_drawsegment.h @@ -38,7 +38,7 @@ namespace swrenderer float yscale; uint8_t silhouette = 0; // 0=none, 1=bottom, 2=top, 3=both bool bFogBoundary = false; - int shade = 0; + int lightlevel = 0; bool foggy = false; // Pointers to lists for sprite clipping, all three adjusted so [x1] is first value. diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index a0a77da0d..f5393ce0b 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -57,15 +57,15 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); namespace swrenderer { - void RenderDecal::RenderDecals(RenderThread *thread, side_t *sidedef, DrawSegment *draw_segment, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass) + void RenderDecal::RenderDecals(RenderThread *thread, side_t *sidedef, DrawSegment *draw_segment, int lightlevel, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass) { for (DBaseDecal *decal = sidedef->AttachedDecals; decal != NULL; decal = decal->WallNext) { - Render(thread, sidedef, decal, draw_segment, wallshade, lightleft, lightstep, curline, wallC, foggy, basecolormap, walltop, wallbottom, drawsegPass); + Render(thread, sidedef, decal, draw_segment, lightlevel, lightleft, lightstep, curline, wallC, foggy, basecolormap, walltop, wallbottom, drawsegPass); } } - void RenderDecal::Render(RenderThread *thread, side_t *wall, DBaseDecal *decal, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, const FWallCoords &savecoord, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass) + void RenderDecal::Render(RenderThread *thread, side_t *wall, DBaseDecal *decal, DrawSegment *clipper, int lightlevel, float lightleft, float lightstep, seg_t *curline, const FWallCoords &savecoord, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass) { DVector2 decal_left, decal_right, decal_pos; int x1, x2; @@ -318,7 +318,7 @@ namespace swrenderer { if (calclighting) { // calculate lighting - drawerargs.SetLight(usecolormap, light, wallshade); + drawerargs.SetLight(usecolormap, light, lightlevel, foggy, thread->Viewport.get()); } DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, decal->RenderStyle); light += lightstep; diff --git a/src/swrenderer/things/r_decal.h b/src/swrenderer/things/r_decal.h index 82eab4d8f..3fe3956b1 100644 --- a/src/swrenderer/things/r_decal.h +++ b/src/swrenderer/things/r_decal.h @@ -12,10 +12,10 @@ namespace swrenderer class RenderDecal { public: - static void RenderDecals(RenderThread *thread, side_t *wall, DrawSegment *draw_segment, 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 RenderDecals(RenderThread *thread, side_t *wall, DrawSegment *draw_segment, int lightlevel, float lightleft, float lightstep, seg_t *curline, const FWallCoords &wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, bool drawsegPass); 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 Render(RenderThread *thread, side_t *wall, DBaseDecal *first, DrawSegment *clipper, int lightlevel, 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, FSoftwareTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, FRenderStyle style); }; } diff --git a/src/swrenderer/viewport/r_drawerargs.cpp b/src/swrenderer/viewport/r_drawerargs.cpp index 19e9d6682..3306381a4 100644 --- a/src/swrenderer/viewport/r_drawerargs.cpp +++ b/src/swrenderer/viewport/r_drawerargs.cpp @@ -24,6 +24,11 @@ namespace swrenderer { + void DrawerArgs::SetLight(FSWColormap *base_colormap, float light, int lightlevel, bool foggy, RenderViewport *viewport) + { + SetLight(base_colormap, light, LightVisibility::LightLevelToShade(lightlevel, foggy, viewport)); + } + void DrawerArgs::SetLight(FSWColormap *base_colormap, float light, int shade) { mBaseColormap = base_colormap; diff --git a/src/swrenderer/viewport/r_drawerargs.h b/src/swrenderer/viewport/r_drawerargs.h index f1c5fc556..1ba8d5e61 100644 --- a/src/swrenderer/viewport/r_drawerargs.h +++ b/src/swrenderer/viewport/r_drawerargs.h @@ -31,6 +31,7 @@ namespace swrenderer { public: void SetLight(FSWColormap *base_colormap, float light, int shade); + void SetLight(FSWColormap *base_colormap, float light, int lightlevel, bool foggy, RenderViewport *viewport); void SetTranslationMap(lighttable_t *translation); uint8_t *Colormap(RenderViewport *viewport) const; From 2ce91ea62f505cc71949260533d0c221afacb2e3 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Mon, 17 Dec 2018 07:54:46 +0100 Subject: [PATCH 110/113] - delay converting sprite lightlevels to a shade until we hit ColormapLight --- src/swrenderer/line/r_fogboundary.cpp | 5 +++-- src/swrenderer/line/r_fogboundary.h | 2 +- src/swrenderer/line/r_renderdrawsegment.cpp | 2 +- src/swrenderer/plane/r_flatplane.cpp | 4 ++-- src/swrenderer/plane/r_flatplane.h | 2 +- src/swrenderer/plane/r_slopeplane.cpp | 6 +++--- src/swrenderer/plane/r_slopeplane.h | 3 ++- src/swrenderer/scene/r_light.cpp | 22 ++++++++++++++------- src/swrenderer/scene/r_light.h | 4 +--- src/swrenderer/scene/r_opaque_pass.cpp | 17 +++++++--------- src/swrenderer/things/r_particle.cpp | 4 ++-- src/swrenderer/things/r_playersprite.cpp | 8 ++++---- src/swrenderer/things/r_playersprite.h | 2 +- src/swrenderer/things/r_sprite.cpp | 4 ++-- src/swrenderer/things/r_sprite.h | 2 +- src/swrenderer/things/r_visiblesprite.cpp | 4 +--- src/swrenderer/things/r_voxel.cpp | 4 ++-- src/swrenderer/things/r_voxel.h | 2 +- src/swrenderer/things/r_wallsprite.cpp | 7 +++---- src/swrenderer/things/r_wallsprite.h | 2 +- src/swrenderer/viewport/r_spandrawer.cpp | 4 ++-- src/swrenderer/viewport/r_spandrawer.h | 2 +- 22 files changed, 57 insertions(+), 55 deletions(-) diff --git a/src/swrenderer/line/r_fogboundary.cpp b/src/swrenderer/line/r_fogboundary.cpp index 1b8f1c99d..ae222200c 100644 --- a/src/swrenderer/line/r_fogboundary.cpp +++ b/src/swrenderer/line/r_fogboundary.cpp @@ -54,12 +54,13 @@ namespace swrenderer { - void RenderFogBoundary::Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap) + void RenderFogBoundary::Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, int lightlevel, bool foggy, float lightleft, float lightstep, FDynamicColormap *basecolormap) { // This is essentially the same as R_MapVisPlane but with an extra step // to create new horizontal spans whenever the light changes enough that // we need to use a new colormap. + int wallshade = LightVisibility::LightLevelToShade(lightlevel, foggy, thread->Viewport.get()); float light = lightleft + lightstep*(x2 - x1 - 1); int x = x2 - 1; int t2 = uclip[x]; @@ -73,7 +74,7 @@ namespace swrenderer fillshort(spanend + t2, b2 - t2, x); } - drawerargs.SetLight(basecolormap, (float)light, wallshade); + drawerargs.SetLight(basecolormap, (float)light, lightlevel, foggy, thread->Viewport.get()); uint8_t *fake_dc_colormap = basecolormap->Maps + (GETPALOOKUP(light, wallshade) << COLORMAPSHIFT); diff --git a/src/swrenderer/line/r_fogboundary.h b/src/swrenderer/line/r_fogboundary.h index b506ec7f8..3da57d583 100644 --- a/src/swrenderer/line/r_fogboundary.h +++ b/src/swrenderer/line/r_fogboundary.h @@ -31,7 +31,7 @@ namespace swrenderer class RenderFogBoundary { public: - void Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, int wallshade, float lightleft, float lightstep, FDynamicColormap *basecolormap); + void Render(RenderThread *thread, int x1, int x2, const short *uclip, const short *dclip, int lightlevel, bool foggy, float lightleft, float lightstep, FDynamicColormap *basecolormap); private: void RenderSection(RenderThread *thread, int y, int y2, int x1); diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index 31653cdba..f1a11c454 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -129,7 +129,7 @@ namespace swrenderer const short *mceilingclip = ds->sprtopclip - ds->x1; RenderFogBoundary renderfog; - renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, LightVisibility::LightLevelToShade(lightlevel, ds->foggy, Thread->Viewport.get()), rw_light, rw_lightstep, basecolormap); + renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, lightlevel, ds->foggy, rw_light, rw_lightstep, basecolormap); if (ds->maskedtexturecol == nullptr) renderwall = false; diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index 3f86f921f..3cbd9ce0d 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -153,7 +153,7 @@ namespace swrenderer else { plane_shade = true; - planeshade = LightVisibility::LightLevelToShade(pl->lightlevel, foggy, viewport); + lightlevel = pl->lightlevel; } drawerargs.SetStyle(masked, additive, alpha); @@ -200,7 +200,7 @@ namespace swrenderer if (plane_shade) { // Determine lighting based on the span's distance from the viewer. - drawerargs.SetLight(basecolormap, (float)Thread->Light->FlatPlaneVis(y, planeheight, foggy, viewport), planeshade); + drawerargs.SetLight(basecolormap, (float)Thread->Light->FlatPlaneVis(y, planeheight, foggy, viewport), lightlevel, foggy, viewport); } if (r_dynlights) diff --git a/src/swrenderer/plane/r_flatplane.h b/src/swrenderer/plane/r_flatplane.h index 537d8a6d0..fa12101d7 100644 --- a/src/swrenderer/plane/r_flatplane.h +++ b/src/swrenderer/plane/r_flatplane.h @@ -44,7 +44,7 @@ namespace swrenderer int minx; double planeheight; bool plane_shade; - int planeshade; + int lightlevel; bool foggy; FDynamicColormap *basecolormap; double pviewx, pviewy; diff --git a/src/swrenderer/plane/r_slopeplane.cpp b/src/swrenderer/plane/r_slopeplane.cpp index 61e085489..0f4ac159a 100644 --- a/src/swrenderer/plane/r_slopeplane.cpp +++ b/src/swrenderer/plane/r_slopeplane.cpp @@ -174,7 +174,7 @@ namespace swrenderer // [RH] set foggy flag basecolormap = colormap; - bool foggy = level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE);; + foggy = level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE);; planelightfloat = (Thread->Light->SlopePlaneGlobVis(foggy) * lxscale * lyscale) / (fabs(pl->height.ZatPoint(Thread->Viewport->viewpoint.Pos) - Thread->Viewport->viewpoint.Pos.Z)) / 65536.f; @@ -197,7 +197,7 @@ namespace swrenderer { drawerargs.SetLight(basecolormap, 0, 0); plane_shade = true; - planeshade = LightVisibility::LightLevelToShade(pl->lightlevel, foggy, viewport); + lightlevel = pl->lightlevel; } // Hack in support for 1 x Z and Z x 1 texture sizes @@ -215,7 +215,7 @@ namespace swrenderer void RenderSlopePlane::RenderLine(int y, int x1, int x2) { - drawerargs.DrawTiltedSpan(Thread, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap); + drawerargs.DrawTiltedSpan(Thread, y, x1, x2, plane_sz, plane_su, plane_sv, plane_shade, lightlevel, foggy, planelightfloat, pviewx, pviewy, basecolormap); if (r_modelscene) { diff --git a/src/swrenderer/plane/r_slopeplane.h b/src/swrenderer/plane/r_slopeplane.h index 88ef199cb..b074492fc 100644 --- a/src/swrenderer/plane/r_slopeplane.h +++ b/src/swrenderer/plane/r_slopeplane.h @@ -43,7 +43,8 @@ namespace swrenderer FVector3 plane_sz, plane_su, plane_sv; float planelightfloat; bool plane_shade; - int planeshade; + int lightlevel; + bool foggy; fixed_t pviewx, pviewy; fixed_t xscale, yscale; FDynamicColormap *basecolormap; diff --git a/src/swrenderer/scene/r_light.cpp b/src/swrenderer/scene/r_light.cpp index 42468374a..73a9e84d7 100644 --- a/src/swrenderer/scene/r_light.cpp +++ b/src/swrenderer/scene/r_light.cpp @@ -160,7 +160,7 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////// - void ColormapLight::SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack) + void ColormapLight::SetColormap(RenderThread *thread, double z, int lightlevel, bool foggy, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack, bool psprite, bool particle) { if (fadeToBlack) { @@ -181,16 +181,16 @@ namespace swrenderer } CameraLight *cameraLight = CameraLight::Instance(); - if (cameraLight->FixedColormap()) - { - BaseColormap = cameraLight->FixedColormap(); - ColormapNum = 0; - } - else if (cameraLight->FixedLightLevel() >= 0) + if (cameraLight->FixedLightLevel() >= 0) { BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap; ColormapNum = cameraLight->FixedLightLevel() >> COLORMAPSHIFT; } + else if (cameraLight->FixedColormap()) + { + BaseColormap = cameraLight->FixedColormap(); + ColormapNum = 0; + } else if (fullbright) { BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap; @@ -198,6 +198,14 @@ namespace swrenderer } else { + double visibility = thread->Light->SpriteVis(z, foggy); + if (particle) + visibility *= 0.5; + + int shade = LightVisibility::LightLevelToShade(lightlevel, foggy, thread->Viewport.get()); + if (psprite) + shade -= 24 * FRACUNIT; + BaseColormap = basecolormap; ColormapNum = GETPALOOKUP(visibility, shade); } diff --git a/src/swrenderer/scene/r_light.h b/src/swrenderer/scene/r_light.h index 8d6791e5d..5c2938cec 100644 --- a/src/swrenderer/scene/r_light.h +++ b/src/swrenderer/scene/r_light.h @@ -83,7 +83,6 @@ namespace swrenderer // The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros double WallVis(double screenZ, bool foggy) const { return WallGlobVis(foggy) / screenZ; } double SpriteVis(double screenZ, bool foggy) const { return SpriteGlobVis(foggy) / MAX(screenZ, MINZ); } - double ParticleVis(double screenZ, bool foggy) const { return ParticleGlobVis(foggy) / screenZ; } double FlatPlaneVis(int screenY, double planeheight, bool foggy, RenderViewport *viewport) const { return FlatPlaneGlobVis(foggy) / planeheight * fabs(viewport->CenterY - screenY); } double SlopePlaneGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : TiltVisibility; } @@ -95,7 +94,6 @@ namespace swrenderer private: double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; } double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; } - double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : (WallVisibility * 0.5); } double FlatPlaneGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : FloorVisibility; } static fixed_t LightLevelToShadeImpl(int lightlevel, bool foggy); @@ -118,6 +116,6 @@ namespace swrenderer int ColormapNum = 0; FSWColormap *BaseColormap = nullptr; - void SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack); + void SetColormap(RenderThread *thread, double z, int lightlevel, bool foggy, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack, bool psprite, bool particle); }; } diff --git a/src/swrenderer/scene/r_opaque_pass.cpp b/src/swrenderer/scene/r_opaque_pass.cpp index a940745bd..30f656296 100644 --- a/src/swrenderer/scene/r_opaque_pass.cpp +++ b/src/swrenderer/scene/r_opaque_pass.cpp @@ -613,10 +613,10 @@ namespace swrenderer // [RH] Add particles if ((unsigned int)(sub->Index()) < level.subsectors.Size()) { // Only do it for the main BSP. - int shade = LightVisibility::LightLevelToShade((floorlightlevel + ceilinglightlevel) / 2, foggy, Thread->Viewport.get()); + int lightlevel = (floorlightlevel + ceilinglightlevel) / 2; 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, lightlevel, FakeSide, foggy); } } @@ -891,8 +891,6 @@ namespace swrenderer //sec->validcount = validcount; SeenSpriteSectors.insert(sec); - int spriteshade = LightVisibility::LightLevelToShade(lightlevel, foggy, Thread->Viewport.get()); - // Handle all things in sector. for (auto p = sec->touching_renderthings; p != nullptr; p = p->m_snext) { @@ -947,25 +945,24 @@ namespace swrenderer else if (GetThingSprite(thing, sprite)) { FDynamicColormap *thingColormap = basecolormap; - int thingShade = spriteshade; + int thinglightlevel = lightlevel; if (sec->sectornum != thing->Sector->sectornum) // compare sectornums to account for R_FakeFlat copies. { - int lightlevel = thing->Sector->GetTexture(sector_t::ceiling) == skyflatnum ? thing->Sector->GetCeilingLight() : thing->Sector->GetFloorLight(); - thingShade = LightVisibility::LightLevelToShade(lightlevel, foggy, Thread->Viewport.get()); + thinglightlevel = thing->Sector->GetTexture(sector_t::ceiling) == skyflatnum ? thing->Sector->GetCeilingLight() : thing->Sector->GetFloorLight(); thingColormap = GetColorTable(thing->Sector->Colormap, thing->Sector->SpecialColors[sector_t::sprites], true); } if ((sprite.renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) { - RenderWallSprite::Project(Thread, thing, sprite.pos, sprite.tex, sprite.spriteScale, sprite.renderflags, thingShade, foggy, thingColormap); + RenderWallSprite::Project(Thread, thing, sprite.pos, sprite.tex, sprite.spriteScale, sprite.renderflags, thinglightlevel, foggy, thingColormap); } else if (sprite.voxel) { - RenderVoxel::Project(Thread, thing, sprite.pos, sprite.voxel, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap); + RenderVoxel::Project(Thread, thing, sprite.pos, sprite.voxel, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thinglightlevel, foggy, thingColormap); } else { - RenderSprite::Project(Thread, thing, sprite.pos, sprite.tex, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thingShade, foggy, thingColormap); + RenderSprite::Project(Thread, thing, sprite.pos, sprite.tex, sprite.spriteScale, sprite.renderflags, fakeside, fakefloor, fakeceiling, sec, thinglightlevel, foggy, thingColormap); } } } diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index 69c739da9..c3b53fcf1 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -69,7 +69,7 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); namespace swrenderer { - void RenderParticle::Project(RenderThread *thread, particle_t *particle, const sector_t *sector, int shade, WaterFakeSide fakeside, bool foggy) + void RenderParticle::Project(RenderThread *thread, particle_t *particle, const sector_t *sector, int lightlevel, WaterFakeSide fakeside, bool foggy) { double tr_x, tr_y; double tx, ty; @@ -220,7 +220,7 @@ namespace swrenderer vis->floorclip = 0; vis->foggy = foggy; - vis->Light.SetColormap(thread->Light->ParticleVis(tz, foggy), shade, map, particle->bright != 0, false, false); + vis->Light.SetColormap(thread, tz, lightlevel, foggy, map, particle->bright != 0, false, false, false, true); thread->SpriteList->Push(vis); } diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 853e99e61..c206c4863 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -137,7 +137,7 @@ namespace swrenderer bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE)); // get light level - int spriteshade = LightVisibility::LightLevelToShade((floorlight + ceilinglight) >> 1, foggy, Thread->Viewport.get()) - 24 * FRACUNIT; + int lightlevel = (floorlight + ceilinglight) >> 1; if (Thread->Viewport->viewpoint.camera->player != NULL) { @@ -182,7 +182,7 @@ namespace swrenderer if ((psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) && psp->GetCaller() != nullptr) { - RenderSprite(psp, viewport->viewpoint.camera, bobx, boby, wx, wy, viewport->viewpoint.TicFrac, spriteshade, basecolormap, foggy); + RenderSprite(psp, viewport->viewpoint.camera, bobx, boby, wx, wy, viewport->viewpoint.TicFrac, lightlevel, basecolormap, foggy); } psp = psp->GetNext(); @@ -192,7 +192,7 @@ namespace swrenderer } } - void RenderPlayerSprites::RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy) + void RenderPlayerSprites::RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int lightlevel, FDynamicColormap *basecolormap, bool foggy) { double tx; int x1; @@ -350,7 +350,7 @@ namespace swrenderer bool fullbright = !foggy && (psprState == nullptr ? false : psprState->GetFullbright()); bool fadeToBlack = (vis.RenderStyle.Flags & STYLEF_FadeToBlack) != 0; - vis.Light.SetColormap(0, spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); + vis.Light.SetColormap(Thread, MINZ, lightlevel, foggy, basecolormap, fullbright, invertcolormap, fadeToBlack, true, false); colormap_to_use = (FDynamicColormap*)vis.Light.BaseColormap; diff --git a/src/swrenderer/things/r_playersprite.h b/src/swrenderer/things/r_playersprite.h index 6b7be57c1..494e693f2 100644 --- a/src/swrenderer/things/r_playersprite.h +++ b/src/swrenderer/things/r_playersprite.h @@ -90,7 +90,7 @@ namespace swrenderer RenderThread *Thread = nullptr; private: - void RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy); + void RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int lightlevel, FDynamicColormap *basecolormap, bool foggy); enum { BASEXCENTER = 160 }; enum { BASEYCENTER = 100 }; diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index c553eb56a..1daa0b62a 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -72,7 +72,7 @@ EXTERN_CVAR(Bool, gl_light_sprites) namespace swrenderer { - 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) + 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 lightlevel, bool foggy, FDynamicColormap *basecolormap) { FSoftwareTexture *tex = ttex->GetSoftwareTexture(); // transform the origin point @@ -300,7 +300,7 @@ namespace swrenderer vis->dynlightcolor = 0; } - vis->Light.SetColormap(thread->Light->SpriteVis(tz, foggy), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); + vis->Light.SetColormap(thread, tz, lightlevel, foggy, basecolormap, fullbright, invertcolormap, fadeToBlack, false, false); thread->SpriteList->Push(vis); } diff --git a/src/swrenderer/things/r_sprite.h b/src/swrenderer/things/r_sprite.h index 8fe53080e..fefe5df68 100644 --- a/src/swrenderer/things/r_sprite.h +++ b/src/swrenderer/things/r_sprite.h @@ -7,7 +7,7 @@ namespace swrenderer class RenderSprite : public VisibleSprite { public: - static void 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); + static void 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 lightlevel, bool foggy, FDynamicColormap *basecolormap); protected: void Render(RenderThread *thread, short *cliptop, short *clipbottom, int minZ, int maxZ, Fake3DTranslucent clip3DFloor) override; diff --git a/src/swrenderer/things/r_visiblesprite.cpp b/src/swrenderer/things/r_visiblesprite.cpp index f596ba76d..7145e2b1e 100644 --- a/src/swrenderer/things/r_visiblesprite.cpp +++ b/src/swrenderer/things/r_visiblesprite.cpp @@ -163,9 +163,7 @@ namespace swrenderer bool isFullBright = !foggy && (renderflags & RF_FULLBRIGHT); bool fadeToBlack = spr->RenderStyle == LegacyRenderStyles[STYLE_Add] && mybasecolormap->Fade != 0; - int spriteshade = LightVisibility::LightLevelToShade(sec->lightlevel, foggy, thread->Viewport.get()); - - Light.SetColormap(thread->Light->SpriteVis(spr->depth, foggy), spriteshade, mybasecolormap, isFullBright, invertcolormap, fadeToBlack); + Light.SetColormap(thread, spr->depth, sec->lightlevel, foggy, mybasecolormap, isFullBright, invertcolormap, fadeToBlack, false, false); } } diff --git a/src/swrenderer/things/r_voxel.cpp b/src/swrenderer/things/r_voxel.cpp index 57f9d1bbf..30b8dc259 100644 --- a/src/swrenderer/things/r_voxel.cpp +++ b/src/swrenderer/things/r_voxel.cpp @@ -60,7 +60,7 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor) namespace swrenderer { - void RenderVoxel::Project(RenderThread *thread, AActor *thing, DVector3 pos, FVoxelDef *voxel, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap) + void RenderVoxel::Project(RenderThread *thread, AActor *thing, DVector3 pos, FVoxelDef *voxel, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int lightlevel, bool foggy, FDynamicColormap *basecolormap) { // transform the origin point double tr_x = pos.X - thread->Viewport->viewpoint.Pos.X; @@ -188,7 +188,7 @@ namespace swrenderer bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)); bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0; - vis->Light.SetColormap(thread->Light->SpriteVis(tz, foggy), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack); + vis->Light.SetColormap(thread, tz, lightlevel, foggy, basecolormap, fullbright, invertcolormap, fadeToBlack, false, false); // Fake a voxel drawing to find its extents.. SpriteDrawerArgs drawerargs; diff --git a/src/swrenderer/things/r_voxel.h b/src/swrenderer/things/r_voxel.h index 7121d3498..d9164899b 100644 --- a/src/swrenderer/things/r_voxel.h +++ b/src/swrenderer/things/r_voxel.h @@ -58,7 +58,7 @@ namespace swrenderer class RenderVoxel : public VisibleSprite { public: - static void Project(RenderThread *thread, AActor *thing, DVector3 pos, FVoxelDef *voxel, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int spriteshade, bool foggy, FDynamicColormap *basecolormap); + static void Project(RenderThread *thread, AActor *thing, DVector3 pos, FVoxelDef *voxel, const DVector2 &spriteScale, int renderflags, WaterFakeSide fakeside, F3DFloor *fakefloor, F3DFloor *fakeceiling, sector_t *current_sector, int lightlevel, bool foggy, FDynamicColormap *basecolormap); static void Deinit(); diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index 296872485..2046fe2f3 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -71,7 +71,7 @@ EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor); namespace swrenderer { - void RenderWallSprite::Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *ppic, 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 lightlevel, bool foggy, FDynamicColormap *basecolormap) { FSoftwareTexture *pic = ppic->GetSoftwareTexture(); FWallCoords wallc; @@ -141,7 +141,7 @@ namespace swrenderer vis->wallc = wallc; vis->foggy = foggy; - vis->Light.SetColormap(thread->Light->SpriteVis(tz, foggy), spriteshade, basecolormap, false, false, false); + vis->Light.SetColormap(thread, tz, lightlevel, foggy, basecolormap, false, false, false, false, false); thread->SpriteList->Push(vis); } @@ -190,7 +190,6 @@ namespace swrenderer SpriteDrawerArgs drawerargs; - int shade = LightVisibility::LightLevelToShade(spr->sector->lightlevel, spr->foggy, thread->Viewport.get()); float lightleft = float(thread->Light->WallVis(spr->wallc.sz1, foggy)); float lightstep = float((thread->Light->WallVis(spr->wallc.sz2, foggy) - lightleft) / (spr->wallc.sx2 - spr->wallc.sx1)); float light = lightleft + (x1 - spr->wallc.sx1) * lightstep; @@ -244,7 +243,7 @@ namespace swrenderer { if (calclighting) { // calculate lighting - drawerargs.SetLight(usecolormap, light, shade); + drawerargs.SetLight(usecolormap, light, spr->sector->lightlevel, spr->foggy, thread->Viewport.get()); } if (!translucentPass->ClipSpriteColumnWithPortals(x, spr)) DrawColumn(thread, drawerargs, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip, spr->RenderStyle); diff --git a/src/swrenderer/things/r_wallsprite.h b/src/swrenderer/things/r_wallsprite.h index d4851d07c..bcd0a1389 100644 --- a/src/swrenderer/things/r_wallsprite.h +++ b/src/swrenderer/things/r_wallsprite.h @@ -10,7 +10,7 @@ namespace swrenderer class RenderWallSprite : public VisibleSprite { public: - static void Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *pic, const DVector2 &scale, int renderflags, int spriteshade, bool foggy, FDynamicColormap *basecolormap); + static void Project(RenderThread *thread, AActor *thing, const DVector3 &pos, FTexture *pic, const DVector2 &scale, int renderflags, int lightlevel, bool foggy, FDynamicColormap *basecolormap); protected: bool IsWallSprite() const override { return true; } diff --git a/src/swrenderer/viewport/r_spandrawer.cpp b/src/swrenderer/viewport/r_spandrawer.cpp index 665d18e89..69c6ead64 100644 --- a/src/swrenderer/viewport/r_spandrawer.cpp +++ b/src/swrenderer/viewport/r_spandrawer.cpp @@ -117,12 +117,12 @@ namespace swrenderer (thread->Drawers(ds_viewport)->*spanfunc)(*this); } - void SpanDrawerArgs::DrawTiltedSpan(RenderThread *thread, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) + void SpanDrawerArgs::DrawTiltedSpan(RenderThread *thread, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int lightlevel, bool foggy, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap) { SetDestY(thread->Viewport.get(), y); SetDestX1(x1); SetDestX2(x2); - thread->Drawers(ds_viewport)->DrawTiltedSpan(*this, plane_sz, plane_su, plane_sv, plane_shade, planeshade, planelightfloat, pviewx, pviewy, basecolormap); + thread->Drawers(ds_viewport)->DrawTiltedSpan(*this, plane_sz, plane_su, plane_sv, plane_shade, LightVisibility::LightLevelToShade(lightlevel, foggy, thread->Viewport.get()), planelightfloat, pviewx, pviewy, basecolormap); } void SpanDrawerArgs::DrawFogBoundaryLine(RenderThread *thread, int y, int x1, int x2) diff --git a/src/swrenderer/viewport/r_spandrawer.h b/src/swrenderer/viewport/r_spandrawer.h index b31b571b2..8bd2aeb10 100644 --- a/src/swrenderer/viewport/r_spandrawer.h +++ b/src/swrenderer/viewport/r_spandrawer.h @@ -29,7 +29,7 @@ namespace swrenderer void DrawDepthSpan(RenderThread *thread, float idepth1, float idepth2); void DrawSpan(RenderThread *thread); - void DrawTiltedSpan(RenderThread *thread, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int planeshade, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap); + void DrawTiltedSpan(RenderThread *thread, int y, int x1, int x2, const FVector3 &plane_sz, const FVector3 &plane_su, const FVector3 &plane_sv, bool plane_shade, int lightlevel, bool foggy, float planelightfloat, fixed_t pviewx, fixed_t pviewy, FDynamicColormap *basecolormap); void DrawColoredSpan(RenderThread *thread, int y, int x1, int x2); void DrawFogBoundaryLine(RenderThread *thread, int y, int x1, int x2); From fb7156331136754683fdbe2de825b88d067de067 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 17 Dec 2018 12:27:35 +0200 Subject: [PATCH 111/113] - fixed inconsistent dymanic lights setup with UBO https://forum.zdoom.org/viewtopic.php?t=62585 --- src/hwrenderer/dynlights/hw_lightbuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hwrenderer/dynlights/hw_lightbuffer.cpp b/src/hwrenderer/dynlights/hw_lightbuffer.cpp index a9e24353c..bb7c78e9b 100644 --- a/src/hwrenderer/dynlights/hw_lightbuffer.cpp +++ b/src/hwrenderer/dynlights/hw_lightbuffer.cpp @@ -64,7 +64,6 @@ FLightBuffer::FLightBuffer() mBuffer->SetData(mByteSize, nullptr, false); Clear(); - mLastMappedIndex = UINT_MAX; } FLightBuffer::~FLightBuffer() @@ -75,6 +74,7 @@ FLightBuffer::~FLightBuffer() void FLightBuffer::Clear() { mIndex = 0; + mLastMappedIndex = UINT_MAX; } int FLightBuffer::UploadLights(FDynLightData &data) From d68cd3aa80a2dc88fd6080dee4bc0136dc80a871 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 17 Dec 2018 17:44:22 +0100 Subject: [PATCH 112/113] - fixed: Alpha textures need to use a color's grayscale value, not their red channel. --- src/swrenderer/textures/r_swtexture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/swrenderer/textures/r_swtexture.cpp b/src/swrenderer/textures/r_swtexture.cpp index 1b6192eee..89f6f3bda 100644 --- a/src/swrenderer/textures/r_swtexture.cpp +++ b/src/swrenderer/textures/r_swtexture.cpp @@ -140,7 +140,7 @@ const uint8_t *FSoftwareTexture::GetPixels(int style) { for (int x = 0; x < GetPhysicalWidth(); x++) { - Pixels[y + x * GetPhysicalHeight()] = pe[x + y * GetPhysicalWidth()].r; + Pixels[y + x * GetPhysicalHeight()] = pe[x + y * GetPhysicalWidth()].Luminance(); } } } From a73c0658117e36df1cd11d414821e0817c783104 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 17 Dec 2018 18:28:04 +0100 Subject: [PATCH 113/113] - replaced several explicit allocations with TArrays. --- src/posix/sdl/i_system.cpp | 21 +++++----- src/r_data/models/models_voxel.cpp | 6 +-- src/r_data/renderinfo.cpp | 11 ++--- src/r_data/voxels.cpp | 32 +++------------ src/r_data/voxels.h | 4 +- src/resourcefiles/file_pak.cpp | 5 +-- src/textures/formats/jpegtexture.cpp | 15 +++---- src/textures/formats/pcxtexture.cpp | 60 +++++++++++----------------- src/textures/formats/tgatexture.cpp | 20 ++++------ src/win32/i_system.cpp | 7 ++-- 10 files changed, 66 insertions(+), 115 deletions(-) diff --git a/src/posix/sdl/i_system.cpp b/src/posix/sdl/i_system.cpp index 9f4797926..8b73d2f14 100644 --- a/src/posix/sdl/i_system.cpp +++ b/src/posix/sdl/i_system.cpp @@ -240,30 +240,29 @@ void I_DebugPrint(const char *cp) { } -void I_PrintStr (const char *cp) +void I_PrintStr(const char *cp) { - // Strip out any color escape sequences before writing to the log file - char * copy = new char[strlen(cp)+1]; + // Strip out any color escape sequences before writing to debug output + TArray copy(strlen(cp) + 1, true); const char * srcp = cp; - char * dstp = copy; + char * dstp = copy.Data(); while (*srcp != 0) { - if (*srcp!=0x1c && *srcp!=0x1d && *srcp!=0x1e && *srcp!=0x1f) + if (*srcp != 0x1c && *srcp != 0x1d && *srcp != 0x1e && *srcp != 0x1f) { - *dstp++=*srcp++; + *dstp++ = *srcp++; } else { - if (srcp[1]!=0) srcp+=2; + if (srcp[1] != 0) srcp += 2; else break; } } - *dstp=0; + *dstp = 0; - fputs (copy, stdout); - delete [] copy; - fflush (stdout); + fputs(copy.Data(), stdout); + fflush(stdout); } int I_PickIWad (WadStuff *wads, int numwads, bool showwin, int defaultiwad) diff --git a/src/r_data/models/models_voxel.cpp b/src/r_data/models/models_voxel.cpp index 8cda437bc..9a01b6487 100644 --- a/src/r_data/models/models_voxel.cpp +++ b/src/r_data/models/models_voxel.cpp @@ -83,7 +83,7 @@ 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); - uint8_t *pp = SourceVox->Palette; + uint8_t *pp = SourceVox->Palette.Data(); if(pp != NULL) { @@ -120,9 +120,9 @@ int FVoxelTexture::CopyPixels(FBitmap *bmp, int conversion) { PalEntry pe[256]; uint8_t bitmap[256]; - uint8_t *pp = SourceVox->Palette; + uint8_t *pp = SourceVox->Palette.Data(); - if(pp != NULL) + if(pp != nullptr) { for(int i=0;i<256;i++, pp+=3) { diff --git a/src/r_data/renderinfo.cpp b/src/r_data/renderinfo.cpp index 88526d824..7edeef789 100644 --- a/src/r_data/renderinfo.cpp +++ b/src/r_data/renderinfo.cpp @@ -392,7 +392,7 @@ static void AddToVertex(const sector_t * sec, TArray & list) static void InitVertexData() { - auto vt_sectorlists = new TArray[level.vertexes.Size()]; + TArray> vt_sectorlists(level.vertexes.Size(), true); for(auto &line : level.lines) { @@ -437,8 +437,6 @@ static void InitVertexData() vert.numsectors=0; } } - - delete [] vt_sectorlists; } //========================================================================== @@ -478,15 +476,15 @@ static int segcmp(const void *a, const void *b) static void PrepareSegs() { auto numsides = level.sides.Size(); - int *segcount = new int[numsides]; + TArray segcount(numsides, true); int realsegs = 0; // count the segs - memset(segcount, 0, numsides * sizeof(int)); + memset(segcount.Data(), 0, numsides * sizeof(int)); for(auto &seg : level.segs) { - if (seg.sidedef == NULL) continue; // miniseg + if (seg.sidedef == nullptr) continue; // miniseg int sidenum = seg.sidedef->Index(); realsegs++; @@ -509,7 +507,6 @@ static void PrepareSegs() level.sides[i].segs = level.sides[i-1].segs + segcount[i-1]; level.sides[i].numsegs = 0; } - delete [] segcount; // assign the segs for (auto &seg : level.segs) diff --git a/src/r_data/voxels.cpp b/src/r_data/voxels.cpp index 9dc0b7006..a9eb9eb68 100644 --- a/src/r_data/voxels.cpp +++ b/src/r_data/voxels.cpp @@ -303,8 +303,8 @@ FVoxel *R_LoadKVX(int lumpnum) } voxel->LumpNum = lumpnum; - voxel->Palette = new uint8_t[768]; - memcpy(voxel->Palette, rawvoxel + voxelsize - 768, 768); + voxel->Palette.Resize(768); + memcpy(voxel->Palette.Data(), rawvoxel + voxelsize - 768, 768); return voxel; } @@ -382,22 +382,6 @@ uint8_t *FVoxelMipLevel::GetSlabData(bool wantremapped) const return SlabData; } -//========================================================================== -// -// FVoxel Constructor -// -//========================================================================== - -FVoxel::FVoxel() -{ - Palette = NULL; -} - -FVoxel::~FVoxel() -{ - if (Palette != NULL) delete [] Palette; -} - //========================================================================== // // Create true color version of the slab data @@ -430,7 +414,7 @@ void FVoxel::CreateBgraSlabData() int colorIndex = src->col[j]; uint32_t red, green, blue; - if (Palette) + if (Palette.Size()) { red = (Palette[colorIndex * 3 + 0] << 2) | (Palette[colorIndex * 3 + 0] >> 4); green = (Palette[colorIndex * 3 + 1] << 2) | (Palette[colorIndex * 3 + 1] >> 4); @@ -464,9 +448,9 @@ void FVoxel::Remap() { if (Remapped) return; Remapped = true; - if (Palette != NULL) + if (Palette.Size()) { - uint8_t *remap = GetVoxelRemap(Palette); + uint8_t *remap = GetVoxelRemap(Palette.Data()); for (int i = 0; i < NumMips; ++i) { int size = Mips[i].OffsetX[Mips[i].SizeX]; @@ -487,11 +471,7 @@ void FVoxel::Remap() void FVoxel::RemovePalette() { - if (Palette != NULL) - { - delete [] Palette; - Palette = NULL; - } + Palette.Reset(); } diff --git a/src/r_data/voxels.h b/src/r_data/voxels.h index eac1b39ee..60a149be9 100644 --- a/src/r_data/voxels.h +++ b/src/r_data/voxels.h @@ -50,16 +50,14 @@ public: struct FVoxel { + TArray Palette; int LumpNum; int NumMips; int VoxelIndex; - uint8_t *Palette; FVoxelMipLevel Mips[MAXVOXMIPS]; bool Remapped = false; bool Bgramade = false; - FVoxel(); - ~FVoxel(); void CreateBgraSlabData(); void Remap(); void RemovePalette(); diff --git a/src/resourcefiles/file_pak.cpp b/src/resourcefiles/file_pak.cpp index d7f091c02..f679a0564 100644 --- a/src/resourcefiles/file_pak.cpp +++ b/src/resourcefiles/file_pak.cpp @@ -96,9 +96,9 @@ bool FPakFile::Open(bool quiet) NumLumps = LittleLong(header.dirlen) / sizeof(dpackfile_t); header.dirofs = LittleLong(header.dirofs); - dpackfile_t *fileinfo = new dpackfile_t[NumLumps]; + TArray fileinfo(NumLumps, true); Reader.Seek (header.dirofs, FileReader::SeekSet); - Reader.Read (fileinfo, NumLumps * sizeof(dpackfile_t)); + Reader.Read (fileinfo.Data(), NumLumps * sizeof(dpackfile_t)); Lumps.Resize(NumLumps); @@ -113,7 +113,6 @@ bool FPakFile::Open(bool quiet) Lumps[i].CheckEmbedded(); } - delete [] fileinfo; return true; } diff --git a/src/textures/formats/jpegtexture.cpp b/src/textures/formats/jpegtexture.cpp index a441c585b..68ead4a7d 100644 --- a/src/textures/formats/jpegtexture.cpp +++ b/src/textures/formats/jpegtexture.cpp @@ -387,7 +387,6 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) PalEntry pe[256]; auto lump = Wads.OpenLumpReader (SourceLump); - JSAMPLE *buff = NULL; jpeg_decompress_struct cinfo; jpeg_error_mgr jerr; @@ -414,12 +413,11 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) jpeg_start_decompress(&cinfo); int yc = 0; - buff = new uint8_t[cinfo.output_height * cinfo.output_width * cinfo.output_components]; - + TArray buff(cinfo.output_height * cinfo.output_width * cinfo.output_components, true); while (cinfo.output_scanline < cinfo.output_height) { - uint8_t * ptr = buff + cinfo.output_width * cinfo.output_components * yc; + uint8_t * ptr = buff.Data() + cinfo.output_width * cinfo.output_components * yc; jpeg_read_scanlines(&cinfo, &ptr, 1); yc++; } @@ -427,23 +425,23 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) switch (cinfo.out_color_space) { case JCS_RGB: - bmp->CopyPixelDataRGB(0, 0, buff, cinfo.output_width, cinfo.output_height, + bmp->CopyPixelDataRGB(0, 0, buff.Data(), 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(0, 0, buff, cinfo.output_width, cinfo.output_height, + bmp->CopyPixelData(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height, 1, cinfo.output_width, 0, pe); break; case JCS_CMYK: - bmp->CopyPixelDataRGB(0, 0, buff, cinfo.output_width, cinfo.output_height, + bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height, 4, cinfo.output_width * cinfo.output_components, 0, CF_CMYK); break; case JCS_YCbCr: - bmp->CopyPixelDataRGB(0, 0, buff, cinfo.output_width, cinfo.output_height, + bmp->CopyPixelDataRGB(0, 0, buff.Data(), cinfo.output_width, cinfo.output_height, 4, cinfo.output_width * cinfo.output_components, 0, CF_YCbCr); break; @@ -459,7 +457,6 @@ int FJPEGTexture::CopyPixels(FBitmap *bmp, int conversion) Printf(TEXTCOLOR_ORANGE "JPEG error in %s\n", Wads.GetLumpFullPath(SourceLump).GetChars()); } jpeg_destroy_decompress(&cinfo); - if (buff != NULL) delete [] buff; return 0; } diff --git a/src/textures/formats/pcxtexture.cpp b/src/textures/formats/pcxtexture.cpp index ff37ce8aa..70cb7e2e7 100644 --- a/src/textures/formats/pcxtexture.cpp +++ b/src/textures/formats/pcxtexture.cpp @@ -161,9 +161,8 @@ void FPCXTexture::ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr) int rle_count = 0; uint8_t rle_value = 0; - uint8_t * srcp = new uint8_t[lump.GetLength() - sizeof(PCXHeader)]; - lump.Read(srcp, lump.GetLength() - sizeof(PCXHeader)); - uint8_t * src = srcp; + TArray srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); + uint8_t * src = srcp.Data(); for (y = 0; y < Height; ++y) { @@ -196,7 +195,6 @@ void FPCXTexture::ReadPCX1bit (uint8_t *dst, FileReader & lump, PCXHeader *hdr) } } } - delete [] srcp; } //========================================================================== @@ -210,12 +208,11 @@ void FPCXTexture::ReadPCX4bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr) int rle_count = 0, rle_value = 0; int x, y, c; int bytes; - uint8_t * line = new uint8_t[hdr->bytesPerScanLine]; - uint8_t * colorIndex = new uint8_t[Width]; + TArray line(hdr->bytesPerScanLine, true); + TArray colorIndex(Width, true); - uint8_t * srcp = new uint8_t[lump.GetLength() - sizeof(PCXHeader)]; - lump.Read(srcp, lump.GetLength() - sizeof(PCXHeader)); - uint8_t * src = srcp; + TArray srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); + uint8_t * src = srcp.Data(); for (y = 0; y < Height; ++y) { @@ -224,7 +221,7 @@ void FPCXTexture::ReadPCX4bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr) for (c = 0; c < 4; ++c) { - uint8_t * pLine = line; + uint8_t * pLine = line.Data(); bytes = hdr->bytesPerScanLine; @@ -255,11 +252,6 @@ void FPCXTexture::ReadPCX4bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr) ptr[x] += (1 << c); } } - - /* release memory */ - delete [] colorIndex; - delete [] line; - delete [] srcp; } //========================================================================== @@ -273,9 +265,8 @@ void FPCXTexture::ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr) int rle_count = 0, rle_value = 0; int y, bytes; - uint8_t * srcp = new uint8_t[lump.GetLength() - sizeof(PCXHeader)]; - lump.Read(srcp, lump.GetLength() - sizeof(PCXHeader)); - uint8_t * src = srcp; + auto srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); + uint8_t * src = srcp.Data(); for (y = 0; y < Height; ++y) { @@ -301,7 +292,6 @@ void FPCXTexture::ReadPCX8bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr) *ptr++ = rle_value; } } - delete [] srcp; } //========================================================================== @@ -316,9 +306,8 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr int y, c; int bytes; - uint8_t * srcp = new uint8_t[lump.GetLength() - sizeof(PCXHeader)]; - lump.Read(srcp, lump.GetLength() - sizeof(PCXHeader)); - uint8_t * src = srcp; + auto srcp = lump.Read(lump.GetLength() - sizeof(PCXHeader)); + uint8_t * src = srcp.Data(); for (y = 0; y < Height; ++y) { @@ -349,7 +338,6 @@ void FPCXTexture::ReadPCX24bits (uint8_t *dst, FileReader & lump, PCXHeader *hdr } } } - delete [] srcp; } //========================================================================== @@ -423,9 +411,9 @@ TArray FPCXTexture::CreatePalettedPixels(int conversion) } else { - uint8_t * buffer = new uint8_t[Width*Height * 3]; - uint8_t * row = buffer; - ReadPCX24bits (buffer, lump, &header, 3); + TArray buffer(Width*Height * 3, true); + uint8_t * row = buffer.Data(); + ReadPCX24bits (row, lump, &header, 3); for(int y=0; y FPCXTexture::CreatePalettedPixels(int conversion) row+=3; } } - delete [] buffer; } return Pixels; } @@ -452,7 +439,7 @@ int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion) PalEntry pe[256]; PCXHeader header; int bitcount; - uint8_t * Pixels; + TArray Pixels; auto lump = Wads.OpenLumpReader(SourceLump); @@ -462,7 +449,7 @@ int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion) if (bitcount < 24) { - Pixels = new uint8_t[Width*Height]; + Pixels.Resize(Width*Height); if (bitcount < 8) { switch (bitcount) @@ -471,7 +458,7 @@ int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion) case 1: pe[0] = PalEntry(255, 0, 0, 0); pe[1] = PalEntry(255, 255, 255, 255); - ReadPCX1bit (Pixels, lump, &header); + ReadPCX1bit (Pixels.Data(), lump, &header); break; case 4: @@ -479,7 +466,7 @@ int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion) { pe[i] = PalEntry(255, header.palette[i * 3], header.palette[i * 3 + 1], header.palette[i * 3 + 2]); } - ReadPCX4bits (Pixels, lump, &header); + ReadPCX4bits (Pixels.Data(), lump, &header); break; } } @@ -500,17 +487,16 @@ int FPCXTexture::CopyPixels(FBitmap *bmp, int conversion) pe[i] = PalEntry(255, r,g,b); } lump.Seek(sizeof(header), FileReader::SeekSet); - ReadPCX8bits (Pixels, lump, &header); + ReadPCX8bits (Pixels.Data(), lump, &header); } - bmp->CopyPixelData(0, 0, Pixels, Width, Height, 1, Width, 0, pe); + bmp->CopyPixelData(0, 0, Pixels.Data(), Width, Height, 1, Width, 0, pe); } else { - Pixels = new uint8_t[Width*Height * 3]; - ReadPCX24bits (Pixels, lump, &header, 3); - bmp->CopyPixelDataRGB(0, 0, Pixels, Width, Height, 3, Width*3, 0, CF_RGB); + Pixels.Resize(Width*Height*4); + ReadPCX24bits (Pixels.Data(), lump, &header, 3); + bmp->CopyPixelDataRGB(0, 0, Pixels.Data(), Width, Height, 3, Width*3, 0, CF_RGB); } - delete [] Pixels; return 0; } diff --git a/src/textures/formats/tgatexture.cpp b/src/textures/formats/tgatexture.cpp index 1a26f6036..9936a828e 100644 --- a/src/textures/formats/tgatexture.cpp +++ b/src/textures/formats/tgatexture.cpp @@ -186,7 +186,6 @@ TArray FTGATexture::CreatePalettedPixels(int conversion) TGAHeader hdr; uint16_t w; uint8_t r,g,b,a; - uint8_t * buffer; TArray Pixels(Width*Height, true); lump.Read(&hdr, sizeof(hdr)); @@ -237,18 +236,18 @@ TArray FTGATexture::CreatePalettedPixels(int conversion) } int Size = Width * Height * (hdr.bpp>>3); - buffer = new uint8_t[Size]; + TArray buffer(Size, true); if (hdr.img_type < 4) // uncompressed { - lump.Read(buffer, Size); + lump.Read(buffer.Data(), Size); } else // compressed { - ReadCompressed(lump, buffer, hdr.bpp>>3); + ReadCompressed(lump, buffer.Data(), hdr.bpp>>3); } - uint8_t * ptr = buffer; + uint8_t * ptr = buffer.Data(); int step_x = (hdr.bpp>>3); int Pitch = Width * step_x; @@ -378,7 +377,6 @@ TArray FTGATexture::CreatePalettedPixels(int conversion) default: break; } - delete [] buffer; return Pixels; } @@ -395,7 +393,6 @@ int FTGATexture::CopyPixels(FBitmap *bmp, int conversion) TGAHeader hdr; uint16_t w; uint8_t r,g,b,a; - uint8_t * sbuffer; int transval = 0; lump.Read(&hdr, sizeof(hdr)); @@ -447,18 +444,18 @@ int FTGATexture::CopyPixels(FBitmap *bmp, int conversion) } int Size = Width * Height * (hdr.bpp>>3); - sbuffer = new uint8_t[Size]; + TArray sbuffer(Size); if (hdr.img_type < 4) // uncompressed { - lump.Read(sbuffer, Size); + lump.Read(sbuffer.Data(), Size); } else // compressed { - ReadCompressed(lump, sbuffer, hdr.bpp>>3); + ReadCompressed(lump, sbuffer.Data(), hdr.bpp>>3); } - uint8_t * ptr = sbuffer; + uint8_t * ptr = sbuffer.Data(); int step_x = (hdr.bpp>>3); int Pitch = Width * step_x; @@ -530,6 +527,5 @@ int FTGATexture::CopyPixels(FBitmap *bmp, int conversion) default: break; } - delete [] sbuffer; return transval; } diff --git a/src/win32/i_system.cpp b/src/win32/i_system.cpp index 7a2522fd7..45bb50b4d 100644 --- a/src/win32/i_system.cpp +++ b/src/win32/i_system.cpp @@ -709,9 +709,9 @@ void I_PrintStr(const char *cp) if (con_debugoutput) { // Strip out any color escape sequences before writing to debug output - char * copy = new char[strlen(cp)+1]; + TArray copy(strlen(cp) + 1, true); const char * srcp = cp; - char * dstp = copy; + char * dstp = copy.Data(); while (*srcp != 0) { @@ -727,8 +727,7 @@ void I_PrintStr(const char *cp) } *dstp=0; - OutputDebugStringA(copy); - delete [] copy; + OutputDebugStringA(copy.Data()); } if (ConWindowHidden)