-
-
Save rjopek/971b0b87a9dfd6950df133e3567da40b to your computer and use it in GitHub Desktop.
How to correctly implement an image using GLFW and Cairo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* | |
*/ | |
#include <math.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <cairo/cairo.h> | |
#include <cairo/cairo-xlib.h> | |
#include <GLFW/glfw3.h> | |
#define GLFW_EXPOSE_NATIVE_X11 | |
#include <GLFW/glfw3native.h> | |
#define UNUSED( x ) ( ( void )( x ) ) | |
typedef struct | |
{ | |
GLFWwindow * win; | |
int width; | |
int height; | |
Display * xdpy; | |
Window xwin; | |
Visual * vis; | |
cairo_surface_t * surface; | |
cairo_t * cr; | |
cairo_surface_t * image; | |
} GLFW_Cairo; | |
static GLFW_Cairo gl; | |
static void key_callback( GLFWwindow * window, int key, int scancode, int action, int mods ); | |
int main() | |
{ | |
memset( &gl, 0, sizeof( gl ) ); | |
int width = 0, height = 0; | |
int w, h; | |
if( ! glfwInit() ) | |
{ | |
glfwTerminate(); | |
exit( EXIT_FAILURE ); | |
} | |
glfwWindowHint( GLFW_CLIENT_API, GLFW_NO_API ); | |
gl.win = glfwCreateWindow( 720, 512, "GLFW .AND. Cairo", NULL, NULL ); | |
if( ! gl.win ) | |
{ | |
glfwTerminate(); | |
exit( EXIT_FAILURE ); | |
} | |
glfwSwapInterval( 1 ); | |
gl.xdpy = glfwGetX11Display(); | |
gl.xwin = glfwGetX11Window( gl.win ); | |
gl.vis = DefaultVisual( gl.xdpy, DefaultScreen( gl.xdpy ) ); | |
if( ! gl.vis ) | |
{ | |
glfwTerminate(); | |
exit( EXIT_FAILURE ); | |
} | |
glfwGetFramebufferSize( gl.win, &gl.width, &gl.height ); | |
gl.surface = cairo_xlib_surface_create( gl.xdpy, gl.xwin, gl.vis, gl.width, gl.height ); | |
gl.cr = cairo_create( gl.surface ); | |
if( ! gl.cr ) | |
{ | |
glfwTerminate(); | |
exit( EXIT_FAILURE ); | |
} | |
glfwSetKeyCallback( gl.win, key_callback ); | |
while( ! glfwWindowShouldClose( gl.win ) ) | |
{ | |
glfwGetFramebufferSize( gl.win, &gl.width, &gl.height ); | |
cairo_xlib_surface_set_size( gl.surface, gl.width, gl.height ); | |
cairo_push_group( gl.cr ); | |
if( width != gl.width || height != gl.height ) | |
{ | |
cairo_set_source_rgb( gl.cr, 0.0, 0.0, 0.0 ); | |
cairo_set_operator( gl.cr, CAIRO_OPERATOR_SOURCE ); | |
cairo_paint( gl.cr ); | |
//--- | |
gl.image = cairo_image_surface_create_from_png( "cairo.png" ); | |
w = cairo_image_surface_get_width( gl.image ); | |
h = cairo_image_surface_get_height( gl.image ); | |
cairo_scale( gl.cr, 80.0 / w, 80.0 / h ); | |
cairo_set_source_surface( gl.cr, gl.image, 0, 0 ); | |
cairo_paint( gl.cr ); | |
width = gl.width; | |
height = gl.height; | |
//--- | |
} | |
cairo_pop_group_to_source( gl.cr ); | |
cairo_paint( gl.cr ); | |
cairo_surface_flush( gl.surface ); | |
glfwSwapBuffers( gl.win ); | |
glfwPollEvents(); | |
} | |
cairo_surface_destroy( gl.image ); | |
cairo_destroy( gl.cr ); | |
cairo_surface_finish( gl.surface ); | |
cairo_surface_destroy( gl.surface ); | |
cairo_surface_destroy( gl.image ); | |
glfwDestroyWindow( gl.win ); | |
glfwTerminate(); | |
exit( EXIT_SUCCESS ); | |
} | |
static void key_callback( GLFWwindow * window, int key, int scancode, int action, int mods ) | |
{ | |
UNUSED( scancode ); | |
UNUSED( mods ); | |
if( action == GLFW_PRESS ) | |
{ | |
return; | |
} | |
switch( key ) | |
{ | |
case GLFW_KEY_ESCAPE: | |
{ | |
glfwSetWindowShouldClose( window, GLFW_TRUE ); | |
break; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment