mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 23:32:02 +00:00
Dynamic lights? Did anyone say DYNAMIC LIGHTS?
This commit is contained in:
parent
b3bed807de
commit
8a3db6c003
10 changed files with 133 additions and 9 deletions
|
@ -79,7 +79,6 @@
|
||||||
#include "gl/utility/gl_convert.h"
|
#include "gl/utility/gl_convert.h"
|
||||||
#include "gl/utility/gl_templates.h"
|
#include "gl/utility/gl_templates.h"
|
||||||
|
|
||||||
EXTERN_CVAR(Int, vid_renderer)
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
@ -260,10 +259,6 @@ void ADynamicLight::Deactivate(AActor *activator)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
void ADynamicLight::Tick()
|
void ADynamicLight::Tick()
|
||||||
{
|
{
|
||||||
if (vid_renderer == 0)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (IsOwned())
|
if (IsOwned())
|
||||||
{
|
{
|
||||||
if (!target || !target->state)
|
if (!target || !target->state)
|
||||||
|
|
|
@ -221,6 +221,26 @@ namespace swrenderer
|
||||||
if (args.source2[0] == nullptr)
|
if (args.source2[0] == nullptr)
|
||||||
args.flags |= DrawWallArgs::nearest_filter;
|
args.flags |= DrawWallArgs::nearest_filter;
|
||||||
|
|
||||||
|
args.dynlights = nullptr;
|
||||||
|
args.num_dynlights = 0;
|
||||||
|
/*
|
||||||
|
static TriLight fakelight;
|
||||||
|
static bool first = true;
|
||||||
|
if (first)
|
||||||
|
{
|
||||||
|
fakelight.x = 100.0f;
|
||||||
|
fakelight.y = 0.0f;
|
||||||
|
fakelight.z = 100.0f;
|
||||||
|
fakelight.color = 0xffffff00;
|
||||||
|
fakelight.radius = 256.0f / 1000.0f;
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
args.z = 0.0f;
|
||||||
|
args.step_z = 1.0f;
|
||||||
|
args.dynlights = &fakelight;
|
||||||
|
args.num_dynlights = 1;
|
||||||
|
*/
|
||||||
DetectRangeError(args.dest, args.dest_y, args.count);
|
DetectRangeError(args.dest, args.dest_y, args.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +299,11 @@ namespace swrenderer
|
||||||
if (args.source2[0] == nullptr)
|
if (args.source2[0] == nullptr)
|
||||||
args.flags |= DrawWallArgs::nearest_filter;
|
args.flags |= DrawWallArgs::nearest_filter;
|
||||||
|
|
||||||
|
args.z = 0.0f;
|
||||||
|
args.step_z = 0.0f;
|
||||||
|
args.dynlights = nullptr;
|
||||||
|
args.num_dynlights = 0;
|
||||||
|
|
||||||
DetectRangeError(args.dest, args.dest_y, args.count);
|
DetectRangeError(args.dest, args.dest_y, args.count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,13 @@ struct WorkerThreadData
|
||||||
int32_t StartY;
|
int32_t StartY;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TriLight
|
||||||
|
{
|
||||||
|
uint32_t color;
|
||||||
|
float x, y, z;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
struct DrawWallArgs
|
struct DrawWallArgs
|
||||||
{
|
{
|
||||||
uint32_t *dest;
|
uint32_t *dest;
|
||||||
|
@ -91,6 +98,10 @@ struct DrawWallArgs
|
||||||
nearest_filter = 2
|
nearest_filter = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
float z, step_z;
|
||||||
|
TriLight *dynlights;
|
||||||
|
uint32_t num_dynlights;
|
||||||
|
|
||||||
FString ToString();
|
FString ToString();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -261,6 +261,9 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane
|
||||||
args.SetColormap(Line->frontsector->ColorMap);
|
args.SetColormap(Line->frontsector->ColorMap);
|
||||||
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
|
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
|
||||||
|
|
||||||
|
//if (Side && Side->lighthead)
|
||||||
|
// args.uniforms.light = 255; // Make walls touched by a light fullbright!
|
||||||
|
|
||||||
if (Polyportal)
|
if (Polyportal)
|
||||||
{
|
{
|
||||||
args.stencilwritevalue = Polyportal->StencilValue;
|
args.stencilwritevalue = Polyportal->StencilValue;
|
||||||
|
|
|
@ -47,6 +47,9 @@
|
||||||
#include "r_poly.h"
|
#include "r_poly.h"
|
||||||
#include "p_setup.h"
|
#include "p_setup.h"
|
||||||
|
|
||||||
|
void gl_ParseDefs();
|
||||||
|
void gl_InitData();
|
||||||
|
|
||||||
EXTERN_CVAR(Bool, r_shadercolormaps)
|
EXTERN_CVAR(Bool, r_shadercolormaps)
|
||||||
EXTERN_CVAR(Float, maxviewpitch) // [SP] CVAR from GZDoom
|
EXTERN_CVAR(Float, maxviewpitch) // [SP] CVAR from GZDoom
|
||||||
|
|
||||||
|
@ -92,6 +95,8 @@ FSoftwareRenderer::~FSoftwareRenderer()
|
||||||
|
|
||||||
void FSoftwareRenderer::Init()
|
void FSoftwareRenderer::Init()
|
||||||
{
|
{
|
||||||
|
gl_ParseDefs();
|
||||||
|
|
||||||
r_swtruecolor = screen->IsBgra();
|
r_swtruecolor = screen->IsBgra();
|
||||||
R_InitRenderer();
|
R_InitRenderer();
|
||||||
}
|
}
|
||||||
|
@ -310,7 +315,7 @@ int FSoftwareRenderer::GetMaxViewPitch(bool down)
|
||||||
|
|
||||||
bool FSoftwareRenderer::RequireGLNodes()
|
bool FSoftwareRenderer::RequireGLNodes()
|
||||||
{
|
{
|
||||||
return r_polyrenderer;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
|
|
||||||
#include "r_renderer.h"
|
#include "r_renderer.h"
|
||||||
|
|
||||||
|
void gl_SetActorLights(AActor *);
|
||||||
|
void gl_PreprocessLevel();
|
||||||
|
void gl_CleanLevelData();
|
||||||
|
|
||||||
struct FSoftwareRenderer : public FRenderer
|
struct FSoftwareRenderer : public FRenderer
|
||||||
{
|
{
|
||||||
FSoftwareRenderer();
|
FSoftwareRenderer();
|
||||||
|
@ -40,6 +44,21 @@ struct FSoftwareRenderer : public FRenderer
|
||||||
void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) override;
|
void RenderTextureView (FCanvasTexture *tex, AActor *viewpoint, int fov) override;
|
||||||
sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back) override;
|
sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, bool back) override;
|
||||||
|
|
||||||
|
void StateChanged(AActor *actor) override
|
||||||
|
{
|
||||||
|
gl_SetActorLights(actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreprocessLevel() override
|
||||||
|
{
|
||||||
|
gl_PreprocessLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CleanLevelData() override
|
||||||
|
{
|
||||||
|
gl_CleanLevelData();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,10 @@ void DrawWallCodegen::Generate(DrawWallVariant variant, bool fourColumns, SSAVal
|
||||||
SSAShort fade_blue = args[0][41].load(true);
|
SSAShort fade_blue = args[0][41].load(true);
|
||||||
SSAShort desaturate = args[0][42].load(true);
|
SSAShort desaturate = args[0][42].load(true);
|
||||||
SSAInt flags = args[0][43].load(true);
|
SSAInt flags = args[0][43].load(true);
|
||||||
|
start_z = args[0][44].load(true);
|
||||||
|
step_z = args[0][45].load(true);
|
||||||
|
dynlights = args[0][46].load(true);
|
||||||
|
num_dynlights = args[0][47].load(true);
|
||||||
shade_constants.light = SSAVec4i(light_blue.zext_int(), light_green.zext_int(), light_red.zext_int(), light_alpha.zext_int());
|
shade_constants.light = SSAVec4i(light_blue.zext_int(), light_green.zext_int(), light_red.zext_int(), light_alpha.zext_int());
|
||||||
shade_constants.fade = SSAVec4i(fade_blue.zext_int(), fade_green.zext_int(), fade_red.zext_int(), fade_alpha.zext_int());
|
shade_constants.fade = SSAVec4i(fade_blue.zext_int(), fade_green.zext_int(), fade_red.zext_int(), fade_alpha.zext_int());
|
||||||
shade_constants.desaturate = desaturate.zext_int();
|
shade_constants.desaturate = desaturate.zext_int();
|
||||||
|
@ -129,9 +133,11 @@ void DrawWallCodegen::Loop(DrawWallVariant variant, bool fourColumns, bool isSim
|
||||||
int numColumns = fourColumns ? 4 : 1;
|
int numColumns = fourColumns ? 4 : 1;
|
||||||
|
|
||||||
stack_index.store(SSAInt(0));
|
stack_index.store(SSAInt(0));
|
||||||
|
stack_z.store(start_z);
|
||||||
{
|
{
|
||||||
SSAForBlock loop;
|
SSAForBlock loop;
|
||||||
SSAInt index = stack_index.load();
|
SSAInt index = stack_index.load();
|
||||||
|
z = stack_z.load();
|
||||||
loop.loop_block(index < count);
|
loop.loop_block(index < count);
|
||||||
|
|
||||||
SSAInt frac[4];
|
SSAInt frac[4];
|
||||||
|
@ -167,6 +173,7 @@ void DrawWallCodegen::Loop(DrawWallVariant variant, bool fourColumns, bool isSim
|
||||||
dest[offset].store_vec4ub(color);
|
dest[offset].store_vec4ub(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stack_z.store(z + step_z);
|
||||||
stack_index.store(index.add(SSAInt(1), true, true));
|
stack_index.store(index.add(SSAInt(1), true, true));
|
||||||
for (int i = 0; i < numColumns; i++)
|
for (int i = 0; i < numColumns; i++)
|
||||||
stack_frac[i].store(frac[i] + fracstep[i]);
|
stack_frac[i].store(frac[i] + fracstep[i]);
|
||||||
|
@ -209,10 +216,41 @@ SSAVec4i DrawWallCodegen::SampleLinear(SSAUBytePtr col0, SSAUBytePtr col1, SSAIn
|
||||||
|
|
||||||
SSAVec4i DrawWallCodegen::Shade(SSAVec4i fg, int index, bool isSimpleShade)
|
SSAVec4i DrawWallCodegen::Shade(SSAVec4i fg, int index, bool isSimpleShade)
|
||||||
{
|
{
|
||||||
|
SSAVec4i c;
|
||||||
if (isSimpleShade)
|
if (isSimpleShade)
|
||||||
return shade_bgra_simple(fg, light[index]);
|
c = shade_bgra_simple(fg, light[index]);
|
||||||
else
|
else
|
||||||
return shade_bgra_advanced(fg, light[index], shade_constants);
|
c = shade_bgra_advanced(fg, light[index], shade_constants);
|
||||||
|
|
||||||
|
stack_lit_color.store(c);
|
||||||
|
stack_light_index.store(SSAInt(0));
|
||||||
|
|
||||||
|
SSAForBlock block;
|
||||||
|
SSAInt light_index = stack_light_index.load();
|
||||||
|
SSAVec4i lit_color = stack_lit_color.load();
|
||||||
|
block.loop_block(light_index < num_dynlights);
|
||||||
|
{
|
||||||
|
SSAVec4i light_color = SSAUBytePtr(dynlights[light_index][0].v).load_vec4ub(true);
|
||||||
|
SSAFloat light_x = dynlights[light_index][1].load(true);
|
||||||
|
//SSAFloat light_y = dynlights[light_index][2].load(true);
|
||||||
|
SSAFloat light_z = dynlights[light_index][3].load(true);
|
||||||
|
SSAFloat light_rcp_radius = dynlights[light_index][4].load(true);
|
||||||
|
|
||||||
|
// L = light-pos
|
||||||
|
// dist = sqrt(dot(L, L))
|
||||||
|
// attenuation = 1 - MIN(dist * (1/radius), 1)
|
||||||
|
SSAFloat Lxy2 = light_x; // L.x*L.x + L.y*L.y
|
||||||
|
SSAFloat Lz = light_z - z;
|
||||||
|
SSAFloat dist = SSAFloat::sqrt(Lxy2 + Lz * Lz);
|
||||||
|
SSAInt attenuation = SSAInt(SSAFloat(256.0f) - SSAFloat::MIN(dist * light_rcp_radius, SSAFloat(256.0f)), true);
|
||||||
|
SSAVec4i contribution = (light_color * fg * attenuation) >> 16;
|
||||||
|
|
||||||
|
stack_lit_color.store(lit_color + contribution);
|
||||||
|
stack_light_index.store(light_index + 1);
|
||||||
|
}
|
||||||
|
block.end_block();
|
||||||
|
|
||||||
|
return stack_lit_color.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
SSAVec4i DrawWallCodegen::Blend(SSAVec4i fg, SSAVec4i bg, DrawWallVariant variant)
|
SSAVec4i DrawWallCodegen::Blend(SSAVec4i fg, SSAVec4i bg, DrawWallVariant variant)
|
||||||
|
|
|
@ -47,7 +47,9 @@ private:
|
||||||
SSAVec4i Shade(SSAVec4i fg, int index, bool isSimpleShade);
|
SSAVec4i Shade(SSAVec4i fg, int index, bool isSimpleShade);
|
||||||
SSAVec4i Blend(SSAVec4i fg, SSAVec4i bg, DrawWallVariant variant);
|
SSAVec4i Blend(SSAVec4i fg, SSAVec4i bg, DrawWallVariant variant);
|
||||||
|
|
||||||
SSAStack<SSAInt> stack_index, stack_frac[4];
|
SSAStack<SSAInt> stack_index, stack_frac[4], stack_light_index;
|
||||||
|
SSAStack<SSAVec4i> stack_lit_color;
|
||||||
|
SSAStack<SSAFloat> stack_z;
|
||||||
|
|
||||||
SSAUBytePtr dest;
|
SSAUBytePtr dest;
|
||||||
SSAUBytePtr source[4];
|
SSAUBytePtr source[4];
|
||||||
|
@ -69,4 +71,10 @@ private:
|
||||||
|
|
||||||
SSAInt fracstep[4];
|
SSAInt fracstep[4];
|
||||||
SSAInt one[4];
|
SSAInt one[4];
|
||||||
|
|
||||||
|
SSAFloat start_z, step_z;
|
||||||
|
|
||||||
|
SSAValue dynlights; // TriLight*
|
||||||
|
SSAInt num_dynlights;
|
||||||
|
SSAFloat z;
|
||||||
};
|
};
|
||||||
|
|
|
@ -290,6 +290,11 @@ llvm::Type *LLVMDrawers::GetDrawWallArgsStruct(llvm::LLVMContext &context)
|
||||||
elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue;
|
elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t fade_blue;
|
||||||
elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate;
|
elements.push_back(llvm::Type::getInt16Ty(context)); // uint16_t desaturate;
|
||||||
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags;
|
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t flags;
|
||||||
|
elements.push_back(llvm::Type::getFloatTy(context)); // float z;
|
||||||
|
elements.push_back(llvm::Type::getFloatTy(context)); // float step_z;
|
||||||
|
elements.push_back(GetTriLightStruct(context)); // TriLight *dynlights;
|
||||||
|
elements.push_back(llvm::Type::getInt32Ty(context)); // uint32_t num_dynlights;
|
||||||
|
|
||||||
DrawWallArgsStruct = llvm::StructType::create(context, elements, "DrawWallArgs", false)->getPointerTo();
|
DrawWallArgsStruct = llvm::StructType::create(context, elements, "DrawWallArgs", false)->getPointerTo();
|
||||||
return DrawWallArgsStruct;
|
return DrawWallArgsStruct;
|
||||||
}
|
}
|
||||||
|
@ -326,6 +331,19 @@ llvm::Type *LLVMDrawers::GetWorkerThreadDataStruct(llvm::LLVMContext &context)
|
||||||
return WorkerThreadDataStruct;
|
return WorkerThreadDataStruct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
llvm::Type *LLVMDrawers::GetTriLightStruct(llvm::LLVMContext &context)
|
||||||
|
{
|
||||||
|
if (TriLightStruct)
|
||||||
|
return TriLightStruct;
|
||||||
|
|
||||||
|
std::vector<llvm::Type *> elements;
|
||||||
|
elements.push_back(llvm::Type::getInt32Ty(context));
|
||||||
|
for (int i = 0; i < 4 + TriVertex::NumVarying; i++)
|
||||||
|
elements.push_back(llvm::Type::getFloatTy(context));
|
||||||
|
TriLightStruct = llvm::StructType::create(context, elements, "TriLight", false)->getPointerTo();
|
||||||
|
return TriLightStruct;
|
||||||
|
}
|
||||||
|
|
||||||
llvm::Type *LLVMDrawers::GetTriVertexStruct(llvm::LLVMContext &context)
|
llvm::Type *LLVMDrawers::GetTriVertexStruct(llvm::LLVMContext &context)
|
||||||
{
|
{
|
||||||
if (TriVertexStruct)
|
if (TriVertexStruct)
|
||||||
|
|
|
@ -58,6 +58,7 @@ private:
|
||||||
llvm::Type *GetDrawWallArgsStruct(llvm::LLVMContext &context);
|
llvm::Type *GetDrawWallArgsStruct(llvm::LLVMContext &context);
|
||||||
llvm::Type *GetDrawSkyArgsStruct(llvm::LLVMContext &context);
|
llvm::Type *GetDrawSkyArgsStruct(llvm::LLVMContext &context);
|
||||||
llvm::Type *GetWorkerThreadDataStruct(llvm::LLVMContext &context);
|
llvm::Type *GetWorkerThreadDataStruct(llvm::LLVMContext &context);
|
||||||
|
llvm::Type *GetTriLightStruct(llvm::LLVMContext &context);
|
||||||
llvm::Type *GetTriVertexStruct(llvm::LLVMContext &context);
|
llvm::Type *GetTriVertexStruct(llvm::LLVMContext &context);
|
||||||
llvm::Type *GetTriMatrixStruct(llvm::LLVMContext &context);
|
llvm::Type *GetTriMatrixStruct(llvm::LLVMContext &context);
|
||||||
llvm::Type *GetTriUniformsStruct(llvm::LLVMContext &context);
|
llvm::Type *GetTriUniformsStruct(llvm::LLVMContext &context);
|
||||||
|
@ -70,6 +71,7 @@ private:
|
||||||
llvm::Type *DrawWallArgsStruct = nullptr;
|
llvm::Type *DrawWallArgsStruct = nullptr;
|
||||||
llvm::Type *DrawSkyArgsStruct = nullptr;
|
llvm::Type *DrawSkyArgsStruct = nullptr;
|
||||||
llvm::Type *WorkerThreadDataStruct = nullptr;
|
llvm::Type *WorkerThreadDataStruct = nullptr;
|
||||||
|
llvm::Type *TriLightStruct = nullptr;
|
||||||
llvm::Type *TriVertexStruct = nullptr;
|
llvm::Type *TriVertexStruct = nullptr;
|
||||||
llvm::Type *TriMatrixStruct = nullptr;
|
llvm::Type *TriMatrixStruct = nullptr;
|
||||||
llvm::Type *TriUniformsStruct = nullptr;
|
llvm::Type *TriUniformsStruct = nullptr;
|
||||||
|
|
Loading…
Reference in a new issue