-
-
Save seanbaxter/947417862033ff7870e564c7a79eb2d1 to your computer and use it in GitHub Desktop.
Load glTF primitive.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
prim_t model_t::load_prim(const cgltf_primitive* prim) { | |
prim_t prim2 { }; | |
glCreateVertexArrays(1, &prim2.vao); | |
if(prim->indices) { | |
// Bind the index array. | |
const cgltf_accessor* accessor = prim->indices; | |
const cgltf_buffer_view* view = accessor->buffer_view; | |
assert(cgltf_buffer_view_type_indices == view->type); | |
prim2.begin = accessor->offset + view->offset; | |
switch(accessor->component_type) { | |
case cgltf_component_type_r_8: | |
case cgltf_component_type_r_8u: | |
prim2.elements_type = GL_UNSIGNED_BYTE; | |
break; | |
case cgltf_component_type_r_16: | |
case cgltf_component_type_r_16u: | |
prim2.begin /= 2; | |
prim2.elements_type = GL_UNSIGNED_SHORT; | |
break; | |
case cgltf_component_type_r_32u: | |
prim2.begin /= 4; | |
prim2.elements_type = GL_UNSIGNED_INT; | |
break; | |
default: | |
break; | |
} | |
prim2.end = prim2.begin + accessor->count; | |
// Associate the buffer holding the indices. | |
GLuint buffer = buffers[find_buffer_index(data, view->buffer)]; | |
glVertexArrayElementBuffer(prim2.vao, buffer); | |
PRINT_ERROR(); | |
} | |
// One slot per potential VBO bind point. | |
const cgltf_buffer_view* views[16] { }; | |
int binding_count = 0; | |
for(int a = 0; a < prim->attributes_count; ++a) { | |
const cgltf_attribute* attrib = prim->attributes + a; | |
const cgltf_accessor* accessor = attrib->data; | |
const cgltf_buffer_view* view = accessor->buffer_view; | |
assert(cgltf_buffer_view_type_vertices == view->type); | |
// Only support 0 index attributes. Eg, don't support TEXCOORD_1, _2 | |
// etc quite yet. | |
if(attrib->index) | |
continue; | |
// Get the attribute location. | |
vattrib_t attribindex; | |
switch(attrib->type) { | |
case cgltf_attribute_type_position: | |
attribindex = vattrib_position; | |
break; | |
case cgltf_attribute_type_normal: | |
attribindex = vattrib_normal; | |
break; | |
case cgltf_attribute_type_texcoord: | |
attribindex = vattrib_texcoord; | |
break; | |
case cgltf_attribute_type_joints: | |
attribindex = vattrib_joints; | |
break; | |
case cgltf_attribute_type_weights: | |
attribindex = vattrib_weights; | |
break; | |
} | |
// Find an existing bufferView binding. | |
int bindingindex = -1; | |
for(int i = 0; i < binding_count; ++i) { | |
if(views[i] == view) { | |
bindingindex = i; | |
break; | |
} | |
} | |
if(-1 == bindingindex) { | |
// Use one binding per attribute. | |
bindingindex = binding_count++; | |
views[bindingindex] = view; | |
GLuint buffer = buffers[find_buffer_index(data, view->buffer)]; | |
glVertexArrayVertexBuffer(prim2.vao, attribindex, buffer, | |
view->offset, view->stride); | |
PRINT_ERROR(); | |
} | |
// Enable the vertex attribute location. | |
glEnableVertexArrayAttrib(prim2.vao, attribindex); | |
PRINT_ERROR(); | |
// Get the attribute size and type. | |
GLenum type = GL_NONE; | |
int size = 0; | |
switch(accessor->type) { | |
case cgltf_type_scalar: size = 1; break; | |
case cgltf_type_vec2: size = 2; break; | |
case cgltf_type_vec3: size = 3; break; | |
case cgltf_type_vec4: size = 4; break; | |
default: break; | |
} | |
switch(accessor->component_type) { | |
case cgltf_component_type_r_8: type = GL_BYTE; break; | |
case cgltf_component_type_r_8u: type = GL_UNSIGNED_BYTE; break; | |
case cgltf_component_type_r_16: type = GL_SHORT; break; | |
case cgltf_component_type_r_16u: type = GL_UNSIGNED_SHORT; break; | |
case cgltf_component_type_r_32u: type = GL_UNSIGNED_INT; break; | |
case cgltf_component_type_r_32f: type = GL_FLOAT; break; | |
default: break; | |
} | |
// Associate the buffer view with the attribute location. | |
glVertexArrayAttribBinding(prim2.vao, attribindex, bindingindex); | |
PRINT_ERROR(); | |
if(accessor->normalized || GL_FLOAT == type) { | |
glVertexArrayAttribFormat(prim2.vao, attribindex, size, type, | |
accessor->normalized, accessor->offset); | |
} else { | |
glVertexArrayAttribIFormat(prim2.vao, attribindex, size, type, | |
accessor->offset); | |
} | |
PRINT_ERROR(); | |
} | |
return prim2; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment