From d20d70e695c4935dab85a8832206a12219b424dd Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Jul 2016 22:27:34 -0700 Subject: [PATCH] Model; --- src/event.c | 4 +- src/glfw.c | 28 +++++++ src/glfw.h | 6 ++ src/graphics.c | 29 ++------ src/graphics.h | 3 - src/lovr.c | 29 +++++++- src/lovr.h | 4 + src/main.c | 40 +--------- src/model.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++ src/model.h | 12 +++ src/util.c | 13 ---- src/util.h | 1 - 12 files changed, 287 insertions(+), 79 deletions(-) create mode 100644 src/glfw.c create mode 100644 src/glfw.h create mode 100644 src/model.c create mode 100644 src/model.h diff --git a/src/event.c b/src/event.c index 5ee04318..173ce8fd 100644 --- a/src/event.c +++ b/src/event.c @@ -1,4 +1,5 @@ #include "event.h" +#include "lovr.h" #include extern GLFWwindow* window; @@ -10,8 +11,7 @@ int lovrEventPoll(lua_State* L) { } int lovrEventQuit(lua_State* L) { - glfwDestroyWindow(window); - glfwTerminate(); + lovrDestroy(); return 0; } diff --git a/src/glfw.c b/src/glfw.c new file mode 100644 index 00000000..f810cd05 --- /dev/null +++ b/src/glfw.c @@ -0,0 +1,28 @@ +#include "glfw.h" +#include +#include "lovr.h" +#include "util.h" + +void initGlfw() { + glfwSetErrorCallback(lovrOnError); + + if (!glfwInit()) { + error("Error initializing glfw"); + } + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); + + // TODO make configurable + window = glfwCreateWindow(800, 600, "Window", NULL, NULL); + + if (!window) { + glfwTerminate(); + exit(EXIT_FAILURE); + } + + glfwSetWindowCloseCallback(window, lovrOnClose); + glfwMakeContextCurrent(window); +} diff --git a/src/glfw.h b/src/glfw.h new file mode 100644 index 00000000..f6393091 --- /dev/null +++ b/src/glfw.h @@ -0,0 +1,6 @@ +#define GLFW_INCLUDE_GLCOREARB +#include + +GLFWwindow* window; + +void initGlfw(); diff --git a/src/graphics.c b/src/graphics.c index 3e0b88d9..2824a89c 100644 --- a/src/graphics.c +++ b/src/graphics.c @@ -1,13 +1,11 @@ +#include "glfw.h" #include "graphics.h" +#include "model.h" #include "util.h" -#include #include #include #include -extern GLFWwindow* window; -typedef const struct aiScene* Model; - int lovrGraphicsClear(lua_State* L) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -22,13 +20,13 @@ int lovrGraphicsPresent(lua_State* L) { int lovrGraphicsNewModel(lua_State* L) { const char* path = luaL_checkstring(L, -1); - Model model = aiImportFile(path, aiProcessPreset_TargetRealtime_MaxQuality); + const struct aiScene* scene = aiImportFile(path, aiProcessPreset_TargetRealtime_MaxQuality); - if (model) { - Model* userdata = (Model*) luaPushType(L, "model"); - *userdata = model; + if (scene) { + Model* model = scene->mMeshes[0]; + luax_pushmodel(L, model); } else { - // error + lua_pushnil(L); } return 1; @@ -40,16 +38,3 @@ const luaL_Reg lovrGraphics[] = { { "newModel", lovrGraphicsNewModel }, { NULL, NULL } }; - -int lovrModelGetVertexCount(lua_State* L) { - const struct aiScene* scene = *(const struct aiScene**) luaL_checkudata(L, -1, "model"); - - lua_pushnumber(L, scene->mMeshes[0]->mNumVertices); - - return 1; -} - -const luaL_Reg lovrModel[] = { - { "getVertexCount", lovrModelGetVertexCount }, - { NULL, NULL } -}; diff --git a/src/graphics.h b/src/graphics.h index d82717f7..cf6eccad 100644 --- a/src/graphics.h +++ b/src/graphics.h @@ -1,4 +1,3 @@ -#include #include #include #include @@ -6,6 +5,4 @@ int lovrGraphicsClear(lua_State* L); int lovrGraphicsPresent(lua_State* L); int lovrGraphicsNewModel(lua_State* L); - extern const luaL_Reg lovrGraphics[]; -extern const luaL_Reg lovrModel[]; diff --git a/src/lovr.c b/src/lovr.c index 72e07fe3..f1471047 100644 --- a/src/lovr.c +++ b/src/lovr.c @@ -2,8 +2,11 @@ #include "util.h" #include "graphics.h" +#include "model.h" #include "event.h" +extern lua_State* L; + void lovrInit(lua_State* L) { // Write top-level lovr global @@ -15,7 +18,7 @@ void lovrInit(lua_State* L) { luaRegisterModule(L, "graphics", lovrGraphics); // Register types - luaRegisterType(L, "model", lovrModel); + luaRegisterType(L, "Model", lovrModel); // Run "main.lua" which will override/define pieces of lovr if (luaL_dofile(L, "main.lua")) { @@ -25,6 +28,11 @@ void lovrInit(lua_State* L) { } } +void lovrDestroy() { + glfwTerminate(); + exit(EXIT_SUCCESS); +} + void lovrRun(lua_State* L) { // lovr.run() @@ -32,3 +40,22 @@ void lovrRun(lua_State* L) { lua_getfield(L, -1, "run"); lua_call(L, 0, 0); } + +void lovrOnError(int code, const char* description) { + error(description); +} + +void lovrOnClose(GLFWwindow* _window) { + if (_window == window) { + + // lovr.quit() + lua_getglobal(L, "lovr"); + lua_getfield(L, -1, "quit"); + lua_call(L, 0, 0); + + if (glfwWindowShouldClose(window)) { + glfwDestroyWindow(window); + lovrDestroy(); + } + } +} diff --git a/src/lovr.h b/src/lovr.h index e27064e1..2b4e3362 100644 --- a/src/lovr.h +++ b/src/lovr.h @@ -1,6 +1,10 @@ #include #include #include +#include "glfw.h" void lovrInit(lua_State* L); +void lovrDestroy(); void lovrRun(lua_State* L); +void lovrOnError(int code, const char* description); +void lovrOnClose(GLFWwindow* window); diff --git a/src/main.c b/src/main.c index 6f08b4a3..736b34d8 100644 --- a/src/main.c +++ b/src/main.c @@ -1,47 +1,13 @@ -#define GLFW_INCLUDE_GLCOREARB - -#include -#include -#include #include #include -#include -#include -#include "util.h" #include "lovr.h" +#include "glfw.h" -GLFWwindow* window; - -void onError(int code, const char* description) { - error(description); -} - -void initGlfw() { - glfwSetErrorCallback(onError); - - if (!glfwInit()) { - error("Error initializing glfw"); - } - - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - - // TODO make configurable - window = glfwCreateWindow(800, 600, "Window", NULL, NULL); - - if (!window) { - glfwTerminate(); - exit(EXIT_FAILURE); - } - - glfwMakeContextCurrent(window); -} +lua_State* L; int main(int argc, char* argv[]) { - lua_State* L = luaL_newstate(); + L = luaL_newstate(); luaL_openlibs(L); lovrInit(L); diff --git a/src/model.c b/src/model.c new file mode 100644 index 00000000..07f94121 --- /dev/null +++ b/src/model.c @@ -0,0 +1,197 @@ +#include "model.h" +#include "util.h" +#include + +void luax_pushmodel(lua_State* L, Model* model) { + Model** userdata = (Model**) lua_newuserdata(L, sizeof(Model*)); + + luaL_getmetatable(L, "Model"); + lua_setmetatable(L, -2); + + *userdata = model; +} + +Model* luax_checkmodel(lua_State* L, int index) { + return *(Model**) luaL_checkudata(L, index, "Model"); +} + +int lovrModelDraw(lua_State* L) { + Model* model = luax_checkmodel(L, 1); + + float x = luaL_checknumber(L, 2); + float y = luaL_checknumber(L, 3); + float z = luaL_checknumber(L, 4); + + if (model) { + printf("I just drew your fuckign model at %f %f %f\n", x, y, z); + } + + return 0; +} + +int lovrModelGetVertexCount(lua_State* L) { + Model* model = luax_checkmodel(L, 1); + + lua_pushinteger(L, model->mNumVertices); + + return 1; +} + +int lovrModelGetColors(lua_State* L) { + Model* model = luax_checkmodel(L, 1); + int colorSetIndex = 0; + + if (lua_gettop(L) > 1) { + colorSetIndex = luaL_checkinteger(L, 2); + } + + if (colorSetIndex >= AI_MAX_NUMBER_OF_COLOR_SETS || !model->mColors[colorSetIndex]) { + lua_pushnil(L); + + return 1; + } + + struct aiColor4D* colorSet = model->mColors[colorSetIndex]; + + lua_createtable(L, model->mNumVertices, 0); + + for (int i = 0; i < model->mNumVertices; i++) { + lua_createtable(L, 4, 0); + + lua_pushnumber(L, colorSet[i].r); + lua_rawseti(L, -2, 1); + + lua_pushnumber(L, colorSet[i].g); + lua_rawseti(L, -2, 2); + + lua_pushnumber(L, colorSet[i].b); + lua_rawseti(L, -2, 3); + + lua_pushnumber(L, colorSet[i].a); + lua_rawseti(L, -2, 4); + + lua_rawseti(L, -1, i); + } + + return 1; +} + +int lovrModelGetNormals(lua_State* L) { + Model* model = luax_checkmodel(L, 1); + + if (!model->mNormals) { + lua_pushnil(L); + + return 1; + } + + lua_createtable(L, model->mNumVertices, 0); + + for (int i = 0; i < model->mNumVertices; i++) { + lua_createtable(L, 3, 0); + + lua_pushnumber(L, model->mNormals[i].x); + lua_rawseti(L, -2, 1); + + lua_pushnumber(L, model->mNormals[i].y); + lua_rawseti(L, -2, 2); + + lua_pushnumber(L, model->mNormals[i].z); + lua_rawseti(L, -2, 3); + + lua_rawseti(L, -2, i); + } + + return 1; +} + +int lovrModelGetTangents(lua_State* L) { + Model* model = luax_checkmodel(L, 1); + + if (!model->mTangents) { + lua_pushnil(L); + + return 1; + } + + lua_createtable(L, model->mNumFaces, 0); + + for (int i = 0; i < model->mNumFaces; i++) { + lua_createtable(L, 3, 0); + + lua_pushnumber(L, model->mTangents[i].x); + lua_rawseti(L, -2, 1); + + lua_pushnumber(L, model->mTangents[i].y); + lua_rawseti(L, -2, 2); + + lua_pushnumber(L, model->mTangents[i].z); + lua_rawseti(L, -2, 3); + + lua_rawseti(L, -2, i); + } + + return 1; +} + +int lovrModelGetUVs(lua_State* L) { + Model* model = luax_checkmodel(L, 1); + int uvSetIndex = 0; + + if (lua_gettop(L) > 1) { + uvSetIndex = luaL_checkinteger(L, 2); + } + + if (uvSetIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS || !model->mTextureCoords[uvSetIndex]) { + lua_pushnil(L); + + return 1; + } + + struct aiVector3D* uvSet = model->mTextureCoords[uvSetIndex]; + + lua_createtable(L, model->mNumVertices, 0); + + for (int i = 0; i < model->mNumVertices; i++) { + lua_createtable(L, 4, 0); + + lua_pushnumber(L, uvSet->x); + lua_rawseti(L, -2, 1); + + lua_pushnumber(L, uvSet->y); + lua_rawseti(L, -2, 2); + + lua_pushnumber(L, uvSet->z); + lua_rawseti(L, -2, 3); + + lua_rawseti(L, -1, i); + } + + return 1; +} + +int lovrModelGetVertex(lua_State* L) { + Model* model = luax_checkmodel(L, 1); + int index = luaL_checkint(L, 2); + + lua_createtable(L, 3, 0); + lua_pushnumber(L, model->mVertices[index].x); + lua_rawseti(L, -2, 1); + lua_pushnumber(L, model->mVertices[index].y); + lua_rawseti(L, -2, 2); + lua_pushnumber(L, model->mVertices[index].z); + lua_rawseti(L, -2, 3); + + return 1; +} + +const luaL_Reg lovrModel[] = { + { "draw", lovrModelDraw }, + { "getVertexCount", lovrModelGetVertexCount }, + { "getColors", lovrModelGetColors }, + { "getNormals", lovrModelGetNormals }, + { "getTangents", lovrModelGetTangents }, + { "getUVs", lovrModelGetUVs }, + { "getVertex", lovrModelGetVertex }, + { NULL, NULL } +}; diff --git a/src/model.h b/src/model.h new file mode 100644 index 00000000..cef4693c --- /dev/null +++ b/src/model.h @@ -0,0 +1,12 @@ +#include +#include +#include + +typedef const struct aiMesh Model; +void luax_pushmodel(lua_State* L, Model* model); +Model* luax_checkmodel(lua_State* L, int index); + +int lovrModelDraw(lua_State* L); +int lovrModelGetVertexCount(lua_State* L); +int lovrModelGetVertexColors(lua_State* L); +extern const luaL_Reg lovrModel[]; diff --git a/src/util.c b/src/util.c index 1927721c..d0bb7e3a 100644 --- a/src/util.c +++ b/src/util.c @@ -78,16 +78,3 @@ void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions) // Pop metatable lua_pop(L, 1); } - -void* luaPushType(lua_State* L, const char* type) { - - // Allocate space for a single pointer - void* userdata = (void*) lua_newuserdata(L, sizeof(void*)); - - // Set the metatable of the userdata to the desired type - luaL_getmetatable(L, type); - lua_setmetatable(L, -2); - - // Return the pointer to the object - return userdata; -} diff --git a/src/util.h b/src/util.h index 31d9577f..fb210d48 100644 --- a/src/util.h +++ b/src/util.h @@ -6,4 +6,3 @@ 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* luaPushType(lua_State* L, const char* type);