zoukankan      html  css  js  c++  java
  • SDL2笔记04_使用Cairo在SDL2上画图01

    1. 先贴一份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
      "
                  "window_height=%d
      ",
                  window_width, window_height);
      
           int renderer_width;
           int renderer_height;
           SDL_GetRendererOutputSize(renderer, &renderer_width, &renderer_height);
      
           printf("renderer_width=%d
      "
                  "renderer_height=%d
      ",
                  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
      "
                  "sdl_surface->h=%d
      "
                  "sdl_surface->pitch=%d
      ",
                  sdl_surface->w, sdl_surface->h, sdl_surface->pitch);
           printf("sdl_surface->format->format=%s
      ",
                  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;
       }
      
      • 运行后是这样的
    2. 正式开始

      1. 我们使用clion创建c++工程,并引入gtk+3.0sdl2.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)
        
        
      2. 把gtk+3需要的dll拷贝到生成.exe的目录里

      3. 编写代码

        1. SDL_RendererSDL_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);
          
          
        2. 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);
            
            
        3. 编写绘图代码,这里从网址上粘贴了一份https://cairographics.org/samples/链接
          * 画个扇形

           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);
           }
          
        4. 完整的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
          ", 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);
              }
          
        5. 运行结果(好像没有抗锯齿)

  • 相关阅读:
    根据 谷歌官网写一个 该浏览器上的扩展
    深度学习
    华为在线学习
    pandas 常规操作大全
    猎奇有些意思的
    LINUX 必知必会检测表--通读无关语言
    自动化部署三剑客 gitlab + ansible + jenkins
    python 框架
    delphi 多线程之System.TMonitor
    函数和对象 及 prototype和__proto__
  • 原文地址:https://www.cnblogs.com/majiao61/p/15143376.html
Copyright © 2011-2022 走看看