kernel: better commenting

kernel: better commenting

// OpenCL Kernel
// https://www.khronos.org/files/opencl-1-2-quick-reference-card.pdf

kernel void convolve_image(__read_only image2d_t image,
                           __read_only image2d_t pattern,
                           __global __write_only float* output,
                           sampler_t sampler,
                           const int2 top_left_rc,   // image (row, column)
                           const int image_start_r,  // where in the image row to start writing (for partitions)
                           const int image_end_r)    // end row writing (for partitions)
{
   // From a birds-eye-view what this kernel does is to compute a similarity
   // measure almost like a convolve operation, but with a distance measure
   // that uses the alpha channel of the pattern as a mask (to ignore or
   // down-weight parts of the pattern) and further uses a squared distance
   // measure. One call to this method computes a single pixel
   // in the `output` image (`output` is our region-of-interest (ROI)). The
   // output just contains float values (NOT in scale 0..1) for how similar
   // pattern and image are at that pixel. Lower value mean "more similar".
   // `top_left_rc` defines to which pixel coordinate the (0, 0) pixel in the
   // output corresponds.

    // Position (row, column) of the pixel in the output image.
    // Note, that OpenCL has uses column-major ("fortran"-style) storage, so
    // in the end we have to access the pixel data (through a sampler) in
    // (column, row) order. But we stick to naming like "C"-style row-major
    // ordering and just do the flip in the two nested for-loops in the loop
    // variables c and r, which are then used according to OpenCL's convention.
    const int2 pos = {get_global_id(0), get_global_id(1)};

    // The width of the image
    const int image_width = get_image_width(image);

    // The pattern should be at least 3x3 and have an odd width and height
    const int pattern_half_w = (get_image_width(pattern)-1) / 2;
    const int pattern_half_h = (get_image_height(pattern)-1) / 2;

    // 4-tuple of the RGBA values from the pattern image and RRB of the image.
    float4 pattern_color = (float4)(0.0, 0.0, 0.0, 0.0);
    float4 image_color = (float4)(0.0, 0.0, 0.0, 0.0);

    // The (column, row) of the center pixel in the pattern is computed
    // Note, that later one we use this as (column, row), therefore we switch
    // already here the .s0 and .s1 assignment
    // (s0 is the first entry, s1 second)
    int2 pattern_pos_cr = (int2)(0, 0);
    pattern_pos_cr.s1 = -top_left_rc.s0 - pos.s0 + pattern_half_h; // row
    pattern_pos_cr.s0 = -top_left_rc.s1 - pos.s1 + pattern_half_w; // column

    // value for the output pixel we are going to compute in this kernel
    float value = 0.0;
    // the distance in the color-space between the image and the pattern
    float dist = 0.0f;
    const float max_dist = distance(1+1+1);

    // Go though all pixel of the pattern image
    for (int r = image_start_r; r < image_end_r; r++) {

        for (int c = 0; c < image_width; c++) {

            pattern_color = read_imagef(pattern, sampler, pattern_pos_cr + (int2)(c, r));

            if(pattern_color.w > 0.0f) {
                // Use the alpha value `.w` from an RGBA image (pattern) as
                // weight and compute the `distance` which is the squared
                // absolute difference
                image_color = read_imagef(image, sampler, (int2)(c, r));
                dist = distance(pattern_color.xyz, image_color.xyz);
                value += (1-pattern_color.w) * max_dist + pattern_color.w * dist;
            } else {
                // Just add a constant that represents the maximal possible
                // difference between image and pattern for a single pixel.
                // E.g. from white (1,1,1) to black (0,0,0).
                value += max_dist;
            }
        }
    }

    output[pos.s0 * get_global_size(1) + pos.s1] = value;
}

kernel void convolve_image(__read_only image2d_t image,
                           __read_only image2d_t pattern,
                           __global __write_only float* output,
                           sampler_t sampler,
                           const int2 top_left_rc,   // image (row, column)
                           const int image_start_r,  // where in the image row to start writing (for partitions)
                           const int image_end_r)    // end row writing (for partitions)
{
   // From a birds-eye-view what this kernel does is to compute a similarity
   // measure almost like a convolve operation, but with a distance measure
   // that uses the alpha channel of the pattern as a mask (to ignore or
   // down-weight parts of the pattern) and further uses a squared distance
   // measure. One call to this method computes a single pixel
   // in the `output` image (`output` is our region-of-interest (ROI)). The
   // output just contains float values (NOT in scale 0..1) for how similar
   // pattern and image are at that pixel. Lower value mean "more similar".
   // `top_left_rc` defines to which pixel coordinate the (0, 0) pixel in the
   // output corresponds.

    // Position (row, column) of the pixel in the output image.
    // Note, that OpenCL has uses column-major ("fortran"-style) storage, so
    // in the end we have to access the pixel data (through a sampler) in
    // (column, row) order. But we stick to naming like "C"-style row-major
    // ordering and just do the flip in the two nested for-loops in the loop
    // variables c and r, which are then used according to OpenCL's convention.
    const int2 pos = {get_global_id(0), get_global_id(1)};

    // The width of the image
    const int image_width = get_image_width(image);

    // The pattern should be at least 3x3 and have an odd width and height
    const int pattern_half_w = (get_image_width(pattern)-1) / 2;
    const int pattern_half_h = (get_image_height(pattern)-1) / 2;

    // 4-tuple of the RGBA values from the pattern image and RRB of the image.
    float4 pattern_color = (float4)(0.0, 0.0, 0.0, 0.0);
    float4 image_color = (float4)(0.0, 0.0, 0.0, 0.0);

    int2 pattern_pos = (int2)(0, 0);
    pattern_pos.s1 = -top_left_rc.s0 - pos.s0 + pattern_half_h; // row
    pattern_pos.s0 = -top_left_rc.s1 - pos.s1 + pattern_half_w; // column

    // value for the output pixel we are going to compute in this kernel
    float value = 0.0;
    // the distance in the color-space between the image and the pattern
    float dist = 0.0f;
    const float max_dist = 1.732050808f;

    // Go though all pixel of the pattern image
    // Note, here c, r seem to be flipped, but that is because OpenCL uses
    // Fortran order.
    for (int r = image_start_r; r < image_end_r; r++) {

        for (int c = 0; c < image_width; c++) {

            pattern_color = read_imagef(pattern, sampler, pattern_pos + (int2)(c, r));

            if(pattern_color.w > 0.0f) {
                // Use the alpha value `.w` from an RGBA image (pattern) as
                // weight and compute the `distance` which is the squared
                // absolute difference
                image_color = read_imagef(image, sampler, (int2)(c, r));
                dist = distance(pattern_color.xyz, image_color.xyz);
                value += (1-pattern_color.w) * max_dist + pattern_color.w * dist;
            } else {
                // Just add a constant that represents the maximal possible
                // difference between image and pattern for a single pixel.
                // E.g. from white (1,1,1) to black (0,0,0) has a squared
                // Euclidean distance of 1.732050808.
                value += max_dist;
            }
        }
    }

    output[pos.s0 * get_global_size(1) + pos.s1] = value;
}


fix: kernel

fix: kernel

__kernel void saxpy_naive(         const int    numElems,
                                   const float  factor,
                          __global const float *src_0,
                          __global const float *src_1,
                          __global       float *dst_0)
{
    uint gid = get_global_id(0);

    if (gid < numElems)
        dst_0[gid] = factor * src_0[gid] * src_1[gid];
}

__kernel void saxpy_stride(         const int    numElems,
                                    const float  factor,
                           __global const float *src_0,
                           __global const float *src_1,
                           __global       float *dst_0)
{
    uint gid = get_global_id(0);
    uint step = get_global_size(0);

    for (int i = gid; i < numElems; i += step)
        dst_0[gid] = factor * src_0[gid] * src_1[gid];
}

__kernel void saxpy_dp(         const int    numElems,
                                const float  factor,
                       __global const float *src_0,
                       __global const float *src_1,
                       __global       float *dst_0)
{
    uint gid = get_global_id(0);
    uint step = get_global_size(0);

    for (int i = gid; i < numElems; i += step)
        dst_0[gid] = factor * src_0[gid] * src_1[gid];
}

void saxpy_dp_child(         const int    numElems,
                             const float  factor,
                    __global const float *src_0,
                    __global const float *src_1,
                    __global       float *dst_0)
{

}

__kernel void saxpy_naive(         const int    numElems,
                                   const float  factor,
                          __global const float *src_0,
                          __global const float *src_1,
                          __global       float *dst_0)
{
    uint gid = get_global_id(0);

    if (gid < N)
        dst_0[gid] = factor * src_0[gid] * src_1[gid];
}

