- 先貼一份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_surface_set_device_scale(cr_surface, (double )cairo_x_multiplier, (double )cairo_y_multiplier); cairo_t *cr = cairo_create(cr_surface); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); SDL_RenderClear(renderer); // White background with SDL2 API // SDL_FillRect(sdl_surface, NULL, SDL_MapRGB(sdl_surface->format, 255, 255, 255)); // White background with cairo API 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
- cmakefiles.txt如下
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++") # GTK3的include 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 ) # SDL2的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渲染器
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); }
- 運作結果(好像沒有抗鋸齒)
-
- 我們使用clion建立c++工程,并引入