aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/error.c37
-rw-r--r--src/event.c33
-rw-r--r--src/shader.c73
-rw-r--r--src/state.c77
4 files changed, 144 insertions, 76 deletions
diff --git a/src/error.c b/src/error.c
index 92e3a71..1e2975f 100644
--- a/src/error.c
+++ b/src/error.c
@@ -7,7 +7,42 @@ void error_check_sdl(const char *code, const char *filename, int line_num)
err = SDL_GetError();
if (*err == '\0')
return ;
- SDL_Log("[ERROR SDL] %s\n\t(%s) at %s:%d", err, code, filename, line_num);
+ SDL_Log("[ERROR SDL] %s\n\t(%s) at %s:%d\n", err, code, filename, line_num);
SDL_Quit();
exit(EXIT_FAILURE);
}
+
+void error_clear_gl(void)
+{
+ while (glGetError() != GL_NO_ERROR)
+ ;
+}
+
+void error_check_gl(const char *code, const char *filename, int line_num)
+{
+ GLenum err;
+ bool occured;
+ char *err_str = "";
+
+ occured = false;
+ while ((err = glGetError()) != GL_NO_ERROR)
+ {
+ switch (err)
+ {
+ case GL_INVALID_OPERATION:
+ err_str = "GL_INVALID_OPERATION";
+ break;
+ case GL_INVALID_VALUE:
+ err_str = "GL_INVALID_VALUE";
+ break;
+ case GL_INVALID_ENUM:
+ err_str = "GL_INVALID_ENUM";
+ break;
+ }
+ fprintf(stderr, "[ERROR OPENGL] (%d) %s\n\t(%s) at %s:%d\n",
+ err, err_str, code, filename, line_num);
+ occured = true;
+ }
+ if (occured)
+ exit(EXIT_FAILURE);
+}
diff --git a/src/event.c b/src/event.c
index f0f0e14..2ce5cc9 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->palette = color_palette_new(state->palette, 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->palette = color_palette_new(state->palette, state->iterations); */
break;
case SDLK_UP:
case SDLK_k:
@@ -68,26 +68,15 @@ void event_handle(State *state)
case SDL_WINDOWEVENT:
if (e.window.event == SDL_WINDOWEVENT_RESIZED)
{
- int width;
- int height;
- SDL_QueryTexture(state->texture, NULL, NULL, &width, &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;
-
- SDL_DestroyTexture(state->texture);
- SDL_CALL(state->texture = SDL_CreateTexture(
- state->renderer,
- SDL_PIXELFORMAT_RGB888,
- SDL_TEXTUREACCESS_STREAMING,
- e.window.data1,
- 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; */
}
break;
}
diff --git a/src/shader.c b/src/shader.c
new file mode 100644
index 0000000..478c93b
--- /dev/null
+++ b/src/shader.c
@@ -0,0 +1,73 @@
+#include "mandel.h"
+
+#define MANDEL_SHADER_VERT_FILE "shader/vertex.glsl"
+#define MANDEL_SHADER_FRAG_FILE "shader/fragment.glsl"
+
+static unsigned int st_compile(char *filepath, unsigned int type);
+
+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)
+ return false;
+
+ GL_CALL(shader->id = glCreateProgram());
+ GL_CALL(glAttachShader(shader->id, shader_vert));
+ GL_CALL(glAttachShader(shader->id, shader_frag));
+ GL_CALL(glLinkProgram(shader->id));
+ GL_CALL(glValidateProgram(shader->id));
+ GL_CALL(glDeleteShader(shader_vert));
+ GL_CALL(glDeleteShader(shader_frag));
+ return (true);
+}
+
+static unsigned int st_compile(char *filepath, unsigned int type)
+{
+ unsigned int id;
+ int result;
+ FILE *file;
+ char *source;
+
+ if ((file = fopen(filepath, "r")) == NULL)
+ return 0;
+ fseek(file, 0, SEEK_END);
+ long file_size = ftell(file);
+ rewind(file);
+
+ if ((source = malloc(sizeof(char) * (file_size + 1))) == NULL
+ || fread(source, sizeof(char), file_size, file) != (unsigned long)file_size)
+ {
+ free(source);
+ fclose(file);
+ return 0;
+ }
+ fclose(file);
+ source[file_size] = '\0';
+
+ GL_CALL(id = glCreateShader(type));
+ GL_CALL(glShaderSource(id, 1, (const char**)&source, (int*)&file_size));
+ free(source);
+ GL_CALL(glCompileShader(id));
+
+ GL_CALL(glGetShaderiv(id, GL_COMPILE_STATUS, &result));
+ if (result == GL_FALSE)
+ {
+ int len;
+ char *msg;
+ GL_CALL(glGetShaderiv(id, GL_INFO_LOG_LENGTH, &len));
+ if ((msg = malloc(sizeof(char) * (len + 1))) == NULL)
+ return 0;
+ GL_CALL(glGetShaderInfoLog(id, len, &len, msg));
+ fputs(msg, stderr);
+ free(msg);
+ GL_CALL(glDeleteShader(id));
+ return 0;
+ }
+ return id;
+}
diff --git a/src/state.c b/src/state.c
index 395d590..b2ea45c 100644
--- a/src/state.c
+++ b/src/state.c
@@ -4,25 +4,32 @@
bool state_init(State *state)
{
SDL_CALL(SDL_Init(SDL_INIT_VIDEO));
+ SDL_CALL(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4));
+ SDL_CALL(SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0));
+ SDL_CALL(SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE));
+ SDL_CALL(SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1));
SDL_CALL(state->window = SDL_CreateWindow(
MANDEL_WINDOW_TITLE,
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
MANDEL_WINDOW_WIDTH,
MANDEL_WINDOW_HEIGHT,
- SDL_WINDOW_RESIZABLE
+ SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
));
- SDL_CALL(state->renderer = SDL_CreateRenderer(state->window, -1, 0));
- SDL_CALL(state->texture = SDL_CreateTexture(
- state->renderer,
- SDL_PIXELFORMAT_RGB888,
- SDL_TEXTUREACCESS_STREAMING,
- MANDEL_WINDOW_WIDTH,
- MANDEL_WINDOW_HEIGHT
- ));
- state->palette = color_palette_new(NULL, MANDEL_ITERATIONS);
- if (state->palette == NULL)
+ SDL_CALL(state->context = SDL_GL_CreateContext(state->window));
+ assert(glewInit() == GLEW_OK);
+ SDL_CALL(SDL_GL_SetSwapInterval(1));
+ if (!shader_init(&state->shader))
+ {
+ perror(NULL);
return false;
+ }
+ SDL_GL_GetDrawableSize(state->window, &state->width, &state->height);
+ GL_CALL(glViewport(0, 0, state->width, state->height));
+
+ /* state->palette = color_palette_new(NULL, MANDEL_ITERATIONS); */
+ /* if (state->palette == NULL) */
+ /* return false; */
state->iterations = MANDEL_ITERATIONS;
state->real_start = -2.0;
state->real_end = 2.0;
@@ -37,55 +44,19 @@ 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);
- double real_step;
- double imag_step;
- double real;
- double imag;
- void *pixels;
- int pitch;
- int width;
- int height;
-
- SDL_CALL(SDL_LockTexture(state->texture, NULL, &pixels, &pitch));
- SDL_CALL(SDL_QueryTexture(state->texture, NULL, NULL, &width, &height));
-
- real_step = (state->real_end - state->real_start) / width;
- imag_step = (state->imag_end - state->imag_start) / height;
- imag = state->imag_start;
-
- uint32_t render_start_time = SDL_GetTicks();
-
- for (int i = 0; i < height; i++)
- {
- real = state->real_start;
- for (int j = 0; j < width; j++)
- {
- int n = mandelbrot(real, imag, state->iterations);
- Color c = state->palette[n];
- ((Color*)pixels)[i * width + j] = c;
- real += real_step;
- }
- imag += imag_step;
- }
-
- uint32_t render_end_time = SDL_GetTicks();
-
- printf("%ums\r", (render_end_time - render_start_time));
- fflush(stdout);
-
- SDL_UnlockTexture(state->texture);
- SDL_CALL(SDL_RenderCopy(state->renderer, state->texture, NULL, NULL));
- SDL_RenderPresent(state->renderer);
+ SDL_GL_SwapWindow(state->window);
SDL_Delay(3);
}
}
void state_quit(State *state)
{
- free(state->palette);
- SDL_DestroyTexture(state->texture);
- SDL_DestroyRenderer(state->renderer);
+ /* free(state->palette); */
+ GL_CALL(glDeleteProgram(state->shader.id));
+ SDL_GL_DeleteContext(state->context);
SDL_DestroyWindow(state->window);
SDL_Quit();
}