__kernel void saxpy_stride(         const int    numElems,
                                    const float  factor,
                           __global const float *src_0,
                           __global const float *src_1,
                           __global       float *dst_0)
{
    uint gid = get_global_id(0);
    uint step = get_global_size(0);

    for (int i = gid; i < numElems; i += step)
        dst_0[gid] = factor * src_0[gid] * src_1[gid];
}

__kernel void saxpy_dp(         const int    numElems,
                                const float  factor,
                       __global const float *src_0,
                       __global const float *src_1,
                       __global       float *dst_0)
{
    uint gid = get_global_id(0);
    uint step = get_global_size(0);

    for (int i = gid; i < numElems; i += step)
        dst_0[gid] = factor * src_0[gid] * src_1[gid];
}

void saxpy_dp_child(         const int    numElems,
                             const float  factor,
                    __global const float *src_0,
                    __global const float *src_1,
                    __global       float *dst_0)
{

}


Formulaeic change in hessian determinant

Added abs()
Changed paranthesis order.

__kernel void hessian( __global float *xx, __global float* xy, __global float* yy, __global float* out, float sigmaD )
{
    int i = get_global_id(0);
    out[i] = abs(((xx[i] * yy[i] - pow(xy[i],2)) / sigmaD ));
}

__kernel void find_keypoints(
        __global float *source_determinants,
        __global int* corner_counts,
        __global ushort* keypoints,
        __global int* hessian_determinant_indices,
        int width,
        int height )
{
    int i = get_global_id(0);

    keypoints[i] = 0;

    if( corner_counts[i] )
    {
        for( int j = 0; j < SCALE_COUNT; j++ )
        {
            float before = 0;
            float after = 0;
            float current = source_determinants[hessian_determinant_indices[j] * width * height + i];

            if( j > 0 )
            {
                before = source_determinants[hessian_determinant_indices[j-1] * width * height + i];
            }

            if( j < SCALE_COUNT - 1 )
            {
                after = source_determinants[hessian_determinant_indices[j+1] * width * height + i];
            }

            if( current > before && current > after && current > 10.0f )
            {
                keypoints[i] |= (1UL << j);
            }
        }
    }
}

__kernel void hessian( __global float *xx, __global float* xy, __global float* yy, __global float* out, float sigmaD )
{
    int i = get_global_id(0);
    out[i] = ( xx[i] * yy[i] - pow(xy[i],2) / sigmaD );
}

__kernel void find_keypoints(
        __global float *source_determinants,
        __global int* corner_counts,
        __global ushort* keypoints,
        __global int* hessian_determinant_indices,
        int width,
        int height )
{
    int i = get_global_id(0);

    keypoints[i] = 0;

    if( corner_counts[i] )
    {
        for( int j = 0; j < SCALE_COUNT; j++ )
        {
            float before = 0;
            float after = 0;
            float current = source_determinants[hessian_determinant_indices[j] * width * height + i];

            if( j > 0 )
            {
                before = source_determinants[hessian_determinant_indices[j-1] * width * height + i];
            }

            if( j < SCALE_COUNT - 1 )
            {
                after = source_determinants[hessian_determinant_indices[j+1] * width * height + i];
            }

            if( current > before && current > after && current > 10.0f )
            {
                keypoints[i] |= (1UL << j);
            }
        }
    }
}


optimization of cv::minMaxLoc - used min/max

// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

// Copyright (C) 2014, Itseez, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.

#ifdef DOUBLE_SUPPORT
#ifdef cl_amd_fp64
#pragma OPENCL EXTENSION cl_amd_fp64:enable
#elif defined (cl_khr_fp64)
#pragma OPENCL EXTENSION cl_khr_fp64:enable
#endif
#endif

#ifdef DEPTH_0
#define MIN_VAL 0
#define MAX_VAL UCHAR_MAX
#elif defined DEPTH_1
#define MIN_VAL SCHAR_MIN
#define MAX_VAL SCHAR_MAX
#elif defined DEPTH_2
#define MIN_VAL 0
#define MAX_VAL USHRT_MAX
#elif defined DEPTH_3
#define MIN_VAL SHRT_MIN
#define MAX_VAL SHRT_MAX
#elif defined DEPTH_4
#define MIN_VAL INT_MIN
#define MAX_VAL INT_MAX
#elif defined DEPTH_5
#define MIN_VAL (-FLT_MAX)
#define MAX_VAL FLT_MAX
#elif defined DEPTH_6
#define MIN_VAL (-DBL_MAX)
#define MAX_VAL DBL_MAX
#endif

#define noconvert
#define INDEX_MAX UINT_MAX

#if wdepth <= 4
#define MIN_ABS(a) convertFromU(abs(a))
#define MIN_ABS2(a, b) convertFromU(abs_diff(a, b))
#define MIN(a, b) min(a, b)
#define MAX(a, b) max(a, b)
#else
#define MIN_ABS(a) fabs(a)
#define MIN_ABS2(a, b) fabs(a - b)
#define MIN(a, b) fmin(a, b)
#define MAX(a, b) fmax(a, b)
#endif

#if kercn != 3
#define loadpix(addr) *(__global const srcT *)(addr)
#define srcTSIZE (int)sizeof(srcT)
#else
#define loadpix(addr) vload3(0, (__global const srcT1 *)(addr))
#define srcTSIZE ((int)sizeof(srcT1) * 3)
#endif

#ifndef HAVE_MASK
#undef srcTSIZE
#define srcTSIZE (int)sizeof(srcT1)
#endif

#ifdef NEED_MINVAL
#ifdef NEED_MINLOC
#define CALC_MIN(p, inc) \
    if (minval > temp.p) \
    { \
        minval = temp.p; \
        minloc = id + inc; \
    }
#else
#define CALC_MIN(p, inc) \
    minval = MIN(minval, temp.p);
#endif
#else
#define CALC_MIN(p, inc)
#endif

#ifdef NEED_MAXVAL
#ifdef NEED_MAXLOC
#define CALC_MAX(p, inc) \
    if (maxval < temp.p) \
    { \
        maxval = temp.p; \
        maxloc = id + inc; \
    }
#else
#define CALC_MAX(p, inc) \
    maxval = MAX(maxval, temp.p);
#endif
#else
#define CALC_MAX(p, inc)
#endif

#ifdef OP_CALC2
#define CALC_MAX2(p) \
    maxval2 = MAX(maxval2, temp.p);
#else
#define CALC_MAX2(p)
#endif

#define CALC_P(p, inc) \
    CALC_MIN(p, inc) \
    CALC_MAX(p, inc) \
    CALC_MAX2(p)

__kernel void minmaxloc(__global const uchar * srcptr, int src_step, int src_offset, int cols,
                        int total, int groupnum, __global uchar * dstptr
#ifdef HAVE_MASK
                        , __global const uchar * mask, int mask_step, int mask_offset
#endif
#ifdef HAVE_SRC2
                        , __global const uchar * src2ptr, int src2_step, int src2_offset
#endif
                        )
{
    int lid = get_local_id(0);
    int gid = get_group_id(0);
    int  id = get_global_id(0)
#ifndef HAVE_MASK
    * kercn;
#else
    ;
#endif

    srcptr += src_offset;
#ifdef HAVE_MASK
    mask += mask_offset;
#endif
#ifdef HAVE_SRC2
    src2ptr += src2_offset;
#endif

#ifdef NEED_MINVAL
    __local dstT1 localmem_min[WGS2_ALIGNED];
    dstT1 minval = MAX_VAL;
#ifdef NEED_MINLOC
    __local uint localmem_minloc[WGS2_ALIGNED];
    uint minloc = INDEX_MAX;
#endif
#endif
#ifdef NEED_MAXVAL
    dstT1 maxval = MIN_VAL;
    __local dstT1 localmem_max[WGS2_ALIGNED];
#ifdef NEED_MAXLOC
    __local uint localmem_maxloc[WGS2_ALIGNED];
    uint maxloc = INDEX_MAX;
#endif
#endif
#ifdef OP_CALC2
    __local dstT1 localmem_max2[WGS2_ALIGNED];
    dstT1 maxval2 = MIN_VAL;
#endif

    int src_index;
#ifdef HAVE_MASK
    int mask_index;
#endif
#ifdef HAVE_SRC2
    int src2_index;
#endif

    dstT temp;
#ifdef HAVE_SRC2
    dstT temp2;
#endif

    for (int grain = groupnum * WGS
#ifndef HAVE_MASK
        * kercn
#endif
        ; id < total; id += grain)
    {
#ifdef HAVE_MASK
#ifdef HAVE_MASK_CONT
        mask_index = id;
#else
        mask_index = mad24(id / cols, mask_step, id % cols);
#endif
        if (mask[mask_index])
#endif
        {
#ifdef HAVE_SRC_CONT
            src_index = mul24(id, srcTSIZE);
#else
            src_index = mad24(id / cols, src_step, mul24(id % cols, srcTSIZE));
#endif
            temp = convertToDT(loadpix(srcptr + src_index));
#ifdef OP_ABS
            temp = MIN_ABS(temp);
#endif

#ifdef HAVE_SRC2
#ifdef HAVE_SRC2_CONT
            src2_index = mul24(id, srcTSIZE);
#else
            src2_index = mad24(id / cols, src2_step, mul24(id % cols, srcTSIZE));
#endif
            temp2 = convertToDT(loadpix(src2ptr + src2_index));
            temp = MIN_ABS2(temp, temp2);
#ifdef OP_CALC2
            temp2 = MIN_ABS(temp2);
#endif
#endif

#if kercn == 1
#ifdef NEED_MINVAL
#if NEED_MINLOC
            if (minval > temp)
            {
                minval = temp;
                minloc = id;
            }
#else
            minval = MIN(minval, temp);
#endif
#endif
#ifdef NEED_MAXVAL
#ifdef NEED_MAXLOC
            if (maxval < temp)
            {
                maxval = temp;
                maxloc = id;
            }
#else
            maxval = MAX(maxval, temp);
#endif
#ifdef OP_CALC2
            maxval2 = MAX(maxval2, temp2);
#endif
#endif
#elif kercn >= 2
            CALC_P(s0, 0)
            CALC_P(s1, 1)
#if kercn >= 3
            CALC_P(s2, 2)
#if kercn >= 4
            CALC_P(s3, 3)
#if kercn >= 8
            CALC_P(s4, 4)
            CALC_P(s5, 5)
            CALC_P(s6, 6)
            CALC_P(s7, 7)
#if kercn == 16
            CALC_P(s8, 8)
            CALC_P(s9, 9)
            CALC_P(sA, 10)
            CALC_P(sB, 11)
            CALC_P(sC, 12)
            CALC_P(sD, 13)
            CALC_P(sE, 14)
            CALC_P(sF, 15)
#endif
#endif
#endif
#endif
#endif
        }
    }

    if (lid < WGS2_ALIGNED)
    {
#ifdef NEED_MINVAL
        localmem_min[lid] = minval;
#endif
#ifdef NEED_MAXVAL
        localmem_max[lid] = maxval;
#endif
#ifdef NEED_MINLOC
        localmem_minloc[lid] = minloc;
#endif
#ifdef NEED_MAXLOC
        localmem_maxloc[lid] = maxloc;
#endif
#ifdef OP_CALC2
        localmem_max2[lid] = maxval2;
#endif
    }
    barrier(CLK_LOCAL_MEM_FENCE);

    if (lid >= WGS2_ALIGNED && total >= WGS2_ALIGNED)
    {
        int lid3 = lid - WGS2_ALIGNED;
#ifdef NEED_MINVAL
#ifdef NEED_MINLOC
        if (localmem_min[lid3] >= minval)
        {
            if (localmem_min[lid3] == minval)
                localmem_minloc[lid3] = min(localmem_minloc[lid3], minloc);
            else
                localmem_minloc[lid3] = minloc,
            localmem_min[lid3] = minval;
        }
#else
        localmem_min[lid3] = MIN(localmem_min[lid3], minval);
#endif
#endif
#ifdef NEED_MAXVAL
#ifdef NEED_MAXLOC
        if (localmem_max[lid3] <= maxval)
        {
            if (localmem_max[lid3] == maxval)
                localmem_maxloc[lid3] = min(localmem_maxloc[lid3], maxloc);
            else
                localmem_maxloc[lid3] = maxloc,
            localmem_max[lid3] = maxval;
        }
#else
        localmem_max[lid3] = MAX(localmem_max[lid3], maxval);
#endif
#endif
#ifdef OP_CALC2
        localmem_max2[lid3] = MAX(localmem_max2[lid3], maxval2);
#endif
    }
    barrier(CLK_LOCAL_MEM_FENCE);

    for (int lsize = WGS2_ALIGNED >> 1; lsize > 0; lsize >>= 1)
    {
        if (lid < lsize)
        {
            int lid2 = lsize + lid;

#ifdef NEED_MINVAL
#ifdef NEED_MAXLOC
            if (localmem_min[lid] >= localmem_min[lid2])
            {
                if (localmem_min[lid] == localmem_min[lid2])
                    localmem_minloc[lid] = min(localmem_minloc[lid2], localmem_minloc[lid]);
                else
                    localmem_minloc[lid] = localmem_minloc[lid2],
                localmem_min[lid] = localmem_min[lid2];
            }
#else
            localmem_min[lid] = MIN(localmem_min[lid], localmem_min[lid2]);
#endif
#endif
#ifdef NEED_MAXVAL
#ifdef NEED_MAXLOC
            if (localmem_max[lid] <= localmem_max[lid2])
            {
                if (localmem_max[lid] == localmem_max[lid2])
                    localmem_maxloc[lid] = min(localmem_maxloc[lid2], localmem_maxloc[lid]);
                else
                    localmem_maxloc[lid] = localmem_maxloc[lid2],
                localmem_max[lid] = localmem_max[lid2];
            }
#else
            localmem_max[lid] = MAX(localmem_max[lid], localmem_max[lid2]);
#endif
#endif
#ifdef OP_CALC2
            localmem_max2[lid] = MAX(localmem_max2[lid], localmem_max2[lid2]);
#endif
        }
        barrier(CLK_LOCAL_MEM_FENCE);
    }

    if (lid == 0)
    {
        int pos = 0;
#ifdef NEED_MINVAL
        *(__global dstT1 *)(dstptr + mad24(gid, (int)sizeof(dstT1), pos)) = localmem_min[0];
        pos = mad24(groupnum, (int)sizeof(dstT1), pos);
#endif
#ifdef NEED_MAXVAL
        *(__global dstT1 *)(dstptr + mad24(gid, (int)sizeof(dstT1), pos)) = localmem_max[0];
        pos = mad24(groupnum, (int)sizeof(dstT1), pos);
#endif
#ifdef NEED_MINLOC
        *(__global uint *)(dstptr + mad24(gid, (int)sizeof(uint), pos)) = localmem_minloc[0];
        pos = mad24(groupnum, (int)sizeof(uint), pos);
#endif
#ifdef NEED_MAXLOC
        *(__global uint *)(dstptr + mad24(gid, (int)sizeof(uint), pos)) = localmem_maxloc[0];
#ifdef OP_CALC2
        pos = mad24(groupnum, (int)sizeof(uint), pos);
#endif
#endif
#ifdef OP_CALC2
        *(__global dstT1 *)(dstptr + mad24(gid, (int)sizeof(dstT1), pos)) = localmem_max2[0];
#endif
    }
}

// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

// Copyright (C) 2014, Itseez, Inc., all rights reserved.
// Third party copyrights are property of their respective owners.

#ifdef DOUBLE_SUPPORT
#ifdef cl_amd_fp64
#pragma OPENCL EXTENSION cl_amd_fp64:enable
#elif defined (cl_khr_fp64)
#pragma OPENCL EXTENSION cl_khr_fp64:enable
#endif
#endif

#ifdef DEPTH_0
#define MIN_VAL 0
#define MAX_VAL UCHAR_MAX
#elif defined DEPTH_1
#define MIN_VAL SCHAR_MIN
#define MAX_VAL SCHAR_MAX
#elif defined DEPTH_2
#define MIN_VAL 0
#define MAX_VAL USHRT_MAX
#elif defined DEPTH_3
#define MIN_VAL SHRT_MIN
#define MAX_VAL SHRT_MAX
#elif defined DEPTH_4
#define MIN_VAL INT_MIN
#define MAX_VAL INT_MAX
#elif defined DEPTH_5
#define MIN_VAL (-FLT_MAX)
#define MAX_VAL FLT_MAX
#elif defined DEPTH_6
#define MIN_VAL (-DBL_MAX)
#define MAX_VAL DBL_MAX
#endif

#define noconvert
#define INDEX_MAX UINT_MAX

#if wdepth <= 4
#define MIN_ABS(a) convertFromU(abs(a))
#define MIN_ABS2(a, b) convertFromU(abs_diff(a, b))
#else
#define MIN_ABS(a) fabs(a)
#define MIN_ABS2(a, b) fabs(a - b)
#endif

