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++
dist: trusty
sudo: required
branches:
except:

View file

@ -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

View file

@ -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;

View file

@ -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<LightFlag> 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;
};

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);
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;

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;
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;

View file

@ -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"

View file

@ -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;

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);

View file

@ -33,6 +33,7 @@
#include "sc_man.h"
#include "colormatcher.h"
#include "textures/warpbuffer.h"
#include "textures/bitmap.h"
//#include "gl/gl_intern.h"
@ -43,7 +44,6 @@
#include "gl/data/gl_data.h"
#include "gl/textures/gl_texture.h"
#include "gl/textures/gl_translate.h"
#include "gl/textures/gl_bitmap.h"
#include "gl/textures/gl_material.h"
#include "gl/textures/gl_samplers.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];
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);
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.
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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[] =

View file

@ -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;

View file

@ -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";
}
}

View file

@ -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<DrawColumnSubClampTranslatedPalCommand>(args); }
void DrawRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnRevSubClampPalCommand>(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 DrawSpanMasked(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanMaskedPalCommand>(args); }
void DrawSpanTranslucent(const SpanDrawerArgs &args) override { Queue->Push<DrawSpanTranslucentPalCommand>(args); }

View file

@ -201,6 +201,11 @@ namespace swrenderer
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)
{
Queue->Push<DrawSpan32Command>(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";
}
}

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
{
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;

View file

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

View file

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

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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());

View file

@ -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<VoxelBlock>(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<backx)) + (1 << (int(ys<backy)+2));
uint8_t oand = (1 << int(xs < backx)) + (1 << (int(ys < backy) + 2));
uint8_t oand16 = oand + 16;
uint8_t oand32 = oand + 32;
if (yi > 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<VoxelBlock>(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)

View file

@ -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)

View file

@ -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;
};
}

View file

@ -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<cPalEntry, cBGRA, bCopy>((uint8_t*)penew, (const uint8_t*)palette, 256, 4, inf, 0, 0, 0);
palette = penew;
if (inf->blend)
{
iCopyColors<cPalEntry, cBGRA, bCopy>((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,

View file

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

View file

@ -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
{

View file

@ -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;
}

View file

@ -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);

View file

@ -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"

View file

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

View file

@ -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);
}