[mtl canvas] convert triangle rasterization to fixed point
This commit is contained in:
parent
7c58145524
commit
13f025ab21
|
@ -109,28 +109,28 @@ int main()
|
||||||
{
|
{
|
||||||
if(x - 200 > 0)
|
if(x - 200 > 0)
|
||||||
{
|
{
|
||||||
x-=5;
|
x-=0.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(event.key.code == MP_KEY_RIGHT)
|
else if(event.key.code == MP_KEY_RIGHT)
|
||||||
{
|
{
|
||||||
if(x + 200 < contentRect.w)
|
if(x + 200 < contentRect.w)
|
||||||
{
|
{
|
||||||
x+=5;
|
x+=0.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(event.key.code == MP_KEY_UP)
|
else if(event.key.code == MP_KEY_UP)
|
||||||
{
|
{
|
||||||
if(y + 200 < contentRect.h)
|
if(y + 200 < contentRect.h)
|
||||||
{
|
{
|
||||||
y-=5;
|
y-=0.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(event.key.code == MP_KEY_DOWN)
|
else if(event.key.code == MP_KEY_DOWN)
|
||||||
{
|
{
|
||||||
if(y - 200 > 0)
|
if(y - 200 > 0)
|
||||||
{
|
{
|
||||||
y+=5;
|
y+=0.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//*/
|
//*/
|
||||||
|
@ -193,14 +193,14 @@ int main()
|
||||||
mg_set_font(font);
|
mg_set_font(font);
|
||||||
mg_set_font_size(12);
|
mg_set_font_size(12);
|
||||||
mg_move_to(50, 600-50);
|
mg_move_to(50, 600-50);
|
||||||
/*
|
|
||||||
str8 text = str8_pushf(mem_scratch(),
|
str8 text = str8_pushf(mem_scratch(),
|
||||||
"Milepost vector graphics test program (frame time = %fs, fps = %f)...",
|
"Milepost vector graphics test program (frame time = %fs, fps = %f)...",
|
||||||
frameTime,
|
frameTime,
|
||||||
1./frameTime);
|
1./frameTime);
|
||||||
mg_text_outlines(text);
|
mg_text_outlines(text);
|
||||||
mg_fill();
|
mg_fill();
|
||||||
*/
|
|
||||||
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
|
printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n",
|
||||||
frameTime,
|
frameTime,
|
||||||
1./frameTime);
|
1./frameTime);
|
||||||
|
|
|
@ -26,7 +26,6 @@ fragment float4 FragmentShader(vs_out i [[stage_in]], texture2d<float> tex [[tex
|
||||||
return(tex.sample(smp, i.uv));
|
return(tex.sample(smp, i.uv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool is_top_left(float2 a, float2 b)
|
bool is_top_left(float2 a, float2 b)
|
||||||
{
|
{
|
||||||
return( (a.y == b.y && b.x < a.x)
|
return( (a.y == b.y && b.x < a.x)
|
||||||
|
@ -158,17 +157,8 @@ kernel void SortKernel(const device uint* tileCounters [[buffer(0)]],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float orient2d(float2 a, float2 b, float2 c)
|
int orient2d(int2 a, int2 b, int2 c)
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//TODO(martin): FIX this. This is a **horrible** quick hack to fix the precision issues
|
|
||||||
// arising when a, b, and c are close. But it degrades when a, c, and c
|
|
||||||
// are big. The proper solution is to change the expression to avoid
|
|
||||||
// precision loss but I'm too busy/lazy to do it now.
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
a *= 10;
|
|
||||||
b *= 10;
|
|
||||||
c *= 10;
|
|
||||||
return((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
|
return((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +180,6 @@ kernel void RenderKernel(texture2d<float, access::write> outTexture [[texture(0)
|
||||||
{
|
{
|
||||||
//TODO: guard against thread group size not equal to tile size?
|
//TODO: guard against thread group size not equal to tile size?
|
||||||
const uint2 tilesMatrixDim = (gridSize - 1) / RENDERER_TILE_SIZE + 1;
|
const uint2 tilesMatrixDim = (gridSize - 1) / RENDERER_TILE_SIZE + 1;
|
||||||
// const uint2 tilePos = tgid * threadsPerThreadgroup / RENDERER_TILE_SIZE;
|
|
||||||
const uint2 tilePos = gid/RENDERER_TILE_SIZE;
|
const uint2 tilePos = gid/RENDERER_TILE_SIZE;
|
||||||
const uint tileIndex = tilePos.y * tilesMatrixDim.x + tilePos.x;
|
const uint tileIndex = tilePos.y * tilesMatrixDim.x + tilePos.x;
|
||||||
const device uint* tileBuffer = tilesArray + tileIndex * RENDERER_TILE_BUFFER_SIZE;
|
const device uint* tileBuffer = tilesArray + tileIndex * RENDERER_TILE_BUFFER_SIZE;
|
||||||
|
@ -224,18 +213,25 @@ kernel void RenderKernel(texture2d<float, access::write> outTexture [[texture(0)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
const float2 sampleOffsets[6] = { float2(5./12, 5./12),
|
|
||||||
float2(-3./12, 3./12),
|
|
||||||
float2(1./12, 1./12),
|
|
||||||
float2(3./12, -1./12),
|
|
||||||
float2(-5./12, -3./12),
|
|
||||||
float2(-1./12, -5./12)};
|
|
||||||
|
|
||||||
int zIndices[6];
|
int subPixelFactor = 16;
|
||||||
uint flipCounts[6];
|
int2 pixelCoord = int2(gid);
|
||||||
float4 pixelColors[6];
|
int2 centerPoint = int2((float2(pixelCoord) + float2(0.5, 0.5)) * subPixelFactor);
|
||||||
float4 nextColors[6];
|
|
||||||
for(int i=0; i<6; i++)
|
const int sampleCount = 8;
|
||||||
|
int2 samplePoints[sampleCount] = {centerPoint + int2(1, 3),
|
||||||
|
centerPoint + int2(-1, -3),
|
||||||
|
centerPoint + int2(5, -1),
|
||||||
|
centerPoint + int2(-3, 5),
|
||||||
|
centerPoint + int2(-5, -5),
|
||||||
|
centerPoint + int2(-7, 1),
|
||||||
|
centerPoint + int2(3, -7),
|
||||||
|
centerPoint + int2(7, 7)};
|
||||||
|
int zIndices[sampleCount];
|
||||||
|
uint flipCounts[sampleCount];
|
||||||
|
float4 pixelColors[sampleCount];
|
||||||
|
float4 nextColors[sampleCount];
|
||||||
|
for(int i=0; i<sampleCount; i++)
|
||||||
{
|
{
|
||||||
zIndices[i] = -1;
|
zIndices[i] = -1;
|
||||||
flipCounts[i] = 0;
|
flipCounts[i] = 0;
|
||||||
|
@ -245,12 +241,12 @@ kernel void RenderKernel(texture2d<float, access::write> outTexture [[texture(0)
|
||||||
|
|
||||||
for(uint tileBufferIndex=0; tileBufferIndex < tileBufferSize; tileBufferIndex++)
|
for(uint tileBufferIndex=0; tileBufferIndex < tileBufferSize; tileBufferIndex++)
|
||||||
{
|
{
|
||||||
float4 box = boxArray[tileBuffer[tileBufferIndex]];
|
// float4 box = boxArray[tileBuffer[tileBufferIndex]];
|
||||||
const device mg_triangle_data* triangle = &triangleArray[tileBuffer[tileBufferIndex]];
|
const device mg_triangle_data* triangle = &triangleArray[tileBuffer[tileBufferIndex]];
|
||||||
|
|
||||||
float2 p0 = triangle->p0;
|
int2 p0 = int2(triangle->p0 * subPixelFactor);
|
||||||
float2 p1 = triangle->p1;
|
int2 p1 = int2(triangle->p1 * subPixelFactor);
|
||||||
float2 p2 = triangle->p2;
|
int2 p2 = int2(triangle->p2 * subPixelFactor);
|
||||||
|
|
||||||
int bias0 = triangle->bias0;
|
int bias0 = triangle->bias0;
|
||||||
int bias1 = triangle->bias1;
|
int bias1 = triangle->bias1;
|
||||||
|
@ -273,26 +269,30 @@ kernel void RenderKernel(texture2d<float, access::write> outTexture [[texture(0)
|
||||||
{uvTransform2x3[1], uvTransform2x3[4], 0},
|
{uvTransform2x3[1], uvTransform2x3[4], 0},
|
||||||
{uvTransform2x3[2], uvTransform2x3[5], 1}};
|
{uvTransform2x3[2], uvTransform2x3[5], 1}};
|
||||||
|
|
||||||
for(int i=0; i<6; i++)
|
for(int i=0; i<sampleCount; i++)
|
||||||
{
|
{
|
||||||
float2 samplePoint = (float2)gid + sampleOffsets[i];
|
int2 samplePoint = samplePoints[i];
|
||||||
|
|
||||||
//NOTE(martin): cull if pixel is outside box
|
//NOTE(martin): cull if pixel is outside box
|
||||||
|
/*
|
||||||
|
// if we use this, make sure box is in fixed points coords
|
||||||
if(samplePoint.x < box.x || samplePoint.x > box.z || samplePoint.y < box.y || samplePoint.y > box.w)
|
if(samplePoint.x < box.x || samplePoint.x > box.z || samplePoint.y < box.y || samplePoint.y > box.w)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
float w0 = orient2d(p1, p2, samplePoint);
|
int w0 = orient2d(p1, p2, samplePoint);
|
||||||
float w1 = orient2d(p2, p0, samplePoint);
|
int w1 = orient2d(p2, p0, samplePoint);
|
||||||
float w2 = orient2d(p0, p1, samplePoint);
|
int w2 = orient2d(p0, p1, samplePoint);
|
||||||
|
|
||||||
if(((int)w0+bias0) >= 0 && ((int)w1+bias1) >= 0 && ((int)w2+bias2) >= 0)
|
if((w0+bias0) >= 0 && (w1+bias1) >= 0 && (w2+bias2) >= 0)
|
||||||
{
|
{
|
||||||
float4 cubic = (cubic0*w0 + cubic1*w1 + cubic2*w2)/(w0+w1+w2);
|
float4 cubic = (cubic0*w0 + cubic1*w1 + cubic2*w2)/(w0+w1+w2);
|
||||||
|
|
||||||
//float2 uv = (uv0*w0 + uv1*w1 + uv2*w2)/(w0+w1+w2);
|
//float2 uv = (uv0*w0 + uv1*w1 + uv2*w2)/(w0+w1+w2);
|
||||||
float2 uv = (uvTransform*(float3(samplePoint.xy/contentsScaling[0], 1))).xy;
|
float2 sampleFP = float2(samplePoint)/subPixelFactor;
|
||||||
|
float2 uv = (uvTransform*(float3(sampleFP/contentsScaling[0], 1))).xy;
|
||||||
|
|
||||||
float4 texColor = float4(1, 1, 1, 1);
|
float4 texColor = float4(1, 1, 1, 1);
|
||||||
if(*useTexture)
|
if(*useTexture)
|
||||||
|
@ -334,7 +334,7 @@ kernel void RenderKernel(texture2d<float, access::write> outTexture [[texture(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
float4 out = float4(0, 0, 0, 0);
|
float4 out = float4(0, 0, 0, 0);
|
||||||
for(int i=0; i<6; i++)
|
for(int i=0; i<sampleCount; i++)
|
||||||
{
|
{
|
||||||
if(flipCounts[i] & 0x01)
|
if(flipCounts[i] & 0x01)
|
||||||
{
|
{
|
||||||
|
@ -342,6 +342,6 @@ kernel void RenderKernel(texture2d<float, access::write> outTexture [[texture(0)
|
||||||
}
|
}
|
||||||
out += pixelColors[i];
|
out += pixelColors[i];
|
||||||
}
|
}
|
||||||
out = out/6.;
|
out = out/sampleCount;
|
||||||
outTexture.write(out, gid);
|
outTexture.write(out, gid);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue