File size: 2,480 Bytes
352fb85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

extern "C" {
void sort(float *viewProj, float *transforms, uint32_t *transformIndices, uint32_t vertexCount, float *positions,
          uint32_t *depthBuffer, uint32_t *depthIndex, uint32_t *starts, uint32_t *counts) {
    int32_t minDepth = 0x7fffffff;
    int32_t maxDepth = 0x80000000;
    int32_t previousTransformIndex = -1;
    float viewTransform[16];
    for (uint32_t i = 0; i < vertexCount; i++) {
        float x = positions[3 * i + 0];
        float y = positions[3 * i + 1];
        float z = positions[3 * i + 2];

        uint32_t transformIndex = transformIndices[i];
        if (transformIndex != previousTransformIndex) {
            previousTransformIndex = transformIndex;
            float *transform = &transforms[20 * transformIndex];
            viewTransform[2] = transform[0] * viewProj[2] + transform[1] * viewProj[6] + transform[2] * viewProj[10] +
                               transform[3] * viewProj[14];
            viewTransform[6] = transform[4] * viewProj[2] + transform[5] * viewProj[6] + transform[6] * viewProj[10] +
                               transform[7] * viewProj[14];
            viewTransform[10] = transform[8] * viewProj[2] + transform[9] * viewProj[6] + transform[10] * viewProj[10] +
                                transform[11] * viewProj[14];
            viewTransform[14] = transform[12] * viewProj[2] + transform[13] * viewProj[6] + transform[14] * viewProj[10] +
                                transform[15] * viewProj[14];
        }

        float projectedZ = viewTransform[2] * x + viewTransform[6] * y + viewTransform[10] * z + viewTransform[14];
        int32_t depth = projectedZ * 4096;
        depthBuffer[i] = depth;
        if (depth > maxDepth) {
            maxDepth = depth;
        }
        if (depth < minDepth) {
            minDepth = depth;
        }
    }

    const uint32_t depthRange = 256 * 256;
    const float depthInv = (float)(depthRange - 1) / (maxDepth - minDepth);
    memset(counts, 0, depthRange * sizeof(uint32_t));
    for (uint32_t i = 0; i < vertexCount; i++) {
        depthBuffer[i] = (depthBuffer[i] - minDepth) * depthInv;
        counts[depthBuffer[i]]++;
    }

    starts[0] = 0;
    for (uint32_t i = 1; i < depthRange; i++) {
        starts[i] = starts[i - 1] + counts[i - 1];
    }

    for (uint32_t i = 0; i < vertexCount; i++) {
        depthIndex[starts[depthBuffer[i]]++] = i;
    }
}
}