void render_game(float dt) { glBindFramebuffer(GL_FRAMEBUFFER, rt_frame.fbo); glViewport(0, 0, rt_frame.width, rt_frame.height); glBindTexture(GL_TEXTURE_2D, tex_dither); depth_test(true, GL_LEQUAL); depth_write(true); clear(0x300224ff, 1.0f); use_shader(shader_default); uniform("projection", mat_projection); uniform("view", mat_view); uniform("model", scale(0.07f)); uniform("lightPos", vec3(0.8, 4.0, 0.8)); uniform("palette", vec3(143.0, 199.0, 132.0) / 255.0f); uniform("texDither", 0); //mesh_teapot.draw(); glBindBuffer(GL_ARRAY_BUFFER, mesh_teapot.vertex_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh_teapot.index_buffer); attribfv("position", 3, 8, 0); attribfv("normal", 3, 8, 5); glDrawElements(GL_TRIANGLES, mesh_teapot.num_indices, GL_UNSIGNED_INT, 0); glBindTexture(GL_TEXTURE_2D, rt_frame.color); glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, window_width, window_height); clear(0x00000000, 1.0f); use_shader(shader_dither); uniform("texScene", 0); mesh_quad.draw(); }
Mesh gen_terrain_mesh(int samples_x, int samples_y) { vector<vec3> vertices; vector<uint32> indices; int i = 0; for (int y = 0; y < samples_y; y++) { for (int x = 0; x < samples_x; x++) { float x0 = -1.0f + 2.0f * x / (samples_x - 1); float y0 = -1.0f + 2.0f * y / (samples_y - 1); float x1 = -1.0f + 2.0f * (x + 1) / (samples_x - 1); float y1 = -1.0f + 2.0f * (y + 1) / (samples_y - 1); vertices.push_back(vec3(x0, 0.0f, y0)); vertices.push_back(vec3(x1, 0.0f, y0)); vertices.push_back(vec3(x1, 0.0f, y1)); vertices.push_back(vec3(x0, 0.0f, y1)); indices.push_back(i + 0); indices.push_back(i + 1); indices.push_back(i + 2); indices.push_back(i + 2); indices.push_back(i + 3); indices.push_back(i + 0); i += 4; } } Mesh mesh; mesh.num_indices = indices.size(); mesh.num_vertices = vertices.size(); mesh.vertex_buffer = gen_buffer(GL_ARRAY_BUFFER, vertices.size() * sizeof(vec3), &vertices[0], GL_STATIC_DRAW); mesh.index_buffer = gen_buffer(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint32), &indices[0], GL_STATIC_DRAW); mesh.draw = [=]() { glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_buffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.index_buffer); attribfv("position", 3, 3, 0); glDrawElements(GL_TRIANGLES, mesh.num_indices, GL_UNSIGNED_INT, 0); }; return mesh; }
void app_update_and_render(App *app) { GL_CHECK(glEnable(GL_DEPTH_TEST)); GL_CHECK(glDepthFunc(GL_LEQUAL)); GL_CHECK(glDepthMask(GL_TRUE)); GL_CHECK(glDepthRangef(0.0, 1.0)); GL_CHECK(glClearDepthf(1.0f)); GL_CHECK(glClearColor(0.15f, 0.17f, 0.2f, 1.0f)); //////////////////////////// // Cube shader GL_CHECK(glUseProgram(app->program_cube)); GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, app->vbo_cube)); attribfv(cube, position, 3, 6, 0); attribfv(cube, normal, 3, 6, 3); float camera_z = Centimeter(500.0f); float camera_y = Centimeter(70.0f); mat4 mat_view[Num_Views]; mat_view[0] = translate(+Eye_IPD / 2.0f, -camera_y, -camera_z); mat_view[1] = translate(-Eye_IPD / 2.0f, -camera_y, -camera_z); mat_view[2] = translate(+Eye_IPD / 2.0f, -camera_y, -camera_z); mat_view[3] = translate(-Eye_IPD / 2.0f, -camera_y, -camera_z); // The scene is rendered twice for each eye position, once with a wide field of view, and // once with a narrower field of view in order to render the midpoint of the screen with // a higher resolution than the rest. mat4 mat_projection[Num_Views]; mat_projection[0] = make_frustum_screen_viewer( Eye_Display_Distance, -(Screen_Size_X - Eye_IPD) / 2.0f, +(Eye_IPD / 2.0f), -Screen_Size_Y / 2.0f, +Screen_Size_Y / 2.0f, Z_Near, Z_Far); mat_projection[1] = make_frustum_screen_viewer( Eye_Display_Distance, -(Eye_IPD / 2.0f), +(Screen_Size_X - Eye_IPD) / 2.0f, -Screen_Size_Y / 2.0f, +Screen_Size_Y / 2.0f, Z_Near, Z_Far); float right_midpoint = -((Screen_Size_X/4.0f) - (Eye_IPD / 2.0f)); float left_midpoint = (Screen_Size_X/4.0f) - (Eye_IPD / 2.0f); mat_projection[2] = make_frustum_screen_viewer( Eye_Display_Distance, right_midpoint - (Screen_Size_X/8.0f), right_midpoint + (Screen_Size_X/8.0f), -Screen_Size_Y / 4.0f, +Screen_Size_Y / 4.0f, Z_Near, Z_Far); mat_projection[3] = make_frustum_screen_viewer( Eye_Display_Distance, left_midpoint - (Screen_Size_X/8.0f), left_midpoint + (Screen_Size_X/8.0f), -Screen_Size_Y / 4.0f, +Screen_Size_Y / 4.0f, Z_Near, Z_Far); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, app->fb.framebuffer)); GL_CHECK(glViewport(0, 0, app->fb.width, app->fb.height)); GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); uniformm4array(cube, projection, mat_projection[0], Num_Views); uniformm4array(cube, view, mat_view[0], Num_Views); draw_scene(app); //////////////////////////// // Distortion shader GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0)); GL_CHECK(glDisable(GL_DEPTH_TEST)); GL_CHECK(glDepthMask(GL_FALSE)); GL_CHECK(glClearColor(0.0f, 0.0f, 0.0f, 1.0f)); GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); GL_CHECK(glUseProgram(app->program_distort)); GL_CHECK(glActiveTexture(GL_TEXTURE0)); uniform1i(distort, framebuffer, 0); // Left eye GL_CHECK(glViewport(0, 0, View_Resolution_X, View_Resolution_Y)); GL_CHECK(glBindTexture(GL_TEXTURE_2D_ARRAY, app->fb.colorbuffer)); uniform1i(distort, layer_index, 0); GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, app->warp_mesh[0])); attribfv(distort, position, 2, 14, 0); attribfv(distort, uv_red_low_res, 2, 14, 2); attribfv(distort, uv_green_low_res, 2, 14, 4); attribfv(distort, uv_blue_low_res, 2, 14, 6); attribfv(distort, uv_red_high_res, 2, 14, 8); attribfv(distort, uv_green_high_res, 2, 14, 10); attribfv(distort, uv_blue_high_res, 2, 14, 12); GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, Warp_Mesh_Resolution_X * Warp_Mesh_Resolution_Y * 6)); // Right eye GL_CHECK(glViewport(View_Resolution_X, 0, View_Resolution_X, View_Resolution_Y)); uniform1i(distort, layer_index, 1); GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, app->warp_mesh[1])); attribfv(distort, position, 2, 14, 0); attribfv(distort, uv_red_low_res, 2, 14, 2); attribfv(distort, uv_green_low_res, 2, 14, 4); attribfv(distort, uv_blue_low_res, 2, 14, 6); attribfv(distort, uv_red_high_res, 2, 14, 8); attribfv(distort, uv_green_high_res, 2, 14, 10); attribfv(distort, uv_blue_high_res, 2, 14, 12); GL_CHECK(glDrawArrays(GL_TRIANGLES, 0, Warp_Mesh_Resolution_X * Warp_Mesh_Resolution_Y * 6)); }
void app_update_and_render(App *app) { app->current_scene = (int)(app->elapsed_time / 20.0f) % NUM_SCENES; Scene scene = app->scenes[app->current_scene]; float model_scale = animate_model_scale(app->elapsed_time); float aspect_ratio = app->window_width / (float)app->window_height; mat4 mat_projection = perspective(scene.fov, aspect_ratio, scene.z_near, scene.z_far); mat4 mat_cube_model = rotateX(PI / 2.0f) * scale(model_scale); mat4 mat_view = animate_camera(app->elapsed_time); glEnable(GL_CULL_FACE); glFrontFace(GL_CCW); glCullFace(GL_BACK); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_DEPTH_TEST); glDepthMask(GL_TRUE); glDepthRangef(0.0, 1.0); glClearDepthf(1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); //////////////// // Draw backdrop glDepthMask(GL_FALSE); glUseProgram(app->program_backdrop); glBindBuffer(GL_ARRAY_BUFFER, app->vbo_quad); attribfv(backdrop, position, 2, 0); uniform3fv(backdrop, sun_dir, scene.sun_dir); uniform2f(backdrop, screen_size, app->window_width, app->window_height); uniform1f(backdrop, inv_tan_fov, 1.0f / (scene.fov / 2.0f)); uniformm4(backdrop, view, mat_view); glDrawArrays(GL_TRIANGLES, 0, 6); glDepthMask(GL_TRUE); ////////////////////////// // Draw tessellated sphere glUseProgram(app->program_mapping); glBindBuffer(GL_ARRAY_BUFFER, app->vbo_cube); attribfv(mapping, position, 3, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, scene.heightmap); uniform1i(mapping, heightmap, 0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_CUBE_MAP, scene.diffusemap); uniform1i(mapping, diffusemap, 1); uniform1f(mapping, height_scale, scene.height_scale); uniform1f(mapping, use_mip, scene.use_mip ? 1.0f : 0.0f); uniform1f(mapping, max_lod_coverage, scene.max_lod_coverage); uniform2f(mapping, screen_size, app->window_width, app->window_height); uniformm4(mapping, model, mat_cube_model); uniformm4(mapping, view, mat_view); uniformm4(mapping, projection, mat_projection); glPatchParameteri(GL_PATCH_VERTICES, VERTICES_PER_PATCH); glDrawArrays(GL_PATCHES, 0, NUM_PATCHES * VERTICES_PER_PATCH); }