glsl canvas shader: do cross products in 64 bits fixed point to avoid overflow

This commit is contained in:
martinfouilleul 2023-02-08 20:36:39 +01:00
parent 7cf4c3d925
commit 3f58b2ac3d
3 changed files with 26 additions and 20 deletions

View File

@ -120,28 +120,28 @@ int main()
{
if(x - 200 > 0)
{
x-=1;
x-=5;
}
}
else if(event.key.code == MP_KEY_RIGHT)
{
if(x + 200 < contentRect.w)
{
x+=1;
x+=5;
}
}
else if(event.key.code == MP_KEY_UP)
{
if(y + 200 < contentRect.h)
{
y+=1;
y+=5;
}
}
else if(event.key.code == MP_KEY_DOWN)
{
if(y - 200 > 0)
{
y-=1;
y-=5;
}
}
//*/
@ -155,18 +155,22 @@ int main()
if(x-200 < 0)
{
x = 200;
dx = speed;
}
if(x+200 > contentRect.w)
{
x = contentRect.w - 200;
dx = -speed;
}
if(y-200 < 0)
{
y = 200;
dy = speed;
}
if(y+200 > contentRect.h)
{
y = contentRect.h - 200;
dy = -speed;
}
x += dx;

View File

@ -1,4 +1,5 @@
#version 430
#extension GL_ARB_gpu_shader_int64 : require
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
precision mediump float;
@ -52,11 +53,16 @@ bool is_top_left(ivec2 a, ivec2 b)
||(b.y < a.y));
}
int orient2d(ivec2 a, ivec2 b, ivec2 p)
int64_t orient2d(i64vec2 a, i64vec2 b, i64vec2 p)
{
return((b.x-a.x)*(p.y-a.y) - (b.y-a.y)*(p.x-a.x));
}
int64_t is_clockwise(i64vec2 p0, i64vec2 p1, i64vec2 p2)
{
return((p1 - p0).x*(p2 - p0).y - (p1 - p0).y*(p2 - p0).x);
}
void main()
{
ivec2 pixelCoord = ivec2(gl_WorkGroupID.xy*uvec2(16, 16) + gl_LocalInvocationID.xy);
@ -79,10 +85,10 @@ void main()
centerPoint + ivec2(7, 7)*16);
/*/
const int sampleCount = 4;
ivec2 samplePoints[sampleCount] = ivec2[sampleCount](centerPoint + ivec2(-2, 6)*16,
centerPoint + ivec2(6, 2)*16,
centerPoint + ivec2(-6, -2)*16,
centerPoint + ivec2(2, -6)*16);
ivec2 samplePoints[sampleCount] = ivec2[sampleCount](centerPoint + ivec2(-2, 6),
centerPoint + ivec2(6, 2),
centerPoint + ivec2(-6, -2),
centerPoint + ivec2(2, -6));
//*/
//DEBUG
/*
@ -142,7 +148,7 @@ void main()
ivec4 clip = ivec4(round((shapeBuffer.elements[zIndex].clip * vec4(scaling, scaling) + vec4(0.5, 0.5, 0.5, 0.5)) * subPixelFactor));
//NOTE(martin): reorder triangle counter-clockwise and compute bias for each edge
int cw = (p1 - p0).x*(p2 - p0).y - (p1 - p0).y*(p2 - p0).x;
int64_t cw = is_clockwise(p0, p1, p2);
if(cw < 0)
{
uint tmpIndex = i1;
@ -158,9 +164,9 @@ void main()
vec4 cubic1 = vertexBuffer.elements[i1].cubic;
vec4 cubic2 = vertexBuffer.elements[i2].cubic;
int bias0 = is_top_left(p1, p2) ? 0 : -1;
int bias1 = is_top_left(p2, p0) ? 0 : -1;
int bias2 = is_top_left(p0, p1) ? 0 : -1;
int64_t bias0 = is_top_left(p1, p2) ? 0 : -1;
int64_t bias1 = is_top_left(p2, p0) ? 0 : -1;
int64_t bias2 = is_top_left(p0, p1) ? 0 : -1;
for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
{
@ -174,9 +180,9 @@ void main()
continue;
}
int w0 = orient2d(p1, p2, samplePoint);
int w1 = orient2d(p2, p0, samplePoint);
int w2 = orient2d(p0, p1, samplePoint);
int64_t w0 = orient2d(p1, p2, samplePoint);
int64_t w1 = orient2d(p2, p0, samplePoint);
int64_t w2 = orient2d(p0, p1, samplePoint);
if((w0+bias0) >= 0 && (w1+bias1) >= 0 && (w2+bias2) >= 0)
{

View File

@ -66,10 +66,6 @@ void main()
min(max(max(p0.x, p1.x), p2.x), clip.z),
min(max(max(p0.y, p1.y), p2.y), clip.w));
/*
fbox.xy = min(fbox.xy, clip.xy);
fbox.zw = max(fbox.zw, clip.zw);
*/
uvec4 box = uvec4(floor(fbox))/tileSize;
uint xMin = max(0u, box.x);