Browse code

Add implementation

Robert Cranston authored on 07/04/2021 05:14:16
Showing 9 changed files

... ...
@@ -0,0 +1,111 @@
1
+#include <cstddef>
2
+#include <string>
3
+#include <vector>
4
+
5
+#include <GL/glew.h>
6
+#include <glm/glm.hpp>
7
+
8
+#include <glfbo3d.hpp>
9
+#include <glshader.hpp>
10
+#include <gltest.hpp>
11
+
12
+
13
+constexpr auto size = 256;
14
+constexpr auto fbo_size_divisor = 2;
15
+
16
+
17
+static void draw(GLuint texture0)
18
+{
19
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
20
+    glViewport(0, 0, size, size);
21
+    glActiveTexture(GL_TEXTURE0 + 0);
22
+    glBindTexture(GL_TEXTURE_3D, texture0);
23
+    auto draw = Shader({
24
+        "draw.vert",
25
+        "draw.geom", "quad.geom",
26
+        "draw.frag",
27
+    });
28
+    draw
29
+        .use()
30
+        .uniform("texture0", 0);
31
+    auto t = 0.0F;
32
+    gltest_set_time(t);
33
+    while ((t = gltest_get_time()) < 1)
34
+    {
35
+        draw
36
+            .uniform("z", t * 2 - 1, false)
37
+            .validate();
38
+        glDrawArrays(GL_TRIANGLES, 0, 3);
39
+        gltest_swap_buffers();
40
+    }
41
+}
42
+
43
+
44
+GLTEST(3, 2, size, size, glfbo3d)
45
+{
46
+    // Settings.
47
+    Shader::root("tests/shaders");
48
+    auto fbo_size = glm::ivec3(size / fbo_size_divisor);
49
+
50
+    // Create and bind vertex array.
51
+    auto vertex_array = GLuint{};
52
+    glGenVertexArrays(1, &vertex_array);
53
+    glBindVertexArray(vertex_array);
54
+
55
+    // Create texture.
56
+    auto texture0 = GLuint{};
57
+    glGenTextures(1, &texture0);
58
+    glBindTexture(GL_TEXTURE_3D, texture0);
59
+    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
60
+    glTexImage3D(
61
+        GL_TEXTURE_3D, 0, GL_RGBA32F,
62
+        fbo_size.x, fbo_size.y, fbo_size.z, 0,
63
+        GL_RGBA, GL_FLOAT, nullptr
64
+    );
65
+
66
+    // Create framebuffer.
67
+    auto framebuffer = GLuint{};
68
+    glGenFramebuffers(1, &framebuffer);
69
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
70
+    glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture0, 0);
71
+
72
+    // Set with CPU and draw.
73
+    auto data = std::vector<glm::vec4>{};
74
+    data.reserve((size_t)(fbo_size.x * fbo_size.y * fbo_size.z));
75
+    for (int z = 0; z < fbo_size.z; ++z)
76
+        for (int y = 0; y < fbo_size.y; ++y)
77
+            for (int x = 0; x < fbo_size.x; ++x)
78
+                data.emplace_back(
79
+                    x / (fbo_size.x / 8) % 2 ^ // NOLINT
80
+                    y / (fbo_size.y / 4) % 2 ^ // NOLINT
81
+                    z / (fbo_size.z / 2) % 2   // NOLINT
82
+                );
83
+    glBindTexture(GL_TEXTURE_3D, texture0);
84
+    glTexSubImage3D(
85
+        GL_TEXTURE_3D, 0,
86
+        0, 0, 0, fbo_size.x, fbo_size.y, fbo_size.z,
87
+        GL_RGBA, GL_FLOAT, &data[0]
88
+    );
89
+    draw(texture0);
90
+
91
+    // Set with GPU and draw.
92
+    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
93
+    glViewport(0, 0, fbo_size.x, fbo_size.y);
94
+    auto instance_count = fbo_size.z;
95
+    auto set = Shader({
96
+        "set.vert",
97
+        "set.geom", "quad.geom",
98
+        "set.frag",
99
+    });
100
+    set
101
+        .use()
102
+        .uniform("instance_count", instance_count)
103
+        .validate();
104
+    glDrawArraysInstanced(GL_TRIANGLES, 0, 3, instance_count);
105
+    draw(texture0);
106
+
107
+    // Delete.
108
+    glDeleteFramebuffers(1, &framebuffer);
109
+    glDeleteTextures(1, &texture0);
110
+    glDeleteVertexArrays(1, &vertex_array);
111
+}
0 112
new file mode 100644
... ...
@@ -0,0 +1,17 @@
1
+#version 150
2
+
3
+
4
+uniform sampler3D texture0;
5
+uniform float z;
6
+
7
+
8
+in vec3 position;
9
+
10
+
11
+out vec4 frag_color;
12
+
13
+
14
+void main()
15
+{
16
+    frag_color = texture(texture0, (vec3(position.xy, z) + 1) / 2);
17
+}
0 18
new file mode 100644
... ...
@@ -0,0 +1,12 @@
1
+#version 150
2
+
3
+#extension GL_ARB_shading_language_include : require
4
+
5
+
6
+#include "quad.geom.h"
7
+
8
+
9
+void main()
10
+{
11
+    quad(0, 1);
12
+}
0 13
new file mode 100644
... ...
@@ -0,0 +1,6 @@
1
+#version 150
2
+
3
+
4
+void main()
5
+{
6
+}
0 7
new file mode 100644
... ...
@@ -0,0 +1,22 @@
1
+#version 150
2
+
3
+
4
+#define QUAD_EMIT_VERTEX_(X, Y, Z, LAYER) position = vec3(X, Y, Z); gl_Position = vec4(position, 1); gl_Layer = LAYER; EmitVertex();
5
+
6
+
7
+layout(triangles) in;
8
+layout(triangle_strip, max_vertices = 4) out;
9
+
10
+
11
+out vec3 position;
12
+
13
+
14
+void quad(int layer, int layer_count)
15
+{
16
+    float z = (layer + 0.5) / layer_count * 2 - 1;
17
+    QUAD_EMIT_VERTEX_(-1, -1, z, layer);
18
+    QUAD_EMIT_VERTEX_(-1, +1, z, layer);
19
+    QUAD_EMIT_VERTEX_(+1, -1, z, layer);
20
+    QUAD_EMIT_VERTEX_(+1, +1, z, layer);
21
+    EndPrimitive();
22
+}
0 23
new file mode 100644
... ...
@@ -0,0 +1,8 @@
1
+#ifndef QUAD_H_
2
+#define QUAD_H_
3
+
4
+
5
+void quad(int layer, int layer_count);
6
+
7
+
8
+#endif // QUAD_H_
0 9
new file mode 100644
... ...
@@ -0,0 +1,13 @@
1
+#version 150
2
+
3
+
4
+in vec3 position;
5
+
6
+
7
+out vec4 frag_color;
8
+
9
+
10
+void main()
11
+{
12
+    frag_color = vec4(vec3(length(position)), 1);
13
+}
0 14
new file mode 100644
... ...
@@ -0,0 +1,18 @@
1
+#version 150
2
+
3
+#extension GL_ARB_shading_language_include : require
4
+
5
+
6
+#include "quad.geom.h"
7
+
8
+
9
+uniform int instance_count;
10
+
11
+
12
+in int instance_id[];
13
+
14
+
15
+void main()
16
+{
17
+    quad(instance_id[0], instance_count);
18
+}
0 19
new file mode 100644
... ...
@@ -0,0 +1,10 @@
1
+#version 150
2
+
3
+
4
+out int instance_id;
5
+
6
+
7
+void main()
8
+{
9
+    instance_id = gl_InstanceID;
10
+}