diff --git a/src/api/types/mesh.c b/src/api/types/mesh.c index a96a53a0..c3b4dafc 100644 --- a/src/api/types/mesh.c +++ b/src/api/types/mesh.c @@ -27,14 +27,21 @@ void luax_checkmeshformat(lua_State* L, int index, MeshFormat* format) { } } -int l_lovrMeshDraw(lua_State* L) { +int l_lovrMeshDrawInstanced(lua_State* L) { Mesh* mesh = luax_checktype(L, 1, Mesh); + int instances = luaL_checkinteger(L, 2); float transform[16]; - luax_readtransform(L, 2, transform, 1); - lovrMeshDraw(mesh, transform, NULL); + luax_readtransform(L, 3, transform, 1); + lovrMeshDraw(mesh, transform, NULL, instances); return 0; } +int l_lovrMeshDraw(lua_State* L) { + lua_pushinteger(L, 1); + lua_insert(L, 2); + return l_lovrMeshDrawInstanced(L); +} + int l_lovrMeshGetVertexFormat(lua_State* L) { Mesh* mesh = luax_checktype(L, 1, Mesh); MeshFormat format = lovrMeshGetVertexFormat(mesh); @@ -400,6 +407,7 @@ int l_lovrMeshSetMaterial(lua_State* L) { } const luaL_Reg lovrMesh[] = { + { "drawInstanced", l_lovrMeshDrawInstanced }, { "draw", l_lovrMeshDraw }, { "getVertexFormat", l_lovrMeshGetVertexFormat }, { "getVertexCount", l_lovrMeshGetVertexCount }, diff --git a/src/api/types/model.c b/src/api/types/model.c index 35f6e12f..23b0702c 100644 --- a/src/api/types/model.c +++ b/src/api/types/model.c @@ -1,14 +1,21 @@ #include "api/lovr.h" #include "graphics/model.h" -int l_lovrModelDraw(lua_State* L) { +int l_lovrModelDrawInstanced(lua_State* L) { Model* model = luax_checktype(L, 1, Model); + int instances = luaL_checkinteger(L, 2); float transform[16]; - luax_readtransform(L, 2, transform, 1); - lovrModelDraw(model, transform); + luax_readtransform(L, 3, transform, 1); + lovrModelDraw(model, transform, instances); return 0; } +int l_lovrModelDraw(lua_State* L) { + lua_pushinteger(L, 1); + lua_insert(L, 2); + return l_lovrModelDrawInstanced(L); +} + int l_lovrModelGetAABB(lua_State* L) { Model* model = luax_checktype(L, 1, Model); const float* aabb = lovrModelGetAABB(model); @@ -72,6 +79,7 @@ int l_lovrModelGetMesh(lua_State* L) { } const luaL_Reg lovrModel[] = { + { "drawInstanced", l_lovrModelDrawInstanced }, { "draw", l_lovrModelDraw }, { "getAABB", l_lovrModelGetAABB }, { "getAnimator", l_lovrModelGetAnimator }, diff --git a/src/graphics/mesh.c b/src/graphics/mesh.c index 02cef417..ae436af7 100644 --- a/src/graphics/mesh.c +++ b/src/graphics/mesh.c @@ -128,7 +128,7 @@ void lovrMeshDestroy(const Ref* ref) { free(mesh); } -void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose) { +void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances) { if (mesh->isMapped) { lovrMeshUnmap(mesh); } @@ -147,9 +147,17 @@ void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose) { if (mesh->indexCount > 0) { count = mesh->isRangeEnabled ? mesh->rangeCount : mesh->indexCount; GLenum indexType = mesh->indexSize == sizeof(uint16_t) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT; - glDrawElements(mesh->drawMode, count, indexType, (GLvoid*) (start * mesh->indexSize)); + if (instances > 1) { + glDrawElementsInstanced(mesh->drawMode, count, indexType, (GLvoid*) (start * mesh->indexSize), instances); + } else { + glDrawElements(mesh->drawMode, count, indexType, (GLvoid*) (start * mesh->indexSize)); + } } else { - glDrawArrays(mesh->drawMode, start, count); + if (instances > 1) { + glDrawArraysInstanced(mesh->drawMode, start, count, instances); + } else { + glDrawArrays(mesh->drawMode, start, count); + } } if (transform) { diff --git a/src/graphics/mesh.h b/src/graphics/mesh.h index 8a854634..295d143b 100644 --- a/src/graphics/mesh.h +++ b/src/graphics/mesh.h @@ -61,7 +61,7 @@ typedef struct { Mesh* lovrMeshCreate(size_t count, MeshFormat* format, MeshDrawMode drawMode, MeshUsage usage); void lovrMeshDestroy(const Ref* ref); -void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose); +void lovrMeshDraw(Mesh* mesh, mat4 transform, float* pose, int instances); MeshFormat lovrMeshGetVertexFormat(Mesh* mesh); MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh); void lovrMeshSetDrawMode(Mesh* mesh, MeshDrawMode drawMode); diff --git a/src/graphics/model.c b/src/graphics/model.c index 485f5fce..b4b71d0c 100644 --- a/src/graphics/model.c +++ b/src/graphics/model.c @@ -4,7 +4,7 @@ #include "math/vec3.h" #include -static void renderNode(Model* model, int nodeIndex) { +static void renderNode(Model* model, int nodeIndex, int instances) { ModelNode* node = &model->modelData->nodes[nodeIndex]; if (node->primitives.length > 0) { @@ -38,14 +38,14 @@ static void renderNode(Model* model, int nodeIndex) { } lovrMeshSetDrawRange(model->mesh, primitive->drawStart, primitive->drawCount); - lovrMeshDraw(model->mesh, NULL, (float*) model->pose); + lovrMeshDraw(model->mesh, NULL, (float*) model->pose, instances); } lovrGraphicsPop(); } for (int i = 0; i < node->children.length; i++) { - renderNode(model, node->children.data[i]); + renderNode(model, node->children.data[i], instances); } } @@ -131,7 +131,7 @@ void lovrModelDestroy(const Ref* ref) { free(model); } -void lovrModelDraw(Model* model, mat4 transform) { +void lovrModelDraw(Model* model, mat4 transform, int instances) { if (model->modelData->nodeCount == 0) { return; } @@ -162,7 +162,7 @@ void lovrModelDraw(Model* model, mat4 transform) { lovrGraphicsPush(); lovrGraphicsMatrixTransform(MATRIX_MODEL, transform); - renderNode(model, 0); + renderNode(model, 0, instances); lovrGraphicsPop(); } diff --git a/src/graphics/model.h b/src/graphics/model.h index b0aae25e..cf6f5c42 100644 --- a/src/graphics/model.h +++ b/src/graphics/model.h @@ -26,7 +26,7 @@ typedef struct { Model* lovrModelCreate(ModelData* modelData); void lovrModelDestroy(const Ref* ref); -void lovrModelDraw(Model* model, mat4 transform); +void lovrModelDraw(Model* model, mat4 transform, int instances); Animator* lovrModelGetAnimator(Model* model); void lovrModelSetAnimator(Model* model, Animator* animator); int lovrModelGetAnimationCount(Model* model);