int l_bufferobject_new(lua_State* L) { if (!context_available()) return luaL_error(L, "No OpenGL context available. Create a window first."); assert_extension(L, ARB_vertex_buffer_object); GLenum target = GL_ARRAY_BUFFER; GLenum usage = GL_STATIC_DRAW; GLenum element_type = GL_FLOAT; int top = lua_gettop(L); if (!lua_istable(L, top)) return luaL_typerror(L, top, "table"); if (top > 1) target = luaL_checkinteger(L, 1); if (top > 2) usage = luaL_checkinteger(L, 2); if (top > 3) element_type = luaL_checkinteger(L, 3); switch (target) { case GL_ARRAY_BUFFER: case GL_COPY_READ_BUFFER: case GL_COPY_WRITE_BUFFER: case GL_ELEMENT_ARRAY_BUFFER: case GL_PIXEL_PACK_BUFFER: case GL_PIXEL_UNPACK_BUFFER: case GL_TEXTURE_BUFFER: case GL_TRANSFORM_FEEDBACK_BUFFER: case GL_UNIFORM_BUFFER: break; default: return luaL_error(L, "Invalid buffer target"); } switch (usage) { case GL_STREAM_DRAW: case GL_STREAM_READ: case GL_STREAM_COPY: case GL_STATIC_DRAW: case GL_STATIC_READ: case GL_STATIC_COPY: case GL_DYNAMIC_DRAW: case GL_DYNAMIC_READ: case GL_DYNAMIC_COPY: break; default: return luaL_error(L, "Invalid buffer usage"); } bufferobject* b = (bufferobject*)lua_newuserdata(L, sizeof(bufferobject)); if (NULL == b) return luaL_error(L, "Out of memory"); GLuint id; glGenBuffers(1, &id); b->id = id; b->target = target; b->usage = usage; b->count = 0; b->element_type = element_type; while (GL_NO_ERROR != glGetError()) /*clear error flags*/; fill_buffer_with_table(L, b, top, 0); if (GL_NO_ERROR != glGetError()) { glDeleteBuffers(1, &(id)); return luaL_error(L, "Unable to create data storage"); } if (luaL_newmetatable(L, INTERNAL_NAME)) { luaL_reg meta[] = { {"__gc", l_bufferobject___gc}, {"update", l_bufferobject_update}, {"draw", l_bufferobject_draw}, {NULL, NULL} }; l_registerFunctions(L, -1, meta); lua_pushvalue(L, -1); lua_setfield(L, -1, "__index"); } lua_setmetatable(L, -2); return 1; }
int l_window_new(lua_State* L) { const char* name = luaL_checkstring(L, 1); int w = luaL_checkinteger(L, 2); int h = luaL_checkinteger(L, 3); int x = luaL_optinteger(L, 4, -1); int y = luaL_optinteger(L, 5, -1); Window* win = (Window*)lua_newuserdata(L, sizeof(Window)); if (NULL == win) return luaL_error(L, "Cannot create window: Out of memory."); glutInitWindowSize(w,h); glutInitWindowPosition(x,y); win->id = glutCreateWindow(name); LUA = L; glutSetWindow(win->id); glutDisplayFunc(_draw); glutReshapeFunc(_reshape); glutIdleFunc(_update); glutVisibilityFunc(_visibility); glutKeyboardFunc(_keyboard); glutSpecialFunc(_special); glutMouseFunc(_mouse); glutMotionFunc(_motion); glutPassiveMotionFunc(_passiveMotion); glutEntryFunc(_entry); if (!context_available()) { GLenum glew_status = glewInit(); if (GLEW_OK != glew_status) return luaL_error(L, "Error initializing GLEW: %s", glewGetErrorString(glew_status)); // check for opengl 3.3 if (!GLEW_VERSION_3_3) return luaL_error(L, "OpenGL version too old"); context_set_available(); } if (luaL_newmetatable(L, INTERNAL_NAME)) { lua_pushcfunction(L, l_window___index); lua_setfield(L, -2, "__index"); lua_pushcfunction(L, l_window___newindex); lua_setfield(L, -2, "__newindex"); luaL_Reg reg[] = { {"__gc", l_window___gc}, {"destroy", l_window_destroy}, {"redraw", l_window_redraw}, {"swap", l_window_swap}, {"position", l_window_position}, {"resize", l_window_resize}, {"fullscreen", l_window_fullscreen}, {"show", l_window_show}, {"hide", l_window_hide}, {"iconify", l_window_iconify}, {"title", l_window_title}, {"cursor", l_window_cursor}, {NULL, NULL} }; l_registerFunctions(L, -1, reg); } lua_setmetatable(L, -2); // create callback table luaL_newmetatable(L, CALLBACKS_NAME); lua_newtable(L); lua_rawseti(L, -2, win->id); lua_pop(L, 1); return 1; }