Create shaders
This commit is contained in:
parent
891a97739f
commit
ff207a458e
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
|
Loading…
Reference in New Issue
Block a user