take all edge cases into account for XMin/XMax calculation
This commit is contained in:
parent
2b52b45f66
commit
e3495011bf
|
@ -307,7 +307,7 @@ void ComputeRenderer::SetupAttrs(SpanSetupY* span, Polygon* poly, int from, int
|
||||||
span->TexcoordV1 = poly->Vertices[to]->TexCoords[1];
|
span->TexcoordV1 = poly->Vertices[to]->TexCoords[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeRenderer::SetupYSpanDummy(SpanSetupY* span, Polygon* poly, int vertex, int side, s32 positions[10][2])
|
void ComputeRenderer::SetupYSpanDummy(RenderPolygon* rp, SpanSetupY* span, Polygon* poly, int vertex, int side, s32 positions[10][2])
|
||||||
{
|
{
|
||||||
s32 x0 = positions[vertex][0];
|
s32 x0 = positions[vertex][0];
|
||||||
if (side)
|
if (side)
|
||||||
|
@ -325,6 +325,17 @@ void ComputeRenderer::SetupYSpanDummy(SpanSetupY* span, Polygon* poly, int verte
|
||||||
span->XMax = x0;
|
span->XMax = x0;
|
||||||
span->Y0 = span->Y1 = positions[vertex][1];
|
span->Y0 = span->Y1 = positions[vertex][1];
|
||||||
|
|
||||||
|
if (span->XMin < rp->XMin)
|
||||||
|
{
|
||||||
|
rp->XMin = span->XMin;
|
||||||
|
rp->XMinY = span->Y0;
|
||||||
|
}
|
||||||
|
if (span->XMax > rp->XMax)
|
||||||
|
{
|
||||||
|
rp->XMax = span->XMax;
|
||||||
|
rp->XMaxY = span->Y0;
|
||||||
|
}
|
||||||
|
|
||||||
span->Increment = 0;
|
span->Increment = 0;
|
||||||
|
|
||||||
span->I0 = span->I1 = span->IRecip = 0;
|
span->I0 = span->I1 = span->IRecip = 0;
|
||||||
|
@ -337,7 +348,7 @@ void ComputeRenderer::SetupYSpanDummy(SpanSetupY* span, Polygon* poly, int verte
|
||||||
SetupAttrs(span, poly, vertex, vertex);
|
SetupAttrs(span, poly, vertex, vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeRenderer::SetupYSpan(int polynum, SpanSetupY* span, Polygon* poly, int from, int to, u32 y, int side, s32 positions[10][2])
|
void ComputeRenderer::SetupYSpan(RenderPolygon* rp, SpanSetupY* span, Polygon* poly, int from, int to, int side, s32 positions[10][2])
|
||||||
{
|
{
|
||||||
span->X0 = positions[from][0];
|
span->X0 = positions[from][0];
|
||||||
span->X1 = positions[to][0];
|
span->X1 = positions[to][0];
|
||||||
|
@ -346,23 +357,45 @@ void ComputeRenderer::SetupYSpan(int polynum, SpanSetupY* span, Polygon* poly, i
|
||||||
|
|
||||||
SetupAttrs(span, poly, from, to);
|
SetupAttrs(span, poly, from, to);
|
||||||
|
|
||||||
|
s32 minXY, maxXY;
|
||||||
bool negative = false;
|
bool negative = false;
|
||||||
if (span->X1 > span->X0)
|
if (span->X1 > span->X0)
|
||||||
{
|
{
|
||||||
span->XMin = span->X0;
|
span->XMin = span->X0;
|
||||||
span->XMax = span->X1-1;
|
span->XMax = span->X1-1;
|
||||||
|
|
||||||
|
minXY = span->Y0;
|
||||||
|
maxXY = span->Y1;
|
||||||
}
|
}
|
||||||
else if (span->X1 < span->X0)
|
else if (span->X1 < span->X0)
|
||||||
{
|
{
|
||||||
span->XMin = span->X1;
|
span->XMin = span->X1;
|
||||||
span->XMax = span->X0-1;
|
span->XMax = span->X0-1;
|
||||||
negative = true;
|
negative = true;
|
||||||
|
|
||||||
|
minXY = span->Y1;
|
||||||
|
maxXY = span->Y0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
span->XMin = span->X0;
|
span->XMin = span->X0;
|
||||||
if (side) span->XMin--;
|
if (side) span->XMin--;
|
||||||
span->XMax = span->XMin;
|
span->XMax = span->XMin;
|
||||||
|
|
||||||
|
// doesn't matter for completely vertical slope
|
||||||
|
minXY = span->Y0;
|
||||||
|
maxXY = span->Y0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (span->XMin < rp->XMin)
|
||||||
|
{
|
||||||
|
rp->XMin = span->XMin;
|
||||||
|
rp->XMinY = minXY;
|
||||||
|
}
|
||||||
|
if (span->XMax > rp->XMax)
|
||||||
|
{
|
||||||
|
rp->XMax = span->XMax;
|
||||||
|
rp->XMaxY = maxXY;
|
||||||
}
|
}
|
||||||
|
|
||||||
span->IsDummy = false;
|
span->IsDummy = false;
|
||||||
|
@ -1072,18 +1105,15 @@ void ComputeRenderer::RenderFrame()
|
||||||
s32 ytop = ScreenHeight, ybot = 0;
|
s32 ytop = ScreenHeight, ybot = 0;
|
||||||
for (int i = 0; i < polygon->NumVertices; i++)
|
for (int i = 0; i < polygon->NumVertices; i++)
|
||||||
{
|
{
|
||||||
scaledPositions[i][0] = (polygon->Vertices[i]->HiresPosition[0] * ScaleFactor) >> 4;
|
scaledPositions[i][0] = (polygon->Vertices[i]->FinalPosition[0] * ScaleFactor);
|
||||||
scaledPositions[i][1] = (polygon->Vertices[i]->HiresPosition[1] * ScaleFactor) >> 4;
|
scaledPositions[i][1] = (polygon->Vertices[i]->FinalPosition[1] * ScaleFactor);
|
||||||
ytop = std::min(scaledPositions[i][1], ytop);
|
ytop = std::min(scaledPositions[i][1], ytop);
|
||||||
ybot = std::max(scaledPositions[i][1], ybot);
|
ybot = std::max(scaledPositions[i][1], ybot);
|
||||||
}
|
}
|
||||||
RenderPolygons[i].YTop = ytop;
|
RenderPolygons[i].YTop = ytop;
|
||||||
RenderPolygons[i].YBot = ybot;
|
RenderPolygons[i].YBot = ybot;
|
||||||
|
RenderPolygons[i].XMin = ScreenWidth;
|
||||||
s32 minX = scaledPositions[vtop][0];
|
RenderPolygons[i].XMax = 0;
|
||||||
s32 minXY = scaledPositions[vtop][1];
|
|
||||||
s32 maxX = scaledPositions[vtop][0];
|
|
||||||
s32 maxXY = scaledPositions[vtop][1];
|
|
||||||
|
|
||||||
if (ybot == ytop)
|
if (ybot == ytop)
|
||||||
{
|
{
|
||||||
|
@ -1101,20 +1131,10 @@ void ComputeRenderer::RenderFrame()
|
||||||
|
|
||||||
assert(numYSpans < MaxYSpanSetups);
|
assert(numYSpans < MaxYSpanSetups);
|
||||||
u32 curSpanL = numYSpans;
|
u32 curSpanL = numYSpans;
|
||||||
SetupYSpanDummy(&YSpanSetups[numYSpans++], polygon, vtop, 0, scaledPositions);
|
SetupYSpanDummy(&RenderPolygons[i], &YSpanSetups[numYSpans++], polygon, vtop, 0, scaledPositions);
|
||||||
assert(numYSpans < MaxYSpanSetups);
|
assert(numYSpans < MaxYSpanSetups);
|
||||||
u32 curSpanR = numYSpans;
|
u32 curSpanR = numYSpans;
|
||||||
SetupYSpanDummy(&YSpanSetups[numYSpans++], polygon, vbot, 1, scaledPositions);
|
SetupYSpanDummy(&RenderPolygons[i], &YSpanSetups[numYSpans++], polygon, vbot, 1, scaledPositions);
|
||||||
|
|
||||||
minX = YSpanSetups[curSpanL].X0;
|
|
||||||
minXY = YSpanSetups[curSpanL].Y0;
|
|
||||||
maxX = YSpanSetups[curSpanR].X0;
|
|
||||||
maxXY = YSpanSetups[curSpanR].Y0;
|
|
||||||
if (maxX < minX)
|
|
||||||
{
|
|
||||||
std::swap(minX, maxX);
|
|
||||||
std::swap(minXY, maxXY);
|
|
||||||
}
|
|
||||||
|
|
||||||
YSpanIndices[numSetupIndices].PolyIdx = i;
|
YSpanIndices[numSetupIndices].PolyIdx = i;
|
||||||
YSpanIndices[numSetupIndices].SpanIdxL = curSpanL;
|
YSpanIndices[numSetupIndices].SpanIdxL = curSpanL;
|
||||||
|
@ -1126,10 +1146,10 @@ void ComputeRenderer::RenderFrame()
|
||||||
{
|
{
|
||||||
u32 curSpanL = numYSpans;
|
u32 curSpanL = numYSpans;
|
||||||
assert(numYSpans < MaxYSpanSetups);
|
assert(numYSpans < MaxYSpanSetups);
|
||||||
SetupYSpan(i, &YSpanSetups[numYSpans++], polygon, curVL, nextVL, ytop, 0, scaledPositions);
|
SetupYSpan(&RenderPolygons[i], &YSpanSetups[numYSpans++], polygon, curVL, nextVL, 0, scaledPositions);
|
||||||
u32 curSpanR = numYSpans;
|
u32 curSpanR = numYSpans;
|
||||||
assert(numYSpans < MaxYSpanSetups);
|
assert(numYSpans < MaxYSpanSetups);
|
||||||
SetupYSpan(i, &YSpanSetups[numYSpans++], polygon, curVR, nextVR, ytop, 1, scaledPositions);
|
SetupYSpan(&RenderPolygons[i], &YSpanSetups[numYSpans++], polygon, curVR, nextVR, 1, scaledPositions);
|
||||||
|
|
||||||
for (u32 y = ytop; y < ybot; y++)
|
for (u32 y = ytop; y < ybot; y++)
|
||||||
{
|
{
|
||||||
|
@ -1152,20 +1172,10 @@ void ComputeRenderer::RenderFrame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scaledPositions[curVL][0] < minX)
|
|
||||||
{
|
|
||||||
minX = scaledPositions[curVL][0];
|
|
||||||
minXY = scaledPositions[curVL][1];
|
|
||||||
}
|
|
||||||
if (scaledPositions[curVL][0] > maxX)
|
|
||||||
{
|
|
||||||
maxX = scaledPositions[curVL][0];
|
|
||||||
maxXY = scaledPositions[curVL][1];
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(numYSpans < MaxYSpanSetups);
|
assert(numYSpans < MaxYSpanSetups);
|
||||||
curSpanL = numYSpans;
|
curSpanL = numYSpans;
|
||||||
SetupYSpan(i,&YSpanSetups[numYSpans++], polygon, curVL, nextVL, y, 0, scaledPositions);
|
SetupYSpan(&RenderPolygons[i], &YSpanSetups[numYSpans++], polygon, curVL, nextVL, 0, scaledPositions);
|
||||||
}
|
}
|
||||||
if (y >= scaledPositions[nextVR][1] && curVR != polygon->VBottom)
|
if (y >= scaledPositions[nextVR][1] && curVR != polygon->VBottom)
|
||||||
{
|
{
|
||||||
|
@ -1186,20 +1196,9 @@ void ComputeRenderer::RenderFrame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scaledPositions[curVR][0] < minX)
|
|
||||||
{
|
|
||||||
minX = scaledPositions[curVR][0];
|
|
||||||
minXY = scaledPositions[curVR][1];
|
|
||||||
}
|
|
||||||
if (scaledPositions[curVR][0] > maxX)
|
|
||||||
{
|
|
||||||
maxX = scaledPositions[curVR][0];
|
|
||||||
maxXY = scaledPositions[curVR][1];
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(numYSpans < MaxYSpanSetups);
|
assert(numYSpans < MaxYSpanSetups);
|
||||||
curSpanR = numYSpans;
|
curSpanR = numYSpans;
|
||||||
SetupYSpan(i,&YSpanSetups[numYSpans++], polygon, curVR, nextVR, y, 1, scaledPositions);
|
SetupYSpan(&RenderPolygons[i] ,&YSpanSetups[numYSpans++], polygon, curVR, nextVR, 1, scaledPositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
YSpanIndices[numSetupIndices].PolyIdx = i;
|
YSpanIndices[numSetupIndices].PolyIdx = i;
|
||||||
|
@ -1210,32 +1209,6 @@ void ComputeRenderer::RenderFrame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scaledPositions[nextVL][0] < minX)
|
|
||||||
{
|
|
||||||
minX = scaledPositions[nextVL][0];
|
|
||||||
minXY = scaledPositions[nextVL][1];
|
|
||||||
}
|
|
||||||
if (scaledPositions[nextVL][0] > maxX)
|
|
||||||
{
|
|
||||||
maxX = scaledPositions[nextVL][0];
|
|
||||||
maxXY = scaledPositions[nextVL][1];
|
|
||||||
}
|
|
||||||
if (scaledPositions[nextVR][0] < minX)
|
|
||||||
{
|
|
||||||
minX = scaledPositions[nextVR][0];
|
|
||||||
minXY = scaledPositions[nextVR][1];
|
|
||||||
}
|
|
||||||
if (scaledPositions[nextVR][0] > maxX)
|
|
||||||
{
|
|
||||||
maxX = scaledPositions[nextVR][0];
|
|
||||||
maxXY = scaledPositions[nextVR][1];
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderPolygons[i].XMin = minX;
|
|
||||||
RenderPolygons[i].XMinY = minXY;
|
|
||||||
RenderPolygons[i].XMax = maxX;
|
|
||||||
RenderPolygons[i].XMaxY = maxXY;
|
|
||||||
|
|
||||||
//printf("polygon min max %d %d | %d %d\n", RenderPolygons[i].XMin, RenderPolygons[i].XMinY, RenderPolygons[i].XMax, RenderPolygons[i].XMaxY);
|
//printf("polygon min max %d %d | %d %d\n", RenderPolygons[i].XMin, RenderPolygons[i].XMinY, RenderPolygons[i].XMax, RenderPolygons[i].XMaxY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -230,8 +230,8 @@ private:
|
||||||
void DeleteShaders();
|
void DeleteShaders();
|
||||||
|
|
||||||
void SetupAttrs(SpanSetupY* span, Polygon* poly, int from, int to);
|
void SetupAttrs(SpanSetupY* span, Polygon* poly, int from, int to);
|
||||||
void SetupYSpan(int polynum, SpanSetupY* span, Polygon* poly, int from, int to, u32 y, int side, s32 positions[10][2]);
|
void SetupYSpan(RenderPolygon* rp, SpanSetupY* span, Polygon* poly, int from, int to, int side, s32 positions[10][2]);
|
||||||
void SetupYSpanDummy(SpanSetupY* span, Polygon* poly, int vertex, int side, s32 positions[10][2]);
|
void SetupYSpanDummy(RenderPolygon* rp, SpanSetupY* span, Polygon* poly, int vertex, int side, s32 positions[10][2]);
|
||||||
|
|
||||||
bool CompileShader(GLuint& shader, const char* source, const std::initializer_list<const char*>& defines);
|
bool CompileShader(GLuint& shader, const char* source, const std::initializer_list<const char*>& defines);
|
||||||
};
|
};
|
||||||
|
|
|
@ -208,6 +208,7 @@ buffer TilesBuffer
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(DepthBlend) || defined(FinalPass)
|
||||||
layout (std430, binding = 5)
|
layout (std430, binding = 5)
|
||||||
#ifdef DepthBlend
|
#ifdef DepthBlend
|
||||||
writeonly
|
writeonly
|
||||||
|
@ -221,6 +222,7 @@ buffer RasterResult
|
||||||
uint DepthResult[ScreenWidth*ScreenHeight*2];
|
uint DepthResult[ScreenWidth*ScreenHeight*2];
|
||||||
uint AttrResult[ScreenWidth*ScreenHeight*2];
|
uint AttrResult[ScreenWidth*ScreenHeight*2];
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
layout (std140, binding = 0) uniform MetaUniform
|
layout (std140, binding = 0) uniform MetaUniform
|
||||||
{
|
{
|
||||||
|
@ -835,6 +837,28 @@ bool BinPolygon(Polygon polygon, ivec2 topLeft, ivec2 botRight)
|
||||||
|
|
||||||
int polygonHeight = polygon.YBot - polygon.YTop;
|
int polygonHeight = polygon.YBot - polygon.YTop;
|
||||||
|
|
||||||
|
/*
|
||||||
|
All (good) polygons are convex. So the following holds true:
|
||||||
|
|
||||||
|
Starting from the top most point where both edges originate
|
||||||
|
the X coordinate of the left edge will stay the same or falls until
|
||||||
|
the minimum X-axis coordinate is reached. Then it stays the same or
|
||||||
|
rises until the point it meets with the right edge.
|
||||||
|
|
||||||
|
The same applies to the right edge, except that it first may rise or stay equal and
|
||||||
|
after the maximum point may only fall or stay the same.
|
||||||
|
|
||||||
|
This means that for every tile which doesn't contain the point where the direction changes
|
||||||
|
we can just get the maximum point by sampling the top most and bottom most coordinate
|
||||||
|
within the tile.
|
||||||
|
|
||||||
|
For a tile which is that the height of the direction change
|
||||||
|
|
||||||
|
As a sidenote another consequence of this design decision is
|
||||||
|
that malformed polygons aren't binned properly.
|
||||||
|
|
||||||
|
As a note bottom Y is exclusive!
|
||||||
|
*/
|
||||||
int polyInnerTopY = clamp(topLeft.y - polygon.YTop, 0, max(polygonHeight-1, 0));
|
int polyInnerTopY = clamp(topLeft.y - polygon.YTop, 0, max(polygonHeight-1, 0));
|
||||||
int polyInnerBotY = clamp(botRight.y - polygon.YTop, 0, max(polygonHeight-1, 0));
|
int polyInnerBotY = clamp(botRight.y - polygon.YTop, 0, max(polygonHeight-1, 0));
|
||||||
|
|
||||||
|
@ -1557,8 +1581,8 @@ void main()
|
||||||
// else
|
// else
|
||||||
// color.x = 0U;
|
// color.x = 0U;
|
||||||
|
|
||||||
//if (gl_LocalInvocationID.x == 7 || gl_LocalInvocationID.y == 7)
|
//if ((gl_GlobalInvocationID.y % 8) == 7 || (gl_GlobalInvocationID.y % 8) == 7)
|
||||||
//color.x = 0x1F00001FU | 0x40000000U;
|
// color.x = 0x1F00001FU | 0x40000000U;
|
||||||
|
|
||||||
vec4 result = vec4(bitfieldExtract(color.x, 16, 8), bitfieldExtract(color.x, 8, 8), color.x & 0x3FU, bitfieldExtract(color.x, 24, 8));
|
vec4 result = vec4(bitfieldExtract(color.x, 16, 8), bitfieldExtract(color.x, 8, 8), color.x & 0x3FU, bitfieldExtract(color.x, 24, 8));
|
||||||
result /= vec4(63.0, 63.0, 63.0, 31.0);
|
result /= vec4(63.0, 63.0, 63.0, 31.0);
|
||||||
|
|
|
@ -24,8 +24,6 @@ using Platform::LogLevel;
|
||||||
namespace OpenGL
|
namespace OpenGL
|
||||||
{
|
{
|
||||||
|
|
||||||
#define checkGLError() if (glGetError() != GL_NO_ERROR) printf("error %d\n", __LINE__)
|
|
||||||
|
|
||||||
bool CompilerShader(GLuint& id, const char* source, const char* name, const char* type)
|
bool CompilerShader(GLuint& id, const char* source, const char* name, const char* type)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
@ -39,12 +37,9 @@ bool CompilerShader(GLuint& id, const char* source, const char* name, const char
|
||||||
|
|
||||||
len = strlen(source);
|
len = strlen(source);
|
||||||
glShaderSource(id, 1, &source, &len);
|
glShaderSource(id, 1, &source, &len);
|
||||||
checkGLError();
|
|
||||||
glCompileShader(id);
|
glCompileShader(id);
|
||||||
checkGLError();
|
|
||||||
|
|
||||||
glGetShaderiv(id, GL_COMPILE_STATUS, &res);
|
glGetShaderiv(id, GL_COMPILE_STATUS, &res);
|
||||||
checkGLError();
|
|
||||||
if (res != GL_TRUE)
|
if (res != GL_TRUE)
|
||||||
{
|
{
|
||||||
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &res);
|
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &res);
|
||||||
|
@ -74,7 +69,6 @@ bool LinkProgram(GLuint& result, GLuint* ids, int numIds)
|
||||||
for (int i = 0; i < numIds; i++)
|
for (int i = 0; i < numIds; i++)
|
||||||
{
|
{
|
||||||
glAttachShader(result, ids[i]);
|
glAttachShader(result, ids[i]);
|
||||||
checkGLError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glLinkProgram(result);
|
glLinkProgram(result);
|
||||||
|
|
Loading…
Reference in New Issue