Add TriUniforms and move light to it

This commit is contained in:
Magnus Norddahl 2016-11-08 16:16:24 +01:00
parent 6620d99fbb
commit 28d1cdc1cc
6 changed files with 194 additions and 137 deletions

View file

@ -1025,58 +1025,58 @@ static void R_DrawCubeSky(visplane_t *pl)
static TriVertex cube[6 * 6] = static TriVertex cube[6 * 6] =
{ {
// Top // Top
{ -1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f }, { -1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f },
{ 1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f },
{ 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.1f, 1.0f }, { 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.1f },
{ 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.1f, 1.0f }, { 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.1f },
{ -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.1f, 1.0f }, { -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.1f },
{ -1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f }, { -1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f },
// Bottom // Bottom
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.9f, 1.0f }, { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.9f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f }, { -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f }, { -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f },
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.9f, 1.0f }, { -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.9f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.9f, 1.0f }, { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 0.9f },
// Front // Front
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f },
{ 1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f },
{ -1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f }, { -1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f },
{ -1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f }, { -1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f }, { -1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 2.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f },
// Back // Back
{ -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f }, { -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f },
{ 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f }, { 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 2.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f }, { 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 2.0f },
{ -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f }, { -1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f },
{ -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f }, { -1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f },
// Right // Right
{ 1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f },
{ 1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.6f, 1.0f, 0.0f, 0.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 2.0f },
{ 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f }, { 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 2.0f },
{ 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f }, { 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 2.0f },
{ 1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f }, { 1.0f, -1.0f, 0.6f, 1.0f, 1.0f, 0.0f },
// Left // Left
{ -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f }, { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f },
{ -1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f, 1.0f }, { -1.0f, 1.0f, 0.6f, 1.0f, 1.0f, 0.0f },
{ -1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f }, { -1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f },
{ -1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f, 1.0f }, { -1.0f, -1.0f, 0.6f, 1.0f, 0.0f, 0.0f },
{ -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 2.0f, 1.0f }, { -1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 2.0f },
{ -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f, 1.0f } { -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 2.0f }
}; };
TriMatrix objectToWorld = TriMatrix::translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z) * TriMatrix::scale(1000.0f, 1000.0f, 1000.0f); TriMatrix objectToWorld = TriMatrix::translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z) * TriMatrix::scale(1000.0f, 1000.0f, 1000.0f);
@ -1090,9 +1090,14 @@ static void R_DrawCubeSky(visplane_t *pl)
solid_top = RGB32k.RGB[(RPART(solid_top) >> 3)][(GPART(solid_top) >> 3)][(BPART(solid_top) >> 3)]; solid_top = RGB32k.RGB[(RPART(solid_top) >> 3)][(GPART(solid_top) >> 3)][(BPART(solid_top) >> 3)];
solid_bottom = RGB32k.RGB[(RPART(solid_bottom) >> 3)][(GPART(solid_bottom) >> 3)][(BPART(solid_bottom) >> 3)]; solid_bottom = RGB32k.RGB[(RPART(solid_bottom) >> 3)][(GPART(solid_bottom) >> 3)][(BPART(solid_bottom) >> 3)];
TriangleDrawer::fill(objectToClip, cube, 6, TriangleDrawMode::Normal, false, x1, x2 - 1, uwal, dwal, solid_top); TriUniforms uniforms;
TriangleDrawer::fill(objectToClip, cube + 6, 6, TriangleDrawMode::Normal, false, x1, x2 - 1, uwal, dwal, solid_bottom); uniforms.objectToClip = objectToClip;
TriangleDrawer::draw(objectToClip, cube + 2 * 6, 4 * 6, TriangleDrawMode::Normal, false, x1, x2 - 1, uwal, dwal, frontskytex); uniforms.light = 256;
uniforms.flags = 0;
TriangleDrawer::fill(uniforms, cube, 6, TriangleDrawMode::Normal, false, x1, x2 - 1, uwal, dwal, solid_top);
TriangleDrawer::fill(uniforms, cube + 6, 6, TriangleDrawMode::Normal, false, x1, x2 - 1, uwal, dwal, solid_bottom);
TriangleDrawer::draw(uniforms, cube + 2 * 6, 4 * 6, TriangleDrawMode::Normal, false, x1, x2 - 1, uwal, dwal, frontskytex);
} }
namespace namespace
@ -1127,7 +1132,6 @@ namespace
v.w = 1.0f; v.w = 1.0f;
v.varying[0] = uu; v.varying[0] = uu;
v.varying[1] = vv; v.varying[1] = vv;
v.varying[2] = 1.0f;
return v; return v;
} }
@ -1140,7 +1144,6 @@ namespace
v.w = 1.0f; v.w = 1.0f;
v.varying[0] = uu; v.varying[0] = uu;
v.varying[1] = vv; v.varying[1] = vv;
v.varying[2] = 1.0f;
return v; return v;
} }
@ -1220,7 +1223,11 @@ namespace
short *dwal = (short *)pl->bottom; short *dwal = (short *)pl->bottom;
TriMatrix objectToWorld = TriMatrix::translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z); TriMatrix objectToWorld = TriMatrix::translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z);
TriMatrix objectToClip = TriMatrix::viewToClip() * TriMatrix::worldToView() * objectToWorld; TriMatrix objectToClip = TriMatrix::viewToClip() * TriMatrix::worldToView() * objectToWorld;
TriangleDrawer::draw(objectToClip, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], TriangleDrawMode::Strip, false, x1, x2 - 1, uwal, dwal, frontskytex); TriUniforms uniforms;
uniforms.objectToClip = objectToClip;
uniforms.light = 256;
uniforms.flags = 0;
TriangleDrawer::draw(uniforms, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], TriangleDrawMode::Strip, false, x1, x2 - 1, uwal, dwal, frontskytex);
} }
void SkyDome::RenderCapColorRow(int row, bool bottomCap, visplane_t *pl) void SkyDome::RenderCapColorRow(int row, bool bottomCap, visplane_t *pl)
@ -1234,7 +1241,11 @@ namespace
short *dwal = (short *)pl->bottom; short *dwal = (short *)pl->bottom;
TriMatrix objectToWorld = TriMatrix::translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z); TriMatrix objectToWorld = TriMatrix::translate((float)ViewPos.X, (float)ViewPos.Y, (float)ViewPos.Z);
TriMatrix objectToClip = TriMatrix::viewToClip() * TriMatrix::worldToView() * objectToWorld; TriMatrix objectToClip = TriMatrix::viewToClip() * TriMatrix::worldToView() * objectToWorld;
TriangleDrawer::fill(objectToClip, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], TriangleDrawMode::Fan, bottomCap, x1, x2 - 1, uwal, dwal, solid); TriUniforms uniforms;
uniforms.objectToClip = objectToClip;
uniforms.light = 256;
uniforms.flags = 0;
TriangleDrawer::fill(uniforms, &mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], TriangleDrawMode::Fan, bottomCap, x1, x2 - 1, uwal, dwal, solid);
} }
void SkyDome::Render(visplane_t *pl) void SkyDome::Render(visplane_t *pl)

View file

@ -87,13 +87,6 @@ TriVertex RenderPolyBsp::PlaneVertex(vertex_t *v1, sector_t *sector, const secpl
v.varying[0] = v.x / 64.0f; v.varying[0] = v.x / 64.0f;
v.varying[1] = v.y / 64.0f; v.varying[1] = v.y / 64.0f;
if (fixedlightlev >= 0)
v.varying[2] = fixedlightlev / 255.0f;
else if (fixedcolormap)
v.varying[2] = 1.0f;
else
v.varying[2] = sector->lightlevel / 255.0f;
/* /*
double vis = r_FloorVisibility / (plane.Zat0() - ViewPos.Z); double vis = r_FloorVisibility / (plane.Zat0() - ViewPos.Z);
if (fixedlightlev >= 0) if (fixedlightlev >= 0)
@ -119,25 +112,53 @@ void RenderPolyBsp::RenderSubsector(subsector_t *sub)
AddLine(line, frontsector); AddLine(line, frontsector);
} }
TriVertex *floorVertices = PolyVertexBuffer::GetVertices(sub->numlines); FTexture *floortex = TexMan(frontsector->GetTexture(sector_t::floor));
TriVertex *ceilVertices = PolyVertexBuffer::GetVertices(sub->numlines); if (floortex->UseType != FTexture::TEX_Null)
if (floorVertices == nullptr || ceilVertices == nullptr) {
TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
if (!vertices)
return; return;
for (uint32_t i = 0; i < sub->numlines; i++) for (uint32_t i = 0; i < sub->numlines; i++)
{ {
seg_t *line = &sub->firstline[i]; seg_t *line = &sub->firstline[i];
ceilVertices[sub->numlines - 1 - i] = PlaneVertex(line->v1, frontsector, frontsector->ceilingplane); vertices[i] = PlaneVertex(line->v1, frontsector, frontsector->floorplane);
floorVertices[i] = PlaneVertex(line->v1, frontsector, frontsector->floorplane);
} }
FTexture *floortex = TexMan(frontsector->GetTexture(sector_t::floor)); TriUniforms uniforms;
if (floortex->UseType != FTexture::TEX_Null) uniforms.objectToClip = worldToClip;
PolyTriangleDrawer::draw(worldToClip, floorVertices, sub->numlines, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, floortex); uniforms.light = (uint32_t)(frontsector->lightlevel / 255.0f * 256.0f);
if (fixedlightlev >= 0)
uniforms.light = (uint32_t)(fixedlightlev / 255.0f * 256.0f);
else if (fixedcolormap)
uniforms.light = 256;
uniforms.flags = 0;
PolyTriangleDrawer::draw(uniforms, vertices, sub->numlines, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, floortex);
}
FTexture *ceiltex = TexMan(frontsector->GetTexture(sector_t::ceiling)); FTexture *ceiltex = TexMan(frontsector->GetTexture(sector_t::ceiling));
if (ceiltex->UseType != FTexture::TEX_Null) if (ceiltex->UseType != FTexture::TEX_Null)
PolyTriangleDrawer::draw(worldToClip, ceilVertices, sub->numlines, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, ceiltex); {
TriVertex *vertices = PolyVertexBuffer::GetVertices(sub->numlines);
if (!vertices)
return;
for (uint32_t i = 0; i < sub->numlines; i++)
{
seg_t *line = &sub->firstline[i];
vertices[sub->numlines - 1 - i] = PlaneVertex(line->v1, frontsector, frontsector->ceilingplane);
}
TriUniforms uniforms;
uniforms.objectToClip = worldToClip;
uniforms.light = (uint32_t)(frontsector->lightlevel / 255.0f * 256.0f);
if (fixedlightlev >= 0)
uniforms.light = (uint32_t)(fixedlightlev / 255.0f * 256.0f);
else if (fixedcolormap)
uniforms.light = 256;
uniforms.flags = 0;
PolyTriangleDrawer::draw(uniforms, vertices, sub->numlines, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, ceiltex);
}
for (AActor *thing = sub->sector->thinglist; thing != nullptr; thing = thing->snext) for (AActor *thing = sub->sector->thinglist; thing != nullptr; thing = thing->snext)
{ {
@ -344,10 +365,13 @@ void RenderPolyBsp::AddSprite(AActor *thing, subsector_t *sub)
vertices[i].varying[1] = (float)((1.0f - offsets[i].second) * tex->Scale.Y); vertices[i].varying[1] = (float)((1.0f - offsets[i].second) * tex->Scale.Y);
if (flipTextureX) if (flipTextureX)
vertices[i].varying[0] = 1.0f - vertices[i].varying[0]; vertices[i].varying[0] = 1.0f - vertices[i].varying[0];
vertices[i].varying[2] = (thing->Sector->lightlevel + actualextralight) / 255.0f;
} }
PolyTriangleDrawer::draw(worldToClip, vertices, 4, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, tex); TriUniforms uniforms;
uniforms.objectToClip = worldToClip;
uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f);
uniforms.flags = 0;
PolyTriangleDrawer::draw(uniforms, vertices, 4, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, tex);
} }
void RenderPolyBsp::AddWallSprite(AActor *thing, subsector_t *sub) void RenderPolyBsp::AddWallSprite(AActor *thing, subsector_t *sub)
@ -858,7 +882,6 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
vertices[0].w = 1.0f; vertices[0].w = 1.0f;
vertices[0].varying[0] = (float)texcoords.u1; vertices[0].varying[0] = (float)texcoords.u1;
vertices[0].varying[1] = (float)texcoords.v1; vertices[0].varying[1] = (float)texcoords.v1;
vertices[0].varying[2] = GetLightLevel() / 255.0f;
vertices[1].x = (float)v2.X; vertices[1].x = (float)v2.X;
vertices[1].y = (float)v2.Y; vertices[1].y = (float)v2.Y;
@ -866,7 +889,6 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
vertices[1].w = 1.0f; vertices[1].w = 1.0f;
vertices[1].varying[0] = (float)texcoords.u2; vertices[1].varying[0] = (float)texcoords.u2;
vertices[1].varying[1] = (float)texcoords.v1; vertices[1].varying[1] = (float)texcoords.v1;
vertices[1].varying[2] = GetLightLevel() / 255.0f;
vertices[2].x = (float)v2.X; vertices[2].x = (float)v2.X;
vertices[2].y = (float)v2.Y; vertices[2].y = (float)v2.Y;
@ -874,7 +896,6 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
vertices[2].w = 1.0f; vertices[2].w = 1.0f;
vertices[2].varying[0] = (float)texcoords.u2; vertices[2].varying[0] = (float)texcoords.u2;
vertices[2].varying[1] = (float)texcoords.v2; vertices[2].varying[1] = (float)texcoords.v2;
vertices[2].varying[2] = GetLightLevel() / 255.0f;
vertices[3].x = (float)v1.X; vertices[3].x = (float)v1.X;
vertices[3].y = (float)v1.Y; vertices[3].y = (float)v1.Y;
@ -882,9 +903,12 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
vertices[3].w = 1.0f; vertices[3].w = 1.0f;
vertices[3].varying[0] = (float)texcoords.u1; vertices[3].varying[0] = (float)texcoords.u1;
vertices[3].varying[1] = (float)texcoords.v2; vertices[3].varying[1] = (float)texcoords.v2;
vertices[3].varying[2] = GetLightLevel() / 255.0f;
PolyTriangleDrawer::draw(worldToClip, vertices, 4, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, tex); TriUniforms uniforms;
uniforms.objectToClip = worldToClip;
uniforms.light = (uint32_t)(GetLightLevel() / 255.0f * 256.0f);
uniforms.flags = 0;
PolyTriangleDrawer::draw(uniforms, vertices, 4, TriangleDrawMode::Fan, true, 0, viewwidth, 0, viewheight, tex);
} }
FTexture *RenderPolyWall::GetTexture() FTexture *RenderPolyWall::GetTexture()

View file

@ -36,31 +36,31 @@
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "r_poly_triangle.h" #include "r_poly_triangle.h"
void PolyTriangleDrawer::draw(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, FTexture *texture) void PolyTriangleDrawer::draw(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, FTexture *texture)
{ {
if (r_swtruecolor) if (r_swtruecolor)
queue_arrays(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, (const uint8_t*)texture->GetPixelsBgra(), texture->GetWidth(), texture->GetHeight(), 0); queue_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, (const uint8_t*)texture->GetPixelsBgra(), texture->GetWidth(), texture->GetHeight(), 0);
else else
draw_arrays(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, texture->GetPixels(), texture->GetWidth(), texture->GetHeight(), 0, nullptr, &ScreenPolyTriangleDrawer::draw); draw_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, texture->GetPixels(), texture->GetWidth(), texture->GetHeight(), 0, nullptr, &ScreenPolyTriangleDrawer::draw);
} }
void PolyTriangleDrawer::fill(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, int solidcolor) void PolyTriangleDrawer::fill(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, int solidcolor)
{ {
if (r_swtruecolor) if (r_swtruecolor)
queue_arrays(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor); queue_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor);
else else
draw_arrays(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor, nullptr, &ScreenPolyTriangleDrawer::fill); draw_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor, nullptr, &ScreenPolyTriangleDrawer::fill);
} }
void PolyTriangleDrawer::queue_arrays(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor) void PolyTriangleDrawer::queue_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor)
{ {
if (clipright < clipleft || clipleft < 0 || clipright > MAXWIDTH || clipbottom < cliptop || cliptop < 0 || clipbottom > MAXHEIGHT) if (clipright < clipleft || clipleft < 0 || clipright > MAXWIDTH || clipbottom < cliptop || cliptop < 0 || clipbottom > MAXHEIGHT)
return; return;
DrawerCommandQueue::QueueCommand<DrawPolyTrianglesCommand>(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, texturePixels, textureWidth, textureHeight, solidcolor); DrawerCommandQueue::QueueCommand<DrawPolyTrianglesCommand>(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, texturePixels, textureWidth, textureHeight, solidcolor);
} }
void PolyTriangleDrawer::draw_arrays(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *)) void PolyTriangleDrawer::draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *))
{ {
if (vcount < 3) if (vcount < 3)
return; return;
@ -76,6 +76,7 @@ void PolyTriangleDrawer::draw_arrays(const TriMatrix &objectToClip, const TriVer
args.textureWidth = textureWidth; args.textureWidth = textureWidth;
args.textureHeight = textureHeight; args.textureHeight = textureHeight;
args.solidcolor = solidcolor; args.solidcolor = solidcolor;
args.uniforms = &uniforms;
TriVertex vert[3]; TriVertex vert[3];
if (mode == TriangleDrawMode::Normal) if (mode == TriangleDrawMode::Normal)
@ -83,28 +84,28 @@ void PolyTriangleDrawer::draw_arrays(const TriMatrix &objectToClip, const TriVer
for (int i = 0; i < vcount / 3; i++) for (int i = 0; i < vcount / 3; i++)
{ {
for (int j = 0; j < 3; j++) for (int j = 0; j < 3; j++)
vert[j] = shade_vertex(objectToClip, *(vinput++)); vert[j] = shade_vertex(uniforms, *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc);
} }
} }
else if (mode == TriangleDrawMode::Fan) else if (mode == TriangleDrawMode::Fan)
{ {
vert[0] = shade_vertex(objectToClip, *(vinput++)); vert[0] = shade_vertex(uniforms, *(vinput++));
vert[1] = shade_vertex(objectToClip, *(vinput++)); vert[1] = shade_vertex(uniforms, *(vinput++));
for (int i = 2; i < vcount; i++) for (int i = 2; i < vcount; i++)
{ {
vert[2] = shade_vertex(objectToClip, *(vinput++)); vert[2] = shade_vertex(uniforms, *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc);
vert[1] = vert[2]; vert[1] = vert[2];
} }
} }
else // TriangleDrawMode::Strip else // TriangleDrawMode::Strip
{ {
vert[0] = shade_vertex(objectToClip, *(vinput++)); vert[0] = shade_vertex(uniforms, *(vinput++));
vert[1] = shade_vertex(objectToClip, *(vinput++)); vert[1] = shade_vertex(uniforms, *(vinput++));
for (int i = 2; i < vcount; i++) for (int i = 2; i < vcount; i++)
{ {
vert[2] = shade_vertex(objectToClip, *(vinput++)); vert[2] = shade_vertex(uniforms, *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc);
vert[0] = vert[1]; vert[0] = vert[1];
vert[1] = vert[2]; vert[1] = vert[2];
@ -113,10 +114,10 @@ void PolyTriangleDrawer::draw_arrays(const TriMatrix &objectToClip, const TriVer
} }
} }
TriVertex PolyTriangleDrawer::shade_vertex(const TriMatrix &objectToClip, TriVertex v) TriVertex PolyTriangleDrawer::shade_vertex(const TriUniforms &uniforms, TriVertex v)
{ {
// Apply transform to get clip coordinates: // Apply transform to get clip coordinates:
return objectToClip * v; return uniforms.objectToClip * v;
} }
void PolyTriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *)) void PolyTriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *))
@ -389,7 +390,6 @@ void ScreenPolyTriangleDrawer::draw(const ScreenPolyTriangleDrawerArgs *args, Dr
{ {
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
//uint32_t light = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f);
uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16; uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
@ -431,7 +431,6 @@ void ScreenPolyTriangleDrawer::draw(const ScreenPolyTriangleDrawerArgs *args, Dr
{ {
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
//uint32_t light = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f);
uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16; uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
@ -631,6 +630,7 @@ void ScreenPolyTriangleDrawer::draw32(const ScreenPolyTriangleDrawerArgs *args,
const uint32_t *texturePixels = (const uint32_t *)args->texturePixels; const uint32_t *texturePixels = (const uint32_t *)args->texturePixels;
int textureWidth = args->textureWidth; int textureWidth = args->textureWidth;
int textureHeight = args->textureHeight; int textureHeight = args->textureHeight;
uint32_t light = args->uniforms->light;
// 28.4 fixed-point coordinates // 28.4 fixed-point coordinates
const int Y1 = (int)round(16.0f * v1.y); const int Y1 = (int)round(16.0f * v1.y);
@ -776,7 +776,6 @@ void ScreenPolyTriangleDrawer::draw32(const ScreenPolyTriangleDrawerArgs *args,
{ {
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
uint32_t light = (uint32_t)clamp(varying[2] * 256.0f + 0.5f, 0.0f, 256.0f);
uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16; uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
@ -825,7 +824,6 @@ void ScreenPolyTriangleDrawer::draw32(const ScreenPolyTriangleDrawerArgs *args,
{ {
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
uint32_t light = (uint32_t)clamp(varying[2] * 256.0f + 0.5f, 0.0f, 256.0f);
uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16; uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
@ -1034,15 +1032,15 @@ float ScreenPolyTriangleDrawer::grady(float x0, float y0, float x1, float y1, fl
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor) DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor)
: objectToClip(objectToClip), vinput(vinput), vcount(vcount), mode(mode), ccw(ccw), clipleft(clipleft), clipright(clipright), cliptop(cliptop), clipbottom(clipbottom), texturePixels(texturePixels), textureWidth(textureWidth), textureHeight(textureHeight), solidcolor(solidcolor) : uniforms(uniforms), vinput(vinput), vcount(vcount), mode(mode), ccw(ccw), clipleft(clipleft), clipright(clipright), cliptop(cliptop), clipbottom(clipbottom), texturePixels(texturePixels), textureWidth(textureWidth), textureHeight(textureHeight), solidcolor(solidcolor)
{ {
} }
void DrawPolyTrianglesCommand::Execute(DrawerThread *thread) void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
{ {
PolyTriangleDrawer::draw_arrays( PolyTriangleDrawer::draw_arrays(
objectToClip, vinput, vcount, mode, ccw, uniforms, vinput, vcount, mode, ccw,
clipleft, clipright, cliptop, clipbottom, clipleft, clipright, cliptop, clipbottom,
texturePixels, textureWidth, textureHeight, solidcolor, texturePixels, textureWidth, textureHeight, solidcolor,
thread, texturePixels ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::fill32); thread, texturePixels ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::fill32);

View file

@ -31,17 +31,17 @@ struct ScreenPolyTriangleDrawerArgs;
class PolyTriangleDrawer class PolyTriangleDrawer
{ {
public: public:
static void draw(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, FTexture *texture); static void draw(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, FTexture *texture);
static void fill(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, int solidcolor); static void fill(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, int solidcolor);
private: private:
static TriVertex shade_vertex(const TriMatrix &objectToClip, TriVertex v); static TriVertex shade_vertex(const TriUniforms &uniforms, TriVertex v);
static void draw_arrays(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *)); static void draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *));
static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *)); static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, ScreenPolyTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenPolyTriangleDrawerArgs *, DrawerThread *));
static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2); static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2);
static void clipedge(const TriVertex &v1, const TriVertex &v2, TriVertex *clippedvert, int &numclipvert); static void clipedge(const TriVertex &v1, const TriVertex &v2, TriVertex *clippedvert, int &numclipvert);
static void queue_arrays(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor); static void queue_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor);
friend class DrawPolyTrianglesCommand; friend class DrawPolyTrianglesCommand;
}; };
@ -61,6 +61,7 @@ struct ScreenPolyTriangleDrawerArgs
int textureWidth; int textureWidth;
int textureHeight; int textureHeight;
int solidcolor; int solidcolor;
const TriUniforms *uniforms;
}; };
class ScreenPolyTriangleDrawer class ScreenPolyTriangleDrawer
@ -80,13 +81,13 @@ private:
class DrawPolyTrianglesCommand : public DrawerCommand class DrawPolyTrianglesCommand : public DrawerCommand
{ {
public: public:
DrawPolyTrianglesCommand(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor); DrawPolyTrianglesCommand(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, int cliptop, int clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor);
void Execute(DrawerThread *thread) override; void Execute(DrawerThread *thread) override;
FString DebugInfo() override; FString DebugInfo() override;
private: private:
TriMatrix objectToClip; TriUniforms uniforms;
const TriVertex *vinput; const TriVertex *vinput;
int vcount; int vcount;
TriangleDrawMode mode; TriangleDrawMode mode;

View file

@ -36,23 +36,23 @@
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "r_triangle.h" #include "r_triangle.h"
void TriangleDrawer::draw(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, FTexture *texture) void TriangleDrawer::draw(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, FTexture *texture)
{ {
if (r_swtruecolor) if (r_swtruecolor)
queue_arrays(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, (const uint8_t*)texture->GetPixelsBgra(), texture->GetWidth(), texture->GetHeight(), 0); queue_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, (const uint8_t*)texture->GetPixelsBgra(), texture->GetWidth(), texture->GetHeight(), 0);
else else
draw_arrays(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, texture->GetPixels(), texture->GetWidth(), texture->GetHeight(), 0, nullptr, &ScreenTriangleDrawer::draw); draw_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, texture->GetPixels(), texture->GetWidth(), texture->GetHeight(), 0, nullptr, &ScreenTriangleDrawer::draw);
} }
void TriangleDrawer::fill(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, int solidcolor) void TriangleDrawer::fill(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, int solidcolor)
{ {
if (r_swtruecolor) if (r_swtruecolor)
queue_arrays(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor); queue_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor);
else else
draw_arrays(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor, nullptr, &ScreenTriangleDrawer::fill); draw_arrays(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, cliptop, clipbottom, nullptr, 0, 0, solidcolor, nullptr, &ScreenTriangleDrawer::fill);
} }
void TriangleDrawer::queue_arrays(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor) void TriangleDrawer::queue_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor)
{ {
if (clipright < clipleft || clipleft < 0 || clipright > MAXWIDTH) if (clipright < clipleft || clipleft < 0 || clipright > MAXWIDTH)
return; return;
@ -72,10 +72,10 @@ void TriangleDrawer::queue_arrays(const TriMatrix &objectToClip, const TriVertex
for (int i = 0; i < cliplength; i++) for (int i = 0; i < cliplength; i++)
clipdata[cliplength + i] = clipbottom[clipleft + i]; clipdata[cliplength + i] = clipbottom[clipleft + i];
DrawerCommandQueue::QueueCommand<DrawTrianglesCommand>(objectToClip, vinput, vcount, mode, ccw, clipleft, clipright, clipdata, texturePixels, textureWidth, textureHeight, solidcolor); DrawerCommandQueue::QueueCommand<DrawTrianglesCommand>(uniforms, vinput, vcount, mode, ccw, clipleft, clipright, clipdata, texturePixels, textureWidth, textureHeight, solidcolor);
} }
void TriangleDrawer::draw_arrays(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *)) void TriangleDrawer::draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *))
{ {
if (vcount < 3) if (vcount < 3)
return; return;
@ -91,6 +91,7 @@ void TriangleDrawer::draw_arrays(const TriMatrix &objectToClip, const TriVertex
args.textureWidth = textureWidth; args.textureWidth = textureWidth;
args.textureHeight = textureHeight; args.textureHeight = textureHeight;
args.solidcolor = solidcolor; args.solidcolor = solidcolor;
args.uniforms = &uniforms;
TriVertex vert[3]; TriVertex vert[3];
if (mode == TriangleDrawMode::Normal) if (mode == TriangleDrawMode::Normal)
@ -98,28 +99,28 @@ void TriangleDrawer::draw_arrays(const TriMatrix &objectToClip, const TriVertex
for (int i = 0; i < vcount / 3; i++) for (int i = 0; i < vcount / 3; i++)
{ {
for (int j = 0; j < 3; j++) for (int j = 0; j < 3; j++)
vert[j] = shade_vertex(objectToClip, *(vinput++)); vert[j] = shade_vertex(uniforms, *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc);
} }
} }
else if (mode == TriangleDrawMode::Fan) else if (mode == TriangleDrawMode::Fan)
{ {
vert[0] = shade_vertex(objectToClip, *(vinput++)); vert[0] = shade_vertex(uniforms, *(vinput++));
vert[1] = shade_vertex(objectToClip, *(vinput++)); vert[1] = shade_vertex(uniforms, *(vinput++));
for (int i = 2; i < vcount; i++) for (int i = 2; i < vcount; i++)
{ {
vert[2] = shade_vertex(objectToClip, *(vinput++)); vert[2] = shade_vertex(uniforms, *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc);
vert[1] = vert[2]; vert[1] = vert[2];
} }
} }
else // TriangleDrawMode::Strip else // TriangleDrawMode::Strip
{ {
vert[0] = shade_vertex(objectToClip, *(vinput++)); vert[0] = shade_vertex(uniforms, *(vinput++));
vert[1] = shade_vertex(objectToClip, *(vinput++)); vert[1] = shade_vertex(uniforms, *(vinput++));
for (int i = 2; i < vcount; i++) for (int i = 2; i < vcount; i++)
{ {
vert[2] = shade_vertex(objectToClip, *(vinput++)); vert[2] = shade_vertex(uniforms, *(vinput++));
draw_shaded_triangle(vert, ccw, &args, thread, drawfunc); draw_shaded_triangle(vert, ccw, &args, thread, drawfunc);
vert[0] = vert[1]; vert[0] = vert[1];
vert[1] = vert[2]; vert[1] = vert[2];
@ -128,10 +129,10 @@ void TriangleDrawer::draw_arrays(const TriMatrix &objectToClip, const TriVertex
} }
} }
TriVertex TriangleDrawer::shade_vertex(const TriMatrix &objectToClip, TriVertex v) TriVertex TriangleDrawer::shade_vertex(const TriUniforms &uniforms, TriVertex v)
{ {
// Apply transform to get clip coordinates: // Apply transform to get clip coordinates:
return objectToClip * v; return uniforms.objectToClip * v;
} }
void TriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, ScreenTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *)) void TriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, ScreenTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *))
@ -412,7 +413,6 @@ void ScreenTriangleDrawer::draw(const ScreenTriangleDrawerArgs *args, DrawerThre
{ {
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
//uint32_t light = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f);
uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16; uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
@ -454,7 +454,6 @@ void ScreenTriangleDrawer::draw(const ScreenTriangleDrawerArgs *args, DrawerThre
{ {
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
//uint32_t light = (uint32_t)clamp(varying[2] * 255.0f + 0.5f, 0.0f, 255.0f);
uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16; uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
@ -666,6 +665,7 @@ void ScreenTriangleDrawer::draw32(const ScreenTriangleDrawerArgs *args, DrawerTh
const uint32_t *texturePixels = (const uint32_t *)args->texturePixels; const uint32_t *texturePixels = (const uint32_t *)args->texturePixels;
int textureWidth = args->textureWidth; int textureWidth = args->textureWidth;
int textureHeight = args->textureHeight; int textureHeight = args->textureHeight;
uint32_t light = args->uniforms->light;
// 28.4 fixed-point coordinates // 28.4 fixed-point coordinates
const int Y1 = (int)round(16.0f * v1.y); const int Y1 = (int)round(16.0f * v1.y);
@ -821,7 +821,6 @@ void ScreenTriangleDrawer::draw32(const ScreenTriangleDrawerArgs *args, DrawerTh
{ {
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
uint32_t light = (uint32_t)clamp(varying[2] * 256.0f + 0.5f, 0.0f, 256.0f);
uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16; uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
@ -873,7 +872,6 @@ void ScreenTriangleDrawer::draw32(const ScreenTriangleDrawerArgs *args, DrawerTh
{ {
uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL); uint32_t ufrac = (uint32_t)((varying[0] - floor(varying[0])) * 0x100000000LL);
uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL); uint32_t vfrac = (uint32_t)((varying[1] - floor(varying[1])) * 0x100000000LL);
uint32_t light = (uint32_t)clamp(varying[2] * 256.0f + 0.5f, 0.0f, 256.0f);
uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16; uint32_t upos = ((ufrac >> 16) * textureWidth) >> 16;
uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16; uint32_t vpos = ((vfrac >> 16) * textureHeight) >> 16;
@ -1248,8 +1246,8 @@ TriVertex TriMatrix::operator*(TriVertex v) const
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
DrawTrianglesCommand::DrawTrianglesCommand(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *clipdata, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor) DrawTrianglesCommand::DrawTrianglesCommand(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *clipdata, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor)
: objectToClip(objectToClip), vinput(vinput), vcount(vcount), mode(mode), ccw(ccw), clipleft(clipleft), clipright(clipright), clipdata(clipdata), texturePixels(texturePixels), textureWidth(textureWidth), textureHeight(textureHeight), solidcolor(solidcolor) : uniforms(uniforms), vinput(vinput), vcount(vcount), mode(mode), ccw(ccw), clipleft(clipleft), clipright(clipright), clipdata(clipdata), texturePixels(texturePixels), textureWidth(textureWidth), textureHeight(textureHeight), solidcolor(solidcolor)
{ {
} }
@ -1263,7 +1261,7 @@ void DrawTrianglesCommand::Execute(DrawerThread *thread)
} }
TriangleDrawer::draw_arrays( TriangleDrawer::draw_arrays(
objectToClip, vinput, vcount, mode, ccw, uniforms, vinput, vcount, mode, ccw,
clipleft, clipright, thread->triangle_clip_top, thread->triangle_clip_bottom, clipleft, clipright, thread->triangle_clip_top, thread->triangle_clip_bottom,
texturePixels, textureWidth, textureHeight, solidcolor, texturePixels, textureWidth, textureHeight, solidcolor,
thread, texturePixels ? ScreenTriangleDrawer::draw32 : ScreenTriangleDrawer::fill32); thread, texturePixels ? ScreenTriangleDrawer::draw32 : ScreenTriangleDrawer::fill32);

View file

@ -33,9 +33,9 @@ struct ScreenTriangleDrawerArgs;
struct TriVertex struct TriVertex
{ {
TriVertex() { } TriVertex() { }
TriVertex(float x, float y, float z, float w, float u, float v, float light) : x(x), y(y), z(z), w(w) { varying[0] = u; varying[1] = v; varying[2] = light; } TriVertex(float x, float y, float z, float w, float u, float v) : x(x), y(y), z(z), w(w) { varying[0] = u; varying[1] = v; }
enum { NumVarying = 3 }; enum { NumVarying = 2 };
float x, y, z, w; float x, y, z, w;
float varying[NumVarying]; float varying[NumVarying];
}; };
@ -60,6 +60,30 @@ struct TriMatrix
float matrix[16]; float matrix[16];
}; };
struct TriUniforms
{
uint32_t light;
uint16_t light_alpha;
uint16_t light_red;
uint16_t light_green;
uint16_t light_blue;
uint16_t fade_alpha;
uint16_t fade_red;
uint16_t fade_green;
uint16_t fade_blue;
uint16_t desaturate;
uint32_t flags;
enum Flags
{
simple_shade = 1,
nearest_filter = 2,
diminishing_lighting = 4
};
TriMatrix objectToClip;
};
enum class TriangleDrawMode enum class TriangleDrawMode
{ {
Normal, Normal,
@ -70,17 +94,17 @@ enum class TriangleDrawMode
class TriangleDrawer class TriangleDrawer
{ {
public: public:
static void draw(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, FTexture *texture); static void draw(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, FTexture *texture);
static void fill(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, int solidcolor); static void fill(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, int solidcolor);
private: private:
static TriVertex shade_vertex(const TriMatrix &objectToClip, TriVertex v); static TriVertex shade_vertex(const TriUniforms &uniforms, TriVertex v);
static void draw_arrays(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *)); static void draw_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *));
static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, ScreenTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *)); static void draw_shaded_triangle(const TriVertex *vertices, bool ccw, ScreenTriangleDrawerArgs *args, DrawerThread *thread, void(*drawfunc)(const ScreenTriangleDrawerArgs *, DrawerThread *));
static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2); static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2);
static void clipedge(const TriVertex &v1, const TriVertex &v2, TriVertex *clippedvert, int &numclipvert); static void clipedge(const TriVertex &v1, const TriVertex &v2, TriVertex *clippedvert, int &numclipvert);
static void queue_arrays(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor); static void queue_arrays(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *cliptop, const short *clipbottom, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor);
friend class DrawTrianglesCommand; friend class DrawTrianglesCommand;
}; };
@ -100,6 +124,7 @@ struct ScreenTriangleDrawerArgs
int textureWidth; int textureWidth;
int textureHeight; int textureHeight;
int solidcolor; int solidcolor;
const TriUniforms *uniforms;
}; };
class ScreenTriangleDrawer class ScreenTriangleDrawer
@ -119,13 +144,13 @@ private:
class DrawTrianglesCommand : public DrawerCommand class DrawTrianglesCommand : public DrawerCommand
{ {
public: public:
DrawTrianglesCommand(const TriMatrix &objectToClip, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *clipdata, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor); DrawTrianglesCommand(const TriUniforms &uniforms, const TriVertex *vinput, int vcount, TriangleDrawMode mode, bool ccw, int clipleft, int clipright, const short *clipdata, const uint8_t *texturePixels, int textureWidth, int textureHeight, int solidcolor);
void Execute(DrawerThread *thread) override; void Execute(DrawerThread *thread) override;
FString DebugInfo() override; FString DebugInfo() override;
private: private:
TriMatrix objectToClip; const TriUniforms uniforms;
const TriVertex *vinput; const TriVertex *vinput;
int vcount; int vcount;
TriangleDrawMode mode; TriangleDrawMode mode;