mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 15:22:16 +00:00
Add support for specifying a viewport out of screen bounds and fixed statusbar by doing just that!
This commit is contained in:
parent
bac3ae3bf8
commit
dbb6c7ca27
11 changed files with 68 additions and 68 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue