This is the code as it is but I'm having trouble making SDL_Rect work or cairo move to / line to. It produces a blank black window. I found out that it is possible for cairo to draw on an SDL2 window but don't know how I would go about making it work. Majority of the code I see uses GTK+.
SDL_Window* mainWindow;
SDL_Renderer* mainRenderer;
SDL_CreateWindowAndRenderer(1280, 960, SDL_WINDOW_SHOWN, &mainWindow, &mainRenderer);
cairo_surface_t* surface;
cairo_t* cr;
surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1200, 900);
cr = cairo_create(surface);
cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
cairo_set_line_width(cr, 25);
cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
cairo_move_to(cr, 100.0, 100.0);
cairo_line_to(cr, 500, 500);
cairo_stroke(cr);
unsigned char* data;
data = cairo_image_surface_get_data(surface);
SDL_Texture* texture;
SDL_Rect rect = {0, 0, 100, 100};
texture = SDL_CreateTexture(mainRenderer, SDL_PIXELFORMAT_ABGR8888,
SDL_TEXTUREACCESS_STREAMING, 100, 200);
SDL_UpdateTexture(texture, &rect, data, 400);
// Main program loop
while (1)
{
SDL_Event event;
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
SDL_DestroyRenderer(mainRenderer);
SDL_DestroyWindow(mainWindow);
SDL_Quit();
break;
}
}
SDL_RenderClear(mainRenderer);
SDL_RenderCopy(mainRenderer, texture, NULL, NULL);
SDL_RenderPresent(mainRenderer);
}
// Cleanup and quit
cairo_destroy(cr);
cairo_surface_destroy(surface);
Your texture is 100x200 and you're only updating its (0,0)(100,100) rectangle from cairo image data, but with cairo you only started drawing at (100,100), so entire area is black. In addition, your pitch
when updating texture is incorrect - it is byte length of source data line; your cairo image have width of 1200 and its format requires 4 bytes per pixel; neglecting padding it is 1200*4, not 400 (note - if format is different, e.g. 3 bytes per pixel, padding may be important - refer to cairo documentation to check if it pads its rows if you're going to use that format). So there are two solutions:
Use cairo to produce full image you want, e.g. don't use (100,100) offset with move_to
, or copy entire image to SDL texture. Then only correcting pitch is enough.
Copy part of cairo data to texture,
e.g.
const unsigned int bpp = 4;
const unsigned int pitch = 1200*bpp;
SDL_UpdateTexture(texture, &rect,
data // offset pointer to start at 'first' pixel you want to copy
+ 100*pitch // skip first 100 rows
+ 100*bpp, // and first 100 pixels
pitch // pitch is the same - it refers to source image, not destination
);