local ffi = require 'ffi' -- from local VK_SERVER_EXECUTABLE = "/usr/bin/texture-share-vk-server" local VK_SERVER_DEFAULT_LOCKFILE_PATH = "/tmp/vk_server/vk_server.lock" local VK_SERVER_DEFAULT_SOCKET_PATH = "/tmp/vk_server/vk_server.sock" local VK_SERVER_DEFAULT_SHMEM_PREFIX = "shmem_img_" -- from gl.h local GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME = 0x8CD1 local GL_COLOR_ATTACHMENT0 = 0x8CE0 local GL_FRAMEBUFFER = 0x8D40 local GL_TEXTURE_2D = 0x0DE1 ffi.cdef [[ // gl.h typedef int GLint; typedef unsigned int GLuint; typedef unsigned int GLenum; void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params); // texture_share_ipc.h typedef enum ImgFormat { R8G8B8A8, R8G8B8, B8G8R8A8, B8G8R8, Undefined, } ImgFormat; // texture_share_gl_client.h typedef enum ImageLookupResult { Error = -1, NotFound = 0, Found = 1, RequiresUpdate = 2, } ImageLookupResult; typedef struct ClientImageDataGuard ClientImageDataGuard; typedef struct GlClient GlClient; typedef struct GlImageExtent { GLint top_left[2]; GLint bottom_right[2]; } GlImageExtent; bool gl_client_initialize_external_gl(void); struct GlClient *gl_client_new(const char *socket_path, uint64_t timeout_in_millis); struct GlClient *gl_client_new_with_server_launch(const char *socket_path, uint64_t client_timeout_in_millis, const char *server_program, const char *server_lock_path, const char *server_socket_path, const char *shmem_prefix, uint64_t server_socket_timeout_in_millis, uint64_t server_connection_wait_timeout_in_millis, uint64_t server_ipc_timeout_in_millis, uint64_t server_lockfile_timeout_in_millis, uint64_t server_spawn_timeout_in_millis); void gl_client_destroy(struct GlClient *gl_client); enum ImageLookupResult gl_client_init_image(struct GlClient *gl_client, const char *image_name, uint32_t width, uint32_t height, ImgFormat format, bool overwrite_existing); int gl_client_send_image(struct GlClient *gl_client, const char *image_name, GLuint src_texture_id, GLenum src_texture_target, bool invert, GLuint prev_fbo, const struct GlImageExtent *extents); ]] local tvs = ffi.load("texture_share_gl_client") local gl = ffi.load("GL") local width, height local canvas local client, image function love.load() width, height = love.graphics.getDimensions() canvas = love.graphics.newCanvas(width, height) assert(tvs.gl_client_initialize_external_gl(), "no init") client = assert(tvs.gl_client_new_with_server_launch( VK_SERVER_DEFAULT_SOCKET_PATH, 1000, VK_SERVER_EXECUTABLE, VK_SERVER_DEFAULT_LOCKFILE_PATH, VK_SERVER_DEFAULT_SOCKET_PATH, VK_SERVER_DEFAULT_SHMEM_PREFIX, 2000, 2000, 2000, 2000, 2000 ), "failed to connect or launch tsv server") image = assert(tvs.gl_client_init_image(client, "love2d", width, height, ffi.C.R8G8B8A8, true) > 0) end local angle = 0 function love.update(dt) angle = angle + 5 * dt end function love.draw() love.graphics.setCanvas(canvas) love.graphics.clear(0, 0, 0, 0) love.graphics.translate(width/2, height/2) love.graphics.rotate(angle) love.graphics.setColor(1, 0, 0, 1) love.graphics.rectangle("fill", -150,-150, 300,300) local name_ptr = ffi.typeof('GLint[1]')() gl.glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, name_ptr ) love.graphics.setCanvas() tvs.gl_client_send_image( client, "love2d", name_ptr[0], GL_TEXTURE_2D, false, 0, nil ) love.graphics.reset() love.graphics.setBlendMode("alpha", "premultiplied") love.graphics.draw(canvas) end