1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
kernel void
REMAPKERNEL(global uint32_t* g_odata, read_only image2d_t tex,
int panoWidth, int panoHeight,
const float2 inPanoScale, const float2 outPanoScale, const vsfloat3x3 R) {
const int x = (int)get_global_id(0);
const int y = (int)get_global_id(1);
if (OUTPUTCROPPER(x, y, panoWidth, panoHeight)) {
float2 uv = make_float2((float)x, (float)y);
/**
* The transformations are applied relative to the center of the panorama image
*/
uv.x -= (panoWidth - 1) / 2.0f;
uv.y -= (panoHeight - 1) / 2.0f;
/**
* Apply transform stack
*/
uv.x /= outPanoScale.x;
uv.y /= outPanoScale.y;
float3 pt = OUTPUTPROJECTION(uv);
pt = rotateSphere(pt, R);
uv = SphereToErect(pt);
uv.x *= inPanoScale.x;
uv.y *= inPanoScale.y;
/**
* See notes in warp kernel
* compensate fetching offset with CLK_FILTER_LINEAR by adding 0.5f https://stackoverflow.com/a/23418156/463796
*/
uv.x += panoWidth / 2.0f;
uv.y += panoHeight / 2.0f;
const float4 im = read_imagef(tex, smp, uv) * 255.0f;
g_odata[y*panoWidth + x] = (uchar)im.s3 << 24 | (uchar)im.s2 << 16 | (uchar)im.s1 << 8 | (uchar)im.s0;
}
else {
g_odata[y*panoWidth + x] = 0;
}
}