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

Ivan Mahonin 105dfe
/*
Ivan Mahonin 20cefb
    ......... 2015-2018 Ivan Mahonin
Ivan Mahonin 105dfe
Ivan Mahonin 105dfe
    This program is free software: you can redistribute it and/or modify
Ivan Mahonin 105dfe
    it under the terms of the GNU General Public License as published by
Ivan Mahonin 105dfe
    the Free Software Foundation, either version 3 of the License, or
Ivan Mahonin 105dfe
    (at your option) any later version.
Ivan Mahonin 105dfe
Ivan Mahonin 105dfe
    This program is distributed in the hope that it will be useful,
Ivan Mahonin 105dfe
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Ivan Mahonin 105dfe
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Ivan Mahonin 105dfe
    GNU General Public License for more details.
Ivan Mahonin 105dfe
Ivan Mahonin 105dfe
    You should have received a copy of the GNU General Public License
Ivan Mahonin 105dfe
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
Ivan Mahonin 105dfe
*/
Ivan Mahonin 105dfe
Ivan Mahonin feaa05
#pragma OPENCL EXTENSION cl_khr_int64_base_atomics: enable
Ivan Mahonin feaa05
Ivan Mahonin 5a7afd
#define ONE       65536
Ivan Mahonin 5a7afd
#define TWO      131072               // (ONE)*2
Ivan Mahonin 5a7afd
#define HALF      32768               // (ONE)/2
Ivan Mahonin 5a7afd
#define ONE_F     65536.f             // (float)(ONE)
Ivan Mahonin 5a7afd
#define DIV_ONE_F 0.0000152587890625f // 1.f/(ONE_F)
Ivan Mahonin 5a7afd
Ivan Mahonin 5a7afd
Ivan Mahonin 105dfe
kernel void path(
Ivan Mahonin 105dfe
	int width,
Ivan Mahonin 105dfe
	int height,
Ivan Mahonin 8cf99a
	global long *marks,
Ivan Mahonin 105dfe
	global float2 *points,
Ivan Mahonin 77d271
	int end,
Ivan Mahonin 77d271
	int minx )
Ivan Mahonin 105dfe
{
Ivan Mahonin 105dfe
	int id = get_global_id(0);
Ivan Mahonin 77d271
	if (id >= end) return;
Ivan Mahonin 105dfe
	float2 p0 = points[id];
Ivan Mahonin 105dfe
	float2 p1 = points[id + 1];
Ivan Mahonin 20cefb
	
Ivan Mahonin 105dfe
	bool flipx = p1.x < p0.x;
Ivan Mahonin 105dfe
	bool flipy = p1.y < p0.y;
Ivan Mahonin 8cf99a
	if (flipx) { p0.x = (float)width  - p0.x; p1.x = (float)width  - p1.x; }
Ivan Mahonin 20cefb
	if (flipy) { p0.y = (float)height - p0.y; p1.y = (float)height - p1.y; }
Ivan Mahonin 105dfe
	float2 d = p1 - p0;
Ivan Mahonin 20cefb
	int w1 = width - 1;
Ivan Mahonin 20cefb
	int h1 = height - 1;
Ivan Mahonin 8cf99a
	float kx = d.x/d.y;
Ivan Mahonin 8cf99a
	float ky = d.y/d.x;
Ivan Mahonin 105dfe
	
Ivan Mahonin 105dfe
	while(p0.x != p1.x || p0.y != p1.y) {
Ivan Mahonin a7622f
		int ix = max((int)p0.x, 0);
Ivan Mahonin a7622f
		int iy = (int)p0.y;
Ivan Mahonin a7622f
		if (ix > w1) return;
Ivan Mahonin 105dfe
Ivan Mahonin 8cf99a
		float2 px, py;
Ivan Mahonin 105dfe
		px.x = (float)(ix + 1);
Ivan Mahonin f14ea7
		py.y = (float)(iy + 1);
Ivan Mahonin a7622f
		iy = clamp(iy, 0, h1);
Ivan Mahonin 8cf99a
		
Ivan Mahonin 8cf99a
		px.y = p0.y + ky*(px.x - p0.x);
Ivan Mahonin 105dfe
		py.x = p0.x + kx*(py.y - p0.y);
Ivan Mahonin 8cf99a
		
Ivan Mahonin 8cf99a
		float2 pp1 = p1;
Ivan Mahonin 105dfe
		if (pp1.x > px.x) pp1 = px;
Ivan Mahonin 105dfe
		if (pp1.y > py.y) pp1 = py;
Ivan Mahonin 105dfe
		
Ivan Mahonin a7622f
		float cover = (pp1.x - p0.x)*ONE_F;
Ivan Mahonin a7622f
		float area = py.y - 0.5f*(p0.y + pp1.y);
Ivan Mahonin a7622f
		if (flipx) { ix = w1 - ix; cover = -cover; }
Ivan Mahonin a7622f
		if (flipy) { iy = h1 - iy; area = 1.f - area; }
Ivan Mahonin 105dfe
		p0 = pp1;
Ivan Mahonin 8cf99a
		
Ivan Mahonin a7622f
		atomic_add(marks + iy*width + ix, upsample((int)cover, (int)(area*cover)));
Ivan Mahonin 105dfe
	}
Ivan Mahonin 105dfe
}
Ivan Mahonin 105dfe
Ivan Mahonin 82f284
// TODO:
Ivan Mahonin 82f284
// different implementations for:
Ivan Mahonin 82f284
//   antialiased, transparent, inverted, evenodd contours and combinations (total 16 implementations)
Ivan Mahonin 105dfe
kernel void fill(
Ivan Mahonin a7622f
	int width,
Ivan Mahonin 8cf99a
	global int2 *marks,
Ivan Mahonin 105dfe
	global float4 *image,
Ivan Mahonin 105dfe
	float4 color,
Ivan Mahonin 77d271
	int4 bounds )
Ivan Mahonin 105dfe
{
Ivan Mahonin a7622f
	if (get_global_id(0) >= bounds.s2) return;
Ivan Mahonin a7622f
	int id = (int)get_global_id(0) + bounds.s1*width;
Ivan Mahonin 20cefb
	marks += id;
Ivan Mahonin 20cefb
	image += id;
Ivan Mahonin 20cefb
Ivan Mahonin 8cf99a
	int icover = 0;
Ivan Mahonin 8cf99a
	while(true) {
Ivan Mahonin 8cf99a
		int2 m = *marks;
Ivan Mahonin 8cf99a
		*marks = (int2)(0, 0);
Ivan Mahonin 8cf99a
		float alpha = (float)abs(m.x + icover)*color.w*DIV_ONE_F;
Ivan Mahonin a7622f
		marks += width;
Ivan Mahonin 82f284
Ivan Mahonin 82f284
		icover += m.y;
Ivan Mahonin 8cf99a
		*image = *image*(1.f - alpha) + color*alpha;
Ivan Mahonin 8cf99a
		
Ivan Mahonin a7622f
		if (++bounds.s1 >= bounds.s3) return;
Ivan Mahonin a7622f
		image += width;
Ivan Mahonin 105dfe
	}
Ivan Mahonin 105dfe
}