From 6f21d1e0ecf78f74dd8a09ac02e7dc00b7a898b2 Mon Sep 17 00:00:00 2001 From: Dimitri Lozeve Date: Thu, 25 Feb 2021 21:09:40 +0100 Subject: [PATCH] Reset frame count and time when reloading shaders Define a struct to hold the renderer state. --- src/main.c | 99 ++++++++++++++++++++++++-------------------------- src/renderer.c | 30 ++++++++------- src/renderer.h | 21 +++++++++-- 3 files changed, 81 insertions(+), 69 deletions(-) diff --git a/src/main.c b/src/main.c index 0ae5e3e..1f1115c 100644 --- a/src/main.c +++ b/src/main.c @@ -14,81 +14,78 @@ int main(int argc, char *argv[]) { log_error("Usage: %s []", argv[0]); return EXIT_FAILURE; } - const char *screen_shader_file = argv[1]; - log_debug("Screen shader file: %s", screen_shader_file); - const char *buffer_shader_file = NULL; + + struct renderer_state state = {0}; + + state.screen_shader_file = argv[1]; + log_debug("Screen shader file: %s", state.screen_shader_file); if (argc >= 3) { - buffer_shader_file = argv[2]; - log_debug("Buffer shader file: %s", buffer_shader_file); + state.buffer_shader_file = argv[2]; + log_debug("Buffer shader file: %s", state.buffer_shader_file); } - GLFWwindow *window = initialize_window(WINDOW_WIDTH, WINDOW_HEIGHT); - if (window == NULL) { + state.window = initialize_window(WINDOW_WIDTH, WINDOW_HEIGHT); + if (state.window == NULL) { glfwTerminate(); return EXIT_FAILURE; } unsigned int VAO = initialize_vertices(); - unsigned int screen_shader = glCreateProgram(); - if (!screen_shader) { + state.screen_shader = glCreateProgram(); + if (!state.screen_shader) { log_error("Could not create screen shader program"); - glfwDestroyWindow(window); + glfwDestroyWindow(state.window); glfwTerminate(); return EXIT_FAILURE; } - compile_shaders(&screen_shader, screen_shader_file); - glUseProgram(screen_shader); - glUniform1i(glGetUniformLocation(screen_shader, "u_texture"), 0); + compile_shaders(&state.screen_shader, state.screen_shader_file); + glUseProgram(state.screen_shader); + glUniform1i(glGetUniformLocation(state.screen_shader, "u_texture"), 0); - unsigned int buffer_shader = 0; unsigned int framebuffer = 0; unsigned int texture_color_buffer = 0; - if (buffer_shader_file) { - buffer_shader = glCreateProgram(); - if (!buffer_shader) { + if (state.buffer_shader_file) { + state.buffer_shader = glCreateProgram(); + if (!state.buffer_shader) { log_error("Could not create buffer shader program"); - glfwDestroyWindow(window); + glfwDestroyWindow(state.window); glfwTerminate(); return EXIT_FAILURE; } - compile_shaders(&buffer_shader, buffer_shader_file); - glUseProgram(buffer_shader); - glUniform1i(glGetUniformLocation(buffer_shader, "u_texture"), 0); + compile_shaders(&state.buffer_shader, state.buffer_shader_file); + glUseProgram(state.buffer_shader); + glUniform1i(glGetUniformLocation(state.buffer_shader, "u_texture"), 0); if (initialize_framebuffer(&framebuffer, &texture_color_buffer, WINDOW_WIDTH, WINDOW_HEIGHT)) { - glfwDestroyWindow(window); + glfwDestroyWindow(state.window); glfwTerminate(); return EXIT_FAILURE; } } /* Drawing loop */ - size_t frame_count = 0; - size_t prev_frame_count = 0; - double time = 0; - double prev_time = 0; - while (!glfwWindowShouldClose(window)) { - process_input(window, &screen_shader, screen_shader_file, &buffer_shader, - buffer_shader_file); + glfwSetTime(0.0); + while (!glfwWindowShouldClose(state.window)) { + process_input(&state); /* data required for uniforms */ - time = glfwGetTime(); + state.time = glfwGetTime(); int viewport[4] = {0}; glGetIntegerv(GL_VIEWPORT, viewport); double mouse_x = 0, mouse_y = 0; - glfwGetCursorPos(window, &mouse_x, &mouse_y); + glfwGetCursorPos(state.window, &mouse_x, &mouse_y); - if (time - prev_time >= 1.0) { - double fps = (frame_count - prev_frame_count) / (time - prev_time); - log_debug("frame = %zu, time = %.2f, fps = %.2f, viewport = (%d, %d)", frame_count, - time, fps, viewport[2], viewport[3]); - prev_frame_count = frame_count; - prev_time = time; + if (state.time - state.prev_time >= 1.0) { + double fps = (state.frame_count - state.prev_frame_count) / (state.time - state.prev_time); + log_debug("frame = %zu, time = %.2f, fps = %.2f, viewport = (%d, %d)", + state.frame_count, state.time, fps, viewport[2], viewport[3]); + state.prev_frame_count = state.frame_count; + state.prev_time = state.time; } - if (buffer_shader_file) { + if (state.buffer_shader_file) { /* bind the framebuffer and draw to it */ glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); @@ -97,12 +94,12 @@ int main(int argc, char *argv[]) { glClear(GL_COLOR_BUFFER_BIT); /* Setup uniforms */ - glUseProgram(buffer_shader); - glUniform1ui(glGetUniformLocation(buffer_shader, "u_frame"), frame_count); - glUniform1f(glGetUniformLocation(buffer_shader, "u_time"), time); - glUniform2f(glGetUniformLocation(buffer_shader, "u_resolution"), + glUseProgram(state.buffer_shader); + glUniform1ui(glGetUniformLocation(state.buffer_shader, "u_frame"), state.frame_count); + glUniform1f(glGetUniformLocation(state.buffer_shader, "u_time"), state.time); + glUniform2f(glGetUniformLocation(state.buffer_shader, "u_resolution"), viewport[2], viewport[3]); - glUniform2f(glGetUniformLocation(buffer_shader, "u_mouse"), mouse_x, + glUniform2f(glGetUniformLocation(state.buffer_shader, "u_mouse"), mouse_x, mouse_y); /* Draw the vertices */ @@ -119,12 +116,12 @@ int main(int argc, char *argv[]) { glClear(GL_COLOR_BUFFER_BIT); /* Setup uniforms */ - glUseProgram(screen_shader); - glUniform1ui(glGetUniformLocation(screen_shader, "u_frame"), frame_count); - glUniform1f(glGetUniformLocation(screen_shader, "u_time"), time); - glUniform2f(glGetUniformLocation(screen_shader, "u_resolution"), + glUseProgram(state.screen_shader); + glUniform1ui(glGetUniformLocation(state.screen_shader, "u_frame"), state.frame_count); + glUniform1f(glGetUniformLocation(state.screen_shader, "u_time"), state.time); + glUniform2f(glGetUniformLocation(state.screen_shader, "u_resolution"), viewport[2], viewport[3]); - glUniform2f(glGetUniformLocation(screen_shader, "u_mouse"), mouse_x, + glUniform2f(glGetUniformLocation(state.screen_shader, "u_mouse"), mouse_x, mouse_y); /* Draw the vertices */ @@ -133,12 +130,12 @@ int main(int argc, char *argv[]) { glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); - glfwSwapBuffers(window); + glfwSwapBuffers(state.window); glfwPollEvents(); - frame_count++; + state.frame_count++; } - glfwDestroyWindow(window); + glfwDestroyWindow(state.window); glfwTerminate(); return EXIT_SUCCESS; } diff --git a/src/renderer.c b/src/renderer.c index 355cf1c..997ce22 100644 --- a/src/renderer.c +++ b/src/renderer.c @@ -186,23 +186,25 @@ void capture_screenshot() { * @brief Ensure the window is closed when the user presses the escape * key. * - * @param window The current window. - * @param shader_program Pointer to the shader program to update if needed. - * @param fragment_shader_file The shader file to reload if needed. + * @param state The current state of the renderer. */ -void process_input(GLFWwindow *window, unsigned int *screen_shader, - const char *const screen_shader_file, - unsigned int *buffer_shader, - const char *const buffer_shader_file) { - if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { +void process_input(struct renderer_state *state) { + if (glfwGetKey(state->window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { log_debug("Quitting"); - glfwSetWindowShouldClose(window, true); - } else if (glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) { - compile_shaders(screen_shader, screen_shader_file); - if (buffer_shader_file) { - compile_shaders(buffer_shader, buffer_shader_file); + glfwSetWindowShouldClose(state->window, true); + } else if (glfwGetKey(state->window, GLFW_KEY_R) == GLFW_PRESS) { + // reinitialize time and frame count + state->frame_count = 0; + state->prev_frame_count = 0; + glfwSetTime(0.0); + state->time = 0.0; + state->prev_time = 0.0; + // recompile shaders + compile_shaders(&state->screen_shader, state->screen_shader_file); + if (state->buffer_shader_file) { + compile_shaders(&state->buffer_shader, state->buffer_shader_file); } - } else if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { + } else if (glfwGetKey(state->window, GLFW_KEY_S) == GLFW_PRESS) { capture_screenshot(); } } diff --git a/src/renderer.h b/src/renderer.h index da77673..4d936ab 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -3,6 +3,22 @@ #include +/** + * Structure representing the state of the renderer and associated + * shaders. + */ +struct renderer_state { + GLFWwindow *window; /**< GLFW window where the shaders are rendered. */ + unsigned int screen_shader; /**< Shader for the main screen. */ + const char *screen_shader_file; /**< Screen shader file name. */ + unsigned int buffer_shader; /**< Shader for the background framebuffer. */ + const char *buffer_shader_file; /**< Buffer shader file name. */ + size_t frame_count; /**< Frame count since the beginning of the render loop. */ + size_t prev_frame_count; /**< Frame count at the last log. */ + double time; /**< Time in seconds since the beginning of the render loop. */ + double prev_time; /**< Time in seconds at the last log. */ +}; + GLFWwindow *initialize_window(int width, int height); unsigned int initialize_vertices(); unsigned int initialize_framebuffer(unsigned int *framebuffer, @@ -11,9 +27,6 @@ unsigned int initialize_framebuffer(unsigned int *framebuffer, unsigned int texture_height); void framebuffer_size_callback(GLFWwindow *window, int width, int height); void capture_screenshot(); -void process_input(GLFWwindow *window, unsigned int *screen_shader, - const char *const screen_shader_file, - unsigned int *buffer_shader, - const char *const buffer_shader_file); +void process_input(struct renderer_state *state); #endif /* RENDERER_H */