-
先贴一份github上的代码https://github.com/tsuu32/sdl2-cairo-example
- 不知道是不是版本问题,有一行编译会报错,注释掉就能跑了
#include <stdio.h>
#include <stdbool.h>
#include <SDL.h>
#include <cairo/cairo.h>
int
main(int argc, char *argv[]) {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *window = SDL_CreateWindow("An SDL2 window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
640,
480,
SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Renderer *renderer = SDL_CreateRenderer(window,
-1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
int window_width;
int window_height;
SDL_GetWindowSize(window, &window_width, &window_height);
printf("window_width=%d\n"
"window_height=%d\n",
window_width, window_height);
int renderer_width;
int renderer_height;
SDL_GetRendererOutputSize(renderer, &renderer_width, &renderer_height);
printf("renderer_width=%d\n"
"renderer_height=%d\n",
renderer_width, renderer_height);
int cairo_x_multiplier = renderer_width / window_width;
int cairo_y_multiplier = renderer_height / window_height;
SDL_Surface *sdl_surface = SDL_CreateRGBSurface(0,
renderer_width,
renderer_height,
32,
0x00ff0000,
0x0000ff00,
0x000000ff,
0);
printf("sdl_surface->w=%d\n"
"sdl_surface->h=%d\n"
"sdl_surface->pitch=%d\n",
sdl_surface->w, sdl_surface->h, sdl_surface->pitch);
printf("sdl_surface->format->format=%s\n",
SDL_GetPixelFormatName(sdl_surface->format->format));
cairo_surface_t *cr_surface = cairo_image_surface_create_for_data((unsigned char *) sdl_surface->pixels,
CAIRO_FORMAT_RGB24,
sdl_surface->w,
sdl_surface->h,
sdl_surface->pitch);
cairo_t *cr = cairo_create(cr_surface);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
cairo_set_source_rgba(cr, 1, 1, 1, 1.0);
cairo_rectangle(cr, 0, 0, 640, 480);
cairo_fill(cr);
double xc = 320.0;
double yc = 240.0;
double radius = 200.0;
double angle1 = 45.0 * (M_PI / 180.0);
double angle2 = 180.0 * (M_PI / 180.0);
cairo_set_source_rgba(cr, 0, 0, 0, 1.0);
cairo_set_line_width(cr, 10.0);
cairo_arc(cr, xc, yc, radius, angle1, angle2);
cairo_stroke(cr);
cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width(cr, 6.0);
cairo_arc(cr, xc, yc, 10.0, 0, 2 * M_PI);
cairo_fill(cr);
cairo_arc(cr, xc, yc, radius, angle1, angle1);
cairo_line_to(cr, xc, yc);
cairo_arc(cr, xc, yc, radius, angle2, angle2);
cairo_line_to(cr, xc, yc);
cairo_stroke(cr);
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, sdl_surface);
SDL_FreeSurface(sdl_surface);
SDL_RenderCopy(renderer, texture, NULL, NULL);
SDL_RenderPresent(renderer);
bool done = false;
while (!done) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
done = true;
break;
default:
break;
}
}
SDL_Delay(100);
}
cairo_destroy(cr);
cairo_surface_destroy(cr_surface);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
- 运行后是这样的
 -
