我如何在 SDL2 window 上使用 Cairo 绘制直线白线?
How would I draw a straight white line using Cairo on an SDL2 window?
这是原样的代码,但我无法使 SDL_Rect 正常工作或将 cairo 移动到 / line to。它产生一个空白的黑色 window。我发现 cairo 可以在 SDL2 window 上绘图,但不知道如何让它工作。我看到的大部分代码都使用 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);
你的纹理是 100x200,你只是从 cairo 图像数据更新它的 (0,0)(100,100) 矩形,但是对于 cairo 你只在 (100,100) 开始绘制,所以整个区域都是黑色的。此外,更新纹理时您的 pitch
不正确 - 它是源数据行的字节长度;您的 cairo 图像宽度为 1200,其格式要求每个像素 4 个字节;忽略填充它是 1200*4,而不是 400(注意 - 如果格式不同,例如每个像素 3 个字节,填充可能很重要 - 如果您要使用该格式,请参阅 cairo 文档以检查它是否填充其行) .所以有两种解决方案:
使用 cairo 生成您想要的完整图像,例如不要将 (100,100) 偏移量与 move_to
一起使用,也不要将整个图像复制到 SDL 纹理。那么只要校正音高就够了。
复制部分cairo数据到texture,
例如
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
);
这是原样的代码,但我无法使 SDL_Rect 正常工作或将 cairo 移动到 / line to。它产生一个空白的黑色 window。我发现 cairo 可以在 SDL2 window 上绘图,但不知道如何让它工作。我看到的大部分代码都使用 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);
你的纹理是 100x200,你只是从 cairo 图像数据更新它的 (0,0)(100,100) 矩形,但是对于 cairo 你只在 (100,100) 开始绘制,所以整个区域都是黑色的。此外,更新纹理时您的 pitch
不正确 - 它是源数据行的字节长度;您的 cairo 图像宽度为 1200,其格式要求每个像素 4 个字节;忽略填充它是 1200*4,而不是 400(注意 - 如果格式不同,例如每个像素 3 个字节,填充可能很重要 - 如果您要使用该格式,请参阅 cairo 文档以检查它是否填充其行) .所以有两种解决方案:
使用 cairo 生成您想要的完整图像,例如不要将 (100,100) 偏移量与
move_to
一起使用,也不要将整个图像复制到 SDL 纹理。那么只要校正音高就够了。复制部分cairo数据到texture,
例如
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 );