SDL 開發實戰(五): SDL 紋理渲染


本文我們講一下如何使用SDL_Texture將視頻紋理渲染出來。

1. SDL 視頻渲染相關對象

SDL 視頻渲染主要涉及到四個對象:SDL_Window、SDL_Render、SDL_Texture和SDL_Surface。

SDL_Window代表的是窗口的邏輯概念,它是存放在主內存中的一個對象。當我們調用SDL API 創建窗口后,它並不會被顯示出來。

SDL_Render 是渲染器,它也是主存中的一個對象。對Render操作時實際上分為兩個階段:

  • 渲染階段。在該階段,用戶可以畫各種圖形渲染到SDL_Surface或SDL_Texture 中;
  • 顯示階段。參SDL_Texture為數據,通過OpenGL操作GPU,最終將 SDL_Surfce 或SDL_Texture中的數據輸出到顯示器上。

SDL_Render對象中有一個視頻緩沖區,該緩沖區我們稱之為SDL_Surface,它是按照像素存放圖像的。我們一般把真彩色的像素稱為RGB24數據。也就是說,每一個像素由24位組成,每8位代表一種顏色,像素的最終顏色是由RGB三種顏色混合而成的。

SDL_Texture 與SDL_Surface 相似,也是一種緩沖區。只不過它存放的不是真正的像素數據,而是存放的圖像的描述信息。這些描述信息通過OpenGL、D3D 或 Metal等技術操作GPU,從而繪制出與SDL_Surface一樣的圖形,且效率更高。

2. 使用 SDL_Texute 渲染紋理的步驟

SDL提供了操作SDL_Texture的方法,使用SDL_Texute的基本步驟為:

  • 創建一個 SDL_Texture。

  • 渲染 Texture

  • Destory Texture

3. 使用SDL渲染紋理的核心API

a). 創建 SDL_Texture

SDL_Texture* SDL_CreateTexture(SDL_Renderer* renderer,  // 渲染器
                       Uint32        format,            // 渲染數據的格式,如YUV、RGB     
                       int           access,            // Texture 類型,target、stream 
                       int           w,                
                       int           h)

下面說明一下重要參數:

format: 指明像素格式,可以是YUV,也可以是RGB

access: 指明Texture的類型。可以是 Stream(視頻),也可以是Target一般的類型。

b). 渲染

int SDL_RenderCopy(SDL_Renderer* renderer,
               SDL_Texture*    texture,
               const SDL_Rect* srcrect,
               const SDL_Rect* dstrect)

 

下面說明一下重要參數:

srcrect: 指定 Texture 中要渲染的一部分。如果將 Texture全部輸出,可以設置它為 NULL。

dstrect: 指定輸出的空間大小。

c). 銷毀 SDL_Texture

void SDL_DestroyTexture(SDL_Texture* texture)

 

紋理渲染實戰:

// SDL.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//

#include "pch.h"
#include <iostream>

extern "C" {
#include "SDL.h"
}

int main(int argc, char* argv[])
{
    SDL_Window *window;
    SDL_Renderer *renderer;
    SDL_Texture *texture;
    SDL_Event event;
    SDL_Rect r;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
        return 3;
    }

    window = SDL_CreateWindow("SDL_CreateTexture",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        1024, 768,
        SDL_WINDOW_RESIZABLE);

    r.w = 100;
    r.h = 50;

    renderer = SDL_CreateRenderer(window, -1, 0);

    texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, 1024, 768);

    // 跳來跳去的方塊
    while (1) {
        SDL_PollEvent(&event);
        if (event.type == SDL_QUIT)
            break;
        r.x = rand() % 500;
        r.y = rand() % 500;

        SDL_SetRenderTarget(renderer, texture);
        SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
        SDL_RenderClear(renderer);
        SDL_RenderDrawRect(renderer, &r);
        SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0x00);
        SDL_RenderFillRect(renderer, &r);
        SDL_SetRenderTarget(renderer, NULL);
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
    }
    SDL_DestroyRenderer(renderer);
    SDL_Quit();
    return 0;
}

運行效果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM