mirror of https://github.com/ZDoom/qzdoom.git
Add particle drawing
This commit is contained in:
parent
266924600a
commit
511eb59479
|
@ -260,7 +260,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
|
||||||
SetStencilBlock(x / 8 + y / 8 * stencilPitch);
|
SetStencilBlock(x / 8 + y / 8 * stencilPitch);
|
||||||
|
|
||||||
SSABool covered = a == SSAInt(0xF) && b == SSAInt(0xF) && c == SSAInt(0xF) && !clipneeded;
|
SSABool covered = a == SSAInt(0xF) && b == SSAInt(0xF) && c == SSAInt(0xF) && !clipneeded;
|
||||||
if (variant != TriDrawVariant::DrawSubsector)
|
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector)
|
||||||
{
|
{
|
||||||
covered = covered && StencilIsSingleValue();
|
covered = covered && StencilIsSingleValue();
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
|
||||||
void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
||||||
{
|
{
|
||||||
SSAIfBlock branch_stenciltest;
|
SSAIfBlock branch_stenciltest;
|
||||||
if (variant != TriDrawVariant::DrawSubsector)
|
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector)
|
||||||
{
|
{
|
||||||
branch_stenciltest.if_block(StencilGetSingle() == stencilTestValue);
|
branch_stenciltest.if_block(StencilGetSingle() == stencilTestValue);
|
||||||
}
|
}
|
||||||
|
@ -325,7 +325,7 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
||||||
varying[i] = stack_varying[i].load();
|
varying[i] = stack_varying[i].load();
|
||||||
loopx.loop_block(ix < SSAInt(q), q);
|
loopx.loop_block(ix < SSAInt(q), q);
|
||||||
{
|
{
|
||||||
if (variant == TriDrawVariant::DrawSubsector)
|
if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector)
|
||||||
{
|
{
|
||||||
SSAIfBlock branch;
|
SSAIfBlock branch;
|
||||||
branch.if_block(subsectorbuffer[ix].load(true) >= subsectorDepth);
|
branch.if_block(subsectorbuffer[ix].load(true) >= subsectorDepth);
|
||||||
|
@ -353,7 +353,7 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
||||||
loopy.end_block();
|
loopy.end_block();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variant != TriDrawVariant::DrawSubsector)
|
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector)
|
||||||
{
|
{
|
||||||
branch_stenciltest.end_block();
|
branch_stenciltest.end_block();
|
||||||
}
|
}
|
||||||
|
@ -404,7 +404,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
|
||||||
SSABool visible = (ix + x >= clipleft) && (ix + x < clipright) && (cliptop <= y + iy) && (clipbottom > y + iy);
|
SSABool visible = (ix + x >= clipleft) && (ix + x < clipright) && (cliptop <= y + iy) && (clipbottom > y + iy);
|
||||||
SSABool covered = CX1 > SSAInt(0) && CX2 > SSAInt(0) && CX3 > SSAInt(0) && visible;
|
SSABool covered = CX1 > SSAInt(0) && CX2 > SSAInt(0) && CX3 > SSAInt(0) && visible;
|
||||||
|
|
||||||
if (variant == TriDrawVariant::DrawSubsector)
|
if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector)
|
||||||
{
|
{
|
||||||
covered = covered && subsectorbuffer[ix].load(true) >= subsectorDepth;
|
covered = covered && subsectorbuffer[ix].load(true) >= subsectorDepth;
|
||||||
}
|
}
|
||||||
|
@ -449,7 +449,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
|
||||||
|
|
||||||
void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying, TriDrawVariant variant, bool truecolor)
|
void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbuffer, SSAInt *varying, TriDrawVariant variant, bool truecolor)
|
||||||
{
|
{
|
||||||
if (variant == TriDrawVariant::Fill)
|
if (variant == TriDrawVariant::Fill || variant == TriDrawVariant::FillSubsector)
|
||||||
{
|
{
|
||||||
if (truecolor)
|
if (truecolor)
|
||||||
{
|
{
|
||||||
|
@ -459,6 +459,8 @@ void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbu
|
||||||
{
|
{
|
||||||
//buffer.store(solidcolor);
|
//buffer.store(solidcolor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (variant != TriDrawVariant::FillSubsector)
|
||||||
subsectorbuffer.store(subsectorDepth);
|
subsectorbuffer.store(subsectorDepth);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -190,6 +190,8 @@ LLVMDrawersImpl::LLVMDrawersImpl()
|
||||||
CodegenDrawTriangle("TriDraw32", TriDrawVariant::Draw, true);
|
CodegenDrawTriangle("TriDraw32", TriDrawVariant::Draw, true);
|
||||||
CodegenDrawTriangle("TriDrawSubsector8", TriDrawVariant::DrawSubsector, false);
|
CodegenDrawTriangle("TriDrawSubsector8", TriDrawVariant::DrawSubsector, false);
|
||||||
CodegenDrawTriangle("TriDrawSubsector32", TriDrawVariant::DrawSubsector, true);
|
CodegenDrawTriangle("TriDrawSubsector32", TriDrawVariant::DrawSubsector, true);
|
||||||
|
CodegenDrawTriangle("TriFillSubsector8", TriDrawVariant::FillSubsector, false);
|
||||||
|
CodegenDrawTriangle("TriFillSubsector32", TriDrawVariant::FillSubsector, true);
|
||||||
CodegenDrawTriangle("TriFill8", TriDrawVariant::Fill, false);
|
CodegenDrawTriangle("TriFill8", TriDrawVariant::Fill, false);
|
||||||
CodegenDrawTriangle("TriFill32", TriDrawVariant::Fill, true);
|
CodegenDrawTriangle("TriFill32", TriDrawVariant::Fill, true);
|
||||||
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, false);
|
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, false);
|
||||||
|
@ -262,6 +264,8 @@ LLVMDrawersImpl::LLVMDrawersImpl()
|
||||||
TriDraw32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32");
|
TriDraw32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32");
|
||||||
TriDrawSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8");
|
TriDrawSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8");
|
||||||
TriDrawSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32");
|
TriDrawSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector32");
|
||||||
|
TriFillSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector8");
|
||||||
|
TriFillSubsector32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFillSubsector32");
|
||||||
TriFill8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8");
|
TriFill8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill8");
|
||||||
TriFill32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32");
|
TriFill32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32");
|
||||||
TriStencil = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencil");
|
TriStencil = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencil");
|
||||||
|
|
|
@ -266,6 +266,7 @@ enum class TriDrawVariant
|
||||||
DrawMasked,
|
DrawMasked,
|
||||||
Fill,
|
Fill,
|
||||||
DrawSubsector,
|
DrawSubsector,
|
||||||
|
FillSubsector,
|
||||||
Stencil,
|
Stencil,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -348,6 +349,8 @@ public:
|
||||||
void(*TriDraw32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
void(*TriDraw32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||||
void(*TriDrawSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
void(*TriDrawSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||||
void(*TriDrawSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
void(*TriDrawSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||||
|
void(*TriFillSubsector8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||||
|
void(*TriFillSubsector32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||||
void(*TriFill8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
void(*TriFill8)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||||
void(*TriFill32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
void(*TriFill32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||||
void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
void(*TriStencil)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||||
|
|
|
@ -111,6 +111,17 @@ void RenderPolyScene::RenderSubsector(subsector_t *sub)
|
||||||
RenderLine(sub, line, frontsector, subsectorDepth);
|
RenderLine(sub, line, frontsector, subsectorDepth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool mainBSP = ((unsigned int)(sub - subsectors) < (unsigned int)numsubsectors);
|
||||||
|
if (mainBSP)
|
||||||
|
{
|
||||||
|
int subsectorIndex = (int)(sub - subsectors);
|
||||||
|
for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||||
|
{
|
||||||
|
particle_t *particle = Particles + i;
|
||||||
|
TranslucentObjects.push_back({ particle, sub, subsectorDepth });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SpriteRange sprites = GetSpritesForSector(sub->sector);
|
SpriteRange sprites = GetSpritesForSector(sub->sector);
|
||||||
for (int i = 0; i < sprites.Count; i++)
|
for (int i = 0; i < sprites.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -176,7 +187,12 @@ void RenderPolyScene::RenderTranslucent()
|
||||||
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
|
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++it)
|
||||||
{
|
{
|
||||||
auto &obj = *it;
|
auto &obj = *it;
|
||||||
if (!obj.thing)
|
if (obj.particle)
|
||||||
|
{
|
||||||
|
RenderPolyParticle spr;
|
||||||
|
spr.Render(WorldToClip, obj.particle, obj.sub, obj.subsectorDepth);
|
||||||
|
}
|
||||||
|
else if (!obj.thing)
|
||||||
{
|
{
|
||||||
obj.wall.Render(WorldToClip);
|
obj.wall.Render(WorldToClip);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "r_poly_sprite.h"
|
#include "r_poly_sprite.h"
|
||||||
#include "r_poly_wallsprite.h"
|
#include "r_poly_wallsprite.h"
|
||||||
#include "r_poly_playersprite.h"
|
#include "r_poly_playersprite.h"
|
||||||
|
#include "r_poly_particle.h"
|
||||||
#include "r_poly_plane.h"
|
#include "r_poly_plane.h"
|
||||||
#include "r_poly_sky.h"
|
#include "r_poly_sky.h"
|
||||||
#include "r_poly_cull.h"
|
#include "r_poly_cull.h"
|
||||||
|
@ -53,9 +54,11 @@ public:
|
||||||
class PolyTranslucentObject
|
class PolyTranslucentObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
PolyTranslucentObject(particle_t *particle, subsector_t *sub, uint32_t subsectorDepth) : particle(particle), sub(sub), subsectorDepth(subsectorDepth) { }
|
||||||
PolyTranslucentObject(AActor *thing, subsector_t *sub, uint32_t subsectorDepth) : thing(thing), sub(sub), subsectorDepth(subsectorDepth) { }
|
PolyTranslucentObject(AActor *thing, subsector_t *sub, uint32_t subsectorDepth) : thing(thing), sub(sub), subsectorDepth(subsectorDepth) { }
|
||||||
PolyTranslucentObject(RenderPolyWall wall) : wall(wall) { }
|
PolyTranslucentObject(RenderPolyWall wall) : wall(wall) { }
|
||||||
|
|
||||||
|
particle_t *particle = nullptr;
|
||||||
AActor *thing = nullptr;
|
AActor *thing = nullptr;
|
||||||
subsector_t *sub = nullptr;
|
subsector_t *sub = nullptr;
|
||||||
uint32_t subsectorDepth = 0;
|
uint32_t subsectorDepth = 0;
|
||||||
|
|
|
@ -28,6 +28,76 @@
|
||||||
#include "r_poly_particle.h"
|
#include "r_poly_particle.h"
|
||||||
#include "r_poly.h"
|
#include "r_poly.h"
|
||||||
|
|
||||||
void RenderPolyParticle::Render()
|
void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth)
|
||||||
{
|
{
|
||||||
|
DVector3 pos = particle->Pos;
|
||||||
|
double psize = particle->size / 8.0;
|
||||||
|
double zpos = pos.Z;
|
||||||
|
|
||||||
|
DVector2 points[2] =
|
||||||
|
{
|
||||||
|
{ pos.X - ViewSin * psize, pos.Y + ViewCos * psize },
|
||||||
|
{ pos.X + ViewSin * psize, pos.Y - ViewCos * psize }
|
||||||
|
};
|
||||||
|
|
||||||
|
TriVertex *vertices = PolyVertexBuffer::GetVertices(4);
|
||||||
|
if (!vertices)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool foggy = false;
|
||||||
|
int actualextralight = foggy ? 0 : extralight << 4;
|
||||||
|
|
||||||
|
std::pair<float, float> offsets[4] =
|
||||||
|
{
|
||||||
|
{ 0.0f, 1.0f },
|
||||||
|
{ 1.0f, 1.0f },
|
||||||
|
{ 1.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
auto &p = (i == 0 || i == 3) ? points[0] : points[1];
|
||||||
|
|
||||||
|
vertices[i].x = (float)p.X;
|
||||||
|
vertices[i].y = (float)p.Y;
|
||||||
|
vertices[i].z = (float)(zpos + psize * (2.0 * offsets[i].second - 1.0));
|
||||||
|
vertices[i].w = 1.0f;
|
||||||
|
vertices[i].varying[0] = (float)(offsets[i].first);
|
||||||
|
vertices[i].varying[1] = (float)(1.0f - offsets[i].second);
|
||||||
|
}
|
||||||
|
|
||||||
|
// int color = (particle->color >> 24) & 0xff; // pal index, I think
|
||||||
|
bool fullbrightSprite = particle->bright != 0;
|
||||||
|
|
||||||
|
TriUniforms uniforms;
|
||||||
|
uniforms.objectToClip = worldToClip;
|
||||||
|
if (fullbrightSprite || fixedlightlev >= 0 || fixedcolormap)
|
||||||
|
{
|
||||||
|
uniforms.light = 256;
|
||||||
|
uniforms.flags = TriUniforms::fixed_light;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uniforms.light = (uint32_t)((sub->sector->lightlevel + actualextralight) / 255.0f * 256.0f);
|
||||||
|
uniforms.flags = 0;
|
||||||
|
}
|
||||||
|
uniforms.subsectorDepth = subsectorDepth;
|
||||||
|
|
||||||
|
uint32_t alpha = particle->trans;
|
||||||
|
|
||||||
|
PolyDrawArgs args;
|
||||||
|
args.uniforms = uniforms;
|
||||||
|
args.vinput = vertices;
|
||||||
|
args.vcount = 4;
|
||||||
|
args.mode = TriangleDrawMode::Fan;
|
||||||
|
args.ccw = true;
|
||||||
|
args.clipleft = 0;
|
||||||
|
args.cliptop = 0;
|
||||||
|
args.clipright = viewwidth;
|
||||||
|
args.clipbottom = viewheight;
|
||||||
|
args.stenciltestvalue = 0;
|
||||||
|
args.stencilwritevalue = 1;
|
||||||
|
args.solidcolor = (alpha << 24) | (particle->color & 0xffffff);
|
||||||
|
PolyTriangleDrawer::draw(args, TriDrawVariant::FillSubsector);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,11 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "r_poly_triangle.h"
|
||||||
|
#include "p_effect.h"
|
||||||
|
|
||||||
class RenderPolyParticle
|
class RenderPolyParticle
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Render();
|
void Render(const TriMatrix &worldToClip, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth);
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,6 +62,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
|
||||||
case TriDrawVariant::Draw: drawfunc = r_swtruecolor ? llvm->TriDraw32: llvm->TriDraw8; break;
|
case TriDrawVariant::Draw: drawfunc = r_swtruecolor ? llvm->TriDraw32: llvm->TriDraw8; break;
|
||||||
case TriDrawVariant::Fill: drawfunc = r_swtruecolor ? llvm->TriFill32 : llvm->TriFill8; break;
|
case TriDrawVariant::Fill: drawfunc = r_swtruecolor ? llvm->TriFill32 : llvm->TriFill8; break;
|
||||||
case TriDrawVariant::DrawSubsector: drawfunc = r_swtruecolor ? llvm->TriDrawSubsector32 : llvm->TriDrawSubsector8; break;
|
case TriDrawVariant::DrawSubsector: drawfunc = r_swtruecolor ? llvm->TriDrawSubsector32 : llvm->TriDrawSubsector8; break;
|
||||||
|
case TriDrawVariant::FillSubsector: drawfunc = r_swtruecolor ? llvm->TriFillSubsector32 : llvm->TriFillSubsector8; break;
|
||||||
case TriDrawVariant::Stencil: drawfunc = llvm->TriStencil; break;
|
case TriDrawVariant::Stencil: drawfunc = llvm->TriStencil; break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -69,6 +70,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
case TriDrawVariant::Draw: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::draw; break;
|
case TriDrawVariant::Draw: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::draw; break;
|
||||||
|
case TriDrawVariant::FillSubsector:
|
||||||
case TriDrawVariant::Fill: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::fill32 : ScreenPolyTriangleDrawer::fill; break;
|
case TriDrawVariant::Fill: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::fill32 : ScreenPolyTriangleDrawer::fill; break;
|
||||||
case TriDrawVariant::DrawSubsector: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::drawsubsector32 : llvm->TriDrawSubsector8; break;
|
case TriDrawVariant::DrawSubsector: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::drawsubsector32 : llvm->TriDrawSubsector8; break;
|
||||||
case TriDrawVariant::Stencil: drawfunc = ScreenPolyTriangleDrawer::stencil; break;
|
case TriDrawVariant::Stencil: drawfunc = ScreenPolyTriangleDrawer::stencil; break;
|
||||||
|
|
Loading…
Reference in New Issue