#if kercn != 3
#define loadpix(addr) *(__global const srcT *)(addr)
#define srcTSIZE (int)sizeof(srcT)
#else
#define loadpix(addr) vload3(0, (__global const srcT1 *)(addr))
#define srcTSIZE ((int)sizeof(srcT1) * 3)
#endif

#ifndef HAVE_MASK
#undef srcTSIZE
#define srcTSIZE (int)sizeof(srcT1)
#endif

#ifdef NEED_MINLOC
#define CALC_MINLOC(inc) minloc = id + inc
#else
#define CALC_MINLOC(inc)
#endif

#ifdef NEED_MAXLOC
#define CALC_MAXLOC(inc) maxloc = id + inc
#else
#define CALC_MAXLOC(inc)
#endif

#ifdef NEED_MINVAL
#define CALC_MIN(p, inc) \
    if (minval > temp.p) \
    { \
        minval = temp.p; \
        CALC_MINLOC(inc); \
    }
#else
#define CALC_MIN(p, inc)
#endif

#ifdef NEED_MAXVAL
#define CALC_MAX(p, inc) \
    if (maxval < temp.p) \
    { \
        maxval = temp.p; \
        CALC_MAXLOC(inc); \
    }
#else
#define CALC_MAX(p, inc)
#endif

#ifdef OP_CALC2
#define CALC_MAX2(p) \
    if (maxval2 < temp.p) \
        maxval2 = temp.p;
#else
#define CALC_MAX2(p)
#endif

#define CALC_P(p, inc) \
    CALC_MIN(p, inc) \
    CALC_MAX(p, inc) \
    CALC_MAX2(p)

__kernel void minmaxloc(__global const uchar * srcptr, int src_step, int src_offset, int cols,
                        int total, int groupnum, __global uchar * dstptr
#ifdef HAVE_MASK
                        , __global const uchar * mask, int mask_step, int mask_offset
#endif
#ifdef HAVE_SRC2
                        , __global const uchar * src2ptr, int src2_step, int src2_offset
#endif
                        )
{
    int lid = get_local_id(0);
    int gid = get_group_id(0);
    int  id = get_global_id(0)
#ifndef HAVE_MASK
    * kercn;
#else
    ;
#endif

    srcptr += src_offset;
#ifdef HAVE_MASK
    mask += mask_offset;
#endif
#ifdef HAVE_SRC2
    src2ptr += src2_offset;
#endif

#ifdef NEED_MINVAL
    __local dstT1 localmem_min[WGS2_ALIGNED];
    dstT1 minval = MAX_VAL;
#ifdef NEED_MINLOC
    __local uint localmem_minloc[WGS2_ALIGNED];
    uint minloc = INDEX_MAX;
#endif
#endif
#ifdef NEED_MAXVAL
    dstT1 maxval = MIN_VAL;
    __local dstT1 localmem_max[WGS2_ALIGNED];
#ifdef NEED_MAXLOC
    __local uint localmem_maxloc[WGS2_ALIGNED];
    uint maxloc = INDEX_MAX;
#endif
#endif
#ifdef OP_CALC2
    __local dstT1 localmem_max2[WGS2_ALIGNED];
    dstT1 maxval2 = MIN_VAL;
#endif

    int src_index;
#ifdef HAVE_MASK
    int mask_index;
#endif
#ifdef HAVE_SRC2
    int src2_index;
#endif

    dstT temp;
#ifdef HAVE_SRC2
    dstT temp2;
#endif

    for (int grain = groupnum * WGS
#ifndef HAVE_MASK
        * kercn
#endif
        ; id < total; id += grain)
    {
#ifdef HAVE_MASK
#ifdef HAVE_MASK_CONT
        mask_index = id;
#else
        mask_index = mad24(id / cols, mask_step, id % cols);
#endif
        if (mask[mask_index])
#endif
        {
#ifdef HAVE_SRC_CONT
            src_index = mul24(id, srcTSIZE);
#else
            src_index = mad24(id / cols, src_step, mul24(id % cols, srcTSIZE));
#endif
            temp = convertToDT(loadpix(srcptr + src_index));
#ifdef OP_ABS
            temp = MIN_ABS(temp);
#endif

#ifdef HAVE_SRC2
#ifdef HAVE_SRC2_CONT
            src2_index = mul24(id, srcTSIZE);
#else
            src2_index = mad24(id / cols, src2_step, mul24(id % cols, srcTSIZE));
#endif
            temp2 = convertToDT(loadpix(src2ptr + src2_index));
            temp = MIN_ABS2(temp, temp2);
#ifdef OP_CALC2
            temp2 = MIN_ABS(temp2);
#endif
#endif

#if kercn == 1
#ifdef NEED_MINVAL
            if (minval > temp)
            {
                minval = temp;
#ifdef NEED_MINLOC
                minloc = id;
#endif
            }
#endif
#ifdef NEED_MAXVAL
            if (maxval < temp)
            {
                maxval = temp;
#ifdef NEED_MAXLOC
                maxloc = id;
#endif
            }
#ifdef OP_CALC2
            if (maxval2 < temp2)
                maxval2 = temp2;
#endif
#endif
#elif kercn >= 2
            CALC_P(s0, 0)
            CALC_P(s1, 1)
#if kercn >= 3
            CALC_P(s2, 2)
#if kercn >= 4
            CALC_P(s3, 3)
#if kercn >= 8
            CALC_P(s4, 4)
            CALC_P(s5, 5)
            CALC_P(s6, 6)
            CALC_P(s7, 7)
#if kercn == 16
            CALC_P(s8, 8)
            CALC_P(s9, 9)
            CALC_P(sA, 10)
            CALC_P(sB, 11)
            CALC_P(sC, 12)
            CALC_P(sD, 13)
            CALC_P(sE, 14)
            CALC_P(sF, 15)
#endif
#endif
#endif
#endif
#endif
        }
    }

    if (lid < WGS2_ALIGNED)
    {
#ifdef NEED_MINVAL
        localmem_min[lid] = minval;
#endif
#ifdef NEED_MAXVAL
        localmem_max[lid] = maxval;
#endif
#ifdef NEED_MINLOC
        localmem_minloc[lid] = minloc;
#endif
#ifdef NEED_MAXLOC
        localmem_maxloc[lid] = maxloc;
#endif
#ifdef OP_CALC2
        localmem_max2[lid] = maxval2;
#endif
    }
    barrier(CLK_LOCAL_MEM_FENCE);

    if (lid >= WGS2_ALIGNED && total >= WGS2_ALIGNED)
    {
        int lid3 = lid - WGS2_ALIGNED;
#ifdef NEED_MINVAL
        if (localmem_min[lid3] >= minval)
        {
#ifdef NEED_MINLOC
            if (localmem_min[lid3] == minval)
                localmem_minloc[lid3] = min(localmem_minloc[lid3], minloc);
            else
                localmem_minloc[lid3] = minloc,
#endif
                localmem_min[lid3] = minval;
        }
#endif
#ifdef NEED_MAXVAL
        if (localmem_max[lid3] <= maxval)
        {
#ifdef NEED_MAXLOC
            if (localmem_max[lid3] == maxval)
                localmem_maxloc[lid3] = min(localmem_maxloc[lid3], maxloc);
            else
                localmem_maxloc[lid3] = maxloc,
#endif
                localmem_max[lid3] = maxval;
        }
#endif
#ifdef OP_CALC2
        if (localmem_max2[lid3] < maxval2)
            localmem_max2[lid3] = maxval2;
#endif
    }
    barrier(CLK_LOCAL_MEM_FENCE);

    for (int lsize = WGS2_ALIGNED >> 1; lsize > 0; lsize >>= 1)
    {
        if (lid < lsize)
        {
            int lid2 = lsize + lid;

#ifdef NEED_MINVAL
            if (localmem_min[lid] >= localmem_min[lid2])
            {
#ifdef NEED_MINLOC
                if (localmem_min[lid] == localmem_min[lid2])
                    localmem_minloc[lid] = min(localmem_minloc[lid2], localmem_minloc[lid]);
                else
                    localmem_minloc[lid] = localmem_minloc[lid2],
#endif
                    localmem_min[lid] = localmem_min[lid2];
            }
#endif
#ifdef NEED_MAXVAL
            if (localmem_max[lid] <= localmem_max[lid2])
            {
#ifdef NEED_MAXLOC
                if (localmem_max[lid] == localmem_max[lid2])
                    localmem_maxloc[lid] = min(localmem_maxloc[lid2], localmem_maxloc[lid]);
                else
                    localmem_maxloc[lid] = localmem_maxloc[lid2],
#endif
                    localmem_max[lid] = localmem_max[lid2];
            }
#endif
#ifdef OP_CALC2
            if (localmem_max2[lid] < localmem_max2[lid2])
                localmem_max2[lid] = localmem_max2[lid2];
#endif
        }
        barrier(CLK_LOCAL_MEM_FENCE);
    }

    if (lid == 0)
    {
        int pos = 0;
#ifdef NEED_MINVAL
        *(__global dstT1 *)(dstptr + mad24(gid, (int)sizeof(dstT1), pos)) = localmem_min[0];
        pos = mad24(groupnum, (int)sizeof(dstT1), pos);
#endif
#ifdef NEED_MAXVAL
        *(__global dstT1 *)(dstptr + mad24(gid, (int)sizeof(dstT1), pos)) = localmem_max[0];
        pos = mad24(groupnum, (int)sizeof(dstT1), pos);
#endif
#ifdef NEED_MINLOC
        *(__global uint *)(dstptr + mad24(gid, (int)sizeof(uint), pos)) = localmem_minloc[0];
        pos = mad24(groupnum, (int)sizeof(uint), pos);
#endif
#ifdef NEED_MAXLOC
        *(__global uint *)(dstptr + mad24(gid, (int)sizeof(uint), pos)) = localmem_maxloc[0];
#ifdef OP_CALC2
        pos = mad24(groupnum, (int)sizeof(uint), pos);
#endif
#endif
#ifdef OP_CALC2
        *(__global dstT1 *)(dstptr + mad24(gid, (int)sizeof(dstT1), pos)) = localmem_max2[0];
#endif
    }
}


