This commit is contained in:
Rachael Alexanderson 2017-06-19 03:22:23 -04:00
commit d454fafc9e
39 changed files with 464 additions and 396 deletions

View File

@ -1,6 +1,5 @@
language: c++ language: c++
dist: trusty dist: trusty
sudo: required
branches: branches:
except: except:

View File

@ -1061,7 +1061,6 @@ set (PCH_SOURCES
gl/textures/gl_texture.cpp gl/textures/gl_texture.cpp
gl/textures/gl_material.cpp gl/textures/gl_material.cpp
gl/textures/gl_hirestex.cpp gl/textures/gl_hirestex.cpp
gl/textures/gl_bitmap.cpp
gl/textures/gl_samplers.cpp gl/textures/gl_samplers.cpp
gl/textures/gl_translate.cpp gl/textures/gl_translate.cpp
gl/textures/gl_hqresize.cpp gl/textures/gl_hqresize.cpp

View File

@ -139,6 +139,19 @@ void ADynamicLight::Serialize(FSerializer &arc)
if (lighttype == PulseLight) if (lighttype == PulseLight)
arc("lastupdate", m_lastUpdate, def->m_lastUpdate) arc("lastupdate", m_lastUpdate, def->m_lastUpdate)
("cycler", m_cycler, def->m_cycler); ("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; specialf1 = DAngle(double(SpawnAngle)).Normalized360().Degrees;
visibletoplayer = true; 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_INTENSITY] = args[LIGHT_INTENSITY] * 2 / 3;
args[LIGHT_SECONDARY_INTENSITY] = args[LIGHT_SECONDARY_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", 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->target? dl->target->GetClass()->TypeName.GetChars() : dl->GetClass()->TypeName.GetChars(),
dl->X(), dl->Y(), dl->Z(), dl->args[LIGHT_RED], 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++; i++;
shadowcount += dl->shadowmapped; shadowcount += dl->shadowmapped;

View File

@ -21,13 +21,19 @@ enum
LIGHT_SCALE = 3, LIGHT_SCALE = 3,
}; };
// This is as good as something new enum LightFlag
#define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE {
#define MF4_ADDITIVE MF4_MISSILEMORE LF_SUBTRACTIVE = 1,
#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS LF_ADDITIVE = 2,
#define MF4_ATTENUATE MF4_INCOMBAT LF_DONTLIGHTSELF = 4,
#define MF4_NOSHADOWMAP MF4_STANDSTILL LF_ATTENUATE = 8,
#define MF4_DONTLIGHTACTORS MF4_EXTREMEDEATH LF_NOSHADOWMAP = 16,
LF_DONTLIGHTACTORS = 32
};
typedef TFlags<LightFlag> LightFlags;
DEFINE_TFLAGS_OPERATORS(LightFlags)
enum ELightType enum ELightType
{ {
@ -92,8 +98,8 @@ public:
void UpdateLocation(); void UpdateLocation();
bool IsOwned() const { return owned; } bool IsOwned() const { return owned; }
bool IsActive() const { return !(flags2&MF2_DORMANT); } bool IsActive() const { return !(flags2&MF2_DORMANT); }
bool IsSubtractive() { return !!(flags4&MF4_SUBTRACTIVE); } bool IsSubtractive() { return !!(lightflags & LF_SUBTRACTIVE); }
bool IsAdditive() { return !!(flags4&MF4_ADDITIVE); } bool IsAdditive() { return !!(lightflags & LF_ADDITIVE); }
FState *targetState; FState *targetState;
FLightNode * touching_sides; FLightNode * touching_sides;
FLightNode * touching_subsectors; FLightNode * touching_subsectors;
@ -112,7 +118,6 @@ protected:
public: public:
int m_tickCount; int m_tickCount;
uint8_t lightflags;
uint8_t lighttype; uint8_t lighttype;
bool owned; bool owned;
bool halo; bool halo;
@ -121,6 +126,7 @@ public:
bool swapped; bool swapped;
bool shadowmapped; bool shadowmapped;
int bufferindex; int bufferindex;
LightFlags lightflags;
}; };

View File

@ -178,11 +178,11 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
for (int a = 0; a < 3; a++) light->args[a] = clamp<int>((int)(m_Args[a]), 0, 255); for (int a = 0; a < 3; a++) light->args[a] = clamp<int>((int)(m_Args[a]), 0, 255);
light->args[LIGHT_INTENSITY] = m_Args[LIGHT_INTENSITY]; light->args[LIGHT_INTENSITY] = m_Args[LIGHT_INTENSITY];
light->args[LIGHT_SECONDARY_INTENSITY] = m_Args[LIGHT_SECONDARY_INTENSITY]; light->args[LIGHT_SECONDARY_INTENSITY] = m_Args[LIGHT_SECONDARY_INTENSITY];
light->flags4 &= ~(MF4_ADDITIVE | MF4_SUBTRACTIVE | MF4_DONTLIGHTSELF); light->lightflags &= ~(LF_ADDITIVE | LF_SUBTRACTIVE | LF_DONTLIGHTSELF);
if (m_subtractive) light->flags4 |= MF4_SUBTRACTIVE; if (m_subtractive) light->lightflags |= LF_SUBTRACTIVE;
if (m_additive) light->flags4 |= MF4_ADDITIVE; if (m_additive) light->lightflags |= LF_ADDITIVE;
if (m_dontlightself) light->flags4 |= MF4_DONTLIGHTSELF; if (m_dontlightself) light->lightflags |= LF_DONTLIGHTSELF;
if (m_dontlightactors) light->flags4 |= MF4_DONTLIGHTACTORS; if (m_dontlightactors) light->lightflags |= LF_DONTLIGHTACTORS;
light->m_tickCount = 0; light->m_tickCount = 0;
if (m_type == PulseLight) if (m_type == PulseLight)
{ {
@ -200,9 +200,9 @@ void FLightDefaults::ApplyProperties(ADynamicLight * light) const
switch (m_attenuate) switch (m_attenuate)
{ {
case 0: light->flags4 &= ~MF4_ATTENUATE; break; case 0: light->lightflags &= ~LF_ATTENUATE; break;
case 1: light->flags4 |= MF4_ATTENUATE; break; case 1: light->lightflags |= LF_ATTENUATE; break;
default: if (level.flags3 & LEVEL3_ATTENUATE) light->flags4 |= MF4_ATTENUATE; else light->flags4 &= ~MF4_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->target = this;
light->owned = true; light->owned = true;
light->ObjectFlags |= OF_Transient; light->ObjectFlags |= OF_Transient;
//light->flags4 |= MF4_ATTENUATE; //light->lightflags |= LF_ATTENUATE;
AttachedLights.Push(light); AttachedLights.Push(light);
} }
light->flags2&=~MF2_DORMANT; light->flags2&=~MF2_DORMANT;

View File

@ -110,7 +110,7 @@ bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, FD
float shadowIndex = GLRenderer->mShadowMap.ShadowMapIndex(light) + 1.0f; float shadowIndex = GLRenderer->mShadowMap.ShadowMapIndex(light) + 1.0f;
bool attenuate; bool attenuate;
if (gl_attenuate == -1) attenuate = !!(light->flags4 & MF4_ATTENUATE); if (gl_attenuate == -1) attenuate = !!(light->lightflags & LF_ATTENUATE);
else attenuate = !!gl_attenuate; else attenuate = !!gl_attenuate;
if (attenuate) shadowIndex = -shadowIndex; if (attenuate) shadowIndex = -shadowIndex;

View File

@ -72,7 +72,6 @@
#include "gl/scene/gl_scenedrawer.h" #include "gl/scene/gl_scenedrawer.h"
#include "gl/scene/gl_portal.h" #include "gl/scene/gl_portal.h"
#include "gl/shaders/gl_shader.h" #include "gl/shaders/gl_shader.h"
#include "gl/textures/gl_bitmap.h"
#include "gl/textures/gl_texture.h" #include "gl/textures/gl_texture.h"
#include "gl/textures/gl_material.h" #include "gl/textures/gl_material.h"

View File

@ -62,7 +62,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
while (node) while (node)
{ {
light=node->lightsource; 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; float dist;

View File

@ -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<class T>
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<count;i++)
{
if ((a = T::A(pin, tr, tg, tb)) != 0)
{
pout[0]=T::R(pin);
pout[1]=T::G(pin);
pout[2]=T::B(pin);
pout[3]=a;
}
pout+=4;
pin+=step;
}
}
typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, int count, int step, uint8_t tr, uint8_t tg, uint8_t tb);
static CopyFunc copyfuncs[]={
iCopyColors<cRGB>,
iCopyColors<cRGBT>,
iCopyColors<cRGBA>,
iCopyColors<cIA>,
iCopyColors<cCMYK>,
iCopyColors<cBGR>,
iCopyColors<cBGRA>,
iCopyColors<cI16>,
iCopyColors<cRGB555>,
iCopyColors<cPalEntry>
};
//===========================================================================
//
// 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<srcheight;y++)
{
copyfuncs[ct](&buffer[y*Pitch], &patch[y*step_y], srcwidth, step_x, (uint8_t)r, (uint8_t)g, (uint8_t)b);
}
}
}
//===========================================================================
//
// Paletted to True Color texture copy function
//
//===========================================================================
void FGLBitmap::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)
{
PalEntry penew[256];
int x,y,pos,i;
if (ClipCopyPixelRect(&ClipRect, originx, originy, patch, srcwidth, srcheight, step_x, step_y, rotate))
{
uint8_t *buffer = GetPixels() + 4*originx + Pitch*originy;
if (translation > 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;y<srcheight;y++)
{
pos=(y*Pitch);
for (x=0;x<srcwidth;x++,pos+=4)
{
int v=(unsigned char)patch[y*step_y+x*step_x];
if (penew[v].a!=0)
{
buffer[pos] = penew[v].r;
buffer[pos+1] = penew[v].g;
buffer[pos+2] = penew[v].b;
buffer[pos+3] = penew[v].a;
}
}
}
}
}

View File

@ -1,36 +0,0 @@
#ifndef __GL_BITMAP_H
#define __GL_BITMAP_H
#include "textures/bitmap.h"
#include "gl/textures/gl_material.h"
class FGLBitmap : public FBitmap
{
int translation = 0;
bool alphatrans = false;
public:
FGLBitmap()
{
}
FGLBitmap(uint8_t *buffer, int pitch, int width, int height)
: FBitmap(buffer, pitch, width, height)
{
}
void SetTranslationInfo(int _trans, bool _alphatrans = false)
{
if (_trans != -1337) translation = _trans;
alphatrans = _alphatrans;
}
virtual 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,
int step_x, int step_y, int rotate, PalEntry * palette, FCopyInfo *inf = NULL);
};
#endif

View File

@ -207,7 +207,7 @@ unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int
} }
} }
} }
glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer); glTexImage2D(GL_TEXTURE_2D, 0, texformat, rw, rh, 0, GL_BGRA, GL_UNSIGNED_BYTE, buffer);
if (deletebuffer) free(buffer); if (deletebuffer) free(buffer);

View File

@ -33,6 +33,7 @@
#include "sc_man.h" #include "sc_man.h"
#include "colormatcher.h" #include "colormatcher.h"
#include "textures/warpbuffer.h" #include "textures/warpbuffer.h"
#include "textures/bitmap.h"
//#include "gl/gl_intern.h" //#include "gl/gl_intern.h"
@ -43,7 +44,6 @@
#include "gl/data/gl_data.h" #include "gl/data/gl_data.h"
#include "gl/textures/gl_texture.h" #include "gl/textures/gl_texture.h"
#include "gl/textures/gl_translate.h" #include "gl/textures/gl_translate.h"
#include "gl/textures/gl_bitmap.h"
#include "gl/textures/gl_material.h" #include "gl/textures/gl_material.h"
#include "gl/textures/gl_samplers.h" #include "gl/textures/gl_samplers.h"
#include "gl/shaders/gl_shader.h" #include "gl/shaders/gl_shader.h"
@ -120,7 +120,7 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig
unsigned char * buffer=new unsigned char[w*(h+1)*4]; unsigned char * buffer=new unsigned char[w*(h+1)*4];
memset(buffer, 0, w * (h+1) * 4); memset(buffer, 0, w * (h+1) * 4);
FGLBitmap bmp(buffer, w*4, w, h); FBitmap bmp(buffer, w*4, w, h);
int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0); int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0);
hirestexture->CheckTrans(buffer, w*h, trans); hirestexture->CheckTrans(buffer, w*h, trans);
@ -210,15 +210,16 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F
buffer=new unsigned char[W*(H+1)*4]; buffer=new unsigned char[W*(H+1)*4];
memset(buffer, 0, W * (H+1) * 4); memset(buffer, 0, W * (H+1) * 4);
FGLBitmap bmp(buffer, W*4, W, H); FBitmap bmp(buffer, W*4, W, H);
bmp.SetTranslationInfo(translation, alphatrans);
if (translation <= 0)
{
// Q: Is this special treatment still needed? Needs to be checked.
if (tex->bComplex) if (tex->bComplex)
{ {
FBitmap imgCreate; FBitmap imgCreate;
// The texture contains special processing so it must be composited using the // The texture contains special processing so it must be fully composited before being converted as a whole.
// base bitmap class and then be converted as a whole.
if (imgCreate.Create(W, H)) if (imgCreate.Create(W, H))
{ {
memset(imgCreate.GetPixels(), 0, W * H * 4); memset(imgCreate.GetPixels(), 0, W * H * 4);
@ -229,19 +230,19 @@ unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, F
if (bIsTransparent == -1) bIsTransparent = isTransparent; if (bIsTransparent == -1) bIsTransparent = isTransparent;
} }
} }
else if (translation<=0) else
{ {
int trans = tex->CopyTrueColorPixels(&bmp, exx, exx); int trans = tex->CopyTrueColorPixels(&bmp, exx, exx);
tex->CheckTrans(buffer, W*H, trans); tex->CheckTrans(buffer, W*H, trans);
isTransparent = tex->gl_info.mIsTransparent; isTransparent = tex->gl_info.mIsTransparent;
if (bIsTransparent == -1) bIsTransparent = isTransparent; if (bIsTransparent == -1) bIsTransparent = isTransparent;
} }
}
else else
{ {
// When using translations everything must be mapped to the base palette. // 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 // so use CopyTrueColorTranslated
// to do all the dirty work for us. ;) tex->CopyTrueColorTranslated(&bmp, exx, exx, 0, GLTranslationPalette::GetPalette(translation));
tex->FTexture::CopyTrueColorPixels(&bmp, exx, exx);
isTransparent = 0; isTransparent = 0;
// This is not conclusive for setting the texture's transparency info. // This is not conclusive for setting the texture's transparency info.
} }

View File

@ -538,7 +538,7 @@ void FBrightmapTexture::Unload ()
int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf) 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; return 0;
} }

View File

@ -757,7 +757,7 @@ int CreateBloodTranslation(PalEntry color)
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
int bright = MAX(MAX(GPalette.BaseColors[i].r, GPalette.BaseColors[i].g), GPalette.BaseColors[i].b); 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); int entry = ColorMatcher.Pick(pe.r, pe.g, pe.b);
trans->Palette[i] = pe; trans->Palette[i] = pe;

View File

