aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-05-20 07:41:03 +0200
committerCharles <sircharlesaze@gmail.com>2020-05-20 07:41:03 +0200
commit09a819b2ef927adf5239a73f91cdfcefd6774688 (patch)
tree8602814faa153aae01acc95a557d45b24c028f3b
parent70bf7ac330545f14ab9babddfdf0cb5df9e9ee69 (diff)
downloadmandelbrot-09a819b2ef927adf5239a73f91cdfcefd6774688.tar.gz
mandelbrot-09a819b2ef927adf5239a73f91cdfcefd6774688.tar.bz2
mandelbrot-09a819b2ef927adf5239a73f91cdfcefd6774688.zip
Added colors with 1D texture
-rw-r--r--Makefile2
-rw-r--r--inc/mandel.h25
-rw-r--r--shader/fragment.glsl35
-rw-r--r--src/color.c30
-rw-r--r--src/event.c17
-rw-r--r--src/shader.c37
-rw-r--r--src/state.c11
7 files changed, 90 insertions, 67 deletions
diff --git a/Makefile b/Makefile
index 0b2f4ab..34f2f01 100644
--- a/Makefile
+++ b/Makefile
@@ -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);