mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 14:51:40 +00:00
- separated the software-renderer-specific parts of colormap processing from the common parts.
- moved testcolor and test fades into SWRenderer files. These CCMDs work by hacking the default colormap and were never implemented for hardware rendering because they require many checks throughout the code.
This commit is contained in:
parent
cd015f9340
commit
921bc763fb
27 changed files with 695 additions and 572 deletions
|
@ -806,6 +806,7 @@ file( GLOB HEADER_FILES
|
||||||
|
|
||||||
set ( SWRENDER_SOURCES
|
set ( SWRENDER_SOURCES
|
||||||
swrenderer/r_swcanvas.cpp
|
swrenderer/r_swcanvas.cpp
|
||||||
|
swrenderer/r_swcolormaps.cpp
|
||||||
swrenderer/r_swrenderer.cpp
|
swrenderer/r_swrenderer.cpp
|
||||||
swrenderer/r_memory.cpp
|
swrenderer/r_memory.cpp
|
||||||
swrenderer/r_renderthread.cpp
|
swrenderer/r_renderthread.cpp
|
||||||
|
|
|
@ -1390,10 +1390,6 @@ void G_InitLevelLocals ()
|
||||||
level_info_t *info;
|
level_info_t *info;
|
||||||
|
|
||||||
BaseBlendA = 0.0f; // Remove underwater blend effect, if any
|
BaseBlendA = 0.0f; // Remove underwater blend effect, if any
|
||||||
NormalLight.Maps = realcolormaps.Maps;
|
|
||||||
|
|
||||||
// [BB] Instead of just setting the color, we also have to reset Desaturate and build the lights.
|
|
||||||
NormalLight.ChangeColor (PalEntry (255, 255, 255), 0);
|
|
||||||
|
|
||||||
level.gravity = sv_gravity * 35/TICRATE;
|
level.gravity = sv_gravity * 35/TICRATE;
|
||||||
level.aircontrol = sv_aircontrol;
|
level.aircontrol = sv_aircontrol;
|
||||||
|
@ -1415,18 +1411,10 @@ void G_InitLevelLocals ()
|
||||||
level.FromSnapshot = false;
|
level.FromSnapshot = false;
|
||||||
if (level.fadeto == 0)
|
if (level.fadeto == 0)
|
||||||
{
|
{
|
||||||
R_SetDefaultColormap (info->FadeTable);
|
|
||||||
if (strnicmp (info->FadeTable, "COLORMAP", 8) != 0)
|
if (strnicmp (info->FadeTable, "COLORMAP", 8) != 0)
|
||||||
{
|
{
|
||||||
level.fadeto = 0xff939393; //[SP] Hexen True-color compatibility, just use gray.
|
|
||||||
level.flags |= LEVEL_HASFADETABLE;
|
level.flags |= LEVEL_HASFADETABLE;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NormalLight.ChangeFade (level.fadeto);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
level.airsupply = info->airsupply*TICRATE;
|
level.airsupply = info->airsupply*TICRATE;
|
||||||
level.outsidefog = info->outsidefog;
|
level.outsidefog = info->outsidefog;
|
||||||
|
@ -1475,8 +1463,6 @@ void G_InitLevelLocals ()
|
||||||
compatflags.Callback();
|
compatflags.Callback();
|
||||||
compatflags2.Callback();
|
compatflags2.Callback();
|
||||||
|
|
||||||
NormalLight.ChangeFade (level.fadeto);
|
|
||||||
|
|
||||||
level.DefaultEnvironment = info->DefaultEnvironment;
|
level.DefaultEnvironment = info->DefaultEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -591,14 +591,6 @@ void GLSceneDrawer::DrawBlend(sector_t * viewsector)
|
||||||
if (blendv.a == 0)
|
if (blendv.a == 0)
|
||||||
{
|
{
|
||||||
blendv = R_BlendForColormap(blendv);
|
blendv = R_BlendForColormap(blendv);
|
||||||
if (blendv.a == 255)
|
|
||||||
{
|
|
||||||
// The calculated average is too dark so brighten it according to the palettes's overall brightness
|
|
||||||
int maxcol = MAX<int>(MAX<int>(GLRenderer->framebuffer->palette_brightness, blendv.r), MAX<int>(blendv.g, blendv.b));
|
|
||||||
blendv.r = blendv.r * 255 / maxcol;
|
|
||||||
blendv.g = blendv.g * 255 / maxcol;
|
|
||||||
blendv.b = blendv.b * 255 / maxcol;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blendv.a == 255)
|
if (blendv.a == 255)
|
||||||
|
@ -983,7 +975,6 @@ void GLSceneDrawer::WriteSavePic (player_t *player, FileWriter *file, int width,
|
||||||
|
|
||||||
struct FGLInterface : public FRenderer
|
struct FGLInterface : public FRenderer
|
||||||
{
|
{
|
||||||
bool UsesColormap() const override;
|
|
||||||
void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override;
|
void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override;
|
||||||
void RenderView(player_t *player) override;
|
void RenderView(player_t *player) override;
|
||||||
void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override;
|
void WriteSavePic (player_t *player, FileWriter *file, int width, int height) override;
|
||||||
|
@ -999,18 +990,6 @@ struct FGLInterface : public FRenderer
|
||||||
void Init() override;
|
void Init() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// The GL renderer has no use for colormaps so let's
|
|
||||||
// not create them and save us some time.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
bool FGLInterface::UsesColormap() const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// DFrameBuffer :: Precache
|
// DFrameBuffer :: Precache
|
||||||
|
|
|
@ -308,19 +308,6 @@ bool OpenGLFrameBuffer::SetContrast(float contrast)
|
||||||
|
|
||||||
void OpenGLFrameBuffer::UpdatePalette()
|
void OpenGLFrameBuffer::UpdatePalette()
|
||||||
{
|
{
|
||||||
int rr=0,gg=0,bb=0;
|
|
||||||
for(int x=0;x<256;x++)
|
|
||||||
{
|
|
||||||
rr+=GPalette.BaseColors[x].r;
|
|
||||||
gg+=GPalette.BaseColors[x].g;
|
|
||||||
bb+=GPalette.BaseColors[x].b;
|
|
||||||
}
|
|
||||||
rr>>=8;
|
|
||||||
gg>>=8;
|
|
||||||
bb>>=8;
|
|
||||||
|
|
||||||
palette_brightness = (rr*77 + gg*143 + bb*35)/255;
|
|
||||||
|
|
||||||
if (GLRenderer)
|
if (GLRenderer)
|
||||||
GLRenderer->ClearTonemapPalette();
|
GLRenderer->ClearTonemapPalette();
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,6 @@ public:
|
||||||
|
|
||||||
void SetVSync(bool vsync);
|
void SetVSync(bool vsync);
|
||||||
|
|
||||||
int palette_brightness; // brightness of the active palette - this is used for screen blends
|
|
||||||
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
bool HWGammaActive = false; // Are we using hardware or software gamma?
|
||||||
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
std::shared_ptr<FGLDebug> mDebug; // Debug API
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -385,7 +385,6 @@ static bool P_LoadBloodMap (uint8_t *data, size_t len, FMapThing **mapthings, in
|
||||||
|
|
||||||
static void LoadSectors (sectortype *bsec, int count)
|
static void LoadSectors (sectortype *bsec, int count)
|
||||||
{
|
{
|
||||||
FDynamicColormap *map = GetSpecialLights (PalEntry (255,255,255), level.fadeto, 0);
|
|
||||||
sector_t *sec;
|
sector_t *sec;
|
||||||
char tnam[9];
|
char tnam[9];
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "r_data/r_translate.h"
|
#include "r_data/r_translate.h"
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "r_data/colormaps.h"
|
#include "r_data/colormaps.h"
|
||||||
|
#include "swrenderer/r_swcolormaps.h"
|
||||||
#include "poly_draw_args.h"
|
#include "poly_draw_args.h"
|
||||||
#include "swrenderer/viewport/r_viewport.h"
|
#include "swrenderer/viewport/r_viewport.h"
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "swrenderer/scene/r_light.h"
|
#include "swrenderer/scene/r_light.h"
|
||||||
#include "swrenderer/drawers/r_draw_rgba.h"
|
#include "swrenderer/drawers/r_draw_rgba.h"
|
||||||
#include "swrenderer/viewport/r_viewport.h"
|
#include "swrenderer/viewport/r_viewport.h"
|
||||||
|
#include "swrenderer/r_swcolormaps.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, r_shadercolormaps)
|
EXTERN_CVAR(Bool, r_shadercolormaps)
|
||||||
EXTERN_CVAR(Int, screenblocks)
|
EXTERN_CVAR(Int, screenblocks)
|
||||||
|
@ -122,6 +123,11 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
|
||||||
P_FindParticleSubsectors();
|
P_FindParticleSubsectors();
|
||||||
PO_LinkToSubsectors();
|
PO_LinkToSubsectors();
|
||||||
R_SetupFrame(Thread.Viewport->viewpoint, Thread.Viewport->viewwindow, actor);
|
R_SetupFrame(Thread.Viewport->viewpoint, Thread.Viewport->viewwindow, actor);
|
||||||
|
|
||||||
|
if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps;
|
||||||
|
else NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS * 256 * R_OldBlend;
|
||||||
|
|
||||||
|
|
||||||
swrenderer::CameraLight::Instance()->SetCamera(Thread.Viewport.get(), actor);
|
swrenderer::CameraLight::Instance()->SetCamera(Thread.Viewport.get(), actor);
|
||||||
Thread.Viewport->SetupFreelook();
|
Thread.Viewport->SetupFreelook();
|
||||||
|
|
||||||
|
|
|
@ -308,7 +308,7 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, floa
|
||||||
|
|
||||||
if (visstyle.Invert)
|
if (visstyle.Invert)
|
||||||
{
|
{
|
||||||
BaseColormap = &SpecialColormaps[INVERSECOLORMAP];
|
BaseColormap = &SpecialSWColormaps[INVERSECOLORMAP];
|
||||||
ColormapNum = 0;
|
ColormapNum = 0;
|
||||||
if (BaseColormap->Maps < mybasecolormap->Maps || BaseColormap->Maps >= mybasecolormap->Maps + NUMCOLORMAPS * 256)
|
if (BaseColormap->Maps < mybasecolormap->Maps || BaseColormap->Maps >= mybasecolormap->Maps + NUMCOLORMAPS * 256)
|
||||||
{
|
{
|
||||||
|
@ -319,8 +319,8 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, floa
|
||||||
|
|
||||||
// If we're drawing with a special colormap, but shaders for them are disabled, do
|
// If we're drawing with a special colormap, but shaders for them are disabled, do
|
||||||
// not accelerate.
|
// not accelerate.
|
||||||
if (!r_shadercolormaps && (BaseColormap >= &SpecialColormaps[0] &&
|
if (!r_shadercolormaps && (BaseColormap >= &SpecialSWColormaps[0] &&
|
||||||
BaseColormap <= &SpecialColormaps.Last()))
|
BaseColormap <= &SpecialSWColormaps.Last()))
|
||||||
{
|
{
|
||||||
noaccel = true;
|
noaccel = true;
|
||||||
}
|
}
|
||||||
|
@ -405,10 +405,10 @@ void PolyScreenSprite::Render()
|
||||||
FColormapStyle colormapstyle;
|
FColormapStyle colormapstyle;
|
||||||
PalEntry overlay = 0;
|
PalEntry overlay = 0;
|
||||||
bool usecolormapstyle = false;
|
bool usecolormapstyle = false;
|
||||||
if (BaseColormap >= &SpecialColormaps[0] &&
|
if (BaseColormap >= &SpecialSWColormaps[0] &&
|
||||||
BaseColormap < &SpecialColormaps[SpecialColormaps.Size()])
|
BaseColormap < &SpecialSWColormaps[SpecialColormaps.Size()])
|
||||||
{
|
{
|
||||||
special = static_cast<FSpecialColormap*>(BaseColormap);
|
special = &SpecialColormaps[BaseColormap - &SpecialSWColormaps[0]];
|
||||||
}
|
}
|
||||||
else if (Colormap->Color == PalEntry(255, 255, 255) &&
|
else if (Colormap->Color == PalEntry(255, 255, 255) &&
|
||||||
Colormap->Desaturate == 0)
|
Colormap->Desaturate == 0)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
** r_data.cpp
|
** colormaps.cpp
|
||||||
|
** common Colormap handling
|
||||||
**
|
**
|
||||||
**---------------------------------------------------------------------------
|
**---------------------------------------------------------------------------
|
||||||
** Copyright 1998-2008 Randy Heit
|
** Copyright 1998-2008 Randy Heit
|
||||||
|
@ -54,27 +55,7 @@
|
||||||
#include "r_utility.h"
|
#include "r_utility.h"
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
|
|
||||||
static bool R_CheckForFixedLights(const uint8_t *colormaps);
|
|
||||||
|
|
||||||
|
|
||||||
FDynamicColormap NormalLight;
|
|
||||||
FDynamicColormap FullNormalLight; //[SP] Emulate GZDoom brightness
|
|
||||||
bool NormalLightHasFixedLights;
|
|
||||||
|
|
||||||
|
|
||||||
struct FakeCmap
|
|
||||||
{
|
|
||||||
char name[8];
|
|
||||||
PalEntry blend;
|
|
||||||
int lump;
|
|
||||||
};
|
|
||||||
|
|
||||||
TArray<FakeCmap> fakecmaps;
|
TArray<FakeCmap> fakecmaps;
|
||||||
FSWColormap realcolormaps;
|
|
||||||
FSWColormap realfbcolormaps; //[SP] For fullbright use
|
|
||||||
size_t numfakecmaps;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TArray<FSpecialColormap> SpecialColormaps;
|
TArray<FSpecialColormap> SpecialColormaps;
|
||||||
uint8_t DesaturateColormap[31][256];
|
uint8_t DesaturateColormap[31][256];
|
||||||
|
@ -176,273 +157,6 @@ int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b
|
||||||
return SpecialColormaps.Size() - 1;
|
return SpecialColormaps.Size() - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// Colored Lighting Stuffs
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
FDynamicColormap *GetSpecialLights (PalEntry color, PalEntry fade, int desaturate)
|
|
||||||
{
|
|
||||||
FDynamicColormap *colormap;
|
|
||||||
|
|
||||||
// If this colormap has already been created, just return it
|
|
||||||
for (colormap = &NormalLight; colormap != NULL; colormap = colormap->Next)
|
|
||||||
{
|
|
||||||
if (color == colormap->Color &&
|
|
||||||
fade == colormap->Fade &&
|
|
||||||
desaturate == colormap->Desaturate)
|
|
||||||
{
|
|
||||||
return colormap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not found. Create it.
|
|
||||||
colormap = new FDynamicColormap;
|
|
||||||
colormap->Next = NormalLight.Next;
|
|
||||||
colormap->Color = color;
|
|
||||||
colormap->Fade = fade;
|
|
||||||
colormap->Desaturate = desaturate;
|
|
||||||
NormalLight.Next = colormap;
|
|
||||||
|
|
||||||
if (Renderer->UsesColormap())
|
|
||||||
{
|
|
||||||
colormap->Maps = new uint8_t[NUMCOLORMAPS*256];
|
|
||||||
colormap->BuildLights ();
|
|
||||||
}
|
|
||||||
else colormap->Maps = NULL;
|
|
||||||
return colormap;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// Free all lights created with GetSpecialLights
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
static void FreeSpecialLights()
|
|
||||||
{
|
|
||||||
FDynamicColormap *colormap, *next;
|
|
||||||
|
|
||||||
for (colormap = NormalLight.Next; colormap != NULL; colormap = next)
|
|
||||||
{
|
|
||||||
next = colormap->Next;
|
|
||||||
delete[] colormap->Maps;
|
|
||||||
delete colormap;
|
|
||||||
}
|
|
||||||
NormalLight.Next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// Builds NUMCOLORMAPS colormaps lit with the specified color
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FDynamicColormap::BuildLights ()
|
|
||||||
{
|
|
||||||
int l, c;
|
|
||||||
int lr, lg, lb, ld, ild;
|
|
||||||
PalEntry colors[256], basecolors[256];
|
|
||||||
uint8_t *shade;
|
|
||||||
|
|
||||||
if (Maps == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Scale light to the range 0-256, so we can avoid
|
|
||||||
// dividing by 255 in the bottom loop.
|
|
||||||
lr = Color.r*256/255;
|
|
||||||
lg = Color.g*256/255;
|
|
||||||
lb = Color.b*256/255;
|
|
||||||
ld = Desaturate*256/255;
|
|
||||||
if (ld < 0) // No negative desaturations, please.
|
|
||||||
{
|
|
||||||
ld = -ld;
|
|
||||||
}
|
|
||||||
ild = 256-ld;
|
|
||||||
|
|
||||||
if (ld == 0)
|
|
||||||
{
|
|
||||||
memcpy (basecolors, GPalette.BaseColors, sizeof(basecolors));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Desaturate the palette before lighting it.
|
|
||||||
for (c = 0; c < 256; c++)
|
|
||||||
{
|
|
||||||
int r = GPalette.BaseColors[c].r;
|
|
||||||
int g = GPalette.BaseColors[c].g;
|
|
||||||
int b = GPalette.BaseColors[c].b;
|
|
||||||
int intensity = ((r * 77 + g * 143 + b * 37) >> 8) * ld;
|
|
||||||
basecolors[c].r = (r*ild + intensity) >> 8;
|
|
||||||
basecolors[c].g = (g*ild + intensity) >> 8;
|
|
||||||
basecolors[c].b = (b*ild + intensity) >> 8;
|
|
||||||
basecolors[c].a = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// build normal (but colored) light mappings
|
|
||||||
for (l = 0; l < NUMCOLORMAPS; l++)
|
|
||||||
{
|
|
||||||
DoBlending (basecolors, colors, 256,
|
|
||||||
Fade.r, Fade.g, Fade.b, l * (256 / NUMCOLORMAPS));
|
|
||||||
|
|
||||||
shade = Maps + 256*l;
|
|
||||||
if ((uint32_t)Color == MAKERGB(255,255,255))
|
|
||||||
{ // White light, so we can just pick the colors directly
|
|
||||||
for (c = 0; c < 256; c++)
|
|
||||||
{
|
|
||||||
*shade++ = ColorMatcher.Pick (colors[c].r, colors[c].g, colors[c].b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // Colored light, so do the (slightly) slower thing
|
|
||||||
for (c = 0; c < 256; c++)
|
|
||||||
{
|
|
||||||
*shade++ = ColorMatcher.Pick (
|
|
||||||
(colors[c].r*lr)>>8,
|
|
||||||
(colors[c].g*lg)>>8,
|
|
||||||
(colors[c].b*lb)>>8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FDynamicColormap::ChangeColor (PalEntry lightcolor, int desaturate)
|
|
||||||
{
|
|
||||||
if (lightcolor != Color || desaturate != Desaturate)
|
|
||||||
{
|
|
||||||
Color = lightcolor;
|
|
||||||
// [BB] desaturate must be in [0,255]
|
|
||||||
Desaturate = clamp(desaturate, 0, 255);
|
|
||||||
if (Maps) BuildLights ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FDynamicColormap::ChangeFade (PalEntry fadecolor)
|
|
||||||
{
|
|
||||||
if (fadecolor != Fade)
|
|
||||||
{
|
|
||||||
Fade = fadecolor;
|
|
||||||
if (Maps) BuildLights ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FDynamicColormap::ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor)
|
|
||||||
{
|
|
||||||
if (lightcolor != Color || fadecolor != Fade)
|
|
||||||
{
|
|
||||||
Color = lightcolor;
|
|
||||||
Fade = fadecolor;
|
|
||||||
if (Maps) BuildLights ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void FDynamicColormap::RebuildAllLights()
|
|
||||||
{
|
|
||||||
if (Renderer->UsesColormap())
|
|
||||||
{
|
|
||||||
FDynamicColormap *cm;
|
|
||||||
|
|
||||||
for (cm = &NormalLight; cm != NULL; cm = cm->Next)
|
|
||||||
{
|
|
||||||
if (cm->Maps == NULL)
|
|
||||||
{
|
|
||||||
cm->Maps = new uint8_t[NUMCOLORMAPS*256];
|
|
||||||
cm->BuildLights ();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_SetDefaultColormap
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
void R_SetDefaultColormap (const char *name)
|
|
||||||
{
|
|
||||||
if (strnicmp (fakecmaps[0].name, name, 8) != 0)
|
|
||||||
{
|
|
||||||
int lump, i, j;
|
|
||||||
uint8_t map[256];
|
|
||||||
uint8_t unremap[256];
|
|
||||||
uint8_t remap[256];
|
|
||||||
|
|
||||||
lump = Wads.CheckNumForFullName (name, true, ns_colormaps);
|
|
||||||
if (lump == -1)
|
|
||||||
lump = Wads.CheckNumForName (name, ns_global);
|
|
||||||
|
|
||||||
// [RH] If using BUILD's palette, generate the colormap
|
|
||||||
if (lump == -1 || Wads.CheckNumForFullName("palette.dat") >= 0 || Wads.CheckNumForFullName("blood.pal") >= 0)
|
|
||||||
{
|
|
||||||
Printf ("Make colormap\n");
|
|
||||||
FDynamicColormap foo;
|
|
||||||
|
|
||||||
foo.Color = 0xFFFFFF;
|
|
||||||
foo.Fade = 0;
|
|
||||||
foo.Maps = realcolormaps.Maps;
|
|
||||||
foo.Desaturate = 0;
|
|
||||||
foo.Next = NULL;
|
|
||||||
foo.BuildLights ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FWadLump lumpr = Wads.OpenLumpNum (lump);
|
|
||||||
|
|
||||||
// [RH] The colormap may not have been designed for the specific
|
|
||||||
// palette we are using, so remap it to match the current palette.
|
|
||||||
memcpy (remap, GPalette.Remap, 256);
|
|
||||||
memset (unremap, 0, 256);
|
|
||||||
for (i = 0; i < 256; ++i)
|
|
||||||
{
|
|
||||||
unremap[remap[i]] = i;
|
|
||||||
}
|
|
||||||
// Mapping to color 0 is okay, because the colormap won't be used to
|
|
||||||
// produce a masked texture.
|
|
||||||
remap[0] = 0;
|
|
||||||
for (i = 0; i < NUMCOLORMAPS; ++i)
|
|
||||||
{
|
|
||||||
uint8_t *map2 = &realcolormaps.Maps[i*256];
|
|
||||||
lumpr.Read (map, 256);
|
|
||||||
for (j = 0; j < 256; ++j)
|
|
||||||
{
|
|
||||||
map2[j] = remap[map[unremap[j]]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uppercopy (fakecmaps[0].name, name);
|
|
||||||
fakecmaps[0].blend = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// R_DeinitColormaps
|
// R_DeinitColormaps
|
||||||
|
@ -453,13 +167,6 @@ void R_DeinitColormaps ()
|
||||||
{
|
{
|
||||||
SpecialColormaps.Clear();
|
SpecialColormaps.Clear();
|
||||||
fakecmaps.Clear();
|
fakecmaps.Clear();
|
||||||
delete[] realcolormaps.Maps;
|
|
||||||
if (realfbcolormaps.Maps)
|
|
||||||
{
|
|
||||||
delete[] realfbcolormaps.Maps;
|
|
||||||
realfbcolormaps.Maps = nullptr;
|
|
||||||
}
|
|
||||||
FreeSpecialLights();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -501,41 +208,32 @@ void R_InitColormaps ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
realcolormaps.Maps = new uint8_t[256*NUMCOLORMAPS*fakecmaps.Size()];
|
|
||||||
R_SetDefaultColormap ("COLORMAP");
|
|
||||||
|
|
||||||
|
int rr = 0, gg = 0, bb = 0;
|
||||||
|
for(int x=0;x<256;x++)
|
||||||
|
{
|
||||||
|
rr += GPalette.BaseColors[x].r;
|
||||||
|
gg += GPalette.BaseColors[x].g;
|
||||||
|
bb += GPalette.BaseColors[x].b;
|
||||||
|
}
|
||||||
|
rr >>= 8;
|
||||||
|
gg >>= 8;
|
||||||
|
bb >>= 8;
|
||||||
|
|
||||||
|
int palette_brightness = (rr*77 + gg*143 + bb*35) / 255;
|
||||||
|
|
||||||
|
// To calculate the blend it will just average the colors of the first map
|
||||||
if (fakecmaps.Size() > 1)
|
if (fakecmaps.Size() > 1)
|
||||||
{
|
{
|
||||||
uint8_t unremap[256], remap[256], mapin[256];
|
uint8_t map[256];
|
||||||
int i;
|
|
||||||
unsigned j;
|
|
||||||
|
|
||||||
memcpy (remap, GPalette.Remap, 256);
|
for (unsigned j = 1; j < fakecmaps.Size(); j++)
|
||||||
memset (unremap, 0, 256);
|
|
||||||
for (i = 0; i < 256; ++i)
|
|
||||||
{
|
{
|
||||||
unremap[remap[i]] = i;
|
if (Wads.LumpLength (fakecmaps[j].lump) >= 256)
|
||||||
}
|
|
||||||
remap[0] = 0;
|
|
||||||
for (j = 1; j < fakecmaps.Size(); j++)
|
|
||||||
{
|
|
||||||
if (Wads.LumpLength (fakecmaps[j].lump) >= (NUMCOLORMAPS+1)*256)
|
|
||||||
{
|
{
|
||||||
int k, r, g, b;
|
int k, r, g, b;
|
||||||
FWadLump lump = Wads.OpenLumpNum (fakecmaps[j].lump);
|
FWadLump lump = Wads.OpenLumpNum (fakecmaps[j].lump);
|
||||||
uint8_t *const map = realcolormaps.Maps + NUMCOLORMAPS*256*j;
|
lump.Read(map, 256);
|
||||||
|
|
||||||
for (k = 0; k < NUMCOLORMAPS; ++k)
|
|
||||||
{
|
|
||||||
uint8_t *map2 = &map[k*256];
|
|
||||||
lump.Read (mapin, 256);
|
|
||||||
map2[0] = 0;
|
|
||||||
for (r = 1; r < 256; ++r)
|
|
||||||
{
|
|
||||||
map2[r] = remap[mapin[unremap[r]]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r = g = b = 0;
|
r = g = b = 0;
|
||||||
|
|
||||||
for (k = 0; k < 256; k++)
|
for (k = 0; k < 256; k++)
|
||||||
|
@ -544,27 +242,17 @@ void R_InitColormaps ()
|
||||||
g += GPalette.BaseColors[map[k]].g;
|
g += GPalette.BaseColors[map[k]].g;
|
||||||
b += GPalette.BaseColors[map[k]].b;
|
b += GPalette.BaseColors[map[k]].b;
|
||||||
}
|
}
|
||||||
fakecmaps[j].blend = PalEntry (255, r/256, g/256, b/256);
|
r /= 256;
|
||||||
|
g /= 256;
|
||||||
|
b /= 256;
|
||||||
|
// The calculated average is too dark so brighten it according to the palettes's overall brightness
|
||||||
|
int maxcol = MAX<int>(MAX<int>(palette_brightness, r), MAX<int>(g, b));
|
||||||
|
|
||||||
|
fakecmaps[j].blend = PalEntry (255, r * 255 / maxcol, g * 255 / maxcol, b * 255 / maxcol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// [SP] Create a copy of the colormap
|
|
||||||
if (!realfbcolormaps.Maps)
|
|
||||||
{
|
|
||||||
realfbcolormaps.Maps = new uint8_t[256*NUMCOLORMAPS*fakecmaps.Size()];
|
|
||||||
memcpy(realfbcolormaps.Maps, realcolormaps.Maps, 256*NUMCOLORMAPS*fakecmaps.Size());
|
|
||||||
}
|
|
||||||
|
|
||||||
NormalLight.Color = PalEntry (255, 255, 255);
|
|
||||||
NormalLight.Fade = 0;
|
|
||||||
NormalLight.Maps = realcolormaps.Maps;
|
|
||||||
FullNormalLight.Color = PalEntry (255, 255, 255);
|
|
||||||
FullNormalLight.Fade = 0;
|
|
||||||
FullNormalLight.Maps = realfbcolormaps.Maps;
|
|
||||||
NormalLightHasFixedLights = R_CheckForFixedLights(realcolormaps.Maps);
|
|
||||||
numfakecmaps = fakecmaps.Size();
|
|
||||||
|
|
||||||
// build default special maps (e.g. invulnerability)
|
// build default special maps (e.g. invulnerability)
|
||||||
|
|
||||||
for (unsigned i = 0; i < countof(SpecialColormapParms); ++i)
|
for (unsigned i = 0; i < countof(SpecialColormapParms); ++i)
|
||||||
|
@ -591,54 +279,6 @@ void R_InitColormaps ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// R_CheckForFixedLights
|
|
||||||
//
|
|
||||||
// Returns true if there are any entries in the colormaps that are the
|
|
||||||
// same for every colormap and not the fade color.
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
static bool R_CheckForFixedLights(const uint8_t *colormaps)
|
|
||||||
{
|
|
||||||
const uint8_t *lastcolormap = colormaps + (NUMCOLORMAPS - 1) * 256;
|
|
||||||
uint8_t freq[256];
|
|
||||||
int i, j;
|
|
||||||
|
|
||||||
// Count the frequencies of different colors in the final colormap.
|
|
||||||
// If they occur more than X amount of times, we ignore them as a
|
|
||||||
// potential fixed light.
|
|
||||||
|
|
||||||
memset(freq, 0, sizeof(freq));
|
|
||||||
for (i = 0; i < 256; ++i)
|
|
||||||
{
|
|
||||||
freq[lastcolormap[i]]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now check the colormaps for fixed lights that are uncommon in the
|
|
||||||
// final coloramp.
|
|
||||||
for (i = 255; i >= 0; --i)
|
|
||||||
{
|
|
||||||
uint8_t color = lastcolormap[i];
|
|
||||||
if (freq[color] > 10) // arbitrary number to decide "common" colors
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// It's rare in the final colormap. See if it's the same for all colormaps.
|
|
||||||
for (j = 0; j < NUMCOLORMAPS - 1; ++j)
|
|
||||||
{
|
|
||||||
if (colormaps[j * 256 + i] != color)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (j == NUMCOLORMAPS - 1)
|
|
||||||
{ // It was the same all the way across.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// [RH] Returns an index into realcolormaps. Multiply it by
|
// [RH] Returns an index into realcolormaps. Multiply it by
|
||||||
|
@ -675,4 +315,5 @@ uint32_t R_BlendForColormap (uint32_t map)
|
||||||
{
|
{
|
||||||
return APART(map) ? map :
|
return APART(map) ? map :
|
||||||
map < fakecmaps.Size() ? uint32_t(fakecmaps[map].blend) : 0;
|
map < fakecmaps.Size() ? uint32_t(fakecmaps[map].blend) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
#ifndef __RES_CMAP_H
|
#ifndef __RES_CMAP_H
|
||||||
#define __RES_CMAP_H
|
#define __RES_CMAP_H
|
||||||
|
|
||||||
#include "m_fixed.h"
|
|
||||||
|
|
||||||
struct FSWColormap;
|
|
||||||
struct lightlist_t;
|
struct lightlist_t;
|
||||||
|
|
||||||
void R_InitColormaps ();
|
void R_InitColormaps ();
|
||||||
|
@ -12,8 +9,15 @@ void R_DeinitColormaps ();
|
||||||
uint32_t R_ColormapNumForName(const char *name); // killough 4/4/98
|
uint32_t R_ColormapNumForName(const char *name); // killough 4/4/98
|
||||||
void R_SetDefaultColormap (const char *name); // [RH] change normal fadetable
|
void R_SetDefaultColormap (const char *name); // [RH] change normal fadetable
|
||||||
uint32_t R_BlendForColormap (uint32_t map); // [RH] return calculated blend for a colormap
|
uint32_t R_BlendForColormap (uint32_t map); // [RH] return calculated blend for a colormap
|
||||||
extern FSWColormap realcolormaps; // [RH] make the colormaps externally visible
|
|
||||||
extern size_t numfakecmaps;
|
struct FakeCmap
|
||||||
|
{
|
||||||
|
char name[8];
|
||||||
|
PalEntry blend;
|
||||||
|
int lump;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern TArray<FakeCmap> fakecmaps;
|
||||||
|
|
||||||
// for internal use
|
// for internal use
|
||||||
struct FColormap
|
struct FColormap
|
||||||
|
@ -79,25 +83,6 @@ struct FColormap
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FSWColormap
|
|
||||||
{
|
|
||||||
uint8_t *Maps = nullptr;
|
|
||||||
PalEntry Color = 0xffffffff;
|
|
||||||
PalEntry Fade = 0xff000000;
|
|
||||||
int Desaturate = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FDynamicColormap : FSWColormap
|
|
||||||
{
|
|
||||||
void ChangeFade (PalEntry fadecolor);
|
|
||||||
void ChangeColor (PalEntry lightcolor, int desaturate);
|
|
||||||
void ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor);
|
|
||||||
void ChangeFogDensity(int newdensity);
|
|
||||||
void BuildLights ();
|
|
||||||
static void RebuildAllLights();
|
|
||||||
|
|
||||||
FDynamicColormap *Next;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// For hardware-accelerated weapon sprites in colored sectors
|
// For hardware-accelerated weapon sprites in colored sectors
|
||||||
|
@ -116,13 +101,8 @@ enum
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct FSpecialColormap : FSWColormap
|
struct FSpecialColormap
|
||||||
{
|
{
|
||||||
FSpecialColormap()
|
|
||||||
{
|
|
||||||
Maps = Colormap;
|
|
||||||
}
|
|
||||||
|
|
||||||
float ColorizeStart[3];
|
float ColorizeStart[3];
|
||||||
float ColorizeEnd[3];
|
float ColorizeEnd[3];
|
||||||
uint8_t Colormap[256];
|
uint8_t Colormap[256];
|
||||||
|
@ -145,23 +125,5 @@ int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b
|
||||||
|
|
||||||
|
|
||||||
extern uint8_t DesaturateColormap[31][256];
|
extern uint8_t DesaturateColormap[31][256];
|
||||||
extern FDynamicColormap NormalLight;
|
|
||||||
extern FDynamicColormap FullNormalLight;
|
|
||||||
extern bool NormalLightHasFixedLights;
|
|
||||||
|
|
||||||
FDynamicColormap *GetSpecialLights (PalEntry lightcolor, PalEntry fadecolor, int desaturate);
|
|
||||||
|
|
||||||
__forceinline FDynamicColormap *GetColorTable(const FColormap &cm)
|
|
||||||
{
|
|
||||||
auto p = &NormalLight;
|
|
||||||
if (cm.LightColor == p->Color &&
|
|
||||||
cm.FadeColor == p->Fade &&
|
|
||||||
cm.Desaturation == p->Desaturate)
|
|
||||||
{
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GetSpecialLights(cm.LightColor, cm.FadeColor, cm.Desaturation);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,9 +25,6 @@ struct FRenderer
|
||||||
Renderer = NULL;
|
Renderer = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can be overridden so that the colormaps for sector color/fade won't be built.
|
|
||||||
virtual bool UsesColormap() const = 0;
|
|
||||||
|
|
||||||
// precache one texture
|
// precache one texture
|
||||||
virtual void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) = 0;
|
virtual void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) = 0;
|
||||||
|
|
||||||
|
|
|
@ -871,7 +871,7 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
|
||||||
: s->ceilingplane.PointOnSide(viewpoint.Pos) < 0
|
: s->ceilingplane.PointOnSide(viewpoint.Pos) < 0
|
||||||
? s->topmap
|
? s->topmap
|
||||||
: s->midmap;
|
: s->midmap;
|
||||||
if (APART(newblend) == 0 && newblend >= numfakecmaps)
|
if (APART(newblend) == 0 && newblend >= fakecmaps.Size())
|
||||||
newblend = 0;
|
newblend = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -888,11 +888,9 @@ void R_SetupFrame (FRenderViewpoint &viewpoint, FViewWindow &viewwindow, AActor
|
||||||
BaseBlendG = GPART(newblend);
|
BaseBlendG = GPART(newblend);
|
||||||
BaseBlendB = BPART(newblend);
|
BaseBlendB = BPART(newblend);
|
||||||
BaseBlendA = APART(newblend) / 255.f;
|
BaseBlendA = APART(newblend) / 255.f;
|
||||||
NormalLight.Maps = realcolormaps.Maps;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS*256*newblend;
|
|
||||||
BaseBlendR = BaseBlendG = BaseBlendB = 0;
|
BaseBlendR = BaseBlendG = BaseBlendB = 0;
|
||||||
BaseBlendA = 0.f;
|
BaseBlendA = 0.f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,7 +248,6 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, player_t *&
|
||||||
template<> FSerializer &Serialize(FSerializer &arc, const char *key, line_t *&value, line_t **defval);
|
template<> FSerializer &Serialize(FSerializer &arc, const char *key, line_t *&value, line_t **defval);
|
||||||
template<> FSerializer &Serialize(FSerializer &arc, const char *key, side_t *&value, side_t **defval);
|
template<> FSerializer &Serialize(FSerializer &arc, const char *key, side_t *&value, side_t **defval);
|
||||||
template<> FSerializer &Serialize(FSerializer &arc, const char *key, vertex_t *&value, vertex_t **defval);
|
template<> FSerializer &Serialize(FSerializer &arc, const char *key, vertex_t *&value, vertex_t **defval);
|
||||||
template<> FSerializer &Serialize(FSerializer &arc, const char *key, FDynamicColormap *&cm, FDynamicColormap **def);
|
|
||||||
template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClassActor *&clst, PClassActor **def);
|
template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClassActor *&clst, PClassActor **def);
|
||||||
template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClass *&clst, PClass **def);
|
template<> FSerializer &Serialize(FSerializer &arc, const char *key, PClass *&clst, PClass **def);
|
||||||
template<> FSerializer &Serialize(FSerializer &arc, const char *key, FStrifeDialogueNode *&node, FStrifeDialogueNode **def);
|
template<> FSerializer &Serialize(FSerializer &arc, const char *key, FStrifeDialogueNode *&node, FStrifeDialogueNode **def);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#pragma once
|
||||||
/*
|
/*
|
||||||
** st_start.h
|
** st_start.h
|
||||||
** Interface for the startup screen.
|
** Interface for the startup screen.
|
||||||
|
|
|
@ -691,7 +691,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// correct colors now
|
// correct colors now
|
||||||
FDynamicColormap *basecolormap = GetColorTable(frontsector->Colormap);
|
FDynamicColormap *basecolormap = nullptr;
|
||||||
wallshade = ds->shade;
|
wallshade = ds->shade;
|
||||||
CameraLight *cameraLight = CameraLight::Instance();
|
CameraLight *cameraLight = CameraLight::Instance();
|
||||||
if (cameraLight->FixedLightLevel() < 0)
|
if (cameraLight->FixedLightLevel() < 0)
|
||||||
|
@ -725,6 +725,8 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap);
|
||||||
|
|
||||||
if (rw_pic != DONT_DRAW)
|
if (rw_pic != DONT_DRAW)
|
||||||
{
|
{
|
||||||
RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap);
|
RenderFakeWall(ds, x1, x2, fover ? fover : rover, wallshade, basecolormap);
|
||||||
|
@ -868,7 +870,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// correct colors now
|
// correct colors now
|
||||||
FDynamicColormap *basecolormap = GetColorTable(frontsector->Colormap);
|
FDynamicColormap *basecolormap = nullptr;
|
||||||
wallshade = ds->shade;
|
wallshade = ds->shade;
|
||||||
CameraLight *cameraLight = CameraLight::Instance();
|
CameraLight *cameraLight = CameraLight::Instance();
|
||||||
if (cameraLight->FixedLightLevel() < 0)
|
if (cameraLight->FixedLightLevel() < 0)
|
||||||
|
@ -902,6 +904,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (basecolormap == nullptr) basecolormap = GetColorTable(frontsector->Colormap);
|
||||||
|
|
||||||
if (rw_pic != DONT_DRAW)
|
if (rw_pic != DONT_DRAW)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "r_renderthread.cpp"
|
#include "r_renderthread.cpp"
|
||||||
#include "r_swcanvas.cpp"
|
#include "r_swcanvas.cpp"
|
||||||
#include "r_swrenderer.cpp"
|
#include "r_swrenderer.cpp"
|
||||||
|
#include "r_swcolormaps.cpp"
|
||||||
#include "drawers/r_draw.cpp"
|
#include "drawers/r_draw.cpp"
|
||||||
#include "drawers/r_draw_pal.cpp"
|
#include "drawers/r_draw_pal.cpp"
|
||||||
#include "drawers/r_draw_rgba.cpp"
|
#include "drawers/r_draw_rgba.cpp"
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "v_palette.h"
|
#include "v_palette.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
#include "m_png.h"
|
#include "m_png.h"
|
||||||
|
#include "r_swcolormaps.h"
|
||||||
#include "colormatcher.h"
|
#include "colormatcher.h"
|
||||||
#include "r_swcanvas.h"
|
#include "r_swcanvas.h"
|
||||||
#include "textures/textures.h"
|
#include "textures/textures.h"
|
||||||
|
|
544
src/swrenderer/r_swcolormaps.cpp
Normal file
544
src/swrenderer/r_swcolormaps.cpp
Normal file
|
@ -0,0 +1,544 @@
|
||||||
|
/*
|
||||||
|
** r_swcolormaps.cpp
|
||||||
|
** Colormap handling for the software renderer
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
** Copyright 1998-2008 Randy Heit
|
||||||
|
** All rights reserved.
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
#include "i_system.h"
|
||||||
|
#include "w_wad.h"
|
||||||
|
#include "doomdef.h"
|
||||||
|
#include "r_sky.h"
|
||||||
|
#include "c_dispatch.h"
|
||||||
|
#include "sc_man.h"
|
||||||
|
#include "v_text.h"
|
||||||
|
#include "st_start.h"
|
||||||
|
#include "doomstat.h"
|
||||||
|
#include "v_palette.h"
|
||||||
|
#include "colormatcher.h"
|
||||||
|
#include "r_data/colormaps.h"
|
||||||
|
#include "r_swcolormaps.h"
|
||||||
|
#include "v_video.h"
|
||||||
|
#include "templates.h"
|
||||||
|
#include "r_utility.h"
|
||||||
|
#include "r_renderer.h"
|
||||||
|
|
||||||
|
FDynamicColormap NormalLight;
|
||||||
|
FDynamicColormap FullNormalLight; //[SP] Emulate GZDoom brightness
|
||||||
|
bool NormalLightHasFixedLights;
|
||||||
|
|
||||||
|
FSWColormap realcolormaps;
|
||||||
|
FSWColormap realfbcolormaps; //[SP] For fullbright use
|
||||||
|
TArray<FSWColormap> SpecialSWColormaps;
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Colored Lighting Stuffs
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
FDynamicColormap *GetSpecialLights (PalEntry color, PalEntry fade, int desaturate)
|
||||||
|
{
|
||||||
|
FDynamicColormap *colormap;
|
||||||
|
|
||||||
|
// If this colormap has already been created, just return it
|
||||||
|
for (colormap = &NormalLight; colormap != NULL; colormap = colormap->Next)
|
||||||
|
{
|
||||||
|
if (color == colormap->Color &&
|
||||||
|
fade == colormap->Fade &&
|
||||||
|
desaturate == colormap->Desaturate)
|
||||||
|
{
|
||||||
|
return colormap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found. Create it.
|
||||||
|
colormap = new FDynamicColormap;
|
||||||
|
colormap->Next = NormalLight.Next;
|
||||||
|
colormap->Color = color;
|
||||||
|
colormap->Fade = fade;
|
||||||
|
colormap->Desaturate = desaturate;
|
||||||
|
NormalLight.Next = colormap;
|
||||||
|
|
||||||
|
colormap->Maps = new uint8_t[NUMCOLORMAPS*256];
|
||||||
|
colormap->BuildLights ();
|
||||||
|
return colormap;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Free all lights created with GetSpecialLights
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void FreeSpecialLights()
|
||||||
|
{
|
||||||
|
FDynamicColormap *colormap, *next;
|
||||||
|
|
||||||
|
for (colormap = NormalLight.Next; colormap != NULL; colormap = next)
|
||||||
|
{
|
||||||
|
next = colormap->Next;
|
||||||
|
delete[] colormap->Maps;
|
||||||
|
delete colormap;
|
||||||
|
}
|
||||||
|
NormalLight.Next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Builds NUMCOLORMAPS colormaps lit with the specified color
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FDynamicColormap::BuildLights ()
|
||||||
|
{
|
||||||
|
int l, c;
|
||||||
|
int lr, lg, lb, ld, ild;
|
||||||
|
PalEntry colors[256], basecolors[256];
|
||||||
|
uint8_t *shade;
|
||||||
|
|
||||||
|
if (Maps == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Scale light to the range 0-256, so we can avoid
|
||||||
|
// dividing by 255 in the bottom loop.
|
||||||
|
lr = Color.r*256/255;
|
||||||
|
lg = Color.g*256/255;
|
||||||
|
lb = Color.b*256/255;
|
||||||
|
ld = Desaturate*256/255;
|
||||||
|
if (ld < 0) // No negative desaturations, please.
|
||||||
|
{
|
||||||
|
ld = -ld;
|
||||||
|
}
|
||||||
|
ild = 256-ld;
|
||||||
|
|
||||||
|
if (ld == 0)
|
||||||
|
{
|
||||||
|
memcpy (basecolors, GPalette.BaseColors, sizeof(basecolors));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Desaturate the palette before lighting it.
|
||||||
|
for (c = 0; c < 256; c++)
|
||||||
|
{
|
||||||
|
int r = GPalette.BaseColors[c].r;
|
||||||
|
int g = GPalette.BaseColors[c].g;
|
||||||
|
int b = GPalette.BaseColors[c].b;
|
||||||
|
int intensity = ((r * 77 + g * 143 + b * 37) >> 8) * ld;
|
||||||
|
basecolors[c].r = (r*ild + intensity) >> 8;
|
||||||
|
basecolors[c].g = (g*ild + intensity) >> 8;
|
||||||
|
basecolors[c].b = (b*ild + intensity) >> 8;
|
||||||
|
basecolors[c].a = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// build normal (but colored) light mappings
|
||||||
|
for (l = 0; l < NUMCOLORMAPS; l++)
|
||||||
|
{
|
||||||
|
DoBlending (basecolors, colors, 256,
|
||||||
|
Fade.r, Fade.g, Fade.b, l * (256 / NUMCOLORMAPS));
|
||||||
|
|
||||||
|
shade = Maps + 256*l;
|
||||||
|
if ((uint32_t)Color == MAKERGB(255,255,255))
|
||||||
|
{ // White light, so we can just pick the colors directly
|
||||||
|
for (c = 0; c < 256; c++)
|
||||||
|
{
|
||||||
|
*shade++ = ColorMatcher.Pick (colors[c].r, colors[c].g, colors[c].b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // Colored light, so do the (slightly) slower thing
|
||||||
|
for (c = 0; c < 256; c++)
|
||||||
|
{
|
||||||
|
*shade++ = ColorMatcher.Pick (
|
||||||
|
(colors[c].r*lr)>>8,
|
||||||
|
(colors[c].g*lg)>>8,
|
||||||
|
(colors[c].b*lb)>>8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FDynamicColormap::ChangeColor (PalEntry lightcolor, int desaturate)
|
||||||
|
{
|
||||||
|
if (lightcolor != Color || desaturate != Desaturate)
|
||||||
|
{
|
||||||
|
Color = lightcolor;
|
||||||
|
// [BB] desaturate must be in [0,255]
|
||||||
|
Desaturate = clamp(desaturate, 0, 255);
|
||||||
|
if (Maps) BuildLights ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FDynamicColormap::ChangeFade (PalEntry fadecolor)
|
||||||
|
{
|
||||||
|
if (fadecolor != Fade)
|
||||||
|
{
|
||||||
|
Fade = fadecolor;
|
||||||
|
if (Maps) BuildLights ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FDynamicColormap::ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor)
|
||||||
|
{
|
||||||
|
if (lightcolor != Color || fadecolor != Fade)
|
||||||
|
{
|
||||||
|
Color = lightcolor;
|
||||||
|
Fade = fadecolor;
|
||||||
|
if (Maps) BuildLights ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void FDynamicColormap::RebuildAllLights()
|
||||||
|
{
|
||||||
|
FDynamicColormap *cm;
|
||||||
|
|
||||||
|
for (cm = &NormalLight; cm != NULL; cm = cm->Next)
|
||||||
|
{
|
||||||
|
if (cm->Maps == NULL)
|
||||||
|
{
|
||||||
|
cm->Maps = new uint8_t[NUMCOLORMAPS*256];
|
||||||
|
cm->BuildLights ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// R_CheckForFixedLights
|
||||||
|
//
|
||||||
|
// Returns true if there are any entries in the colormaps that are the
|
||||||
|
// same for every colormap and not the fade color.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static bool R_CheckForFixedLights(const uint8_t *colormaps)
|
||||||
|
{
|
||||||
|
const uint8_t *lastcolormap = colormaps + (NUMCOLORMAPS - 1) * 256;
|
||||||
|
uint8_t freq[256];
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
// Count the frequencies of different colors in the final colormap.
|
||||||
|
// If they occur more than X amount of times, we ignore them as a
|
||||||
|
// potential fixed light.
|
||||||
|
|
||||||
|
memset(freq, 0, sizeof(freq));
|
||||||
|
for (i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
freq[lastcolormap[i]]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now check the colormaps for fixed lights that are uncommon in the
|
||||||
|
// final coloramp.
|
||||||
|
for (i = 255; i >= 0; --i)
|
||||||
|
{
|
||||||
|
uint8_t color = lastcolormap[i];
|
||||||
|
if (freq[color] > 10) // arbitrary number to decide "common" colors
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// It's rare in the final colormap. See if it's the same for all colormaps.
|
||||||
|
for (j = 0; j < NUMCOLORMAPS - 1; ++j)
|
||||||
|
{
|
||||||
|
if (colormaps[j * 256 + i] != color)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j == NUMCOLORMAPS - 1)
|
||||||
|
{ // It was the same all the way across.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// R_SetDefaultColormap
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void SetDefaultColormap (const char *name)
|
||||||
|
{
|
||||||
|
if (strnicmp (fakecmaps[0].name, name, 8) != 0)
|
||||||
|
{
|
||||||
|
int lump, i, j;
|
||||||
|
uint8_t map[256];
|
||||||
|
uint8_t unremap[256];
|
||||||
|
uint8_t remap[256];
|
||||||
|
|
||||||
|
lump = Wads.CheckNumForFullName (name, true, ns_colormaps);
|
||||||
|
if (lump == -1)
|
||||||
|
lump = Wads.CheckNumForName (name, ns_global);
|
||||||
|
|
||||||
|
// [RH] If using BUILD's palette, generate the colormap
|
||||||
|
if (lump == -1 || Wads.CheckNumForFullName("palette.dat") >= 0 || Wads.CheckNumForFullName("blood.pal") >= 0)
|
||||||
|
{
|
||||||
|
Printf ("Make colormap\n");
|
||||||
|
FDynamicColormap foo;
|
||||||
|
|
||||||
|
foo.Color = 0xFFFFFF;
|
||||||
|
foo.Fade = 0;
|
||||||
|
foo.Maps = realcolormaps.Maps;
|
||||||
|
foo.Desaturate = 0;
|
||||||
|
foo.Next = NULL;
|
||||||
|
foo.BuildLights ();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FWadLump lumpr = Wads.OpenLumpNum (lump);
|
||||||
|
|
||||||
|
// [RH] The colormap may not have been designed for the specific
|
||||||
|
// palette we are using, so remap it to match the current palette.
|
||||||
|
memcpy (remap, GPalette.Remap, 256);
|
||||||
|
memset (unremap, 0, 256);
|
||||||
|
for (i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
unremap[remap[i]] = i;
|
||||||
|
}
|
||||||
|
// Mapping to color 0 is okay, because the colormap won't be used to
|
||||||
|
// produce a masked texture.
|
||||||
|
remap[0] = 0;
|
||||||
|
for (i = 0; i < NUMCOLORMAPS; ++i)
|
||||||
|
{
|
||||||
|
uint8_t *map2 = &realcolormaps.Maps[i*256];
|
||||||
|
lumpr.Read (map, 256);
|
||||||
|
for (j = 0; j < 256; ++j)
|
||||||
|
{
|
||||||
|
map2[j] = remap[map[unremap[j]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// R_InitColormaps
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void InitBoomColormaps ()
|
||||||
|
{
|
||||||
|
// [RH] Try and convert BOOM colormaps into blending values.
|
||||||
|
// This is a really rough hack, but it's better than
|
||||||
|
// not doing anything with them at all (right?)
|
||||||
|
|
||||||
|
uint32_t NumLumps = Wads.GetNumLumps();
|
||||||
|
|
||||||
|
realcolormaps.Maps = new uint8_t[256*NUMCOLORMAPS*fakecmaps.Size()];
|
||||||
|
SetDefaultColormap ("COLORMAP");
|
||||||
|
|
||||||
|
if (fakecmaps.Size() > 1)
|
||||||
|
{
|
||||||
|
uint8_t unremap[256], remap[256], mapin[256];
|
||||||
|
int i;
|
||||||
|
unsigned j;
|
||||||
|
|
||||||
|
memcpy (remap, GPalette.Remap, 256);
|
||||||
|
memset (unremap, 0, 256);
|
||||||
|
for (i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
unremap[remap[i]] = i;
|
||||||
|
}
|
||||||
|
remap[0] = 0;
|
||||||
|
for (j = 1; j < fakecmaps.Size(); j++)
|
||||||
|
{
|
||||||
|
if (Wads.LumpLength (fakecmaps[j].lump) >= (NUMCOLORMAPS+1)*256)
|
||||||
|
{
|
||||||
|
int k, r;
|
||||||
|
FWadLump lump = Wads.OpenLumpNum (fakecmaps[j].lump);
|
||||||
|
uint8_t *const map = realcolormaps.Maps + NUMCOLORMAPS*256*j;
|
||||||
|
|
||||||
|
for (k = 0; k < NUMCOLORMAPS; ++k)
|
||||||
|
{
|
||||||
|
uint8_t *map2 = &map[k*256];
|
||||||
|
lump.Read (mapin, 256);
|
||||||
|
map2[0] = 0;
|
||||||
|
for (r = 1; r < 256; ++r)
|
||||||
|
{
|
||||||
|
map2[r] = remap[mapin[unremap[r]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
static void DeinitSWColorMaps()
|
||||||
|
{
|
||||||
|
FreeSpecialLights();
|
||||||
|
if (realcolormaps.Maps != nullptr)
|
||||||
|
{
|
||||||
|
delete[] realcolormaps.Maps;
|
||||||
|
realcolormaps.Maps = nullptr;
|
||||||
|
}
|
||||||
|
if (realfbcolormaps.Maps)
|
||||||
|
{
|
||||||
|
delete[] realfbcolormaps.Maps;
|
||||||
|
realfbcolormaps.Maps = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
void InitSWColorMaps()
|
||||||
|
{
|
||||||
|
DeinitSWColorMaps();
|
||||||
|
atterm(DeinitSWColorMaps);
|
||||||
|
InitBoomColormaps();
|
||||||
|
NormalLight.Color = PalEntry (255, 255, 255);
|
||||||
|
NormalLight.Fade = 0;
|
||||||
|
NormalLight.Maps = realcolormaps.Maps;
|
||||||
|
NormalLightHasFixedLights = R_CheckForFixedLights(realcolormaps.Maps);
|
||||||
|
|
||||||
|
// [SP] Create a copy of the colormap
|
||||||
|
if (!realfbcolormaps.Maps)
|
||||||
|
{
|
||||||
|
realfbcolormaps.Maps = new uint8_t[256*NUMCOLORMAPS*fakecmaps.Size()];
|
||||||
|
memcpy(realfbcolormaps.Maps, realcolormaps.Maps, 256*NUMCOLORMAPS*fakecmaps.Size());
|
||||||
|
}
|
||||||
|
FullNormalLight.Color = PalEntry(255, 255, 255);
|
||||||
|
FullNormalLight.Fade = 0;
|
||||||
|
FullNormalLight.Maps = realfbcolormaps.Maps;
|
||||||
|
|
||||||
|
SpecialSWColormaps.Resize(SpecialColormaps.Size());
|
||||||
|
for(unsigned i = 0; i < SpecialColormaps.Size(); i++)
|
||||||
|
{
|
||||||
|
SpecialSWColormaps[i].Maps = SpecialColormaps[i].Colormap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
CCMD (testfade)
|
||||||
|
{
|
||||||
|
FString colorstring;
|
||||||
|
uint32_t color;
|
||||||
|
|
||||||
|
if (argv.argc() < 2)
|
||||||
|
{
|
||||||
|
Printf ("testfade <color>\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() )
|
||||||
|
{
|
||||||
|
color = V_GetColorFromString (NULL, colorstring);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = V_GetColorFromString (NULL, argv[1]);
|
||||||
|
}
|
||||||
|
level.fadeto = color;
|
||||||
|
NormalLight.ChangeFade (color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
CCMD (testcolor)
|
||||||
|
{
|
||||||
|
FString colorstring;
|
||||||
|
uint32_t color;
|
||||||
|
int desaturate;
|
||||||
|
|
||||||
|
if (argv.argc() < 2)
|
||||||
|
{
|
||||||
|
Printf ("testcolor <color> [desaturation]\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() )
|
||||||
|
{
|
||||||
|
color = V_GetColorFromString (NULL, colorstring);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
color = V_GetColorFromString (NULL, argv[1]);
|
||||||
|
}
|
||||||
|
if (argv.argc() > 2)
|
||||||
|
{
|
||||||
|
desaturate = atoi (argv[2]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
desaturate = NormalLight.Desaturate;
|
||||||
|
}
|
||||||
|
NormalLight.ChangeColor (color, desaturate);
|
||||||
|
}
|
||||||
|
}
|
60
src/swrenderer/r_swcolormaps.h
Normal file
60
src/swrenderer/r_swcolormaps.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct FSWColormap
|
||||||
|
{
|
||||||
|
uint8_t *Maps = nullptr;
|
||||||
|
PalEntry Color = 0xffffffff;
|
||||||
|
PalEntry Fade = 0xff000000;
|
||||||
|
int Desaturate = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FDynamicColormap : FSWColormap
|
||||||
|
{
|
||||||
|
void ChangeFade (PalEntry fadecolor);
|
||||||
|
void ChangeColor (PalEntry lightcolor, int desaturate);
|
||||||
|
void ChangeColorFade (PalEntry lightcolor, PalEntry fadecolor);
|
||||||
|
void ChangeFogDensity(int newdensity);
|
||||||
|
void BuildLights ();
|
||||||
|
static void RebuildAllLights();
|
||||||
|
|
||||||
|
FDynamicColormap *Next;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern FSWColormap realcolormaps; // [RH] make the colormaps externally visible
|
||||||
|
|
||||||
|
extern FDynamicColormap NormalLight;
|
||||||
|
extern FDynamicColormap FullNormalLight;
|
||||||
|
extern bool NormalLightHasFixedLights;
|
||||||
|
extern TArray<FSWColormap> SpecialSWColormaps;
|
||||||
|
|
||||||
|
void InitSWColorMaps();
|
||||||
|
FDynamicColormap *GetSpecialLights (PalEntry lightcolor, PalEntry fadecolor, int desaturate);
|
||||||
|
void SetDefaultColormap (const char *name);
|
||||||
|
|
||||||
|
|
||||||
|
// Give the compiler a strong hint we want these functions inlined:
|
||||||
|
#ifndef FORCEINLINE
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define FORCEINLINE __forceinline
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define FORCEINLINE __attribute__((always_inline)) inline
|
||||||
|
#else
|
||||||
|
#define FORCEINLINE inline
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// MSVC needs the forceinline here.
|
||||||
|
FORCEINLINE FDynamicColormap *GetColorTable(const FColormap &cm)
|
||||||
|
{
|
||||||
|
auto p = &NormalLight;
|
||||||
|
if (cm.LightColor == p->Color &&
|
||||||
|
cm.FadeColor == p->Fade &&
|
||||||
|
cm.Desaturation == p->Desaturate)
|
||||||
|
{
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetSpecialLights(cm.LightColor, cm.FadeColor, cm.Desaturation);
|
||||||
|
}
|
|
@ -49,6 +49,7 @@
|
||||||
#include "drawers/r_draw_rgba.h"
|
#include "drawers/r_draw_rgba.h"
|
||||||
#include "polyrenderer/poly_renderer.h"
|
#include "polyrenderer/poly_renderer.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
|
#include "g_levellocals.h"
|
||||||
|
|
||||||
void gl_InitData();
|
void gl_InitData();
|
||||||
void gl_PreprocessLevel();
|
void gl_PreprocessLevel();
|
||||||
|
@ -84,11 +85,7 @@ FSoftwareRenderer::~FSoftwareRenderer()
|
||||||
void FSoftwareRenderer::Init()
|
void FSoftwareRenderer::Init()
|
||||||
{
|
{
|
||||||
mScene.Init();
|
mScene.Init();
|
||||||
}
|
InitSWColorMaps();
|
||||||
|
|
||||||
bool FSoftwareRenderer::UsesColormap() const
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache)
|
void FSoftwareRenderer::PrecacheTexture(FTexture *tex, int cache)
|
||||||
|
@ -356,6 +353,19 @@ void FSoftwareRenderer::RenderTextureView (FCanvasTexture *tex, AActor *viewpoin
|
||||||
void FSoftwareRenderer::PreprocessLevel()
|
void FSoftwareRenderer::PreprocessLevel()
|
||||||
{
|
{
|
||||||
gl_PreprocessLevel();
|
gl_PreprocessLevel();
|
||||||
|
// This just sets the default colormap for the spftware renderer.
|
||||||
|
NormalLight.Maps = realcolormaps.Maps;
|
||||||
|
NormalLight.ChangeColor(PalEntry(255, 255, 255), 0);
|
||||||
|
NormalLight.ChangeFade(level.fadeto);
|
||||||
|
|
||||||
|
if (level.fadeto == 0)
|
||||||
|
{
|
||||||
|
SetDefaultColormap(level.info->FadeTable);
|
||||||
|
if (level.flags & LEVEL_HASFADETABLE)
|
||||||
|
{
|
||||||
|
level.fadeto = 0xff939393; //[SP] Hexen True-color compatibility, just use gray.
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FSoftwareRenderer::CleanLevelData()
|
void FSoftwareRenderer::CleanLevelData()
|
||||||
|
@ -372,3 +382,4 @@ void FSoftwareRenderer::SetVisibility(double vis)
|
||||||
{
|
{
|
||||||
mScene.MainThread()->Light->SetVisibility(mScene.MainThread()->Viewport.get(), vis);
|
mScene.MainThread()->Light->SetVisibility(mScene.MainThread()->Viewport.get(), vis);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,6 @@ struct FSoftwareRenderer : public FRenderer
|
||||||
FSoftwareRenderer();
|
FSoftwareRenderer();
|
||||||
~FSoftwareRenderer();
|
~FSoftwareRenderer();
|
||||||
|
|
||||||
// Can be overridden so that the colormaps for sector color/fade won't be built.
|
|
||||||
bool UsesColormap() const override;
|
|
||||||
|
|
||||||
// precache textures
|
// precache textures
|
||||||
void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override;
|
void Precache(uint8_t *texhitlist, TMap<PClassActor*, bool> &actorhitlist) override;
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ namespace swrenderer
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fixedcolormap = &SpecialColormaps[player->fixedcolormap];
|
fixedcolormap = &SpecialSWColormaps[player->fixedcolormap];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (player->fixedlightlevel >= 0 && player->fixedlightlevel < NUMCOLORMAPS)
|
else if (player->fixedlightlevel >= 0 && player->fixedlightlevel < NUMCOLORMAPS)
|
||||||
|
@ -86,7 +86,7 @@ namespace swrenderer
|
||||||
// [RH] Inverse light for shooting the Sigil
|
// [RH] Inverse light for shooting the Sigil
|
||||||
if (fixedcolormap == nullptr && viewport->viewpoint.extralight == INT_MIN)
|
if (fixedcolormap == nullptr && viewport->viewpoint.extralight == INT_MIN)
|
||||||
{
|
{
|
||||||
fixedcolormap = &SpecialColormaps[INVERSECOLORMAP];
|
fixedcolormap = &SpecialSWColormaps[INVERSECOLORMAP];
|
||||||
viewport->viewpoint.extralight = 0;
|
viewport->viewpoint.extralight = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,10 @@ namespace swrenderer
|
||||||
WallScanCycles.Reset();
|
WallScanCycles.Reset();
|
||||||
|
|
||||||
R_SetupFrame(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, actor);
|
R_SetupFrame(MainThread()->Viewport->viewpoint, MainThread()->Viewport->viewwindow, actor);
|
||||||
|
|
||||||
|
if (APART(R_OldBlend)) NormalLight.Maps = realcolormaps.Maps;
|
||||||
|
else NormalLight.Maps = realcolormaps.Maps + NUMCOLORMAPS * 256 * R_OldBlend;
|
||||||
|
|
||||||
CameraLight::Instance()->SetCamera(MainThread()->Viewport.get(), actor);
|
CameraLight::Instance()->SetCamera(MainThread()->Viewport.get(), actor);
|
||||||
MainThread()->Viewport->SetupFreelook();
|
MainThread()->Viewport->SetupFreelook();
|
||||||
|
|
||||||
|
|
|
@ -465,15 +465,15 @@ namespace swrenderer
|
||||||
|
|
||||||
if (visstyle.Invert)
|
if (visstyle.Invert)
|
||||||
{
|
{
|
||||||
vis.Light.BaseColormap = &SpecialColormaps[INVERSECOLORMAP];
|
vis.Light.BaseColormap = &SpecialSWColormaps[INVERSECOLORMAP];
|
||||||
vis.Light.ColormapNum = 0;
|
vis.Light.ColormapNum = 0;
|
||||||
noaccel = true;
|
noaccel = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If we're drawing with a special colormap, but shaders for them are disabled, do
|
// If we're drawing with a special colormap, but shaders for them are disabled, do
|
||||||
// not accelerate.
|
// not accelerate.
|
||||||
if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialColormaps[0] &&
|
if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialSWColormaps[0] &&
|
||||||
vis.Light.BaseColormap <= &SpecialColormaps.Last()))
|
vis.Light.BaseColormap <= &SpecialSWColormaps.Last()))
|
||||||
{
|
{
|
||||||
noaccel = true;
|
noaccel = true;
|
||||||
}
|
}
|
||||||
|
@ -524,10 +524,10 @@ namespace swrenderer
|
||||||
accelSprite.x1 = x1;
|
accelSprite.x1 = x1;
|
||||||
accelSprite.flip = vis.xiscale < 0;
|
accelSprite.flip = vis.xiscale < 0;
|
||||||
|
|
||||||
if (vis.Light.BaseColormap >= &SpecialColormaps[0] &&
|
if (vis.Light.BaseColormap >= &SpecialSWColormaps[0] &&
|
||||||
vis.Light.BaseColormap < &SpecialColormaps[SpecialColormaps.Size()])
|
vis.Light.BaseColormap < &SpecialSWColormaps[SpecialColormaps.Size()])
|
||||||
{
|
{
|
||||||
accelSprite.special = static_cast<FSpecialColormap*>(vis.Light.BaseColormap);
|
accelSprite.special = &SpecialColormaps[vis.Light.BaseColormap - &SpecialSWColormaps[0]];
|
||||||
}
|
}
|
||||||
else if (CameraLight::Instance()->ShaderColormap())
|
else if (CameraLight::Instance()->ShaderColormap())
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace swrenderer
|
||||||
void DrawerArgs::SetLight(FSWColormap *base_colormap, float light, int shade)
|
void DrawerArgs::SetLight(FSWColormap *base_colormap, float light, int shade)
|
||||||
{
|
{
|
||||||
mBaseColormap = base_colormap;
|
mBaseColormap = base_colormap;
|
||||||
|
assert(mBaseColormap->Maps != nullptr);
|
||||||
mLight = light;
|
mLight = light;
|
||||||
mShade = shade;
|
mShade = shade;
|
||||||
}
|
}
|
||||||
|
|
|
@ -538,30 +538,6 @@ CCMD (testblend)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CCMD (testfade)
|
|
||||||
{
|
|
||||||
FString colorstring;
|
|
||||||
uint32_t color;
|
|
||||||
|
|
||||||
if (argv.argc() < 2)
|
|
||||||
{
|
|
||||||
Printf ("testfade <color>\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() )
|
|
||||||
{
|
|
||||||
color = V_GetColorFromString (NULL, colorstring);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
color = V_GetColorFromString (NULL, argv[1]);
|
|
||||||
}
|
|
||||||
level.fadeto = color;
|
|
||||||
NormalLight.ChangeFade (color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****** Colorspace Conversion Functions ******/
|
/****** Colorspace Conversion Functions ******/
|
||||||
|
|
||||||
// Code from http://www.cs.rit.edu/~yxv4997/t_convert.html
|
// Code from http://www.cs.rit.edu/~yxv4997/t_convert.html
|
||||||
|
@ -637,34 +613,3 @@ void HSVtoRGB (float *r, float *g, float *b, float h, float s, float v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CCMD (testcolor)
|
|
||||||
{
|
|
||||||
FString colorstring;
|
|
||||||
uint32_t color;
|
|
||||||
int desaturate;
|
|
||||||
|
|
||||||
if (argv.argc() < 2)
|
|
||||||
{
|
|
||||||
Printf ("testcolor <color> [desaturation]\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( !(colorstring = V_GetColorStringByName (argv[1])).IsEmpty() )
|
|
||||||
{
|
|
||||||
color = V_GetColorFromString (NULL, colorstring);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
color = V_GetColorFromString (NULL, argv[1]);
|
|
||||||
}
|
|
||||||
if (argv.argc() > 2)
|
|
||||||
{
|
|
||||||
desaturate = atoi (argv[2]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
desaturate = NormalLight.Desaturate;
|
|
||||||
}
|
|
||||||
NormalLight.ChangeColor (color, desaturate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue