diff --git a/.travis.yml b/.travis.yml index 3f46053ee..3de14e1d9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: c++ dist: trusty -sudo: required branches: except: diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a711c8944..5a034fc1a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1061,7 +1061,6 @@ set (PCH_SOURCES gl/textures/gl_texture.cpp gl/textures/gl_material.cpp gl/textures/gl_hirestex.cpp - gl/textures/gl_bitmap.cpp gl/textures/gl_samplers.cpp gl/textures/gl_translate.cpp gl/textures/gl_hqresize.cpp diff --git a/src/g_shared/a_dynlight.cpp b/src/g_shared/a_dynlight.cpp index b3cac45ae..0cad5e9ba 100644 --- a/src/g_shared/a_dynlight.cpp +++ b/src/g_shared/a_dynlight.cpp @@ -139,6 +139,19 @@ void ADynamicLight::Serialize(FSerializer &arc) if (lighttype == PulseLight) arc("lastupdate", m_lastUpdate, def->m_lastUpdate) ("cycler", m_cycler, def->m_cycler); + + // Remap the old flags. + if (SaveVersion < 4552) + { + lightflags = 0; + if (flags4 & MF4_MISSILEEVENMORE) lightflags |= LF_SUBTRACTIVE; + if (flags4 & MF4_MISSILEMORE) lightflags |= LF_ADDITIVE; + if (flags4 & MF4_SEESDAGGERS) lightflags |= LF_DONTLIGHTSELF; + if (flags4 & MF4_INCOMBAT) lightflags |= LF_ATTENUATE; + if (flags4 & MF4_STANDSTILL) lightflags |= LF_NOSHADOWMAP; + if (flags4 & MF4_EXTREMEDEATH) lightflags |= LF_DONTLIGHTACTORS; + flags4 &= ~(MF4_SEESDAGGERS); // this flag is dangerous and must be cleared. The others do not matter. + } } @@ -164,7 +177,7 @@ void ADynamicLight::BeginPlay() specialf1 = DAngle(double(SpawnAngle)).Normalized360().Degrees; visibletoplayer = true; - if (currentrenderer == 1 && gl.legacyMode && (flags4 & MF4_ATTENUATE)) + if (currentrenderer == 1 && gl.legacyMode && (lightflags & LF_ATTENUATE)) { args[LIGHT_INTENSITY] = args[LIGHT_INTENSITY] * 2 / 3; args[LIGHT_SECONDARY_INTENSITY] = args[LIGHT_SECONDARY_INTENSITY] * 2 / 3; @@ -663,7 +676,7 @@ void ADynamicLight::CollectWithinRadius(const DVector3 &opos, subsector_t *subSe } } } - shadowmapped = hitonesidedback && !(flags4 & MF4_NOSHADOWMAP); + shadowmapped = hitonesidedback && !(lightflags & LF_NOSHADOWMAP); } //========================================================================== @@ -791,7 +804,7 @@ CCMD(listlights) Printf("%s at (%f, %f, %f), color = 0x%02x%02x%02x, radius = %f %s %s", dl->target? dl->target->GetClass()->TypeName.GetChars() : dl->GetClass()->TypeName.GetChars(), dl->X(), dl->Y(), dl->Z(), dl->args[LIGHT_RED], - dl->args[LIGHT_GREEN], dl->args[LIGHT_BLUE], dl->radius, (dl->flags4 & MF4_ATTENUATE)? "attenuated" : "", dl->shadowmapped? "shadowmapped" : ""); + dl->args[LIGHT_GREEN], dl->args[LIGHT_BLUE], dl->radius, (dl->lightflags & LF_ATTENUATE)? "attenuated" : "", dl->shadowmapped? "shadowmapped" : ""); i++; shadowcount += dl->shadowmapped; diff --git a/src/g_shared/a_dynlight.h b/src/g_shared/a_dynlight.h index 893bbfbee..5446ba8cf 100644 --- a/src/g_shared/a_dynlight.h +++ b/src/g_shared/a_dynlight.h @@ -21,13 +21,19 @@ enum LIGHT_SCALE = 3, }; -// This is as good as something new -#define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE -#define MF4_ADDITIVE MF4_MISSILEMORE -#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS -#define MF4_ATTENUATE MF4_INCOMBAT -#define MF4_NOSHADOWMAP MF4_STANDSTILL -#define MF4_DONTLIGHTACTORS MF4_EXTREMEDEATH +enum LightFlag +{ + LF_SUBTRACTIVE = 1, + LF_ADDITIVE = 2, + LF_DONTLIGHTSELF = 4, + LF_ATTENUATE = 8, + LF_NOSHADOWMAP = 16, + LF_DONTLIGHTACTORS = 32 +}; + +typedef TFlags LightFlags; +DEFINE_TFLAGS_OPERATORS(LightFlags) + enum ELightType { @@ -69,7 +75,7 @@ struct FLightNode class ADynamicLight : public AActor { friend class FLightDefaults; - DECLARE_CLASS (ADynamicLight, AActor) + DECLARE_CLASS(ADynamicLight, AActor) public: virtual void Tick(); void Serialize(FSerializer &arc); @@ -80,10 +86,10 @@ public: float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); } void LinkLight(); void UnlinkLight(); - size_t PointerSubstitution (DObject *old, DObject *notOld); + size_t PointerSubstitution(DObject *old, DObject *notOld); void BeginPlay(); - void SetOrigin (double x, double y, double z, bool moving = false); + void SetOrigin(double x, double y, double z, bool moving = false); void PostBeginPlay(); void OnDestroy() override; void Activate(AActor *activator); @@ -92,8 +98,8 @@ public: void UpdateLocation(); bool IsOwned() const { return owned; } bool IsActive() const { return !(flags2&MF2_DORMANT); } - bool IsSubtractive() { return !!(flags4&MF4_SUBTRACTIVE); } - bool IsAdditive() { return !!(flags4&MF4_ADDITIVE); } + bool IsSubtractive() { return !!(lightflags & LF_SUBTRACTIVE); } + bool IsAdditive() { return !!(lightflags & LF_ADDITIVE); } FState *targetState; FLightNode * touching_sides; FLightNode * touching_subsectors; @@ -112,7 +118,6 @@ protected: public: int m_tickCount; - uint8_t lightflags; uint8_t lighttype; bool owned; bool halo; @@ -121,6 +126,7 @@ public: bool swapped; bool shadowmapped; int bufferindex; + LightFlags lightflags; }; diff --git a/src/g_shared/a_dynlightdata.cpp b/src/g_shared/a_dynlightdata.cpp index 3c1f7c134..c45d6fe9f 100644 --- a/src/g_shared/a_dynlightdata.cpp +++ b/src/g_shared/a_dynlightdata.cpp @@ -178,11 +178,11 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const for (int a = 0; a < 3; a++) light->args[a] = clamp((int)(m_Args[a]), 0, 255); light->args[LIGHT_INTENSITY] = m_Args[LIGHT_INTENSITY]; light->args[LIGHT_SECONDARY_INTENSITY] = m_Args[LIGHT_SECONDARY_INTENSITY]; - light->flags4 &= ~(MF4_ADDITIVE | MF4_SUBTRACTIVE | MF4_DONTLIGHTSELF); - if (m_subtractive) light->flags4 |= MF4_SUBTRACTIVE; - if (m_additive) light->flags4 |= MF4_ADDITIVE; - if (m_dontlightself) light->flags4 |= MF4_DONTLIGHTSELF; - if (m_dontlightactors) light->flags4 |= MF4_DONTLIGHTACTORS; + light->lightflags &= ~(LF_ADDITIVE | LF_SUBTRACTIVE | LF_DONTLIGHTSELF); + if (m_subtractive) light->lightflags |= LF_SUBTRACTIVE; + if (m_additive) light->lightflags |= LF_ADDITIVE; + if (m_dontlightself) light->lightflags |= LF_DONTLIGHTSELF; + if (m_dontlightactors) light->lightflags |= LF_DONTLIGHTACTORS; light->m_tickCount = 0; if (m_type == PulseLight) { @@ -200,9 +200,9 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const switch (m_attenuate) { - case 0: light->flags4 &= ~MF4_ATTENUATE; break; - case 1: light->flags4 |= MF4_ATTENUATE; break; - default: if (level.flags3 & LEVEL3_ATTENUATE) light->flags4 |= MF4_ATTENUATE; else light->flags4 &= ~MF4_ATTENUATE; break; + case 0: light->lightflags &= ~LF_ATTENUATE; break; + case 1: light->lightflags |= LF_ATTENUATE; break; + default: if (level.flags3 & LEVEL3_ATTENUATE) light->lightflags |= LF_ATTENUATE; else light->lightflags &= ~LF_ATTENUATE; break; } } @@ -1103,7 +1103,7 @@ void AActor::AttachLight(unsigned int count, const FLightDefaults *lightdef) light->target = this; light->owned = true; light->ObjectFlags |= OF_Transient; - //light->flags4 |= MF4_ATTENUATE; + //light->lightflags |= LF_ATTENUATE; AttachedLights.Push(light); } light->flags2&=~MF2_DORMANT; diff --git a/src/gl/dynlights/gl_dynlight1.cpp b/src/gl/dynlights/gl_dynlight1.cpp index a2c749e08..4000554c8 100644 --- a/src/gl/dynlights/gl_dynlight1.cpp +++ b/src/gl/dynlights/gl_dynlight1.cpp @@ -110,7 +110,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD float shadowIndex = GLRenderer->mShadowMap.ShadowMapIndex(light) + 1.0f; bool attenuate; - if (gl_attenuate == -1) attenuate = !!(light->flags4 & MF4_ATTENUATE); + if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE); else attenuate = !!gl_attenuate; if (attenuate) shadowIndex = -shadowIndex; diff --git a/src/gl/scene/gl_skydome.cpp b/src/gl/scene/gl_skydome.cpp index b57e3f4f4..9b0073c12 100644 --- a/src/gl/scene/gl_skydome.cpp +++ b/src/gl/scene/gl_skydome.cpp @@ -72,7 +72,6 @@ #include "gl/scene/gl_scenedrawer.h" #include "gl/scene/gl_portal.h" #include "gl/shaders/gl_shader.h" -#include "gl/textures/gl_bitmap.h" #include "gl/textures/gl_texture.h" #include "gl/textures/gl_material.h" diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index 793a10c7c..bb9de17b3 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -62,7 +62,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * while (node) { light=node->lightsource; - if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self) && !(light->flags4&MF4_DONTLIGHTACTORS)) + if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS)) { float dist; diff --git a/src/gl/textures/gl_bitmap.cpp b/src/gl/textures/gl_bitmap.cpp deleted file mode 100644 index f6909c952..000000000 --- a/src/gl/textures/gl_bitmap.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// -//--------------------------------------------------------------------------- -// -// Copyright(C) 2004-2016 Christoph Oelckers -// All rights reserved. -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see http://www.gnu.org/licenses/ -// -//-------------------------------------------------------------------------- -// -/* -** gl_bitmap.cpp -** Bitmap class for texture composition -** -*/ - - -#include "v_palette.h" -#include "templates.h" -#include "gl/textures/gl_translate.h" -#include "gl/textures/gl_bitmap.h" -#include "gl/system/gl_interface.h" - -//=========================================================================== -// -// multi-format pixel copy with colormap application -// requires one of the previously defined conversion classes to work -// -//=========================================================================== -template -void iCopyColors(unsigned char * pout, const unsigned char * pin, int count, int step, uint8_t tr, uint8_t tg, uint8_t tb) -{ - int i; - unsigned char a; - - for(i=0;i, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors, - iCopyColors -}; - -//=========================================================================== -// -// True Color texture copy function -// This excludes all the cases that force downconversion to the -// base palette because they wouldn't be used anyway. -// -//=========================================================================== -void FGLBitmap::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, int r, int g, int b) -{ - if (ClipCopyPixelRect(&ClipRect, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate)) - { - uint8_t *buffer = GetPixels() + 4*originx + Pitch*originy; - for (int y=0;y 0) - { - PalEntry *ptrans = GLTranslationPalette::GetPalette(translation); - if (ptrans && !alphatrans) - { - for (i = 0; i < 256; i++) - { - penew[i] = (ptrans[i] & 0xffffff) | (palette[i] & 0xff000000); - } - } - else if (ptrans) - { - memcpy(penew, ptrans, 256 * sizeof(PalEntry)); - } - } - else - { - memcpy(penew, palette, 256*sizeof(PalEntry)); - } - - // convert the image according to the translated palette. - for (y=0;yCopyTrueColorPixels(&bmp, 0, 0); hirestexture->CheckTrans(buffer, w*h, trans); @@ -210,38 +210,39 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F buffer=new unsigned char[W*(H+1)*4]; memset(buffer, 0, W * (H+1) * 4); - FGLBitmap bmp(buffer, W*4, W, H); - bmp.SetTranslationInfo(translation, alphatrans); + FBitmap bmp(buffer, W*4, W, H); - if (tex->bComplex) + if (translation <= 0) { - FBitmap imgCreate; - - // The texture contains special processing so it must be composited using the - // base bitmap class and then be converted as a whole. - if (imgCreate.Create(W, H)) + // Q: Is this special treatment still needed? Needs to be checked. + if (tex->bComplex) { - memset(imgCreate.GetPixels(), 0, W * H * 4); - int trans = tex->CopyTrueColorPixels(&imgCreate, exx, exx); - bmp.CopyPixelDataRGB(0, 0, imgCreate.GetPixels(), W, H, 4, W * 4, 0, CF_BGRA); + FBitmap imgCreate; + + // The texture contains special processing so it must be fully composited before being converted as a whole. + if (imgCreate.Create(W, H)) + { + memset(imgCreate.GetPixels(), 0, W * H * 4); + int trans = tex->CopyTrueColorPixels(&imgCreate, exx, exx); + bmp.CopyPixelDataRGB(0, 0, imgCreate.GetPixels(), W, H, 4, W * 4, 0, CF_BGRA); + tex->CheckTrans(buffer, W*H, trans); + isTransparent = tex->gl_info.mIsTransparent; + if (bIsTransparent == -1) bIsTransparent = isTransparent; + } + } + else + { + int trans = tex->CopyTrueColorPixels(&bmp, exx, exx); tex->CheckTrans(buffer, W*H, trans); isTransparent = tex->gl_info.mIsTransparent; if (bIsTransparent == -1) bIsTransparent = isTransparent; } } - else if (translation<=0) - { - int trans = tex->CopyTrueColorPixels(&bmp, exx, exx); - tex->CheckTrans(buffer, W*H, trans); - isTransparent = tex->gl_info.mIsTransparent; - if (bIsTransparent == -1) bIsTransparent = isTransparent; - } else { // When using translations everything must be mapped to the base palette. - // Since FTexture's method is doing exactly that by calling GetPixels let's use that here - // to do all the dirty work for us. ;) - tex->FTexture::CopyTrueColorPixels(&bmp, exx, exx); + // so use CopyTrueColorTranslated + tex->CopyTrueColorTranslated(&bmp, exx, exx, 0, GLTranslationPalette::GetPalette(translation)); isTransparent = 0; // This is not conclusive for setting the texture's transparency info. } diff --git a/src/gl/textures/gl_texture.cpp b/src/gl/textures/gl_texture.cpp index b671edbf7..af1a6178f 100644 --- a/src/gl/textures/gl_texture.cpp +++ b/src/gl/textures/gl_texture.cpp @@ -538,7 +538,7 @@ void FBrightmapTexture::Unload () int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) { - SourcePic->CopyTrueColorTranslated(bmp, x, y, rotate, &GlobalBrightmap); + SourcePic->CopyTrueColorTranslated(bmp, x, y, rotate, GlobalBrightmap.Palette); return 0; } diff --git a/src/r_data/r_translate.cpp b/src/r_data/r_translate.cpp index b069aa9f3..2b8849b68 100644 --- a/src/r_data/r_translate.cpp +++ b/src/r_data/r_translate.cpp @@ -757,7 +757,7 @@ int CreateBloodTranslation(PalEntry color) for (i = 0; i < 256; i++) { int bright = MAX(MAX(GPalette.BaseColors[i].r, GPalette.BaseColors[i].g), GPalette.BaseColors[i].b); - PalEntry pe = PalEntry(color.r*bright/255, color.g*bright/255, color.b*bright/255); + PalEntry pe = PalEntry(255, color.r*bright/255, color.g*bright/255, color.b*bright/255); int entry = ColorMatcher.Pick(pe.r, pe.g, pe.b); trans->Palette[i] = pe; diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index b63fd4eca..7cfa53504 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -488,12 +488,12 @@ static FFlagDef PlayerPawnFlagDefs[] = static FFlagDef DynLightFlagDefs[] = { // PlayerPawn flags - DEFINE_FLAG(MF4, SUBTRACTIVE, ADynamicLight, flags4), - DEFINE_FLAG(MF4, ADDITIVE, ADynamicLight, flags4), - DEFINE_FLAG(MF4, DONTLIGHTSELF, ADynamicLight, flags4), - DEFINE_FLAG(MF4, ATTENUATE, ADynamicLight, flags4), - DEFINE_FLAG(MF4, NOSHADOWMAP, ADynamicLight, flags4), - DEFINE_FLAG(MF4, DONTLIGHTACTORS, ADynamicLight, flags4), + DEFINE_FLAG(LF, SUBTRACTIVE, ADynamicLight, lightflags), + DEFINE_FLAG(LF, ADDITIVE, ADynamicLight, lightflags), + DEFINE_FLAG(LF, DONTLIGHTSELF, ADynamicLight, lightflags), + DEFINE_FLAG(LF, ATTENUATE, ADynamicLight, lightflags), + DEFINE_FLAG(LF, NOSHADOWMAP, ADynamicLight, lightflags), + DEFINE_FLAG(LF, DONTLIGHTACTORS, ADynamicLight, lightflags), }; static FFlagDef PowerSpeedFlagDefs[] = diff --git a/src/swrenderer/drawers/r_draw.h b/src/swrenderer/drawers/r_draw.h index e9b893aba..b29ea8512 100644 --- a/src/swrenderer/drawers/r_draw.h +++ b/src/swrenderer/drawers/r_draw.h @@ -28,6 +28,7 @@ namespace swrenderer class WallDrawerArgs; class SpanDrawerArgs; class SpriteDrawerArgs; + class VoxelBlock; extern uint8_t shadetables[/*NUMCOLORMAPS*16*256*/]; extern FDynamicColormap ShadeFakeColormap[16]; @@ -79,6 +80,7 @@ namespace swrenderer virtual void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) = 0; virtual void DrawRevSubClampColumn(const SpriteDrawerArgs &args) = 0; virtual void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) = 0; + virtual void DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) = 0; virtual void DrawSpan(const SpanDrawerArgs &args) = 0; virtual void DrawSpanMasked(const SpanDrawerArgs &args) = 0; virtual void DrawSpanTranslucent(const SpanDrawerArgs &args) = 0; diff --git a/src/swrenderer/drawers/r_draw_pal.cpp b/src/swrenderer/drawers/r_draw_pal.cpp index cb7c16d24..40981a63f 100644 --- a/src/swrenderer/drawers/r_draw_pal.cpp +++ b/src/swrenderer/drawers/r_draw_pal.cpp @@ -3011,4 +3011,107 @@ namespace swrenderer { return "DrawParticle"; } + + ///////////////////////////////////////////////////////////////////////////// + + DrawVoxelBlocksPalCommand::DrawVoxelBlocksPalCommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) : args(args), blocks(blocks), blockcount(blockcount) + { + } + + void DrawVoxelBlocksPalCommand::Execute(DrawerThread *thread) + { + int destpitch = args.Viewport()->RenderTarget->GetPitch(); + uint8_t *destorig = args.Viewport()->RenderTarget->GetBuffer(); + const uint8_t *colormap = args.Colormap(args.Viewport()); + + for (int i = 0; i < blockcount; i++) + { + const VoxelBlock &block = blocks[i]; + + const uint8_t *source = block.voxels; + + fixed_t fracpos = block.vPos; + fixed_t iscale = block.vStep; + int count = block.height; + int width = block.width; + int pitch = destpitch; + uint8_t *dest = destorig + (block.x + block.y * pitch); + + count = thread->count_for_thread(block.y, count); + dest = thread->dest_for_thread(block.y, pitch, dest); + fracpos += iscale * thread->skipped_by_thread(block.y); + iscale *= thread->num_cores; + pitch *= thread->num_cores; + + if (width == 1) + { + while (count > 0) + { + uint8_t color = colormap[source[fracpos >> FRACBITS]]; + *dest = color; + dest += pitch; + fracpos += iscale; + count--; + } + } + else if (width == 2) + { + while (count > 0) + { + uint8_t color = colormap[source[fracpos >> FRACBITS]]; + dest[0] = color; + dest[1] = color; + dest += pitch; + fracpos += iscale; + count--; + } + } + else if (width == 3) + { + while (count > 0) + { + uint8_t color = colormap[source[fracpos >> FRACBITS]]; + dest[0] = color; + dest[1] = color; + dest[2] = color; + dest += pitch; + fracpos += iscale; + count--; + } + } + else if (width == 4) + { + while (count > 0) + { + uint8_t color = colormap[source[fracpos >> FRACBITS]]; + dest[0] = color; + dest[1] = color; + dest[2] = color; + dest[3] = color; + dest += pitch; + fracpos += iscale; + count--; + } + } + else + { + while (count > 0) + { + uint8_t color = colormap[source[fracpos >> FRACBITS]]; + + for (int x = 0; x < width; x++) + dest[x] = color; + + dest += pitch; + fracpos += iscale; + count--; + } + } + } + } + + FString DrawVoxelBlocksPalCommand::DebugInfo() + { + return "DrawVoxelBlocks"; + } } diff --git a/src/swrenderer/drawers/r_draw_pal.h b/src/swrenderer/drawers/r_draw_pal.h index 8d2a726c7..813825f2b 100644 --- a/src/swrenderer/drawers/r_draw_pal.h +++ b/src/swrenderer/drawers/r_draw_pal.h @@ -49,10 +49,10 @@ namespace swrenderer PalColumnCommand(const SpriteDrawerArgs &args); FString DebugInfo() override { return "PalColumnCommand"; } + SpriteDrawerArgs args; + protected: uint8_t AddLights(uint8_t fg, uint8_t material, uint32_t lit_r, uint32_t lit_g, uint32_t lit_b); - - SpriteDrawerArgs args; }; class DrawColumnPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; }; @@ -205,6 +205,19 @@ namespace swrenderer uint32_t _fracposx; }; + class DrawVoxelBlocksPalCommand : public DrawerCommand + { + public: + DrawVoxelBlocksPalCommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount); + void Execute(DrawerThread *thread) override; + FString DebugInfo() override; + + private: + SpriteDrawerArgs args; + const VoxelBlock *blocks; + int blockcount; + }; + class SWPalDrawers : public SWPixelFormatDrawers { public: @@ -244,6 +257,7 @@ namespace swrenderer void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push(args); } + void DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) override { Queue->Push(args, blocks, blockcount); } void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push(args); } void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push(args); } void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push(args); } diff --git a/src/swrenderer/drawers/r_draw_rgba.cpp b/src/swrenderer/drawers/r_draw_rgba.cpp index f94190fa3..ae3c563f3 100644 --- a/src/swrenderer/drawers/r_draw_rgba.cpp +++ b/src/swrenderer/drawers/r_draw_rgba.cpp @@ -201,6 +201,11 @@ namespace swrenderer Queue->Push(args); } + void SWTruecolorDrawers::DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) + { + Queue->Push(args, blocks, blockcount); + } + void SWTruecolorDrawers::DrawSpan(const SpanDrawerArgs &args) { Queue->Push(args); @@ -858,4 +863,44 @@ namespace swrenderer return "DrawParticle"; } + ///////////////////////////////////////////////////////////////////////////// + + DrawVoxelBlocksRGBACommand::DrawVoxelBlocksRGBACommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) : args(args), blocks(blocks), blockcount(blockcount) + { + } + + void DrawVoxelBlocksRGBACommand::Execute(DrawerThread *thread) + { + int pitch = args.Viewport()->RenderTarget->GetPitch(); + uint8_t *destorig = args.Viewport()->RenderTarget->GetBuffer(); + + DrawSprite32Command drawer(args); + drawer.args.dc_texturefracx = 0; + drawer.args.dc_source2 = 0; + for (int i = 0; i < blockcount; i++) + { + const VoxelBlock &block = blocks[i]; + + double v = block.vPos / (double)block.voxelsCount / FRACUNIT; + double vstep = block.vStep / (double)block.voxelsCount / FRACUNIT; + drawer.args.dc_texturefrac = (int)(v * (1 << 30)); + drawer.args.dc_iscale = (int)(vstep * (1 << 30)); + drawer.args.dc_source = block.voxels; + drawer.args.dc_textureheight = block.voxelsCount; + drawer.args.dc_count = block.height; + drawer.args.dc_dest_y = block.y; + drawer.args.dc_dest = destorig + (block.x + block.y * pitch) * 4; + + for (int j = 0; j < block.width; j++) + { + drawer.Execute(thread); + drawer.args.dc_dest += 4; + } + } + } + + FString DrawVoxelBlocksRGBACommand::DebugInfo() + { + return "DrawVoxelBlocks"; + } } diff --git a/src/swrenderer/drawers/r_draw_rgba.h b/src/swrenderer/drawers/r_draw_rgba.h index 0d0b0bf78..c13eb5162 100644 --- a/src/swrenderer/drawers/r_draw_rgba.h +++ b/src/swrenderer/drawers/r_draw_rgba.h @@ -215,6 +215,21 @@ namespace swrenderer ///////////////////////////////////////////////////////////////////////////// + class DrawVoxelBlocksRGBACommand : public DrawerCommand + { + public: + DrawVoxelBlocksRGBACommand(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount); + void Execute(DrawerThread *thread) override; + FString DebugInfo() override; + + private: + SpriteDrawerArgs args; + const VoxelBlock *blocks; + int blockcount; + }; + + ///////////////////////////////////////////////////////////////////////////// + class SWTruecolorDrawers : public SWPixelFormatDrawers { public: @@ -246,6 +261,7 @@ namespace swrenderer void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override; void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override; void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override; + void DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) override; void DrawSpan(const SpanDrawerArgs &args) override; void DrawSpanMasked(const SpanDrawerArgs &args) override; void DrawSpanTranslucent(const SpanDrawerArgs &args) override; diff --git a/src/swrenderer/drawers/r_draw_sprite32.h b/src/swrenderer/drawers/r_draw_sprite32.h index 63f642692..3437db81e 100644 --- a/src/swrenderer/drawers/r_draw_sprite32.h +++ b/src/swrenderer/drawers/r_draw_sprite32.h @@ -56,10 +56,9 @@ namespace swrenderer template class DrawSprite32T : public DrawerCommand { - protected: + public: SpriteDrawerArgs args; - public: DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { } void Execute(DrawerThread *thread) override diff --git a/src/swrenderer/drawers/r_draw_sprite32_sse2.h b/src/swrenderer/drawers/r_draw_sprite32_sse2.h index 1b5e682b1..6463402d8 100644 --- a/src/swrenderer/drawers/r_draw_sprite32_sse2.h +++ b/src/swrenderer/drawers/r_draw_sprite32_sse2.h @@ -56,10 +56,9 @@ namespace swrenderer template class DrawSprite32T : public DrawerCommand { - protected: + public: SpriteDrawerArgs args; - public: DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { } void Execute(DrawerThread *thread) override diff --git a/src/swrenderer/line/r_renderdrawsegment.cpp b/src/swrenderer/line/r_renderdrawsegment.cpp index 6718bc370..b32520707 100644 --- a/src/swrenderer/line/r_renderdrawsegment.cpp +++ b/src/swrenderer/line/r_renderdrawsegment.cpp @@ -66,21 +66,6 @@ namespace swrenderer void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2) { auto viewport = Thread->Viewport.get(); - RenderFogBoundary renderfog; - float *MaskedSWall = nullptr, MaskedScaleY = 0, rw_scalestep = 0; - fixed_t *maskedtexturecol = nullptr; - - FTexture *tex; - int i; - sector_t tempsec; // killough 4/13/98 - double texheight, texheightscale; - bool notrelevant = false; - double rowoffset; - bool wrap = false; - - const sector_t *sec; - - bool sprflipvert = false; curline = ds->curline; @@ -105,14 +90,9 @@ namespace swrenderer frontsector = curline->frontsector; backsector = curline->backsector; - tex = TexMan(curline->sidedef->GetTexture(side_t::mid), true); - if (i_compatflags & COMPATF_MASKEDMIDTEX) - { - tex = tex->GetRawTexture(); - } - // killough 4/13/98: get correct lightlevel for 2s normal textures - sec = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0); + sector_t tempsec; + const sector_t *sec = Thread->OpaquePass->FakeFlat(frontsector, &tempsec, nullptr, nullptr, nullptr, 0, 0, 0, 0); FDynamicColormap *basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::walltop]); // [RH] Set basecolormap @@ -122,14 +102,15 @@ namespace swrenderer Clip3DFloors *clip3d = Thread->Clip3D.get(); + if (!(clip3d->fake3D & FAKE3D_CLIPTOP)) + { + clip3d->sclipTop = sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos); + } + CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() < 0) { - if (!(clip3d->fake3D & FAKE3D_CLIPTOP)) - { - clip3d->sclipTop = sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos); - } - for (i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) + for (int i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--) { if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0()) { @@ -142,30 +123,71 @@ namespace swrenderer } } - short *mfloorclip = ds->sprbottomclip - ds->x1; - short *mceilingclip = ds->sprtopclip - ds->x1; - double spryscale; + bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX); // [RH] Draw fog partition + bool notrelevant = false; if (ds->bFogBoundary) { + short *mfloorclip = ds->sprbottomclip - ds->x1; + short *mceilingclip = ds->sprtopclip - ds->x1; + + RenderFogBoundary renderfog; renderfog.Render(Thread, x1, x2, mceilingclip, mfloorclip, wallshade, rw_light, rw_lightstep, basecolormap); - if (ds->maskedtexturecol == nullptr) + + if (!ds->maskedtexturecol) { - goto clearfog; + if (!(ds->bFakeBoundary && !(ds->bFakeBoundary & 4)) || visible) + notrelevant = RenderWall(ds, x1, x2, walldrawerargs, columndrawerargs, visible, basecolormap, wallshade, wrap); } } - if ((ds->bFakeBoundary && !(ds->bFakeBoundary & 4)) || !visible) + else if (!(ds->bFakeBoundary && !(ds->bFakeBoundary & 4)) || visible) { - goto clearfog; + notrelevant = RenderWall(ds, x1, x2, walldrawerargs, columndrawerargs, visible, basecolormap, wallshade, wrap); } - MaskedSWall = ds->swall - ds->x1; - MaskedScaleY = ds->yscale; - maskedtexturecol = ds->maskedtexturecol - ds->x1; - spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1); - rw_scalestep = ds->iscalestep; + if (ds->bFakeBoundary & 3) + { + RenderFakeWallRange(ds, x1, x2, wallshade); + } + if (!notrelevant) + { + if (clip3d->fake3D & FAKE3D_REFRESHCLIP) + { + if (!wrap) + { + assert(ds->bkup != nullptr); + memcpy(ds->sprtopclip, ds->bkup, (ds->x2 - ds->x1) * 2); + } + } + else + { + fillshort(ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight); + } + } + } + bool RenderDrawSegment::RenderWall(DrawSegment *ds, int x1, int x2, WallDrawerArgs &walldrawerargs, SpriteDrawerArgs &columndrawerargs, bool visible, FDynamicColormap *basecolormap, int wallshade, bool wrap) + { + auto viewport = Thread->Viewport.get(); + Clip3DFloors *clip3d = Thread->Clip3D.get(); + + FTexture *tex = TexMan(curline->sidedef->GetTexture(side_t::mid), true); + if (i_compatflags & COMPATF_MASKEDMIDTEX) + { + tex = tex->GetRawTexture(); + } + + short *mfloorclip = ds->sprbottomclip - ds->x1; + short *mceilingclip = ds->sprtopclip - ds->x1; + + float *MaskedSWall = ds->swall - ds->x1; + float MaskedScaleY = ds->yscale; + fixed_t *maskedtexturecol = ds->maskedtexturecol - ds->x1; + double spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1); + float rw_scalestep = ds->iscalestep; + + CameraLight *cameraLight = CameraLight::Instance(); if (cameraLight->FixedLightLevel() >= 0) { walldrawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, cameraLight->FixedLightLevelShade()); @@ -178,8 +200,8 @@ namespace swrenderer } // find positioning - texheight = tex->GetScaledHeightDouble(); - texheightscale = fabs(curline->sidedef->GetTextureYScale(side_t::mid)); + double texheight = tex->GetScaledHeightDouble(); + double texheightscale = fabs(curline->sidedef->GetTextureYScale(side_t::mid)); if (texheightscale != 1) { texheight = texheight / texheightscale; @@ -195,13 +217,14 @@ namespace swrenderer texturemid = MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling)); } - rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid); + double rowoffset = curline->sidedef->GetTextureYOffset(side_t::mid); - wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX); if (!wrap) { // Texture does not wrap vertically. double textop; + bool sprflipvert = false; + if (MaskedScaleY < 0) { MaskedScaleY = -MaskedScaleY; @@ -231,23 +254,21 @@ namespace swrenderer // [RH] Don't bother drawing segs that are completely offscreen if (viewport->globaldclip * ds->sz1 < -textop && viewport->globaldclip * ds->sz2 < -textop) { // Texture top is below the bottom of the screen - goto clearfog; + return false; } if (viewport->globaluclip * ds->sz1 > texheight - textop && viewport->globaluclip * ds->sz2 > texheight - textop) { // Texture bottom is above the top of the screen - goto clearfog; + return false; } if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && textop < clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z) { - notrelevant = true; - goto clearfog; + return true; } if ((clip3d->fake3D & FAKE3D_CLIPTOP) && textop - texheight > clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z) { - notrelevant = true; - goto clearfog; + return true; } WallC.sz1 = ds->sz1; @@ -272,12 +293,12 @@ namespace swrenderer walllower.Project(Thread->Viewport.get(), textop - texheight, &WallC); } - for (i = x1; i < x2; i++) + for (int i = x1; i < x2; i++) { if (wallupper.ScreenY[i] < mceilingclip[i]) wallupper.ScreenY[i] = mceilingclip[i]; } - for (i = x1; i < x2; i++) + for (int i = x1; i < x2; i++) { if (walllower.ScreenY[i] > mfloorclip[i]) walllower.ScreenY[i] = mfloorclip[i]; @@ -358,7 +379,7 @@ namespace swrenderer if (clip3d->fake3D & FAKE3D_CLIPTOP) { wallupper.Project(Thread->Viewport.get(), clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); - for (i = x1; i < x2; i++) + for (int i = x1; i < x2; i++) { if (wallupper.ScreenY[i] < mceilingclip[i]) wallupper.ScreenY[i] = mceilingclip[i]; @@ -368,7 +389,7 @@ namespace swrenderer if (clip3d->fake3D & FAKE3D_CLIPBOTTOM) { walllower.Project(Thread->Viewport.get(), clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); - for (i = x1; i < x2; i++) + for (int i = x1; i < x2; i++) { if (walllower.ScreenY[i] > mfloorclip[i]) walllower.ScreenY[i] = mfloorclip[i]; @@ -386,27 +407,7 @@ namespace swrenderer 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); } - clearfog: - if (ds->bFakeBoundary & 3) - { - RenderFakeWallRange(ds, x1, x2, wallshade); - } - if (!notrelevant) - { - if (clip3d->fake3D & FAKE3D_REFRESHCLIP) - { - if (!wrap) - { - assert(ds->bkup != nullptr); - memcpy(ds->sprtopclip, ds->bkup, (ds->x2 - ds->x1) * 2); - } - } - else - { - fillshort(ds->sprtopclip - ds->x1 + x1, x2 - x1, viewheight); - } - } - return; + return false; } // kg3D - render one fake wall diff --git a/src/swrenderer/line/r_renderdrawsegment.h b/src/swrenderer/line/r_renderdrawsegment.h index 6587dd1c5..42a5ac5bc 100644 --- a/src/swrenderer/line/r_renderdrawsegment.h +++ b/src/swrenderer/line/r_renderdrawsegment.h @@ -37,6 +37,7 @@ 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 wrap); void ClipMidtex(int x1, int x2); void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap); void RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade); diff --git a/src/swrenderer/line/r_walldraw.cpp b/src/swrenderer/line/r_walldraw.cpp index b5b69f305..8a639fec5 100644 --- a/src/swrenderer/line/r_walldraw.cpp +++ b/src/swrenderer/line/r_walldraw.cpp @@ -220,7 +220,7 @@ namespace swrenderer float lz = (float)lightZ; // Precalculate the constant part of the dot here so the drawer doesn't have to. - bool is_point_light = (cur_node->lightsource->flags4 & MF4_ATTENUATE) != 0; + bool is_point_light = (cur_node->lightsource->lightflags & LF_ATTENUATE) != 0; float lconstant = lx * lx + ly * ly; float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f; diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index 28be2aa25..bbc6f2871 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -249,7 +249,7 @@ namespace swrenderer float lz = (float)lightZ - drawerargs.dc_viewpos.Z; // Precalculate the constant part of the dot here so the drawer doesn't have to. - bool is_point_light = (cur_node->lightsource->flags4 & MF4_ATTENUATE) != 0; + bool is_point_light = (cur_node->lightsource->lightflags & LF_ATTENUATE) != 0; float lconstant = ly * ly + lz * lz; float nlconstant = is_point_light ? lz * drawerargs.dc_normal.Z : 0.0f; diff --git a/src/swrenderer/things/r_sprite.cpp b/src/swrenderer/things/r_sprite.cpp index 25cfd58f3..b9ed668bc 100644 --- a/src/swrenderer/things/r_sprite.cpp +++ b/src/swrenderer/things/r_sprite.cpp @@ -255,7 +255,7 @@ namespace swrenderer while (node != nullptr) { ADynamicLight *light = node->lightsource; - if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != thing) && !(light->flags4&MF4_DONTLIGHTACTORS)) + if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != thing) && !(light->lightflags&LF_DONTLIGHTACTORS)) { float lx = (float)(light->X() - thing->X()); float ly = (float)(light->Y() - thing->Y()); diff --git a/src/swrenderer/things/r_voxel.cpp b/src/swrenderer/things/r_voxel.cpp index 18ab8850b..fe626dd2f 100644 --- a/src/swrenderer/things/r_voxel.cpp +++ b/src/swrenderer/things/r_voxel.cpp @@ -220,11 +220,12 @@ namespace swrenderer { CheckOffscreenBuffer(viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight(), !!(flags & DVF_SPANSONLY)); } + */ + if (spr->bInMirror) { flags |= DVF_MIRRORED; } - */ // Render the voxel, either directly to the screen or offscreen. DrawVoxel(thread, drawerargs, spr->pa.vpos, spr->pa.vang, spr->gpos, spr->Angle, @@ -276,18 +277,18 @@ namespace swrenderer fixed_t cosang, sinang, sprcosang, sprsinang; int backx, backy, gxinc, gyinc; int daxscalerecip, dayscalerecip, cnt, gxstart, gystart, dazscale; - int lx, rx, nx, ny, x1=0, y1=0, x2=0, y2=0, yinc=0; - int yoff, xs=0, ys=0, xe, ye, xi=0, yi=0, cbackx, cbacky, dagxinc, dagyinc; + int lx, rx, nx, ny, x1 = 0, y1 = 0, x2 = 0, y2 = 0, yinc = 0; + int yoff, xs = 0, ys = 0, xe, ye, xi = 0, yi = 0, cbackx, cbacky, dagxinc, dagyinc; kvxslab_t *voxptr, *voxend; FVoxelMipLevel *mip; int z1a[64], z2a[64], yplc[64]; auto viewport = thread->Viewport.get(); - const int nytooclose = viewport->viewwindow.centerxwide * 2100, nytoofar = 32768*32768 - 1048576; + const int nytooclose = viewport->viewwindow.centerxwide * 2100, nytoofar = 32768 * 32768 - 1048576; const int xdimenscale = FLOAT2FIXED(viewport->viewwindow.centerxwide * viewport->YaspectMul / 160); const double centerxwide_f = viewport->viewwindow.centerxwide; - const double centerxwidebig_f = centerxwide_f * 65536*65536*8; + const double centerxwidebig_f = centerxwide_f * 65536 * 65536 * 8; // Convert to Build's coordinate system. fixed_t globalposx = xs_Fix<4>::ToFix(globalpos.X); @@ -329,14 +330,14 @@ namespace swrenderer minslabz >>= k; maxslabz >>= k; - daxscale <<= (k+8); dayscale <<= (k+8); + daxscale <<= (k + 8); dayscale <<= (k + 8); dazscale = FixedDiv(dayscale, FLOAT2FIXED(viewport->BaseYaspectMul)); daxscale = fixed_t(daxscale / viewport->YaspectMul); daxscale = Scale(daxscale, xdimenscale, viewport->viewwindow.centerxwide << 9); dayscale = Scale(dayscale, FixedMul(xdimenscale, viewport->viewingrangerecip), viewport->viewwindow.centerxwide << 9); - daxscalerecip = (1<<30) / daxscale; - dayscalerecip = (1<<30) / dayscale; + daxscalerecip = (1 << 30) / daxscale; + dayscalerecip = (1 << 30) / dayscale; fixed_t piv_x = fixed_t(mip->Pivot.X*256.); fixed_t piv_y = fixed_t(mip->Pivot.Y*256.); @@ -344,7 +345,7 @@ namespace swrenderer x = FixedMul(globalposx - dasprx, daxscalerecip); y = FixedMul(globalposy - daspry, daxscalerecip); - backx = (DMulScale10(x, sprcosang, y, sprsinang) + piv_x) >> 8; + backx = (DMulScale10(x, sprcosang, y, sprsinang) + piv_x) >> 8; backy = (DMulScale10(y, sprcosang, x, -sprsinang) + piv_y) >> 8; cbackx = clamp(backx, 0, mip->SizeX - 1); cbacky = clamp(backy, 0, mip->SizeY - 1); @@ -353,7 +354,7 @@ namespace swrenderer sprsinang = MulScale14(daxscale, sprsinang); x = (dasprx - globalposx) - DMulScale18(piv_x, sprcosang, piv_y, -sprsinang); - y = (daspry - globalposy) - DMulScale18(piv_y, sprcosang, piv_x, sprsinang); + y = (daspry - globalposy) - DMulScale18(piv_y, sprcosang, piv_x, sprsinang); cosang = FixedMul(cosang, dayscalerecip); sinang = FixedMul(sinang, dayscalerecip); @@ -361,7 +362,7 @@ namespace swrenderer gxstart = y*cosang - x*sinang; gystart = x*cosang + y*sinang; gxinc = DMulScale10(sprsinang, cosang, sprcosang, -sinang); - gyinc = DMulScale10(sprcosang, cosang, sprsinang, sinang); + gyinc = DMulScale10(sprcosang, cosang, sprsinang, sinang); if ((abs(globalposz - dasprz) >> 10) >= abs(dazscale)) return; x = 0; y = 0; j = MAX(mip->SizeX, mip->SizeY); @@ -376,18 +377,24 @@ namespace swrenderer syoff = DivScale21(globalposz - dasprz, FixedMul(dazscale, 0xE800)) + (piv_z << 7); yoff = (abs(gxinc) + abs(gyinc)) >> 1; + bool useSlabDataBgra = !drawerargs.DrawerNeedsPalInput() && viewport->RenderTarget->IsBgra(); + + const int maxoutblocks = 100; + VoxelBlock *outblocks = thread->FrameMemory->AllocMemory(maxoutblocks); + int nextoutblock = 0; + for (cnt = 0; cnt < 8; cnt++) { switch (cnt) { - case 0: xs = 0; ys = 0; xi = 1; yi = 1; break; - case 1: xs = mip->SizeX-1; ys = 0; xi = -1; yi = 1; break; - case 2: xs = 0; ys = mip->SizeY-1; xi = 1; yi = -1; break; - case 3: xs = mip->SizeX-1; ys = mip->SizeY-1; xi = -1; yi = -1; break; - case 4: xs = 0; ys = cbacky; xi = 1; yi = 2; break; - case 5: xs = mip->SizeX-1; ys = cbacky; xi = -1; yi = 2; break; - case 6: xs = cbackx; ys = 0; xi = 2; yi = 1; break; - case 7: xs = cbackx; ys = mip->SizeY-1; xi = 2; yi = -1; break; + case 0: xs = 0; ys = 0; xi = 1; yi = 1; break; + case 1: xs = mip->SizeX - 1; ys = 0; xi = -1; yi = 1; break; + case 2: xs = 0; ys = mip->SizeY - 1; xi = 1; yi = -1; break; + case 3: xs = mip->SizeX - 1; ys = mip->SizeY - 1; xi = -1; yi = -1; break; + case 4: xs = 0; ys = cbacky; xi = 1; yi = 2; break; + case 5: xs = mip->SizeX - 1; ys = cbacky; xi = -1; yi = 2; break; + case 6: xs = cbackx; ys = 0; xi = 2; yi = 1; break; + case 7: xs = cbackx; ys = mip->SizeY - 1; xi = 2; yi = -1; break; } xe = cbackx; ye = cbacky; if (cnt < 4) @@ -407,28 +414,28 @@ namespace swrenderer } i = sgn(ys - backy) + sgn(xs - backx) * 3 + 4; - switch(i) + switch (i) { - case 6: case 7: x1 = 0; y1 = 0; break; - case 8: case 5: x1 = gxinc; y1 = gyinc; break; - case 0: case 3: x1 = gyinc; y1 = -gxinc; break; - case 2: case 1: x1 = gxinc+gyinc; y1 = gyinc-gxinc; break; + case 6: case 7: x1 = 0; y1 = 0; break; + case 8: case 5: x1 = gxinc; y1 = gyinc; break; + case 0: case 3: x1 = gyinc; y1 = -gxinc; break; + case 2: case 1: x1 = gxinc + gyinc; y1 = gyinc - gxinc; break; } - switch(i) + switch (i) { - case 2: case 5: x2 = 0; y2 = 0; break; - case 0: case 1: x2 = gxinc; y2 = gyinc; break; - case 8: case 7: x2 = gyinc; y2 = -gxinc; break; - case 6: case 3: x2 = gxinc+gyinc; y2 = gyinc-gxinc; break; + case 2: case 5: x2 = 0; y2 = 0; break; + case 0: case 1: x2 = gxinc; y2 = gyinc; break; + case 8: case 7: x2 = gyinc; y2 = -gxinc; break; + case 6: case 3: x2 = gxinc + gyinc; y2 = gyinc - gxinc; break; } - uint8_t oand = (1 << int(xs 0) { dagxinc = gxinc; dagyinc = FixedMul(gyinc, viewport->viewingrangerecip); } - else { dagxinc = -gxinc; dagyinc = -FixedMul(gyinc, viewport->viewingrangerecip); } + if (yi > 0) { dagxinc = gxinc; dagyinc = FixedMul(gyinc, viewport->viewingrangerecip); } + else { dagxinc = -gxinc; dagyinc = -FixedMul(gyinc, viewport->viewingrangerecip); } - /* Fix for non 90 degree viewing ranges */ + /* Fix for non 90 degree viewing ranges */ nxoff = FixedMul(x2 - x1, viewport->viewingrangerecip); x1 = FixedMul(x1, viewport->viewingrangerecip); @@ -446,7 +453,7 @@ namespace swrenderer { if ((ny <= nytooclose) || (ny >= nytoofar)) continue; voxptr = (kvxslab_t *)(slabxoffs + xyoffs[y]); - voxend = (kvxslab_t *)(slabxoffs + xyoffs[y+1]); + voxend = (kvxslab_t *)(slabxoffs + xyoffs[y + 1]); if (voxptr >= voxend) continue; lx = xs_RoundToInt(nx * centerxwide_f / (ny + y1)) + viewport->viewwindow.centerx; @@ -516,7 +523,7 @@ namespace swrenderer } else { - if (z2-z1 >= 1024) yinc = FixedDiv(zleng, z2 - z1); + if (z2 - z1 >= 1024) yinc = FixedDiv(zleng, z2 - z1); else yinc = (((1 << 24) - 1) / (z2 - z1)) * zleng >> 8; } // [RH] Clip each column separately, not just by the first one. @@ -549,7 +556,7 @@ namespace swrenderer } const uint8_t *columnColors = col; - if (!drawerargs.DrawerNeedsPalInput() && viewport->RenderTarget->IsBgra()) + if (useSlabDataBgra) { // The true color slab data array is identical, except its using uint32_t instead of uint8. // @@ -575,12 +582,31 @@ namespace swrenderer break; } + outblocks[nextoutblock].x = lxt + xxl; + outblocks[nextoutblock].y = z1; + outblocks[nextoutblock].width = xxr - xxl; + outblocks[nextoutblock].height = z2 - z1; + outblocks[nextoutblock].vPos = yplc[xxl]; + outblocks[nextoutblock].vStep = yinc; + outblocks[nextoutblock].voxels = columnColors; + outblocks[nextoutblock].voxelsCount = zleng; + nextoutblock++; + + if (nextoutblock == maxoutblocks) + { + drawerargs.DrawVoxelBlocks(thread, outblocks, nextoutblock); + outblocks = thread->FrameMemory->AllocMemory(maxoutblocks); + nextoutblock = 0; + } + + /* for (int x = xxl; x < xxr; ++x) { drawerargs.SetDest(viewport, lxt + x, z1); drawerargs.SetCount(z2 - z1); drawerargs.DrawVoxelColumn(thread, yplc[xxl], yinc, columnColors, zleng); } + */ /* if (!(flags & DVF_OFFSCREEN)) @@ -618,6 +644,11 @@ namespace swrenderer } } } + + if (nextoutblock != 0) + { + drawerargs.DrawVoxelBlocks(thread, outblocks, nextoutblock); + } } kvxslab_t *RenderVoxel::GetSlabStart(const FVoxelMipLevel &mip, int x, int y) diff --git a/src/swrenderer/viewport/r_spritedrawer.cpp b/src/swrenderer/viewport/r_spritedrawer.cpp index 841c17867..0dbb38716 100644 --- a/src/swrenderer/viewport/r_spritedrawer.cpp +++ b/src/swrenderer/viewport/r_spritedrawer.cpp @@ -494,8 +494,11 @@ namespace swrenderer thread->Drawers(dc_viewport)->FillColumn(*this); } - void SpriteDrawerArgs::DrawVoxelColumn(RenderThread *thread, fixed_t vPos, fixed_t vStep, const uint8_t *voxels, int voxelsCount) + void SpriteDrawerArgs::DrawVoxelBlocks(RenderThread *thread, const VoxelBlock *blocks, int blockcount) { + SetDest(thread->Viewport.get(), 0, 0); + thread->Drawers(dc_viewport)->DrawVoxelBlocks(*this, blocks, blockcount); +#if 0 if (dc_viewport->RenderTarget->IsBgra()) { double v = vPos / (double)voxelsCount / FRACUNIT; @@ -514,6 +517,7 @@ namespace swrenderer dc_source2 = 0; dc_textureheight = voxelsCount; (thread->Drawers(dc_viewport)->*colfunc)(*this); +#endif } void SpriteDrawerArgs::SetDest(RenderViewport *viewport, int x, int y) diff --git a/src/swrenderer/viewport/r_spritedrawer.h b/src/swrenderer/viewport/r_spritedrawer.h index a2610a4a1..e1df5e926 100644 --- a/src/swrenderer/viewport/r_spritedrawer.h +++ b/src/swrenderer/viewport/r_spritedrawer.h @@ -10,6 +10,17 @@ namespace swrenderer { class RenderThread; + class VoxelBlock + { + public: + int x, y; + uint16_t width, height; + fixed_t vPos; + fixed_t vStep; + const uint8_t *voxels; + int voxelsCount; + }; + class SpriteDrawerArgs : public DrawerArgs { public: @@ -24,7 +35,7 @@ namespace swrenderer 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, bool unmasked = false); void FillColumn(RenderThread *thread); - void DrawVoxelColumn(RenderThread *thread, fixed_t vPos, fixed_t vStep, const uint8_t *voxels, int voxelsCount); + void DrawVoxelBlocks(RenderThread *thread, const VoxelBlock *blocks, int blockcount); uint8_t *Dest() const { return dc_dest; } int DestY() const { return dc_dest_y; } @@ -95,5 +106,8 @@ namespace swrenderer SpriteDrawerFunc colfunc; RenderViewport *dc_viewport = nullptr; + + friend class DrawVoxelBlocksRGBACommand; + friend class DrawVoxelBlocksPalCommand; }; } diff --git a/src/textures/bitmap.cpp b/src/textures/bitmap.cpp index 18fb5446b..cdeb645e3 100644 --- a/src/textures/bitmap.cpp +++ b/src/textures/bitmap.cpp @@ -444,10 +444,17 @@ void FBitmap::CopyPixelData(int originx, int originy, const uint8_t * patch, int PalEntry penew[256]; memset(penew, 0, sizeof(penew)); - if (inf && inf->blend) + if (inf) { - iCopyColors((uint8_t*)penew, (const uint8_t*)palette, 256, 4, inf, 0, 0, 0); - palette = penew; + if (inf->blend) + { + iCopyColors((uint8_t*)penew, (const uint8_t*)palette, 256, 4, inf, 0, 0, 0); + palette = penew; + } + else if (inf->palette) + { + palette = inf->palette; + } } copypalettedfuncs[inf==NULL? OP_COPY : inf->op](buffer, patch, srcwidth, srcheight, Pitch, diff --git a/src/textures/bitmap.h b/src/textures/bitmap.h index 9a6dcd853..0811eaa70 100644 --- a/src/textures/bitmap.h +++ b/src/textures/bitmap.h @@ -349,6 +349,7 @@ struct FCopyInfo blend_t blendcolor[4]; blend_t alpha; blend_t invalpha; + PalEntry *palette; }; struct bOverwrite diff --git a/src/textures/multipatchtexture.cpp b/src/textures/multipatchtexture.cpp index 63b86d7a9..a765d2d41 100644 --- a/src/textures/multipatchtexture.cpp +++ b/src/textures/multipatchtexture.cpp @@ -620,7 +620,7 @@ 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, &info); + ret = Parts[i].Texture->CopyTrueColorTranslated(bmp, x+Parts[i].OriginX, y+Parts[i].OriginY, Parts[i].Rotate, Parts[i].Translation->Palette, &info); } else { diff --git a/src/textures/texture.cpp b/src/textures/texture.cpp index 162d0ca43..b446c43c6 100644 --- a/src/textures/texture.cpp +++ b/src/textures/texture.cpp @@ -811,10 +811,9 @@ int FTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyI return 0; } -int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, FRemapTable *remap, FCopyInfo *inf) +int FTexture::CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, PalEntry *remap, FCopyInfo *inf) { - PalEntry *palette = remap->Palette; - bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, palette, inf); + bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, remap, inf); return 0; } diff --git a/src/textures/textures.h b/src/textures/textures.h index 1c5a1ddf8..96bd8d3ca 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -242,7 +242,7 @@ public: virtual bool Mipmapped() { return true; } virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL); - int CopyTrueColorTranslated(FBitmap *bmp, int x, int y, int rotate, FRemapTable *remap, FCopyInfo *inf = NULL); + 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(bool wantwarped); diff --git a/src/version.h b/src/version.h index ccfa1fb7b..e939eecd2 100644 --- a/src/version.h +++ b/src/version.h @@ -91,7 +91,7 @@ const char *GetVersionString(); // Use 4500 as the base git save version, since it's higher than the // SVN revision ever got. -#define SAVEVER 4551 +#define SAVEVER 4552 // This is so that derivates can use the same savegame versions without worrying about engine compatibility #define GAMESIG "QZDOOM" diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index f78015360..485991a07 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -344,6 +344,7 @@ F481922F4881F74760F3C0437FD5EDD0 // map03 8B2AC8D4DB4A49A5DCCBB067E04434D6 // The Hell Factory Hub One, map04 65A1EB4C87386F290816660A52932FF1 // Master Levels, garrison.wad +3DEE4EFEFAF3260C800A30734F54CE75 // Hellbound, map14 { rebuildnodes } diff --git a/wadsrc/static/zscript/shared/dynlights.txt b/wadsrc/static/zscript/shared/dynlights.txt index a39b682fe..fed9696d4 100644 --- a/wadsrc/static/zscript/shared/dynlights.txt +++ b/wadsrc/static/zscript/shared/dynlights.txt @@ -77,13 +77,13 @@ class PointLightFlickerRandom : PointLight } } -// MISSILEMORE and MISSILEEVENMORE are used by the lights for additive and subtractive lights +// DYNAMICLIGHT.ADDITIVE and DYNAMICLIGHT.SUBTRACTIVE are used by the lights for additive and subtractive lights class PointLightAdditive : PointLight { Default { - +MISSILEMORE + +DYNAMICLIGHT.ADDITIVE } } @@ -91,7 +91,7 @@ class PointLightPulseAdditive : PointLightPulse { Default { - +MISSILEMORE + +DYNAMICLIGHT.ADDITIVE } } @@ -99,7 +99,7 @@ class PointLightFlickerAdditive : PointLightFlicker { Default { - +MISSILEMORE + +DYNAMICLIGHT.ADDITIVE } } @@ -107,7 +107,7 @@ class SectorPointLightAdditive : SectorPointLight { Default { - +MISSILEMORE + +DYNAMICLIGHT.ADDITIVE } } @@ -115,7 +115,7 @@ class PointLightFlickerRandomAdditive :PointLightFlickerRandom { Default { - +MISSILEMORE + +DYNAMICLIGHT.ADDITIVE } } @@ -123,7 +123,7 @@ class PointLightSubtractive : PointLight { Default { - +MISSILEEVENMORE + +DYNAMICLIGHT.SUBTRACTIVE } } @@ -131,7 +131,7 @@ class PointLightPulseSubtractive : PointLightPulse { Default { - +MISSILEEVENMORE + +DYNAMICLIGHT.SUBTRACTIVE } } @@ -139,7 +139,7 @@ class PointLightFlickerSubtractive : PointLightFlicker { Default { - +MISSILEEVENMORE + +DYNAMICLIGHT.SUBTRACTIVE } } @@ -147,7 +147,7 @@ class SectorPointLightSubtractive : SectorPointLight { Default { - +MISSILEEVENMORE + +DYNAMICLIGHT.SUBTRACTIVE } } @@ -155,7 +155,7 @@ class PointLightFlickerRandomSubtractive : PointLightFlickerRandom { Default { - +MISSILEEVENMORE + +DYNAMICLIGHT.SUBTRACTIVE } } @@ -163,7 +163,7 @@ class PointLightAttenuated : PointLight { Default { - +INCOMBAT + +DYNAMICLIGHT.ATTENUATE } } @@ -171,7 +171,7 @@ class PointLightPulseAttenuated : PointLightPulse { Default { - +INCOMBAT + +DYNAMICLIGHT.ATTENUATE } } @@ -179,7 +179,7 @@ class PointLightFlickerAttenuated : PointLightFlicker { Default { - +INCOMBAT + +DYNAMICLIGHT.ATTENUATE } } @@ -187,7 +187,7 @@ class SectorPointLightAttenuated : SectorPointLight { Default { - +INCOMBAT + +DYNAMICLIGHT.ATTENUATE } } @@ -195,7 +195,7 @@ class PointLightFlickerRandomAttenuated :PointLightFlickerRandom { Default { - +INCOMBAT + +DYNAMICLIGHT.ATTENUATE } } diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt index cc773e1a2..992328e81 100644 --- a/wadsrc/static/zscript/statusbar/statusbar.txt +++ b/wadsrc/static/zscript/statusbar/statusbar.txt @@ -1058,7 +1058,7 @@ class BaseStatusBar native ui { for(int j = 0; j < 2; j++) { - if (j ^ !!(parms.flags & DI_DRAWCURSORFIRST)) + if (j ^ !!(flags & DI_DRAWCURSORFIRST)) { if (item == CPlayer.mo.InvSel) { @@ -1073,7 +1073,7 @@ class BaseStatusBar native ui } } - if (parms.amountfont != null && (item.Amount > 1 || (parms.flags & DI_ALWAYSSHOWCOUNTERS))) + if (parms.amountfont != null && (item.Amount > 1 || (flags & DI_ALWAYSSHOWCOUNTERS))) { DrawString(parms.amountfont, FormatNumber(item.Amount, 0, 5), textpos + (boxsize.X * i, 0), flags | DI_TEXT_ALIGN_RIGHT, parms.cr, parms.itemalpha); }