mirror of https://github.com/bjornbytes/lovr.git
Refactor MeshFormat;
This commit is contained in:
parent
031663c096
commit
ea7f3d48a2
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
|
@ -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;
|
Loading…
Reference in New Issue