Implement shaders #1
							
								
								
									
										55
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -1,9 +1,10 @@ | |||||||
| #include "aliases.h" |  | ||||||
| #include "img.h" | #include "img.h" | ||||||
| #include "mem_arena.h" | #include "mem_arena.h" | ||||||
| #include "mem_utils.h" | #include "mem_utils.h" | ||||||
| #include "obj.h" | #include "obj.h" | ||||||
| #include "vec.h" | #include "shader.h" | ||||||
|  | #include "shaders.h" | ||||||
|  | #include <stdbool.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| @@ -12,10 +13,12 @@ | |||||||
| #define SIZE 1200 | #define SIZE 1200 | ||||||
| #define RESOURCE(NAME) "resources/" NAME | #define RESOURCE(NAME) "resources/" NAME | ||||||
|  |  | ||||||
| V3f g_eye = {0.2f, 0.1f, 0.75f}; | extern ShaderID perspective_lit_textured_id; | ||||||
| V3f g_target = {0}; | extern ShaderID perspective_lit_coloured_id; | ||||||
| V3f g_up = {0.0f, 1.0f, 0.0f}; | extern ShaderID perspective_albedo_id; | ||||||
| M4x4f g_cam_matrix = mat4x4_identity; | extern ShaderID orthographic_lit_textured_id; | ||||||
|  | extern ShaderID orthographic_lit_coloured_id; | ||||||
|  | extern ShaderID orthographic_albedo_id; | ||||||
|  |  | ||||||
| enum { | enum { | ||||||
|   TINY_EXIT_SUCCESS, |   TINY_EXIT_SUCCESS, | ||||||
| @@ -24,10 +27,6 @@ enum { | |||||||
|   TINY_EXIT_MODEL_LOAD_FAILED, |   TINY_EXIT_MODEL_LOAD_FAILED, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| internal M4x4f get_projection_matrix(ProjectionType projection_type); |  | ||||||
| internal V3f main_shader_vertex(const V3f *vertex, M4x4f *model_view, |  | ||||||
|                                 M4x4f *projection, const Image *img); |  | ||||||
|  |  | ||||||
| int main(void) { | int main(void) { | ||||||
|   Arena *arena = NULL; |   Arena *arena = NULL; | ||||||
|   if (!wapp_mem_arena_init(&arena, 10ul * 1024ul * 1024ul * 1024ul, |   if (!wapp_mem_arena_init(&arena, 10ul * 1024ul * 1024ul * 1024ul, | ||||||
| @@ -49,44 +48,14 @@ int main(void) { | |||||||
|     return TINY_EXIT_MODEL_LOAD_FAILED; |     return TINY_EXIT_MODEL_LOAD_FAILED; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   M4x4f model_view = lookat(g_eye, g_target, g_up); |   load_shaders(); | ||||||
|   M4x4f perspective_projection = |  | ||||||
|       get_projection_matrix(PROJECTION_TYPE_PERSPECTIVE); |  | ||||||
|  |  | ||||||
|   Shader main_shader = { |  | ||||||
|       .vertex = main_shader_vertex, |  | ||||||
|       .model_view = &model_view, |  | ||||||
|       .projection = &perspective_projection, |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   clear_buffer(&(render.img), &bg); |   clear_buffer(&(render.img), &bg); | ||||||
|   render_model(&obj, &render, &main_shader, RENDER_TYPE_SHADED, teal); |   render_model(&obj, &render, perspective_lit_textured_id, RENDER_TYPE_SHADED, | ||||||
|  |                teal); | ||||||
|   save_image(&(render.img), "result.pam"); |   save_image(&(render.img), "result.pam"); | ||||||
|  |  | ||||||
|   wapp_mem_arena_destroy(&arena); |   wapp_mem_arena_destroy(&arena); | ||||||
|  |  | ||||||
|   return TINY_EXIT_SUCCESS; |   return TINY_EXIT_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
| internal M4x4f get_projection_matrix(ProjectionType projection_type) { |  | ||||||
|   if (projection_type == PROJECTION_TYPE_PERSPECTIVE) { |  | ||||||
|     // Calculate projection matrix |  | ||||||
|     V3f cam = V3(V3f, f32, g_target.x, g_target.y, g_target.z, g_eye.x, g_eye.y, |  | ||||||
|                  g_eye.z); |  | ||||||
|     normalise_v3(cam); |  | ||||||
|     f32 coeff = -1.0f / magnitude_v3(cam) * 0.5f; |  | ||||||
|     return projection(coeff); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return mat4x4_identity; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| internal V3f main_shader_vertex(const V3f *vertex, M4x4f *model_view, |  | ||||||
|                                 M4x4f *projection, const Image *img) { |  | ||||||
|   V4f vh = {.x = vertex->x, .y = vertex->y, .z = vertex->z, .w = 1.0f}; |  | ||||||
|   vh = mat4x4_mul_vec4((*projection), mat4x4_mul_vec4((*model_view), vh)); |  | ||||||
|   vh.y = 0.0 - vh.y; |  | ||||||
|   vh = mat4x4_mul_vec4(viewport(vh.x, vh.y, img->width, img->height), vh); |  | ||||||
|  |  | ||||||
|   return project_vec4(vh); |  | ||||||
| } |  | ||||||
|   | |||||||
							
								
								
									
										148
									
								
								src/shaders.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								src/shaders.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | |||||||
|  | #include "img.h" | ||||||
|  | #include "obj.h" | ||||||
|  | #include "shader.h" | ||||||
|  | #include "utils.h" | ||||||
|  | #include "vec.h" | ||||||
|  |  | ||||||
|  | typedef struct shader Shader; | ||||||
|  | struct shader { | ||||||
|  |   M4x4f model_view; | ||||||
|  |   M4x4f projection; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | Shader perspective = {0}; | ||||||
|  | Shader orthographic = {0}; | ||||||
|  |  | ||||||
|  | ShaderID perspective_lit_textured_id = {0}; | ||||||
|  | ShaderID perspective_lit_coloured_id = {0}; | ||||||
|  | ShaderID perspective_albedo_id = {0}; | ||||||
|  | ShaderID orthographic_lit_textured_id = {0}; | ||||||
|  | ShaderID orthographic_lit_coloured_id = {0}; | ||||||
|  | ShaderID orthographic_albedo_id = {0}; | ||||||
|  |  | ||||||
|  | V3f g_light_dir = {0.0f, 0.0f, 1.0f}; | ||||||
|  | V3f g_eye = {0.2f, 0.1f, 0.75f}; | ||||||
|  | V3f g_target = {0}; | ||||||
|  | V3f g_up = {0.0f, 1.0f, 0.0f}; | ||||||
|  | M4x4f g_cam_matrix = mat4x4_identity; | ||||||
|  |  | ||||||
|  | internal V3f general_shader_vertex(void *shader, const V3f *vertex, | ||||||
|  |                                    const Buffer *out_buf); | ||||||
|  | internal FragmentResult lit_textured_shader_fragment(void *shader, V3f normal, | ||||||
|  |                                                      V2f tex_coords, | ||||||
|  |                                                      const Colour *colour, | ||||||
|  |                                                      const Image *texture); | ||||||
|  | internal FragmentResult lit_coloured_shader_fragment(void *shader, V3f normal, | ||||||
|  |                                                      V2f tex_coords, | ||||||
|  |                                                      const Colour *colour, | ||||||
|  |                                                      const Image *texture); | ||||||
|  | internal FragmentResult albedo_shader_fragment(void *shader, V3f normal, | ||||||
|  |                                                V2f tex_coords, | ||||||
|  |                                                const Colour *colour, | ||||||
|  |                                                const Image *texture); | ||||||
|  | internal M4x4f get_projection_matrix(ProjectionType projection_type); | ||||||
|  | internal f32 get_intensity(const V3f *normal); | ||||||
|  |  | ||||||
|  | void load_shaders(void) { | ||||||
|  |   M4x4f model_view = lookat(g_eye, g_target, g_up); | ||||||
|  |   M4x4f orthographic_projection = | ||||||
|  |       get_projection_matrix(PROJECTION_TYPE_ORTHOGRAPHIC); | ||||||
|  |   M4x4f perspective_projection = | ||||||
|  |       get_projection_matrix(PROJECTION_TYPE_PERSPECTIVE); | ||||||
|  |  | ||||||
|  |   perspective.model_view = orthographic.model_view = model_view; | ||||||
|  |   perspective.projection = perspective_projection; | ||||||
|  |   orthographic.projection = orthographic_projection; | ||||||
|  |  | ||||||
|  |   perspective_lit_textured_id = create_shader( | ||||||
|  |       &perspective, general_shader_vertex, lit_textured_shader_fragment); | ||||||
|  |   perspective_lit_coloured_id = create_shader( | ||||||
|  |       &perspective, general_shader_vertex, lit_coloured_shader_fragment); | ||||||
|  |   perspective_albedo_id = create_shader(&perspective, general_shader_vertex, | ||||||
|  |                                         albedo_shader_fragment); | ||||||
|  |   orthographic_lit_textured_id = create_shader( | ||||||
|  |       &orthographic, general_shader_vertex, lit_textured_shader_fragment); | ||||||
|  |   orthographic_lit_coloured_id = create_shader( | ||||||
|  |       &orthographic, general_shader_vertex, lit_coloured_shader_fragment); | ||||||
|  |   orthographic_albedo_id = create_shader(&orthographic, general_shader_vertex, | ||||||
|  |                                          albedo_shader_fragment); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | internal V3f general_shader_vertex(void *shader, const V3f *vertex, | ||||||
|  |                                    const Buffer *out_buf) { | ||||||
|  |   Shader *shader_ptr = (Shader *)shader; | ||||||
|  |  | ||||||
|  |   V4f vh = {.x = vertex->x, .y = vertex->y, .z = vertex->z, .w = 1.0f}; | ||||||
|  |   vh = mat4x4_mul_vec4(shader_ptr->projection, | ||||||
|  |                        mat4x4_mul_vec4(shader_ptr->model_view, vh)); | ||||||
|  |   vh.y = 0.0 - vh.y; | ||||||
|  |   vh = mat4x4_mul_vec4(viewport(vh.x, vh.y, out_buf->width, out_buf->height), | ||||||
|  |                        vh); | ||||||
|  |  | ||||||
|  |   return project_vec4(vh); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | internal FragmentResult lit_textured_shader_fragment(void *shader, V3f normal, | ||||||
|  |                                                      V2f tex_coords, | ||||||
|  |                                                      const Colour *colour, | ||||||
|  |                                                      const Image *texture) { | ||||||
|  |   if (!texture) { | ||||||
|  |     return DISCARDED_FRAGMENT; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   f32 intensity = get_intensity(&normal); | ||||||
|  |  | ||||||
|  |   u64 tx_x = tex_coords.u * texture->width; | ||||||
|  |   u64 tx_y = (1.0f - tex_coords.v) * texture->height; | ||||||
|  |  | ||||||
|  |   Colour output = get_pixel(Colour, texture, tx_x, tx_y); | ||||||
|  |  | ||||||
|  |   output.r *= intensity; | ||||||
|  |   output.g *= intensity; | ||||||
|  |   output.b *= intensity; | ||||||
|  |  | ||||||
|  |   return (FragmentResult){.colour = output}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | internal FragmentResult lit_coloured_shader_fragment(void *shader, V3f normal, | ||||||
|  |                                                      V2f tex_coords, | ||||||
|  |                                                      const Colour *colour, | ||||||
|  |                                                      const Image *texture) { | ||||||
|  |   f32 intensity = get_intensity(&normal); | ||||||
|  |   Colour output = *colour; | ||||||
|  |  | ||||||
|  |   output.r *= intensity; | ||||||
|  |   output.g *= intensity; | ||||||
|  |   output.b *= intensity; | ||||||
|  |  | ||||||
|  |   return (FragmentResult){.colour = output}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | internal FragmentResult albedo_shader_fragment(void *shader, V3f normal, | ||||||
|  |                                                V2f tex_coords, | ||||||
|  |                                                const Colour *colour, | ||||||
|  |                                                const Image *texture) { | ||||||
|  |   return (FragmentResult){.colour = *colour}; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | internal M4x4f get_projection_matrix(ProjectionType projection_type) { | ||||||
|  |   if (projection_type == PROJECTION_TYPE_PERSPECTIVE) { | ||||||
|  |     // Calculate projection matrix | ||||||
|  |     V3f cam = V3(V3f, f32, g_target.x, g_target.y, g_target.z, g_eye.x, g_eye.y, | ||||||
|  |                  g_eye.z); | ||||||
|  |     normalise_v3(cam); | ||||||
|  |     f32 coeff = -1.0f / magnitude_v3(cam) * 0.5f; | ||||||
|  |     return projection(coeff); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return mat4x4_identity; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | internal f32 get_intensity(const V3f *normal) { | ||||||
|  |   f32 intensity = dot_v3((*normal), g_light_dir); | ||||||
|  |   if (intensity < 0.0f) { | ||||||
|  |     intensity = 0.01f; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return intensity; | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								src/shaders.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/shaders.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | #ifndef SHADERS_H | ||||||
|  | #define SHADERS_H | ||||||
|  |  | ||||||
|  | void load_shaders(void); | ||||||
|  |  | ||||||
|  | #endif // SHADERS_H | ||||||
		Reference in New Issue
	
	Block a user