lovr/src/api/l_graphics_texture.c

218 lines
6.9 KiB
C

#include "api.h"
#include "util.h"
#include "graphics/graphics.h"
#include "data/image.h"
#include <string.h>
static int l_lovrTextureGetType(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
const TextureInfo* info = lovrTextureGetInfo(texture);
luax_pushenum(L, TextureType, info->type);
return 1;
}
static int l_lovrTextureGetFormat(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
const TextureInfo* info = lovrTextureGetInfo(texture);
luax_pushenum(L, TextureFormat, info->format);
lua_pushboolean(L, !info->srgb);
return 2;
}
static int l_lovrTextureGetWidth(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
const TextureInfo* info = lovrTextureGetInfo(texture);
lua_pushinteger(L, info->width);
return 1;
}
static int l_lovrTextureGetHeight(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
const TextureInfo* info = lovrTextureGetInfo(texture);
lua_pushinteger(L, info->height);
return 1;
}
static int l_lovrTextureGetLayerCount(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
const TextureInfo* info = lovrTextureGetInfo(texture);
lua_pushinteger(L, info->layers);
return 1;
}
static int l_lovrTextureGetDimensions(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
const TextureInfo* info = lovrTextureGetInfo(texture);
lua_pushinteger(L, info->width);
lua_pushinteger(L, info->height);
lua_pushinteger(L, info->layers);
return 3;
}
static int l_lovrTextureGetMipmapCount(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
const TextureInfo* info = lovrTextureGetInfo(texture);
lua_pushinteger(L, info->mipmaps);
return 1;
}
static int l_lovrTextureGetSampleCount(lua_State* L) { // Deprecated
lua_pushinteger(L, 1);
return 1;
}
static int l_lovrTextureHasUsage(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
const TextureInfo* info = lovrTextureGetInfo(texture);
luaL_checkany(L, 2);
int top = lua_gettop(L);
for (int i = 2; i <= top; i++) {
int bit = luax_checkenum(L, i, TextureUsage, NULL);
if (~info->usage & (1 << bit)) {
lua_pushboolean(L, false);
}
}
lua_pushboolean(L, true);
return 1;
}
static int l_lovrTextureNewReadback(lua_State* L) {
Texture* texture = luax_totype(L, 1, Texture);
uint32_t offset[4], extent[3];
offset[0] = luax_optu32(L, 2, 0);
offset[1] = luax_optu32(L, 3, 0);
offset[2] = luax_optu32(L, 4, 1) - 1;
offset[3] = luax_optu32(L, 5, 1) - 1;
extent[0] = luax_optu32(L, 6, ~0u);
extent[1] = luax_optu32(L, 7, ~0u);
extent[2] = 1;
Readback* readback = lovrReadbackCreateTexture(texture, offset, extent);
luax_pushtype(L, Readback, readback);
lovrRelease(readback, lovrReadbackDestroy);
return 1;
}
static int l_lovrTextureGetPixels(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
uint32_t offset[4], extent[3];
offset[0] = luax_optu32(L, 2, 0);
offset[1] = luax_optu32(L, 3, 0);
offset[2] = luax_optu32(L, 4, 1) - 1;
offset[3] = luax_optu32(L, 5, 1) - 1;
extent[0] = luax_optu32(L, 6, ~0u);
extent[1] = luax_optu32(L, 7, ~0u);
extent[2] = 1;
Image* image = lovrTextureGetPixels(texture, offset, extent);
luax_pushtype(L, Image, image);
lovrRelease(image, lovrImageDestroy);
return 1;
}
static int l_lovrTextureSetPixels(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
Image* image = luax_totype(L, 2, Image);
if (image) {
uint32_t dstOffset[4];
uint32_t srcOffset[4];
uint32_t extent[3];
dstOffset[0] = luax_optu32(L, 3, 0);
dstOffset[1] = luax_optu32(L, 4, 0);
dstOffset[2] = luax_optu32(L, 5, 1) - 1;
dstOffset[3] = luax_optu32(L, 6, 1) - 1;
srcOffset[0] = luax_optu32(L, 7, 0);
srcOffset[1] = luax_optu32(L, 8, 0);
srcOffset[2] = luax_optu32(L, 9, 1) - 1;
srcOffset[3] = luax_optu32(L, 10, 1) - 1;
extent[0] = luax_optu32(L, 11, ~0u);
extent[1] = luax_optu32(L, 12, ~0u);
extent[2] = luax_optu32(L, 13, ~0u);
lovrTextureSetPixels(texture, image, dstOffset, srcOffset, extent);
return 0;
}
Texture* src = luax_totype(L, 2, Texture);
if (texture) {
Texture* dst = texture;
uint32_t dstOffset[4];
uint32_t srcOffset[4];
uint32_t dstExtent[3];
uint32_t srcExtent[3];
dstOffset[0] = luax_optu32(L, 3, 0);
dstOffset[1] = luax_optu32(L, 4, 0);
dstOffset[2] = luax_optu32(L, 5, 1) - 1;
dstOffset[3] = luax_optu32(L, 6, 1) - 1;
srcOffset[0] = luax_optu32(L, 7, 0);
srcOffset[1] = luax_optu32(L, 8, 0);
srcOffset[2] = luax_optu32(L, 9, 1) - 1;
srcOffset[3] = luax_optu32(L, 10, 1) - 1;
dstExtent[0] = luax_optu32(L, 11, ~0u);
dstExtent[1] = luax_optu32(L, 12, ~0u);
dstExtent[2] = luax_optu32(L, 13, ~0u);
srcExtent[0] = luax_optu32(L, 14, dstExtent[0]);
srcExtent[1] = luax_optu32(L, 15, dstExtent[1]);
srcExtent[2] = luax_optu32(L, 16, dstExtent[2]);
FilterMode filter = luax_checkenum(L, 17, FilterMode, "linear");
if (srcExtent[0] == dstExtent[0] && srcExtent[1] == dstExtent[1] && srcExtent[2] == dstExtent[2]) {
lovrTextureCopy(src, dst, srcOffset, dstOffset, dstExtent);
} else {
lovrTextureBlit(src, dst, srcOffset, dstOffset, srcExtent, dstExtent, filter);
}
return 0;
}
return luax_typeerror(L, 2, "Image or Texture");
}
static int l_lovrTextureClear(lua_State* L) {
Texture* texture = luax_totype(L, 1, Texture);
int index;
float value[4];
if (lua_isnoneornil(L, 2)) {
memset(value, 0, sizeof(value));
index = 3;
} else if (lua_type(L, 2) == LUA_TNUMBER && lua_gettop(L) > 2) {
luax_readcolor(L, 2, value);
index = 6;
} else {
luax_optcolor(L, 2, value);
index = 3;
}
uint32_t layer = luax_optu32(L, index++, 1) - 1;
uint32_t layerCount = luax_optu32(L, index++, ~0u);
uint32_t level = luax_optu32(L, index++, 1) - 1;
uint32_t levelCount = luax_optu32(L, index++, ~0u);
lovrTextureClear(texture, value, layer, layerCount, level, levelCount);
return 0;
}
static int l_lovrTextureGenerateMipmaps(lua_State* L) {
Texture* texture = luax_checktype(L, 1, Texture);
uint32_t base = luax_optu32(L, 2, 1) - 1;
uint32_t count = luax_optu32(L, 3, ~0u);
lovrTextureGenerateMipmaps(texture, base, count);
return 0;
}
const luaL_Reg lovrTexture[] = {
{ "getType", l_lovrTextureGetType },
{ "getFormat", l_lovrTextureGetFormat },
{ "getWidth", l_lovrTextureGetWidth },
{ "getHeight", l_lovrTextureGetHeight },
{ "getLayerCount", l_lovrTextureGetLayerCount },
{ "getDimensions", l_lovrTextureGetDimensions },
{ "getMipmapCount", l_lovrTextureGetMipmapCount },
{ "getSampleCount", l_lovrTextureGetSampleCount }, // Deprecated
{ "hasUsage", l_lovrTextureHasUsage },
{ "newReadback", l_lovrTextureNewReadback },
{ "getPixels", l_lovrTextureGetPixels },
{ "setPixels", l_lovrTextureSetPixels },
{ "clear", l_lovrTextureClear },
{ "generateMipmaps", l_lovrTextureGenerateMipmaps },
{ NULL, NULL }
};