@ -488,12 +488,12 @@ static FFlagDef PlayerPawnFlagDefs[] =
static FFlagDef DynLightFlagDefs[] = static FFlagDef DynLightFlagDefs[] =
{ {
// PlayerPawn flags // PlayerPawn flags
DEFINE_FLAG(MF4, SUBTRACTIVE, ADynamicLight, flags4), DEFINE_FLAG(LF, SUBTRACTIVE, ADynamicLight, lightflags),
DEFINE_FLAG(MF4, ADDITIVE, ADynamicLight, flags4), DEFINE_FLAG(LF, ADDITIVE, ADynamicLight, lightflags),
DEFINE_FLAG(MF4, DONTLIGHTSELF, ADynamicLight, flags4), DEFINE_FLAG(LF, DONTLIGHTSELF, ADynamicLight, lightflags),
DEFINE_FLAG(MF4, ATTENUATE, ADynamicLight, flags4), DEFINE_FLAG(LF, ATTENUATE, ADynamicLight, lightflags),
DEFINE_FLAG(MF4, NOSHADOWMAP, ADynamicLight, flags4), DEFINE_FLAG(LF, NOSHADOWMAP, ADynamicLight, lightflags),
DEFINE_FLAG(MF4, DONTLIGHTACTORS, ADynamicLight, flags4), DEFINE_FLAG(LF, DONTLIGHTACTORS, ADynamicLight, lightflags),
}; };
static FFlagDef PowerSpeedFlagDefs[] = static FFlagDef PowerSpeedFlagDefs[] =

View File

@ -28,6 +28,7 @@ namespace swrenderer
class WallDrawerArgs; class WallDrawerArgs;
class SpanDrawerArgs; class SpanDrawerArgs;
class SpriteDrawerArgs; class SpriteDrawerArgs;
class VoxelBlock;
extern uint8_t shadetables[/*NUMCOLORMAPS*16*256*/]; extern uint8_t shadetables[/*NUMCOLORMAPS*16*256*/];
extern FDynamicColormap ShadeFakeColormap[16]; extern FDynamicColormap ShadeFakeColormap[16];
@ -79,6 +80,7 @@ namespace swrenderer
virtual void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) = 0; virtual void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) = 0;
virtual void DrawRevSubClampColumn(const SpriteDrawerArgs &args) = 0; virtual void DrawRevSubClampColumn(const SpriteDrawerArgs &args) = 0;
virtual void DrawRevSubClampTranslatedColumn(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 DrawSpan(const SpanDrawerArgs &args) = 0;
virtual void DrawSpanMasked(const SpanDrawerArgs &args) = 0; virtual void DrawSpanMasked(const SpanDrawerArgs &args) = 0;
virtual void DrawSpanTranslucent(const SpanDrawerArgs &args) = 0; virtual void DrawSpanTranslucent(const SpanDrawerArgs &args) = 0;

View File

@ -3011,4 +3011,107 @@ namespace swrenderer
{ {
return "DrawParticle"; 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";
}
} }

View File

@ -49,10 +49,10 @@ namespace swrenderer
PalColumnCommand(const SpriteDrawerArgs &args); PalColumnCommand(const SpriteDrawerArgs &args);
FString DebugInfo() override { return "PalColumnCommand"; } FString DebugInfo() override { return "PalColumnCommand"; }
SpriteDrawerArgs args;
protected: protected:
uint8_t AddLights(uint8_t fg, uint8_t material, uint32_t lit_r, uint32_t lit_g, uint32_t lit_b); 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; }; class DrawColumnPalCommand : public PalColumnCommand { public: using PalColumnCommand::PalColumnCommand; void Execute(DrawerThread *thread) override; };
@ -205,6 +205,19 @@ namespace swrenderer
uint32_t _fracposx; 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 class SWPalDrawers : public SWPixelFormatDrawers
{ {
public: public:
@ -244,6 +257,7 @@ namespace swrenderer
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampTranslatedPalCommand>(args); } void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnSubClampTranslatedPalCommand>(args); }
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampPalCommand>(args); } void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampPalCommand>(args); }
void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampTranslatedPalCommand>(args); } void DrawRevSubClampTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampTranslatedPalCommand>(args); }
void DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount) override { Queue->Push<DrawVoxelBlocksPalCommand>(args, blocks, blockcount); }
void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanPalCommand>(args); } void DrawSpan(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanPalCommand>(args); }
void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedPalCommand>(args); } void DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedPalCommand>(args); }
void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanTranslucentPalCommand>(args); } void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanTranslucentPalCommand>(args); }

View File

@ -201,6 +201,11 @@ namespace swrenderer
Queue->Push<DrawSpriteTranslatedRevSubClamp32Command>(args); Queue->Push<DrawSpriteTranslatedRevSubClamp32Command>(args);
} }
void SWTruecolorDrawers::DrawVoxelBlocks(const SpriteDrawerArgs &args, const VoxelBlock *blocks, int blockcount)
{
Queue->Push<DrawVoxelBlocksRGBACommand>(args, blocks, blockcount);
}
void SWTruecolorDrawers::DrawSpan(const SpanDrawerArgs &args) void SWTruecolorDrawers::DrawSpan(const SpanDrawerArgs &args)
{ {
Queue->Push<DrawSpan32Command>(args); Queue->Push<DrawSpan32Command>(args);
@ -858,4 +863,44 @@ namespace swrenderer
return "DrawParticle"; 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";
}
} }

View File

