Create FragmentData struct
This commit is contained in:
parent
760d9b6b9c
commit
29749c834a
@ -1,5 +1,7 @@
|
|||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
#include "shader.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
#include "vec.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#define TRIANGLE_VERTICES 3
|
#define TRIANGLE_VERTICES 3
|
||||||
@ -117,11 +119,14 @@ internal void fill_triangle(Render *render, ShaderID shader,
|
|||||||
V3f coords;
|
V3f coords;
|
||||||
f32 z;
|
f32 z;
|
||||||
f32 zbuf;
|
f32 zbuf;
|
||||||
|
f32 px, py, pz;
|
||||||
|
V3f position;
|
||||||
f32 nx, ny, nz;
|
f32 nx, ny, nz;
|
||||||
V3f normal;
|
V3f normal;
|
||||||
f32 tx_u, tx_v;
|
f32 tx_u, tx_v;
|
||||||
u64 tx_x, tx_y;
|
u64 tx_x, tx_y;
|
||||||
V2f tex_coords;
|
V2f tex_coords;
|
||||||
|
FragmentData data = {0};
|
||||||
FragmentResult result;
|
FragmentResult result;
|
||||||
|
|
||||||
f32 intensity = 1.0f;
|
f32 intensity = 1.0f;
|
||||||
@ -142,6 +147,16 @@ internal void fill_triangle(Render *render, ShaderID shader,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
px = vertices[0].x * coords.x + vertices[1].x * coords.y +
|
||||||
|
vertices[2].x * coords.z;
|
||||||
|
py = vertices[0].y * coords.x + vertices[1].y * coords.y +
|
||||||
|
vertices[2].y * coords.z;
|
||||||
|
pz = vertices[0].z * coords.x + vertices[1].z * coords.y +
|
||||||
|
vertices[2].z * coords.z;
|
||||||
|
position = (V3f){px, py, pz};
|
||||||
|
normalise_v3(position);
|
||||||
|
data.position = position;
|
||||||
|
|
||||||
nx = normals[0].x * coords.x + normals[1].x * coords.y +
|
nx = normals[0].x * coords.x + normals[1].x * coords.y +
|
||||||
normals[2].x * coords.z;
|
normals[2].x * coords.z;
|
||||||
ny = normals[0].y * coords.x + normals[1].y * coords.y +
|
ny = normals[0].y * coords.x + normals[1].y * coords.y +
|
||||||
@ -149,14 +164,16 @@ internal void fill_triangle(Render *render, ShaderID shader,
|
|||||||
nz = normals[0].z * coords.x + normals[1].z * coords.y +
|
nz = normals[0].z * coords.x + normals[1].z * coords.y +
|
||||||
normals[2].z * coords.z;
|
normals[2].z * coords.z;
|
||||||
normal = (V3f){nx, ny, nz};
|
normal = (V3f){nx, ny, nz};
|
||||||
|
data.normal = normal;
|
||||||
|
|
||||||
tx_u = coordinates[0].u * coords.x + coordinates[1].u * coords.y +
|
tx_u = coordinates[0].u * coords.x + coordinates[1].u * coords.y +
|
||||||
coordinates[2].u * coords.z;
|
coordinates[2].u * coords.z;
|
||||||
tx_v = coordinates[0].v * coords.x + coordinates[1].v * coords.y +
|
tx_v = coordinates[0].v * coords.x + coordinates[1].v * coords.y +
|
||||||
coordinates[2].v * coords.z;
|
coordinates[2].v * coords.z;
|
||||||
tex_coords = (V2f){tx_u, tx_v};
|
tex_coords = (V2f){tx_u, tx_v};
|
||||||
|
data.tex_coords = tex_coords;
|
||||||
|
|
||||||
result = run_fragment_shader(shader, normal, tex_coords, &colour, model);
|
result = run_fragment_shader(shader, &data, &colour, model);
|
||||||
if (DISCARD_FRAGMENT(result)) {
|
if (DISCARD_FRAGMENT(result)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ V3f run_vertex_shader(ShaderID shader, const V3f *vertex,
|
|||||||
return vertex_func(shader_obj, vertex, out_buf);
|
return vertex_func(shader_obj, vertex, out_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
FragmentResult run_fragment_shader(ShaderID shader, V3f normal, V2f tex_coords,
|
FragmentResult run_fragment_shader(ShaderID shader, const FragmentData *data,
|
||||||
const Colour *colour, const Model *model) {
|
const Colour *colour, const Model *model) {
|
||||||
if (IS_INVALID_SHADER(shader) || shader.id > g_repository.count || !colour) {
|
if (IS_INVALID_SHADER(shader) || shader.id > g_repository.count || !colour) {
|
||||||
return DISCARDED_FRAGMENT;
|
return DISCARDED_FRAGMENT;
|
||||||
@ -58,5 +58,5 @@ FragmentResult run_fragment_shader(ShaderID shader, V3f normal, V2f tex_coords,
|
|||||||
return DISCARDED_FRAGMENT;
|
return DISCARDED_FRAGMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fragment_func(shader_obj, normal, tex_coords, colour, model);
|
return fragment_func(shader_obj, data, colour, model);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,13 @@ struct fragment_result {
|
|||||||
bool discard;
|
bool discard;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct fragment_data FragmentData;
|
||||||
|
struct fragment_data {
|
||||||
|
V3f position;
|
||||||
|
V3f normal;
|
||||||
|
V2f tex_coords;
|
||||||
|
};
|
||||||
|
|
||||||
#define INVALID_SHADER ((ShaderID){0})
|
#define INVALID_SHADER ((ShaderID){0})
|
||||||
#define IS_INVALID_SHADER(ID) (ID.id == 0)
|
#define IS_INVALID_SHADER(ID) (ID.id == 0)
|
||||||
#define DISCARDED_FRAGMENT ((FragmentResult){.discard = true})
|
#define DISCARDED_FRAGMENT ((FragmentResult){.discard = true})
|
||||||
@ -24,7 +31,7 @@ struct fragment_result {
|
|||||||
|
|
||||||
typedef V3f(VertexShader)(void *shader, const V3f *vertex,
|
typedef V3f(VertexShader)(void *shader, const V3f *vertex,
|
||||||
const Buffer *out_buf);
|
const Buffer *out_buf);
|
||||||
typedef FragmentResult(FragmentShader)(void *shader, V3f normal, V2f tex_coords,
|
typedef FragmentResult(FragmentShader)(void *shader, const FragmentData *data,
|
||||||
const Colour *colour,
|
const Colour *colour,
|
||||||
const Model *model);
|
const Model *model);
|
||||||
|
|
||||||
@ -32,7 +39,7 @@ ShaderID create_shader(void *shader, VertexShader *vertex,
|
|||||||
FragmentShader *fragment);
|
FragmentShader *fragment);
|
||||||
V3f run_vertex_shader(ShaderID shader, const V3f *vertex,
|
V3f run_vertex_shader(ShaderID shader, const V3f *vertex,
|
||||||
const Buffer *out_buf);
|
const Buffer *out_buf);
|
||||||
FragmentResult run_fragment_shader(ShaderID shader, V3f normal, V2f tex_coords,
|
FragmentResult run_fragment_shader(ShaderID shader, const FragmentData *data,
|
||||||
const Colour *colour, const Model *model);
|
const Colour *colour, const Model *model);
|
||||||
|
|
||||||
#endif // SHADER_H
|
#endif // SHADER_H
|
||||||
|
@ -10,15 +10,15 @@ struct shader {
|
|||||||
M4x4f projection;
|
M4x4f projection;
|
||||||
};
|
};
|
||||||
|
|
||||||
internal Shader perspective = {0};
|
|
||||||
internal Shader orthographic = {0};
|
|
||||||
|
|
||||||
ShaderID perspective_phong = {0};
|
ShaderID perspective_phong = {0};
|
||||||
ShaderID perspective_albedo = {0};
|
ShaderID perspective_albedo = {0};
|
||||||
ShaderID orthographic_phong = {0};
|
ShaderID orthographic_phong = {0};
|
||||||
ShaderID orthographic_albedo = {0};
|
ShaderID orthographic_albedo = {0};
|
||||||
|
|
||||||
internal V3f g_light_dir = {0.0f, 0.0f, 1.0f};
|
internal Shader perspective = {0};
|
||||||
|
internal Shader orthographic = {0};
|
||||||
|
|
||||||
|
internal V3f g_directional_light = {0.0f, 0.0f, 1.0f};
|
||||||
internal V3f g_eye = {0.2f, 0.1f, 0.75f};
|
internal V3f g_eye = {0.2f, 0.1f, 0.75f};
|
||||||
internal V3f g_target = {0};
|
internal V3f g_target = {0};
|
||||||
internal V3f g_up = {0.0f, 1.0f, 0.0f};
|
internal V3f g_up = {0.0f, 1.0f, 0.0f};
|
||||||
@ -26,12 +26,12 @@ internal M4x4f g_cam_matrix = mat4x4_identity;
|
|||||||
|
|
||||||
internal V3f general_shader_vertex(void *shader, const V3f *vertex,
|
internal V3f general_shader_vertex(void *shader, const V3f *vertex,
|
||||||
const Buffer *out_buf);
|
const Buffer *out_buf);
|
||||||
internal FragmentResult phong_shader_fragment(void *shader, V3f normal,
|
internal FragmentResult phong_shader_fragment(void *shader,
|
||||||
V2f tex_coords,
|
const FragmentData *data,
|
||||||
const Colour *colour,
|
const Colour *colour,
|
||||||
const Model *model);
|
const Model *model);
|
||||||
internal FragmentResult albedo_shader_fragment(void *shader, V3f normal,
|
internal FragmentResult albedo_shader_fragment(void *shader,
|
||||||
V2f tex_coords,
|
const FragmentData *data,
|
||||||
const Colour *colour,
|
const Colour *colour,
|
||||||
const Model *model);
|
const Model *model);
|
||||||
internal M4x4f get_projection_matrix(ProjectionType projection_type);
|
internal M4x4f get_projection_matrix(ProjectionType projection_type);
|
||||||
@ -76,14 +76,14 @@ internal V3f general_shader_vertex(void *shader, const V3f *vertex,
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal FragmentResult phong_shader_fragment(void *shader, V3f normal,
|
internal FragmentResult phong_shader_fragment(void *shader,
|
||||||
V2f tex_coords,
|
const FragmentData *data,
|
||||||
const Colour *colour,
|
const Colour *colour,
|
||||||
const Model *model) {
|
const Model *model) {
|
||||||
f32 intensity;
|
f32 intensity;
|
||||||
if (model->normal) {
|
if (model->normal) {
|
||||||
u64 nm_x = tex_coords.u * model->normal->width;
|
u64 nm_x = data->tex_coords.u * model->normal->width;
|
||||||
u64 nm_y = (1.0f - tex_coords.v) * model->normal->height;
|
u64 nm_y = (1.0f - data->tex_coords.v) * model->normal->height;
|
||||||
|
|
||||||
Colour pixel = get_pixel(Colour, model->normal, nm_x, nm_y);
|
Colour pixel = get_pixel(Colour, model->normal, nm_x, nm_y);
|
||||||
V3f norm = {.x = pixel.r, .y = pixel.g, .z = pixel.b};
|
V3f norm = {.x = pixel.r, .y = pixel.g, .z = pixel.b};
|
||||||
@ -91,27 +91,27 @@ internal FragmentResult phong_shader_fragment(void *shader, V3f normal,
|
|||||||
|
|
||||||
intensity = get_intensity(&norm);
|
intensity = get_intensity(&norm);
|
||||||
} else {
|
} else {
|
||||||
intensity = get_intensity(&normal);
|
intensity = get_intensity(&data->normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Colour output;
|
Colour output;
|
||||||
if (model->texture) {
|
if (model->texture) {
|
||||||
u64 tx_x = tex_coords.u * model->texture->width;
|
u64 tx_x = data->tex_coords.u * model->texture->width;
|
||||||
u64 tx_y = (1.0f - tex_coords.v) * model->texture->height;
|
u64 tx_y = (1.0f - data->tex_coords.v) * model->texture->height;
|
||||||
output = get_pixel(Colour, model->texture, tx_x, tx_y);
|
output = get_pixel(Colour, model->texture, tx_x, tx_y);
|
||||||
} else {
|
} else {
|
||||||
output = *colour;
|
output = *colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
output.r *= intensity;
|
output.r = clamp(intensity * output.r, 0.0f, 255.0f);
|
||||||
output.g *= intensity;
|
output.g = clamp(intensity * output.g, 0.0f, 255.0f);
|
||||||
output.b *= intensity;
|
output.b = clamp(intensity * output.b, 0.0f, 255.0f);
|
||||||
|
|
||||||
return (FragmentResult){.colour = output};
|
return (FragmentResult){.colour = output};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal FragmentResult albedo_shader_fragment(void *shader, V3f normal,
|
internal FragmentResult albedo_shader_fragment(void *shader,
|
||||||
V2f tex_coords,
|
const FragmentData *data,
|
||||||
const Colour *colour,
|
const Colour *colour,
|
||||||
const Model *model) {
|
const Model *model) {
|
||||||
return (FragmentResult){.colour = *colour};
|
return (FragmentResult){.colour = *colour};
|
||||||
@ -131,7 +131,7 @@ internal M4x4f get_projection_matrix(ProjectionType projection_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal f32 get_intensity(const V3f *normal) {
|
internal f32 get_intensity(const V3f *normal) {
|
||||||
V3f light = g_light_dir;
|
V3f light = g_directional_light;
|
||||||
normalise_v3(light);
|
normalise_v3(light);
|
||||||
|
|
||||||
f32 intensity = dot_v3((*normal), light);
|
f32 intensity = dot_v3((*normal), light);
|
||||||
|
Loading…
Reference in New Issue
Block a user