|
|
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 |
|
|
|
d989ab |
__kernel void lines(
|
|
|
d989ab |
__global int width,
|
|
|
d989ab |
__global float *lines,
|
|
|
d989ab |
__global int *rows,
|
|
|
d989ab |
__global float *mark_buffer )
|
|
|
d989ab |
{
|
|
|
d989ab |
size_t id = get_global_id(0);
|
|
|
d989ab |
int *row = rows + id*2;
|
|
|
d989ab |
int begin = *rows;
|
|
|
d989ab |
int end = begin + rows[1];
|
|
|
d989ab |
for(int i = begin; i < end; ++i) {
|
|
|
d989ab |
float *line = lines + 4*begin;
|
|
|
d989ab |
float2 p0(*line, line[1]);
|
|
|
d989ab |
float2 p1(line[2], line[3]);
|
|
|
d989ab |
|
|
|
d989ab |
int iy0 = (int)floor(p0.y);
|
|
|
d989ab |
int iy1 = (int)floor(p1.x);
|
|
|
d989ab |
if (iy1 < iy0) { int sw = iy0; iy0 = iy1; iy1 = iy0; }
|
|
|
d989ab |
|
|
|
d989ab |
float2 d = p1 - p0;
|
|
|
d989ab |
float2 k( fabs(d.y) < 1e-6 ? 0.0 : d.x/d.y,
|
|
|
d989ab |
fabs(d.x) < 1e-6 ? 0.0 : d.y/d.x );
|
|
|
d989ab |
|
|
|
d989ab |
for(int r = iy0; r <= iy1; ++r) {
|
|
|
d989ab |
float y = (float)iy0;
|
|
|
d989ab |
|
|
|
d989ab |
float2 pp0 = p0;
|
|
|
d989ab |
pp0.y -= y;
|
|
|
d989ab |
if (pp0.y < 0.0) {
|
|
|
d989ab |
pp0.y = 0.0;
|
|
|
d989ab |
pp0.x = p0.x - k.x*y;
|
|
|
d989ab |
} else
|
|
|
d989ab |
if (pp0.y > 1.0) {
|
|
|
d989ab |
pp0.y = 1.0;
|
|
|
d989ab |
pp0.x = p0.x - k.x*(y - 1.0);
|
|
|
d989ab |
}
|
|
|
d989ab |
|
|
|
d989ab |
float2 pp1 = p1;
|
|
|
d989ab |
pp1.y -= y;
|
|
|
d989ab |
if (pp1.y < 0.0) {
|
|
|
d989ab |
pp1.y = 0.0;
|
|
|
d989ab |
pp1.x = p0.x - k.x*y;
|
|
|
d989ab |
} else
|
|
|
d989ab |
if (pp1.y > 1.0) {
|
|
|
d989ab |
pp1.y = 1.0;
|
|
|
d989ab |
pp1.x = p0.x - k.x*(y - 1.0);
|
|
|
d989ab |
}
|
|
|
d989ab |
|
|
|
d989ab |
int ix0 = min(max((int)floor(pp0.x), 0), width);
|
|
|
d989ab |
int ix1 = min(max((int)floor(pp1.x), 0), width);
|
|
|
d989ab |
if (ix1 < ix0) { int sw = ix0; ix0 = ix1; ix1 = ix0; }
|
|
|
d989ab |
for(int c = ix0; c <= ix1; ++c) {
|
|
|
d989ab |
float x = (float)ix0;
|
|
|
d989ab |
|
|
|
d989ab |
float2 ppp0 = pp0;
|
|
|
d989ab |
ppp0.x -= x;
|
|
|
d989ab |
if (ppp0.x < 0.0) {
|
|
|
d989ab |
ppp0.x = 0.0;
|
|
|
d989ab |
ppp0.y = pp0.y - k.y*x;
|
|
|
d989ab |
} else
|
|
|
d989ab |
if (ppp0.x > 1.0) {
|
|
|
d989ab |
ppp0.x = 1.0;
|
|
|
d989ab |
ppp0.y = pp0.y - k.y*(x - 1.0);
|
|
|
d989ab |
}
|
|
|
d989ab |
|
|
|
d989ab |
float2 ppp1 = pp1;
|
|
|
d989ab |
ppp1.x -= x;
|
|
|
d989ab |
if (ppp1.x < 0.0) {
|
|
|
d989ab |
ppp1.x = 0.0;
|
|
|
d989ab |
ppp1.y = pp0.y - k.y*x;
|
|
|
d989ab |
} else
|
|
|
d989ab |
if (ppp1.x > 1.0) {
|
|
|
d989ab |
ppp1.x = 1.0;
|
|
|
d989ab |
ppp1.y = pp0.y - k.y*(x - 1.0);
|
|
|
d989ab |
}
|
|
|
d989ab |
|
|
|
d989ab |
float cover = ppp0.y - ppp1.y;
|
|
|
d989ab |
float area = (0.5*(ppp1.x + ppp1.x) - 1.0)*cover;
|
|
|
d989ab |
float *mark = mark_buffer + 2*(r*width + c);
|
|
|
d989ab |
*mark += area;
|
|
|
d989ab |
mark[1] += cover;
|
|
|
d989ab |
}
|
|
|
d989ab |
}
|
|
|
d989ab |
}
|
|
|
d989ab |
}
|
|
|
d989ab |
|
|
|
d989ab |
__kernel void fill(
|
|
|
d989ab |
__global int width,
|
|
|
d989ab |
__global float *mark_buffer,
|
|
|
d989ab |
__global float *surface_buffer,
|
|
|
d989ab |
__global float color_r,
|
|
|
d989ab |
__global float color_g,
|
|
|
d989ab |
__global float color_b,
|
|
|
d989ab |
__global float color_a )
|
|
|
d989ab |
{
|
|
|
d989ab |
sizet id = get_global_id(0);
|
|
|
d989ab |
int w = width;
|
|
|
d989ab |
float cr = color_r;
|
|
|
d989ab |
float cg = color_g;
|
|
|
d989ab |
float cb = color_b;
|
|
|
d989ab |
float ca = color_a;
|
|
|
d989ab |
float *mark = mark_buffer + 2*id*width;
|
|
|
d989ab |
float *surface = surface_buffer + 4*id*width;
|
|
|
d989ab |
float cover = 0;
|
|
|
d989ab |
for(int i = 0; i < w; ++i, mark += 2, surface += 4) {
|
|
|
d989ab |
float alpha = ca*(1.0 - fabs(1.0 - 0.5*frac(fabs(2.0*(*mark + cover)))));
|
|
|
d989ab |
float alpha_inv = 1.0 - alpha;
|
|
|
d989ab |
surface[0] = surface[0]*alpha_inv + cr*alpha;
|
|
|
d989ab |
surface[1] = surface[1]*alpha_inv + cg*alpha;
|
|
|
d989ab |
surface[2] = surface[2]*alpha_inv + cb*alpha;
|
|
|
d989ab |
surface[3] = surface[3]*alpha_inv + ca*alpha;
|
|
|
d989ab |
cover += mark[1];
|
|
|
d989ab |
}
|
|
|
d989ab |
}
|