diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-05-20 07:41:03 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-05-20 07:41:03 +0200 |
| commit | 09a819b2ef927adf5239a73f91cdfcefd6774688 (patch) | |
| tree | 8602814faa153aae01acc95a557d45b24c028f3b | |
| parent | 70bf7ac330545f14ab9babddfdf0cb5df9e9ee69 (diff) | |
| download | mandelbrot-09a819b2ef927adf5239a73f91cdfcefd6774688.tar.gz mandelbrot-09a819b2ef927adf5239a73f91cdfcefd6774688.tar.bz2 mandelbrot-09a819b2ef927adf5239a73f91cdfcefd6774688.zip | |
Added colors with 1D texture
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | inc/mandel.h | 25 | ||||
| -rw-r--r-- | shader/fragment.glsl | 35 | ||||
| -rw-r--r-- | src/color.c | 30 | ||||
| -rw-r--r-- | src/event.c | 17 | ||||
| -rw-r--r-- | src/shader.c | 37 | ||||
| -rw-r--r-- | src/state.c | 11 |
7 files changed, 90 insertions, 67 deletions
@@ -7,7 +7,7 @@ INC_DIR = inc OBJ_DIR = obj CC = gcc -OFLAG = -O0 #-Ofast -funroll-loops -ffast-math +OFLAG = -O3 CCFLAGS = -I$(INC_DIR) -Wall -Wextra -Wpedantic $(OFLAG) \ $(shell pkg-config --cflags sdl2 glew) LDFLAGS = $(shell pkg-config --libs sdl2 glew) diff --git a/inc/mandel.h b/inc/mandel.h index a537f87..ca2988e 100644 --- a/inc/mandel.h +++ b/inc/mandel.h @@ -22,15 +22,11 @@ error_check_gl(#x, __FILE__, __LINE__); \ } while (0) -typedef union +typedef struct { - uint32_t data; - struct - { - uint8_t b; - uint8_t g; - uint8_t r; - }; + uint8_t r; + uint8_t b; + uint8_t g; } Color; typedef struct @@ -53,13 +49,12 @@ typedef struct { int width; int height; - - float real_start; - float real_end; - float imag_start; - float imag_end; - + int real_start; + int real_end; + int imag_start; + int imag_end; int iterations; + int texture; } location; } Shader; @@ -103,7 +98,7 @@ void error_clear_gl(void); void error_check_gl(const char *code, const char *filename, int line_num); // color.c -Color *color_palette_new(Color *palette, int iterations); +unsigned int color_texture_new(int iterations); // shader.c bool shader_init(Shader *shader); diff --git a/shader/fragment.glsl b/shader/fragment.glsl index 19b020e..6720236 100644 --- a/shader/fragment.glsl +++ b/shader/fragment.glsl @@ -1,16 +1,20 @@ #version 400 core -out vec4 out_color; +out vec4 out_color; -uniform int u_width; -uniform int u_height; +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 float u_real_start; +uniform float u_real_end; +uniform float u_imag_start; +uniform float u_imag_end; -uniform int u_iterations; +uniform int u_iterations; + +uniform sampler1D u_texture; + +#define ESCAPE_RADIUS 4.0 void main() { @@ -18,15 +22,16 @@ void main() 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; + int n; for (n = 0; n < u_iterations; n++) { zi_square = zi * zi; zr_square = zr * zr; - if (zr_square + zi_square > 4.0) + if (zr_square + zi_square > ESCAPE_RADIUS) break; zi = 2.0 * zr * zi; zr = zr_square - zi_square; @@ -34,10 +39,8 @@ void main() zr += ca; } - out_color = vec4( - float(n) / float(u_iterations), - float(n) / float(u_iterations), - 0.0, - 1.0 - ); + if (n == u_iterations) + out_color = vec4(0.0, 0.0, 0.0, 1.0); + else + out_color = texture1D(u_texture, float(n) / float(u_iterations)); } diff --git a/src/color.c b/src/color.c index 2ad4bad..24ca2f2 100644 --- a/src/color.c +++ b/src/color.c @@ -5,22 +5,36 @@ static Color color_hsl_to_rgb(ColorHSL color_hsl); -Color *color_palette_new(Color *palette, int iterations) +unsigned int color_texture_new(int count) { - ColorHSL hsl; + ColorHSL hsl; + Color *palette; + unsigned int texture; - palette = realloc(palette, sizeof(Color) * (iterations + 1)); + palette = malloc(sizeof(Color) * count); if (palette == NULL) - return NULL; - for (int i = 0; i < iterations; i++) + return 0; + for (int i = 0; i < count; i++) { - hsl.h = (int)(255.0 * ((double)i / (double)iterations)); + hsl.h = (uint8_t)(255.0 * ((double)i / (double)count)); hsl.s = 150; hsl.l = 127; palette[i] = color_hsl_to_rgb(hsl); } - palette[iterations].data = 0x0; - return palette; + for (int i = 0, j = count - 1; i < j; i++, j--) + { + Color tmp = palette[i]; + palette[i] = palette[j]; + palette[j] = tmp; + } + + GL_CALL(glGenTextures(1, &texture)); + GL_CALL(glBindTexture(GL_TEXTURE_1D, texture)); + GL_CALL(glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + GL_CALL(glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + GL_CALL(glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, count + 1, 0, GL_RGB, GL_UNSIGNED_BYTE, palette)); + free(palette); + return texture; } static Color color_hsl_to_rgb(ColorHSL color_hsl) diff --git a/src/event.c b/src/event.c index 18763b0..6fd6a8c 100644 --- a/src/event.c +++ b/src/event.c @@ -21,13 +21,13 @@ void event_handle(State *state) { case SDLK_r: state->iterations += 10; - /* state->palette = color_palette_new(state->palette, state->iterations); */ + /* state->texture = color_texture_new( state->iterations); */ break; case SDLK_e: state->iterations -= 10; if (state->iterations <= 0) state->iterations = 1; - /* state->palette = color_palette_new(state->palette, state->iterations); */ + /* state->texture = color_texture_new( state->iterations); */ break; case SDLK_UP: case SDLK_k: @@ -68,15 +68,14 @@ void event_handle(State *state) case SDL_WINDOWEVENT: if (e.window.event == SDL_WINDOWEVENT_RESIZED) { + double w_ratio = (double)state->width / (double)e.window.data1; + double h_ratio = (double)state->height / (double)e.window.data2; SDL_GL_GetDrawableSize(state->window, &state->width, &state->height); GL_CALL(glViewport(0, 0, state->width, state->height)); - /* double w_ratio = (double)width / (double)e.window.data1; */ - /* double h_ratio = (double)height / (double)e.window.data2; */ - /* */ - /* state->real_start /= w_ratio; */ - /* state->real_end /= w_ratio; */ - /* state->imag_start /= h_ratio; */ - /* state->imag_end /= h_ratio; */ + state->real_start /= w_ratio; + state->real_end /= w_ratio; + state->imag_start /= h_ratio; + state->imag_end /= h_ratio; } break; } diff --git a/src/shader.c b/src/shader.c index 0b4091d..68295ab 100644 --- a/src/shader.c +++ b/src/shader.c @@ -4,17 +4,15 @@ #define MANDEL_SHADER_FRAG_FILE "shader/fragment.glsl" static unsigned int st_compile(char *filepath, unsigned int type); +static int st_get_location(unsigned int shader_id, const char *name); bool shader_init(Shader *shader) { unsigned int shader_vert; unsigned int shader_frag; - shader_vert = st_compile(MANDEL_SHADER_VERT_FILE, GL_VERTEX_SHADER); - if (shader_vert == 0) - return false; - shader_frag = st_compile(MANDEL_SHADER_FRAG_FILE, GL_FRAGMENT_SHADER); - if (shader_frag == 0) + if ((shader_vert = st_compile(MANDEL_SHADER_VERT_FILE, GL_VERTEX_SHADER)) == 0 + || (shader_frag = st_compile(MANDEL_SHADER_FRAG_FILE, GL_FRAGMENT_SHADER)) == 0) return false; GL_CALL(shader->id = glCreateProgram()); @@ -25,17 +23,24 @@ bool shader_init(Shader *shader) 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")); + if ((shader->location.width = st_get_location(shader->id, "u_width")) == -1 + || (shader->location.height = st_get_location(shader->id, "u_height")) == -1 + || (shader->location.real_start = st_get_location(shader->id, "u_real_start")) == -1 + || (shader->location.real_end = st_get_location(shader->id, "u_real_end")) == -1 + || (shader->location.imag_start = st_get_location(shader->id, "u_imag_start")) == -1 + || (shader->location.imag_end = st_get_location(shader->id, "u_imag_end")) == -1 + || (shader->location.iterations = st_get_location(shader->id, "u_iterations")) == -1 + || (shader->location.texture = st_get_location(shader->id, "u_texture")) == -1) + return false; + return true; +} - GL_CALL(shader->location.iterations = glGetUniformLocation(shader->id, "u_iterations")); +static int st_get_location(unsigned int shader_id, const char *name) +{ + int location; - return (true); + GL_CALL(location = glGetUniformLocation(shader_id, name)); + return location; } void shader_set_uniforms(Shader *shader, State *state) @@ -49,6 +54,10 @@ void shader_set_uniforms(Shader *shader, State *state) GL_CALL(glUniform1f(shader->location.imag_end, state->imag_end)); GL_CALL(glUniform1i(shader->location.iterations, state->iterations)); + + GL_CALL(glUniform1i(shader->location.texture, 0)); + GL_CALL(glActiveTexture(GL_TEXTURE0)); + GL_CALL(glBindTexture(GL_TEXTURE_1D, state->texture)); } static unsigned int st_compile(char *filepath, unsigned int type) diff --git a/src/state.c b/src/state.c index 3468464..37eeccc 100644 --- a/src/state.c +++ b/src/state.c @@ -24,6 +24,7 @@ bool state_init(State *state) perror(NULL); return false; } + SDL_GL_GetDrawableSize(state->window, &state->width, &state->height); GL_CALL(glViewport(0, 0, state->width, state->height)); @@ -45,10 +46,10 @@ bool state_init(State *state) 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; */ state->iterations = MANDEL_ITERATIONS; + state->texture = color_texture_new(1024); + if (state->texture == 0) + return false; state->real_start = -2.0; state->real_end = 2.0; state->imag_start = -2.0; @@ -77,7 +78,9 @@ void state_run(State *state) void state_quit(State *state) { - /* free(state->palette); */ + GL_CALL(glDeleteTextures(1, &state->texture)); + GL_CALL(glDeleteBuffers(1, &state->vertex_buf)); + GL_CALL(glDeleteVertexArrays(1, &state->vertex_array)); GL_CALL(glDeleteProgram(state->shader.id)); SDL_GL_DeleteContext(state->context); SDL_DestroyWindow(state->window); |
