mirror of https://github.com/bjornbytes/lovr.git
117 lines
3.1 KiB
C
117 lines
3.1 KiB
C
#include "api.h"
|
|
#include "graphics/graphics.h"
|
|
#include "util.h"
|
|
#include <stdlib.h>
|
|
|
|
static int l_lovrShaderClone(lua_State* L) {
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
luaL_checktype(L, 2, LUA_TTABLE);
|
|
lua_pushnil(L);
|
|
|
|
arr_t(ShaderFlag) flags;
|
|
arr_init(&flags);
|
|
|
|
while (lua_next(L, 2) != 0) {
|
|
ShaderFlag flag = { 0 };
|
|
flag.value = lua_isboolean(L, -1) ? (double) lua_toboolean(L, -1) : lua_tonumber(L, -1);
|
|
switch (lua_type(L, -2)) {
|
|
case LUA_TSTRING: flag.name = lua_tostring(L, -2); break;
|
|
case LUA_TNUMBER: flag.id = lua_tointeger(L, -2); break;
|
|
default: lovrThrow("Unexpected ShaderFlag key type (%s)", lua_typename(L, lua_type(L, -2)));
|
|
}
|
|
arr_push(&flags, flag);
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
lovrCheck(flags.length < 1000, "Too many Shader flags");
|
|
|
|
Shader* clone = lovrShaderClone(shader, flags.data, (uint32_t) flags.length);
|
|
arr_free(&flags);
|
|
|
|
luax_pushtype(L, Shader, clone);
|
|
lovrRelease(clone, lovrShaderDestroy);
|
|
return 1;
|
|
}
|
|
|
|
static int l_lovrShaderGetType(lua_State* L) {
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
const ShaderInfo* info = lovrShaderGetInfo(shader);
|
|
luax_pushenum(L, ShaderType, info->type);
|
|
return 1;
|
|
}
|
|
|
|
static int l_lovrShaderHasStage(lua_State* L) {
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
ShaderStage stage = luax_checkenum(L, 2, ShaderStage, NULL);
|
|
bool present = lovrShaderHasStage(shader, stage);
|
|
lua_pushboolean(L, present);
|
|
return 1;
|
|
}
|
|
|
|
static int l_lovrShaderHasAttribute(lua_State* L) {
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
const char* name;
|
|
uint32_t location;
|
|
if (lua_type(L, 2) == LUA_TNUMBER) {
|
|
location = luax_checku32(L, 2);
|
|
name = NULL;
|
|
} else {
|
|
name = lua_tostring(L, 2);
|
|
location = 0;
|
|
}
|
|
bool present = lovrShaderHasAttribute(shader, name, location);
|
|
lua_pushboolean(L, present);
|
|
return 1;
|
|
}
|
|
|
|
static int l_lovrShaderGetWorkgroupSize(lua_State* L) {
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
|
|
if (!lovrShaderHasStage(shader, STAGE_COMPUTE)) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
uint32_t size[3];
|
|
lovrShaderGetWorkgroupSize(shader, size);
|
|
lua_pushinteger(L, size[0]);
|
|
lua_pushinteger(L, size[1]);
|
|
lua_pushinteger(L, size[2]);
|
|
return 3;
|
|
}
|
|
|
|
static int l_lovrShaderGetBufferFormat(lua_State* L) {
|
|
Shader* shader = luax_checktype(L, 1, Shader);
|
|
const char* name = luaL_checkstring(L, 2);
|
|
|
|
uint32_t fieldCount;
|
|
const DataField* format = lovrShaderGetBufferFormat(shader, name, &fieldCount);
|
|
|
|
if (!format) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
luax_pushbufferformat(L, format->fields, format->fieldCount);
|
|
lua_pushinteger(L, format->stride);
|
|
lua_setfield(L, -2, "stride");
|
|
|
|
if (format->length == 0 || format->length == ~0u) {
|
|
lua_pushnil(L);
|
|
} else {
|
|
lua_pushinteger(L, format->length);
|
|
}
|
|
|
|
return 2;
|
|
}
|
|
|
|
const luaL_Reg lovrShader[] = {
|
|
{ "clone", l_lovrShaderClone },
|
|
{ "getType", l_lovrShaderGetType },
|
|
{ "hasStage", l_lovrShaderHasStage },
|
|
{ "hasAttribute", l_lovrShaderHasAttribute },
|
|
{ "getWorkgroupSize", l_lovrShaderGetWorkgroupSize },
|
|
{ "getBufferFormat", l_lovrShaderGetBufferFormat },
|
|
{ NULL, NULL }
|
|
};
|