diff options
| -rw-r--r-- | inc/mandel.h | 12 | ||||
| -rw-r--r-- | shader/fragment.glsl | 39 | ||||
| -rw-r--r-- | shader/vertex.glsl | 3 | ||||
| -rw-r--r-- | src/event.c | 2 | ||||
| -rw-r--r-- | src/shader.c | 24 | ||||
| -rw-r--r-- | src/state.c | 27 |
6 files changed, 101 insertions, 6 deletions
diff --git a/inc/mandel.h b/inc/mandel.h index f55466c..a537f87 100644 --- a/inc/mandel.h +++ b/inc/mandel.h @@ -51,7 +51,15 @@ typedef struct unsigned int id; struct { - int iteration; + int width; + int height; + + float real_start; + float real_end; + float imag_start; + float imag_end; + + int iterations; } location; } Shader; @@ -64,6 +72,7 @@ typedef struct int height; unsigned int vertex_buf; + unsigned int vertex_array; unsigned int texture; Shader shader; @@ -98,5 +107,6 @@ Color *color_palette_new(Color *palette, int iterations); // shader.c bool shader_init(Shader *shader); +void shader_set_uniforms(Shader *shader, State *state); #endif diff --git a/shader/fragment.glsl b/shader/fragment.glsl index 3fbeac5..19b020e 100644 --- a/shader/fragment.glsl +++ b/shader/fragment.glsl @@ -1,8 +1,43 @@ #version 400 core -out vec4 out_color; +out vec4 out_color; + +uniform int u_width; +uniform int u_height; + +uniform float u_real_start; +uniform float u_real_end; +uniform float u_imag_start; +uniform float u_imag_end; + +uniform int u_iterations; void main() { - out_color = vec4(1.0, 1.0, 1.0, 1.0); + float ca = u_real_start + float(gl_FragCoord.x) / float(u_width) * (u_real_end - u_real_start); + float cb = u_imag_start + float(gl_FragCoord.y) / float(u_height) * (u_imag_end - u_imag_start); + float zr = ca; + float zi = cb; + float zr_square; + float zi_square; + int n; + + for (n = 0; n < u_iterations; n++) + { + zi_square = zi * zi; + zr_square = zr * zr; + if (zr_square + zi_square > 4.0) + break; + zi = 2.0 * zr * zi; + zr = zr_square - zi_square; + zi += cb; + zr += ca; + } + + out_color = vec4( + float(n) / float(u_iterations), + float(n) / float(u_iterations), + 0.0, + 1.0 + ); } diff --git a/shader/vertex.glsl b/shader/vertex.glsl index 9ec6439..714e089 100644 --- a/shader/vertex.glsl +++ b/shader/vertex.glsl @@ -1,5 +1,8 @@ #version 400 core +layout (location = 0) in vec2 in_position; + void main() { + gl_Position = vec4(in_position, 0.0, 1.0); } 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); |
