SDL学习笔记7--用SDL显示图像数据

时间:2022-07-24 12:03:48

这篇文章实际和学习笔记3和4差不多,未来需要深入理解window, render, texture, surface等概念。

#include "SDL.h"

struct
{
Uint32 pixformat;
int w, h;
Uint8 *data;
}frame;

int screen_width = 0;
int screen_height = 0;
int status = 0; // 1: request to stop; 2: stop
SDL_Texture *p_texture = NULL;
SDL_Renderer *p_render = NULL;

static void quit(int rc)
{
SDL_Quit();
exit(rc);
}

void fill_color_rgba8888()
{
static Uint8 r = 0, g = 0, b = 0, a = 0;

r += 10, g += 15, b += 20, a += 5;

Uint32 *pdst = (Uint32 *)frame.data;
Uint32 color = (r << 24) | (g << 16) | (b << 8) | a;
for (int i = 0; i < frame.w*frame.h; i++)
{
*pdst++ = color;
}
}

int SDLCALL video_process(void * data)
{
int ret;
while (1)
{
if (1 == status) // request to stop
{
status = 2;
break;
}
fill_color_rgba8888();

ret = SDL_UpdateTexture(p_texture, NULL, frame.data, frame.w * 4);
ret = SDL_RenderClear(p_render);
SDL_RenderCopy(p_render, p_texture, NULL, NULL);
SDL_RenderPresent(p_render);

SDL_Delay(1000);
}

return 0;
}

int video_test()
{

// 1. init
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL Timer SubSystem: %s\n", SDL_GetError());
quit(1);
}

screen_width = screen_height = 500;
frame.w = frame.h = 300;
frame.pixformat = SDL_PIXELFORMAT_RGBA8888;
frame.data = (Uint8 *)calloc(frame.w*frame.h*4, 1); // 4: pixsize

SDL_Window *p_screen;
p_screen = SDL_CreateWindow("video test",SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
screen_width, screen_height, SDL_WINDOW_RESIZABLE);
if (NULL == p_screen)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError());
quit(2);
}

p_render = SDL_CreateRenderer(p_screen, -1, 0);
if (NULL == p_render)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError());
quit(3);
}

p_texture = SDL_CreateTexture(p_render, frame.pixformat, SDL_TEXTUREACCESS_STREAMING, frame.w, frame.h);
if (NULL == p_texture)
{
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create texture: %s\n", SDL_GetError());
quit(4);
}

// 2. disp
SDL_Thread *video_thread = SDL_CreateThread(video_process, NULL, NULL);

// 3. event loop
SDL_Event event;
while (status != 2)
{
SDL_WaitEvent(&event);
switch (event.type)
{
case SDL_QUIT:
status = 1;
break;
}
}

// 4. exit
SDL_DestroyTexture(p_texture);
SDL_DestroyRenderer(p_render);
SDL_DestroyWindow(p_screen);
free(frame.data);
SDL_Quit();

return 0;
}