summaryrefslogtreecommitdiff
path: root/src/renderer/render.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer/render.c')
-rw-r--r--src/renderer/render.c134
1 files changed, 108 insertions, 26 deletions
diff --git a/src/renderer/render.c b/src/renderer/render.c
index 806979d..e420043 100644
--- a/src/renderer/render.c
+++ b/src/renderer/render.c
@@ -1,3 +1,7 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include "maths_types.h"
#include "mem.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
@@ -59,6 +63,9 @@ bool renderer_init(renderer* ren) {
ren->blinn_phong =
shader_create_separate("assets/shaders/blinn_phong.vert", "assets/shaders/blinn_phong.frag");
+ ren->skinned =
+ shader_create_separate("assets/shaders/skinned.vert", "assets/shaders/blinn_phong.frag");
+
default_material_init();
return true;
@@ -158,6 +165,59 @@ void draw_mesh(renderer* ren, mesh* mesh, transform tf, material* mat, mat4* vie
draw_primitives(CEL_PRIMITIVE_TOPOLOGY_TRIANGLE, 0, num_vertices);
}
+void draw_skinned_mesh(renderer* ren, mesh* mesh, transform tf, material* mat, mat4* view,
+ mat4* proj) {
+ shader lighting_shader = ren->skinned;
+
+ // bind buffer
+ bind_mesh_vertex_buffer(ren->backend_state, mesh);
+
+ // bind textures
+ bind_texture(lighting_shader, &mat->diffuse_texture, 0); // bind to slot 0
+ bind_texture(lighting_shader, &mat->specular_texture, 1); // bind to slot 1
+ uniform_f32(lighting_shader.program_id, "material.shininess", 32.);
+
+ // upload model transform
+ mat4 trans = mat4_translation(tf.position);
+ mat4 rot = mat4_rotation(tf.rotation);
+ mat4 scale = mat4_scale(tf.scale);
+ mat4 model_tf = mat4_mult(trans, mat4_mult(rot, scale));
+
+ uniform_mat4f(lighting_shader.program_id, "model", &model_tf);
+ // upload view & projection matrices
+ uniform_mat4f(lighting_shader.program_id, "view", view);
+ uniform_mat4f(lighting_shader.program_id, "projection", proj);
+
+ // draw triangles
+ u32 num_vertices = vertex_darray_len(mesh->vertices);
+ draw_primitives(CEL_PRIMITIVE_TOPOLOGY_TRIANGLE, 0, num_vertices);
+}
+
+void draw_skinned_model(renderer* ren, camera* cam, model* model, transform tf, scene* scene) {
+ mat4 view;
+ mat4 proj;
+ camera_view_projection(cam, SCR_HEIGHT, SCR_WIDTH, &view, &proj);
+
+ set_shader(ren->skinned);
+
+ // set camera uniform
+ uniform_vec3f(ren->blinn_phong.program_id, "viewPos", &cam->position);
+ // set light uniforms
+ dir_light_upload_uniforms(ren->blinn_phong, &scene->dir_light);
+ for (int i = 0; i < scene->n_point_lights; i++) {
+ point_light_upload_uniforms(ren->blinn_phong, &scene->point_lights[i], '0' + i);
+ }
+
+ for (size_t i = 0; i < mesh_darray_len(model->meshes); i++) {
+ mesh* m = &model->meshes->data[i];
+ if (vertex_darray_len(m->vertices) == 0) {
+ continue;
+ }
+ material* mat = &model->materials->data[m->material_index];
+ draw_skinned_mesh(ren, m, tf, mat, &view, &proj);
+ }
+}
+
void model_upload_meshes(renderer* ren, model* model) {
INFO("Upload mesh vertex data to GPU for model %s", model->name);
@@ -173,6 +233,7 @@ void model_upload_meshes(renderer* ren, model* model) {
// upload each mesh to the GPU
for (int mesh_i = 0; mesh_i < num_meshes; mesh_i++) {
+ mesh mesh = model->meshes->data[mesh_i];
model->meshes->data[mesh_i].vao = VAOs[mesh_i];
model->meshes->data[mesh_i].vbo = VBOs[mesh_i];
// 3. bind buffers
@@ -185,34 +246,51 @@ void model_upload_meshes(renderer* ren, model* model) {
// TODO: convert this garbage into a function
f32 verts[num_vertices * 8];
// for each face
- for (int i = 0; i < (num_vertices / 3); i++) {
- // for each vert in face
- for (int j = 0; j < 3; j++) {
- size_t stride = (i * 24) + j * 8;
- // printf("i: %d, stride: %ld, loc %d\n", i, stride, i * 3 + j);
- vertex vert = model->meshes->data[mesh_i].vertices->data[i];
- // printf("pos %f %f %f\n", vert.position.x, vert.position.y, vert.position.z);
- // printf("norm %f %f %f\n", vert.normal.x, vert.normal.y, vert.normal.z);
- // printf("tex %f %f\n", vert.uv.x, vert.uv.y);
- verts[stride + 0] =
- ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].position.x;
- verts[stride + 1] =
- ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].position.y;
- verts[stride + 2] =
- ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].position.z;
- verts[stride + 3] =
- ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].normal.x;
- verts[stride + 4] =
- ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].normal.y;
- verts[stride + 5] =
- ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].normal.z;
- verts[stride + 6] = ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].uv.x;
- verts[stride + 7] = ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].uv.y;
- }
+ // for (int i = 0; i < (num_vertices / 3); i++) {
+ // // for each vert in face
+ // for (int j = 0; j < 3; j++) {
+ // size_t stride = (i * 24) + j * 8;
+ // // printf("i: %d, stride: %ld, loc %d\n", i, stride, i * 3 + j);
+ // vertex vert = model->meshes->data[mesh_i].vertices->data[i];
+ // // printf("pos %f %f %f\n", vert.position.x, vert.position.y, vert.position.z);
+ // // printf("norm %f %f %f\n", vert.normal.x, vert.normal.y, vert.normal.z);
+ // // printf("tex %f %f\n", vert.uv.x, vert.uv.y);
+ // verts[stride + 0] =
+ // ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].position.x;
+ // verts[stride + 1] =
+ // ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].position.y;
+ // verts[stride + 2] =
+ // ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].position.z;
+ // verts[stride + 3] =
+ // ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].normal.x;
+ // verts[stride + 4] =
+ // ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].normal.y;
+ // verts[stride + 5] =
+ // ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 + j].normal.z;
+ // verts[stride + 6] = ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3 +
+ // j].uv.x; verts[stride + 7] = ((vertex*)model->meshes->data[mesh_i].vertices->data)[i * 3
+ // + j].uv.y;
+ // }
+ // }
+ size_t vertex_size = mesh.is_skinned
+ ? sizeof(vec3) * 2 + sizeof(vec2) + sizeof(u32) * 4 + sizeof(vec4)
+ : sizeof(vec3) * 2 + sizeof(vec2);
+ if (!mesh.is_skinned) {
+ printf("sizeof(vertex) -> %ld, vertex_size -> %ld\n", sizeof(vertex), vertex_size);
+ assert(vertex_size == sizeof(vertex));
+ }
+ size_t buffer_size = vertex_size * num_vertices;
+ u8* bytes = malloc(buffer_size);
+
+ for (int i = 0; i < num_vertices; i++) {
+ u8* p = bytes + vertex_size * i;
+ u8* bone_data_offset = p + sizeof(u32) * 4 + sizeof(vec4);
+ memcpy(p, &mesh.vertices->data[i], sizeof(vertex));
+ memcpy(bone_data_offset, &mesh.vertex_bone_data->data[i], sizeof(vertex_bone_data));
}
// 4. upload data
- glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, buffer_size, bytes, GL_STATIC_DRAW);
// 5. cont. set mesh vertex layout
glBindVertexArray(model->meshes->data[mesh_i].vao);
@@ -225,6 +303,10 @@ void model_upload_meshes(renderer* ren, model* model) {
// tex coords
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
+
+ // skinning (optional)
+ if (mesh.is_skinned) {
+ }
}
INFO("Uploaded %d submeshes with a total of %d vertices\n", num_meshes, total_verts);
@@ -242,7 +324,7 @@ texture texture_data_load(const char* path, bool invert_y) {
stbi_set_flip_vertically_on_load(invert_y);
#pragma GCC diagnostic ignored "-Wpointer-sign"
- char* data = stbi_load(path, &width, &height, &num_channels, 0); // STBI_rgb_alpha);
+ char* data = stbi_load(path, &width, &height, &num_channels, 0); // STBI_rgb_alpha);
if (data) {
DEBUG("loaded texture: %s", path);
} else {