SDL_Texture 介绍
SDL_Texture 是 SDL 2.0 引入的核心图形数据结构,用于高效硬件加速渲染。相比 SDL_Surface,它直接在 GPU 显存中存储纹理数据,提供更快的渲染性能。
SDL_Texture 特性
- 硬件加速:利用 GPU 进行渲染,性能显著高于软件渲染
- 不直接访问像素:无法像 Surface 那样直接操作像素数据
- 与渲染器绑定:必须通过 SDL_Renderer 创建和使用
- 支持高级特性:包括混合模式、颜色调制、Alpha 混合等
创建与销毁 Texture
创建方法
// 从 Surface 创建 Texture
SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer* renderer, SDL_Surface* surface);
// 直接创建空 Texture
SDL_Texture* SDL_CreateTexture(SDL_Renderer* renderer,
Uint32 format, // 像素格式 (SDL_PIXELFORMAT_*)
int access, // 访问模式 (SDL_TEXTUREACCESS_*)
int w, int h); // 宽度和高度
访问模式 (access)
SDL_TEXTUREACCESS_STATIC
:不常修改的内容SDL_TEXTUREACCESS_STREAMING
:频繁更新的内容SDL_TEXTUREACCESS_TARGET
:可作为渲染目标
销毁 Texture
void SDL_DestroyTexture(SDL_Texture* texture);
常用操作函数
更新纹理数据
// 更新整个纹理
int SDL_UpdateTexture(SDL_Texture* texture,
const SDL_Rect* rect, // NULL 表示整个纹理
const void* pixels, // 像素数据
int pitch); // 每行字节数
// 锁定纹理以直接访问 (谨慎使用)
int SDL_LockTexture(SDL_Texture* texture,
const SDL_Rect* rect,
void** pixels,
int* pitch);
void SDL_UnlockTexture(SDL_Texture* texture);
渲染属性设置
// 设置混合模式
int SDL_SetTextureBlendMode(SDL_Texture* texture, SDL_BlendMode blendMode);
// 设置颜色调制 (RGBA)
int SDL_SetTextureColorMod(SDL_Texture* texture,
Uint8 r, Uint8 g, Uint8 b);
// 设置Alpha透明度
int SDL_SetTextureAlphaMod(SDL_Texture* texture, Uint8 alpha);
渲染 Texture
// 复制纹理到渲染目标
int SDL_RenderCopy(SDL_Renderer* renderer,
SDL_Texture* texture,
const SDL_Rect* srcrect, // 源矩形 (NULL表示整个纹理)
const SDL_Rect* dstrect); // 目标矩形
// 带旋转和翻转的复制
int SDL_RenderCopyEx(SDL_Renderer* renderer,
SDL_Texture* texture,
const SDL_Rect* srcrect,
const SDL_Rect* dstrect,
const double angle, // 旋转角度(度)
const SDL_Point* center, // 旋转中心点
const SDL_RendererFlip flip); // 翻转标志
使用示例
基本使用流程
#include <SDL2/SDL.h>
int main() {
SDL_Init(SDL_INIT_VIDEO);
// 创建窗口和渲染器
SDL_Window* window = SDL_CreateWindow("Texture Demo",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
800, 600,
SDL_WINDOW_SHOWN);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED);
// 加载图像到Surface然后转为Texture
SDL_Surface* surface = SDL_LoadBMP("image.bmp");
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface); // 不再需要Surface
// 主循环
SDL_Event event;
int quit = 0;
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = 1;
}
}
// 清屏
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// 渲染纹理
SDL_Rect dstrect = {100, 100, 200, 200};
SDL_RenderCopy(renderer, texture, NULL, &dstrect);
// 更新屏幕
SDL_RenderPresent(renderer);
}
// 清理资源
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
动态更新纹理示例
// 创建可流式访问的纹理
SDL_Texture* dynamicTex = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STREAMING,
256, 256);
// 在主循环中更新纹理
void* pixels;
int pitch;
SDL_LockTexture(dynamicTex, NULL, &pixels, &pitch);
// 直接操作像素数据
Uint32* upixels = (Uint32*)pixels;
for (int y = 0; y < 256; y++) {
for (int x = 0; x < 256; x++) {
upixels[y * (pitch / 4) + x] = SDL_MapRGBA(format, x, y, (x + y) % 256, 255);
}
}
SDL_UnlockTexture(dynamicTex);
最佳实践
- 尽量减少纹理切换:批量渲染相同纹理的对象
- 合理选择访问模式:
- 静态内容用
SDL_TEXTUREACCESS_STATIC
- 频繁更新的用
SDL_TEXTUREACCESS_STREAMING
- 静态内容用
- 适当使用纹理图集:将多个小图像合并到一个大纹理中
- 注意资源管理:及时销毁不再使用的纹理
- 优先使用SDL_RenderCopyEx:它比多个单独变换操作更高效
SDL_Texture 是 SDL 2.x 中高效渲染的关键,特别适合游戏开发和需要高性能图形处理的应用程序。