Add support for specifying a viewport out of screen bounds and fixed statusbar by doing just that!

This commit is contained in:
Magnus Norddahl 2016-11-18 01:58:39 +01:00
parent bac3ae3bf8
commit dbb6c7ca27
11 changed files with 68 additions and 68 deletions

View file

@ -78,10 +78,10 @@ void DrawTriangleCodegen::Setup(TriDrawVariant variant, bool truecolor)
FDY31 = DY31 << 4;
// Bounding rectangle
minx = SSAInt::MAX((SSAInt::MIN(SSAInt::MIN(X1, X2), X3) + 0xF) >> 4, clipleft);
maxx = SSAInt::MIN((SSAInt::MAX(SSAInt::MAX(X1, X2), X3) + 0xF) >> 4, clipright - 1);
miny = SSAInt::MAX((SSAInt::MIN(SSAInt::MIN(Y1, Y2), Y3) + 0xF) >> 4, cliptop);
maxy = SSAInt::MIN((SSAInt::MAX(SSAInt::MAX(Y1, Y2), Y3) + 0xF) >> 4, clipbottom - 1);
minx = SSAInt::MAX((SSAInt::MIN(SSAInt::MIN(X1, X2), X3) + 0xF).ashr(4), clipleft);
maxx = SSAInt::MIN((SSAInt::MAX(SSAInt::MAX(X1, X2), X3) + 0xF).ashr(4), clipright - 1);
miny = SSAInt::MAX((SSAInt::MIN(SSAInt::MIN(Y1, Y2), Y3) + 0xF).ashr(4), cliptop);
maxy = SSAInt::MIN((SSAInt::MAX(SSAInt::MAX(Y1, Y2), Y3) + 0xF).ashr(4), clipbottom - 1);
SSAIfBlock if0;
if0.if_block(minx >= maxx || miny >= maxy);
@ -221,7 +221,7 @@ void DrawTriangleCodegen::LoopBlockX(TriDrawVariant variant, bool truecolor)
branch.if_block(!(a == SSAInt(0) || b == SSAInt(0) || c == SSAInt(0)));
// Check if block needs clipping
SSABool clipneeded = clipleft > x || clipright < (x + q) || cliptop > y || clipbottom < (y + q);
SSABool clipneeded = x < clipleft || (x + q) > clipright || y < cliptop || (y + q) > clipbottom;
// Calculate varying variables for affine block
SSAFloat offx0 = SSAFloat(x - minx);
@ -401,7 +401,7 @@ void DrawTriangleCodegen::LoopPartialBlock(TriDrawVariant variant, bool truecolo
varying[i] = stack_varying[i].load();
loopx.loop_block(ix < SSAInt(q), q);
{
SSABool visible = (ix + x >= clipleft) && (ix + x < clipright) && (cliptop <= y + iy) && (clipbottom > y + iy);
SSABool visible = (ix + x >= clipleft) && (ix + x < clipright) && (iy + y >= cliptop) && (iy + y < clipbottom);
SSABool covered = CX1 > SSAInt(0) && CX2 > SSAInt(0) && CX3 > SSAInt(0) && visible;
if (variant == TriDrawVariant::DrawSubsector || variant == TriDrawVariant::DrawShadedSubsector || variant == TriDrawVariant::FillSubsector)
@ -589,9 +589,9 @@ void DrawTriangleCodegen::LoadArgs(TriDrawVariant variant, bool truecolor, SSAVa
v1 = LoadTriVertex(args[0][2].load(true));
v2 = LoadTriVertex(args[0][3].load(true));
v3 = LoadTriVertex(args[0][4].load(true));
clipleft = args[0][5].load(true);
clipleft = SSAInt(0);// args[0][5].load(true);
clipright = args[0][6].load(true);
cliptop = args[0][7].load(true);
cliptop = SSAInt(0);// args[0][7].load(true);
clipbottom = args[0][8].load(true);
texturePixels = args[0][9].load(true);
textureWidth = args[0][10].load(true);

View file

@ -62,8 +62,8 @@ void RenderPolyScene::ClearBuffers()
SectorSpriteRanges.resize(numsectors);
SortedSprites.clear();
TranslucentObjects.clear();
PolyStencilBuffer::Instance()->Clear(viewwidth, viewheight, 0);
PolySubsectorGBuffer::Instance()->Resize(dc_pitch, viewheight);
PolyStencilBuffer::Instance()->Clear(screen->GetWidth(), screen->GetHeight(), 0);
PolySubsectorGBuffer::Instance()->Resize(screen->GetPitch(), screen->GetHeight());
NextSubsectorDepth = 0;
}
@ -79,14 +79,12 @@ void RenderPolyScene::SetupPerspectiveMatrix()
int height;
if (screenblocks >= 10)
{
height = SCREENHEIGHT;
}
else
{
height = (screenblocks*SCREENHEIGHT / 10) & ~7;
}
viewheight = height; // So viewheight was calculated incorrectly. That's just.. wonderful.
int bottom = SCREENHEIGHT - (height + viewwindowy - ((height - viewheight) / 2));
PolyTriangleDrawer::set_viewport(viewwindowx, SCREENHEIGHT - bottom - height, viewwidth, height, screen);
// Code provided courtesy of Graf Zahl. Now we just have to plug it into the viewmatrix code...
// We have to scale the pitch to account for the pixel stretching, because the playsim doesn't know about this and treats it as 1:1.
@ -105,6 +103,7 @@ void RenderPolyScene::SetupPerspectiveMatrix()
TriMatrix::scale(1.0f, glset.pixelstretch, 1.0f) *
TriMatrix::swapYZ() *
TriMatrix::translate((float)-ViewPos.X, (float)-ViewPos.Y, (float)-ViewPos.Z);
WorldToClip = TriMatrix::perspective(fovy, ratio, 5.0f, 65535.0f) * worldToView;
}

View file

@ -148,10 +148,6 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, DBaseDecal *decal, co
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.SetTexture(tex);

View file

@ -92,10 +92,6 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, particle_t *partic
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);

View file

@ -137,10 +137,6 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, subsector_t *s
args.vcount = sub->numlines;
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.SetTexture(tex);
@ -233,10 +229,6 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, subsector_t *sub, uin
args.vcount = sub->numlines;
args.mode = TriangleDrawMode::Fan;
args.ccw = ccw;
args.clipleft = 0;
args.cliptop = 0;
args.clipright = viewwidth;
args.clipbottom = viewheight;
args.stenciltestvalue = 0;
args.stencilwritevalue = 1;

View file

@ -59,10 +59,6 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
PolyDrawArgs args;
args.uniforms = uniforms;
args.clipleft = 0;
args.cliptop = 0;
args.clipright = viewwidth;
args.clipbottom = viewheight;
args.stenciltestvalue = 255;
args.stencilwritevalue = 1;
args.SetTexture(frontskytex);

View file

@ -133,10 +133,6 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, AActor *thing, subse
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.SetTexture(tex);

View file

@ -40,9 +40,41 @@
#include <immintrin.h>
#endif
int PolyTriangleDrawer::viewport_x;
int PolyTriangleDrawer::viewport_y;
int PolyTriangleDrawer::viewport_width;
int PolyTriangleDrawer::viewport_height;
int PolyTriangleDrawer::dest_pitch;
int PolyTriangleDrawer::dest_width;
int PolyTriangleDrawer::dest_height;
uint8_t *PolyTriangleDrawer::dest;
bool PolyTriangleDrawer::dest_bgra;
void PolyTriangleDrawer::set_viewport(int x, int y, int width, int height, DCanvas *canvas)
{
dest = (uint8_t*)canvas->GetBuffer();
dest_width = canvas->GetWidth();
dest_height = canvas->GetHeight();
dest_pitch = canvas->GetPitch();
dest_bgra = canvas->IsBgra();
int offsetx = clamp(x, 0, dest_width);
int offsety = clamp(y, 0, dest_height);
int pixelsize = dest_bgra ? 4 : 1;
viewport_x = x - offsetx;
viewport_y = y - offsety;
viewport_width = width;
viewport_height = height;
dest += (offsetx + offsety * dest_pitch) * pixelsize;
dest_width = clamp(viewport_x + viewport_width, 0, dest_width - offsetx);
dest_height = clamp(viewport_y + viewport_height, 0, dest_height - offsety);
}
void PolyTriangleDrawer::draw(const PolyDrawArgs &args, TriDrawVariant variant)
{
if (r_swtruecolor)
if (dest_bgra)
DrawerCommandQueue::QueueCommand<DrawPolyTrianglesCommand>(args, variant);
else
draw_arrays(args, variant, nullptr);
@ -59,33 +91,33 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, TriDrawVarian
switch (variant)
{
default:
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::DrawShadedSubsector: drawfunc = r_swtruecolor ? llvm->TriDrawShadedSubsector32 : llvm->TriDrawShadedSubsector8; break;
case TriDrawVariant::FillSubsector: drawfunc = r_swtruecolor ? llvm->TriFillSubsector32 : llvm->TriFillSubsector8; break;
case TriDrawVariant::Draw: drawfunc = dest_bgra ? llvm->TriDraw32: llvm->TriDraw8; break;
case TriDrawVariant::Fill: drawfunc = dest_bgra ? llvm->TriFill32 : llvm->TriFill8; break;
case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? llvm->TriDrawSubsector32 : llvm->TriDrawSubsector8; break;
case TriDrawVariant::DrawShadedSubsector: drawfunc = dest_bgra ? llvm->TriDrawShadedSubsector32 : llvm->TriDrawShadedSubsector8; break;
case TriDrawVariant::FillSubsector: drawfunc = dest_bgra ? llvm->TriFillSubsector32 : llvm->TriFillSubsector8; break;
case TriDrawVariant::Stencil: drawfunc = llvm->TriStencil; break;
}
#else
switch (variant)
{
default:
case TriDrawVariant::Draw: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::draw; break;
case TriDrawVariant::Draw: drawfunc = dest_bgra ? ScreenPolyTriangleDrawer::draw32 : ScreenPolyTriangleDrawer::draw; break;
case TriDrawVariant::FillSubsector:
case TriDrawVariant::Fill: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::fill32 : ScreenPolyTriangleDrawer::fill; break;
case TriDrawVariant::Fill: drawfunc = dest_bgra ? ScreenPolyTriangleDrawer::fill32 : ScreenPolyTriangleDrawer::fill; break;
case TriDrawVariant::DrawShadedSubsector:
case TriDrawVariant::DrawSubsector: drawfunc = r_swtruecolor ? ScreenPolyTriangleDrawer::drawsubsector32 : llvm->TriDrawSubsector8; break;
case TriDrawVariant::DrawSubsector: drawfunc = dest_bgra ? ScreenPolyTriangleDrawer::drawsubsector32 : llvm->TriDrawSubsector8; break;
case TriDrawVariant::Stencil: drawfunc = ScreenPolyTriangleDrawer::stencil; break;
}
#endif
TriDrawTriangleArgs args;
args.dest = dc_destorg;
args.pitch = dc_pitch;
args.clipleft = drawargs.clipleft;
args.clipright = drawargs.clipright;
args.cliptop = drawargs.cliptop;
args.clipbottom = drawargs.clipbottom;
args.dest = dest;
args.pitch = dest_pitch;
args.clipleft = 0;
args.clipright = dest_width;
args.cliptop = 0;
args.clipbottom = dest_height;
args.texturePixels = drawargs.texturePixels;
args.textureWidth = drawargs.textureWidth;
args.textureHeight = drawargs.textureHeight;
@ -163,8 +195,8 @@ void PolyTriangleDrawer::draw_shaded_triangle(const TriVertex *vert, bool ccw, T
v.z *= v.w;
// Apply viewport scale to get screen coordinates:
v.x = viewwidth * (1.0f + v.x) * 0.5f;
v.y = viewheight * (1.0f - v.y) * 0.5f;
v.x = viewport_x + viewport_width * (1.0f + v.x) * 0.5f;
v.y = viewport_y + viewport_height * (1.0f - v.y) * 0.5f;
}
// Draw screen triangles

View file

@ -36,10 +36,6 @@ public:
int vcount = 0;
TriangleDrawMode mode = TriangleDrawMode::Normal;
bool ccw = false;
int clipleft = 0;
int clipright = 0;
int cliptop = 0;
int clipbottom = 0;
const uint8_t *texturePixels = nullptr;
int textureWidth = 0;
int textureHeight = 0;
@ -61,6 +57,7 @@ public:
class PolyTriangleDrawer
{
public:
static void set_viewport(int x, int y, int width, int height, DCanvas *canvas);
static void draw(const PolyDrawArgs &args, TriDrawVariant variant);
private:
@ -70,6 +67,10 @@ private:
static bool cullhalfspace(float clipdistance1, float clipdistance2, float &t1, float &t2);
static void clipedge(const TriVertex *verts, TriVertex *clippedvert, int &numclipvert);
static int viewport_x, viewport_y, viewport_width, viewport_height, dest_pitch, dest_width, dest_height;
static bool dest_bgra;
static uint8_t *dest;
enum { max_additional_vertices = 16 };
friend class DrawPolyTrianglesCommand;

View file

@ -187,10 +187,6 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip)
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.SetTexture(tex);

View file

@ -118,10 +118,6 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, AActor *thing, s
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.SetTexture(tex);