added image gradient 3d kernels

added image gradient 3d kernels

__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;

#ifdef TYPE_UINT
#define READ_IMAGE (float)read_imageui
#elif TYPE_INT
#define READ_IMAGE (float)read_imagei
#elif TYPE_FLOAT
#define READ_IMAGE read_imagef
#endif

__kernel void gradient2D(
        __read_only image2d_t input,
        __write_only image2d_t output
        ) {
    const int2 pos = {get_global_id(0), get_global_id(1)};

    // TODO take pixel spacing into account
    float4 gradient = {
            (READ_IMAGE(input, sampler, pos+(int2)(1,0)).x - READ_IMAGE(input, sampler, pos-(int2)(1,0)).x)/2.0f,
            (READ_IMAGE(input, sampler, pos+(int2)(0,1)).x - READ_IMAGE(input, sampler, pos-(int2)(0,1)).x)/2.0f,
            0,0
    };
    write_imagef(output, pos, gradient);
}

#ifdef cl_khr_3d_image_writes
__kernel void gradient3D(
        __read_only image3d_t input,
        __write_only image3d_t output
        ) {
    const int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0};

    // TODO take pixel spacing into account
    float4 gradient = {
            (READ_IMAGE(input, sampler, pos+(int4)(1,0,0,0)).x - READ_IMAGE(input, sampler, pos-(int4)(1,0,0,0)).x)*0.5f,
            (READ_IMAGE(input, sampler, pos+(int4)(0,1,0,0)).x - READ_IMAGE(input, sampler, pos-(int4)(0,1,0,0)).x)*0.5f,
            (READ_IMAGE(input, sampler, pos+(int4)(0,0,1,0)).x - READ_IMAGE(input, sampler, pos-(int4)(0,0,1,0)).x)*0.5f,
            0
    };
    write_imagef(output, pos, gradient);
}
#else // cl_khr_3d_image_writes
__kernel void gradient3D(
        __read_only image3d_t input,
        __global float* output
        ) {
    const int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0};

    // TODO take pixel spacing into account
    float4 gradient = {
            (READ_IMAGE(input, sampler, pos+(int4)(1,0,0,0)).x - READ_IMAGE(input, sampler, pos-(int4)(1,0,0,0)).x)*0.5f,
            (READ_IMAGE(input, sampler, pos+(int4)(0,1,0,0)).x - READ_IMAGE(input, sampler, pos-(int4)(0,1,0,0)).x)*0.5f,
            (READ_IMAGE(input, sampler, pos+(int4)(0,0,1,0)).x - READ_IMAGE(input, sampler, pos-(int4)(0,0,1,0)).x)*0.5f,
            0
    };
    vstore3(gradient, pos.x()+pos.y()*get_global_size(0)+pos.z()*get_global_size(0)*get_global_size(1), output);
}
#endif // cl_khr_3d_image_writes

__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;

#ifdef TYPE_UINT
#define READ_IMAGE (float)read_imageui
#elif TYPE_INT
#define READ_IMAGE (float)read_imagei
#elif TYPE_FLOAT
#define READ_IMAGE read_imagef
#endif

__kernel void gradient2D(
        __read_only image2d_t input,
        __write_only image2d_t output
        ) {
    const int2 pos = {get_global_id(0), get_global_id(1)};

    // TODO take pixel spacing into account
    float4 gradient = {
            (READ_IMAGE(input, sampler, pos+(int2)(1,0)).x - READ_IMAGE(input, sampler, pos-(int2)(1,0)).x)/2.0f,
            (READ_IMAGE(input, sampler, pos+(int2)(0,1)).x - READ_IMAGE(input, sampler, pos-(int2)(0,1)).x)/2.0f,
            0,0
    };
    //printf("gradient: %f %f\n", READ_IMAGE(input, sampler, pos+(int2)(0,1)).x, gradient.y);
    write_imagef(output, pos, gradient);
}


added a condition for avoid using an ambient light during computing

#include "kernel_header.h"
#include "kernel_color.h"
#include "kernel_data.h"
#include "kernel_vector.h"

float3					get_sphere_abc(float radius, float3 ray, float3 origin)
{
	float3		abc;

	abc.x = dot_vect(ray, ray);
	abc.y = 2 * dot_vect(ray, origin);
	abc.z = dot_vect(origin, origin) - (radius * radius);
	return (abc);
}

float					inter_sphere(t_sphere sphere, float3 ray, float3 origin)
{
	float3				abc;
	float				d;
	float				res1;
	float				res2;

	origin -= sphere.pos;
	abc = get_sphere_abc(sphere.radius, ray, origin);
	d = (abc.y * abc.y) - (4 * (abc.x * abc.z));
	if (d < 0)
		return (0);
	if (d == 0)
		return ((-abc[1]) / (2 * abc[0]));
	res1 = (((-abc[1]) + sqrt(d)) / (2 * abc[0]));
	res2 = (((-abc[1]) - sqrt(d)) / (2 * abc[0]));
	if ((res1 < res2 && res1 > 0) || (res1 > res2 && res2 < 0))
		return (res1);
	return (res2);
}

float3					get_cylinder_abc(float radius, float3 dir, float3 ray, float3 origin)
{
	float3		abc;

	abc.x = dot_vect(ray, ray) - (dot_vect(ray, dir) * dot_vect(ray, dir));
	abc.y = 2 * (dot_vect(ray, origin) - (dot_vect(ray, dir) * dot_vect(origin, dir)));
	abc.z = dot_vect(origin, origin) - (dot_vect(origin, dir) * dot_vect(origin, dir)) - (radius * radius);
	return (abc);
}

float					inter_cylinder(t_cylinder cylind, float3 ray, float3 origin)
{
	float3				abc;
	float				d;
	float				res1;
	float				res2;

	origin -= cylind.pos;
	abc = get_cylinder_abc(cylind.radius, normalize(cylind.dir), ray, origin);
	d = (abc.y * abc.y) - (4 * (abc.x * abc.z));
	if (d < 0)
		return (0);
	if (d == 0)
		return ((-abc[1]) / (2 * abc[0]));
	res1 = (((-abc[1]) + sqrt(d)) / (2 * abc[0]));
	res2 = (((-abc[1]) - sqrt(d)) / (2 * abc[0]));
	if (res1 < 0 && res2 < 0)
		return (0);
	if ((res1 < res2 && res1 > 0) || (res1 > res2 && res2 < 0))
	{
		if (cylind.height == 0 || (dot_vect(ray, normalize(cylind.dir) * res1 +
			dot_vect(origin, normalize(cylind.dir))) < cylind.height && dot_vect(ray, normalize(cylind.dir) * res1 +
			dot_vect(origin, normalize(cylind.dir))) > 0))
			return (res1);
	}
	if (cylind.height ==  0 || (dot_vect(ray, normalize(cylind.dir) * res2 +
			dot_vect(origin, normalize(cylind.dir))) < cylind.height && dot_vect(ray, normalize(cylind.dir) * res2 +
			dot_vect(origin, normalize(cylind.dir))) > 0))
		return (res2);
	else
		return (0);
}

float3					get_cone_abc(t_cone cone, float3 ray, float3 origin)
{
	float3		abc;
	float		k = cone.angle * DEG2RAD;
	k = tan(k);
	k = 1 + k * k;

	abc.x = dot_vect(ray, ray) - (k * (dot_vect(ray, cone.dir) * dot_vect(ray, cone.dir)));
	abc.y = 2 * (dot_vect(ray, origin) - (k * \
			(dot_vect(ray, cone.dir) * dot_vect(origin, cone.dir))));
	abc.z = (dot_vect(origin, origin) - \
			(k * (dot_vect(origin, cone.dir) * dot_vect(origin, cone.dir))));
	return (abc);
}

float					inter_cone(t_cone cone, float3 ray, float3 origin)
{
	float3				abc;
	float				d;
	float				res1;
	float				res2;
	float				res;

	origin -= cone.pos;
	abc = get_cone_abc(cone, ray, origin);
	d = (abc.y * abc.y) - (4 * (abc.x * abc.z));
	if (d < 0)
		return (0);
	if (d == 0)
		res = (-abc[1]) / (2 * abc[0]);
	res1 = (((-abc[1]) + sqrt(d)) / (2 * abc[0]));
	res2 = (((-abc[1]) - sqrt(d)) / (2 * abc[0]));
	if ((res1 < res2 && res1 > 0) || (res1 > res2 && res2 < 0))
		res = res1;
	else
		res = res2;
	return (res);
}

float					inter_plan(t_plane plane, float3 ray, float3 origin)
{
	float				t;

	if ((t = dot_vect(normalize(ray), normalize(plane.normale))) == 0)
		return (0);
	t = (dot_vect(plane.pos - origin, normalize(plane.normale))) / t;
		if (t < 0.001)
		return (0);
	return (t);
}

unsigned int			light_angle(float angle, unsigned int obj_color, t_scene scene)
{
	unsigned int		r = (obj_color & 0x00FF0000) >> 16;
	unsigned int		g = (obj_color & 0x0000FF00) >> 8;
	unsigned int		b = (obj_color & 0x000000FF);
	float				mult = scene.param->bloom * angle;

	//if (angle <= 0)
	//	return (obj_color);
	if (mult > r)
		r = 0;
	else if ((r -= mult) > 255)
		r = 255;
	if (mult > g)
		g = 0;
	else if ((g -= mult) > 255)
		g = 255;
	if (mult > b)
		b = 0;
	else if ((b -= mult) > 255)
		b = 255;
	return ((r << 16) + (g << 8) + b);
}

unsigned int			get_obj_hue(t_scene scene, t_hit hit)
{
	unsigned int		color = 0;

	if (hit.type == 1)
		color = CONES[hit.id].color;
	if (hit.type == 2)
		color = CYLIND[hit.id].color;
	if (hit.type == 4)
		color = PLANE[hit.id].color;
	if (hit.type == 5)
		color = SPHERE[hit.id].color;
	return (color);
}

float					light_angelamerkel(t_hit hit, t_light_ray light_ray)
{
	float				cos_angela;
	float				angela;

	cos_angela = dot_vect(light_ray.dir, hit.normale) / (norme_vect(light_ray.dir) * norme_vect(hit.normale));
	angela = acos(cos_angela) * RAD2DEG;
	//printf("%f\n", angela);
	return (angela);
}

t_hit			ray_hit(float3 origin, float3 ray, t_scene scene)
{
	unsigned int			i = 0;
	int			max = get_max_obj(PARAM);
	t_hit		hit;
	float		dist = 0;

	hit.dist = 0;
	hit.type = 0;
	hit.id = 0;
	hit.pos = (0, 0, 0);
	hit.normale = (0, 0, 0);

//	printf("dist = %i\n", PARAM->n_cones);
	while (i < max)
	{
		if (i < PARAM->n_cones)
			if (((dist = inter_cone(CONES[i], ray, origin)) < hit.dist || hit.dist == 0) && dist > 0)
			{
				hit.dist = dist;
				hit.type = 1;
				hit.id = i;
			}
		if (i < PARAM->n_cylinders)
			if (((dist = inter_cylinder(CYLIND[i], ray, origin)) < hit.dist || hit.dist == 0) && dist > 0)
			{
				hit.dist = dist;
				hit.type = 2;
				hit.id = i;
			}
		if (i < PARAM->n_planes)
			if (((dist = inter_plan(PLANE[i], ray, origin)) < hit.dist || hit.dist == 0) && dist > 0)
			{
				hit.dist = dist;
				hit.type = 4;
				hit.id = i;
		//		printf("weeeee");
			}
		if (i < PARAM->n_spheres)
			if (((dist = inter_sphere(SPHERE[i], ray, origin)) < hit.dist || hit.dist == 0) && dist > 0)
			{
				hit.dist = dist;
				hit.type = 5;
				hit.id = i;
			}
		i++;
	}
	return (hit);
}

float3			get_hit_normale(t_scene scene, t_hit hit)
{
	float3		res;

	if (hit.type == 1)
	{
		float k = CONES[hit.id].angle * DEG2RAD;
		k = tan(k);
		k = 1 + k * k;
		res = dot_vect(scene.ray, normalize(CONES[hit.id].dir)) * \
			hit.dist - dot_vect(ACTIVECAM.pos + PARAM->mvt - CONES[hit.id].pos, normalize(CONES[hit.id].dir));
		res = (hit.pos - normalize(CONES[hit.id].pos)) - (k * normalize(CONES[hit.id].dir) * res);
		if (dot_vect(CONES[hit.id].pos - hit.pos, normalize(CONES[hit.id].dir)) > 0)
			res = -res;
	}
	else if (hit.type == 2)
	{
		res = dot_vect(scene.ray, normalize(CYLIND[hit.id].dir) * hit.dist + \
			dot_vect(ACTIVECAM.pos + PARAM->mvt - CYLIND[hit.id].pos, normalize(CYLIND[hit.id].dir)));
		res = (hit.pos - CYLIND[hit.id].pos) - (normalize(CYLIND[hit.id].dir) * res);
	}
	else if (hit.type == 4) // bizarrement on fait l'inverse de ce qu'on peut voir dans le code d'autres personnes
	{
		if (dot_vect(PLANE[hit.id].normale, scene.ray) < 0)
			res = PLANE[hit.id].normale;
		else
			res = -PLANE[hit.id].normale;
	}
	else if (hit.type == 5)
		res = hit.pos - SPHERE[hit.id].pos;
	return (normalize(res));
}

unsigned int			light(t_hit hit, t_scene scene)
{
	int					i = -1;
	float				angle = 0;
	t_light_ray			light_ray;
	t_hit				light_hit;
	unsigned int		obj_color = get_obj_hue(scene, hit);
	unsigned int		ambiant_color = blend_ambiant(obj_color);//light_angle(120, obj_color, scene);
	unsigned int		res_color = 0;
	unsigned int		tmp_color = 0;

	//	printf("%u\n", obj_color);
	while (++i < PARAM->n_lights)
	{
		if (LIGHT[i].type != 0)
		{
			light_ray.dir = LIGHT[i].pos - hit.pos;
			light_ray.dist = norme_vect(light_ray.dir);
			light_ray.dir = normalize(light_ray.dir);
			light_hit = ray_hit(hit.pos, light_ray.dir, scene);
			if (light_hit.dist < light_ray.dist && light_hit.dist > 0)
			;//	printf("%f\n", light_hit.dist);
			else
			{
				angle = light_angelamerkel(hit, light_ray);
				if ((tmp_color = light_angle(angle, obj_color, scene)) < ambiant_color)
					tmp_color = ambiant_color;
				res_color = blend_add(res_color, tmp_color);
			}
		}
	}
	if (res_color == 0)
		res_color = ambiant_color;
	return (res_color);
}

unsigned int	get_pixel_color(t_scene scene)
{
	t_hit		hit;
	float		bias = 0.000001;

	// PARAM mvt pour mouvement de la camera remplacable par position de la cam
	// directement incrementee?
	hit = ray_hit((ACTIVECAM.pos + PARAM->mvt), scene.ray, scene);
	if (hit.dist > 0)
	{
		hit.pos = mult_fvect(hit.dist, scene.ray) + (ACTIVECAM.pos + PARAM->mvt);
		hit.normale = get_hit_normale(scene, hit);
		if (hit.type == 4)
			hit.pos = hit.pos + ((bias + hit.dist / 5) * hit.normale);
		else
			hit.pos = hit.pos + ((bias + hit.dist / 200) * hit.normale);
		return (light(hit, scene));
	}
	return (BACKCOLOR);
}

