Implement shaders #1
							
								
								
									
										55
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -1,9 +1,10 @@ | ||||
| #include "aliases.h" | ||||
| #include "img.h" | ||||
| #include "mem_arena.h" | ||||
| #include "mem_utils.h" | ||||
| #include "obj.h" | ||||
| #include "vec.h" | ||||
| #include "shader.h" | ||||
| #include "shaders.h" | ||||
| #include <stdbool.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| @@ -12,10 +13,12 @@ | ||||
| #define SIZE 1200 | ||||
| #define RESOURCE(NAME) "resources/" NAME | ||||
|  | ||||
| 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; | ||||
| extern ShaderID perspective_lit_textured_id; | ||||
| extern ShaderID perspective_lit_coloured_id; | ||||
| extern ShaderID perspective_albedo_id; | ||||
| extern ShaderID orthographic_lit_textured_id; | ||||
| extern ShaderID orthographic_lit_coloured_id; | ||||
| extern ShaderID orthographic_albedo_id; | ||||
|  | ||||
| enum { | ||||
|   TINY_EXIT_SUCCESS, | ||||
| @@ -24,10 +27,6 @@ enum { | ||||
|   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) { | ||||
|   Arena *arena = NULL; | ||||
|   if (!wapp_mem_arena_init(&arena, 10ul * 1024ul * 1024ul * 1024ul, | ||||
| @@ -49,44 +48,14 @@ int main(void) { | ||||
|     return TINY_EXIT_MODEL_LOAD_FAILED; | ||||
|   } | ||||
|  | ||||
|   M4x4f model_view = lookat(g_eye, g_target, g_up); | ||||
|   M4x4f perspective_projection = | ||||
|       get_projection_matrix(PROJECTION_TYPE_PERSPECTIVE); | ||||
|  | ||||
|   Shader main_shader = { | ||||
|       .vertex = main_shader_vertex, | ||||
|       .model_view = &model_view, | ||||
|       .projection = &perspective_projection, | ||||
|   }; | ||||
|   load_shaders(); | ||||
|  | ||||
|   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"); | ||||
|  | ||||
|   wapp_mem_arena_destroy(&arena); | ||||
|  | ||||
|   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