.
This commit is contained in:
parent
507d635433
commit
1c13514a4d
45 changed files with 2615 additions and 2014 deletions
234
src/obj.c
234
src/obj.c
|
|
@ -5,7 +5,7 @@
|
|||
#define CGLTF_IMPLEMENTATION
|
||||
#include "libs/cgltf.h"
|
||||
|
||||
#include "vecmath.h"
|
||||
#include "libs/handmademath.h"
|
||||
|
||||
typedef struct vertex_t vertex_t;
|
||||
struct vertex_t {
|
||||
|
|
@ -15,236 +15,12 @@ struct vertex_t {
|
|||
vec2 lightmap;
|
||||
};
|
||||
|
||||
typedef struct material_t material_t;
|
||||
struct material_t {
|
||||
// texture
|
||||
vec3 ambient_color;
|
||||
vec3 diff_color;
|
||||
|
||||
/*
|
||||
* (*) -> unused
|
||||
* Ka: ambient color
|
||||
* Kd: diffuse color
|
||||
* Ks*: specular color
|
||||
* Ns*: specular exponent
|
||||
* d*: dissolve (opacity)
|
||||
* Ni*: optical density (???)
|
||||
* Ke*: emissive color
|
||||
* illum*: illumination mode:
|
||||
0. Color on and Ambient off
|
||||
1. Color on and Ambient on
|
||||
2. Highlight on
|
||||
3. Reflection on and Ray trace on
|
||||
4. Transparency: Glass on, Reflection: Ray trace on
|
||||
5. Reflection: Fresnel on and Ray trace on
|
||||
6. Transparency: Refraction on, Reflection: Fresnel off and Ray trace on
|
||||
7. Transparency: Refraction on, Reflection: Fresnel on and Ray trace on
|
||||
8. Reflection on and Ray trace off
|
||||
9. Transparency: Glass on, Reflection: Ray trace off
|
||||
10. Casts shadows onto invisible surfaces
|
||||
* */
|
||||
};
|
||||
|
||||
typedef struct obj_t obj_t;
|
||||
struct obj_t {
|
||||
sg_bindings bindings;
|
||||
u16 draw_count;
|
||||
};
|
||||
|
||||
darr_define(f2_list_t, vec2);
|
||||
darr_define(f3_list_t, vec3);
|
||||
darr_define(i3_list_t, int3);
|
||||
|
||||
#define list_get(l, i) do { } while (0)
|
||||
|
||||
typedef struct {
|
||||
f3_list_t *verts;
|
||||
f3_list_t *norms;
|
||||
f2_list_t *uvs;
|
||||
i3_list_t *faces;
|
||||
u32 vcount;
|
||||
u32 ncount;
|
||||
u32 tcount;
|
||||
u32 fcount;
|
||||
} obj_ctx_t;
|
||||
|
||||
#define READ_F2(arr, c) do { \
|
||||
vec2 v = {0}; \
|
||||
istr_skip_whitespace(in); istr_get_float(in, &v.x); \
|
||||
istr_skip_whitespace(in); istr_get_float(in, &v.y); \
|
||||
darr_push(arena, arr, v); \
|
||||
++(c); \
|
||||
} while (0)
|
||||
|
||||
#define READ_F3(arr, c) do { \
|
||||
vec3 v = {0}; \
|
||||
istr_skip_whitespace(in); istr_get_float(in, &v.x); \
|
||||
istr_skip_whitespace(in); istr_get_float(in, &v.y); \
|
||||
istr_skip_whitespace(in); istr_get_float(in, &v.z); \
|
||||
darr_push(arena, arr, v); \
|
||||
++(c); \
|
||||
} while (0)
|
||||
|
||||
#define READ_I3(arr, c) do { \
|
||||
int3 v = {0}; \
|
||||
istr_skip_whitespace(in); istr_get_i32(in, &v.x); \
|
||||
istr_skip_whitespace(in); istr_get_i32(in, &v.y); \
|
||||
istr_skip_whitespace(in); istr_get_i32(in, &v.z); \
|
||||
darr_push(arena, arr, v); \
|
||||
++(c); \
|
||||
} while (0)
|
||||
|
||||
void obj__parse_line(arena_t *arena, instream_t *in, obj_ctx_t *ctx) {
|
||||
if (istr_peek(in) == '#') {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (istr_peek(in)) {
|
||||
// vertex stuff
|
||||
case 'v':
|
||||
istr_skip(in, 1);
|
||||
switch (istr_get(in)) {
|
||||
// vertex
|
||||
case ' ':
|
||||
READ_F3(ctx->verts, ctx->vcount);
|
||||
break;
|
||||
// normal
|
||||
case 'n':
|
||||
READ_F3(ctx->norms, ctx->ncount);
|
||||
break;
|
||||
// texture
|
||||
case 't':
|
||||
READ_F2(ctx->uvs, ctx->tcount);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
|
||||
// faces
|
||||
case 'f':
|
||||
READ_I3(ctx->faces, ctx->fcount);
|
||||
return;
|
||||
|
||||
// smooth shading
|
||||
case 's':
|
||||
// not implemented
|
||||
return;
|
||||
|
||||
// group
|
||||
case 'g':
|
||||
// not implemented
|
||||
return;
|
||||
|
||||
// object
|
||||
case 'o':
|
||||
// not implemented
|
||||
return;
|
||||
|
||||
case '#':
|
||||
return;
|
||||
}
|
||||
|
||||
strview_t word = istr_get_word(in);
|
||||
if (strv_equals(word, strv("mtllib"))) {
|
||||
// load mtl file
|
||||
}
|
||||
else if (strv_equals(word, strv("usemtl"))) {
|
||||
// use material
|
||||
}
|
||||
}
|
||||
|
||||
obj_t obj_load(arena_t scratch, strview_t filename) {
|
||||
obj_t out = {0};
|
||||
|
||||
str_t text = os_file_read_all_str(&scratch, filename);
|
||||
instream_t in = istr_init(strv(text));
|
||||
|
||||
obj_ctx_t ctx = {0};
|
||||
|
||||
while (!istr_is_finished(&in)) {
|
||||
instream_t line = istr_init(istr_get_line(&in));
|
||||
obj__parse_line(&scratch, &line, &ctx);
|
||||
}
|
||||
|
||||
debug("%u %u %u", ctx.vcount, ctx.ncount, ctx.tcount);
|
||||
colla_assert(ctx.vcount == ctx.ncount && ctx.vcount == ctx.tcount);
|
||||
|
||||
// copy over vertex data
|
||||
vertex_t *vertices = alloc(&scratch, vertex_t, ctx.vcount);
|
||||
|
||||
{
|
||||
u32 i = 0;
|
||||
for_each (v, ctx.verts) {
|
||||
for (int k = 0; k < v->count; ++k) {
|
||||
vertices[i++].pos = v->items[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
u32 i = 0;
|
||||
for_each (v, ctx.uvs) {
|
||||
for (int k = 0; k < v->count; ++k) {
|
||||
vertices[i++].tex = v->items[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
u32 i = 0;
|
||||
for_each (v, ctx.norms) {
|
||||
for (int k = 0; k < v->count; ++k) {
|
||||
vertices[i++].norm = v->items[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy over indices data
|
||||
u32 icount = ctx.fcount * 3;
|
||||
u16 *indices = alloc(&scratch, u16, icount);
|
||||
|
||||
{
|
||||
u32 i = 0;
|
||||
for_each (v, ctx.faces) {
|
||||
for (int k = 0; k < v->count; ++k) {
|
||||
indices[i++] = v->items[k].x - 1;
|
||||
indices[i++] = v->items[k].y - 1;
|
||||
indices[i++] = v->items[k].z - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sg_buffer vertex_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data = {
|
||||
.ptr = vertices,
|
||||
.size = sizeof(vertex_t) * ctx.vcount,
|
||||
},
|
||||
.usage = {
|
||||
.vertex_buffer = true,
|
||||
.immutable = true,
|
||||
},
|
||||
});
|
||||
|
||||
sg_buffer index_buffer = sg_make_buffer(&(sg_buffer_desc){
|
||||
.data = {
|
||||
.ptr = indices,
|
||||
.size = sizeof(u16) * ctx.fcount * 3,
|
||||
},
|
||||
.usage = {
|
||||
.index_buffer = true,
|
||||
.immutable = true,
|
||||
},
|
||||
});
|
||||
|
||||
return (obj_t){
|
||||
.bindings = {
|
||||
.vertex_buffers[0] = vertex_buffer,
|
||||
.index_buffer = index_buffer,
|
||||
// .views[0] = {0},
|
||||
},
|
||||
.draw_count = icount,
|
||||
};
|
||||
}
|
||||
|
||||
cgltf_result obj__cgltf_file_read_cb(
|
||||
const cgltf_memory_options *m,
|
||||
const cgltf_file_options *opt,
|
||||
|
|
@ -466,25 +242,25 @@ scene_t obj_load_gltf(arena_t scratch, strview_t filename) {
|
|||
case cgltf_attribute_type_position:
|
||||
{
|
||||
for (usize k = 0; k < acc->count; ++k) {
|
||||
cgltf_accessor_read_float(acc, k, verts[k].pos.data, 3);
|
||||
cgltf_accessor_read_float(acc, k, verts[k].pos.elements, 3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case cgltf_attribute_type_normal:
|
||||
for (usize k = 0; k < acc->count; ++k) {
|
||||
cgltf_accessor_read_float(acc, k, verts[k].norm.data, 3);
|
||||
cgltf_accessor_read_float(acc, k, verts[k].norm.elements, 3);
|
||||
}
|
||||
break;
|
||||
case cgltf_attribute_type_texcoord:
|
||||
{
|
||||
if (attr->index == 0) {
|
||||
for (usize k = 0; k < acc->count; ++k) {
|
||||
cgltf_accessor_read_float(acc, k, verts[k].tex.data, 2);
|
||||
cgltf_accessor_read_float(acc, k, verts[k].tex.elements, 2);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (usize k = 0; k < acc->count; ++k) {
|
||||
cgltf_accessor_read_float(acc, k, verts[k].lightmap.data, 2);
|
||||
cgltf_accessor_read_float(acc, k, verts[k].lightmap.elements, 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue