2016-08-10 06:28:17 +00:00
|
|
|
#include "graphics.h"
|
|
|
|
#include "buffer.h"
|
|
|
|
#include "model.h"
|
|
|
|
#include "shader.h"
|
|
|
|
#include "../graphics/graphics.h"
|
|
|
|
#include "../util.h"
|
|
|
|
|
|
|
|
const luaL_Reg lovrGraphics[] = {
|
2016-09-28 03:20:08 +00:00
|
|
|
{ "reset", l_lovrGraphicsReset },
|
2016-08-10 06:28:17 +00:00
|
|
|
{ "clear", l_lovrGraphicsClear },
|
|
|
|
{ "present", l_lovrGraphicsPresent },
|
2016-09-28 04:37:46 +00:00
|
|
|
{ "getBackgroundColor", l_lovrGraphicsGetBackgroundColor },
|
|
|
|
{ "setBackgroundColor", l_lovrGraphicsSetBackgroundColor },
|
2016-09-29 03:11:58 +00:00
|
|
|
{ "getColor", l_lovrGraphicsGetColor },
|
|
|
|
{ "setColor", l_lovrGraphicsSetColor },
|
2016-09-28 04:32:57 +00:00
|
|
|
{ "getColorMask", l_lovrGraphicsGetColorMask },
|
|
|
|
{ "setColorMask", l_lovrGraphicsSetColorMask },
|
2016-09-29 04:47:36 +00:00
|
|
|
{ "getScissor", l_lovrGraphicsGetScissor },
|
|
|
|
{ "setScissor", l_lovrGraphicsSetScissor },
|
2016-08-10 06:28:17 +00:00
|
|
|
{ "setShader", l_lovrGraphicsSetShader },
|
2016-09-24 05:11:56 +00:00
|
|
|
{ "setProjection", l_lovrGraphicsSetProjection },
|
2016-09-21 07:55:53 +00:00
|
|
|
{ "push", l_lovrGraphicsPush },
|
|
|
|
{ "pop", l_lovrGraphicsPop },
|
2016-09-21 22:26:05 +00:00
|
|
|
{ "origin", l_lovrGraphicsOrigin },
|
2016-09-23 04:53:17 +00:00
|
|
|
{ "translate", l_lovrGraphicsTranslate },
|
|
|
|
{ "rotate", l_lovrGraphicsRotate },
|
|
|
|
{ "scale", l_lovrGraphicsScale },
|
2016-09-29 05:10:03 +00:00
|
|
|
{ "getWidth", l_lovrGraphicsGetWidth },
|
|
|
|
{ "getHeight", l_lovrGraphicsGetHeight },
|
|
|
|
{ "getDimensions", l_lovrGraphicsGetDimensions },
|
2016-08-10 06:28:17 +00:00
|
|
|
{ "newModel", l_lovrGraphicsNewModel },
|
|
|
|
{ "newBuffer", l_lovrGraphicsNewBuffer },
|
|
|
|
{ "newShader", l_lovrGraphicsNewShader },
|
|
|
|
{ NULL, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
int l_lovrGraphicsInit(lua_State* L) {
|
|
|
|
lua_newtable(L);
|
|
|
|
luaL_register(L, NULL, lovrGraphics);
|
|
|
|
luaRegisterType(L, "Buffer", lovrBuffer, luax_destroybuffer);
|
|
|
|
luaRegisterType(L, "Model", lovrModel, NULL);
|
|
|
|
luaRegisterType(L, "Shader", lovrShader, luax_destroyshader);
|
2016-09-17 22:38:13 +00:00
|
|
|
|
|
|
|
map_init(&BufferDrawModes);
|
|
|
|
map_set(&BufferDrawModes, "points", BUFFER_POINTS);
|
|
|
|
map_set(&BufferDrawModes, "strip", BUFFER_TRIANGLE_STRIP);
|
|
|
|
map_set(&BufferDrawModes, "triangles", BUFFER_TRIANGLES);
|
|
|
|
map_set(&BufferDrawModes, "fan", BUFFER_TRIANGLE_FAN);
|
|
|
|
|
|
|
|
map_init(&BufferUsages);
|
|
|
|
map_set(&BufferUsages, "static", BUFFER_STATIC);
|
|
|
|
map_set(&BufferUsages, "dynamic", BUFFER_DYNAMIC);
|
|
|
|
map_set(&BufferUsages, "stream", BUFFER_STREAM);
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
lovrGraphicsInit();
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-09-28 03:20:08 +00:00
|
|
|
int l_lovrGraphicsReset(lua_State* L) {
|
|
|
|
lovrGraphicsReset();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
int l_lovrGraphicsClear(lua_State* L) {
|
2016-09-17 03:11:11 +00:00
|
|
|
int color = lua_gettop(L) < 1 || lua_toboolean(L, 1);
|
|
|
|
int depth = lua_gettop(L) < 2 || lua_toboolean(L, 2);
|
|
|
|
lovrGraphicsClear(color, depth);
|
2016-08-10 06:28:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsPresent(lua_State* L) {
|
|
|
|
lovrGraphicsPresent();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-28 04:37:46 +00:00
|
|
|
int l_lovrGraphicsGetBackgroundColor(lua_State* L) {
|
2016-08-10 06:28:17 +00:00
|
|
|
float r, g, b, a;
|
2016-09-28 04:37:46 +00:00
|
|
|
lovrGraphicsGetBackgroundColor(&r, &g, &b, &a);
|
2016-08-10 06:28:17 +00:00
|
|
|
lua_pushnumber(L, r);
|
|
|
|
lua_pushnumber(L, g);
|
|
|
|
lua_pushnumber(L, b);
|
|
|
|
lua_pushnumber(L, a);
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
2016-09-28 04:37:46 +00:00
|
|
|
int l_lovrGraphicsSetBackgroundColor(lua_State* L) {
|
2016-08-10 06:28:17 +00:00
|
|
|
float r = luaL_checknumber(L, 1);
|
|
|
|
float g = luaL_checknumber(L, 2);
|
|
|
|
float b = luaL_checknumber(L, 3);
|
|
|
|
float a = 255.0;
|
|
|
|
if (lua_gettop(L) > 3) {
|
|
|
|
a = luaL_checknumber(L, 4);
|
|
|
|
}
|
2016-09-28 04:37:46 +00:00
|
|
|
lovrGraphicsSetBackgroundColor(r, g, b, a);
|
2016-08-10 06:28:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-29 03:11:58 +00:00
|
|
|
int l_lovrGraphicsGetColor(lua_State* L) {
|
|
|
|
unsigned char r, g, b, a;
|
|
|
|
lovrGraphicsGetColor(&r, &g, &b, &a);
|
|
|
|
lua_pushinteger(L, r);
|
|
|
|
lua_pushinteger(L, g);
|
|
|
|
lua_pushinteger(L, b);
|
|
|
|
lua_pushinteger(L, a);
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetColor(lua_State* L) {
|
|
|
|
if (lua_gettop(L) <= 1 && lua_isnoneornil(L, 1)) {
|
|
|
|
lovrGraphicsSetColor(255, 255, 255, 255);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned char r = lua_tointeger(L, 1);
|
|
|
|
unsigned char g = lua_tointeger(L, 2);
|
|
|
|
unsigned char b = lua_tointeger(L, 3);
|
|
|
|
unsigned char a = lua_isnoneornil(L, 4) ? 255 : lua_tointeger(L, 4);
|
|
|
|
lovrGraphicsSetColor(r, g, b, a);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-28 04:32:57 +00:00
|
|
|
int l_lovrGraphicsGetColorMask(lua_State* L) {
|
2016-09-29 02:38:58 +00:00
|
|
|
unsigned char r, g, b, a;
|
2016-09-28 04:32:57 +00:00
|
|
|
lovrGraphicsGetColorMask(&r, &g, &b, &a);
|
|
|
|
lua_pushboolean(L, r);
|
|
|
|
lua_pushboolean(L, g);
|
|
|
|
lua_pushboolean(L, b);
|
|
|
|
lua_pushboolean(L, a);
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetColorMask(lua_State* L) {
|
|
|
|
if (lua_gettop(L) <= 1 && lua_isnoneornil(L, 1)) {
|
|
|
|
lovrGraphicsSetColorMask(1, 1, 1, 1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-29 02:38:58 +00:00
|
|
|
unsigned char r = lua_toboolean(L, 1);
|
|
|
|
unsigned char g = lua_toboolean(L, 2);
|
|
|
|
unsigned char b = lua_toboolean(L, 3);
|
|
|
|
unsigned char a = lua_toboolean(L, 4);
|
2016-09-28 04:32:57 +00:00
|
|
|
lovrGraphicsSetColorMask(r, g, b, a);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-29 04:47:36 +00:00
|
|
|
int l_lovrGraphicsGetScissor(lua_State* L) {
|
|
|
|
if (!lovrGraphicsIsScissorEnabled()) {
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int x, y, width, height;
|
|
|
|
lovrGraphicsGetScissor(&x, &y, &width, &height);
|
|
|
|
lua_pushnumber(L, x);
|
|
|
|
lua_pushnumber(L, y);
|
|
|
|
lua_pushnumber(L, width);
|
|
|
|
lua_pushnumber(L, height);
|
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetScissor(lua_State* L) {
|
|
|
|
if (lua_gettop(L) <= 1 && lua_isnoneornil(L, 1)) {
|
|
|
|
lovrGraphicsSetScissorEnabled(0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int x = luaL_checkint(L, 1);
|
|
|
|
int y = luaL_checkint(L, 2);
|
|
|
|
int width = luaL_checkint(L, 3);
|
|
|
|
int height = luaL_checkint(L, 4);
|
|
|
|
lovrGraphicsSetScissor(x, y, width, height);
|
|
|
|
lovrGraphicsSetScissorEnabled(1);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-14 00:02:23 +00:00
|
|
|
int l_lovrGraphicsGetShader(lua_State* L) {
|
|
|
|
luax_pushshader(L, lovrGraphicsGetShader());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
int l_lovrGraphicsSetShader(lua_State* L) {
|
|
|
|
Shader* shader = luax_checkshader(L, 1);
|
|
|
|
lovrGraphicsSetShader(shader);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-24 05:11:56 +00:00
|
|
|
int l_lovrGraphicsSetProjection(lua_State* L) {
|
|
|
|
float near = luaL_checknumber(L, 1);
|
|
|
|
float far = luaL_checknumber(L, 2);
|
|
|
|
float fov = luaL_checknumber(L, 3);
|
2016-09-27 06:48:09 +00:00
|
|
|
lovrGraphicsSetProjection(near, far, fov);
|
2016-09-24 05:11:56 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-21 07:55:53 +00:00
|
|
|
int l_lovrGraphicsPush(lua_State* L) {
|
|
|
|
if (lovrGraphicsPush()) {
|
|
|
|
return luaL_error(L, "Unbalanced matrix stack (more pushes than pops?)");
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsPop(lua_State* L) {
|
|
|
|
if (lovrGraphicsPop()) {
|
|
|
|
return luaL_error(L, "Unbalanced matrix stack (more pops than pushes?)");
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-21 22:26:05 +00:00
|
|
|
int l_lovrGraphicsOrigin(lua_State* L) {
|
|
|
|
lovrGraphicsOrigin();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-23 04:53:17 +00:00
|
|
|
int l_lovrGraphicsTranslate(lua_State* L) {
|
|
|
|
float x = luaL_checknumber(L, 1);
|
|
|
|
float y = luaL_checknumber(L, 2);
|
|
|
|
float z = luaL_checknumber(L, 3);
|
|
|
|
lovrGraphicsTranslate(x, y, z);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsRotate(lua_State* L) {
|
|
|
|
float w = luaL_checknumber(L, 1);
|
|
|
|
float x = luaL_checknumber(L, 2);
|
|
|
|
float y = luaL_checknumber(L, 3);
|
|
|
|
float z = luaL_checknumber(L, 4);
|
|
|
|
lovrGraphicsRotate(w, x, y, z);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsScale(lua_State* L) {
|
|
|
|
float x = luaL_checknumber(L, 1);
|
|
|
|
float y = luaL_checknumber(L, 2);
|
|
|
|
float z = luaL_checknumber(L, 3);
|
|
|
|
lovrGraphicsScale(x, y, z);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-29 05:10:03 +00:00
|
|
|
int l_lovrGraphicsGetWidth(lua_State* L) {
|
|
|
|
int width;
|
|
|
|
lovrGraphicsGetDimensions(&width, NULL);
|
|
|
|
lua_pushnumber(L, width);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsGetHeight(lua_State* L) {
|
|
|
|
int height;
|
|
|
|
lovrGraphicsGetDimensions(NULL, &height);
|
|
|
|
lua_pushnumber(L, height);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsGetDimensions(lua_State* L) {
|
|
|
|
int width, height;
|
|
|
|
lovrGraphicsGetDimensions(&width, &height);
|
|
|
|
lua_pushnumber(L, width);
|
|
|
|
lua_pushnumber(L, height);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
int l_lovrGraphicsNewBuffer(lua_State* L) {
|
2016-09-17 22:38:13 +00:00
|
|
|
const char* userDrawMode = luaL_optstring(L, 2, "fan");
|
|
|
|
BufferDrawMode* drawMode = (BufferDrawMode*) map_get(&BufferDrawModes, userDrawMode);
|
|
|
|
if (!drawMode) {
|
|
|
|
return luaL_error(L, "Invalid buffer draw mode: '%s'", userDrawMode);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* userUsage = luaL_optstring(L, 3, "dynamic");
|
|
|
|
BufferUsage* usage = (BufferUsage*) map_get(&BufferUsages, userUsage);
|
|
|
|
if (!usage) {
|
|
|
|
return luaL_error(L, "Invalid buffer usage: '%s'", userUsage);
|
|
|
|
}
|
|
|
|
|
|
|
|
int size;
|
|
|
|
|
|
|
|
if (lua_isnumber(L, 1)) {
|
|
|
|
size = lua_tonumber(L, 1);
|
|
|
|
} else if (lua_istable(L, 1)) {
|
|
|
|
size = lua_objlen(L, 1);
|
|
|
|
} else {
|
|
|
|
return luaL_argerror(L, 1, "table or number expected");
|
|
|
|
}
|
|
|
|
|
|
|
|
Buffer* buffer = lovrGraphicsNewBuffer(size, *drawMode, *usage);
|
|
|
|
|
|
|
|
if (lua_istable(L, 1)) {
|
|
|
|
float x, y, z;
|
|
|
|
for (int i = 0; i < size; i++) {
|
|
|
|
lua_rawgeti(L, 1, i + 1);
|
|
|
|
lua_rawgeti(L, -1, 1);
|
|
|
|
lua_rawgeti(L, -2, 2);
|
|
|
|
lua_rawgeti(L, -3, 3);
|
|
|
|
x = lua_tonumber(L, -3);
|
|
|
|
y = lua_tonumber(L, -2);
|
|
|
|
z = lua_tonumber(L, -1);
|
|
|
|
lovrBufferSetVertex(buffer, i, x, y, z);
|
|
|
|
lua_pop(L, 4);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
luax_pushbuffer(L, buffer);
|
2016-08-10 06:28:17 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsNewModel(lua_State* L) {
|
|
|
|
const char* path = luaL_checkstring(L, 1);
|
|
|
|
luax_pushmodel(L, lovrGraphicsNewModel(path));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsNewShader(lua_State* L) {
|
|
|
|
const char* vertexSource = luaL_checkstring(L, 1);
|
|
|
|
const char* fragmentSource = luaL_checkstring(L, 2);
|
|
|
|
luax_pushshader(L, lovrGraphicsNewShader(vertexSource, fragmentSource));
|
|
|
|
return 1;
|
|
|
|
}
|