Add particle drawing

This commit is contained in:
Magnus Norddahl 2016-11-17 01:29:08 +01:00
parent 266924600a
commit 511eb59479
8 changed files with 113 additions and 10 deletions

View file

@ -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
{

View file

@ -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");

View file

@ -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;

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
};

View file

@ -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;