aboutsummaryrefslogtreecommitdiff
path: root/graphics.c
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-05-19 13:22:59 +0200
committerCharles <sircharlesaze@gmail.com>2020-05-19 13:22:59 +0200
commit6a80b1b70ec069b051c0e31aafac6eb596e20261 (patch)
treeedf9856bcd2b4415796a2a49f0232ba830e69560 /graphics.c
parentc5008a4e62fb83eb71f5f94f622c01f2d8fe8b6b (diff)
downloadmandelbrot-6a80b1b70ec069b051c0e31aafac6eb596e20261.tar.gz
mandelbrot-6a80b1b70ec069b051c0e31aafac6eb596e20261.tar.bz2
mandelbrot-6a80b1b70ec069b051c0e31aafac6eb596e20261.zip
Back to basic SDL application boilerplate
Diffstat (limited to 'graphics.c')
-rw-r--r--graphics.c302
1 files changed, 0 insertions, 302 deletions
diff --git a/graphics.c b/graphics.c
deleted file mode 100644
index e422071..0000000
--- a/graphics.c
+++ /dev/null
@@ -1,302 +0,0 @@
-#include <stdbool.h>
-#include <pthread.h>
-#include <SDL2/SDL.h>
-#include "header.h"
-
-#define WINDOW_TITLE "Mandelbrot"
-#define WINDOW_X 20
-#define WINDOW_Y 20
-#define REFRESH_RATE 2
-#define MOVE_RATIO 10
-#define ZOOM_RATIO 1.1
-#define REAL_LO(state) (state->center.x - state->real_range / 2)
-#define REAL_HI(state) (state->center.x + state->real_range / 2)
-#define IMAG_LO(state) (state->center.y - state->imag_range / 2)
-#define IMAG_HI(state) (state->center.y + state->imag_range / 2)
-
-#define IN_SET_COLOR 0x050505
-#define PALETTE_START 0x000022
-#define PALETTE_END 0xd62f2f
-/* #define PALETTE_START 0x000000 */
-/* #define PALETTE_END 0xffffff */
-#define SET_DRAW_COLOR(renderer, c) ( \
- SDL_SetRenderDrawColor(renderer, c.rgb.r, c.rgb.g, c.rgb.b, SDL_ALPHA_OPAQUE));
-
-#define RED_MASK 0x0000ff
-#define GREEN_MASK 0x00ff00
-#define BLUE_MASK 0xff0000
-#define PITCH(ch, width) (ch * width)
-
-static void update(GState *state);
-static void event_handler(GState *state);
-static Color *create_palette(Color start, Color end);
-/* static void move_center(GState *state, int motion_x, int motion_y); */
-static void recenter(GState *state, int x, int y);
-static void recenter_x(GState *state, int x);
-static void recenter_y(GState *state, int y);
-static void zoom_in(GState *state, double ratio);
-static void zoom_out(GState *state, double ratio);
-static void destroy_state(GState *state);
-static void error_exit_state(GState *state, const char *msg);
-static void error_exit(const char *msg);
-
-GState *graphics_init(Config *config)
-{
- Color start, end;
-
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
- error_exit("unable to init SDL");
- GState *state = (GState*)malloc(sizeof(GState));
- if (state == NULL)
- error_exit("state allocation failed");
- state->window = SDL_CreateWindow(WINDOW_TITLE, WINDOW_X, WINDOW_Y,
- config->window_w, config->window_h, 0);
- if (state->window == NULL)
- error_exit_state(state, "unable to create window");
- state->renderer = SDL_CreateRenderer(state->window, -1, 0);
- if (state->renderer == NULL)
- error_exit_state(state, "unable to create renderer");
- start.hexcode = PALETTE_START;
- end.hexcode = PALETTE_END;
- state->palette = create_palette(start, end);
- if (state->palette == NULL)
- error_exit_state(state, "unable to create color palette");
- state->canvas = SDL_CreateTexture(
- state->renderer, SDL_PIXELFORMAT_RGBA8888,
- SDL_TEXTUREACCESS_TARGET, config->window_w, config->window_h
- );
- if (state->canvas == NULL)
- error_exit_state(state, "unable to create canvas texture");
- state->running = true;
- state->window_w = config->window_w;
- state->window_h = config->window_h;
- state->real_range = config->real_range;
- state->imag_range = config->imag_range;
- state->center.x = config->center_x;
- state->center.y = config->center_y;
- state->in_set_color.hexcode = IN_SET_COLOR;
- state->moving = false;
- state->changed = true;
- return state;
-}
-
-void graphics_quit(GState *state)
-{
- destroy_state(state);
- SDL_Quit();
-}
-
-void graphics_run(GState *state)
-{
- while (state->running)
- {
- event_handler(state);
- if (state->changed)
- {
- update(state);
- state->changed = false;
- }
- SDL_Delay(REFRESH_RATE);
- }
-}
-
-static void update(GState *state)
-{
- void *pixels = mandelbrot_pixels(REAL_LO(state), REAL_HI(state),
- IMAG_LO(state), IMAG_HI(state),
- state->window_w, state->window_h, state->palette);
- if (pixels == NULL)
- error_exit_state(state, "unable to create pixels");
- SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(
- pixels, state->window_w, state->window_h,
- PIXELS_DEPTH, PITCH(PIXELS_CHANELS, state->window_w),
- RED_MASK, BLUE_MASK, GREEN_MASK, 0
- );
- if (surface == NULL)
- {
- free(pixels);
- error_exit_state(state, "unable to create pixels surface");
- }
- SDL_Texture *texture = SDL_CreateTextureFromSurface(state->renderer, surface);
- free(pixels);
- SDL_FreeSurface(surface);
- if (texture == NULL)
- error_exit_state(state, "unable to create texture");
- SDL_Rect frame;
- if (SDL_QueryTexture(texture, NULL, NULL, &frame.w, &frame.h) != 0)
- {
- SDL_DestroyTexture(texture);
- error_exit_state(state, "unable to load texture");
- }
- frame.x = 0;
- frame.y = 0;
- if (SDL_RenderCopy(state->renderer, texture, NULL, &frame) != 0)
- {
- SDL_DestroyTexture(texture);
- error_exit_state(state, "unable to render texture");
- }
- SDL_RenderPresent(state->renderer);
- SDL_DestroyTexture(texture);
-}
-
-static void event_handler(GState *state)
-{
- SDL_Event e;
- while (SDL_PollEvent(&e))
- {
- switch (e.type)
- {
- case SDL_QUIT:
- state->running = false;
- break;
- case SDL_KEYDOWN:
- switch (e.key.keysym.sym)
- {
- case SDLK_UP:
- case SDLK_k:
- state->center.y -= state->imag_range / MOVE_RATIO;
- break;
- case SDLK_DOWN:
- case SDLK_j:
- state->center.y += state->imag_range / MOVE_RATIO;
- break;
- case SDLK_LEFT:
- case SDLK_h:
- state->center.x -= state->real_range / MOVE_RATIO;
- break;
- case SDLK_RIGHT:
- case SDLK_l:
- state->center.x += state->real_range / MOVE_RATIO;
- break;
- case SDLK_PLUS:
- case SDLK_p:
- zoom_in(state, ZOOM_RATIO);
- break;
- case SDLK_MINUS:
- case SDLK_m:
- zoom_out(state, ZOOM_RATIO);
- break;
- case SDLK_q:
- state->running = false;
- }
- break;
- case SDL_MOUSEWHEEL:
- if (e.wheel.y == -1)
- zoom_in(state, ZOOM_RATIO);
- else if (e.wheel.y == 1)
- zoom_out(state, ZOOM_RATIO);
- break;
- case SDL_MOUSEBUTTONDOWN:
- /* printf("> %d, %d\n", e.button.x, e.button.y); */
- if (e.button.button == SDL_BUTTON_RIGHT)
- recenter(state, e.button.x, e.button.y);
- // TODO
- /* case SDL_MOUSEBUTTONUP: */
- /* if (e.button.button == SDL_BUTTON_LEFT) */
- /* { */
- /* if (!state->moving && e.button.state == SDL_PRESSED) */
- /* state->moving = true; */
- /* else if (state->moving && e.button.state == SDL_RELEASED) */
- /* state->moving = false; */
- /* printf("%d %d\n", state->moving, e.button.state); */
- /* } */
- /* break; */
- /* case SDL_MOUSEMOTION: */
- /* if (state->moving) */
- /* { */
- /* printf("%d, %d\n", e.motion.x, e.motion.y); */
- /* move_center(state, e.motion.xrel, e.motion.yrel); */
- /* printf("%f, %f\n", state->center.x, state->center.y); */
- /* } */
- }
- state->changed = true;
- }
-}
-
- static Color *create_palette(Color start, Color end)
-{
- int red_step = abs(end.rgb.r - start.rgb.r) / MAX_ITERATION;
- int green_step = abs(end.rgb.g - start.rgb.g) / MAX_ITERATION;
- int blue_step = abs(end.rgb.b - start.rgb.b) / MAX_ITERATION;
-
- Color *palette = (Color*)malloc(sizeof(Color) * (MAX_ITERATION + 1));
- if (palette == NULL)
- return NULL;
- for (int i = 0; i < MAX_ITERATION; i++)
- {
- /* palette[i] = helper_HSL_to_RGB(i, 0.6, 1.0); */
- /* printf("%x\n", palette[i].hexcode); */
- palette[i].rgb.r = i * red_step + start.rgb.r;
- palette[i].rgb.g = i * green_step + start.rgb.g;
- palette[i].rgb.b = i * blue_step + start.rgb.b;
- }
- palette[MAX_ITERATION].hexcode = 0x0;
- return palette;
-}
-
-// TODO
-/* static void move_center(GState *state, int motion_x, int motion_y) */
-/* { */
-/* printf("%d, %d\n", motion_x, motion_y); */
-/* if (motion_x != 0) */
-/* state->center.x -= map_range(150 - motion_x, 0, state->window_w, */
-/* REAL_LO(state), REAL_HI(state)); */
-/* if (motion_y != 0) */
-/* state->center.y -= map_range(150 - motion_y, 0, state->window_h, */
-/* IMAG_LO(state), IMAG_HI(state)); */
-/* printf(">> %f, %f\n", state->center.x, state->center.y); */
-/* } */
-
-static void recenter(GState *state, int x, int y)
-{
- recenter_x(state, x);
- recenter_y(state, y);
-}
-
-static void recenter_x(GState *state, int x)
-{
- state->center.x = map_range(x, 0, state->window_w,
- REAL_LO(state), REAL_HI(state));
-}
-
-static void recenter_y(GState *state, int y)
-{
- state->center.y = map_range(y, 0, state->window_w,
- IMAG_LO(state), IMAG_HI(state));
-}
-
-static void zoom_in(GState *state, double ratio)
-{
- state->real_range /= ratio;
- state->imag_range /= ratio;
-}
-
-static void zoom_out(GState *state, double ratio)
-{
- state->real_range *= ratio;
- state->imag_range *= ratio;
-}
-
-static void destroy_state(GState *state)
-{
- if (state == NULL)
- return;
- free(state->palette);
- SDL_DestroyTexture(state->canvas);
- SDL_DestroyRenderer(state->renderer);
- SDL_DestroyWindow(state->window);
- free(state);
-}
-
-static void error_exit_state(GState *state, const char *msg)
-{
- destroy_state(state);
- error_exit(msg);
-}
-
-static void error_exit(const char *msg)
-{
- SDL_Log("ERROR: %s: %s", SDL_GetError(), msg);
- SDL_Quit();
- exit(EXIT_FAILURE);
-}