From 70bf7ac330545f14ab9babddfdf0cb5df9e9ee69 Mon Sep 17 00:00:00 2001 From: Charles Date: Tue, 19 May 2020 22:45:04 +0200 Subject: Simple (but insanly fast compared to CPU) fragment shader to draw mandelbrot set --- src/event.c | 2 +- src/shader.c | 24 ++++++++++++++++++++++++ src/state.c | 27 +++++++++++++++++++++++++-- 3 files changed, 50 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/event.c b/src/event.c index 2ce5cc9..18763b0 100644 --- a/src/event.c +++ b/src/event.c @@ -108,7 +108,7 @@ static void st_move_horizontal(State *state, bool move_right) static void st_move_vertical(State *state, bool move_down) { - double factor = move_down ? 1 : -1; + double factor = move_down ? -1 : 1; double imag_change = (state->imag_end - state->imag_start) / MANDEL_MOVE_RATIO; state->imag_start += factor * imag_change; state->imag_end += factor * imag_change; diff --git a/src/shader.c b/src/shader.c index 478c93b..0b4091d 100644 --- a/src/shader.c +++ b/src/shader.c @@ -24,9 +24,33 @@ bool shader_init(Shader *shader) GL_CALL(glValidateProgram(shader->id)); GL_CALL(glDeleteShader(shader_vert)); GL_CALL(glDeleteShader(shader_frag)); + + GL_CALL(shader->location.width = glGetUniformLocation(shader->id, "u_width")); + GL_CALL(shader->location.height = glGetUniformLocation(shader->id, "u_height")); + + GL_CALL(shader->location.real_start = glGetUniformLocation(shader->id, "u_real_start")); + GL_CALL(shader->location.real_end = glGetUniformLocation(shader->id, "u_real_end")); + GL_CALL(shader->location.imag_start = glGetUniformLocation(shader->id, "u_imag_start")); + GL_CALL(shader->location.imag_end = glGetUniformLocation(shader->id, "u_imag_end")); + + GL_CALL(shader->location.iterations = glGetUniformLocation(shader->id, "u_iterations")); + return (true); } +void shader_set_uniforms(Shader *shader, State *state) +{ + GL_CALL(glUniform1i(shader->location.width, state->width)); + GL_CALL(glUniform1i(shader->location.height, state->height)); + + GL_CALL(glUniform1f(shader->location.real_start, state->real_start)); + GL_CALL(glUniform1f(shader->location.real_end, state->real_end)); + GL_CALL(glUniform1f(shader->location.imag_start, state->imag_start)); + GL_CALL(glUniform1f(shader->location.imag_end, state->imag_end)); + + GL_CALL(glUniform1i(shader->location.iterations, state->iterations)); +} + static unsigned int st_compile(char *filepath, unsigned int type) { unsigned int id; diff --git a/src/state.c b/src/state.c index b2ea45c..3468464 100644 --- a/src/state.c +++ b/src/state.c @@ -27,6 +27,24 @@ bool state_init(State *state) SDL_GL_GetDrawableSize(state->window, &state->width, &state->height); GL_CALL(glViewport(0, 0, state->width, state->height)); + float vertices[] = { + 1.0f, 1.0f, + 1.0f, -1.0f, + -1.0f, 1.0f, + + 1.0f, -1.0f, + -1.0f, -1.0f, + -1.0f, 1.0f, + }; + GL_CALL(glGenVertexArrays(1, &state->vertex_array)); + GL_CALL(glBindVertexArray(state->vertex_array)); + + GL_CALL(glGenBuffers(1, &state->vertex_buf)); + GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, state->vertex_buf)); + GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW)); + GL_CALL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0)); + GL_CALL(glEnableVertexAttribArray(0)); + /* state->palette = color_palette_new(NULL, MANDEL_ITERATIONS); */ /* if (state->palette == NULL) */ /* return false; */ @@ -44,8 +62,13 @@ void state_run(State *state) while (state->running) { event_handle(state); - glClearColor(0.2, 0.3, 0.2, 1.0); - glClear(GL_COLOR_BUFFER_BIT); + GL_CALL(glClearColor(0.2, 0.3, 0.2, 1.0)); + GL_CALL(glClear(GL_COLOR_BUFFER_BIT)); + + GL_CALL(glUseProgram(state->shader.id)); + shader_set_uniforms(&state->shader, state); + GL_CALL(glBindVertexArray(state->vertex_array)); + GL_CALL(glDrawArrays(GL_TRIANGLES, 0, 6)); SDL_GL_SwapWindow(state->window); SDL_Delay(3); -- cgit