Improve newCanvas API;

This commit is contained in:
bjorn 2018-08-31 16:37:30 -07:00
parent a5256aaa27
commit dca52ee967
4 changed files with 99 additions and 18 deletions

View File

@ -1,6 +1,7 @@
#include "luax.h"
#include "data/blob.h"
#include "event/event.h"
#include "graphics/canvas.h"
#include "graphics/mesh.h"
#include "math/math.h"
#include "math/randomGenerator.h"
@ -122,3 +123,4 @@ int luax_checkuniform(lua_State* L, int index, const Uniform* uniform, void* des
void luax_checkuniformtype(lua_State* L, int index, UniformType* baseType, int* components);
int luax_optmipmap(lua_State* L, int index, Texture* texture);
Texture* luax_checktexture(lua_State* L, int index);
void luax_readattachments(lua_State* L, int index, Attachment* attachments, int* count);

View File

@ -929,12 +929,32 @@ int l_lovrGraphicsNewShaderBlock(lua_State* L) {
}
int l_lovrGraphicsNewCanvas(lua_State* L) {
int width = luaL_checkinteger(L, 1);
int height = luaL_checkinteger(L, 2);
Attachment attachments[MAX_CANVAS_ATTACHMENTS];
bool anonymous = false;
int attachmentCount = 0;
int width = 0;
int height = 0;
int index;
if (luax_totype(L, 1, Texture)) {
for (index = 1; index <= MAX_CANVAS_ATTACHMENTS; index++) {
Texture* texture = luax_totype(L, index, Texture);
if (!texture) break;
attachments[attachmentCount++] = (Attachment) { texture, 0, 0 };
}
} else if (lua_istable(L, 1)) {
luax_readattachments(L, 1, attachments, &attachmentCount);
index = 2;
} else {
width = luaL_checkinteger(L, 1);
height = luaL_checkinteger(L, 2);
index = 3;
}
CanvasFlags flags = { .depth = DEPTH_D16, .stereo = true, .msaa = 0, .mipmaps = true };
if (lua_istable(L, 3)) {
lua_getfield(L, 3, "depth");
if (lua_istable(L, index)) {
lua_getfield(L, index, "depth");
switch (lua_type(L, -1)) {
case LUA_TNIL: break;
case LUA_TBOOLEAN: flags.depth = lua_toboolean(L, -1) ? DEPTH_D16 : DEPTH_NONE; break;
@ -942,20 +962,46 @@ int l_lovrGraphicsNewCanvas(lua_State* L) {
}
lua_pop(L, 1);
lua_getfield(L, 3, "stereo");
lua_getfield(L, index, "stereo");
flags.stereo = lua_isnil(L, -1) ? flags.stereo : lua_toboolean(L, -1);
lua_pop(L, 1);
lua_getfield(L, 3, "msaa");
lua_getfield(L, index, "msaa");
flags.msaa = lua_isnil(L, -1) ? flags.msaa : luaL_checkinteger(L, -1);
lua_pop(L, 1);
lua_getfield(L, 3, "mipmaps");
lua_getfield(L, index, "mipmaps");
flags.mipmaps = lua_isnil(L, -1) ? flags.mipmaps : lua_toboolean(L, -1);
lua_pop(L, 1);
if (attachmentCount == 0) {
lua_getfield(L, index, "format");
if (lua_type(L, -1) == LUA_TSTRING) {
TextureFormat format = luaL_checkoption(L, -1, "rgba", TextureFormats);
Texture* texture = lovrTextureCreate(TEXTURE_2D, NULL, 0, true, flags.mipmaps, flags.msaa);
lovrTextureAllocate(texture, width, height, 1, format);
attachments[0] = (Attachment) { texture, 0, 0 };
attachmentCount++;
anonymous = true;
}
lua_pop(L, 1);
}
}
if (width == 0 && height == 0 && attachmentCount > 0) {
width = lovrTextureGetWidth(attachments[0].texture, attachments[0].level);
height = lovrTextureGetHeight(attachments[0].texture, attachments[0].level);
}
Canvas* canvas = lovrCanvasCreate(width, height, flags);
if (attachmentCount > 0) {
lovrCanvasSetAttachments(canvas, attachments, attachmentCount);
if (anonymous) {
lovrRelease(attachments[0].texture);
}
}
luax_pushobject(L, canvas);
lovrRelease(canvas);
return 1;

View File

@ -13,14 +13,53 @@ Texture* luax_checktexture(lua_State* L, int index) {
}
static int luax_checkattachment(lua_State* L, int index, Attachment* attachment) {
attachment->texture = luax_checktype(L, index++, Texture);
attachment->slice = lua_type(L, index) == LUA_TNUMBER ? lua_tointeger(L, index++) - 1 : 0;
attachment->level = lua_type(L, index) == LUA_TNUMBER ? luax_optmipmap(L, index++, attachment->texture) : 0;
if (lua_istable(L, index)) {
lua_rawgeti(L, index, 1);
attachment->texture = luax_checktype(L, -1, Texture);
lua_pop(L, 1);
lua_rawgeti(L, index, 2);
attachment->slice = luaL_optinteger(L, -1, 1) - 1;
lua_pop(L, 1);
lua_rawgeti(L, index, 3);
attachment->level = luax_optmipmap(L, -1, attachment->texture);
lua_pop(L, 1);
index++;
} else {
attachment->texture = luax_checktype(L, index++, Texture);
attachment->slice = lua_type(L, index) == LUA_TNUMBER ? lua_tointeger(L, index++) - 1 : 0;
attachment->level = lua_type(L, index) == LUA_TNUMBER ? luax_optmipmap(L, index++, attachment->texture) : 0;
}
bool isValidSlice = attachment->slice >= 0 && attachment->slice < lovrTextureGetDepth(attachment->texture, 0);
lovrAssert(isValidSlice, "Invalid slice %d\n", attachment->slice + 1);
return index;
}
void luax_readattachments(lua_State* L, int index, Attachment* attachments, int* count) {
bool table = lua_istable(L, index);
int top = table ? -1 : lua_gettop(L);
int n;
if (lua_istable(L, index)) {
n = lua_objlen(L, index);
n = MIN(n, 3 * MAX_CANVAS_ATTACHMENTS);
for (int i = 0; i < n; i++) {
lua_rawgeti(L, index, i + 1);
}
index = -n;
}
for (*count = 0; *count < MAX_CANVAS_ATTACHMENTS && index <= top; (*count)++) {
index = luax_checkattachment(L, index, attachments + *count);
}
if (table) {
lua_pop(L, n);
}
}
int l_lovrCanvasNewTextureData(lua_State* L) {
Canvas* canvas = luax_checktype(L, 1, Canvas);
int index = luaL_optinteger(L, 2, 1) - 1;
@ -58,14 +97,8 @@ int l_lovrCanvasSetTexture(lua_State* L) {
Canvas* canvas = luax_checktype(L, 1, Canvas);
Attachment attachments[MAX_CANVAS_ATTACHMENTS];
int count;
int index = 2;
int top = lua_gettop(L);
for (count = 0; count < MAX_CANVAS_ATTACHMENTS && index <= top; count++) {
index = luax_checkattachment(L, index, attachments + count);
}
luax_readattachments(L, 2, attachments, &count);
lovrCanvasSetAttachments(canvas, attachments, count);
return 0;
}

View File

@ -23,7 +23,7 @@ Mesh* lovrMeshCreate(uint32_t count, VertexFormat format, MeshDrawMode drawMode,
void lovrMeshDestroy(void* ref);
void lovrMeshAttachAttribute(Mesh* mesh, Mesh* other, const char* name, int divisor);
void lovrMeshDetachAttribute(Mesh* mesh, const char* name);
void lovrMeshBind(Mesh* mesh, Shader* shader);
void lovrMeshBind(Mesh* mesh, Shader* shader, int divisorMultiplier);
void lovrMeshDraw(Mesh* mesh, int instances);
VertexFormat* lovrMeshGetVertexFormat(Mesh* mesh);
MeshDrawMode lovrMeshGetDrawMode(Mesh* mesh);