diff --git a/src/graphics/buffer.c b/src/graphics/buffer.c index bf299121..851f1d53 100644 --- a/src/graphics/buffer.c +++ b/src/graphics/buffer.c @@ -1,4 +1,5 @@ #include "buffer.h" +#include void luax_pushbuffer(lua_State* L, Buffer* buffer) { Buffer** userdata = (Buffer**) lua_newuserdata(L, sizeof(Buffer*)); @@ -11,6 +12,15 @@ Buffer* luax_checkbuffer(lua_State* L, int index) { return *(Buffer**) luaL_checkudata(L, index, "Buffer"); } +int luax_destroybuffer(lua_State* L) { + Buffer* buffer = luax_checkbuffer(L, 1); + glDeleteBuffers(1, &buffer->vbo); + glDeleteVertexArrays(1, &buffer->vao); + free(buffer->data); + free(buffer); + return 0; +} + int lovrBufferDraw(lua_State* L) { Buffer* buffer = luax_checkbuffer(L, 1); @@ -41,8 +51,20 @@ int lovrBufferSetVertex(lua_State* L) { return 0; } +int lovrBufferGetVertex(lua_State* L) { + Buffer* buffer = luax_checkbuffer(L, 1); + int index = luaL_checkint(L, 2) - 1; + + lua_pushnumber(L, buffer->data[3 * index + 0]); + lua_pushnumber(L, buffer->data[3 * index + 1]); + lua_pushnumber(L, buffer->data[3 * index + 2]); + + return 3; +} + const luaL_Reg lovrBuffer[] = { { "draw", lovrBufferDraw }, { "setVertex", lovrBufferSetVertex }, + { "getVertex", lovrBufferGetVertex }, { NULL, NULL } }; diff --git a/src/graphics/buffer.h b/src/graphics/buffer.h index 0ead4b5a..ed179553 100644 --- a/src/graphics/buffer.h +++ b/src/graphics/buffer.h @@ -12,8 +12,10 @@ typedef struct { void luax_pushbuffer(lua_State* L, Buffer* buffer); Buffer* luax_checkbuffer(lua_State* L, int index); +int luax_destroybuffer(lua_State* L); int lovrBufferDraw(lua_State* L); int lovrBufferSetVertex(lua_State* L); +int lovrBufferGetVertex(lua_State* L); extern const luaL_Reg lovrBuffer[]; diff --git a/src/graphics/graphics.c b/src/graphics/graphics.c index 878380a6..ba135a01 100644 --- a/src/graphics/graphics.c +++ b/src/graphics/graphics.c @@ -73,9 +73,9 @@ int lovrGraphicsNewModel(lua_State* L) { int lovrGraphicsNewBuffer(lua_State* L) { int size = luaL_checkint(L, 1); - Buffer* buffer = (Buffer*) malloc(sizeof(Buffer)); + Buffer* buffer = malloc(sizeof(Buffer)); - buffer->data = (GLfloat*) malloc(size * 3 * sizeof(GLfloat)); + buffer->data = malloc(size * 3 * sizeof(GLfloat)); glGenBuffers(1, &buffer->vbo); glBindBuffer(GL_ARRAY_BUFFER, buffer->vbo); @@ -123,8 +123,8 @@ const luaL_Reg lovrGraphics[] = { int lovrInitGraphics(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrGraphics); - luaRegisterType(L, "Model", lovrModel); - luaRegisterType(L, "Buffer", lovrBuffer); - luaRegisterType(L, "Shader", lovrShader); + luaRegisterType(L, "Model", lovrModel, NULL); + luaRegisterType(L, "Buffer", lovrBuffer, luax_destroybuffer); + luaRegisterType(L, "Shader", lovrShader, luax_destroyshader); return 1; } diff --git a/src/graphics/shader.c b/src/graphics/shader.c index e2481b83..1f1789ab 100644 --- a/src/graphics/shader.c +++ b/src/graphics/shader.c @@ -13,6 +13,13 @@ Shader* luax_checkshader(lua_State* L, int index) { return *(Shader**) luaL_checkudata(L, index, "Shader"); } +int luax_destroyshader(lua_State* L) { + Shader* shader = luax_checkshader(L, 1); + glDeleteProgram(shader->id); + free(shader); + return 0; +} + GLuint compileShader(GLenum type, const char* source) { GLuint shader = glCreateShader(type); @@ -57,7 +64,9 @@ GLuint linkShaders(GLuint vertexShader, GLuint fragmentShader) { error(log); } + glDetachShader(shader, vertexShader); glDeleteShader(vertexShader); + glDetachShader(shader, fragmentShader); glDeleteShader(fragmentShader); return shader; diff --git a/src/graphics/shader.h b/src/graphics/shader.h index f07bb56c..89d7a495 100644 --- a/src/graphics/shader.h +++ b/src/graphics/shader.h @@ -9,6 +9,7 @@ typedef struct { void luax_pushshader(lua_State* L, Shader* shader); Shader* luax_checkshader(lua_State* L, int index); +int luax_destroyshader(lua_State* L); GLuint compileShader(GLuint type, const char* filename); GLuint linkShaders(GLuint vertexShader, GLuint fragmentShader); diff --git a/src/joystick/joystick.c b/src/joystick/joystick.c index 0b47496f..26dbe95e 100644 --- a/src/joystick/joystick.c +++ b/src/joystick/joystick.c @@ -15,6 +15,24 @@ Joystick* luax_checkjoystick(lua_State* L, int index) { return *(Joystick**) luaL_checkudata(L, index, "Joystick"); } +int luax_destroyjoystick(lua_State* L) { + Joystick* joystick = luax_checkjoystick(L, 1); + + if (joystick->isTracked) { + osvrClientFreeInterface(ctx, *joystick->osvrTrackerInterface); + + for (int i = 0; i < sizeof(joystick->osvrButtonInterfaces); i++) { + osvrClientFreeInterface(ctx, *joystick->osvrButtonInterfaces[i]); + } + + for (int i = 0; i < sizeof(joystick->osvrAxisInterfaces); i++) { + osvrClientFreeInterface(ctx, *joystick->osvrAxisInterfaces[i]); + } + } + + // The joystick itself is never freed +} + static unsigned char lovrJoystickGetButtonState(Joystick* joystick, int buttonIndex) { if (joystick->isTracked) { OSVR_TimeValue timestamp; @@ -43,20 +61,6 @@ static float lovrJoystickGetAxisState(Joystick* joystick, int axisIndex) { } } -void lovrJoystickDestroy(Joystick* joystick) { - if (joystick->isTracked) { - osvrClientFreeInterface(ctx, *joystick->osvrTrackerInterface); - - for (int i = 0; i < sizeof(joystick->osvrButtonInterfaces); i++) { - osvrClientFreeInterface(ctx, *joystick->osvrButtonInterfaces[i]); - } - - for (int i = 0; i < sizeof(joystick->osvrAxisInterfaces); i++) { - osvrClientFreeInterface(ctx, *joystick->osvrAxisInterfaces[i]); - } - } -} - int lovrJoystickIsConnected(Joystick* joystick) { if (joystick == NULL) { return 0; diff --git a/src/joystick/joystick.h b/src/joystick/joystick.h index edd2533a..81183e6c 100644 --- a/src/joystick/joystick.h +++ b/src/joystick/joystick.h @@ -13,8 +13,8 @@ typedef struct { void luax_pushjoystick(lua_State* L, Joystick* joystick); Joystick* luax_checkjoystick(lua_State* L, int index); +int luax_destroyjoystick(lua_State* L); -void lovrJoystickDestroy(Joystick* joystick); int lovrJoystickIsConnected(Joystick* joystick); int lovrJoystickGetAngularAcceleration(lua_State* L); diff --git a/src/joystick/joysticks.c b/src/joystick/joysticks.c index 1dd8f4b3..87a28622 100644 --- a/src/joystick/joysticks.c +++ b/src/joystick/joysticks.c @@ -67,7 +67,7 @@ const luaL_Reg lovrJoysticks[] = { int lovrInitJoysticks(lua_State* L) { lua_newtable(L); luaL_register(L, NULL, lovrJoysticks); - luaRegisterType(L, "Joystick", lovrJoystick); + luaRegisterType(L, "Joystick", lovrJoystick, luax_destroyjoystick); glfwSetJoystickCallback(lovrJoysticksOnJoystickChanged); for (int i = GLFW_JOYSTICK_1; i <= GLFW_JOYSTICK_LAST; i++) { diff --git a/src/util.c b/src/util.c index 85ebd92f..713c1754 100644 --- a/src/util.c +++ b/src/util.c @@ -68,7 +68,7 @@ void luaRegisterModule(lua_State* L, const char* name, const luaL_Reg* module) { lua_pop(L, 1); } -void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions) { +void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions, lua_CFunction gc) { // Push metatable luaL_newmetatable(L, name); @@ -78,10 +78,15 @@ void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions) lua_pushvalue(L, -1); lua_setfield(L, -1, "__index"); + // m.__gc = gc + if (gc) { + lua_pushcfunction(L, gc); + lua_setfield(L, -2, "__gc"); + } + // m.name = name - lua_pushstring(L, "name"); lua_pushstring(L, name); - lua_settable(L, -3); + lua_setfield(L, -2, "name"); // Register class functions if (functions) { diff --git a/src/util.h b/src/util.h index e464efb1..6d889d8f 100644 --- a/src/util.h +++ b/src/util.h @@ -5,5 +5,5 @@ void error(const char* format, ...); char* loadFile(char* filename); void luaRegisterModule(lua_State* L, const char* name, const luaL_Reg* module); -void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions); +void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions, lua_CFunction gc); int luaPreloadModule(lua_State* L, const char* key, lua_CFunction f);