26 #define GROUP_SIZE_AABB 64
50 GL_CHECK(glGenTextures(1, &depth_texture));
51 GL_CHECK(glBindTexture(GL_TEXTURE_2D, depth_texture));
52 GL_CHECK(glTexStorage2D(GL_TEXTURE_2D, lod_levels, GL_DEPTH24_STENCIL8,
56 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST));
57 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST));
59 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
60 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
63 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED));
64 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_RED));
65 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED));
66 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ONE));
67 GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
70 framebuffers.resize(lod_levels);
71 GL_CHECK(glGenFramebuffers(lod_levels, &framebuffers[0]));
72 for (
unsigned i = 0; i < lod_levels; i++)
74 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[i]));
75 GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
76 GL_TEXTURE_2D, depth_texture, i));
78 GL_CHECK(
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER));
79 if (status != GL_FRAMEBUFFER_COMPLETE)
81 LOGE(
"Framebuffer for LOD %u is incomplete!", i);
84 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
86 GL_CHECK(glGenBuffers(1, &occluder.vertex));
87 GL_CHECK(glGenBuffers(1, &occluder.index));
88 GL_CHECK(glGenVertexArrays(1, &occluder.vao));
92 GL_CHECK(glGenSamplers(1, &shadow_sampler));
93 GL_CHECK(glSamplerParameteri(shadow_sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST));
94 GL_CHECK(glSamplerParameteri(shadow_sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
95 GL_CHECK(glSamplerParameteri(shadow_sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
96 GL_CHECK(glSamplerParameteri(shadow_sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
97 GL_CHECK(glSamplerParameteri(shadow_sampler, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE));
98 GL_CHECK(glSamplerParameteri(shadow_sampler, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL));
100 GL_CHECK(glGenBuffers(1, &uniform_buffer));
101 GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, uniform_buffer));
102 GL_CHECK(glBufferData(GL_UNIFORM_BUFFER,
sizeof(
Uniforms), NULL, GL_STREAM_DRAW));
106 const GLuint *culled_instance_buffer,
GLuint instance_data_buffer,
107 unsigned num_instances)
109 GL_CHECK(glUseProgram(culling_program));
112 GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, uniform_buffer));
113 GL_CHECK(glBufferSubData(GL_UNIFORM_BUFFER, 0,
sizeof(
Uniforms), &uniforms));
114 GL_CHECK(glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniform_buffer));
119 GL_CHECK(glProgramUniform1ui(culling_program, 0, num_instances));
121 for (
unsigned i = 0; i < num_offsets; i++)
123 GL_CHECK(glBindBufferRange(GL_ATOMIC_COUNTER_BUFFER, i, counter_buffer, counter_offsets[i],
sizeof(uint32_t)));
124 GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1 + i, culled_instance_buffer[i]));
128 GL_CHECK(glActiveTexture(GL_TEXTURE0));
129 GL_CHECK(glBindTexture(GL_TEXTURE_2D, depth_texture));
130 GL_CHECK(glBindSampler(0, shadow_sampler));
133 GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, instance_data_buffer));
134 GL_CHECK(glDispatchCompute(aabb_groups, 1, 1));
139 GL_CHECK(glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_COMMAND_BARRIER_BIT));
145 GL_CHECK(glBindVertexArray(occluder.vao));
147 GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, occluder.vertex));
148 GL_CHECK(glBufferData(GL_ARRAY_BUFFER, position.size() *
sizeof(
vec4), &position[0], GL_STATIC_DRAW));
150 GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, occluder.index));
151 GL_CHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() *
sizeof(uint32_t), &indices[0], GL_STATIC_DRAW));
153 GL_CHECK(glEnableVertexAttribArray(0));
154 GL_CHECK(glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0));
157 GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
158 GL_CHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
160 occluder.elements = indices.size();
165 GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0));
168 GL_CHECK(glUseProgram(depth_render_program));
169 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[0]));
172 GL_CHECK(glBindVertexArray(occluder.vao));
174 GL_CHECK(glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
175 GL_CHECK(glDrawElements(GL_TRIANGLES, occluder.elements, GL_UNSIGNED_INT, 0));
178 GL_CHECK(glBindTexture(GL_TEXTURE_2D, depth_texture));
179 GL_CHECK(glUseProgram(depth_mip_program));
181 for (
unsigned lod = 1; lod < lod_levels; lod++)
183 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[lod]));
184 GL_CHECK(glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
189 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, lod - 1));
190 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, lod - 1));
193 GL_CHECK(glDrawElements(GL_TRIANGLES,
quad.get_num_elements(), GL_UNSIGNED_SHORT, 0));
197 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0));
198 GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1000));
199 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
204 mat4 view_projection = projection * view;
205 GL_CHECK(glProgramUniformMatrix4fv(depth_render_program, 0, 1, GL_FALSE,
value_ptr(view_projection)));
207 uniforms.uVP = view_projection;
208 uniforms.uView = view;
210 uniforms.zNearFar = zNearFar;
213 compute_frustum_from_view_projection(uniforms.planes, view_projection);
218 GL_CHECK(glDeleteTextures(1, &depth_texture));
219 GL_CHECK(glDeleteProgram(depth_render_program));
220 GL_CHECK(glDeleteProgram(depth_mip_program));
221 GL_CHECK(glDeleteProgram(culling_program));
222 GL_CHECK(glDeleteFramebuffers(framebuffers.size(), &framebuffers[0]));
224 GL_CHECK(glDeleteBuffers(1, &occluder.vertex));
225 GL_CHECK(glDeleteBuffers(1, &occluder.index));
226 GL_CHECK(glDeleteBuffers(1, &uniform_buffer));
227 GL_CHECK(glDeleteVertexArrays(1, &occluder.vao));
229 GL_CHECK(glDeleteSamplers(1, &shadow_sampler));
GLuint common_compile_compute_shader_from_file(const char *cs_source)
GLuint common_compile_shader_from_file(const char *vs_source, const char *fs_source)
const T::data_type * value_ptr(const T &vec)
GLsizei GLenum const void * indices
void setup_occluder_geometry(const std::vector< vec4 > &positions, const std::vector< uint32_t > &indices)
void set_view_projection(const mat4 &projection, const mat4 &view, const vec2 &zNearFar)
void rasterize_occluders()
void test_bounding_boxes(GLuint counter_buffer, const unsigned *counter_offsets, unsigned num_offsets, const GLuint *culled_instance_buffer, GLuint instance_data_buffer, unsigned num_instances)
typedef GLenum(GL_APIENTRYP PFNGLGETGRAPHICSRESETSTATUSKHRPROC)(void)
typedef GLuint(GL_APIENTRYP PFNGLGETDEBUGMESSAGELOGKHRPROC)(GLuint count