mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-13 07:57:52 +00:00
This commit is contained in:
commit
d454fafc9e
39 changed files with 464 additions and 396 deletions
|
@ -1,6 +1,5 @@
|
||||||
language: c++
|
language: c++
|
||||||
dist: trusty
|
dist: trusty
|
||||||
sudo: required
|
|
||||||
|
|
||||||
branches:
|
branches:
|
||||||
except:
|
except:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -69,7 +75,7 @@ struct FLightNode
|
||||||
class ADynamicLight : public AActor
|
class ADynamicLight : public AActor
|
||||||
{
|
{
|
||||||
friend class FLightDefaults;
|
friend class FLightDefaults;
|
||||||
DECLARE_CLASS (ADynamicLight, AActor)
|
DECLARE_CLASS(ADynamicLight, AActor)
|
||||||
public:
|
public:
|
||||||
virtual void Tick();
|
virtual void Tick();
|
||||||
void Serialize(FSerializer &arc);
|
void Serialize(FSerializer &arc);
|
||||||
|
@ -80,10 +86,10 @@ public:
|
||||||
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
|
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
|
||||||
void LinkLight();
|
void LinkLight();
|
||||||
void UnlinkLight();
|
void UnlinkLight();
|
||||||
size_t PointerSubstitution (DObject *old, DObject *notOld);
|
size_t PointerSubstitution(DObject *old, DObject *notOld);
|
||||||
|
|
||||||
void BeginPlay();
|
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 PostBeginPlay();
|
||||||
void OnDestroy() override;
|
void OnDestroy() override;
|
||||||
void Activate(AActor *activator);
|
void Activate(AActor *activator);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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,38 +210,39 @@ 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 (tex->bComplex)
|
if (translation <= 0)
|
||||||
{
|
{
|
||||||
FBitmap imgCreate;
|
// Q: Is this special treatment still needed? Needs to be checked.
|
||||||
|
if (tex->bComplex)
|
||||||
// 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))
|
|
||||||
{
|
{
|
||||||
memset(imgCreate.GetPixels(), 0, W * H * 4);
|
FBitmap imgCreate;
|
||||||
int trans = tex->CopyTrueColorPixels(&imgCreate, exx, exx);
|
|
||||||
bmp.CopyPixelDataRGB(0, 0, imgCreate.GetPixels(), W, H, 4, W * 4, 0, CF_BGRA);
|
// 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);
|
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 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
|
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.
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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[] =
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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); }
|
||||||
|
|
|
@ -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";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
if (!(clip3d->fake3D & FAKE3D_CLIPTOP))
|
||||||
|
{
|
||||||
|
clip3d->sclipTop = sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos);
|
||||||
|
}
|
||||||
|
|
||||||
CameraLight *cameraLight = CameraLight::Instance();
|
CameraLight *cameraLight = CameraLight::Instance();
|
||||||
if (cameraLight->FixedLightLevel() < 0)
|
if (cameraLight->FixedLightLevel() < 0)
|
||||||
{
|
{
|
||||||
if (!(clip3d->fake3D & FAKE3D_CLIPTOP))
|
for (int i = frontsector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
|
||||||
{
|
|
||||||
clip3d->sclipTop = sec->ceilingplane.ZatPoint(Thread->Viewport->viewpoint.Pos);
|
|
||||||
}
|
|
||||||
for (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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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,
|
||||||
|
@ -276,18 +277,18 @@ namespace swrenderer
|
||||||
fixed_t cosang, sinang, sprcosang, sprsinang;
|
fixed_t cosang, sinang, sprcosang, sprsinang;
|
||||||
int backx, backy, gxinc, gyinc;
|
int backx, backy, gxinc, gyinc;
|
||||||
int daxscalerecip, dayscalerecip, cnt, gxstart, gystart, dazscale;
|
int daxscalerecip, dayscalerecip, cnt, gxstart, gystart, dazscale;
|
||||||
int lx, rx, nx, ny, x1=0, y1=0, x2=0, y2=0, yinc=0;
|
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 yoff, xs = 0, ys = 0, xe, ye, xi = 0, yi = 0, cbackx, cbacky, dagxinc, dagyinc;
|
||||||
kvxslab_t *voxptr, *voxend;
|
kvxslab_t *voxptr, *voxend;
|
||||||
FVoxelMipLevel *mip;
|
FVoxelMipLevel *mip;
|
||||||
int z1a[64], z2a[64], yplc[64];
|
int z1a[64], z2a[64], yplc[64];
|
||||||
|
|
||||||
auto viewport = thread->Viewport.get();
|
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 int xdimenscale = FLOAT2FIXED(viewport->viewwindow.centerxwide * viewport->YaspectMul / 160);
|
||||||
const double centerxwide_f = viewport->viewwindow.centerxwide;
|
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.
|
// Convert to Build's coordinate system.
|
||||||
fixed_t globalposx = xs_Fix<4>::ToFix(globalpos.X);
|
fixed_t globalposx = xs_Fix<4>::ToFix(globalpos.X);
|
||||||
|
@ -329,14 +330,14 @@ namespace swrenderer
|
||||||
minslabz >>= k;
|
minslabz >>= k;
|
||||||
maxslabz >>= k;
|
maxslabz >>= k;
|
||||||
|
|
||||||
daxscale <<= (k+8); dayscale <<= (k+8);
|
daxscale <<= (k + 8); dayscale <<= (k + 8);
|
||||||
dazscale = FixedDiv(dayscale, FLOAT2FIXED(viewport->BaseYaspectMul));
|
dazscale = FixedDiv(dayscale, FLOAT2FIXED(viewport->BaseYaspectMul));
|
||||||
daxscale = fixed_t(daxscale / viewport->YaspectMul);
|
daxscale = fixed_t(daxscale / viewport->YaspectMul);
|
||||||
daxscale = Scale(daxscale, xdimenscale, viewport->viewwindow.centerxwide << 9);
|
daxscale = Scale(daxscale, xdimenscale, viewport->viewwindow.centerxwide << 9);
|
||||||
dayscale = Scale(dayscale, FixedMul(xdimenscale, viewport->viewingrangerecip), viewport->viewwindow.centerxwide << 9);
|
dayscale = Scale(dayscale, FixedMul(xdimenscale, viewport->viewingrangerecip), viewport->viewwindow.centerxwide << 9);
|
||||||
|
|
||||||
daxscalerecip = (1<<30) / daxscale;
|
daxscalerecip = (1 << 30) / daxscale;
|
||||||
dayscalerecip = (1<<30) / dayscale;
|
dayscalerecip = (1 << 30) / dayscale;
|
||||||
|
|
||||||
fixed_t piv_x = fixed_t(mip->Pivot.X*256.);
|
fixed_t piv_x = fixed_t(mip->Pivot.X*256.);
|
||||||
fixed_t piv_y = fixed_t(mip->Pivot.Y*256.);
|
fixed_t piv_y = fixed_t(mip->Pivot.Y*256.);
|
||||||
|
@ -344,7 +345,7 @@ namespace swrenderer
|
||||||
|
|
||||||
x = FixedMul(globalposx - dasprx, daxscalerecip);
|
x = FixedMul(globalposx - dasprx, daxscalerecip);
|
||||||
y = FixedMul(globalposy - daspry, 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;
|
backy = (DMulScale10(y, sprcosang, x, -sprsinang) + piv_y) >> 8;
|
||||||
cbackx = clamp(backx, 0, mip->SizeX - 1);
|
cbackx = clamp(backx, 0, mip->SizeX - 1);
|
||||||
cbacky = clamp(backy, 0, mip->SizeY - 1);
|
cbacky = clamp(backy, 0, mip->SizeY - 1);
|
||||||
|
@ -353,7 +354,7 @@ namespace swrenderer
|
||||||
sprsinang = MulScale14(daxscale, sprsinang);
|
sprsinang = MulScale14(daxscale, sprsinang);
|
||||||
|
|
||||||
x = (dasprx - globalposx) - DMulScale18(piv_x, sprcosang, piv_y, -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);
|
cosang = FixedMul(cosang, dayscalerecip);
|
||||||
sinang = FixedMul(sinang, dayscalerecip);
|
sinang = FixedMul(sinang, dayscalerecip);
|
||||||
|
@ -361,7 +362,7 @@ namespace swrenderer
|
||||||
gxstart = y*cosang - x*sinang;
|
gxstart = y*cosang - x*sinang;
|
||||||
gystart = x*cosang + y*sinang;
|
gystart = x*cosang + y*sinang;
|
||||||
gxinc = DMulScale10(sprsinang, cosang, sprcosang, -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;
|
if ((abs(globalposz - dasprz) >> 10) >= abs(dazscale)) return;
|
||||||
|
|
||||||
x = 0; y = 0; j = MAX(mip->SizeX, mip->SizeY);
|
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);
|
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)
|
||||||
{
|
{
|
||||||
case 0: xs = 0; ys = 0; xi = 1; 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 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 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 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 4: xs = 0; ys = cbacky; xi = 1; yi = 2; break;
|
||||||
case 5: xs = mip->SizeX-1; 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 6: xs = cbackx; ys = 0; xi = 2; yi = 1; break;
|
||||||
case 7: xs = cbackx; ys = mip->SizeY-1; xi = 2; yi = -1; break;
|
case 7: xs = cbackx; ys = mip->SizeY - 1; xi = 2; yi = -1; break;
|
||||||
}
|
}
|
||||||
xe = cbackx; ye = cbacky;
|
xe = cbackx; ye = cbacky;
|
||||||
if (cnt < 4)
|
if (cnt < 4)
|
||||||
|
@ -407,28 +414,28 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
|
|
||||||
i = sgn(ys - backy) + sgn(xs - backx) * 3 + 4;
|
i = sgn(ys - backy) + sgn(xs - backx) * 3 + 4;
|
||||||
switch(i)
|
switch (i)
|
||||||
{
|
{
|
||||||
case 6: case 7: x1 = 0; y1 = 0; break;
|
case 6: case 7: x1 = 0; y1 = 0; break;
|
||||||
case 8: case 5: x1 = gxinc; y1 = gyinc; break;
|
case 8: case 5: x1 = gxinc; y1 = gyinc; break;
|
||||||
case 0: case 3: x1 = gyinc; y1 = -gxinc; break;
|
case 0: case 3: x1 = gyinc; y1 = -gxinc; break;
|
||||||
case 2: case 1: x1 = gxinc+gyinc; y1 = gyinc-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 2: case 5: x2 = 0; y2 = 0; break;
|
||||||
case 0: case 1: x2 = gxinc; y2 = gyinc; break;
|
case 0: case 1: x2 = gxinc; y2 = gyinc; break;
|
||||||
case 8: case 7: x2 = gyinc; y2 = -gxinc; break;
|
case 8: case 7: x2 = gyinc; y2 = -gxinc; break;
|
||||||
case 6: case 3: x2 = gxinc+gyinc; y2 = gyinc-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 oand16 = oand + 16;
|
||||||
uint8_t oand32 = oand + 32;
|
uint8_t oand32 = oand + 32;
|
||||||
|
|
||||||
if (yi > 0) { 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); }
|
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);
|
nxoff = FixedMul(x2 - x1, viewport->viewingrangerecip);
|
||||||
x1 = FixedMul(x1, viewport->viewingrangerecip);
|
x1 = FixedMul(x1, viewport->viewingrangerecip);
|
||||||
|
|
||||||
|
@ -446,7 +453,7 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
if ((ny <= nytooclose) || (ny >= nytoofar)) continue;
|
if ((ny <= nytooclose) || (ny >= nytoofar)) continue;
|
||||||
voxptr = (kvxslab_t *)(slabxoffs + xyoffs[y]);
|
voxptr = (kvxslab_t *)(slabxoffs + xyoffs[y]);
|
||||||
voxend = (kvxslab_t *)(slabxoffs + xyoffs[y+1]);
|
voxend = (kvxslab_t *)(slabxoffs + xyoffs[y + 1]);
|
||||||
if (voxptr >= voxend) continue;
|
if (voxptr >= voxend) continue;
|
||||||
|
|
||||||
lx = xs_RoundToInt(nx * centerxwide_f / (ny + y1)) + viewport->viewwindow.centerx;
|
lx = xs_RoundToInt(nx * centerxwide_f / (ny + y1)) + viewport->viewwindow.centerx;
|
||||||
|
@ -516,7 +523,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
else
|
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;
|
else yinc = (((1 << 24) - 1) / (z2 - z1)) * zleng >> 8;
|
||||||
}
|
}
|
||||||
// [RH] Clip each column separately, not just by the first one.
|
// [RH] Clip each column separately, not just by the first one.
|
||||||
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -444,10 +444,17 @@ 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)
|
||||||
{
|
{
|
||||||
iCopyColors<cPalEntry, cBGRA, bCopy>((uint8_t*)penew, (const uint8_t*)palette, 256, 4, inf, 0, 0, 0);
|
if (inf->blend)
|
||||||
palette = penew;
|
{
|
||||||
|
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,
|
copypalettedfuncs[inf==NULL? OP_COPY : inf->op](buffer, patch, srcwidth, srcheight, Pitch,
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue