|
|
d989ab |
/*
|
|
|
d989ab |
......... 2015 Ivan Mahonin
|
|
|
d989ab |
|
|
|
d989ab |
This program is free software: you can redistribute it and/or modify
|
|
|
d989ab |
it under the terms of the GNU General Public License as published by
|
|
|
d989ab |
the Free Software Foundation, either version 3 of the License, or
|
|
|
d989ab |
(at your option) any later version.
|
|
|
d989ab |
|
|
|
d989ab |
This program is distributed in the hope that it will be useful,
|
|
|
d989ab |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
d989ab |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
d989ab |
GNU General Public License for more details.
|
|
|
d989ab |
|
|
|
d989ab |
You should have received a copy of the GNU General Public License
|
|
|
d989ab |
along with this program. If not, see <http: licenses="" www.gnu.org="">.</http:>
|
|
|
d989ab |
*/
|
|
|
d989ab |
|
|
|
67876c |
__kernel void clear2f(
|
|
|
67876c |
__global float2 *buffer )
|
|
|
67876c |
{
|
|
|
67876c |
const float2 v = { 0.f, 0.f };
|
|
|
67876c |
buffer[get_global_id(0)] = v;
|
|
|
67876c |
}
|
|
|
67876c |
|
|
|
d989ab |
__kernel void lines(
|
|
|
5890eb |
int width,
|
|
|
a04770 |
__global float4 *lines,
|
|
|
a04770 |
__global int2 *rows,
|
|
|
67876c |
__global float2 *mark_buffer )
|
|
|
d989ab |
{
|
|
|
5890eb |
const float e = 1e-6f;
|
|
|
a04770 |
int2 row = rows[get_global_id(0)];
|
|
|
67876c |
sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE
|
|
|
67876c |
| CLK_ADDRESS_NONE
|
|
|
67876c |
| CLK_FILTER_NEAREST;
|
|
|
67876c |
int w = width;
|
|
|
a04770 |
for(__global float4 *i = lines + row.x, *end = i + row.y; i < end; ++i) {
|
|
|
a04770 |
float4 line = *i;
|
|
|
a04770 |
float2 p0 = { line.x, line.y };
|
|
|
a04770 |
float2 p1 = { line.z, line.w };
|
|
|
d989ab |
|
|
|
5890eb |
int iy0 = (int)floor(fmin(p0.y, p1.y) + e);
|
|
|
5890eb |
int iy1 = (int)floor(fmax(p0.y, p1.y) - e);
|
|
|
d989ab |
|
|
|
d989ab |
float2 d = p1 - p0;
|
|
|
5890eb |
float kx = fabs(d.y) < e ? 0.f : d.x/d.y;
|
|
|
5890eb |
float ky = fabs(d.x) < e ? 0.f : d.y/d.x;
|
|
|
d989ab |
|
|
|
d989ab |
for(int r = iy0; r <= iy1; ++r) {
|
|
|
5890eb |
float y = (float)r;
|
|
|
5890eb |
float2 pya = { p0.x + kx*(y - p0.y), y };
|
|
|
5890eb |
float2 pyb = { p0.x + kx*(y + 1.0 - p0.y), y + 1.f };
|
|
|
5890eb |
float2 pp0 = p0.y - y < -e ? pya
|
|
|
5890eb |
: (p0.y - y > 1.f + e ? pyb : p0);
|
|
|
5890eb |
float2 pp1 = p1.y - y < -e ? pya
|
|
|
5890eb |
: (p1.y - y > 1.f + e ? pyb : p1);
|
|
|
d989ab |
|
|
|
5890eb |
int ix0 = (int)floor(fmin(pp0.x, pp1.x) + e);
|
|
|
5890eb |
int ix1 = (int)floor(fmax(pp0.x, pp1.x) - e);
|
|
|
d989ab |
for(int c = ix0; c <= ix1; ++c) {
|
|
|
5890eb |
float x = (float)c;
|
|
|
5890eb |
float2 pxa = { x, p0.y + ky*(x - p0.x) };
|
|
|
5890eb |
float2 pxb = { x + 1.0, p0.y + ky*(x + 1.0 - p0.x) };
|
|
|
5890eb |
float2 ppp0 = pp0.x - x < -e ? pxa
|
|
|
5890eb |
: (pp0.x - x > 1.f + e ? pxb : pp0);
|
|
|
5890eb |
float2 ppp1 = pp1.x - x < -e ? pxa
|
|
|
5890eb |
: (pp1.x - x > 1.f + e ? pxb : pp1);
|
|
|
d989ab |
|
|
|
67876c |
float2 m;
|
|
|
67876c |
m.y = ppp1.y - ppp0.y;
|
|
|
67876c |
m.x = (x + 1.f - 0.5f*(ppp0.x + ppp1.x))*m.y;
|
|
|
67876c |
mark_buffer[r*w + c] += m;
|
|
|
d989ab |
}
|
|
|
d989ab |
}
|
|
|
d989ab |
}
|
|
|
d989ab |
}
|
|
|
d989ab |
|
|
|
d989ab |
__kernel void fill(
|
|
|
5890eb |
int width,
|
|
|
67876c |
__global float2 *mark_buffer,
|
|
|
67876c |
__read_only image2d_t surface_read_image,
|
|
|
67876c |
__write_only image2d_t surface_write_image,
|
|
|
a04770 |
float4 color,
|
|
|
5890eb |
int invert,
|
|
|
5890eb |
int evenodd )
|
|
|
d989ab |
{
|
|
|
5890eb |
size_t id = get_global_id(0);
|
|
|
d989ab |
int w = width;
|
|
|
67876c |
const sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE
|
|
|
67876c |
| CLK_ADDRESS_NONE
|
|
|
67876c |
| CLK_FILTER_NEAREST;
|
|
|
a04770 |
float4 cl = color;
|
|
|
5890eb |
float cover = 0.f;
|
|
|
67876c |
__global float2 *mark = mark_buffer + id*w;
|
|
|
67876c |
for(int2 coord = { 0, id }; coord.x < w; ++coord.x, ++mark) {
|
|
|
67876c |
float2 m = *mark;
|
|
|
67876c |
|
|
|
67876c |
float alpha = fabs(m.x + cover);
|
|
|
67876c |
cover += m.y;
|
|
|
67876c |
alpha = evenodd ? (1.f - fabs(1.f - alpha - 2.f*floor(0.5f*alpha)))
|
|
|
5890eb |
: fmin(alpha, 1.f);
|
|
|
a04770 |
alpha *= cl.w;
|
|
|
5890eb |
if (invert) alpha = 1.f - alpha;
|
|
|
5890eb |
float alpha_inv = 1.f - alpha;
|
|
|
a04770 |
|
|
|
67876c |
float4 c = read_imagef(surface_read_image, sampler, coord);
|
|
|
a04770 |
c.x = c.x*alpha_inv + cl.x*alpha;
|
|
|
a04770 |
c.y = c.y*alpha_inv + cl.y*alpha;
|
|
|
a04770 |
c.z = c.z*alpha_inv + cl.z*alpha;
|
|
|
67876c |
c.w = min(c.w + alpha, 1.f);
|
|
|
67876c |
write_imagef(surface_write_image, coord, c);
|
|
|
d989ab |
}
|
|
|
d989ab |
}
|