diff options
| author | 3gg <3gg@shellblade.net> | 2023-02-11 17:25:26 -0800 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2023-02-11 17:25:26 -0800 |
| commit | 53582d2a90fb72e02056612163239b3b3f62eb4a (patch) | |
| tree | 83f0d36f29272a88e110584abb69fd3d547637e8 | |
| parent | c6e5f631ee26e97385fd5e2e980bad0b461e8953 (diff) | |
Add support for 8-bit vertex indices.
| -rw-r--r-- | gfx/include/gfx/render_backend.h | 19 | ||||
| -rw-r--r-- | gfx/src/render/geometry.c | 43 | ||||
| -rw-r--r-- | gfx/src/render/geometry.h | 3 | ||||
| -rw-r--r-- | gfx/src/util/scene.c | 33 |
4 files changed, 72 insertions, 26 deletions
diff --git a/gfx/include/gfx/render_backend.h b/gfx/include/gfx/render_backend.h index e037f78..785c4b9 100644 --- a/gfx/include/gfx/render_backend.h +++ b/gfx/include/gfx/render_backend.h | |||
| @@ -27,7 +27,8 @@ typedef struct RenderBackend RenderBackend; | |||
| 27 | 27 | ||
| 28 | /// Data type for vertex indices. | 28 | /// Data type for vertex indices. |
| 29 | /// Might need U32 for bigger models. | 29 | /// Might need U32 for bigger models. |
| 30 | typedef uint16_t VertexIndex; | 30 | typedef uint8_t VertexIndex8; |
| 31 | typedef uint16_t VertexIndex16; | ||
| 31 | typedef uint16_t VertexCount; | 32 | typedef uint16_t VertexCount; |
| 32 | 33 | ||
| 33 | /// Geometry drawing modes. | 34 | /// Geometry drawing modes. |
| @@ -69,8 +70,11 @@ MAKE_BUFFER_VIEW(BufferViewU8, uint8_t) | |||
| 69 | /// A buffer view for 16-bit unsigned integers. | 70 | /// A buffer view for 16-bit unsigned integers. |
| 70 | MAKE_BUFFER_VIEW(BufferViewU16, uint16_t) | 71 | MAKE_BUFFER_VIEW(BufferViewU16, uint16_t) |
| 71 | 72 | ||
| 72 | /// A buffer view for vertex indices. | 73 | /// A buffer view for 8-bit vertex indices. |
| 73 | MAKE_BUFFER_VIEW(BufferViewIdx, uint16_t) | 74 | MAKE_BUFFER_VIEW(BufferViewIdx8, uint16_t) |
| 75 | |||
| 76 | /// A buffer view for 16-bit vertex indices. | ||
| 77 | MAKE_BUFFER_VIEW(BufferViewIdx16, uint16_t) | ||
| 74 | 78 | ||
| 75 | /// Describes a piece of geometry. | 79 | /// Describes a piece of geometry. |
| 76 | /// | 80 | /// |
| @@ -91,10 +95,11 @@ typedef struct GeometryDesc { | |||
| 91 | BufferViewU8 u8; | 95 | BufferViewU8 u8; |
| 92 | BufferViewU16 u16; | 96 | BufferViewU16 u16; |
| 93 | } weights; // vec4 or uvec4. | 97 | } weights; // vec4 or uvec4. |
| 94 | BufferViewIdx indices; | 98 | BufferViewIdx8 indices8; |
| 95 | VertexCount num_verts; | 99 | BufferViewIdx16 indices16; |
| 96 | size_t num_indices; | 100 | VertexCount num_verts; |
| 97 | PrimitiveType type; | 101 | size_t num_indices; |
| 102 | PrimitiveType type; | ||
| 98 | } GeometryDesc; | 103 | } GeometryDesc; |
| 99 | 104 | ||
| 100 | /// Shader compiler define. | 105 | /// Shader compiler define. |
diff --git a/gfx/src/render/geometry.c b/gfx/src/render/geometry.c index 0df6efb..7f3fc46 100644 --- a/gfx/src/render/geometry.c +++ b/gfx/src/render/geometry.c | |||
| @@ -83,10 +83,9 @@ bool gfx_init_geometry( | |||
| 83 | view_is_populated(desc->positions2d)); | 83 | view_is_populated(desc->positions2d)); |
| 84 | assert(desc->num_verts > 0); | 84 | assert(desc->num_verts > 0); |
| 85 | 85 | ||
| 86 | geometry->mode = primitive_type_to_gl(desc->type); | 86 | geometry->mode = primitive_type_to_gl(desc->type); |
| 87 | geometry->num_verts = desc->num_verts; | 87 | geometry->num_verts = desc->num_verts; |
| 88 | geometry->num_indices = desc->num_indices; | 88 | geometry->num_indices = desc->num_indices; |
| 89 | geometry->indices_offset_bytes = desc->indices.offset_bytes; | ||
| 90 | 89 | ||
| 91 | glGenVertexArrays(1, &geometry->vao); | 90 | glGenVertexArrays(1, &geometry->vao); |
| 92 | glBindVertexArray(geometry->vao); | 91 | glBindVertexArray(geometry->vao); |
| @@ -174,16 +173,31 @@ bool gfx_init_geometry( | |||
| 174 | 173 | ||
| 175 | glBindBuffer(GL_ARRAY_BUFFER, 0); | 174 | glBindBuffer(GL_ARRAY_BUFFER, 0); |
| 176 | 175 | ||
| 177 | if (view_is_populated(desc->indices)) { | 176 | if (view_is_populated(desc->indices8)) { |
| 178 | assert(desc->num_indices > 0); | 177 | assert(desc->num_indices > 0); |
| 179 | assert(desc->num_indices <= desc->indices.size_bytes / sizeof(VertexIndex)); | 178 | assert( |
| 180 | geometry->indices = | 179 | desc->num_indices <= desc->indices8.size_bytes / sizeof(VertexIndex8)); |
| 181 | get_or_make_buffer(render_backend, (const BufferView*)&desc->indices); | 180 | geometry->indices_offset_bytes = desc->indices8.offset_bytes; |
| 182 | if (!geometry->indices) { | 181 | geometry->indices8 = |
| 182 | get_or_make_buffer(render_backend, (const BufferView*)&desc->indices8); | ||
| 183 | if (!geometry->indices8) { | ||
| 184 | gfx_del_geometry(geometry); | ||
| 185 | return false; | ||
| 186 | } | ||
| 187 | assert(desc->indices8.size_bytes <= geometry->indices8->size_bytes); | ||
| 188 | } else if (view_is_populated(desc->indices16)) { | ||
| 189 | assert(desc->num_indices > 0); | ||
| 190 | assert( | ||
| 191 | desc->num_indices <= | ||
| 192 | desc->indices16.size_bytes / sizeof(VertexIndex16)); | ||
| 193 | geometry->indices_offset_bytes = desc->indices16.offset_bytes; | ||
| 194 | geometry->indices16 = | ||
| 195 | get_or_make_buffer(render_backend, (const BufferView*)&desc->indices16); | ||
| 196 | if (!geometry->indices16) { | ||
| 183 | gfx_del_geometry(geometry); | 197 | gfx_del_geometry(geometry); |
| 184 | return false; | 198 | return false; |
| 185 | } | 199 | } |
| 186 | assert(desc->indices.size_bytes <= geometry->indices->size_bytes); | 200 | assert(desc->indices16.size_bytes <= geometry->indices16->size_bytes); |
| 187 | } | 201 | } |
| 188 | 202 | ||
| 189 | glBindVertexArray(0); | 203 | glBindVertexArray(0); |
| @@ -203,8 +217,13 @@ void gfx_render_geometry(const Geometry* geometry) { | |||
| 203 | assert(geometry); | 217 | assert(geometry); |
| 204 | assert(geometry->vao); | 218 | assert(geometry->vao); |
| 205 | glBindVertexArray(geometry->vao); | 219 | glBindVertexArray(geometry->vao); |
| 206 | if (geometry->indices) { | 220 | if (geometry->indices8) { |
| 207 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->indices->vbo); | 221 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->indices8->vbo); |
| 222 | glDrawElements( | ||
| 223 | geometry->mode, geometry->num_indices, GL_UNSIGNED_BYTE, | ||
| 224 | (const void*)geometry->indices_offset_bytes); | ||
| 225 | } else if (geometry->indices16) { | ||
| 226 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->indices16->vbo); | ||
| 208 | glDrawElements( | 227 | glDrawElements( |
| 209 | geometry->mode, geometry->num_indices, GL_UNSIGNED_SHORT, | 228 | geometry->mode, geometry->num_indices, GL_UNSIGNED_SHORT, |
| 210 | (const void*)geometry->indices_offset_bytes); | 229 | (const void*)geometry->indices_offset_bytes); |
diff --git a/gfx/src/render/geometry.h b/gfx/src/render/geometry.h index 38e716b..fb8f923 100644 --- a/gfx/src/render/geometry.h +++ b/gfx/src/render/geometry.h | |||
| @@ -27,7 +27,8 @@ typedef struct Geometry { | |||
| 27 | const Buffer* texcoords; | 27 | const Buffer* texcoords; |
| 28 | const Buffer* joints; | 28 | const Buffer* joints; |
| 29 | const Buffer* weights; | 29 | const Buffer* weights; |
| 30 | const Buffer* indices; | 30 | const Buffer* indices8; |
| 31 | const Buffer* indices16; | ||
| 31 | } Geometry; | 32 | } Geometry; |
| 32 | 33 | ||
| 33 | /// Create new geometry. | 34 | /// Create new geometry. |
diff --git a/gfx/src/util/scene.c b/gfx/src/util/scene.c index 6f34922..40d6686 100644 --- a/gfx/src/util/scene.c +++ b/gfx/src/util/scene.c | |||
| @@ -909,12 +909,33 @@ static bool load_meshes( | |||
| 909 | const cgltf_buffer_view* view = prim->indices->buffer_view; | 909 | const cgltf_buffer_view* view = prim->indices->buffer_view; |
| 910 | const cgltf_size buffer_index = view->buffer - data->buffers; | 910 | const cgltf_size buffer_index = view->buffer - data->buffers; |
| 911 | assert(buffer_index < data->buffers_count); | 911 | assert(buffer_index < data->buffers_count); |
| 912 | const Buffer* buffer = buffers[buffer_index]; | 912 | const Buffer* buffer = buffers[buffer_index]; |
| 913 | geometry_desc.indices.buffer = buffer; | 913 | const cgltf_size component_size = |
| 914 | geometry_desc.indices.offset_bytes = accessor->offset + view->offset; | 914 | get_component_size(accessor->component_type); |
| 915 | geometry_desc.indices.size_bytes = view->size; | 915 | switch (component_size) { |
| 916 | geometry_desc.indices.stride_bytes = view->stride; | 916 | case 1: { |
| 917 | geometry_desc.num_indices = prim->indices->count; | 917 | BufferViewIdx8* indices = &geometry_desc.indices8; |
| 918 | indices->buffer = buffer; | ||
| 919 | indices->offset_bytes = accessor->offset + view->offset; | ||
| 920 | indices->size_bytes = view->size; | ||
| 921 | indices->stride_bytes = view->stride; | ||
| 922 | geometry_desc.num_indices = prim->indices->count; | ||
| 923 | break; | ||
| 924 | } | ||
| 925 | case 2: { | ||
| 926 | BufferViewIdx16* indices = &geometry_desc.indices16; | ||
| 927 | indices->buffer = buffer; | ||
| 928 | indices->offset_bytes = accessor->offset + view->offset; | ||
| 929 | indices->size_bytes = view->size; | ||
| 930 | indices->stride_bytes = view->stride; | ||
| 931 | geometry_desc.num_indices = prim->indices->count; | ||
| 932 | break; | ||
| 933 | } | ||
| 934 | default: | ||
| 935 | // TODO: Handle 32-bit indices. | ||
| 936 | assert(false); | ||
| 937 | break; | ||
| 938 | } | ||
| 918 | } | 939 | } |
| 919 | 940 | ||
| 920 | // Vertex attributes. | 941 | // Vertex attributes. |
