返回> 网站首页
使用SDL2实现多屏拼接滚动显示文字
yoours2024-04-11 21:04:18
简介一边听听音乐,一边写写文章。
一、简介
用mfc自绘的形式纯手工模拟多屏幕文字滚动的示例,cpu占用率很高。在此改用sdl2编写测试。
二、源代码
#include "stdafx.h"
#include <SDL.h>
#include <SDL_ttf.h>
#include <stdbool.h>
#include <time.h>
// 屏幕分辨率
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
// 屏幕数量
#define NUM_SCREENS 3
// 文字步进速度
#define TEXT_SPEED 5
SDL_Window *windows[NUM_SCREENS];
SDL_Renderer *renderers[NUM_SCREENS];
TTF_Font *font;
SDL_Texture* textTexture[NUM_SCREENS];
SDL_Rect textRect;
// 文字移动距离
int textX = 0;
void init()
{
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
font = TTF_OpenFont("monaco.ttf", 24);
if (!font)
exit(1);
for (int i = 0; i < NUM_SCREENS; ++i)
{
windows[i] = SDL_CreateWindow("Scrolling Text Screen " + i, i * SCREEN_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
renderers[i] = SDL_CreateRenderer(windows[i], -1, SDL_RENDERER_ACCELERATED);
}
const char *text = "Scrolling Text";
SDL_Surface *surface = TTF_RenderText_Solid(font, text, SDL_Color{ 255, 255, 255, 255 });
for (int i = 0; i < NUM_SCREENS; ++i)
{
textTexture[i] = SDL_CreateTextureFromSurface(renderers[i], surface);
}
SDL_FreeSurface(surface);
// 获取文字占用像素尺寸
SDL_QueryTexture(textTexture[0], NULL, NULL, &textRect.w, &textRect.h);
}
void renderText(int screenIndex)
{
SDL_SetRenderDrawColor(renderers[screenIndex], 0, 0, 0, 255);
SDL_RenderClear(renderers[screenIndex]);
int renderX = 0;
if (textX / SCREEN_WIDTH == screenIndex)
{
renderX = textX % SCREEN_WIDTH;
}else if ((textX + textRect.w) / SCREEN_WIDTH == screenIndex){
renderX = (textX + textRect.w) % SCREEN_WIDTH - textRect.w;
}else {
SDL_RenderPresent(renderers[screenIndex]);
return;
}
SDL_Rect renderRect = { renderX, (SCREEN_HEIGHT - textRect.h) / 2, textRect.w, textRect.h };
#define SHOW_TIME
#ifdef SHOW_TIME
// 同时更新文本内容为当前时间
time_t currentTime = time(NULL);
struct tm *localTime = localtime(¤tTime);
char timeStr[9];
strftime(timeStr, sizeof(timeStr), "%H:%M:%S", localTime);
// 创建一个新的纹理来显示新的时间
SDL_DestroyTexture(textTexture[screenIndex]);
SDL_Surface *surface = TTF_RenderText_Solid(font, timeStr, SDL_Color{ 255, 255, 255, 255 });
textTexture[screenIndex] = SDL_CreateTextureFromSurface(renderers[screenIndex], surface);
SDL_FreeSurface(surface);
#endif
// 可以执行多个SDL_RenderCopy绘制多个纹理
SDL_RenderCopy(renderers[screenIndex], textTexture[screenIndex], NULL, &renderRect);
SDL_RenderPresent(renderers[screenIndex]);
}
void moveText()
{
#define RIGHT_MOVE
#ifdef RIGHT_MOVE
if (textX >= SCREEN_WIDTH * NUM_SCREENS)
textX = 0;
textX += TEXT_SPEED;
#endif
#ifdef LEFT_MOVE
if (textX <= -textRect.w)
textX = SCREEN_WIDTH * NUM_SCREENS;
textX -= TEXT_SPEED;
#endif
for (int i = 0; i < NUM_SCREENS; ++i)
renderText(i);
}
int main(int argc, char *argv[])
{
init();
bool running = true;
SDL_Event event;
while (running)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
running = false;
}
moveText();
SDL_Delay(16); // 60 FPS
}
for (int i = 0; i < NUM_SCREENS; ++i)
{
SDL_DestroyRenderer(renderers[i]);
SDL_DestroyWindow(windows[i]);
SDL_DestroyTexture(textTexture[i]);
}
TTF_CloseFont(font);
return 0;
}