summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2023-02-11 17:25:26 -0800
committer3gg <3gg@shellblade.net>2023-02-11 17:25:26 -0800
commit53582d2a90fb72e02056612163239b3b3f62eb4a (patch)
tree83f0d36f29272a88e110584abb69fd3d547637e8
parentc6e5f631ee26e97385fd5e2e980bad0b461e8953 (diff)
Add support for 8-bit vertex indices.
-rw-r--r--gfx/include/gfx/render_backend.h19
-rw-r--r--gfx/src/render/geometry.c43
-rw-r--r--gfx/src/render/geometry.h3
-rw-r--r--gfx/src/util/scene.c33
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.
30typedef uint16_t VertexIndex; 30typedef uint8_t VertexIndex8;
31typedef uint16_t VertexIndex16;
31typedef uint16_t VertexCount; 32typedef 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.
70MAKE_BUFFER_VIEW(BufferViewU16, uint16_t) 71MAKE_BUFFER_VIEW(BufferViewU16, uint16_t)
71 72
72/// A buffer view for vertex indices. 73/// A buffer view for 8-bit vertex indices.
73MAKE_BUFFER_VIEW(BufferViewIdx, uint16_t) 74MAKE_BUFFER_VIEW(BufferViewIdx8, uint16_t)
75
76/// A buffer view for 16-bit vertex indices.
77MAKE_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.