Refactor MeshFormat;

This commit is contained in:
bjorn 2018-01-25 18:31:56 -08:00
parent 031663c096
commit ea7f3d48a2
8 changed files with 133 additions and 178 deletions

View File

@ -60,6 +60,8 @@ extern const luaL_Reg lovrTransform[];
extern const luaL_Reg lovrWorld[];
// Enums
extern map_int_t ArcModes;
extern map_int_t AttributeTypes;
extern map_int_t BlendAlphaModes;
extern map_int_t BlendModes;
extern map_int_t CanvasTypes;
@ -78,7 +80,6 @@ extern map_int_t JointTypes;
extern map_int_t MaterialColors;
extern map_int_t MaterialTextures;
extern map_int_t MatrixTypes;
extern map_int_t MeshAttributeTypes;
extern map_int_t MeshDrawModes;
extern map_int_t MeshUsages;
extern map_int_t PolygonWindings;
@ -89,7 +90,6 @@ extern map_int_t VerticalAligns;
extern map_int_t WrapModes;
// Shared helpers
void luax_checkmeshformat(lua_State* L, int index, MeshFormat* format);
int luax_readtransform(lua_State* L, int index, mat4 transform, bool uniformScale);
Blob* luax_readblob(lua_State* L, int index, const char* debug);
int luax_pushshape(lua_State* L, Shape* shape);

View File

@ -10,10 +10,12 @@
#include "data/rasterizer.h"
#include "data/texture.h"
#include "filesystem/filesystem.h"
#include "lib/vertex.h"
#include <math.h>
#include <stdbool.h>
map_int_t ArcModes;
map_int_t AttributeTypes;
map_int_t BlendAlphaModes;
map_int_t BlendModes;
map_int_t CanvasTypes;
@ -24,7 +26,6 @@ map_int_t HorizontalAligns;
map_int_t MaterialColors;
map_int_t MaterialTextures;
map_int_t MatrixTypes;
map_int_t MeshAttributeTypes;
map_int_t MeshDrawModes;
map_int_t MeshUsages;
map_int_t StencilActions;
@ -79,6 +80,33 @@ static void stencilCallback(void* userdata) {
lua_call(L, 0, 0);
}
static void luax_checkvertexformat(lua_State* L, int index, VertexFormat* format) {
if (!lua_istable(L, index)) {
return;
}
int length = lua_objlen(L, index);
for (int i = 0; i < length; i++) {
lua_rawgeti(L, index, i + 1);
if (!lua_istable(L, -1) || lua_objlen(L, -1) != 3) {
luaL_error(L, "Expected vertex format specified as tables containing name, data type, and size");
return;
}
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
lua_rawgeti(L, -3, 3);
const char* name = lua_tostring(L, -3);
AttributeType* type = (AttributeType*) luax_checkenum(L, -2, &AttributeTypes, "mesh attribute type");
int count = lua_tointeger(L, -1);
Attribute attribute = { .name = name, .type = *type, .count = count };
vec_push(format, attribute);
lua_pop(L, 4);
}
}
static TextureData* luax_checktexturedata(lua_State* L, int index) {
void** type;
if ((type = luax_totype(L, index, TextureData)) != NULL) {
@ -110,6 +138,11 @@ int l_lovrGraphicsInit(lua_State* L) {
map_set(&ArcModes, "open", ARC_MODE_OPEN);
map_set(&ArcModes, "closed", ARC_MODE_CLOSED);
map_init(&AttributeTypes);
map_set(&AttributeTypes, "float", ATTR_FLOAT);
map_set(&AttributeTypes, "byte", ATTR_BYTE);
map_set(&AttributeTypes, "int", ATTR_INT);
map_init(&BlendAlphaModes);
map_set(&BlendAlphaModes, "alphamultiply", BLEND_ALPHA_MULTIPLY);
map_set(&BlendAlphaModes, "premultiplied", BLEND_PREMULTIPLIED);
@ -162,11 +195,6 @@ int l_lovrGraphicsInit(lua_State* L) {
map_set(&MatrixTypes, "model", MATRIX_MODEL);
map_set(&MatrixTypes, "view", MATRIX_VIEW);
map_init(&MeshAttributeTypes);
map_set(&MeshAttributeTypes, "float", MESH_FLOAT);
map_set(&MeshAttributeTypes, "byte", MESH_BYTE);
map_set(&MeshAttributeTypes, "int", MESH_INT);
map_init(&MeshDrawModes);
map_set(&MeshDrawModes, "points", MESH_POINTS);
map_set(&MeshDrawModes, "lines", MESH_LINES);
@ -880,7 +908,7 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
int size;
int dataIndex = 0;
int drawModeIndex = 2;
MeshFormat format;
VertexFormat format;
vec_init(&format);
if (lua_isnumber(L, 1)) {
@ -888,12 +916,12 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
} else if (lua_istable(L, 1)) {
if (lua_isnumber(L, 2)) {
drawModeIndex++;
luax_checkmeshformat(L, 1, &format);
luax_checkvertexformat(L, 1, &format);
size = lua_tointeger(L, 2);
dataIndex = 0;
} else if (lua_istable(L, 2)) {
drawModeIndex++;
luax_checkmeshformat(L, 1, &format);
luax_checkvertexformat(L, 1, &format);
size = lua_objlen(L, 2);
dataIndex = 2;
} else {
@ -911,7 +939,7 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
if (dataIndex) {
int count = lua_objlen(L, dataIndex);
MeshFormat format = lovrMeshGetVertexFormat(mesh);
VertexFormat format = lovrMeshGetVertexFormat(mesh);
char* vertex = lovrMeshMap(mesh, 0, count, false, true);
for (int i = 0; i < count; i++) {
@ -922,25 +950,15 @@ int l_lovrGraphicsNewMesh(lua_State* L) {
int component = 0;
for (int j = 0; j < format.length; j++) {
MeshAttribute attribute = format.data[j];
Attribute attribute = format.data[j];
for (int k = 0; k < attribute.count; k++) {
lua_rawgeti(L, -1, ++component);
switch (attribute.type) {
case MESH_FLOAT:
*((float*) vertex) = luaL_optnumber(L, -1, 0.f);
vertex += sizeof(float);
break;
case MESH_BYTE:
*((uint8_t*) vertex) = luaL_optint(L, -1, 255);
vertex += sizeof(uint8_t);
break;
case MESH_INT:
*((int*) vertex) = luaL_optint(L, -1, 0);
vertex += sizeof(int);
break;
case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, -1, 0.f); break;
case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, -1, 255); break;
case ATTR_INT: *((int*) vertex) = luaL_optint(L, -1, 0); break;
}
vertex += AttributeSizes[attribute.type];
lua_pop(L, 1);
}
}

View File

@ -1,32 +1,5 @@
#include "api.h"
void luax_checkmeshformat(lua_State* L, int index, MeshFormat* format) {
if (!lua_istable(L, index)) {
return;
}
int length = lua_objlen(L, index);
for (int i = 0; i < length; i++) {
lua_rawgeti(L, index, i + 1);
if (!lua_istable(L, -1) || lua_objlen(L, -1) != 3) {
luaL_error(L, "Expected vertex format specified as tables containing name, data type, and size");
return;
}
lua_rawgeti(L, -1, 1);
lua_rawgeti(L, -2, 2);
lua_rawgeti(L, -3, 3);
const char* name = lua_tostring(L, -3);
MeshAttributeType* type = (MeshAttributeType*) luax_checkenum(L, -2, &MeshAttributeTypes, "mesh attribute type");
int count = lua_tointeger(L, -1);
MeshAttribute attribute = { .name = name, .type = *type, .count = count };
vec_push(format, attribute);
lua_pop(L, 4);
}
}
int l_lovrMeshDrawInstanced(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
int instances = luaL_checkinteger(L, 2);
@ -44,10 +17,10 @@ int l_lovrMeshDraw(lua_State* L) {
int l_lovrMeshGetVertexFormat(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
MeshFormat format = lovrMeshGetVertexFormat(mesh);
VertexFormat format = lovrMeshGetVertexFormat(mesh);
lua_newtable(L);
for (int i = 0; i < format.length; i++) {
MeshAttribute attribute = format.data[i];
Attribute attribute = format.data[i];
lua_newtable(L);
// Name
@ -55,7 +28,7 @@ int l_lovrMeshGetVertexFormat(lua_State* L) {
lua_rawseti(L, -2, 1);
// Type
luax_pushenum(L, &MeshAttributeTypes, attribute.type);
luax_pushenum(L, &AttributeTypes, attribute.type);
lua_rawseti(L, -2, 2);
// Count
@ -90,29 +63,19 @@ int l_lovrMeshGetVertex(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
int index = luaL_checkint(L, 2) - 1;
char* vertex = lovrMeshMap(mesh, index, 1, true, false);
MeshFormat format = lovrMeshGetVertexFormat(mesh);
VertexFormat format = lovrMeshGetVertexFormat(mesh);
int total = 0;
for (int i = 0; i < format.length; i++) {
MeshAttribute attribute = format.data[i];
Attribute attribute = format.data[i];
total += attribute.count;
for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) {
case MESH_FLOAT:
lua_pushnumber(L, *((float*) vertex));
vertex += sizeof(float);
break;
case MESH_BYTE:
lua_pushnumber(L, *((uint8_t*) vertex));
vertex += sizeof(uint8_t);
break;
case MESH_INT:
lua_pushnumber(L, *((int*) vertex));
vertex += sizeof(int);
break;
case ATTR_FLOAT: lua_pushnumber(L, *((float*) vertex)); break;
case ATTR_BYTE: lua_pushnumber(L, *((uint8_t*) vertex)); break;
case ATTR_INT: lua_pushnumber(L, *((int*) vertex)); break;
}
vertex += AttributeSizes[attribute.type];
}
}
@ -127,7 +90,7 @@ int l_lovrMeshSetVertex(lua_State* L) {
return luaL_error(L, "Invalid mesh vertex index: %d", index + 1);
}
MeshFormat format = lovrMeshGetVertexFormat(mesh);
VertexFormat format = lovrMeshGetVertexFormat(mesh);
char* vertex = lovrMeshMap(mesh, index, 1, false, true);
// Unwrap table
@ -140,24 +103,14 @@ int l_lovrMeshSetVertex(lua_State* L) {
}
for (int i = 0; i < format.length; i++) {
MeshAttribute attribute = format.data[i];
Attribute attribute = format.data[i];
for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) {
case MESH_FLOAT:
*((float*) vertex) = luaL_optnumber(L, arg++, 0.f);
vertex += sizeof(float);
break;
case MESH_BYTE:
*((uint8_t*) vertex) = luaL_optint(L, arg++, 255);
vertex += sizeof(uint8_t);
break;
case MESH_INT:
*((int*) vertex) = luaL_optint(L, arg++, 0);
vertex += sizeof(int);
break;
case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break;
case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, arg++, 255); break;
case ATTR_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break;
}
vertex += AttributeSizes[attribute.type];
}
}
@ -168,7 +121,7 @@ int l_lovrMeshGetVertexAttribute(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
int vertexIndex = luaL_checkint(L, 2) - 1;
int attributeIndex = luaL_checkint(L, 3) - 1;
MeshFormat format = lovrMeshGetVertexFormat(mesh);
VertexFormat format = lovrMeshGetVertexFormat(mesh);
if (vertexIndex < 0 || vertexIndex >= lovrMeshGetVertexCount(mesh)) {
return luaL_error(L, "Invalid mesh vertex index: %d", vertexIndex + 1);
@ -178,24 +131,19 @@ int l_lovrMeshGetVertexAttribute(lua_State* L) {
char* vertex = lovrMeshMap(mesh, vertexIndex, 1, true, false);
MeshAttribute attribute;
Attribute attribute;
for (int i = 0; i <= attributeIndex; i++) {
attribute = format.data[i];
if (i == attributeIndex) {
for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) {
case MESH_FLOAT: lua_pushnumber(L, *((float*) vertex)); break;
case MESH_BYTE: lua_pushinteger(L, *((uint8_t*) vertex)); break;
case MESH_INT: lua_pushinteger(L, *((int*) vertex)); break;
case ATTR_FLOAT: lua_pushnumber(L, *((float*) vertex)); break;
case ATTR_BYTE: lua_pushinteger(L, *((uint8_t*) vertex)); break;
case ATTR_INT: lua_pushinteger(L, *((int*) vertex)); break;
}
}
}
switch (attribute.type) {
case MESH_FLOAT: vertex += attribute.count * sizeof(float); break;
case MESH_BYTE: vertex += attribute.count * sizeof(uint8_t); break;
case MESH_INT: vertex += attribute.count * sizeof(int); break;
}
vertex += attribute.count * AttributeSizes[attribute.type];
}
return attribute.count;
@ -205,7 +153,7 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
int vertexIndex = luaL_checkint(L, 2) - 1;
int attributeIndex = luaL_checkint(L, 3) - 1;
MeshFormat format = lovrMeshGetVertexFormat(mesh);
VertexFormat format = lovrMeshGetVertexFormat(mesh);
if (vertexIndex < 0 || vertexIndex >= lovrMeshGetVertexCount(mesh)) {
return luaL_error(L, "Invalid mesh vertex index: %d", vertexIndex + 1);
@ -217,22 +165,17 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
int arg = 4;
for (int i = 0; i <= attributeIndex; i++) {
MeshAttribute attribute = format.data[i];
Attribute attribute = format.data[i];
if (i == attributeIndex) {
for (int j = 0; j < attribute.count; j++) {
switch (attribute.type) {
case MESH_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break;
case MESH_BYTE: *((unsigned char*) vertex) = luaL_optint(L, arg++, 255); break;
case MESH_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break;
case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, arg++, 0.f); break;
case ATTR_BYTE: *((unsigned char*) vertex) = luaL_optint(L, arg++, 255); break;
case ATTR_INT: *((int*) vertex) = luaL_optint(L, arg++, 0); break;
}
}
}
switch (attribute.type) {
case MESH_FLOAT: vertex += attribute.count * sizeof(float); break;
case MESH_BYTE: vertex += attribute.count * sizeof(uint8_t); break;
case MESH_INT: vertex += attribute.count * sizeof(int); break;
}
vertex += attribute.count * AttributeSizes[attribute.type];
}
return 0;
@ -240,7 +183,7 @@ int l_lovrMeshSetVertexAttribute(lua_State* L) {
int l_lovrMeshSetVertices(lua_State* L) {
Mesh* mesh = luax_checktype(L, 1, Mesh);
MeshFormat format = lovrMeshGetVertexFormat(mesh);
VertexFormat format = lovrMeshGetVertexFormat(mesh);
luaL_checktype(L, 2, LUA_TTABLE);
int vertexCount = lua_objlen(L, 2);
int start = luaL_optnumber(L, 3, 1) - 1;
@ -257,25 +200,15 @@ int l_lovrMeshSetVertices(lua_State* L) {
lua_rawgeti(L, 2, i + 1);
int component = 0;
for (int j = 0; j < format.length; j++) {
MeshAttribute attribute = format.data[j];
Attribute attribute = format.data[j];
for (int k = 0; k < attribute.count; k++) {
lua_rawgeti(L, -1, ++component);
switch (attribute.type) {
case MESH_FLOAT:
*((float*) vertex) = luaL_optnumber(L, -1, 0.f);
vertex += sizeof(float);
break;
case MESH_BYTE:
*((uint8_t*) vertex) = luaL_optint(L, -1, 255);
vertex += sizeof(uint8_t);
break;
case MESH_INT:
*((int*) vertex) = luaL_optint(L, -1, 0);
vertex += sizeof(int);
break;
case ATTR_FLOAT: *((float*) vertex) = luaL_optnumber(L, -1, 0.f); break;
case ATTR_BYTE: *((uint8_t*) vertex) = luaL_optint(L, -1, 255); break;
case ATTR_INT: *((int*) vertex) = luaL_optint(L, -1, 0); break;
}
vertex += AttributeSizes[attribute.type];
lua_pop(L, 1);
}
}

View File

@ -4,18 +4,6 @@
#include <stdlib.h>
#include <stdio.h>
static size_t getAttributeTypeSize(MeshAttributeType type) {
switch (type) {
case MESH_FLOAT:
case MESH_INT:
return 4;
case MESH_BYTE:
return 1;
default:
return 0;
}
}
static void lovrMeshBindAttributes(Mesh* mesh) {
Shader* shader = lovrGraphicsGetActiveShader();
if (shader == mesh->lastShader && !mesh->attributesDirty) {
@ -26,7 +14,7 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
size_t offset = 0;
int i;
MeshAttribute attribute;
Attribute attribute;
vec_foreach(&mesh->format, attribute, i) {
int location = lovrShaderGetAttributeId(shader, attribute.name);
@ -34,25 +22,26 @@ static void lovrMeshBindAttributes(Mesh* mesh) {
if (location >= 0) {
if (mesh->enabledAttributes & (1 << i)) {
glEnableVertexAttribArray(location);
GLenum attributeType = AttributeConstants[attribute.type];
if (attribute.type == MESH_INT) {
glVertexAttribIPointer(location, attribute.count, attribute.type, mesh->stride, (void*) offset);
if (attribute.type == ATTR_INT) {
glVertexAttribIPointer(location, attribute.count, attributeType, mesh->stride, (void*) offset);
} else {
glVertexAttribPointer(location, attribute.count, attribute.type, GL_TRUE, mesh->stride, (void*) offset);
glVertexAttribPointer(location, attribute.count, attributeType, GL_TRUE, mesh->stride, (void*) offset);
}
} else {
glDisableVertexAttribArray(location);
}
}
offset += getAttributeTypeSize(attribute.type) * attribute.count;
offset += AttributeSizes[attribute.type] * attribute.count;
}
mesh->lastShader = shader;
mesh->attributesDirty = false;
}
Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, MeshUsage usage) {
Mesh* lovrMeshCreate(size_t count, VertexFormat* format, MeshDrawMode drawMode, MeshUsage usage) {
Mesh* mesh = lovrAlloc(sizeof(Mesh), lovrMeshDestroy);
if (!mesh) return NULL;
@ -61,10 +50,10 @@ Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, Me
if (format) {
vec_extend(&mesh->format, format);
} else {
MeshAttribute position = { .name = "lovrPosition", .type = MESH_FLOAT, .count = 3 };
MeshAttribute normal = { .name = "lovrNormal", .type = MESH_FLOAT, .count = 3 };
MeshAttribute texCoord = { .name = "lovrTexCoord", .type = MESH_FLOAT, .count = 2 };
MeshAttribute vertexColor = { .name = "lovrVertexColor", .type = MESH_BYTE, .count = 4 };
Attribute position = { .name = "lovrPosition", .type = ATTR_FLOAT, .count = 3 };
Attribute normal = { .name = "lovrNormal", .type = ATTR_FLOAT, .count = 3 };
Attribute texCoord = { .name = "lovrTexCoord", .type = ATTR_FLOAT, .count = 2 };
Attribute vertexColor = { .name = "lovrVertexColor", .type = ATTR_BYTE, .count = 4 };
vec_push(&mesh->format, position);
vec_push(&mesh->format, normal);
vec_push(&mesh->format, texCoord);
@ -73,9 +62,9 @@ Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, Me
int stride = 0;
int i;
MeshAttribute attribute;
Attribute attribute;
vec_foreach(&mesh->format, attribute, i) {
stride += attribute.count * getAttributeTypeSize(attribute.type);
stride += attribute.count * AttributeSizes[attribute.type];
}
if (stride == 0) {
@ -160,7 +149,7 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances) {
}
}
MeshFormat lovrMeshGetVertexFormat(Mesh* mesh) {
VertexFormat lovrMeshGetVertexFormat(Mesh* mesh) {
return mesh->format;
}
@ -207,7 +196,7 @@ void lovrMeshSetVertexMap(Mesh* mesh, void* data, size_t count) {
bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) {
int i;
MeshAttribute attribute;
Attribute attribute;
vec_foreach(&mesh->format, attribute, i) {
if (!strcmp(attribute.name, name)) {
@ -220,7 +209,7 @@ bool lovrMeshIsAttributeEnabled(Mesh* mesh, const char* name) {
void lovrMeshSetAttributeEnabled(Mesh* mesh, const char* name, bool enable) {
int i;
MeshAttribute attribute;
Attribute attribute;
vec_foreach(&mesh->format, attribute, i) {
if (!strcmp(attribute.name, name)) {

View File

@ -3,6 +3,7 @@
#include "graphics/material.h"
#include "math/math.h"
#include "lib/glfw.h"
#include "lib/vertex.h"
#pragma once
@ -21,20 +22,6 @@ typedef enum {
MESH_STREAM = GL_STREAM_DRAW
} MeshUsage;
typedef enum {
MESH_FLOAT = GL_FLOAT,
MESH_BYTE = GL_UNSIGNED_BYTE,
MESH_INT = GL_INT
} MeshAttributeType;
typedef struct {
const char* name;
MeshAttributeType type;
int count;
} MeshAttribute;
typedef vec_t(MeshAttribute) MeshFormat;
typedef struct {
Ref ref;
void* data;
@ -45,7 +32,7 @@ typedef struct {
bool isMapped;
int mapStart;
size_t mapCount;
MeshFormat format;
VertexFormat format;
MeshDrawMode drawMode;
MeshUsage usage;
GLuint vao;
@ -61,10 +48,10 @@ typedef struct {
Shader* lastShader;
} Mesh;
Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, MeshUsage usage);
Mesh* lovrMeshCreate(size_t count, VertexFormat* format, MeshDrawMode drawMode, MeshUsage usage);
void lovrMeshDestroy(const Ref* ref);
void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances);
MeshFormat lovrMeshGetVertexFormat(Mesh* mesh);
VertexFormat lovrMeshGetVertexFormat(Mesh* mesh);
MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh);
void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode);
int lovrMeshGetVertexCount(Mesh* mesh);

View File

@ -59,32 +59,32 @@ Model* lovrModelCreate(ModelData* modelData) {
model->animator = NULL;
model->material = NULL;
MeshFormat format;
VertexFormat format;
vec_init(&format);
MeshAttribute attribute = { .name = "lovrPosition", .type = MESH_FLOAT, .count = 3 };
Attribute attribute = { .name = "lovrPosition", .type = ATTR_FLOAT, .count = 3 };
vec_push(&format, attribute);
if (modelData->hasNormals) {
MeshAttribute attribute = { .name = "lovrNormal", .type = MESH_FLOAT, .count = 3 };
Attribute attribute = { .name = "lovrNormal", .type = ATTR_FLOAT, .count = 3 };
vec_push(&format, attribute);
}
if (modelData->hasUVs) {
MeshAttribute attribute = { .name = "lovrTexCoord", .type = MESH_FLOAT, .count = 2 };
Attribute attribute = { .name = "lovrTexCoord", .type = ATTR_FLOAT, .count = 2 };
vec_push(&format, attribute);
}
if (modelData->hasVertexColors) {
MeshAttribute attribute = { .name = "lovrVertexColor", .type = MESH_BYTE, .count = 4 };
Attribute attribute = { .name = "lovrVertexColor", .type = ATTR_BYTE, .count = 4 };
vec_push(&format, attribute);
}
if (modelData->skinned) {
MeshAttribute bones = { .name = "lovrBones", .type = MESH_INT, .count = 4 };
Attribute bones = { .name = "lovrBones", .type = ATTR_INT, .count = 4 };
vec_push(&format, bones);
MeshAttribute weights = { .name = "lovrBoneWeights", .type = MESH_FLOAT, .count = 4 };
Attribute weights = { .name = "lovrBoneWeights", .type = ATTR_FLOAT, .count = 4 };
vec_push(&format, weights);
}

4
src/lib/vertex.c Normal file
View File

@ -0,0 +1,4 @@
#include "lib/vertex.h"
size_t AttributeSizes[] = { sizeof(float), sizeof(uint8_t), sizeof(int) };
GLenum AttributeConstants[] = { GL_FLOAT, GL_UNSIGNED_BYTE, GL_UNSIGNED_INT };

24
src/lib/vertex.h Normal file
View File

@ -0,0 +1,24 @@
#include <stdlib.h>
#include "lib/glfw.h"
#include "lib/vec/vec.h"
#pragma once
#define ATTRIBUTE_COUNT 3
size_t AttributeSizes[ATTRIBUTE_COUNT];
GLenum AttributeConstants[ATTRIBUTE_COUNT];
typedef enum {
ATTR_FLOAT,
ATTR_BYTE,
ATTR_INT
} AttributeType;
typedef struct {
const char* name;
AttributeType type;
int count;
} Attribute;
typedef vec_t(Attribute) VertexFormat;