// OLD CAN BE DELETED
/*float3					get_ray_cam(t_cam cam, int x, int y)
{
	float3				ray;
	float3				h = mult_fvect(modh_vect(x), cam.hor);
	float3				v = mult_fvect(modv_vect(y), cam.ver);

	ray = normalize(cam.dir) + v + h;
	return (normalize(ray));
}
*/

float3						get_ray_cam(t_cam cam, t_scene scene, int x, int y)
{
	float3					cam_ray;
	float					ratio = (float)PARAM->win_w / (float)PARAM->win_h;
	cam_ray.x = ((2 * ((x + 0.5) / PARAM->win_w)) - 1) * ratio * (tan((PARAM->fov / 2) * DEG2RAD));
//	cam_ray.x += sin(cam_ray.x * 10) / 10.0; // deformation kikoolol
	cam_ray.y = ((1 - (2 * ((y + 0.5) / PARAM->win_h))) * tan((PARAM->fov / 2) * DEG2RAD));
	cam_ray.z = cam.dir.z;
	return(normalize(cam_ray));
}

__kernel void	ray_trace(__global char *output,
						  t_param param,
						  __constant t_cam *cameras,
						  __constant t_cone *cones,
						  __constant t_cylinder *cylinders,
						  __constant t_light *lights,
						  __constant t_plane *planes,
						  __constant t_sphere *spheres)
{
	t_scene scene = grab_data(cameras, cones, cylinders, lights, planes, spheres, param);
	int		x = get_global_id(0);
	int		y = get_global_id(1);
	int		id = x + (PARAM->win_w * y);
	scene.ray = get_ray_cam(ACTIVECAM, scene, x ,y);
	OUTPUTE = get_pixel_color(scene);
}

#include "kernel_header.h"
#include "kernel_color.h"
#include "kernel_data.h"
#include "kernel_vector.h"

float3					get_sphere_abc(float radius, float3 ray, float3 origin)
{
	float3		abc;

	abc.x = dot_vect(ray, ray);
	abc.y = 2 * dot_vect(ray, origin);
	abc.z = dot_vect(origin, origin) - (radius * radius);
	return (abc);
}

float					inter_sphere(t_sphere sphere, float3 ray, float3 origin)
{
	float3				abc;
	float				d;
	float				res1;
	float				res2;

	origin -= sphere.pos;
	abc = get_sphere_abc(sphere.radius, ray, origin);
	d = (abc.y * abc.y) - (4 * (abc.x * abc.z));
	if (d < 0)
		return (0);
	if (d == 0)
		return ((-abc[1]) / (2 * abc[0]));
	res1 = (((-abc[1]) + sqrt(d)) / (2 * abc[0]));
	res2 = (((-abc[1]) - sqrt(d)) / (2 * abc[0]));
	if ((res1 < res2 && res1 > 0) || (res1 > res2 && res2 < 0))
		return (res1);
	return (res2);
}

float3					get_cylinder_abc(float radius, float3 dir, float3 ray, float3 origin)
{
	float3		abc;

	abc.x = dot_vect(ray, ray) - (dot_vect(ray, dir) * dot_vect(ray, dir));
	abc.y = 2 * (dot_vect(ray, origin) - (dot_vect(ray, dir) * dot_vect(origin, dir)));
	abc.z = dot_vect(origin, origin) - (dot_vect(origin, dir) * dot_vect(origin, dir)) - (radius * radius);
	return (abc);
}

float					inter_cylinder(t_cylinder cylind, float3 ray, float3 origin)
{
	float3				abc;
	float				d;
	float				res1;
	float				res2;

	origin -= cylind.pos;
	abc = get_cylinder_abc(cylind.radius, normalize(cylind.dir), ray, origin);
	d = (abc.y * abc.y) - (4 * (abc.x * abc.z));
	if (d < 0)
		return (0);
	if (d == 0)
		return ((-abc[1]) / (2 * abc[0]));
	res1 = (((-abc[1]) + sqrt(d)) / (2 * abc[0]));
	res2 = (((-abc[1]) - sqrt(d)) / (2 * abc[0]));
	if (res1 < 0 && res2 < 0)
		return (0);
	if ((res1 < res2 && res1 > 0) || (res1 > res2 && res2 < 0))
	{
		if (cylind.height == 0 || (dot_vect(ray, normalize(cylind.dir) * res1 +
			dot_vect(origin, normalize(cylind.dir))) < cylind.height && dot_vect(ray, normalize(cylind.dir) * res1 +
			dot_vect(origin, normalize(cylind.dir))) > 0))
			return (res1);
	}
	if (cylind.height ==  0 || (dot_vect(ray, normalize(cylind.dir) * res2 +
			dot_vect(origin, normalize(cylind.dir))) < cylind.height && dot_vect(ray, normalize(cylind.dir) * res2 +
			dot_vect(origin, normalize(cylind.dir))) > 0))
		return (res2);
	else
		return (0);
}

float3					get_cone_abc(t_cone cone, float3 ray, float3 origin)
{
	float3		abc;
	float		k = cone.angle * DEG2RAD;
	k = tan(k);
	k = 1 + k * k;

	abc.x = dot_vect(ray, ray) - (k * (dot_vect(ray, cone.dir) * dot_vect(ray, cone.dir)));
	abc.y = 2 * (dot_vect(ray, origin) - (k * \
			(dot_vect(ray, cone.dir) * dot_vect(origin, cone.dir))));
	abc.z = (dot_vect(origin, origin) - \
			(k * (dot_vect(origin, cone.dir) * dot_vect(origin, cone.dir))));
	return (abc);
}

float					inter_cone(t_cone cone, float3 ray, float3 origin)
{
	float3				abc;
	float				d;
	float				res1;
	float				res2;
	float				res;

	origin -= cone.pos;
	abc = get_cone_abc(cone, ray, origin);
	d = (abc.y * abc.y) - (4 * (abc.x * abc.z));
	if (d < 0)
		return (0);
	if (d == 0)
		res = (-abc[1]) / (2 * abc[0]);
	res1 = (((-abc[1]) + sqrt(d)) / (2 * abc[0]));
	res2 = (((-abc[1]) - sqrt(d)) / (2 * abc[0]));
	if ((res1 < res2 && res1 > 0) || (res1 > res2 && res2 < 0))
		res = res1;
	else
		res = res2;
	return (res);
}

float					inter_plan(t_plane plane, float3 ray, float3 origin)
{
	float				t;

	if ((t = dot_vect(normalize(ray), normalize(plane.normale))) == 0)
		return (0);
	t = (dot_vect(plane.pos - origin, normalize(plane.normale))) / t;
		if (t < 0.001)
		return (0);
	return (t);
}

unsigned int			light_angle(float angle, unsigned int obj_color, t_scene scene)
{
	unsigned int		r = (obj_color & 0x00FF0000) >> 16;
	unsigned int		g = (obj_color & 0x0000FF00) >> 8;
	unsigned int		b = (obj_color & 0x000000FF);
	float				mult = scene.param->bloom * angle;

	//if (angle <= 0)
	//	return (obj_color);
	if (mult > r)
		r = 0;
	else if ((r -= mult) > 255)
		r = 255;
	if (mult > g)
		g = 0;
	else if ((g -= mult) > 255)
		g = 255;
	if (mult > b)
		b = 0;
	else if ((b -= mult) > 255)
		b = 255;
	return ((r << 16) + (g << 8) + b);
}

unsigned int			get_obj_hue(t_scene scene, t_hit hit)
{
	unsigned int		color = 0;

	if (hit.type == 1)
		color = CONES[hit.id].color;
	if (hit.type == 2)
		color = CYLIND[hit.id].color;
	if (hit.type == 4)
		color = PLANE[hit.id].color;
	if (hit.type == 5)
		color = SPHERE[hit.id].color;
	return (color);
}

float					light_angelamerkel(t_hit hit, t_light_ray light_ray)
{
	float				cos_angela;
	float				angela;

	cos_angela = dot_vect(light_ray.dir, hit.normale) / (norme_vect(light_ray.dir) * norme_vect(hit.normale));
	angela = acos(cos_angela) * RAD2DEG;
	//printf("%f\n", angela);
	return (angela);
}

t_hit			ray_hit(float3 origin, float3 ray, t_scene scene)
{
	unsigned int			i = 0;
	int			max = get_max_obj(PARAM);
	t_hit		hit;
	float		dist = 0;

	hit.dist = 0;
	hit.type = 0;
	hit.id = 0;
	hit.pos = (0, 0, 0);
	hit.normale = (0, 0, 0);

//	printf("dist = %i\n", PARAM->n_cones);
	while (i < max)
	{
		if (i < PARAM->n_cones)
			if (((dist = inter_cone(CONES[i], ray, origin)) < hit.dist || hit.dist == 0) && dist > 0)
			{
				hit.dist = dist;
				hit.type = 1;
				hit.id = i;
			}
		if (i < PARAM->n_cylinders)
			if (((dist = inter_cylinder(CYLIND[i], ray, origin)) < hit.dist || hit.dist == 0) && dist > 0)
			{
				hit.dist = dist;
				hit.type = 2;
				hit.id = i;
			}
		if (i < PARAM->n_planes)
			if (((dist = inter_plan(PLANE[i], ray, origin)) < hit.dist || hit.dist == 0) && dist > 0)
			{
				hit.dist = dist;
				hit.type = 4;
				hit.id = i;
		//		printf("weeeee");
			}
		if (i < PARAM->n_spheres)
			if (((dist = inter_sphere(SPHERE[i], ray, origin)) < hit.dist || hit.dist == 0) && dist > 0)
			{
				hit.dist = dist;
				hit.type = 5;
				hit.id = i;
			}
		i++;
	}
	return (hit);
}

float3			get_hit_normale(t_scene scene, t_hit hit)
{
	float3		res;

	if (hit.type == 1)
	{
		float k = CONES[hit.id].angle * DEG2RAD;
		k = tan(k);
		k = 1 + k * k;
		res = dot_vect(scene.ray, normalize(CONES[hit.id].dir)) * \
			hit.dist - dot_vect(ACTIVECAM.pos + PARAM->mvt - CONES[hit.id].pos, normalize(CONES[hit.id].dir));
		res = (hit.pos - normalize(CONES[hit.id].pos)) - (k * normalize(CONES[hit.id].dir) * res);
		if (dot_vect(CONES[hit.id].pos - hit.pos, normalize(CONES[hit.id].dir)) > 0)
			res = -res;
	}
	else if (hit.type == 2)
	{
		res = dot_vect(scene.ray, normalize(CYLIND[hit.id].dir) * hit.dist + \
			dot_vect(ACTIVECAM.pos + PARAM->mvt - CYLIND[hit.id].pos, normalize(CYLIND[hit.id].dir)));
		res = (hit.pos - CYLIND[hit.id].pos) - (normalize(CYLIND[hit.id].dir) * res);
	}
	else if (hit.type == 4) // bizarrement on fait l'inverse de ce qu'on peut voir dans le code d'autres personnes
	{
		if (dot_vect(PLANE[hit.id].normale, scene.ray) < 0)
			res = PLANE[hit.id].normale;
		else
			res = -PLANE[hit.id].normale;
	}
	else if (hit.type == 5)
		res = hit.pos - SPHERE[hit.id].pos;
	return (normalize(res));
}

unsigned int			light(t_hit hit, t_scene scene)
{
	int					i = -1;
	float				angle = 0;
	t_light_ray			light_ray;
	t_hit				light_hit;
	unsigned int		obj_color = get_obj_hue(scene, hit);
	unsigned int		ambiant_color = blend_ambiant(obj_color);//light_angle(120, obj_color, scene);
	unsigned int		res_color = 0;
	unsigned int		tmp_color = 0;

	//	printf("%u\n", obj_color);
	while (++i < PARAM->n_lights)
	{
		light_ray.dir = LIGHT[i].pos - hit.pos;
		light_ray.dist = norme_vect(light_ray.dir);
		light_ray.dir = normalize(light_ray.dir);
		light_hit = ray_hit(hit.pos, light_ray.dir, scene);
		if (light_hit.dist < light_ray.dist && light_hit.dist > 0)
		;//	printf("%f\n", light_hit.dist);
		else
		{
			angle = light_angelamerkel(hit, light_ray);
			if ((tmp_color = light_angle(angle, obj_color, scene)) < ambiant_color)
				tmp_color = ambiant_color;
			res_color = blend_add(res_color, tmp_color);
		}
	}
	if (res_color == 0)
		res_color = ambiant_color;
	return (res_color);
}

unsigned int	get_pixel_color(t_scene scene)
{
	t_hit		hit;
	float		bias = 0.000001;

	// PARAM mvt pour mouvement de la camera remplacable par position de la cam
	// directement incrementee?
	hit = ray_hit((ACTIVECAM.pos + PARAM->mvt), scene.ray, scene);
	if (hit.dist > 0)
	{
		hit.pos = mult_fvect(hit.dist, scene.ray) + (ACTIVECAM.pos + PARAM->mvt);
		hit.normale = get_hit_normale(scene, hit);
		if (hit.type == 4)
			hit.pos = hit.pos + ((bias + hit.dist / 5) * hit.normale);
		else
			hit.pos = hit.pos + ((bias + hit.dist / 200) * hit.normale);
		return (light(hit, scene));
	}
	return (BACKCOLOR);
}

// OLD CAN BE DELETED
/*float3					get_ray_cam(t_cam cam, int x, int y)
{
	float3				ray;
	float3				h = mult_fvect(modh_vect(x), cam.hor);
	float3				v = mult_fvect(modv_vect(y), cam.ver);

	ray = normalize(cam.dir) + v + h;
	return (normalize(ray));
}
*/

float3						get_ray_cam(t_cam cam, t_scene scene, int x, int y)
{
	float3					cam_ray;
	float					ratio = (float)PARAM->win_w / (float)PARAM->win_h;
	cam_ray.x = ((2 * ((x + 0.5) / PARAM->win_w)) - 1) * ratio * (tan((PARAM->fov / 2) * DEG2RAD));
//	cam_ray.x += sin(cam_ray.x * 10) / 10.0; // deformation kikoolol
	cam_ray.y = ((1 - (2 * ((y + 0.5) / PARAM->win_h))) * tan((PARAM->fov / 2) * DEG2RAD));
	cam_ray.z = cam.dir.z;
	return(normalize(cam_ray));
}

__kernel void	ray_trace(__global char *output,
						  t_param param,
						  __constant t_cam *cameras,
						  __constant t_cone *cones,
						  __constant t_cylinder *cylinders,
						  __constant t_light *lights,
						  __constant t_plane *planes,
						  __constant t_sphere *spheres)
{
	t_scene scene = grab_data(cameras, cones, cylinders, lights, planes, spheres, param);
	int		x = get_global_id(0);
	int		y = get_global_id(1);
	int		id = x + (PARAM->win_w * y);
	scene.ray = get_ray_cam(ACTIVECAM, scene, x ,y);
	OUTPUTE = get_pixel_color(scene);
}


minor fixup from debugging

minor fixup from debugging

#include "util_common.cl"

kernel void img_proc_rgb_luminosity(global float const input [/*3 * size.x * size.y*/]
                                   ,global float       output[/*    size.x * size.y*/]
                                   ,       uint2 const img_size
                                   ) {
    assert(get_work_dim()       == 1                  );
    assert(get_global_size(0)   == dim_size(img_size) );

    size_t const idx                  = get_global_id(0);
    assert(idx                  <  dim_size(img_size) );

    float3 const k_rgb_to_luminosity  = (float3)(0.299, 0.587, 0.114);
    float3 const rgb                  = vload3(idx, input);
    output[idx] = dot(rgb, k_rgb_to_luminosity);
}

#include "util_common.cl"

kernel void img_proc_rgb_luminosity(global float const input [/*3 * size.x * size.y*/]
                                   ,global float       output[/*    size.x * size.y*/]
                                   ,       uint2 const img_size
                                   ) {
    assert(get_work_dim()       == 1                  );
    assert(get_global_size(0)   == dim_size(img_size) );

    size_t const idx                  = get_global_id(0);
    assert(idx                  <  dim_size(img_size) );

    float3 const k_rgb_to_luminosity  = (float3)(0.299, 0.587, 0.114);
    float3 const rgb                  = (float3)(input[idx * 3 + 0]
                                                ,input[idx * 3 + 1]
                                                ,input[idx * 3 + 2]);
    output[idx] = dot(rgb, k_rgb_to_luminosity);
}


removing old file

removing old file

__kernel void simplexnoise(__read_only image2d_t random_values, __write_only image2d_t heightmap, __global float* frequency, __global float* persistence, __global int* octaves)
{
    int x = get_global_id(0);
	int y = get_global_id(1);

	int2 coord = (int2) (x, y);

	float out = octave_noise_2d(*octaves, *persistence, *frequency, x, y);
	float4 outvalue;
	outvalue.x = out;
	outvalue.y = out;
	outvalue.z = out;
	outvalue.w = 1.0f;
	write_imagef(heightmap, coord, outvalue);
}