diff options
author | sanine <sanine.not@pm.me> | 2022-09-28 17:42:56 -0500 |
---|---|---|
committer | sanine <sanine.not@pm.me> | 2022-09-28 17:42:56 -0500 |
commit | 1cf9cc3408af7008451f9133fb95af66a9697d15 (patch) | |
tree | b5c62dade54a67aefbb234ec9a35cfcf6d486120 | |
parent | 40e4c6890f3f94e360b5e0249ad0045f2133b390 (diff) |
add basic cairo demo functions
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | demo/honey.lua | 45 | ||||
-rw-r--r-- | src/gl/texture.c | 12 | ||||
-rw-r--r-- | src/image/image.c | 180 |
4 files changed, 225 insertions, 14 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b63625..46db609 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,7 +42,7 @@ add_subdirectory(${LIB_ROOT}/cargs) set(HONEY_SOURCE ${SRC_ROOT}/main.c) add_executable(honey ${HONEY_SOURCE}) -set(LIBRARIES lua5.1 honeysuckle glfw cargs assimp) +set(LIBRARIES lua5.1 honeysuckle glfw cargs assimp cairo) if (WIN32) set(LIBRARIES ${LIBRARIES} opengl32) else() diff --git a/demo/honey.lua b/demo/honey.lua index 113d845..d543488 100644 --- a/demo/honey.lua +++ b/demo/honey.lua @@ -188,15 +188,43 @@ gl.UseProgram(shader) gl.Uniform1i(gl.GetUniformLocation(shader, 'ourTexture'), 0) +--===== generate cairo texture =====-- + +local image = honey.image +local surface = image.surface_create(image.FORMAT_ARGB32, 512, 512) +local cr = image.context_create(surface) +image.context_select_font_face(cr, "sans-serif", image.FONT_SLANT_NORMAL, image.FONT_WEIGHT_NORMAL) +image.context_set_font_size(cr, 32) +image.context_set_source_rgb(cr, 1, 0, 0) +image.context_move_to(cr, 100, 100) +image.context_show_text(cr, "hello, world!") +local data = image.surface_get_data(surface) +gl.BindTexture(gl.TEXTURE_2D, texture) +gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_SWIZZLE_R, gl.GREEN) +gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_SWIZZLE_G, gl.BLUE) +gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_SWIZZLE_B, gl.ALPHA) +--gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_SWIZZLE_A, gl.RED) +gl.TexImage2D( + gl.TEXTURE_2D, 0, + gl.RGB, width, height, + gl.RGBA, gl.UNSIGNED_BYTE, + data +) +gl.GenerateMipmap(gl.TEXTURE_2D) + + --====== matrices ======-- local model = honey.glm.mat4() -honey.glm.mat4_identity(model) -local axis = honey.glm.vec3() -honey.glm.vec3_set(axis, 0, 1.0) -honey.glm.vec3_set(axis, 1, 0.0) -honey.glm.vec3_set(axis, 2, 0.0) -honey.glm.rotate(model, math.rad(-90), axis) +local axis1 = honey.glm.vec3() +honey.glm.vec3_set(axis1, 0, 1.0) +honey.glm.vec3_set(axis1, 1, 0.0) +honey.glm.vec3_set(axis1, 2, 0.0) + +local axis2 = honey.glm.vec3() +honey.glm.vec3_set(axis2, 0, 0.0) +honey.glm.vec3_set(axis2, 1, 1.0) +honey.glm.vec3_set(axis2, 2, 0.0) local view = honey.glm.mat4() honey.glm.mat4_identity(view) @@ -230,7 +258,8 @@ while not window.shouldClose(w) do local projectionL = gl.GetUniformLocation(shader, 'projection') honey.glm.mat4_identity(model) - honey.glm.rotate(model, math.pi*time, axis) + honey.glm.rotate(model, 0.5*math.pi*time, axis2) + honey.glm.rotate(model, math.rad(-90), axis1) gl.UniformMatrix4fv(modelL, false, model) gl.UniformMatrix4fv(viewL, false, view) @@ -251,3 +280,5 @@ end window.destroy(w) gl.Terminate() honey.audio.engine_uninit(engine) +image.surface_destroy(surface) +image.context_destroy(cr) diff --git a/src/gl/texture.c b/src/gl/texture.c index f9a65b3..002ec95 100644 --- a/src/gl/texture.c +++ b/src/gl/texture.c @@ -37,6 +37,10 @@ void setup_texture(lua_State *L, int gl_index) hs_str_int("TEXTURE_WRAP_T", GL_TEXTURE_WRAP_T), hs_str_int("TEXTURE_MIN_FILTER", GL_TEXTURE_MIN_FILTER), hs_str_int("TEXTURE_MAG_FILTER", GL_TEXTURE_MAG_FILTER), + hs_str_int("TEXTURE_SWIZZLE_R", GL_TEXTURE_SWIZZLE_R), + hs_str_int("TEXTURE_SWIZZLE_G", GL_TEXTURE_SWIZZLE_G), + hs_str_int("TEXTURE_SWIZZLE_B", GL_TEXTURE_SWIZZLE_B), + hs_str_int("TEXTURE_SWIZZLE_A", GL_TEXTURE_SWIZZLE_A), /* wrapping types */ hs_str_int("REPEAT", GL_REPEAT), @@ -44,6 +48,14 @@ void setup_texture(lua_State *L, int gl_index) /* filter types */ hs_str_int("NEAREST", GL_NEAREST), hs_str_int("LINEAR", GL_LINEAR), + + /* swizzle targets */ + hs_str_int("RED", GL_RED), + hs_str_int("GREEN", GL_GREEN), + hs_str_int("BLUE", GL_BLUE), + hs_str_int("ALPHA", GL_ALPHA), + hs_str_int("ZERO", GL_ZERO), + hs_str_int("ONE", GL_ONE), ); append_table(L, gl_index, tbl); diff --git a/src/image/image.c b/src/image/image.c index a8a0502..1c747e2 100644 --- a/src/image/image.c +++ b/src/image/image.c @@ -1,10 +1,61 @@ #include <lua.h> #include <honeysuckle.h> +#include <cairo/cairo.h> /* assimp provides its own stb_image implementation */ /*#define STB_IMAGE_IMPLEMENTATION*/ #include "stb_image.h" #include "image.h" + +int load_image(lua_State *L); +int free_image(lua_State *L); + +int surface_create(lua_State *L); +int surface_destroy(lua_State *L); +int surface_get_data(lua_State *L); +int context_create(lua_State *L); +int context_destroy(lua_State *L); +int context_select_font_face(lua_State *L); +int context_set_font_size(lua_State *L); +int context_show_text(lua_State *L); +int context_set_source_rgb(lua_State *L); +int context_move_to(lua_State *L); + + +void setup_image(lua_State *L, int honey_index) +{ + hs_create_table(L, + /* basic images */ + hs_str_cfunc("load", load_image), + hs_str_cfunc("destroy", free_image), + + /* cairo bindings */ + hs_str_cfunc("surface_create", surface_create), + hs_str_cfunc("surface_destroy", surface_destroy), + hs_str_cfunc("surface_get_data", surface_get_data), + hs_str_cfunc("context_create", context_create), + hs_str_cfunc("context_destroy", context_destroy), + hs_str_cfunc("context_select_font_face", context_select_font_face), + hs_str_cfunc("context_set_font_size", context_set_font_size), + hs_str_cfunc("context_show_text", context_show_text), + hs_str_cfunc("context_set_source_rgb", context_set_source_rgb), + hs_str_cfunc("context_move_to", context_move_to), + + /* format enum */ + hs_str_int("FORMAT_ARGB32", CAIRO_FORMAT_ARGB32), + + + /* font enums */ + hs_str_int("FONT_SLANT_NORMAL", CAIRO_FONT_SLANT_NORMAL), + hs_str_int("FONT_WEIGHT_NORMAL", CAIRO_FONT_WEIGHT_NORMAL), + ); + + lua_setfield(L, honey_index, "image"); +} + + +/* --===== basic images =====-- */ + int load_image(lua_State *L) { char *filename; @@ -33,12 +84,129 @@ int free_image(lua_State *L) } -void setup_image(lua_State *L, int honey_index) +/* --===== cairo bindings =====-- */ + +int surface_create(lua_State *L) { - hs_create_table(L, - hs_str_cfunc("load", load_image), - hs_str_cfunc("destroy", free_image), - ); + lua_Integer format, width, height; + hs_parse_args(L, hs_int(format), hs_int(width), hs_int(height)); - lua_setfield(L, honey_index, "image"); + cairo_surface_t *surface = cairo_image_surface_create(format, width, height); + cairo_status_t status = cairo_surface_status(surface); + if (status != CAIRO_STATUS_SUCCESS) + hs_throw_error(L, "error creating cairo surface: %s", cairo_status_to_string(status)); + + lua_pushlightuserdata(L, surface); + return 1; +} + + +int surface_destroy(lua_State *L) +{ + void *surface_ptr; + hs_parse_args(L, hs_light(surface_ptr)); + cairo_surface_t *surface = surface_ptr; + + cairo_surface_destroy(surface); + return 0; +} + + +int surface_get_data(lua_State *L) +{ + void *surface_ptr; + hs_parse_args(L, hs_light(surface_ptr)); + cairo_surface_t *surface = surface_ptr; + + unsigned char *data = cairo_image_surface_get_data(surface); + lua_pushlightuserdata(L, data); + return 1; +} + + +int context_create(lua_State *L) +{ + void *surface_ptr; + hs_parse_args(L, hs_light(surface_ptr)); + cairo_surface_t *surface = surface_ptr; + + cairo_t *cr = cairo_create(surface); + cairo_status_t status = cairo_status(cr); + if (status != CAIRO_STATUS_SUCCESS) + hs_throw_error(L, "error creating cairo context: %s", cairo_status_to_string(status)); + + lua_pushlightuserdata(L, cr); + return 1; +} + + +int context_destroy(lua_State *L) +{ + void *cr_ptr; + hs_parse_args(L, hs_light(cr_ptr)); + cairo_t *cr = cr_ptr; + + cairo_destroy(cr); + return 0; +} + + +int context_select_font_face(lua_State *L) +{ + void *cr_ptr; + char *family; + lua_Integer slant, weight; + hs_parse_args(L, hs_light(cr_ptr), hs_str(family), hs_int(slant), hs_int(weight)); + cairo_t *cr = cr_ptr; + + cairo_select_font_face(cr, family, slant, weight); + return 0; +} + + +int context_set_font_size(lua_State *L) +{ + void *cr_ptr; + lua_Number size; + hs_parse_args(L, hs_light(cr_ptr), hs_num(size)); + cairo_t *cr = cr_ptr; + + cairo_set_font_size(cr, size); + return 0; +} + + +int context_show_text(lua_State *L) +{ + void *cr_ptr; + char *str; + hs_parse_args(L, hs_light(cr_ptr), hs_str(str)); + cairo_t *cr = cr_ptr; + + cairo_show_text(cr, str); + return 0; +} + + +int context_set_source_rgb(lua_State *L) +{ + void *cr_ptr; + lua_Number r, g, b; + hs_parse_args(L, hs_light(cr_ptr), hs_num(r), hs_num(g), hs_num(b)); + cairo_t *cr = cr_ptr; + + cairo_set_source_rgb(cr, r, g, b); + return 0; +} + + +int context_move_to(lua_State *L) +{ + void *cr_ptr; + lua_Number x, y; + hs_parse_args(L, hs_light(cr_ptr), hs_num(x), hs_num(y)); + cairo_t *cr = cr_ptr; + + cairo_move_to(cr, x, y); + return 0; } |