mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
Add particle drawing
This commit is contained in:
parent
266924600a
commit
511eb59479
8 changed files with 113 additions and 10 deletions
|
@ -260,7 +260,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
|
|||
SetStencilBlock(x / 8 + y / 8 * stencilPitch);
|
||||
|
||||
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();
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
|
|||
void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
||||
{
|
||||
SSAIfBlock branch_stenciltest;
|
||||
if (variant != TriDrawVariant::DrawSubsector)
|
||||
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector)
|
||||
{
|
||||
branch_stenciltest.if_block(StencilGetSingle() == stencilTestValue);
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
|||
varying[i] = stack_varying[i].load();
|
||||
loopx.loop_block(ix < SSAInt(q), q);
|
||||
{
|
||||
if (variant == TriDrawVariant::DrawSubsector)
|
||||
if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::FillSubsector)
|
||||
{
|
||||
SSAIfBlock branch;
|
||||
branch.if_block(subsectorbuffer[ix].load(true) >= subsectorDepth);
|
||||
|
@ -353,7 +353,7 @@ void DrawTriangleCodegen::LoopFullBlock(TriDrawVariant variant, bool truecolor)
|
|||
loopy.end_block();
|
||||
}
|
||||
|
||||
if (variant != TriDrawVariant::DrawSubsector)
|
||||
if (variant != TriDrawVariant::DrawSubsector && variant != TriDrawVariant::FillSubsector)
|
||||
{
|
||||
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 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;
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -459,7 +459,9 @@ void DrawTriangleCodegen::ProcessPixel(SSAUBytePtr buffer, SSAIntPtr subsectorbu
|
|||
{
|
||||
//buffer.store(solidcolor);
|
||||
}
|
||||
subsectorbuffer.store(subsectorDepth);
|
||||
|
||||
if (variant != TriDrawVariant::FillSubsector)
|
||||
subsectorbuffer.store(subsectorDepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -190,6 +190,8 @@ LLVMDrawersImpl::LLVMDrawersImpl()
|
|||
CodegenDrawTriangle("TriDraw32", TriDrawVariant::Draw, true);
|
||||
CodegenDrawTriangle("TriDrawSubsector8", TriDrawVariant::DrawSubsector, false);
|
||||
CodegenDrawTriangle("TriDrawSubsector32", TriDrawVariant::DrawSubsector, true);
|
||||
CodegenDrawTriangle("TriFillSubsector8", TriDrawVariant::FillSubsector, false);
|
||||
CodegenDrawTriangle("TriFillSubsector32", TriDrawVariant::FillSubsector, true);
|
||||
CodegenDrawTriangle("TriFill8", TriDrawVariant::Fill, false);
|
||||
CodegenDrawTriangle("TriFill32", TriDrawVariant::Fill, true);
|
||||
CodegenDrawTriangle("TriStencil", TriDrawVariant::Stencil, false);
|
||||
|
@ -262,6 +264,8 @@ LLVMDrawersImpl::LLVMDrawersImpl()
|
|||
TriDraw32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDraw32");
|
||||
TriDrawSubsector8 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriDrawSubsector8");
|
||||
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");
|
||||
TriFill32 = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriFill32");
|
||||
TriStencil = mProgram.GetProcAddress<void(const TriDrawTriangleArgs *, WorkerThreadData *)>("TriStencil");
|
||||
|
|
|
@ -266,6 +266,7 @@ enum class TriDrawVariant
|
|||
DrawMasked,
|
||||
Fill,
|
||||
DrawSubsector,
|
||||
FillSubsector,
|
||||
Stencil,
|
||||
};
|
||||
|
||||
|
@ -348,6 +349,8 @@ public:
|
|||
void(*TriDraw32)(const TriDrawTriangleArgs *, WorkerThreadData *) = nullptr;
|
||||
void(*TriDrawSubsector8)(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(*TriFill32)(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);
|
||||
}
|
||||
|
||||
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);
|
||||
for (int i = 0; i < sprites.Count; i++)
|
||||
{
|
||||
|
@ -176,7 +187,12 @@ void RenderPolyScene::RenderTranslucent()
|
|||
for (auto it = TranslucentObjects.rbegin(); it != TranslucentObjects.rend(); ++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);
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "r_poly_sprite.h"
|
||||
#include "r_poly_wallsprite.h"
|
||||
#include "r_poly_playersprite.h"
|
||||
#include "r_poly_particle.h"
|
||||
#include "r_poly_plane.h"
|
||||
#include "r_poly_sky.h"
|
||||
#include "r_poly_cull.h"
|
||||
|
@ -53,9 +54,11 @@ public:
|
|||
class PolyTranslucentObject
|
||||
{
|
||||
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(RenderPolyWall wall) : wall(wall) { }
|
||||
|
||||
particle_t *particle = nullptr;
|
||||
AActor *thing = nullptr;
|
||||
subsector_t *sub = nullptr;
|
||||
uint32_t subsectorDepth = 0;
|
||||
|
|
|
@ -28,6 +28,76 @@
|
|||
#include "r_poly_particle.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
|
||||
|
||||
#include "r_poly_triangle.h"
|
||||
#include "p_effect.h"
|
||||
|
||||
class RenderPolyParticle
|
||||
{
|
||||
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::Fill: drawfunc = r_swtruecolor ? llvm->TriFill32 : llvm->TriFill8; 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;
|
||||
}
|
||||
#else
|
||||
|
@ -69,6 +70,7 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
|
|||
{
|
||||
default:
|
||||
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::DrawSubsector: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::drawsubsector32 : llvm->TriDrawSubsector8; break;
|
||||
case TriDrawVariant::Stencil: drawfunc = ScreenPolyTriangleDrawer::stencil; break;
|
||||
|
|
Loading…
Reference in a new issue