正式开始
-
我们使用clion创建c++工程,并引入gtk+3.0 和sdl2.0 库
cmake_minimum_required(VERSION 3.19)
project(main)
set(SDL2_DIR G:/Xubuntu_Work_Space/From_Xubuntu/codeTest_2019_2_21/SDL2/win/SDL2-devel-2.0.14-mingw/SDL2-2.0.14/x86_64-w64-mingw32)
set(SDL2_IMAGE_DIR G:/Xubuntu_Work_Space/From_Xubuntu/codeTest_2019_2_21/SDL2/win/SDL2_image-devel-2.0.5-mingw/SDL2_image-2.0.5/x86_64-w64-mingw32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -lmingw32")
set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
include_directories(
H:/mysoft/clion/clionWorkSpace/gtk+364/include
H:/mysoft/clion/clionWorkSpace/gtk+364/include/gtk-3.0
H:/mysoft/clion/clionWorkSpace/gtk+364/include/cairo
H:/mysoft/clion/clionWorkSpace/gtk+364/include/gdk
H:/mysoft/clion/clionWorkSpace/gtk+364/include/glib-2.0
H:/mysoft/clion/clionWorkSpace/gtk+364/include/pango-1.0
H:/mysoft/clion/clionWorkSpace/gtk+364/include/atk-1.0
H:/mysoft/clion/clionWorkSpace/gtk+364/include/gdk-pixbuf-2.0
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/glib-2.0/include
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/gtk-3.0/include
)
include_directories(
${SDL2_DIR}/include/SDL2
${SDL2_IMAGE_DIR}/include/SDL2
)
link_directories(
${SDL2_DIR}/lib
${SDL2_IMAGE_DIR}/lib
)
link_libraries(
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libatk-1.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libcairo-gobject.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libcairo-script-interpreter.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libcairo.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libcroco-0.6.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libffi.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libfontconfig.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libfreetype.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libgailutil-3.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libgdk-3.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libgdk_pixbuf-2.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libgio-2.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libglib-2.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libgmodule-2.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libgobject-2.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libgthread-2.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libgtk-3.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libjasper.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libjpeg.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/liblzma.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libpango-1.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libpangocairo-1.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libpangoft2-1.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libpangowin32-1.0.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libpixman-1.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libpng.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libpng15.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/librsvg-2.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libtiff.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libtiffxx.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libxml2.dll.a
H:/mysoft/clion/clionWorkSpace/gtk+364/lib/libz.dll.a
)
set(SOURCE_FILES main.cpp)
add_executable(main ${SOURCE_FILES})
target_link_libraries(main mingw32 SDL2main SDL2 SDL2_image)
-
把gtk+3需要的dll拷贝到生成.exe的目录里 -
编写代码
-
SDL_Renderer 和SDL_Texture 都必须要用SDL_TEXTUREACCESS_STREAMING 来创建
SDL_Renderer *sdlRenderer = SDL_CreateRenderer(sdlWindow, -1,
/**SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC |*/
SDL_TEXTUREACCESS_STREAMING); // 使用STREAMING 流式 建立render
- 创建sdl_texture纹理,必须使用
SDL_PIXELFORMAT_ARGB8888 格式 SDL_Rect textureRect = {0, 0, 640, 480};
SDL_Rect tmpRect = {100, 100, 100, 100};
SDL_Texture *sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, // 目前发现只用Steaming才能显示
textureRect.w,
textureRect.h);
-
让cairo 画到sdl_texture 上,创建cairo_surface_t
- 使用
CAIRO_FORMAT_ARGB32 格式
void *pixels;
int pitch = 0;
SDL_LockTexture(sdlTexture, NULL, &(pixels), &pitch);
cairo_surface_t *cairo_surface = cairo_image_surface_create_for_data(
(unsigned char *) pixels,
CAIRO_FORMAT_ARGB32, // 与 SDLSDL_PIXELFORMAT_ARGB8888 对应
textureRect.w, textureRect.h, pitch);
cairo_t *pen = cairo_create(cairo_surface);
SDL_UnlockTexture(sdlTexture);
-
编写绘图代码,这里从网址上粘贴了一份https://cairographics.org/samples/ 链接 * 画个扇形
```c++
void drawIt(cairo_t *cr) {
double xc = 128.0;
double yc = 128.0;
double radius = 100.0;
double angle1 = 45.0 * (M_PI / 180.0); /* angles are specified */
double angle2 = 180.0 * (M_PI / 180.0); /* in radians */
cairo_set_line_width(cr, 1.0);
cairo_arc(cr, xc, yc, radius, angle1, angle2);
cairo_stroke(cr);
/* draw helping lines */
cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width(cr, 1.0);
cairo_arc(cr, xc, yc, 10.0, 0, 2 * M_PI);
cairo_fill(cr);
cairo_arc(cr, xc, yc, radius, angle1, angle1);
cairo_line_to(cr, xc, yc);
cairo_arc(cr, xc, yc, radius, angle2, angle2);
cairo_line_to(cr, xc, yc);
cairo_stroke(cr);
}
```
- 完整的main.cpp代码如下
#include <iostream>
#include "SDL.h"
#include "SDL_image.h"
#include "cairo/cairo.h"
void drawIt(cairo_t *pCairo);
// 绘制一条曲线
void drawBesizer(cairo_t *pen) {
if (pen) {
double x = 100.6, y = 328.0;
double x1 = 102.4 + 100, y1 = 130.4,
x2 = 153.6 + 240, y2 = 405.6,
x3 = 230.4 + 400, y3 = 200;
cairo_move_to(pen, x, y);
cairo_curve_to(pen, x1, y1, x2, y2, x3, y3);
cairo_set_line_width(pen, 1); //设置线宽
cairo_set_source_rgb(pen, 1.0, 0.0, 0.0); //设置线颜色
cairo_stroke(pen);
}
}
// 输出个hello,中文会乱码
void drawText(cairo_t *pen, SDL_Rect &rect) {
int x = (++rect.x) % rect.w, y = rect.y;
// cairo_set_source_rgba(pen, 1, 1, 1, 0.5);
cairo_set_source_rgba(pen, 255, 255, 255, 1);
cairo_rectangle(pen, x, y - 20, 50, 20);
cairo_fill(pen);
// cairo_paint (pen);
cairo_move_to(pen, x, y);
cairo_set_line_width(pen, 1);
cairo_set_source_rgba(pen, 0, 0, 0, 1);
cairo_set_font_size(pen, 14);
cairo_show_text(pen, "hello");
cairo_stroke(pen);
}
int main(int argc, char *argv[]) {
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *sdlWindow = SDL_CreateWindow("sdl_draw_on_texture", 0, 0, 640, 480, SDL_WINDOW_ALWAYS_ON_TOP);
SDL_Renderer *sdlRenderer = SDL_CreateRenderer(sdlWindow, -1,
/**SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC |*/
SDL_TEXTUREACCESS_STREAMING); // 使用STREAMING 流式 建立render
SDL_Rect textureRect = {0, 0, 640, 480};
SDL_Rect tmpRect = {100, 100, 100, 100};
SDL_Texture *sdlTexture = SDL_CreateTexture(sdlRenderer, SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, // 目前发现只用Steaming才能显示
textureRect.w,
textureRect.h);
void *pixels;
int pitch = 0;
SDL_LockTexture(sdlTexture, NULL, &(pixels), &pitch);
cairo_surface_t *cairo_surface = cairo_image_surface_create_for_data(
(unsigned char *) pixels,
CAIRO_FORMAT_ARGB32, // 与 SDLSDL_PIXELFORMAT_ARGB8888 对应
textureRect.w, textureRect.h, pitch);
cairo_t *pen = cairo_create(cairo_surface);
SDL_UnlockTexture(sdlTexture);
SDL_Event event;
int quit = false, delayMs = 1000 / 24;
while (!quit) {
uint32_t startTime = SDL_GetTicks();
while (SDL_PollEvent(&event) > 0) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
drawIt(pen);
// cairo_paint(pen);
// drawBesizer(pen);
// drawText(pen, tmpRect);
SDL_RenderCopy(sdlRenderer, sdlTexture, &textureRect, &textureRect);
SDL_RenderPresent(sdlRenderer);
uint32_t endTime = SDL_GetTicks();
if (endTime - startTime < delayMs) {
SDL_Log("delay %d\n", delayMs - (endTime - startTime));
SDL_Delay(delayMs - (endTime - startTime));
}
}
return 0;
}
void drawIt(cairo_t *cr) {
double xc = 128.0;
double yc = 128.0;
double radius = 100.0;
double angle1 = 45.0 * (M_PI / 180.0); /* angles are specified */
double angle2 = 180.0 * (M_PI / 180.0); /* in radians */
cairo_set_line_width(cr, 1.0);
cairo_arc(cr, xc, yc, radius, angle1, angle2);
cairo_stroke(cr);
/* draw helping lines */
cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.6);
cairo_set_line_width(cr, 1.0);
cairo_arc(cr, xc, yc, 10.0, 0, 2 * M_PI);
cairo_fill(cr);
cairo_arc(cr, xc, yc, radius, angle1, angle1);
cairo_line_to(cr, xc, yc);
cairo_arc(cr, xc, yc, radius, angle2, angle2);
cairo_line_to(cr, xc, yc);
cairo_stroke(cr);
}
- 运行结果(好像没有抗锯齿)

|