28 #define PHYSICS_GROUP_SIZE 128
31 #define SPHERE_INSTANCES_X 24
32 #define SPHERE_INSTANCES_Y 24
33 #define SPHERE_INSTANCES_Z 24
34 #define SPHERE_INSTANCES (SPHERE_INSTANCES_X * SPHERE_INSTANCES_Y * SPHERE_INSTANCES_Z)
36 #define SPHERE_RADIUS 0.30f
39 #define SPHERE_VERT_PER_CIRC_LOD0 24
40 #define SPHERE_VERT_PER_CIRC_LOD1 20
41 #define SPHERE_VERT_PER_CIRC_LOD2 16
42 #define SPHERE_VERT_PER_CIRC_LOD3 12
45 #define UNIFORM_MVP_LOCATION 0
46 #define UNIFORM_COLOR_LOCATION 1
47 #define UNIFORM_LIGHT_DIR_LOCATION 2
65 culling_implementations.push_back(
new HiZCulling);
67 culling_implementation_index = CullHiZ;
68 enable_culling =
true;
73 camera_rotation_y = 0.0f;
74 camera_rotation_x = 0.0f;
79 show_redundant =
false;
86 camera_rotation_y -= delta_x * 0.25f;
87 camera_rotation_x += delta_y * 0.15f;
88 camera_rotation_x =
clamp(camera_rotation_x, -0.20
f, 0.20
f);
89 camera_rotation_y -= floor(camera_rotation_y);
95 const Mesh &box_mesh,
const vec4 *instances,
unsigned num_instances)
97 unsigned total_vertices = num_instances * box_mesh.
vbo.size();
98 occluder_positions.reserve(total_vertices);
100 unsigned total_indices = num_instances * box_mesh.
ibo.size();
101 occluder_indices.reserve(total_indices);
104 for (
unsigned i = 0; i < total_indices; i++)
106 unsigned instance = i / box_mesh.
ibo.size();
107 unsigned index = i % box_mesh.
ibo.size();
109 unsigned baked_index = box_mesh.
ibo[
index] + instance * box_mesh.
vbo.size();
110 occluder_indices.push_back(baked_index);
114 for (
unsigned i = 0; i < total_vertices; i++)
116 unsigned instance = i / box_mesh.
vbo.size();
117 unsigned index = i % box_mesh.
vbo.size();
119 vec4 pos = instances[instance] +
vec4(box_mesh.
vbo[index].position, 1.0f);
120 occluder_positions.push_back(pos);
153 vector<vec4> occluder_instances;
154 for (
int z = 0; z < 13; z++)
156 for (
int x = 0;
x < 13;
x++)
158 if (z >= 5 && z <= 7 && x >= 5 &&
x <= 7)
162 occluder_instances.push_back(
vec4(3.0
f) *
vec4(
x - 6, 0, z - 6, 0));
166 sort(occluder_instances.begin(), occluder_instances.end(),
OccluderSorter());
168 num_occluder_instances = occluder_instances.size();
171 GL_CHECK(glGenBuffers(1, &occluder_instances_buffer));
172 GL_CHECK(glBindBuffer(GL_UNIFORM_BUFFER, occluder_instances_buffer));
173 GL_CHECK(glBufferData(GL_UNIFORM_BUFFER, occluder_instances.size() *
sizeof(
vec4), &occluder_instances[0], GL_STATIC_DRAW));
177 std::vector<SphereInstance> sphere_instances;
189 sphere_instances.push_back(instance);
195 GL_CHECK(glGenBuffers(1, &sphere_instances_buffer));
196 GL_CHECK(glBindBuffer(GL_SHADER_STORAGE_BUFFER, sphere_instances_buffer));
197 GL_CHECK(glBufferData(GL_SHADER_STORAGE_BUFFER, sphere_instances.size() *
sizeof(
SphereInstance), &sphere_instances[0], GL_STATIC_DRAW));
205 GL_CHECK(glBufferData(GL_ARRAY_BUFFER, sphere_instances.size() *
sizeof(
vec4), NULL, GL_DYNAMIC_COPY));
209 vector<vec4> occluder_positions;
210 vector<uint32_t> occluder_indices;
211 bake_occluder_geometry(occluder_positions, occluder_indices, box_mesh, &occluder_instances[0], occluder_instances.size());
213 for (
unsigned i = 0; i < culling_implementations.size(); i++)
215 culling_implementations[i]->setup_occluder_geometry(occluder_positions, occluder_indices);
231 void Scene::update_camera(
float rotation_y,
float rotation_x,
unsigned viewport_width,
unsigned viewport_height)
234 float radians_y = 2.0f *
PI * rotation_y;
235 float radians_x = 2.0f *
PI * rotation_x;
239 vec3 camera_dir =
vec3(rotation_matrix_y * rotation_matrix_x *
vec4(0, 0, -1, 1));
241 vec3 camera_position =
vec3(0, 2, 0);
243 view =
mat_look_at(camera_position, camera_position + camera_dir,
vec3(0, 1, 0));
253 if (method == CullNone)
255 enable_culling =
false;
256 culling_implementation_index = 0;
260 enable_culling =
true;
261 culling_implementation_index =
static_cast<unsigned>(method);
267 if (physics_speed <= 0.0
f)
273 GL_CHECK(glUseProgram(physics_program));
274 GL_CHECK(glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, sphere_instances_buffer));
276 GL_CHECK(glProgramUniform1f(physics_program, 1, physics_speed * delta_time));
285 update_camera(camera_rotation_y, camera_rotation_x, width, height);
293 apply_physics(delta_time);
297 CullingInterface *culler = culling_implementations[culling_implementation_index];
305 GL_CHECK(glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT));
310 memset(indirect_command, 0,
sizeof(indirect_command));
314 indirect_command[i].
count =
sphere[i]->get_num_elements();
320 GL_CHECK(glBufferData(GL_DRAW_INDIRECT_BUFFER,
sizeof(indirect_command), indirect_command, GL_STREAM_DRAW));
324 indirect.instance_buffer, sphere_instances_buffer,
325 num_render_sphere_instances);
330 GL_CHECK(glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT));
331 num_sphere_render_lods = 1;
341 for (
unsigned i = 0; i < num_sphere_render_lods; i++)
350 GL_CHECK(glEnableVertexAttribArray(3));
351 GL_CHECK(glVertexAttribDivisor(3, 1));
353 GL_CHECK(glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE,
sizeof(
vec4), 0));
355 GL_CHECK(glDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_SHORT,
364 GL_CHECK(glEnableVertexAttribArray(3));
365 GL_CHECK(glVertexAttribDivisor(3, 1));
366 GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, sphere_instances_buffer));
367 GL_CHECK(glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 2 *
sizeof(
vec4), 0));
368 GL_CHECK(glDrawElementsInstanced(GL_TRIANGLES,
sphere[0]->get_num_elements(),
369 GL_UNSIGNED_SHORT, NULL, num_render_sphere_instances));
388 GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
389 GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT));
390 GL_CHECK(glViewport(0, 0, width, height));
393 GL_CHECK(glUseProgram(occluder_program));
395 GL_CHECK(glBindVertexArray(box->get_vertex_array()));
396 GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, occluder_instances_buffer));
397 GL_CHECK(glEnableVertexAttribArray(3));
398 GL_CHECK(glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE,
sizeof(
vec4), 0));
399 GL_CHECK(glVertexAttribDivisor(3, 1));
400 GL_CHECK(glDrawElementsInstanced(GL_TRIANGLES, box->get_num_elements(), GL_UNSIGNED_SHORT, 0, num_occluder_instances));
402 GL_CHECK(glUseProgram(sphere_program));
411 render_spheres(
vec3(0.25
f));
415 render_spheres(
vec3(1.0
f));
423 GL_CHECK(glViewport(0, 0, width, height));
432 GL_CHECK(glUseProgram(quad_program));
437 unsigned offset_x = 0;
439 GL_CHECK(glBindTexture(GL_TEXTURE_2D, culling_implementations[culling_implementation_index]->get_depth_texture()));
445 GL_CHECK(glDrawElements(GL_TRIANGLES,
quad.get_num_elements(), GL_UNSIGNED_SHORT, 0));
460 for (
unsigned i = 0; i < culling_implementations.size(); i++)
462 delete culling_implementations[i];
465 GL_CHECK(glDeleteBuffers(1, &occluder_instances_buffer));
466 GL_CHECK(glDeleteBuffers(1, &sphere_instances_buffer));
467 GL_CHECK(glDeleteProgram(occluder_program));
468 GL_CHECK(glDeleteProgram(quad_program));
469 GL_CHECK(glDeleteProgram(physics_program));
470 GL_CHECK(glDeleteProgram(sphere_program));
#define UNIFORM_COLOR_LOCATION
#define SPHERE_INSTANCES_X
#define SPHERE_INSTANCES_Y
static const unsigned verts_per_circ[]
void render(unsigned width, unsigned height)
GLboolean GLboolean GLboolean GLboolean a
Mesh create_box_mesh(const AABB &aabb)
float vec_dot(const T &a, const T &b)
virtual unsigned get_num_lods() const
virtual 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)=0
mat4 mat_look_at(const vec3 &eye, const vec3 ¢er, const vec3 &up)
GLint GLsizei GLsizei height
void bake_occluder_geometry(std::vector< vec4 > &occluder_positions, std::vector< uint32_t > &occluder_indices, const Mesh &box_mesh, const vec4 *instances, unsigned num_instances)
#define SPHERE_INSTANCES_Z
GLuint common_compile_compute_shader_from_file(const char *cs_source)
void update(float delta_time, unsigned width, unsigned height)
#define SPHERE_VERT_PER_CIRC_LOD0
float clamp(float x, float min, float max)
GLuint common_compile_shader_from_file(const char *vs_source, const char *fs_source)
void render_spheres(vec3 color_mod)
void apply_physics(float delta_time)
const T::data_type * value_ptr(const T &vec)
mat4 mat_rotate_y(float radians)
void move_camera(float delta_x, float delta_y)
#define SPHERE_VERT_PER_CIRC_LOD3
void set_culling_method(CullingMethod method)
#define UNIFORM_MVP_LOCATION
#define SPHERE_VERT_PER_CIRC_LOD2
#define UNIFORM_LIGHT_DIR_LOCATION
mat4 mat_rotate_x(float radians)
mat4 mat_perspective_fov(float fovy, float aspect, float zn, float zf)
GLint GLint GLint GLint GLint x
#define PHYSICS_GROUP_SIZE
virtual void set_view_projection(const mat4 &projection, const mat4 &view, const vec2 &zNearFar)=0
#define SPHERE_VERT_PER_CIRC_LOD1
virtual void rasterize_occluders()=0
T vec_normalize(const T &vec)
bool operator()(const vec4 &a, const vec4 &b)
GLboolean GLboolean GLboolean b
Mesh create_sphere_mesh(float radius, vec3 center, unsigned vertices_per_circumference)
void update_camera(float rotation_y, float rotation_x, unsigned viewport_width, unsigned viewport_height)