summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsanine-a <sanine.not@pm.me>2020-12-16 23:34:37 -0600
committersanine-a <sanine.not@pm.me>2020-12-16 23:34:37 -0600
commit5e54281d71d3ab4c1ba19888bb1aac9ad51673d0 (patch)
tree160c5bb300fa9b406cce9ceef5a4c9a608c07283
parent2263acad65be7c881e81f2dc845d4acaefb9603e (diff)
add textures to cairo bindings
-rw-r--r--src/cairo_bindings.c90
-rw-r--r--src/texture.c2
-rw-r--r--src/texture.h2
3 files changed, 82 insertions, 12 deletions
diff --git a/src/cairo_bindings.c b/src/cairo_bindings.c
index 95dea92..99ad7d9 100644
--- a/src/cairo_bindings.c
+++ b/src/cairo_bindings.c
@@ -3,6 +3,8 @@
int honey_cairo_mt_ref = LUA_NOREF;
+static const cairo_user_data_key_t TEXTURE_KEY;
+
int honey_setup_cairo(lua_State* L)
{
honey_lua_create_table
@@ -19,19 +21,66 @@ int honey_setup_cairo(lua_State* L)
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-int honey_cairo_new(lua_State* L)
+struct texture_ref {
+ int id;
+ lua_State* L;
+};
+
+static void destroy_texture_ref(void* data)
{
- int width, height;
- honey_lua_parse_arguments(L, 1, 2, HONEY_INTEGER, &width, HONEY_INTEGER, &height);
+ struct texture_ref* ref = data;
+ luaL_unref(ref->L, LUA_REGISTRYINDEX, ref->id);
+ free(ref);
+}
+int honey_cairo_new(lua_State* L)
+{
+ int choice = honey_lua_parse_arguments(L, 2, 0, 1, HONEY_TABLE, NULL);
+
+ lua_pushcfunction(L, honey_lua_texture_new);
+ if (choice == 0)
+ honey_lua_pcall(L, 0, 1);
+ else {
+ lua_pushvalue(L, 1);
+ honey_lua_pcall(L, 1, 1);
+ }
+
+ /* configure texture swizzling ARGB -> RGBA */
+ honey_texture* texture = lua_touserdata(L, -1);
+ glBindTexture(GL_TEXTURE_2D, texture->id);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_GREEN);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_ALPHA);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED);
+
+ /* setup texture reference */
+ struct texture_ref* ref = malloc(sizeof(struct texture_ref));
+ if (ref == NULL)
+ honey_lua_throw_error
+ (L, "failed to allocate memory for texture handle!");
+
+ ref->id = luaL_ref(L, LUA_REGISTRYINDEX);
+
+ /* create cairo surface */
cairo_surface_t** surface = lua_newuserdata(L, sizeof(cairo_surface_t*));
- *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
-
+ *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+ texture->params.width,
+ texture->params.height);
+
cairo_status_t status = cairo_surface_status(*surface);
if (status != CAIRO_STATUS_SUCCESS)
honey_lua_throw_error
(L, "libcairo error: %s", cairo_status_to_string(status));
+ /* bind texture ref to surface userdata */
+ status = cairo_surface_set_user_data(*surface,
+ &TEXTURE_KEY,
+ ref,
+ destroy_texture_ref);
+ if (status != CAIRO_STATUS_SUCCESS)
+ honey_lua_throw_error
+ (L, "libcairo error: %s", cairo_status_to_string(status));
+
lua_rawgeti(L, LUA_REGISTRYINDEX, honey_cairo_mt_ref);
lua_setmetatable(L, -2);
@@ -40,18 +89,37 @@ int honey_cairo_new(lua_State* L)
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-int honey_cairo_get_texture(lua_State* L)
+int honey_cairo_update_texture(lua_State* L)
{
- /* todo
cairo_surface_t** surface;
honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &surface);
- unsigned char* data = cairo_image_surface_get_data(*surface);
- honey_texture* texture = lua_newuserdata(L, sizeof(honey_texture));
+ struct texture_ref *ref = cairo_surface_get_user_data(*surface, &TEXTURE_KEY);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, ref->id);
+ honey_texture* texture = lua_touserdata(L, -1);
+ lua_pop(L, 1);
- glGenTextures(1, &(texture->id));
glBindTexture(GL_TEXTURE_2D, texture->id);
- */
+ unsigned char* image_data = cairo_image_surface_get_data(*surface);
+ glTexSubImage2D(GL_TEXTURE_2D,
+ 0, 0, 0,
+ texture->params.width,
+ texture->params.height,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ image_data);
+ return 0;
+}
+
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+int honey_cairo_get_texture(lua_State* L)
+{
+ cairo_surface_t** surface;
+ honey_lua_parse_arguments(L, 1, 1, HONEY_USERDATA, &surface);
+
+ struct texture_ref *ref = cairo_surface_get_user_data(*surface, &TEXTURE_KEY);
+ lua_rawgeti(L, LUA_REGISTRYINDEX, ref->id);
return 1;
}
diff --git a/src/texture.c b/src/texture.c
index 32240c6..4dbc8d1 100644
--- a/src/texture.c
+++ b/src/texture.c
@@ -36,7 +36,7 @@ static void setup_texture(lua_State* L, honey_texture** tex, bool use_params)
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-static int honey_lua_texture_new(lua_State* L)
+int honey_lua_texture_new(lua_State* L)
{
honey_texture* texture;
int choice = honey_lua_parse_arguments(L, 2, 0, 1, HONEY_TABLE, NULL);
diff --git a/src/texture.h b/src/texture.h
index e822a59..fbabdda 100644
--- a/src/texture.h
+++ b/src/texture.h
@@ -54,6 +54,8 @@ typedef struct {
/** @brief Place the honey.texture bindings as a table on the stack. */
void honey_setup_texture(lua_State* L);
+int honey_lua_texture_new(lua_State* L);
+
/** @brief Generate a texture.
*
* @param[out] texture Pointer to the destination texture.