@ -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 class SWTruecolorDrawers : public SWPixelFormatDrawers
{ {
public: public:
@ -246,6 +261,7 @@ namespace swrenderer
void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override; void DrawSubClampTranslatedColumn(const SpriteDrawerArgs &args) override;
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override; void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override;
void DrawRevSubClampTranslatedColumn(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 DrawSpan(const SpanDrawerArgs &args) override;
void DrawSpanMasked(const SpanDrawerArgs &args) override; void DrawSpanMasked(const SpanDrawerArgs &args) override;
void DrawSpanTranslucent(const SpanDrawerArgs &args) override; void DrawSpanTranslucent(const SpanDrawerArgs &args) override;

View File

@ -56,10 +56,9 @@ namespace swrenderer
template<typename BlendT, typename SamplerT> template<typename BlendT, typename SamplerT>
class DrawSprite32T : public DrawerCommand class DrawSprite32T : public DrawerCommand
{ {
protected: public:
SpriteDrawerArgs args; SpriteDrawerArgs args;
public:
DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { } DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { }
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override

View File

@ -56,10 +56,9 @@ namespace swrenderer
template<typename BlendT, typename SamplerT> template<typename BlendT, typename SamplerT>
class DrawSprite32T : public DrawerCommand class DrawSprite32T : public DrawerCommand
{ {
protected: public:
SpriteDrawerArgs args; SpriteDrawerArgs args;
public:
DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { } DrawSprite32T(const SpriteDrawerArgs &drawerargs) : args(drawerargs) { }
void Execute(DrawerThread *thread) override void Execute(DrawerThread *thread) override

View File

@ -66,21 +66,6 @@ namespace swrenderer
void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2) void RenderDrawSegment::Render(DrawSegment *ds, int x1, int x2)
{ {
auto viewport = Thread->Viewport.get(); 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; curline = ds->curline;
@ -105,14 +90,9 @@ namespace swrenderer
frontsector = curline->frontsector; frontsector = curline->frontsector;
backsector = curline->backsector; 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 // 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 FDynamicColormap *basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::walltop]); // [RH] Set basecolormap
@ -122,14 +102,15 @@ namespace swrenderer
Clip3DFloors *clip3d = Thread->Clip3D.get(); Clip3DFloors *clip3d = Thread->Clip3D.get();
CameraLight *cameraLight = CameraLight::Instance();
if (cameraLight->FixedLightLevel() < 0)
{
if (!(clip3d->fake3D & FAKE3D_CLIPTOP)) if (!(clip3d->fake3D & FAKE3D_CLIPTOP))
{ {
clip3d->sclipTop = sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos); clip3d->sclipTop = sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos);
} }
for (i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
CameraLight *cameraLight = CameraLight::Instance();
if (cameraLight->FixedLightLevel() < 0)
{
for (int i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
{ {
if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0()) if (clip3d->sclipTop <= frontsector->e->XFloor.lightlist[i].plane.Zat0())
{ {
@ -142,30 +123,71 @@ namespace swrenderer
} }
} }
short *mfloorclip = ds->sprbottomclip - ds->x1; bool wrap = (curline->linedef->flags & ML_WRAP_MIDTEX) || (curline->sidedef->Flags & WALLF_WRAP_MIDTEX);
short *mceilingclip = ds->sprtopclip - ds->x1;
double spryscale;
// [RH] Draw fog partition // [RH] Draw fog partition
bool notrelevant = false;
if (ds->bFogBoundary) 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); 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; if (ds->bFakeBoundary & 3)
MaskedScaleY = ds->yscale; {
maskedtexturecol = ds->maskedtexturecol - ds->x1; RenderFakeWallRange(ds, x1, x2, wallshade);
spryscale = ds->iscale + ds->iscalestep * (x1 - ds->x1); }
rw_scalestep = ds->iscalestep; 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) if (cameraLight->FixedLightLevel() >= 0)
{ {
walldrawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, cameraLight->FixedLightLevelShade()); walldrawerargs.SetLight((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap, 0, cameraLight->FixedLightLevelShade());
@ -178,8 +200,8 @@ namespace swrenderer
} }
// find positioning // find positioning
texheight = tex->GetScaledHeightDouble(); double texheight = tex->GetScaledHeightDouble();
texheightscale = fabs(curline->sidedef->GetTextureYScale(side_t::mid)); double texheightscale = fabs(curline->sidedef->GetTextureYScale(side_t::mid));
if (texheightscale != 1) if (texheightscale != 1)
{ {
texheight = texheight / texheightscale; texheight = texheight / texheightscale;
@ -195,13 +217,14 @@ namespace swrenderer
texturemid = MIN(frontsector->GetPlaneTexZ(sector_t::ceiling), backsector->GetPlaneTexZ(sector_t::ceiling)); 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) if (!wrap)
{ // Texture does not wrap vertically. { // Texture does not wrap vertically.
double textop; double textop;
bool sprflipvert = false;
if (MaskedScaleY < 0) if (MaskedScaleY < 0)
{ {
MaskedScaleY = -MaskedScaleY; MaskedScaleY = -MaskedScaleY;
@ -231,23 +254,21 @@ namespace swrenderer
// [RH] Don't bother drawing segs that are completely offscreen // [RH] Don't bother drawing segs that are completely offscreen
if (viewport->globaldclip * ds->sz1 < -textop && viewport->globaldclip * ds->sz2 < -textop) if (viewport->globaldclip * ds->sz1 < -textop && viewport->globaldclip * ds->sz2 < -textop)
{ // Texture top is below the bottom of the screen { // 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) if (viewport->globaluclip * ds->sz1 > texheight - textop && viewport->globaluclip * ds->sz2 > texheight - textop)
{ // Texture bottom is above the top of the screen { // 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) if ((clip3d->fake3D & FAKE3D_CLIPBOTTOM) && textop < clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z)
{ {
notrelevant = true; return true;
goto clearfog;
} }
if ((clip3d->fake3D & FAKE3D_CLIPTOP) && textop - texheight > clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z) if ((clip3d->fake3D & FAKE3D_CLIPTOP) && textop - texheight > clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z)
{ {
notrelevant = true; return true;
goto clearfog;
} }
WallC.sz1 = ds->sz1; WallC.sz1 = ds->sz1;
@ -272,12 +293,12 @@ namespace swrenderer
walllower.Project(Thread->Viewport.get(), textop - texheight, &WallC); 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]) if (wallupper.ScreenY[i] < mceilingclip[i])
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]) if (walllower.ScreenY[i] > mfloorclip[i])
walllower.ScreenY[i] = mfloorclip[i]; walllower.ScreenY[i] = mfloorclip[i];
@ -358,7 +379,7 @@ namespace swrenderer
if (clip3d->fake3D & FAKE3D_CLIPTOP) if (clip3d->fake3D & FAKE3D_CLIPTOP)
{ {
wallupper.Project(Thread->Viewport.get(), clip3d->sclipTop - Thread->Viewport->viewpoint.Pos.Z, &WallC); 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]) if (wallupper.ScreenY[i] < mceilingclip[i])
wallupper.ScreenY[i] = mceilingclip[i]; wallupper.ScreenY[i] = mceilingclip[i];
@ -368,7 +389,7 @@ namespace swrenderer
if (clip3d->fake3D & FAKE3D_CLIPBOTTOM) if (clip3d->fake3D & FAKE3D_CLIPBOTTOM)
{ {
walllower.Project(Thread->Viewport.get(), clip3d->sclipBottom - Thread->Viewport->viewpoint.Pos.Z, &WallC); 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]) if (walllower.ScreenY[i] > mfloorclip[i])
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); 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: return false;
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;
} }
// kg3D - render one fake wall // kg3D - render one fake wall

View File

@ -37,6 +37,7 @@ namespace swrenderer
RenderThread *Thread = nullptr; RenderThread *Thread = nullptr;
private: 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 ClipMidtex(int x1, int x2);
void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap); void RenderFakeWall(DrawSegment *ds, int x1, int x2, F3DFloor *rover, int wallshade, FDynamicColormap *basecolormap);
void RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade); void RenderFakeWallRange(DrawSegment *ds, int x1, int x2, int wallshade);

View File

@ -220,7 +220,7 @@ namespace swrenderer
float lz = (float)lightZ; float lz = (float)lightZ;
// Precalculate the constant part of the dot here so the drawer doesn't have to. // 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 lconstant = lx * lx + ly * ly;
float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f; float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f;

View File

@ -249,7 +249,7 @@ namespace swrenderer
float lz = (float)lightZ - drawerargs.dc_viewpos.Z; float lz = (float)lightZ - drawerargs.dc_viewpos.Z;
// Precalculate the constant part of the dot here so the drawer doesn't have to. // 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 lconstant = ly * ly + lz * lz;
float nlconstant = is_point_light ? lz * drawerargs.dc_normal.Z : 0.0f; float nlconstant = is_point_light ? lz * drawerargs.dc_normal.Z : 0.0f;

View File

@ -255,7 +255,7 @@ namespace swrenderer
while (node != nullptr) while (node != nullptr)
{ {
ADynamicLight *light = node->lightsource; 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 lx = (float)(light->X() - thing->X());
float ly = (float)(light->Y() - thing->Y()); float ly = (float)(light->Y() - thing->Y());

View File

@ -220,11 +220,12 @@ namespace swrenderer
{ {
CheckOffscreenBuffer(viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight(), !!(flags & DVF_SPANSONLY)); CheckOffscreenBuffer(viewport->RenderTarget->GetWidth(), viewport->RenderTarget->GetHeight(), !!(flags & DVF_SPANSONLY));
} }
*/
if (spr->bInMirror) if (spr->bInMirror)
{ {
flags |= DVF_MIRRORED; flags |= DVF_MIRRORED;
} }
*/
// Render the voxel, either directly to the screen or offscreen. // Render the voxel, either directly to the screen or offscreen.
DrawVoxel(thread, drawerargs, spr->pa.vpos, spr->pa.vang, spr->gpos, spr->Angle, DrawVoxel(thread, drawerargs, spr->pa.vpos, spr->pa.vang, spr->gpos, spr->Angle,
@ -376,6 +377,12 @@ namespace swrenderer
syoff = DivScale21(globalposz - dasprz, FixedMul(dazscale, 0xE800)) + (piv_z << 7); syoff = DivScale21(globalposz - dasprz, FixedMul(dazscale, 0xE800)) + (piv_z << 7);
yoff = (abs(gxinc) + abs(gyinc)) >> 1; yoff = (abs(gxinc) + abs(gyinc)) >> 1;
bool useSlabDataBgra = !drawerargs.DrawerNeedsPalInput() && viewport->RenderTarget->IsBgra();
const int maxoutblocks = 100;
VoxelBlock *outblocks = thread->FrameMemory->AllocMemory<VoxelBlock>(maxoutblocks);
int nextoutblock = 0;
for (cnt = 0; cnt < 8; cnt++) for (cnt = 0; cnt < 8; cnt++)
{ {
switch (cnt) switch (cnt)
@ -549,7 +556,7 @@ namespace swrenderer
} }
const uint8_t *columnColors = col; 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. // The true color slab data array is identical, except its using uint32_t instead of uint8.
// //
@ -575,12 +582,31 @@ namespace swrenderer
break; 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<VoxelBlock>(maxoutblocks);
nextoutblock = 0;
}
/*
for (int x = xxl; x < xxr; ++x) for (int x = xxl; x < xxr; ++x)
{ {
drawerargs.SetDest(viewport, lxt + x, z1); drawerargs.SetDest(viewport, lxt + x, z1);
drawerargs.SetCount(z2 - z1); drawerargs.SetCount(z2 - z1);
drawerargs.DrawVoxelColumn(thread, yplc[xxl], yinc, columnColors, zleng); drawerargs.DrawVoxelColumn(thread, yplc[xxl], yinc, columnColors, zleng);
} }
*/
/* /*
if (!(flags & DVF_OFFSCREEN)) 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) kvxslab_t *RenderVoxel::GetSlabStart(const FVoxelMipLevel &mip, int x, int y)

View File

@ -494,8 +494,11 @@ namespace swrenderer
thread->Drawers(dc_viewport)->FillColumn(*this); 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()) if (dc_viewport->RenderTarget->IsBgra())
{ {
double v = vPos / (double)voxelsCount / FRACUNIT; double v = vPos / (double)voxelsCount / FRACUNIT;
@ -514,6 +517,7 @@ namespace swrenderer
dc_source2 = 0; dc_source2 = 0;
dc_textureheight = voxelsCount; dc_textureheight = voxelsCount;
(thread->Drawers(dc_viewport)->*colfunc)(*this); (thread->Drawers(dc_viewport)->*colfunc)(*this);
#endif
} }
void SpriteDrawerArgs::SetDest(RenderViewport *viewport, int x, int y) void SpriteDrawerArgs::SetDest(RenderViewport *viewport, int x, int y)

View File

@ -10,6 +10,17 @@ namespace swrenderer
{ {
class RenderThread; 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 class SpriteDrawerArgs : public DrawerArgs
{ {
public: 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 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 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; } uint8_t *Dest() const { return dc_dest; }
int DestY() const { return dc_dest_y; } int DestY() const { return dc_dest_y; }
@ -95,5 +106,8 @@ namespace swrenderer
SpriteDrawerFunc colfunc; SpriteDrawerFunc colfunc;
RenderViewport *dc_viewport = nullptr; RenderViewport *dc_viewport = nullptr;
friend class DrawVoxelBlocksRGBACommand;
friend class DrawVoxelBlocksPalCommand;
}; };
} }

View File

@ -444,11 +444,18 @@ void FBitmap::CopyPixelData(int originx, int originy, const uint8_t * patch, int
PalEntry penew[256]; PalEntry penew[256];
memset(penew, 0, sizeof(penew)); memset(penew, 0, sizeof(penew));
if (inf && inf->blend) if (inf)
{
if (inf->blend)
{ {
iCopyColors<cPalEntry, cBGRA, bCopy>((uint8_t*)penew, (const uint8_t*)palette, 256, 4, inf, 0, 0, 0); iCopyColors<cPalEntry, cBGRA, bCopy>((uint8_t*)penew, (const uint8_t*)palette, 256, 4, inf, 0, 0, 0);
palette = penew; palette = penew;
} }
else if (inf->palette)
{
palette = inf->palette;
}
}
copypalettedfuncs[inf==NULL? OP_COPY : inf->op](buffer, patch, srcwidth, srcheight, Pitch, copypalettedfuncs[inf==NULL? OP_COPY : inf->op](buffer, patch, srcwidth, srcheight, Pitch,
step_x, step_y, rotate, palette, inf); step_x, step_y, rotate, palette, inf);

View File

@ -349,6 +349,7 @@ struct FCopyInfo
blend_t blendcolor[4]; blend_t blendcolor[4];
blend_t alpha; blend_t alpha;
blend_t invalpha; blend_t invalpha;
PalEntry *palette;
}; };
struct bOverwrite struct bOverwrite

View File

@ -620,7 +620,7 @@ int FMultiPatchTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rota
if (Parts[i].Translation != NULL) if (Parts[i].Translation != NULL)
{ // Using a translation forces downconversion to the base palette { // 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 else
{ {

View File

@ -811,10 +811,9 @@ int FTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyI
return 0; 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, remap, inf);
bmp->CopyPixelData(x, y, GetPixels(), Width, Height, Height, 1, rotate, palette, inf);
return 0; return 0;
} }

View File

@ -242,7 +242,7 @@ public:
virtual bool Mipmapped() { return true; } virtual bool Mipmapped() { return true; }
virtual int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate=0, FCopyInfo *inf = NULL); 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 bool UseBasePalette();
virtual int GetSourceLump() { return SourceLump; } virtual int GetSourceLump() { return SourceLump; }
virtual FTexture *GetRedirect(bool wantwarped); virtual FTexture *GetRedirect(bool wantwarped);

View File

@ -91,7 +91,7 @@ const char *GetVersionString();
// Use 4500 as the base git save version, since it's higher than the // Use 4500 as the base git save version, since it's higher than the
// SVN revision ever got. // 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 // This is so that derivates can use the same savegame versions without worrying about engine compatibility
#define GAMESIG "QZDOOM" #define GAMESIG "QZDOOM"

View File

@ -344,6 +344,7 @@ F481922F4881F74760F3C0437FD5EDD0 // map03
8B2AC8D4DB4A49A5DCCBB067E04434D6 // The Hell Factory Hub One, map04 8B2AC8D4DB4A49A5DCCBB067E04434D6 // The Hell Factory Hub One, map04
65A1EB4C87386F290816660A52932FF1 // Master Levels, garrison.wad 65A1EB4C87386F290816660A52932FF1 // Master Levels, garrison.wad
3DEE4EFEFAF3260C800A30734F54CE75 // Hellbound, map14
{ {
rebuildnodes rebuildnodes
} }

View File

@ -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 class PointLightAdditive : PointLight
{ {
Default Default
{ {
+MISSILEMORE +DYNAMICLIGHT.ADDITIVE
} }
} }
@ -91,7 +91,7 @@ class PointLightPulseAdditive : PointLightPulse
{ {
Default Default
{ {
+MISSILEMORE +DYNAMICLIGHT.ADDITIVE
} }
} }
@ -99,7 +99,7 @@ class PointLightFlickerAdditive : PointLightFlicker
{ {
Default Default
{ {
+MISSILEMORE +DYNAMICLIGHT.ADDITIVE
} }
} }
@ -107,7 +107,7 @@ class SectorPointLightAdditive : SectorPointLight
{ {
Default Default
{ {
+MISSILEMORE +DYNAMICLIGHT.ADDITIVE
} }
} }
@ -115,7 +115,7 @@ class PointLightFlickerRandomAdditive :PointLightFlickerRandom
{ {
Default Default
{ {
+MISSILEMORE +DYNAMICLIGHT.ADDITIVE
} }
} }
@ -123,7 +123,7 @@ class PointLightSubtractive : PointLight
{ {
Default Default
{ {
+MISSILEEVENMORE +DYNAMICLIGHT.SUBTRACTIVE
} }
} }
@ -131,7 +131,7 @@ class PointLightPulseSubtractive : PointLightPulse
{ {
Default Default
{ {
+MISSILEEVENMORE +DYNAMICLIGHT.SUBTRACTIVE
} }
} }
@ -139,7 +139,7 @@ class PointLightFlickerSubtractive : PointLightFlicker
{ {
Default Default
{ {
+MISSILEEVENMORE +DYNAMICLIGHT.SUBTRACTIVE
} }
} }
@ -147,7 +147,7 @@ class SectorPointLightSubtractive : SectorPointLight
{ {
Default Default
{ {
+MISSILEEVENMORE +DYNAMICLIGHT.SUBTRACTIVE
} }
} }
@ -155,7 +155,7 @@ class PointLightFlickerRandomSubtractive : PointLightFlickerRandom
{ {
Default Default
{ {
+MISSILEEVENMORE +DYNAMICLIGHT.SUBTRACTIVE
} }
} }
@ -163,7 +163,7 @@ class PointLightAttenuated : PointLight
{ {
Default Default
{ {
+INCOMBAT +DYNAMICLIGHT.ATTENUATE
} }
} }
@ -171,7 +171,7 @@ class PointLightPulseAttenuated : PointLightPulse
{ {
Default Default
{ {
+INCOMBAT +DYNAMICLIGHT.ATTENUATE
} }
} }
@ -179,7 +179,7 @@ class PointLightFlickerAttenuated : PointLightFlicker
{ {
Default Default
{ {
+INCOMBAT +DYNAMICLIGHT.ATTENUATE
} }
} }
@ -187,7 +187,7 @@ class SectorPointLightAttenuated : SectorPointLight
{ {
Default Default
{ {
+INCOMBAT +DYNAMICLIGHT.ATTENUATE
} }
} }
@ -195,7 +195,7 @@ class PointLightFlickerRandomAttenuated :PointLightFlickerRandom
{ {
Default Default
{ {
+INCOMBAT +DYNAMICLIGHT.ATTENUATE
} }
} }

View File

@ -1058,7 +1058,7 @@ class BaseStatusBar native ui
{ {
for(int j = 0; j < 2; j++) for(int j = 0; j < 2; j++)
{ {
if (j ^ !!(parms.flags & DI_DRAWCURSORFIRST)) if (j ^ !!(flags & DI_DRAWCURSORFIRST))
{ {
if (item == CPlayer.mo.InvSel) 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); DrawString(parms.amountfont, FormatNumber(item.Amount, 0, 5), textpos + (boxsize.X * i, 0), flags | DI_TEXT_ALIGN_RIGHT, parms.cr, parms.itemalpha);
} }