Blame c++/contourgl/cl/contour.cl

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
}