#include <cstddef> #include <string> #include <vector> #include <GL/glew.h> #include <glm/glm.hpp> #include <glfbo3d.hpp> #include <glshader.hpp> #include <gltest.hpp> constexpr auto size = 256; constexpr auto fbo_size_divisor = 2; static void draw(GLuint texture0) { glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, size, size); glActiveTexture(GL_TEXTURE0 + 0); glBindTexture(GL_TEXTURE_3D, texture0); auto draw = Shader({ "draw.vert", "draw.geom", "quad.geom", "draw.frag", }); draw .use() .uniform("texture0", 0); auto t = 0.0F; gltest_set_time(t); while ((t = gltest_get_time()) < 1) { draw .uniform("z", t * 2 - 1, false) .validate(); glDrawArrays(GL_TRIANGLES, 0, 3); gltest_swap_buffers(); } } GLTEST(3, 2, size, size, glfbo3d) { // Settings. Shader::root("tests/shaders"); auto fbo_size = glm::ivec3(size / fbo_size_divisor); // Create and bind vertex array. auto vertex_array = GLuint{}; glGenVertexArrays(1, &vertex_array); glBindVertexArray(vertex_array); // Create texture. auto texture0 = GLuint{}; glGenTextures(1, &texture0); glBindTexture(GL_TEXTURE_3D, texture0); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage3D( GL_TEXTURE_3D, 0, GL_RGBA32F, fbo_size.x, fbo_size.y, fbo_size.z, 0, GL_RGBA, GL_FLOAT, nullptr ); // Create framebuffer. auto framebuffer = GLuint{}; glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture0, 0); // Set with CPU and draw. auto data = std::vector<glm::vec4>{}; data.reserve((size_t)(fbo_size.x * fbo_size.y * fbo_size.z)); for (int z = 0; z < fbo_size.z; ++z) for (int y = 0; y < fbo_size.y; ++y) for (int x = 0; x < fbo_size.x; ++x) data.emplace_back( x / (fbo_size.x / 8) % 2 ^ // NOLINT y / (fbo_size.y / 4) % 2 ^ // NOLINT z / (fbo_size.z / 2) % 2 // NOLINT ); glBindTexture(GL_TEXTURE_3D, texture0); glTexSubImage3D( GL_TEXTURE_3D, 0, 0, 0, 0, fbo_size.x, fbo_size.y, fbo_size.z, GL_RGBA, GL_FLOAT, &data[0] ); draw(texture0); // Set with GPU and draw. glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glViewport(0, 0, fbo_size.x, fbo_size.y); auto instance_count = fbo_size.z; auto set = Shader({ "set.vert", "set.geom", "quad.geom", "set.frag", }); set .use() .uniform("instance_count", instance_count) .validate(); glDrawArraysInstanced(GL_TRIANGLES, 0, 3, instance_count); draw(texture0); // Delete. glDeleteFramebuffers(1, &framebuffer); glDeleteTextures(1, &texture0); glDeleteVertexArrays(1, &vertex_array); }