diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/error.c | 37 | ||||
| -rw-r--r-- | src/event.c | 33 | ||||
| -rw-r--r-- | src/shader.c | 73 | ||||
| -rw-r--r-- | src/state.c | 77 |
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(); } |
