Compare commits
	
		
			5 Commits
		
	
	
		
			c5cc8643e1
			...
			2ec654774e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2ec654774e | |||
| 6b0732980a | |||
| 36913bf365 | |||
| 25ff01b815 | |||
| f0b6771255 | 
							
								
								
									
										3
									
								
								compile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								compile
									
									
									
									
									
								
							@@ -2,9 +2,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
CC=clang
 | 
					CC=clang
 | 
				
			||||||
CFLAGS="-g -Wall -Werror -pedantic -Iinclude $(pkg-config --cflags sdl2)"
 | 
					CFLAGS="-g -Wall -Werror -pedantic -Iinclude $(pkg-config --cflags sdl2)"
 | 
				
			||||||
LIBS="$(pkg-config --libs sdl2)"
 | 
					LIBS="$(pkg-config --libs sdl2) -lm"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RAYTRACER_SRC="src/window/*.c \
 | 
					RAYTRACER_SRC="src/window/*.c \
 | 
				
			||||||
 | 
						src/vector/*.c \
 | 
				
			||||||
	src/raytracer/*.c \
 | 
						src/raytracer/*.c \
 | 
				
			||||||
"
 | 
					"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										53
									
								
								include/vector/vec.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								include/vector/vec.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					#ifndef VEC_H
 | 
				
			||||||
 | 
					#define VEC_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "c_cpp_aliases/aliases.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  i32 x;
 | 
				
			||||||
 | 
					  i32 y;
 | 
				
			||||||
 | 
					} vec2i_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  f32 x;
 | 
				
			||||||
 | 
					  f32 y;
 | 
				
			||||||
 | 
					} vec2f_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  i32 x;
 | 
				
			||||||
 | 
					  i32 y;
 | 
				
			||||||
 | 
					  i32 z;
 | 
				
			||||||
 | 
					} vec3i_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  f32 x;
 | 
				
			||||||
 | 
					  f32 y;
 | 
				
			||||||
 | 
					  f32 z;
 | 
				
			||||||
 | 
					} vec3f_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define vec_add(T, v1, v2) vec_add_##T(v1, v2)
 | 
				
			||||||
 | 
					#define vec_sub(T, v1, v2) vec_sub_##T(v1, v2)
 | 
				
			||||||
 | 
					#define vec_mul(T, v1, v2) vec_mul_##T(v1, v2)
 | 
				
			||||||
 | 
					#define vec_dot(T, v1, v2) vec_dot_##T(v1, v2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec2i_t vec_add_vec2i_t(vec2i_t v1, vec2i_t v2);
 | 
				
			||||||
 | 
					vec2i_t vec_sub_vec2i_t(vec2i_t v1, vec2i_t v2);
 | 
				
			||||||
 | 
					vec2i_t vec_mul_vec2i_t(vec2i_t v1, vec2i_t v2);
 | 
				
			||||||
 | 
					i32 vec_dot_vec2i_t(vec2i_t v1, vec2i_t v2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec2f_t vec_add_vec2f_t(vec2f_t v1, vec2f_t v2);
 | 
				
			||||||
 | 
					vec2f_t vec_sub_vec2f_t(vec2f_t v1, vec2f_t v2);
 | 
				
			||||||
 | 
					vec2f_t vec_mul_vec2f_t(vec2f_t v1, vec2f_t v2);
 | 
				
			||||||
 | 
					f32 vec_dot_vec2f_t(vec2f_t v1, vec2f_t v2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3i_t vec_add_vec3i_t(vec3i_t v1, vec3i_t v2);
 | 
				
			||||||
 | 
					vec3i_t vec_sub_vec3i_t(vec3i_t v1, vec3i_t v2);
 | 
				
			||||||
 | 
					vec3i_t vec_mul_vec3i_t(vec3i_t v1, vec3i_t v2);
 | 
				
			||||||
 | 
					i32 vec_dot_vec3i_t(vec3i_t v1, vec3i_t v2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3f_t vec_add_vec3f_t(vec3f_t v1, vec3f_t v2);
 | 
				
			||||||
 | 
					vec3f_t vec_sub_vec3f_t(vec3f_t v1, vec3f_t v2);
 | 
				
			||||||
 | 
					vec3f_t vec_mul_vec3f_t(vec3f_t v1, vec3f_t v2);
 | 
				
			||||||
 | 
					f32 vec_dot_vec3f_t(vec3f_t v1, vec3f_t v2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // !VEC_H
 | 
				
			||||||
@@ -2,6 +2,7 @@
 | 
				
			|||||||
#define WINDOW_H
 | 
					#define WINDOW_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "c_cpp_aliases/aliases.h"
 | 
					#include "c_cpp_aliases/aliases.h"
 | 
				
			||||||
 | 
					#include "vector/vec.h"
 | 
				
			||||||
#include <SDL2/SDL_video.h>
 | 
					#include <SDL2/SDL_video.h>
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,4 +31,6 @@ void clear_window(window_t *wnd, colour_t colour);
 | 
				
			|||||||
void set_pixel(window_t *wnd, i32 x, i32 y, colour_t colour);
 | 
					void set_pixel(window_t *wnd, i32 x, i32 y, colour_t colour);
 | 
				
			||||||
void swap_buffers(window_t *wnd);
 | 
					void swap_buffers(window_t *wnd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3f_t window_to_viewport(window_t *wnd, i32 x, i32 y, vec3f_t viewport);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // !WINDOW_H
 | 
					#endif // !WINDOW_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,22 +1,77 @@
 | 
				
			|||||||
#include "SDL_events.h"
 | 
					#include "SDL_events.h"
 | 
				
			||||||
#include "c_cpp_aliases/aliases.h"
 | 
					#include "c_cpp_aliases/aliases.h"
 | 
				
			||||||
 | 
					#include "vector/vec.h"
 | 
				
			||||||
#include "window/window.h"
 | 
					#include "window/window.h"
 | 
				
			||||||
 | 
					#include <math.h>
 | 
				
			||||||
#include <stdbool.h>
 | 
					#include <stdbool.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ARR_LEN(ARR) sizeof(ARR) / sizeof(ARR[0])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  f32 radius;
 | 
				
			||||||
 | 
					  vec3f_t centre;
 | 
				
			||||||
 | 
					  colour_t colour;
 | 
				
			||||||
 | 
					} sphere_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  sphere_t *spheres;
 | 
				
			||||||
 | 
					  u32 count;
 | 
				
			||||||
 | 
					} scene_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					  f32 t1;
 | 
				
			||||||
 | 
					  f32 t2;
 | 
				
			||||||
 | 
					} solutions_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					solutions_t ray_intersects_sphere(vec3f_t origin, vec3f_t direction,
 | 
				
			||||||
 | 
					                                  sphere_t sphere);
 | 
				
			||||||
 | 
					colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
 | 
				
			||||||
 | 
					                   const scene_t *scene, colour_t default_colour);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char *argv[]) {
 | 
					int main(int argc, char *argv[]) {
 | 
				
			||||||
  colour_t bg = (colour_t){.r = 128, .g = 128, .b = 128, .a = 255};
 | 
					  colour_t bg = (colour_t){.r = 27, .g = 38, .b = 79, .a = 255};
 | 
				
			||||||
 | 
					  vec3f_t camera = {.x = 0.0f, .y = 0.0f, .z = 0.0f};
 | 
				
			||||||
 | 
					  vec3f_t viewport = {.x = 1.0f, .y = 1.0f, .z = 1.0f};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  window_t window = {0};
 | 
					  window_t window = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (!init_window(&window, 1000, 800, "CG From Scratch")) {
 | 
					  if (!init_window(&window, 800, 800, "CG From Scratch")) {
 | 
				
			||||||
    return EXIT_FAILURE;
 | 
					    return EXIT_FAILURE;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool running = true;
 | 
					  bool running = true;
 | 
				
			||||||
  SDL_Event event = {0};
 | 
					  SDL_Event event = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sphere_t spheres[] = {
 | 
				
			||||||
 | 
					      (sphere_t){
 | 
				
			||||||
 | 
					          .radius = 1.0f,
 | 
				
			||||||
 | 
					          .centre = (vec3f_t){.x = 0.0f, .y = -1.0f, .z = 3.0f},
 | 
				
			||||||
 | 
					          .colour = (colour_t){.r = 245, .g = 238, .b = 158, .a = 255},
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      (sphere_t){
 | 
				
			||||||
 | 
					          .radius = 1.0f,
 | 
				
			||||||
 | 
					          .centre = (vec3f_t){.x = -2.0f, .y = 0.0f, .z = 4.0f},
 | 
				
			||||||
 | 
					          .colour = (colour_t){.r = 59, .g = 142, .b = 165, .a = 255},
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      (sphere_t){
 | 
				
			||||||
 | 
					          .radius = 1.0f,
 | 
				
			||||||
 | 
					          .centre = (vec3f_t){.x = 2.0f, .y = 0.0f, .z = 4.0f},
 | 
				
			||||||
 | 
					          .colour = (colour_t){.r = 171, .g = 52, .b = 40, .a = 255},
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  scene_t scene = {
 | 
				
			||||||
 | 
					      .spheres = spheres,
 | 
				
			||||||
 | 
					      .count = ARR_LEN(spheres),
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  i32 w_min = ((i32)window.half_width) * -1;
 | 
				
			||||||
 | 
					  i32 w_max = (i32)window.half_width;
 | 
				
			||||||
 | 
					  i32 h_min = ((i32)window.half_height) * -1;
 | 
				
			||||||
 | 
					  i32 h_max = (i32)window.half_height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while (running) {
 | 
					  while (running) {
 | 
				
			||||||
    while (SDL_PollEvent(&event)) {
 | 
					    while (SDL_PollEvent(&event)) {
 | 
				
			||||||
      switch (event.type) {
 | 
					      switch (event.type) {
 | 
				
			||||||
@@ -28,6 +83,14 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    clear_window(&window, bg);
 | 
					    clear_window(&window, bg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i32 y = h_min; y < h_max; ++y) {
 | 
				
			||||||
 | 
					      for (i32 x = w_min; x < w_max; ++x) {
 | 
				
			||||||
 | 
					        vec3f_t direction = window_to_viewport(&window, x, y, viewport);
 | 
				
			||||||
 | 
					        colour_t colour = trace_ray(camera, direction, 1, INFINITY, &scene, bg);
 | 
				
			||||||
 | 
					        set_pixel(&window, x, y, colour);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    swap_buffers(&window);
 | 
					    swap_buffers(&window);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,3 +98,52 @@ int main(int argc, char *argv[]) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  return EXIT_SUCCESS;
 | 
					  return EXIT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					solutions_t ray_intersects_sphere(vec3f_t origin, vec3f_t direction,
 | 
				
			||||||
 | 
					                                  sphere_t sphere) {
 | 
				
			||||||
 | 
					  f32 r = sphere.radius;
 | 
				
			||||||
 | 
					  vec3f_t CO = vec_sub(vec3f_t, origin, sphere.centre);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  f32 a = vec_dot(vec3f_t, direction, direction);
 | 
				
			||||||
 | 
					  f32 b = 2.0f * vec_dot(vec3f_t, CO, direction);
 | 
				
			||||||
 | 
					  f32 c = vec_dot(vec3f_t, CO, CO) - r * r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  f32 discriminant = b * b - 4 * a * c;
 | 
				
			||||||
 | 
					  if (discriminant < 0) {
 | 
				
			||||||
 | 
					    return (solutions_t){INFINITY, INFINITY};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  f32 t1 = (-b + sqrtf(discriminant)) / (2 * a);
 | 
				
			||||||
 | 
					  f32 t2 = (-b - sqrtf(discriminant)) / (2 * a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (solutions_t){t1, t2};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					colour_t trace_ray(vec3f_t origin, vec3f_t direction, f32 t_min, f32 t_max,
 | 
				
			||||||
 | 
					                   const scene_t *scene, colour_t default_colour) {
 | 
				
			||||||
 | 
					  f32 closest_t = INFINITY;
 | 
				
			||||||
 | 
					  sphere_t *closest_sphere = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (u32 i = 0; i < scene->count; ++i) {
 | 
				
			||||||
 | 
					    solutions_t solutions =
 | 
				
			||||||
 | 
					        ray_intersects_sphere(origin, direction, scene->spheres[i]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (solutions.t1 >= t_min && solutions.t1 <= t_max &&
 | 
				
			||||||
 | 
					        solutions.t1 < closest_t) {
 | 
				
			||||||
 | 
					      closest_t = solutions.t1;
 | 
				
			||||||
 | 
					      closest_sphere = &(scene->spheres[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (solutions.t2 >= t_min && solutions.t2 <= t_max &&
 | 
				
			||||||
 | 
					        solutions.t2 < closest_t) {
 | 
				
			||||||
 | 
					      closest_t = solutions.t2;
 | 
				
			||||||
 | 
					      closest_sphere = &(scene->spheres[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!closest_sphere) {
 | 
				
			||||||
 | 
					    return default_colour;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return closest_sphere->colour;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										65
									
								
								src/vector/vec.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								src/vector/vec.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					#include "vector/vec.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec2i_t vec_add_vec2i_t(vec2i_t v1, vec2i_t v2) {
 | 
				
			||||||
 | 
					  return (vec2i_t){.x = v1.x + v2.x, .y = v1.y + v2.y};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec2i_t vec_sub_vec2i_t(vec2i_t v1, vec2i_t v2) {
 | 
				
			||||||
 | 
					  return (vec2i_t){.x = v1.x - v2.x, .y = v1.y - v2.y};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec2i_t vec_mul_vec2i_t(vec2i_t v1, vec2i_t v2) {
 | 
				
			||||||
 | 
					  return (vec2i_t){.x = v1.x * v2.x, .y = v1.y * v2.y};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i32 vec_dot_vec2i_t(vec2i_t v1, vec2i_t v2) {
 | 
				
			||||||
 | 
					  return v1.x * v2.x + v1.y * v2.y;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec2f_t vec_add_vec2f_t(vec2f_t v1, vec2f_t v2) {
 | 
				
			||||||
 | 
					  return (vec2f_t){.x = v1.x + v2.x, .y = v1.y + v2.y};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec2f_t vec_sub_vec2f_t(vec2f_t v1, vec2f_t v2) {
 | 
				
			||||||
 | 
					  return (vec2f_t){.x = v1.x - v2.x, .y = v1.y - v2.y};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec2f_t vec_mul_vec2f_t(vec2f_t v1, vec2f_t v2) {
 | 
				
			||||||
 | 
					  return (vec2f_t){.x = v1.x * v2.x, .y = v1.y * v2.y};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					f32 vec_dot_vec2f_t(vec2f_t v1, vec2f_t v2) {
 | 
				
			||||||
 | 
					  return v1.x * v2.x + v1.y * v2.y;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3i_t vec_add_vec3i_t(vec3i_t v1, vec3i_t v2) {
 | 
				
			||||||
 | 
					  return (vec3i_t){.x = v1.x + v2.x, .y = v1.y + v2.y, .z = v1.z + v2.z};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3i_t vec_sub_vec3i_t(vec3i_t v1, vec3i_t v2) {
 | 
				
			||||||
 | 
					  return (vec3i_t){.x = v1.x - v2.x, .y = v1.y - v2.y, .z = v1.z - v2.z};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3i_t vec_mul_vec3i_t(vec3i_t v1, vec3i_t v2) {
 | 
				
			||||||
 | 
					  return (vec3i_t){.x = v1.x * v2.x, .y = v1.y * v2.y, .z = v1.z * v2.z};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					i32 vec_dot_vec3i_t(vec3i_t v1, vec3i_t v2) {
 | 
				
			||||||
 | 
					  return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3f_t vec_add_vec3f_t(vec3f_t v1, vec3f_t v2) {
 | 
				
			||||||
 | 
					  return (vec3f_t){.x = v1.x + v2.x, .y = v1.y + v2.y, .z = v1.z + v2.z};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3f_t vec_sub_vec3f_t(vec3f_t v1, vec3f_t v2) {
 | 
				
			||||||
 | 
					  return (vec3f_t){.x = v1.x - v2.x, .y = v1.y - v2.y, .z = v1.z - v2.z};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3f_t vec_mul_vec3f_t(vec3f_t v1, vec3f_t v2) {
 | 
				
			||||||
 | 
					  return (vec3f_t){.x = v1.x * v2.x, .y = v1.y * v2.y, .z = v1.z * v2.z};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					f32 vec_dot_vec3f_t(vec3f_t v1, vec3f_t v2) {
 | 
				
			||||||
 | 
					  return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
#include "window/window.h"
 | 
					#include "window/window.h"
 | 
				
			||||||
#include "c_cpp_aliases/aliases.h"
 | 
					#include "c_cpp_aliases/aliases.h"
 | 
				
			||||||
 | 
					#include "vector/vec.h"
 | 
				
			||||||
#include <SDL2/SDL.h>
 | 
					#include <SDL2/SDL.h>
 | 
				
			||||||
#include <SDL2/SDL_error.h>
 | 
					#include <SDL2/SDL_error.h>
 | 
				
			||||||
#include <SDL2/SDL_pixels.h>
 | 
					#include <SDL2/SDL_pixels.h>
 | 
				
			||||||
@@ -10,6 +11,7 @@
 | 
				
			|||||||
u32 colour_to_u32(colour_t colour);
 | 
					u32 colour_to_u32(colour_t colour);
 | 
				
			||||||
u32 index_from_coordinates(window_t *wnd, u32 x, u32 y);
 | 
					u32 index_from_coordinates(window_t *wnd, u32 x, u32 y);
 | 
				
			||||||
i32 denormalise(i32 value, u32 max, u32 abs_half);
 | 
					i32 denormalise(i32 value, u32 max, u32 abs_half);
 | 
				
			||||||
 | 
					vec2i_t denormalised_coords(const window_t *wnd, i32 x, i32 y);
 | 
				
			||||||
void set_screen_pixel(window_t *wnd, u32 x, u32 y, colour_t colour);
 | 
					void set_screen_pixel(window_t *wnd, u32 x, u32 y, colour_t colour);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool init_window(window_t *wnd, u32 width, u32 height, const char *title) {
 | 
					bool init_window(window_t *wnd, u32 width, u32 height, const char *title) {
 | 
				
			||||||
@@ -103,16 +105,15 @@ void clear_window(window_t *wnd, colour_t colour) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void set_pixel(window_t *wnd, i32 x, i32 y, colour_t colour) {
 | 
					void set_pixel(window_t *wnd, i32 x, i32 y, colour_t colour) {
 | 
				
			||||||
  i32 screen_x = denormalise(x, wnd->width, wnd->half_width);
 | 
					  vec2i_t coords = denormalised_coords(wnd, x, y);
 | 
				
			||||||
  i32 screen_y = denormalise(-y, wnd->height, wnd->half_height);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (screen_x < 0 || screen_y < 0) {
 | 
					  if (coords.x < 0 || coords.y < 0) {
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SDL_LockSurface(wnd->back_buffer);
 | 
					  SDL_LockSurface(wnd->back_buffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  set_screen_pixel(wnd, (u32)screen_x, (u32)screen_y, colour);
 | 
					  set_screen_pixel(wnd, (u32)(coords.x), (u32)(coords.y), colour);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  SDL_UnlockSurface(wnd->back_buffer);
 | 
					  SDL_UnlockSurface(wnd->back_buffer);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -150,6 +151,13 @@ i32 denormalise(i32 value, u32 max, u32 abs_half) {
 | 
				
			|||||||
  return denormalised;
 | 
					  return denormalised;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec2i_t denormalised_coords(const window_t *wnd, i32 x, i32 y) {
 | 
				
			||||||
 | 
					  i32 screen_x = denormalise(x, wnd->width, wnd->half_width);
 | 
				
			||||||
 | 
					  i32 screen_y = denormalise(-y, wnd->height, wnd->half_height);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (vec2i_t){.x = screen_x, .y = screen_y};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void set_screen_pixel(window_t *wnd, u32 x, u32 y, colour_t colour) {
 | 
					void set_screen_pixel(window_t *wnd, u32 x, u32 y, colour_t colour) {
 | 
				
			||||||
  u32 index = index_from_coordinates(wnd, x, y);
 | 
					  u32 index = index_from_coordinates(wnd, x, y);
 | 
				
			||||||
  u32 c = colour_to_u32(colour);
 | 
					  u32 c = colour_to_u32(colour);
 | 
				
			||||||
@@ -158,3 +166,11 @@ void set_screen_pixel(window_t *wnd, u32 x, u32 y, colour_t colour) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  pixels[index] = c;
 | 
					  pixels[index] = c;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					vec3f_t window_to_viewport(window_t *wnd, i32 x, i32 y, vec3f_t viewport) {
 | 
				
			||||||
 | 
					  return (vec3f_t){
 | 
				
			||||||
 | 
					      .x = x * viewport.x / wnd->width,
 | 
				
			||||||
 | 
					      .y = y * viewport.y / wnd->height,
 | 
				
			||||||
 | 
					      .z = viewport.z,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user