summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-06-17 22:17:48 +1000
committeromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-06-18 10:30:28 +1000
commit4b5695ce26a8f821dfac987e8e11a6ba5eeff610 (patch)
tree0cd8f80bdb0520ffcf0cd62851f72055d4ee5546
parentf1cb5bece520dba63fa77e4721909ab8f0a6c26f (diff)
start working on a immediate mode drawing API
-rw-r--r--LICENSE21
-rw-r--r--README.md8
-rw-r--r--assets/shaders/pbr_textured.frag134
-rw-r--r--assets/shaders/pbr_textured.vert28
-rw-r--r--examples/pbr_textured/ex_pbr_textured.c135
-rw-r--r--src/maths/maths.h3
-rw-r--r--src/renderer/backends/opengl/backend_opengl.c7
-rw-r--r--src/renderer/builtin_materials.h53
-rw-r--r--src/renderer/immediate.c50
-rw-r--r--src/renderer/immediate.h21
-rw-r--r--src/renderer/render_types.h6
-rw-r--r--src/resources/gltf.c33
-rw-r--r--src/transform_hierarchy.c1
-rw-r--r--xmake.lua7
14 files changed, 439 insertions, 68 deletions
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 21f18ca..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2024 Joshua Rowe
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
index ccd9652..45b4015 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,14 @@
All third-party dependencies are licensed under their own license.
+## "Modules"
+
+| prefix | module | Description |
+| --------- | ----------- | ----------- |
+| `gpu` | RAL | |
+| `plat` | Platforn | |
+| `phys` | Physics | |
+
## Notes
* Check symbols in an 'archive' (static library)
diff --git a/assets/shaders/pbr_textured.frag b/assets/shaders/pbr_textured.frag
new file mode 100644
index 0000000..132c449
--- /dev/null
+++ b/assets/shaders/pbr_textured.frag
@@ -0,0 +1,134 @@
+#version 410 core
+
+out vec4 FragColor;
+
+in vec3 fragWorldPos;
+in vec3 fragNormal;
+in vec2 fragTexCoords;
+
+struct PointLight {
+ vec4 position;
+ vec4 color;
+};
+
+// --- Uniforms
+
+// Lights data
+#define NUM_POINT_LIGHTS 4
+uniform Scene_Lights {
+ PointLight pointLights[NUM_POINT_LIGHTS];
+ vec4 viewPos;
+} scene;
+
+// Material Textures
+uniform sampler2D albedoMap;
+uniform sampler2D metallicRoughnessMap;
+// uniform sampler2D roughnessMap;
+uniform sampler2D aoMap;
+uniform sampler2D normalMap;
+
+const float PI = 3.14;
+
+// Forward declarations
+vec3 fresnelSchlick(float cosTheta, vec3 F0);
+float DistributionGGX(vec3 N, vec3 H, float roughness);
+float GeometrySchlickGGX(float NdotV, float roughness);
+float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
+
+void main() {
+ vec3 albedo = pow(texture(albedoMap, fragTexCoords).rgb, vec3(2.2));
+ // vec3 normal = getNormalFromNormalMap();
+ float metallic = texture(metallicRoughnessMap, fragTexCoords).g;
+ float roughness = texture(metallicRoughnessMap, fragTexCoords).b;
+ float ao = texture(aoMap, fragTexCoords).r;
+
+ vec3 norm = normalize(fragNormal); // N
+ vec3 N = norm;
+ vec3 viewDir = normalize(vec3(scene.viewPos) - fragWorldPos); // V
+ vec3 V = viewDir;
+
+ vec3 F0 = vec3(0.04);
+ F0 = mix(F0, albedo, metallic);
+
+ vec3 Lo = vec3(0.0);
+ for (int i = 0; i < 4; ++i) {
+ vec3 lightVec = normalize(vec3(scene.pointLights[i].position) - fragWorldPos); // L
+ vec3 L = lightVec;
+ vec3 halfway = normalize(viewDir + lightVec); // H
+ vec3 H = halfway;
+ float distance = length(vec3(scene.pointLights[i].position) - fragWorldPos);
+ float attenuation = 1.0 / (distance * distance);
+ vec3 radiance = vec3(scene.pointLights[i].color) * attenuation;
+
+ // cook-torrance brdf
+ float NDF = DistributionGGX(norm, halfway, roughness);
+ float G = GeometrySmith(norm, viewDir, lightVec, roughness);
+ // vec3 F = fresnelSchlick(max(dot(halfway, viewDir), 0.0), F0);
+ vec3 F = fresnelSchlick(clamp(dot(H, V), 0.0, 1.0), F0);
+
+ vec3 numerator = NDF * G * F;
+ float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001;
+ vec3 specular = numerator / denominator;
+
+ vec3 kS = F;
+
+ vec3 kD = vec3(1.0) - kS;
+ kD *= 1.0 - metallic;
+
+ // add to outgoing radiance Lo
+ float NdotL = max(dot(N, L), 0.0);
+ Lo += (kD * albedo / PI + specular) * radiance * NdotL;
+ // Lo += radiance;
+ }
+
+ vec3 ambient = vec3(0.03) * albedo * ao;
+ vec3 color = ambient + Lo; //ambient + Lo;
+
+ color = color / (color + vec3(1.0));
+ color = pow(color, vec3(1.0/2.2));
+
+ FragColor = vec4(color, 1.0);
+ // FragColor = vec4(1.0);
+ // FragColor = vec4(scene.pointLights[0].position);
+ FragColor = vec4(albedo, 1.0);
+ // FragColor = vec4(pbr.metallic, pbr.roughness, pbr.ao, 1.0);
+ // FragColor = scene.viewPos;
+}
+
+/* The below are from https://learnopengl.com/PBR/Lighting */
+
+vec3 fresnelSchlick(float cosTheta, vec3 F0) {
+ return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0);
+}
+float DistributionGGX(vec3 N, vec3 H, float roughness) {
+ float a = roughness*roughness;
+ float a2 = a*a;
+ float NdotH = max(dot(N, H), 0.0);
+ float NdotH2 = NdotH*NdotH;
+
+ float num = a2;
+ float denom = (NdotH2 * (a2 - 1.0) + 1.0);
+ denom = PI * denom * denom;
+
+ return num / denom;
+}
+
+float GeometrySchlickGGX(float NdotV, float roughness)
+{
+ float r = (roughness + 1.0);
+ float k = (r*r) / 8.0;
+
+ float num = NdotV;
+ float denom = NdotV * (1.0 - k) + k;
+
+ return num / denom;
+}
+float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
+{
+ float NdotV = max(dot(N, V), 0.0);
+ float NdotL = max(dot(N, L), 0.0);
+ float ggx2 = GeometrySchlickGGX(NdotV, roughness);
+ float ggx1 = GeometrySchlickGGX(NdotL, roughness);
+
+ return ggx1 * ggx2;
+}
diff --git a/assets/shaders/pbr_textured.vert b/assets/shaders/pbr_textured.vert
new file mode 100644
index 0000000..40a6f29
--- /dev/null
+++ b/assets/shaders/pbr_textured.vert
@@ -0,0 +1,28 @@
+#version 410 core
+
+// Vertex attributes
+layout(location = 0) in vec3 inPosition;
+layout(location = 1) in vec3 inNormal;
+layout(location = 2) in vec2 inTexCoords;
+
+// Uniforms
+uniform MVP_Matrices {
+ mat4 model; // TODO: make model a push constant/raw uniform
+ mat4 view;
+ mat4 proj;
+} mvp;
+
+// Outputs
+layout(location = 0) out vec3 fragWorldPos;
+layout(location = 1) out vec3 fragNormal;
+layout(location = 2) out vec2 fragTexCoords;
+
+void main() {
+ fragWorldPos = vec3(mvp.model * vec4(inPosition, 1.0));
+ fragNormal = mat3(transpose(inverse(mvp.model))) * inNormal;
+ // fragNormal = inNormal;
+
+ fragTexCoords = inTexCoords;
+
+ gl_Position = mvp.proj * mvp.view * mvp.model * vec4(inPosition, 1.0);
+}
diff --git a/examples/pbr_textured/ex_pbr_textured.c b/examples/pbr_textured/ex_pbr_textured.c
new file mode 100644
index 0000000..a28d3fb
--- /dev/null
+++ b/examples/pbr_textured/ex_pbr_textured.c
@@ -0,0 +1,135 @@
+#include <glfw3.h>
+#include <stdbool.h>
+
+#include "builtin_materials.h"
+#include "camera.h"
+#include "colours.h"
+#include "core.h"
+#include "loaders.h"
+#include "log.h"
+#include "maths.h"
+#include "maths_types.h"
+#include "primitives.h"
+#include "ral.h"
+#include "render.h"
+#include "render_types.h"
+#include "str.h"
+
+extern core g_core;
+
+#define MODEL_GET(h) (model_pool_get(&g_core.models, h))
+
+const vec3 pointlight_positions[4] = {
+ { 10.0 / 1., 10.0 / 1., 10.0 },
+ { -10.0 / 1., 10.0 / 1., 10.0 },
+ { 10.0 / 1., -10.0 / 1., 10.0 },
+ { -10.0 / 1., -10.0 / 1., 10.0 },
+};
+pbr_point_light point_lights[4];
+
+int main() {
+ core_bringup();
+
+ arena scratch = arena_create(malloc(1024 * 1024), 1024 * 1024);
+
+ for (int i = 0; i < 4; i++) {
+ point_lights[i].pos = pointlight_positions[i];
+ point_lights[i].color = vec3(300.0, 300.0, 300.0);
+ }
+
+ vec3 camera_pos = vec3(5., 0., 0.);
+ vec3 camera_front = vec3_normalise(vec3_negate(camera_pos));
+ camera cam = camera_create(camera_pos, camera_front, VEC3_NEG_Z, deg_to_rad(45.0));
+
+ shader_data pbr_uniforms = { .data = NULL, .shader_data_get_layout = &pbr_textured_shader_layout };
+
+ // Make the pipeline
+ gpu_renderpass_desc pass_description = {};
+ gpu_renderpass* renderpass = gpu_renderpass_create(&pass_description);
+ str8 vert_path = str8lit("assets/shaders/pbr_textured.vert");
+ str8 frag_path = str8lit("assets/shaders/pbr_textured.frag");
+ str8_opt vertex_shader = str8_from_file(&scratch, vert_path);
+ str8_opt fragment_shader = str8_from_file(&scratch, frag_path);
+ if (!vertex_shader.has_value || !fragment_shader.has_value) {
+ ERROR_EXIT("Failed to load shaders from disk")
+ }
+
+ struct graphics_pipeline_desc pipeline_description = {
+ .debug_name = "Basic Pipeline",
+ .vertex_desc = static_3d_vertex_description(),
+ .data_layouts = { pbr_uniforms },
+ .data_layouts_count = 1,
+ .vs = { .debug_name = "PBR (textured) Vertex Shader",
+ .filepath = vert_path,
+ .code = vertex_shader.contents,
+ .is_spirv = false },
+ .fs = { .debug_name = "PBR (textured) Fragment Shader",
+ .filepath = frag_path,
+ .code = fragment_shader.contents,
+ .is_spirv = false },
+ .renderpass = renderpass,
+ .wireframe = false,
+ .depth_test = false
+ };
+ gpu_pipeline* pbr_pipeline = gpu_graphics_pipeline_create(pipeline_description);
+
+ // Model
+ model_handle helmet_handle =
+ model_load_gltf("assets/models/gltf/DamagedHelmet/glTF/DamagedHelmet.gltf", false);
+ INFO("GLTF loaded successfully!");
+ model* helmet = MODEL_GET(helmet_handle);
+
+ pbr_textured_bindgroup pbr_bind_data;
+
+ while (!should_exit()) {
+ input_update(&g_core.input);
+
+ if (!gpu_backend_begin_frame()) {
+ continue;
+ }
+ gpu_cmd_encoder* enc = gpu_get_default_cmd_encoder();
+ // Begin recording
+ gpu_cmd_encoder_begin(*enc);
+ gpu_cmd_encoder_begin_render(enc, renderpass);
+ encode_bind_pipeline(enc, PIPELINE_GRAPHICS, pbr_pipeline);
+ encode_set_default_settings(enc);
+
+ mat4 model_affine = mat4_ident();
+ mat4 view, proj;
+ camera_view_projection(&cam, 1000, 1000, &view, &proj);
+
+ // Feed shader data
+ pbr_bind_data.mvp_matrices =
+ (mvp_matrix_uniforms){ .model = model_affine, .view = view, .projection = proj };
+ pbr_bind_data.lights = (pbr_params_light_uniforms){
+ .viewPos = vec4(cam.position.x, cam.position.y, cam.position.z, 1.0),
+ .pointLights = { point_lights[0], point_lights[1], point_lights[2], point_lights[3] }
+ };
+ pbr_bind_data.textures = (pbr_textures){
+ .albedo_tex = helmet->materials->data[0].mat_data.pbr.albedo_map,
+ .metal_roughness_tex = helmet->materials->data[0].mat_data.pbr.metallic_map,
+ .ao_tex = helmet->materials->data[0].mat_data.pbr.ao_map,
+ .normal_tex = helmet->materials->data[0].mat_data.pbr.normal_map,
+ };
+ pbr_uniforms.data = &pbr_bind_data;
+ encode_bind_shader_data(enc, 0, &pbr_uniforms);
+
+ // Record draw calls
+ mesh m = helmet->meshes->data[0];
+ encode_set_vertex_buffer(enc, m.vertex_buffer);
+ encode_set_index_buffer(enc, m.index_buffer);
+ encode_draw_indexed(enc, m.geometry->indices->len);
+
+ // End recording
+ gpu_cmd_encoder_end_render(enc);
+
+ gpu_cmd_buffer buf = gpu_cmd_encoder_finish(enc);
+ gpu_queue_submit(&buf);
+ // Submit
+ gpu_backend_end_frame();
+ }
+
+ renderer_shutdown(&g_core.renderer);
+
+ return 0;
+} \ No newline at end of file
diff --git a/src/maths/maths.h b/src/maths/maths.h
index fa58088..7c0e06e 100644
--- a/src/maths/maths.h
+++ b/src/maths/maths.h
@@ -314,7 +314,8 @@ static inline mat4 transform_to_mat(transform *tf) {
mat4 scale = mat4_scale(tf->scale);
mat4 rotation = mat4_rotation(tf->rotation);
mat4 translation = mat4_translation(tf->position);
- return mat4_mult(mat4_mult(scale, rotation), translation);
+ return mat4_mult(translation, mat4_mult(rotation, scale));
+ // return mat4_mult(mat4_mult(scale, rotation), translation);
}
// --- Sizing asserts
diff --git a/src/renderer/backends/opengl/backend_opengl.c b/src/renderer/backends/opengl/backend_opengl.c
index d9859b2..18cd7ee 100644
--- a/src/renderer/backends/opengl/backend_opengl.c
+++ b/src/renderer/backends/opengl/backend_opengl.c
@@ -207,16 +207,11 @@ void encode_bind_shader_data(gpu_cmd_encoder* encoder, u32 group, shader_data* d
glBindBuffer(GL_UNIFORM_BUFFER, ubo_buf->id.ubo);
glBindBufferBase(GL_UNIFORM_BUFFER, ubo_buf->ubo_binding_point, ubo_buf->id.ubo);
- if (i == 2) {
- // pbr_params_light_uniforms* u = binding.data.bytes.data;
- // vec4* v = &u->viewPos;
- }
glBufferSubData(GL_UNIFORM_BUFFER, 0, ubo_buf->size, binding.data.bytes.data);
} else if (binding.type == SHADER_BINDING_TEXTURE) {
gpu_texture* tex = TEXTURE_GET(binding.data.texture.handle);
- glActiveTexture(GL_TEXTURE0);
- // glActiveTexture(GL_TEXTURE0 + i);
+ glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, tex->id);
}
}
diff --git a/src/renderer/builtin_materials.h b/src/renderer/builtin_materials.h
index 7748599..1a04f32 100644
--- a/src/renderer/builtin_materials.h
+++ b/src/renderer/builtin_materials.h
@@ -102,3 +102,56 @@ static void* shader_layout_get_binding(shader_data_layout* layout, u32 nth_bindi
assert(nth_binding < layout->bindings_count);
return &layout->bindings[nth_binding].data;
}
+
+typedef struct pbr_textures {
+ texture_handle albedo_tex;
+ texture_handle metal_roughness_tex;
+ texture_handle ao_tex;
+ texture_handle normal_tex;
+} pbr_textures;
+
+typedef struct pbr_textured_bindgroup {
+ mvp_matrix_uniforms mvp_matrices;
+ pbr_params_light_uniforms lights;
+ pbr_textures textures;
+} pbr_textured_bindgroup;
+
+static shader_data_layout pbr_textured_shader_layout(void* data) {
+ pbr_textured_bindgroup* d = (pbr_textured_bindgroup*)data;
+ bool has_data = data != NULL;
+
+ shader_binding b1 = { .label = "MVP_Matrices",
+ .type = SHADER_BINDING_BYTES,
+ .stores_data = has_data,
+ .data = { .bytes = { .size = sizeof(mvp_matrix_uniforms) } } };
+
+ shader_binding b2 = { .label = "Scene_Lights",
+ .type = SHADER_BINDING_BYTES,
+ .stores_data = has_data,
+ .data = { .bytes = { .size = sizeof(pbr_params_light_uniforms) } } };
+
+ shader_binding b3 = {.label = "Albedo",
+ .type = SHADER_BINDING_TEXTURE,
+ .stores_data = has_data };
+ shader_binding b4 = {.label = "Metallic Roughness",
+ .type = SHADER_BINDING_TEXTURE,
+ .stores_data = has_data };
+ shader_binding b5 = {.label = "Ambient Occlusion",
+ .type = SHADER_BINDING_TEXTURE,
+ .stores_data = has_data };
+ shader_binding b6 = {.label = "Normal Vectors",
+ .type = SHADER_BINDING_TEXTURE,
+ .stores_data = has_data };
+
+ if (has_data) {
+ b1.data.bytes.data = &d->mvp_matrices;
+ b2.data.bytes.data = &d->lights;
+ b3.data.texture.handle = d->textures.albedo_tex;
+ b4.data.texture.handle = d->textures.metal_roughness_tex;
+ b5.data.texture.handle = d->textures.ao_tex;
+ b6.data.texture.handle = d->textures.normal_tex;
+ }
+
+ return (shader_data_layout){ .name = "pbr_params", .bindings = { b1, b2, b3, b4, b5, b6 }, .bindings_count = 6
+ };
+} \ No newline at end of file
diff --git a/src/renderer/immediate.c b/src/renderer/immediate.c
index e76d102..b3431fa 100644
--- a/src/renderer/immediate.c
+++ b/src/renderer/immediate.c
@@ -1,18 +1,50 @@
#include "immediate.h"
+#include "glad/glad.h"
#include "maths.h"
#include "primitives.h"
#include "ral_types.h"
#include "render.h"
+#include "render_types.h"
-void imm_draw_sphere(vec3 pos, f32 radius, vec4 colour) {
- // Create the vertices
- geometry_data geometry = geo_create_uvsphere(radius, 16, 16);
- geo_set_vertex_colours(&geometry, colour);
+typedef struct immdraw_system {
+ // primitive meshes (get reused for each draw call)
+ mesh plane;
+ mesh cube;
+ mesh sphere;
+ // command lists
+
+} immdraw_system;
- // Upload to GPU
- mat4 model = mat4_translation(pos);
+bool immdraw_system_init(immdraw_system* state) {
+ geometry_data plane_geometry = geo_create_plane(f32x2(1, 1));
+ state->plane = mesh_create(&plane_geometry, true);
- // Set pipeline
+ geometry_data cube_geometry = geo_create_cuboid(f32x3(1, 1, 1));
+ state->cube = mesh_create(&cube_geometry, true);
- // Draw
-} \ No newline at end of file
+ geometry_data sphere_geometry = geo_create_uvsphere(1.0, 48, 48);
+ state->sphere = mesh_create(&sphere_geometry, true);
+
+ return true;
+}
+
+void immdraw_plane(vec3 pos, quat rotation, f32 u_scale, f32 v_scale, vec4 colour) {
+
+}
+
+void immdraw_system_render(immdraw_system* state) {
+
+}
+
+// void imm_draw_sphere(vec3 pos, f32 radius, vec4 colour) {
+// // Create the vertices
+// geometry_data geometry = geo_create_uvsphere(radius, 16, 16);
+// geo_set_vertex_colours(&geometry, colour);
+
+// // Upload to GPU
+// mat4 model = mat4_translation(pos);
+
+// // Set pipeline
+
+// // Draw
+// } \ No newline at end of file
diff --git a/src/renderer/immediate.h b/src/renderer/immediate.h
index b9d7c61..f4b1729 100644
--- a/src/renderer/immediate.h
+++ b/src/renderer/immediate.h
@@ -3,18 +3,17 @@
#include "geometry.h"
#include "maths_types.h"
+typedef struct immdraw_system immdraw_system;
+
+bool immdraw_system_init(immdraw_system* state);
+void immdraw_system_shutdown(immdraw_system* state);
+void immdraw_system_render(immdraw_system* state);
+
// 3. SIMA (simplified immediate mode api) / render.h
// - dont need to worry about uploading mesh data
// - very useful for debugging
-void imm_draw_cuboid(vec3 pos, quat rotation, f32x3 extents, vec4 colour);
-void imm_draw_sphere(vec3 pos, f32 radius, vec4 colour);
-void imm_draw_camera_frustum();
-
-// static void imm_draw_model(
-// const char* model_filepath); // tracks internally whether the model is loaded
+void immdraw_plane(vec3 pos, quat rotation, f32 u_scale, f32 v_scale, vec4 colour);
+void immdraw_cuboid(vec3 pos, quat rotation, f32x3 extents, vec4 colour);
+void immdraw_sphere(vec3 pos, f32 radius, vec4 colour);
-// static void imm_draw_model(const char* model_filepath) {
-// check that model is loaded
-// if not loaded, load model and upload to gpu - LRU cache for models
-// else submit draw call
-// } \ No newline at end of file
+void immdraw_camera_frustum();
diff --git a/src/renderer/render_types.h b/src/renderer/render_types.h
index 8588b87..b25fa14 100644
--- a/src/renderer/render_types.h
+++ b/src/renderer/render_types.h
@@ -35,11 +35,17 @@ typedef struct geometry_data {
rgba colour; /** Optional: set vertex colours */
} geometry_data;
+typedef struct u32_opt {
+ u32 value;
+ bool has_value;
+} u32_opt;
+
// 'Upload' a geometry_data (to GPU) -> get back a mesh
typedef struct mesh {
buffer_handle vertex_buffer;
buffer_handle index_buffer;
geometry_data* geometry; // NULL means it has been freed
+ u32_opt material_index;
bool is_uploaded;
bool is_latent;
} mesh;
diff --git a/src/resources/gltf.c b/src/resources/gltf.c
index 46ad4f3..f136595 100644
--- a/src/resources/gltf.c
+++ b/src/resources/gltf.c
@@ -192,6 +192,9 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
material_darray_push(out_model->materials, our_material);
}
+ // TEMP
+ u32 mat_idx = 9999;
+
// --- Meshes
size_t num_meshes = data->meshes_count;
TRACE("Num meshes %d", num_meshes);
@@ -288,14 +291,15 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
if (primitive.material != NULL) {
ERROR("Primitive Material %s", primitive.material->name);
- // for (int i = 0; i < material_darray_len(out_model->materials); i++) {
- // printf("%s vs %s \n", primitive.material->name, out_model->materials->data[i].name);
- // if (strcmp(primitive.material->name, out_model->materials->data[i].name) == 0) {
- // TRACE("Found material");
- // mesh.material_index = i;
- // break;
- // }
- // }
+ for (u32 i = 0; i < material_darray_len(out_model->materials); i++) {
+ printf("%s vs %s \n", primitive.material->name, out_model->materials->data[i].name);
+ if (strcmp(primitive.material->name, out_model->materials->data[i].name) == 0) {
+ INFO("Found material");
+ mat_idx = i;
+ // mesh.material_index = i;
+ break;
+ }
+ }
}
// // FIXME
@@ -317,17 +321,6 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
// // }
// // }
- /*
- typedef struct mesh {
- buffer_handle vertex_buffer;
- buffer_handle index_buffer;
- u32 index_count;
- bool has_indices;
- geometry_data* vertices; // NULL means it has been freed
- bool is_uploaded;
- bool is_latent;
- } mesh;
- */
bool has_indices = false;
vertex_darray *geo_vertices = vertex_darray_new(3);
u32_darray *geo_indices = u32_darray_new(0);
@@ -384,7 +377,9 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
geometry->vertices = geo_vertices;
geometry->indices = geo_indices;
geometry->has_indices = has_indices;
+
mesh m = mesh_create(geometry, true);
+ m.material_index = (u32_opt){.has_value = mat_idx == 9999, .value = mat_idx };
mesh_darray_push(out_model->meshes, m);
}
diff --git a/src/transform_hierarchy.c b/src/transform_hierarchy.c
index 2c427b2..b9795bc 100644
--- a/src/transform_hierarchy.c
+++ b/src/transform_hierarchy.c
@@ -11,7 +11,6 @@
#include "log.h"
#include "maths.h"
#include "maths_types.h"
-// #include "render_types.h"
struct transform_hierarchy {
transform_node root;
diff --git a/xmake.lua b/xmake.lua
index 67a21a0..179e14f 100644
--- a/xmake.lua
+++ b/xmake.lua
@@ -230,6 +230,13 @@ target("pbr_params")
add_files("examples/pbr_params/ex_pbr_params.c")
set_rundir("$(projectdir)")
+target("pbr_textured")
+ set_kind("binary")
+ set_group("examples")
+ add_deps("core_static")
+ add_files("examples/pbr_textured/ex_pbr_textured.c")
+ set_rundir("$(projectdir)")
+
-- target("transforms")
-- set_kind("binary")
-- set_group("examples")