Initial commit;

This commit is contained in:
bjorn 2016-07-07 00:04:24 -07:00
commit 6a50fae9a3
11 changed files with 309 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.tup
lovr
src/obj

13
src/Tupfile Normal file
View File

@ -0,0 +1,13 @@
CFLAGS += -I /usr/local/Cellar/luajit/2.0.4/include/luajit-2.0
CFLAGS += -O2
CFLAGS += -Wall
LIBS += -L/usr/local/Cellar/luajit/2.0.4/lib
LIBS += -l luajit-5.1
LIBS += -l glfw3
LIBS += -l assimp
LIBS += -framework OpenGL
LIBS += -pagezero_size 10000 -image_base 100000000 # OSX magic
: foreach *.c |> clang -c %f -o %o $(CFLAGS) |> obj/%B.o
: obj/*.o |> clang -o %o %f $(LIBS) |> ../lovr

23
src/event.c Normal file
View File

@ -0,0 +1,23 @@
#include "event.h"
#include <GLFW/glfw3.h>
extern GLFWwindow* window;
int lovrEventPoll(lua_State* L) {
glfwPollEvents();
return 0;
}
int lovrEventQuit(lua_State* L) {
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
const luaL_Reg lovrEvent[] = {
{ "poll", lovrEventPoll },
{ "quit", lovrEventQuit },
{ NULL, NULL }
};

9
src/event.h Normal file
View File

@ -0,0 +1,9 @@
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int lovrEventPoll(lua_State* L);
int lovrEventQuit(lua_State* L);
extern const luaL_Reg lovrEvent[];

55
src/graphics.c Normal file
View File

@ -0,0 +1,55 @@
#include "graphics.h"
#include "util.h"
#include <GLFW/glfw3.h>
#include <assimp/cimport.h>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
extern GLFWwindow* window;
typedef const struct aiScene* Model;
int lovrGraphicsClear(lua_State* L) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
return 0;
}
int lovrGraphicsPresent(lua_State* L) {
glfwSwapBuffers(window);
return 0;
}
int lovrGraphicsNewModel(lua_State* L) {
const char* path = luaL_checkstring(L, -1);
Model model = aiImportFile(path, aiProcessPreset_TargetRealtime_MaxQuality);
if (model) {
Model* userdata = (Model*) luaPushType(L, "model");
*userdata = model;
} else {
// error
}
return 1;
}
const luaL_Reg lovrGraphics[] = {
{ "clear", lovrGraphicsClear },
{ "present", lovrGraphicsPresent },
{ "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 }
};

11
src/graphics.h Normal file
View File

@ -0,0 +1,11 @@
#include <stdlib.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
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[];

34
src/lovr.c Normal file
View File

@ -0,0 +1,34 @@
#include "lovr.h"
#include "util.h"
#include "graphics.h"
#include "event.h"
void lovrInit(lua_State* L) {
// Write top-level lovr global
lua_newtable(L);
lua_setglobal(L, "lovr");
// Register modules
luaRegisterModule(L, "event", lovrEvent);
luaRegisterModule(L, "graphics", lovrGraphics);
// Register types
luaRegisterType(L, "model", lovrModel);
// Run "main.lua" which will override/define pieces of lovr
if (luaL_dofile(L, "main.lua")) {
error("Failed to run main.lua");
lua_pop(L, 1);
exit(EXIT_FAILURE);
}
}
void lovrRun(lua_State* L) {
// lovr.run()
lua_getglobal(L, "lovr");
lua_getfield(L, -1, "run");
lua_call(L, 0, 0);
}

6
src/lovr.h Normal file
View File

@ -0,0 +1,6 @@
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
void lovrInit(lua_State* L);
void lovrRun(lua_State* L);

53
src/main.c Normal file
View File

@ -0,0 +1,53 @@
#define GLFW_INCLUDE_GLCOREARB
#include <stdio.h>
#include <stdlib.h>
#include <GLFW/glfw3.h>
#include <luajit.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include "util.h"
#include "lovr.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);
}
int main(int argc, char* argv[]) {
lua_State* L = luaL_newstate();
luaL_openlibs(L);
lovrInit(L);
initGlfw();
lovrRun(L);
return 0;
}

93
src/util.c Normal file
View File

@ -0,0 +1,93 @@
#include "util.h"
#include <stdarg.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
void error(const char* format, ...) {
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
fputs("\n", stderr);
va_end(args);
exit(EXIT_FAILURE);
}
char* loadFile(char* filename) {
struct stat info;
if (stat(filename, &info)) {
error("Could not stat '%s'", filename);
}
int size = (int)info.st_size;
char* buffer = malloc(size + 1);
int fd = open(filename, O_RDONLY);
if (fd < 0) {
error("Could not open '%s'", filename);
}
if (read(fd, buffer, size) < 0) {
error("Could not read '%s'", filename);
}
buffer[size] = '\0';
return buffer;
}
void luaRegisterModule(lua_State* L, const char* name, const luaL_Reg* module) {
// Get reference to lovr
lua_getglobal(L, "lovr");
// Create a table and fill it with the module functions
lua_newtable(L);
luaL_register(L, NULL, module);
// lovr[name] = module
lua_setfield(L, -2, name);
// Pop lovr
lua_pop(L, 1);
}
void luaRegisterType(lua_State* L, const char* name, const luaL_Reg* functions) {
// Push metatable
luaL_newmetatable(L, name);
lua_getmetatable(L, -1);
// m.__index = m
lua_pushvalue(L, -1);
lua_setfield(L, -1, "__index");
// m.name = name
lua_pushstring(L, "name");
lua_pushstring(L, name);
lua_settable(L, -3);
// Register class functions
if (functions) {
luaL_register(L, NULL, 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;
}

9
src/util.h Normal file
View File

@ -0,0 +1,9 @@
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
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);