2017-03-11 11:08:07 +00:00
|
|
|
#include "api/lovr.h"
|
2016-11-19 09:28:01 +00:00
|
|
|
#include "graphics/graphics.h"
|
2017-11-03 06:47:13 +00:00
|
|
|
#include "graphics/animator.h"
|
2017-10-21 21:05:58 +00:00
|
|
|
#include "graphics/material.h"
|
2017-08-09 05:34:23 +00:00
|
|
|
#include "graphics/mesh.h"
|
|
|
|
#include "graphics/model.h"
|
2017-02-03 23:16:30 +00:00
|
|
|
#include "loaders/font.h"
|
2017-10-21 21:05:58 +00:00
|
|
|
#include "loaders/material.h"
|
2016-11-26 07:15:04 +00:00
|
|
|
#include "loaders/model.h"
|
2016-11-26 07:54:45 +00:00
|
|
|
#include "loaders/texture.h"
|
2016-11-19 09:28:01 +00:00
|
|
|
#include "filesystem/filesystem.h"
|
2016-10-29 22:17:49 +00:00
|
|
|
#include <math.h>
|
2017-10-31 08:14:09 +00:00
|
|
|
#include <stdbool.h>
|
2016-08-10 06:28:17 +00:00
|
|
|
|
2017-11-22 19:32:30 +00:00
|
|
|
map_int_t ArcModes;
|
2017-03-12 11:03:36 +00:00
|
|
|
map_int_t BlendAlphaModes;
|
|
|
|
map_int_t BlendModes;
|
2017-03-11 11:08:07 +00:00
|
|
|
map_int_t CompareModes;
|
|
|
|
map_int_t DrawModes;
|
|
|
|
map_int_t FilterModes;
|
2017-03-16 03:12:56 +00:00
|
|
|
map_int_t HorizontalAligns;
|
2017-10-21 21:05:58 +00:00
|
|
|
map_int_t MaterialColors;
|
|
|
|
map_int_t MaterialTextures;
|
2017-08-11 05:23:19 +00:00
|
|
|
map_int_t MatrixTypes;
|
2017-03-12 11:03:36 +00:00
|
|
|
map_int_t MeshAttributeTypes;
|
|
|
|
map_int_t MeshDrawModes;
|
|
|
|
map_int_t MeshUsages;
|
2017-03-11 11:08:07 +00:00
|
|
|
map_int_t TextureProjections;
|
2017-03-16 03:12:56 +00:00
|
|
|
map_int_t VerticalAligns;
|
2017-08-02 07:54:33 +00:00
|
|
|
map_int_t Windings;
|
2017-03-11 11:08:07 +00:00
|
|
|
map_int_t WrapModes;
|
|
|
|
|
2017-08-11 05:23:19 +00:00
|
|
|
static int luax_optmatrixtype(lua_State* L, int index, MatrixType* type) {
|
|
|
|
if (lua_type(L, index) == LUA_TSTRING) {
|
|
|
|
*type = *(MatrixType*) luax_checkenum(L, index++, &MatrixTypes, "matrix type");
|
|
|
|
} else {
|
|
|
|
*type = MATRIX_MODEL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return index;
|
|
|
|
}
|
|
|
|
|
2016-11-08 07:16:33 +00:00
|
|
|
static void luax_readvertices(lua_State* L, int index, vec_float_t* points) {
|
2017-10-31 08:14:09 +00:00
|
|
|
bool isTable = lua_istable(L, index);
|
2016-11-08 07:16:33 +00:00
|
|
|
|
|
|
|
if (!isTable && !lua_isnumber(L, index)) {
|
|
|
|
luaL_error(L, "Expected number or table, got '%s'", lua_typename(L, lua_type(L, 1)));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-11-23 04:43:22 +00:00
|
|
|
int count = isTable ? lua_objlen(L, index) : lua_gettop(L) - index + 1;
|
2016-11-08 07:16:33 +00:00
|
|
|
if (count % 3 != 0) {
|
|
|
|
vec_deinit(points);
|
|
|
|
luaL_error(L, "Number of coordinates must be a multiple of 3, got '%d'", count);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vec_reserve(points, count);
|
|
|
|
|
|
|
|
if (isTable) {
|
|
|
|
for (int i = 1; i <= count; i++) {
|
|
|
|
lua_rawgeti(L, index, i);
|
|
|
|
vec_push(points, lua_tonumber(L, -1));
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
vec_push(points, lua_tonumber(L, index + i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-23 05:16:13 +00:00
|
|
|
// Base
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
int l_lovrGraphicsInit(lua_State* L) {
|
|
|
|
lua_newtable(L);
|
|
|
|
luaL_register(L, NULL, lovrGraphics);
|
2017-11-03 06:47:13 +00:00
|
|
|
luax_registertype(L, "Animator", lovrAnimator);
|
2017-02-06 05:05:09 +00:00
|
|
|
luax_registertype(L, "Font", lovrFont);
|
2017-10-21 21:05:58 +00:00
|
|
|
luax_registertype(L, "Material", lovrMaterial);
|
2017-03-15 04:38:03 +00:00
|
|
|
luax_registertype(L, "Mesh", lovrMesh);
|
2017-01-21 03:46:45 +00:00
|
|
|
luax_registertype(L, "Model", lovrModel);
|
|
|
|
luax_registertype(L, "Shader", lovrShader);
|
|
|
|
luax_registertype(L, "Texture", lovrTexture);
|
2016-09-17 22:38:13 +00:00
|
|
|
|
2017-11-22 19:32:30 +00:00
|
|
|
map_init(&ArcModes);
|
|
|
|
map_set(&ArcModes, "pie", ARC_MODE_PIE);
|
|
|
|
map_set(&ArcModes, "open", ARC_MODE_OPEN);
|
|
|
|
map_set(&ArcModes, "closed", ARC_MODE_CLOSED);
|
|
|
|
|
2017-03-12 11:03:36 +00:00
|
|
|
map_init(&BlendAlphaModes);
|
|
|
|
map_set(&BlendAlphaModes, "alphamultiply", BLEND_ALPHA_MULTIPLY);
|
|
|
|
map_set(&BlendAlphaModes, "premultiplied", BLEND_PREMULTIPLIED);
|
2016-10-10 00:40:02 +00:00
|
|
|
|
2017-03-12 11:03:36 +00:00
|
|
|
map_init(&BlendModes);
|
|
|
|
map_set(&BlendModes, "alpha", BLEND_ALPHA);
|
|
|
|
map_set(&BlendModes, "add", BLEND_ADD);
|
|
|
|
map_set(&BlendModes, "subtract", BLEND_SUBTRACT);
|
|
|
|
map_set(&BlendModes, "multiply", BLEND_MULTIPLY);
|
|
|
|
map_set(&BlendModes, "lighten", BLEND_LIGHTEN);
|
|
|
|
map_set(&BlendModes, "darken", BLEND_DARKEN);
|
|
|
|
map_set(&BlendModes, "screen", BLEND_SCREEN);
|
|
|
|
map_set(&BlendModes, "replace", BLEND_REPLACE);
|
2016-09-17 22:38:13 +00:00
|
|
|
|
2016-11-23 04:59:11 +00:00
|
|
|
map_init(&CompareModes);
|
|
|
|
map_set(&CompareModes, "equal", COMPARE_EQUAL);
|
|
|
|
map_set(&CompareModes, "notequal", COMPARE_NOT_EQUAL);
|
|
|
|
map_set(&CompareModes, "less", COMPARE_LESS);
|
|
|
|
map_set(&CompareModes, "lequal", COMPARE_LEQUAL);
|
|
|
|
map_set(&CompareModes, "gequal", COMPARE_GEQUAL);
|
|
|
|
map_set(&CompareModes, "greater", COMPARE_GREATER);
|
|
|
|
|
2017-03-15 04:38:03 +00:00
|
|
|
map_init(&DrawModes);
|
|
|
|
map_set(&DrawModes, "fill", DRAW_MODE_FILL);
|
|
|
|
map_set(&DrawModes, "line", DRAW_MODE_LINE);
|
|
|
|
|
2016-11-08 22:44:22 +00:00
|
|
|
map_init(&FilterModes);
|
|
|
|
map_set(&FilterModes, "nearest", FILTER_NEAREST);
|
2017-07-23 10:09:07 +00:00
|
|
|
map_set(&FilterModes, "bilinear", FILTER_BILINEAR);
|
|
|
|
map_set(&FilterModes, "trilinear", FILTER_TRILINEAR);
|
|
|
|
map_set(&FilterModes, "anisotropic", FILTER_ANISOTROPIC);
|
2016-11-08 22:44:22 +00:00
|
|
|
|
2017-03-16 03:12:56 +00:00
|
|
|
map_init(&HorizontalAligns);
|
|
|
|
map_set(&HorizontalAligns, "left", ALIGN_LEFT);
|
|
|
|
map_set(&HorizontalAligns, "right", ALIGN_RIGHT);
|
|
|
|
map_set(&HorizontalAligns, "center", ALIGN_CENTER);
|
|
|
|
|
2017-10-21 21:05:58 +00:00
|
|
|
map_init(&MaterialColors);
|
|
|
|
map_set(&MaterialColors, "diffuse", COLOR_DIFFUSE);
|
|
|
|
|
|
|
|
map_init(&MaterialTextures);
|
|
|
|
map_set(&MaterialTextures, "diffuse", TEXTURE_DIFFUSE);
|
2017-10-21 21:59:34 +00:00
|
|
|
map_set(&MaterialTextures, "environment", TEXTURE_ENVIRONMENT_MAP);
|
2017-10-21 21:05:58 +00:00
|
|
|
|
2017-08-11 05:23:19 +00:00
|
|
|
map_init(&MatrixTypes);
|
|
|
|
map_set(&MatrixTypes, "model", MATRIX_MODEL);
|
|
|
|
map_set(&MatrixTypes, "view", MATRIX_VIEW);
|
|
|
|
|
2017-03-12 11:03:36 +00:00
|
|
|
map_init(&MeshAttributeTypes);
|
|
|
|
map_set(&MeshAttributeTypes, "float", MESH_FLOAT);
|
|
|
|
map_set(&MeshAttributeTypes, "byte", MESH_BYTE);
|
|
|
|
map_set(&MeshAttributeTypes, "int", MESH_INT);
|
|
|
|
|
|
|
|
map_init(&MeshDrawModes);
|
|
|
|
map_set(&MeshDrawModes, "points", MESH_POINTS);
|
|
|
|
map_set(&MeshDrawModes, "strip", MESH_TRIANGLE_STRIP);
|
|
|
|
map_set(&MeshDrawModes, "triangles", MESH_TRIANGLES);
|
|
|
|
map_set(&MeshDrawModes, "fan", MESH_TRIANGLE_FAN);
|
|
|
|
|
|
|
|
map_init(&MeshUsages);
|
|
|
|
map_set(&MeshUsages, "static", MESH_STATIC);
|
|
|
|
map_set(&MeshUsages, "dynamic", MESH_DYNAMIC);
|
|
|
|
map_set(&MeshUsages, "stream", MESH_STREAM);
|
|
|
|
|
2017-03-15 04:38:03 +00:00
|
|
|
map_init(&TextureProjections);
|
|
|
|
map_set(&TextureProjections, "2d", PROJECTION_ORTHOGRAPHIC);
|
|
|
|
map_set(&TextureProjections, "3d", PROJECTION_PERSPECTIVE);
|
|
|
|
|
2017-03-16 03:12:56 +00:00
|
|
|
map_init(&VerticalAligns);
|
|
|
|
map_set(&VerticalAligns, "top", ALIGN_TOP);
|
|
|
|
map_set(&VerticalAligns, "bottom", ALIGN_BOTTOM);
|
|
|
|
map_set(&VerticalAligns, "middle", ALIGN_MIDDLE);
|
|
|
|
|
2017-08-02 07:54:33 +00:00
|
|
|
map_init(&Windings);
|
|
|
|
map_set(&Windings, "clockwise", WINDING_CLOCKWISE);
|
|
|
|
map_set(&Windings, "counterclockwise", WINDING_COUNTERCLOCKWISE);
|
|
|
|
|
2016-11-08 22:44:22 +00:00
|
|
|
map_init(&WrapModes);
|
|
|
|
map_set(&WrapModes, "clamp", WRAP_CLAMP);
|
|
|
|
map_set(&WrapModes, "repeat", WRAP_REPEAT);
|
|
|
|
map_set(&WrapModes, "mirroredrepeat", WRAP_MIRRORED_REPEAT);
|
|
|
|
|
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) {
|
2017-10-31 08:14:09 +00:00
|
|
|
bool color = lua_gettop(L) < 1 || lua_toboolean(L, 1);
|
|
|
|
bool depth = lua_gettop(L) < 2 || lua_toboolean(L, 2);
|
2016-09-17 03:11:11 +00:00
|
|
|
lovrGraphicsClear(color, depth);
|
2016-08-10 06:28:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsPresent(lua_State* L) {
|
|
|
|
lovrGraphicsPresent();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-10 03:02:02 +00:00
|
|
|
int l_lovrGraphicsCreateWindow(lua_State* L) {
|
|
|
|
int width = luaL_optnumber(L, 1, 800);
|
|
|
|
int height = luaL_optnumber(L, 2, 600);
|
2017-10-31 08:14:09 +00:00
|
|
|
bool fullscreen = !lua_isnoneornil(L, 3) && lua_toboolean(L, 3);
|
2017-08-10 03:02:02 +00:00
|
|
|
int msaa = luaL_optnumber(L, 4, 0);
|
|
|
|
const char* title = luaL_optstring(L, 5, "LÖVR");
|
|
|
|
const char* icon = luaL_optstring(L, 6, NULL);
|
|
|
|
lovrGraphicsCreateWindow(width, height, fullscreen, msaa, title, icon);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsGetWidth(lua_State* L) {
|
|
|
|
lua_pushnumber(L, lovrGraphicsGetWidth());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsGetHeight(lua_State* L) {
|
|
|
|
lua_pushnumber(L, lovrGraphicsGetHeight());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsGetDimensions(lua_State* L) {
|
|
|
|
lua_pushnumber(L, lovrGraphicsGetWidth());
|
|
|
|
lua_pushnumber(L, lovrGraphicsGetHeight());
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
2016-11-23 05:16:13 +00:00
|
|
|
// State
|
|
|
|
|
2016-09-28 04:37:46 +00:00
|
|
|
int l_lovrGraphicsGetBackgroundColor(lua_State* L) {
|
2017-08-02 08:25:56 +00:00
|
|
|
Color color = lovrGraphicsGetBackgroundColor();
|
|
|
|
lua_pushnumber(L, color.r);
|
|
|
|
lua_pushnumber(L, color.g);
|
|
|
|
lua_pushnumber(L, color.b);
|
|
|
|
lua_pushnumber(L, color.a);
|
2016-08-10 06:28:17 +00:00
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
2016-09-28 04:37:46 +00:00
|
|
|
int l_lovrGraphicsSetBackgroundColor(lua_State* L) {
|
2017-08-02 08:25:56 +00:00
|
|
|
Color color;
|
|
|
|
color.r = luaL_checknumber(L, 1);
|
|
|
|
color.g = luaL_checknumber(L, 2);
|
|
|
|
color.b = luaL_checknumber(L, 3);
|
2017-11-21 05:47:25 +00:00
|
|
|
color.a = luaL_optnumber(L, 4, 1.);
|
2017-08-02 08:25:56 +00:00
|
|
|
lovrGraphicsSetBackgroundColor(color);
|
2016-08-10 06:28:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-03-12 11:03:36 +00:00
|
|
|
int l_lovrGraphicsGetBlendMode(lua_State* L) {
|
|
|
|
BlendMode mode;
|
|
|
|
BlendAlphaMode alphaMode;
|
|
|
|
lovrGraphicsGetBlendMode(&mode, &alphaMode);
|
|
|
|
luax_pushenum(L, &BlendModes, mode);
|
|
|
|
luax_pushenum(L, &BlendAlphaModes, alphaMode);
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetBlendMode(lua_State* L) {
|
|
|
|
BlendMode mode = *(BlendMode*) luax_checkenum(L, 1, &BlendModes, "blend mode");
|
|
|
|
BlendAlphaMode alphaMode = *(BlendAlphaMode*) luax_optenum(L, 2, "alphamultiply", &BlendAlphaModes, "alpha blend mode");
|
|
|
|
lovrGraphicsSetBlendMode(mode, alphaMode);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-09-29 03:11:58 +00:00
|
|
|
int l_lovrGraphicsGetColor(lua_State* L) {
|
2017-08-02 08:25:56 +00:00
|
|
|
Color color = lovrGraphicsGetColor();
|
2017-11-21 05:47:25 +00:00
|
|
|
lua_pushnumber(L, color.r);
|
|
|
|
lua_pushnumber(L, color.g);
|
|
|
|
lua_pushnumber(L, color.b);
|
|
|
|
lua_pushnumber(L, color.a);
|
2016-09-29 03:11:58 +00:00
|
|
|
return 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetColor(lua_State* L) {
|
2017-10-21 20:10:07 +00:00
|
|
|
Color color = luax_checkcolor(L, 1);
|
2017-08-02 08:25:56 +00:00
|
|
|
lovrGraphicsSetColor(color);
|
2016-09-29 03:11:58 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-02 07:54:33 +00:00
|
|
|
int l_lovrGraphicsIsCullingEnabled(lua_State* L) {
|
|
|
|
lua_pushboolean(L, lovrGraphicsIsCullingEnabled());
|
2016-09-14 00:02:23 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-08-02 07:54:33 +00:00
|
|
|
int l_lovrGraphicsSetCullingEnabled(lua_State* L) {
|
|
|
|
lovrGraphicsSetCullingEnabled(lua_toboolean(L, 1));
|
2016-08-10 06:28:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-02 07:54:33 +00:00
|
|
|
int l_lovrGraphicsGetDefaultFilter(lua_State* L) {
|
|
|
|
TextureFilter filter = lovrGraphicsGetDefaultFilter();
|
|
|
|
luax_pushenum(L, &FilterModes, filter.mode);
|
|
|
|
if (filter.mode == FILTER_ANISOTROPIC) {
|
|
|
|
lua_pushnumber(L, filter.anisotropy);
|
|
|
|
return 2;
|
|
|
|
}
|
2017-02-03 23:16:30 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-08-02 07:54:33 +00:00
|
|
|
int l_lovrGraphicsSetDefaultFilter(lua_State* L) {
|
|
|
|
FilterMode mode = *(FilterMode*) luax_checkenum(L, 1, &FilterModes, "filter mode");
|
|
|
|
float anisotropy = luaL_optnumber(L, 2, 1.);
|
|
|
|
TextureFilter filter = { .mode = mode, .anisotropy = anisotropy };
|
|
|
|
lovrGraphicsSetDefaultFilter(filter);
|
2017-02-03 23:16:30 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-02 07:54:33 +00:00
|
|
|
int l_lovrGraphicsGetDepthTest(lua_State* L) {
|
|
|
|
luax_pushenum(L, &CompareModes, lovrGraphicsGetDepthTest());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetDepthTest(lua_State* L) {
|
|
|
|
if (lua_isnoneornil(L, 1)) {
|
|
|
|
lovrGraphicsSetDepthTest(COMPARE_NONE);
|
|
|
|
} else {
|
|
|
|
CompareMode* depthTest = (CompareMode*) luax_checkenum(L, 1, &CompareModes, "compare mode");
|
|
|
|
lovrGraphicsSetDepthTest(*depthTest);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-10 03:02:02 +00:00
|
|
|
int l_lovrGraphicsGetFont(lua_State* L) {
|
|
|
|
Font* font = lovrGraphicsGetFont();
|
|
|
|
luax_pushtype(L, Font, font);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetFont(lua_State* L) {
|
|
|
|
Font* font = lua_isnoneornil(L, 1) ? NULL : luax_checktype(L, 1, Font);
|
|
|
|
lovrGraphicsSetFont(font);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-02 07:54:33 +00:00
|
|
|
int l_lovrGraphicsGetSystemLimits(lua_State* L) {
|
|
|
|
GraphicsLimits limits = lovrGraphicsGetLimits();
|
|
|
|
lua_newtable(L);
|
|
|
|
lua_pushnumber(L, limits.pointSizes[1]);
|
|
|
|
lua_setfield(L, -2, "pointsize");
|
|
|
|
lua_pushinteger(L, limits.textureSize);
|
|
|
|
lua_setfield(L, -2, "texturesize");
|
|
|
|
lua_pushinteger(L, limits.textureMSAA);
|
|
|
|
lua_setfield(L, -2, "texturemsaa");
|
|
|
|
lua_pushinteger(L, limits.textureAnisotropy);
|
|
|
|
lua_setfield(L, -2, "anisotropy");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-10-01 20:48:31 +00:00
|
|
|
int l_lovrGraphicsGetLineWidth(lua_State* L) {
|
|
|
|
lua_pushnumber(L, lovrGraphicsGetLineWidth());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetLineWidth(lua_State* L) {
|
|
|
|
float width = luaL_optnumber(L, 1, 1.f);
|
|
|
|
lovrGraphicsSetLineWidth(width);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-10-21 21:32:41 +00:00
|
|
|
int l_lovrGraphicsGetMaterial(lua_State* L) {
|
|
|
|
Material* material = lovrGraphicsGetMaterial();
|
|
|
|
if (material && !material->isDefault) {
|
|
|
|
luax_pushtype(L, Material, material);
|
|
|
|
} else {
|
|
|
|
lua_pushnil(L);
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetMaterial(lua_State* L) {
|
|
|
|
Material* material = lua_isnoneornil(L, 1) ? NULL : luax_checktype(L, 1, Material);
|
|
|
|
lovrGraphicsSetMaterial(material);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-11-13 01:38:49 +00:00
|
|
|
int l_lovrGraphicsGetPointSize(lua_State* L) {
|
|
|
|
lua_pushnumber(L, lovrGraphicsGetPointSize());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSetPointSize(lua_State* L) {
|
|
|
|
float size = luaL_optnumber(L, 1, 1.f);
|
|
|
|
lovrGraphicsSetPointSize(size);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-02 07:54:33 +00:00
|
|
|
int l_lovrGraphicsGetShader(lua_State* L) {
|
|
|
|
Shader* shader = lovrGraphicsGetShader();
|
|
|
|
luax_pushtype(L, Shader, shader);
|
2016-11-23 05:07:33 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-08-02 07:54:33 +00:00
|
|
|
int l_lovrGraphicsSetShader(lua_State* L) {
|
|
|
|
Shader* shader = lua_isnoneornil(L, 1) ? NULL : luax_checktype(L, 1, Shader);
|
|
|
|
lovrGraphicsSetShader(shader);
|
2016-11-23 05:07:33 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-10 03:02:02 +00:00
|
|
|
int l_lovrGraphicsGetWinding(lua_State* L) {
|
|
|
|
luax_pushenum(L, &Windings, lovrGraphicsGetWinding());
|
2017-07-23 10:09:07 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-08-10 03:02:02 +00:00
|
|
|
int l_lovrGraphicsSetWinding(lua_State* L) {
|
|
|
|
Winding* winding = (Winding*) luax_checkenum(L, 1, &Windings, "winding");
|
|
|
|
lovrGraphicsSetWinding(*winding);
|
2017-07-23 10:09:07 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-08-10 03:02:02 +00:00
|
|
|
int l_lovrGraphicsIsWireframe(lua_State* L) {
|
|
|
|
lua_pushboolean(L, lovrGraphicsIsWireframe());
|
2016-11-23 05:16:13 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-08-10 03:02:02 +00:00
|
|
|
int l_lovrGraphicsSetWireframe(lua_State* L) {
|
|
|
|
lovrGraphicsSetWireframe(lua_toboolean(L, 1));
|
|
|
|
return 0;
|
2016-11-23 05:16:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Transforms
|
|
|
|
|
2016-09-21 07:55:53 +00:00
|
|
|
int l_lovrGraphicsPush(lua_State* L) {
|
2017-08-10 08:05:04 +00:00
|
|
|
lovrGraphicsPush();
|
2016-09-21 07:55:53 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsPop(lua_State* L) {
|
2017-08-10 08:05:04 +00:00
|
|
|
lovrGraphicsPop();
|
2016-09-21 07:55:53 +00:00
|
|
|
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) {
|
2017-08-11 05:23:19 +00:00
|
|
|
MatrixType type;
|
|
|
|
int i = luax_optmatrixtype(L, 1, &type);
|
|
|
|
float x = luaL_checknumber(L, i++);
|
|
|
|
float y = luaL_checknumber(L, i++);
|
|
|
|
float z = luaL_checknumber(L, i++);
|
|
|
|
lovrGraphicsTranslate(type, x, y, z);
|
2016-09-23 04:53:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsRotate(lua_State* L) {
|
2017-08-11 05:23:19 +00:00
|
|
|
MatrixType type;
|
|
|
|
int i = luax_optmatrixtype(L, 1, &type);
|
|
|
|
float angle = luaL_checknumber(L, i++);
|
|
|
|
float axisX = luaL_optnumber(L, i++, 0);
|
|
|
|
float axisY = luaL_optnumber(L, i++, 1);
|
|
|
|
float axisZ = luaL_optnumber(L, i++, 0);
|
|
|
|
lovrGraphicsRotate(type, angle, axisX, axisY, axisZ);
|
2016-09-23 04:53:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsScale(lua_State* L) {
|
2017-08-11 05:23:19 +00:00
|
|
|
MatrixType type;
|
|
|
|
int i = luax_optmatrixtype(L, 1, &type);
|
|
|
|
float x = luaL_checknumber(L, i++);
|
|
|
|
float y = luaL_optnumber(L, i++, x);
|
|
|
|
float z = luaL_optnumber(L, i++, x);
|
|
|
|
lovrGraphicsScale(type, x, y, z);
|
2016-09-23 04:53:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-01-20 03:13:37 +00:00
|
|
|
int l_lovrGraphicsTransform(lua_State* L) {
|
2017-08-11 05:23:19 +00:00
|
|
|
MatrixType type;
|
|
|
|
int i = luax_optmatrixtype(L, 1, &type);
|
2017-01-20 03:13:37 +00:00
|
|
|
float transform[16];
|
2017-08-11 05:23:19 +00:00
|
|
|
luax_readtransform(L, i++, transform, 0);
|
|
|
|
lovrGraphicsMatrixTransform(type, transform);
|
2017-01-20 03:13:37 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-11-23 05:16:13 +00:00
|
|
|
// Primitives
|
|
|
|
|
2016-11-08 07:16:33 +00:00
|
|
|
int l_lovrGraphicsPoints(lua_State* L) {
|
2016-09-30 02:39:25 +00:00
|
|
|
vec_float_t points;
|
|
|
|
vec_init(&points);
|
2016-11-08 07:16:33 +00:00
|
|
|
luax_readvertices(L, 1, &points);
|
|
|
|
lovrGraphicsPoints(points.data, points.length);
|
|
|
|
vec_deinit(&points);
|
|
|
|
return 0;
|
|
|
|
}
|
2016-09-30 02:39:25 +00:00
|
|
|
|
2016-11-08 07:16:33 +00:00
|
|
|
int l_lovrGraphicsLine(lua_State* L) {
|
|
|
|
vec_float_t points;
|
|
|
|
vec_init(&points);
|
|
|
|
luax_readvertices(L, 1, &points);
|
|
|
|
lovrGraphicsLine(points.data, points.length);
|
2016-09-30 02:39:25 +00:00
|
|
|
vec_deinit(&points);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-11-23 04:43:22 +00:00
|
|
|
int l_lovrGraphicsTriangle(lua_State* L) {
|
|
|
|
DrawMode* drawMode = (DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
|
|
|
|
int top = lua_gettop(L);
|
|
|
|
if (top != 10) {
|
|
|
|
return luaL_error(L, "Expected 9 coordinates to make a triangle, got %d values", top - 1);
|
|
|
|
}
|
|
|
|
vec_float_t points;
|
|
|
|
vec_init(&points);
|
|
|
|
luax_readvertices(L, 2, &points);
|
|
|
|
lovrGraphicsTriangle(*drawMode, points.data);
|
|
|
|
vec_deinit(&points);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-10-04 03:56:45 +00:00
|
|
|
int l_lovrGraphicsPlane(lua_State* L) {
|
2017-10-21 20:50:43 +00:00
|
|
|
if (lua_isuserdata(L, 1)) {
|
|
|
|
Texture* texture = luax_checktype(L, 1, Texture);
|
|
|
|
lovrGraphicsPlaneFullscreen(texture);
|
|
|
|
return 0;
|
2017-01-13 09:59:00 +00:00
|
|
|
}
|
2017-10-21 20:50:43 +00:00
|
|
|
|
|
|
|
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
|
2017-07-18 20:07:18 +00:00
|
|
|
float transform[16];
|
|
|
|
luax_readtransform(L, 2, transform, 1);
|
2017-10-21 20:50:43 +00:00
|
|
|
lovrGraphicsPlane(drawMode, transform);
|
2016-10-04 03:56:45 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-10-31 08:14:09 +00:00
|
|
|
static int luax_rectangularprism(lua_State* L, bool uniformScale) {
|
2017-10-21 20:50:43 +00:00
|
|
|
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
|
2017-01-20 03:11:42 +00:00
|
|
|
float transform[16];
|
2017-06-22 02:42:34 +00:00
|
|
|
luax_readtransform(L, 2, transform, uniformScale);
|
2017-10-21 20:50:43 +00:00
|
|
|
lovrGraphicsBox(drawMode, transform);
|
2016-09-30 06:18:51 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-22 02:42:34 +00:00
|
|
|
int l_lovrGraphicsCube(lua_State* L) {
|
2017-10-31 08:14:09 +00:00
|
|
|
return luax_rectangularprism(L, true);
|
2017-06-22 02:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsBox(lua_State* L) {
|
2017-10-31 08:14:09 +00:00
|
|
|
return luax_rectangularprism(L, false);
|
2017-06-22 02:42:34 +00:00
|
|
|
}
|
|
|
|
|
2017-11-22 19:32:30 +00:00
|
|
|
int l_lovrGraphicsArc(lua_State* L) {
|
|
|
|
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
|
|
|
|
ArcMode arcMode = ARC_MODE_PIE;
|
|
|
|
int index = 2;
|
|
|
|
if (lua_type(L, 2) == LUA_TSTRING) {
|
|
|
|
arcMode = *(ArcMode*) luax_checkenum(L, index++, &ArcModes, "arc mode");
|
|
|
|
}
|
|
|
|
float transform[16];
|
|
|
|
index = luax_readtransform(L, index, transform, true);
|
|
|
|
float theta1 = luaL_optnumber(L, index++, 0);
|
|
|
|
float theta2 = luaL_optnumber(L, index++, 2 * M_PI);
|
|
|
|
int segments = luaL_optinteger(L, index, 32) * fabsf(theta2 - theta1) * 2 * M_PI + .5f;
|
|
|
|
lovrGraphicsArc(drawMode, arcMode, transform, theta1, theta2, segments);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-11-22 04:53:34 +00:00
|
|
|
int l_lovrGraphicsCircle(lua_State* L) {
|
|
|
|
DrawMode drawMode = *(DrawMode*) luax_checkenum(L, 1, &DrawModes, "draw mode");
|
|
|
|
float transform[16];
|
|
|
|
int index = luax_readtransform(L, 2, transform, true);
|
|
|
|
int segments = luaL_optnumber(L, index, 32);
|
|
|
|
lovrGraphicsCircle(drawMode, transform, segments);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-21 03:54:22 +00:00
|
|
|
int l_lovrGraphicsCylinder(lua_State* L) {
|
|
|
|
float x1 = luaL_checknumber(L, 1);
|
|
|
|
float y1 = luaL_checknumber(L, 2);
|
|
|
|
float z1 = luaL_checknumber(L, 3);
|
|
|
|
float x2 = luaL_checknumber(L, 4);
|
|
|
|
float y2 = luaL_checknumber(L, 5);
|
|
|
|
float z2 = luaL_checknumber(L, 6);
|
|
|
|
float r1 = luaL_optnumber(L, 7, 1);
|
|
|
|
float r2 = luaL_optnumber(L, 8, 1);
|
2017-10-31 08:14:09 +00:00
|
|
|
bool capped = lua_isnoneornil(L, 9) ? true : lua_toboolean(L, 9);
|
2017-06-21 03:54:22 +00:00
|
|
|
int segments = luaL_optnumber(L, 10, floorf(16 + 16 * MAX(r1, r2)));
|
|
|
|
lovrGraphicsCylinder(x1, y1, z1, x2, y2, z2, r1, r2, capped, segments);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-22 06:10:45 +00:00
|
|
|
int l_lovrGraphicsSphere(lua_State* L) {
|
|
|
|
float transform[16];
|
|
|
|
int index = 1;
|
|
|
|
index = luax_readtransform(L, index, transform, 1);
|
|
|
|
int segments = luaL_optnumber(L, index, 30);
|
2017-10-15 23:56:00 +00:00
|
|
|
lovrGraphicsSphere(transform, segments);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsSkybox(lua_State* L) {
|
|
|
|
Texture* texture = luax_checktype(L, 1, Texture);
|
|
|
|
float angle = luaL_optnumber(L, 2, 0);
|
|
|
|
float ax = luaL_optnumber(L, 3, 0);
|
|
|
|
float ay = luaL_optnumber(L, 4, 1);
|
|
|
|
float az = luaL_optnumber(L, 5, 0);
|
|
|
|
lovrGraphicsSkybox(texture, angle, ax, ay, az);
|
2017-06-22 06:10:45 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2017-06-22 02:44:02 +00:00
|
|
|
int l_lovrGraphicsPrint(lua_State* L) {
|
|
|
|
const char* str = luaL_checkstring(L, 1);
|
|
|
|
float transform[16];
|
|
|
|
int index = luax_readtransform(L, 2, transform, 1);
|
|
|
|
float wrap = luaL_optnumber(L, index++, 0);
|
|
|
|
HorizontalAlign halign = *(HorizontalAlign*) luax_optenum(L, index++, "center", &HorizontalAligns, "alignment");
|
|
|
|
VerticalAlign valign = *(VerticalAlign*) luax_optenum(L, index++, "middle", &VerticalAligns, "alignment");
|
|
|
|
lovrGraphicsPrint(str, transform, wrap, halign, valign);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-11-23 05:16:13 +00:00
|
|
|
// Types
|
2016-09-29 05:10:03 +00:00
|
|
|
|
2017-11-03 06:47:13 +00:00
|
|
|
int l_lovrGraphicsNewAnimator(lua_State* L) {
|
|
|
|
Model* model = luax_checktype(L, 1, Model);
|
|
|
|
Animator* animator = lovrAnimatorCreate(model->modelData->animationData);
|
|
|
|
luax_pushtype(L, Animator, animator);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-03-11 22:13:49 +00:00
|
|
|
int l_lovrGraphicsNewFont(lua_State* L) {
|
2017-04-02 12:55:21 +00:00
|
|
|
Blob* blob = NULL;
|
|
|
|
float size;
|
2017-03-11 22:13:49 +00:00
|
|
|
|
|
|
|
if (lua_type(L, 1) == LUA_TNUMBER || lua_isnoneornil(L, 1)) {
|
2017-04-02 12:55:21 +00:00
|
|
|
size = luaL_optnumber(L, 1, 32);
|
2017-03-11 22:13:49 +00:00
|
|
|
} else {
|
2017-04-02 12:55:21 +00:00
|
|
|
blob = luax_readblob(L, 1, "Font");
|
|
|
|
size = luaL_optnumber(L, 2, 32);
|
2017-03-11 22:13:49 +00:00
|
|
|
}
|
|
|
|
|
2017-04-02 12:55:21 +00:00
|
|
|
FontData* fontData = lovrFontDataCreate(blob, size);
|
2017-03-11 22:13:49 +00:00
|
|
|
Font* font = lovrFontCreate(fontData);
|
|
|
|
luax_pushtype(L, Font, font);
|
|
|
|
lovrRelease(&font->ref);
|
2017-04-02 12:55:21 +00:00
|
|
|
|
|
|
|
if (blob) {
|
|
|
|
lovrRelease(&blob->ref);
|
|
|
|
}
|
|
|
|
|
2017-03-11 22:13:49 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-10-21 21:05:58 +00:00
|
|
|
int l_lovrGraphicsNewMaterial(lua_State* L) {
|
|
|
|
MaterialData* materialData = lovrMaterialDataCreateEmpty();
|
2017-10-31 08:14:09 +00:00
|
|
|
Material* material = lovrMaterialCreate(materialData, false);
|
2017-10-21 21:05:58 +00:00
|
|
|
luax_pushtype(L, Material, material);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-03-11 22:13:49 +00:00
|
|
|
int l_lovrGraphicsNewMesh(lua_State* L) {
|
2016-10-10 00:40:02 +00:00
|
|
|
int size;
|
|
|
|
int dataIndex = 0;
|
|
|
|
int drawModeIndex = 2;
|
2017-03-11 22:13:49 +00:00
|
|
|
MeshFormat format;
|
2016-10-10 00:40:02 +00:00
|
|
|
vec_init(&format);
|
|
|
|
|
|
|
|
if (lua_isnumber(L, 1)) {
|
|
|
|
size = lua_tointeger(L, 1);
|
|
|
|
} else if (lua_istable(L, 1)) {
|
|
|
|
if (lua_isnumber(L, 2)) {
|
2016-11-13 10:42:05 +00:00
|
|
|
drawModeIndex++;
|
2017-03-11 22:13:49 +00:00
|
|
|
luax_checkmeshformat(L, 1, &format);
|
2016-10-10 00:40:02 +00:00
|
|
|
size = lua_tointeger(L, 2);
|
|
|
|
dataIndex = 0;
|
|
|
|
} else if (lua_istable(L, 2)) {
|
2016-11-13 10:42:05 +00:00
|
|
|
drawModeIndex++;
|
2017-03-11 22:13:49 +00:00
|
|
|
luax_checkmeshformat(L, 1, &format);
|
2016-10-10 00:40:02 +00:00
|
|
|
size = lua_objlen(L, 2);
|
|
|
|
dataIndex = 2;
|
|
|
|
} else {
|
|
|
|
size = lua_objlen(L, 1);
|
|
|
|
dataIndex = 1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
luaL_argerror(L, 1, "table or number expected");
|
2016-11-08 22:15:37 +00:00
|
|
|
return 0;
|
2016-10-10 00:40:02 +00:00
|
|
|
}
|
|
|
|
|
2017-03-11 22:13:49 +00:00
|
|
|
MeshDrawMode* drawMode = (MeshDrawMode*) luax_optenum(L, drawModeIndex, "fan", &MeshDrawModes, "mesh draw mode");
|
|
|
|
MeshUsage* usage = (MeshUsage*) luax_optenum(L, drawModeIndex + 1, "dynamic", &MeshUsages, "mesh usage");
|
|
|
|
Mesh* mesh = lovrMeshCreate(size, format.length ? &format : NULL, *drawMode, *usage);
|
2016-10-10 00:40:02 +00:00
|
|
|
|
|
|
|
if (dataIndex) {
|
2017-03-12 01:27:18 +00:00
|
|
|
int count = lua_objlen(L, dataIndex);
|
2017-03-11 22:13:49 +00:00
|
|
|
MeshFormat format = lovrMeshGetVertexFormat(mesh);
|
2017-10-31 08:14:09 +00:00
|
|
|
char* vertex = lovrMeshMap(mesh, 0, count, false, true);
|
2017-03-12 01:27:18 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < count; i++) {
|
2016-10-10 00:40:02 +00:00
|
|
|
lua_rawgeti(L, dataIndex, i + 1);
|
|
|
|
if (!lua_istable(L, -1)) {
|
|
|
|
return luaL_error(L, "Vertex information should be specified as a table");
|
|
|
|
}
|
|
|
|
|
2016-11-21 01:33:19 +00:00
|
|
|
int component = 0;
|
|
|
|
for (int j = 0; j < format.length; j++) {
|
2017-03-11 22:13:49 +00:00
|
|
|
MeshAttribute attribute = format.data[j];
|
2016-11-20 23:53:36 +00:00
|
|
|
for (int k = 0; k < attribute.count; k++) {
|
2016-11-21 01:33:19 +00:00
|
|
|
lua_rawgeti(L, -1, ++component);
|
|
|
|
switch (attribute.type) {
|
2017-10-24 02:24:23 +00:00
|
|
|
case MESH_FLOAT:
|
|
|
|
*((float*) vertex) = luaL_optnumber(L, -1, 0.f);
|
|
|
|
vertex += sizeof(float);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MESH_BYTE:
|
|
|
|
*((uint8_t*) vertex) = luaL_optint(L, -1, 255);
|
|
|
|
vertex += sizeof(uint8_t);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case MESH_INT:
|
|
|
|
*((int*) vertex) = luaL_optint(L, -1, 0);
|
|
|
|
vertex += sizeof(int);
|
|
|
|
break;
|
2016-10-10 00:40:02 +00:00
|
|
|
}
|
2016-11-21 01:33:19 +00:00
|
|
|
lua_pop(L, 1);
|
2016-10-10 00:40:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
lua_pop(L, 1);
|
2016-09-17 22:38:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-10 00:40:02 +00:00
|
|
|
vec_deinit(&format);
|
2017-03-11 22:13:49 +00:00
|
|
|
luax_pushtype(L, Mesh, mesh);
|
|
|
|
lovrRelease(&mesh->ref);
|
2017-02-03 23:16:30 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-08-10 06:28:17 +00:00
|
|
|
int l_lovrGraphicsNewModel(lua_State* L) {
|
2017-04-02 12:55:21 +00:00
|
|
|
Blob* blob = luax_readblob(L, 1, "Model");
|
|
|
|
ModelData* modelData = lovrModelDataCreate(blob);
|
2017-01-30 03:03:50 +00:00
|
|
|
Model* model = lovrModelCreate(modelData);
|
|
|
|
luax_pushtype(L, Model, model);
|
2017-02-18 22:44:52 +00:00
|
|
|
lovrRelease(&model->ref);
|
2017-04-02 12:55:21 +00:00
|
|
|
lovrRelease(&blob->ref);
|
2016-08-10 06:28:17 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrGraphicsNewShader(lua_State* L) {
|
2016-11-14 22:42:40 +00:00
|
|
|
for (int i = 0; i < 2; i++) {
|
|
|
|
if (lua_isnoneornil(L, i + 1)) continue;
|
|
|
|
const char* source = luaL_checkstring(L, i + 1);
|
|
|
|
if (!lovrFilesystemIsFile(source)) continue;
|
2017-03-11 09:37:00 +00:00
|
|
|
size_t bytesRead;
|
2016-11-14 22:42:40 +00:00
|
|
|
char* contents = lovrFilesystemRead(source, &bytesRead);
|
|
|
|
if (bytesRead <= 0) {
|
|
|
|
return luaL_error(L, "Could not read shader from file '%s'", source);
|
|
|
|
}
|
|
|
|
lua_pushlstring(L, contents, bytesRead);
|
|
|
|
lua_replace(L, i + 1);
|
|
|
|
free(contents);
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* vertexSource = lua_tostring(L, 1);
|
|
|
|
const char* fragmentSource = lua_tostring(L, 2);
|
2017-08-09 07:56:13 +00:00
|
|
|
Shader* shader = lovrShaderCreate(vertexSource, fragmentSource);
|
2017-02-18 22:44:52 +00:00
|
|
|
luax_pushtype(L, Shader, shader);
|
|
|
|
lovrRelease(&shader->ref);
|
2016-08-10 06:28:17 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2016-10-16 03:11:54 +00:00
|
|
|
|
2016-11-08 11:14:33 +00:00
|
|
|
int l_lovrGraphicsNewTexture(lua_State* L) {
|
2016-11-14 01:28:22 +00:00
|
|
|
Texture* texture;
|
|
|
|
|
2017-04-02 12:55:21 +00:00
|
|
|
if (lua_type(L, 1) == LUA_TNUMBER) {
|
2017-01-09 06:51:43 +00:00
|
|
|
int width = luaL_checknumber(L, 1);
|
|
|
|
int height = luaL_checknumber(L, 2);
|
2017-08-09 08:09:19 +00:00
|
|
|
TextureProjection* projection = luax_optenum(L, 3, "3d", &TextureProjections, "projection");
|
2017-01-15 01:38:25 +00:00
|
|
|
int msaa = luaL_optnumber(L, 4, 0);
|
2017-02-06 04:30:17 +00:00
|
|
|
TextureData* textureData = lovrTextureDataGetEmpty(width, height, FORMAT_RGBA);
|
2017-01-15 01:38:25 +00:00
|
|
|
texture = lovrTextureCreateWithFramebuffer(textureData, *projection, msaa);
|
2017-04-02 12:55:21 +00:00
|
|
|
} else {
|
2017-10-15 23:56:00 +00:00
|
|
|
Blob* blobs[6];
|
2017-10-31 08:14:09 +00:00
|
|
|
bool isTable = lua_istable(L, 1);
|
2017-10-15 23:56:00 +00:00
|
|
|
int count = isTable ? lua_objlen(L, 1) : lua_gettop(L);
|
|
|
|
|
|
|
|
if (count != 1 && count != 6) {
|
|
|
|
return luaL_error(L, "Expected 1 image for a 2D texture or 6 images for a cube texture, got %d", count);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isTable) {
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
lua_rawgeti(L, -1, i + 1);
|
|
|
|
blobs[i] = luax_readblob(L, -1, "Texture");
|
|
|
|
lua_pop(L, 1);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
blobs[i] = luax_readblob(L, i + 1, "Texture");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TextureData* slices[6];
|
|
|
|
for (int i = 0; i < count; i++) {
|
|
|
|
slices[i] = lovrTextureDataFromBlob(blobs[i]);
|
|
|
|
lovrRelease(&blobs[i]->ref);
|
|
|
|
}
|
|
|
|
|
|
|
|
TextureType type = (count == 1) ? TEXTURE_2D : TEXTURE_CUBE;
|
|
|
|
texture = lovrTextureCreate(type, slices, count);
|
2016-11-08 11:14:33 +00:00
|
|
|
}
|
|
|
|
|
2016-11-19 08:57:18 +00:00
|
|
|
luax_pushtype(L, Texture, texture);
|
2017-02-18 22:44:52 +00:00
|
|
|
lovrRelease(&texture->ref);
|
2016-11-08 11:14:33 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2017-03-11 11:08:07 +00:00
|
|
|
|
|
|
|
const luaL_Reg lovrGraphics[] = {
|
|
|
|
{ "reset", l_lovrGraphicsReset },
|
|
|
|
{ "clear", l_lovrGraphicsClear },
|
|
|
|
{ "present", l_lovrGraphicsPresent },
|
2017-08-10 03:02:02 +00:00
|
|
|
{ "createWindow", l_lovrGraphicsCreateWindow },
|
|
|
|
{ "getWidth", l_lovrGraphicsGetWidth },
|
|
|
|
{ "getHeight", l_lovrGraphicsGetHeight },
|
|
|
|
{ "getDimensions", l_lovrGraphicsGetDimensions },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "getBackgroundColor", l_lovrGraphicsGetBackgroundColor },
|
|
|
|
{ "setBackgroundColor", l_lovrGraphicsSetBackgroundColor },
|
2017-03-12 11:03:36 +00:00
|
|
|
{ "getBlendMode", l_lovrGraphicsGetBlendMode },
|
|
|
|
{ "setBlendMode", l_lovrGraphicsSetBlendMode },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "getColor", l_lovrGraphicsGetColor },
|
|
|
|
{ "setColor", l_lovrGraphicsSetColor },
|
|
|
|
{ "isCullingEnabled", l_lovrGraphicsIsCullingEnabled },
|
|
|
|
{ "setCullingEnabled", l_lovrGraphicsSetCullingEnabled },
|
2017-07-23 10:09:07 +00:00
|
|
|
{ "getDefaultFilter", l_lovrGraphicsGetDefaultFilter },
|
|
|
|
{ "setDefaultFilter", l_lovrGraphicsSetDefaultFilter },
|
2017-08-28 05:59:51 +00:00
|
|
|
{ "getDepthTest", l_lovrGraphicsGetDepthTest },
|
|
|
|
{ "setDepthTest", l_lovrGraphicsSetDepthTest },
|
2017-08-10 03:02:02 +00:00
|
|
|
{ "getFont", l_lovrGraphicsGetFont },
|
|
|
|
{ "setFont", l_lovrGraphicsSetFont },
|
2017-08-02 07:54:33 +00:00
|
|
|
{ "getSystemLimits", l_lovrGraphicsGetSystemLimits },
|
|
|
|
{ "getLineWidth", l_lovrGraphicsGetLineWidth },
|
|
|
|
{ "setLineWidth", l_lovrGraphicsSetLineWidth },
|
2017-10-21 21:32:41 +00:00
|
|
|
{ "getMaterial", l_lovrGraphicsGetMaterial },
|
|
|
|
{ "setMaterial", l_lovrGraphicsSetMaterial },
|
2017-08-02 07:54:33 +00:00
|
|
|
{ "getPointSize", l_lovrGraphicsGetPointSize },
|
|
|
|
{ "setPointSize", l_lovrGraphicsSetPointSize },
|
2017-08-10 03:02:02 +00:00
|
|
|
{ "getShader", l_lovrGraphicsGetShader },
|
|
|
|
{ "setShader", l_lovrGraphicsSetShader },
|
2017-08-02 07:54:33 +00:00
|
|
|
{ "getWinding", l_lovrGraphicsGetWinding },
|
|
|
|
{ "setWinding", l_lovrGraphicsSetWinding },
|
|
|
|
{ "isWireframe", l_lovrGraphicsIsWireframe },
|
|
|
|
{ "setWireframe", l_lovrGraphicsSetWireframe },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "push", l_lovrGraphicsPush },
|
|
|
|
{ "pop", l_lovrGraphicsPop },
|
|
|
|
{ "origin", l_lovrGraphicsOrigin },
|
|
|
|
{ "translate", l_lovrGraphicsTranslate },
|
|
|
|
{ "rotate", l_lovrGraphicsRotate },
|
|
|
|
{ "scale", l_lovrGraphicsScale },
|
|
|
|
{ "transform", l_lovrGraphicsTransform },
|
|
|
|
{ "points", l_lovrGraphicsPoints },
|
|
|
|
{ "line", l_lovrGraphicsLine },
|
|
|
|
{ "triangle", l_lovrGraphicsTriangle },
|
|
|
|
{ "plane", l_lovrGraphicsPlane },
|
|
|
|
{ "cube", l_lovrGraphicsCube },
|
2017-06-22 02:42:34 +00:00
|
|
|
{ "box", l_lovrGraphicsBox },
|
2017-11-22 19:32:30 +00:00
|
|
|
{ "arc", l_lovrGraphicsArc },
|
2017-11-22 04:53:34 +00:00
|
|
|
{ "circle", l_lovrGraphicsCircle },
|
2017-06-21 03:54:22 +00:00
|
|
|
{ "cylinder", l_lovrGraphicsCylinder },
|
2017-06-22 06:10:45 +00:00
|
|
|
{ "sphere", l_lovrGraphicsSphere },
|
2017-10-15 23:56:00 +00:00
|
|
|
{ "skybox", l_lovrGraphicsSkybox },
|
2017-06-22 02:44:02 +00:00
|
|
|
{ "print", l_lovrGraphicsPrint },
|
2017-11-03 06:47:13 +00:00
|
|
|
{ "newAnimator", l_lovrGraphicsNewAnimator },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "newFont", l_lovrGraphicsNewFont },
|
2017-10-21 21:05:58 +00:00
|
|
|
{ "newMaterial", l_lovrGraphicsNewMaterial },
|
2017-03-11 22:13:49 +00:00
|
|
|
{ "newMesh", l_lovrGraphicsNewMesh },
|
2017-03-11 11:08:07 +00:00
|
|
|
{ "newModel", l_lovrGraphicsNewModel },
|
|
|
|
{ "newShader", l_lovrGraphicsNewShader },
|
|
|
|
{ "newTexture", l_lovrGraphicsNewTexture },
|
|
|
|
{ NULL, NULL }
|
|
|
|
};
|