我一直在努力学习如何将SDL库与C(而不是C)一起使用,并且最近发现我遇到的所有错误的原因是我正在查看SDL1教程,而不是SDL2教程.我已经发现SDL2在SDL1上实现了许多抽象层(据我所知),这似乎是不可能绕过的.
具体来说,在SDL1中,在屏幕上绘制一组像素是通过以下方式完成的:
定义曲面 – 找到像素的rgb值 – 在曲面上绘制像素 – 在屏幕上绘制曲面
在SDL2中,它似乎通过以下方式完成:
定义窗口 – 为窗口创建渲染器 – 创建曲面 – 查找像素的rgb值 – 将像素绘制到曲面 – 将曲面转换为纹理 – 将纹理发送到渲染器 – 重绘窗口
虽然我理解如果除了原始像素数据之外还有其他东西,纹理可以是一种更简单的方法,特别是如果有多个数据源,在特定情况下我想用它(单个窗口程序)哪个原始像素数据是唯一可以绘制的东西)窗口,渲染器和纹理之间的区别只是无意义的抽象.此外,似乎在大多数情况下,来自图像的数据将被加载到SDL_Surface类,然后必须将其转换为纹理,从而添加更多不必要的抽象.
除了恢复到旧版本的SDL之外,还有什么方法可以避免这种情况吗?
最佳答案 当我开始使用SDL2时,我的想法完全相同.
首先,它可能不清楚,因为你没有探索很多SDL2,但即使你不想做OGL / DX,这些附加层即使使用普通的2D和像素处理也很有用.
例如,SDL_RenderCopyEx可以在旋转时渲染曲面并在运行时调整其大小.在SDL1中,您需要使用第三方库或编写自己的rotozoom算法来实现相同的功能.
另一个有用的功能是您可以轻松渲染基元.例如,有一个优化的SDL_RenderDrawLine方法,在SDL1中,您需要构建自己的方法,该方法将创建表面,浏览和blit像素信息,并将线条返回到整个表面.
还有很多其他的方法,我相信你会在给定的时间内发现,比如颜色调制.
接下来的一点是,您认为SDL1更低级且更“逼真”,并且SDL2会添加一些额外的层.实际上,现代图形卡用于SDL2.通常,您不会在内存中存储大量位图(SDL_Surfaces是原始数据),您不会将其他表面与其相关联,然后将其发送到图形卡.图形卡正在考虑纹理.
现在,如果你仍想绕过这些“附加层”,你仍然可以通过隔离纹理渲染过程来实现.我认为实现这一目标的最简洁方法是创建一个想要blit的曲面的链表:
struct SurfaceElement {
SDL_Surface* s;
SDL_Rect clip;
SDL_Rect position;
struct SurfaceElement * next;
};
typedef struct SurfaceElement SurfaceElement;
void ProcessingLoop() {
SurfaceElement *surfacesList = (SurfaceElement *)malloc(sizeof(SurfaceElement));
// Create surfaces, work on surfaces
// When you're done with a surface, add it to the list:
surfacesList = AddToBlitList(yourSurface, yourClipPos, yourBlitPos, surfacesList);
// When everything is okay and you're ready to blit:
TextureBlittingProcess(surfacesList, renderer);
}
SurfaceElement* AddToBlitList(SDL_Surface *s, SDL_Rect clip, SDL_Rect position, SurfaceElement *head) {
SurfaceElement *current = (SurfaceElement*)malloc(sizeof(SurfaceElement));
current->s = s;
current->clip = clip;
current->position = position;
current->next = head;
return current;
}
void TextureBlittingProcess(SurfaceElement *surfacesList, SDL_Renderer *renderer) {
while (surfaceList) {
SDL_Texture *t = SDL_CreateTextureFromSurface(renderer, surfaceList->s)
SDL_RenderCopy(renderer, t, &(surfaceList->clip), &(surfaceList->position));
surfaceList = surfaceList->next;
}
}
最后,如果您真的没有看到使用这些纹理的重点,如果您不一定想要对纹理进行blit而只是对其像素进行操作,那么SDL可能不适合您.您应该阅读有关Matlab或可能是脚本语言(如Python或Caml)的内容.