为了了解如何在渲染到纹理模式下使用 SDL2,我从这个问题的答案中找到了这个漂亮、清晰的示例并尝试了它。它会构建、执行,不会报告任何错误,并按指定运行 8 秒,但不会出现任何窗口。将位置更改为 SDL_WINDOWPOS_UNDEFINED、SDL_WINDOWPOS_UNDEFINED 没有什么区别。
10 年来 SDL2 中是否发生了一些变化,导致此示例失效? 或者 Mac 上有什么特殊问题吗?
在 Apple Silicon 计算机上运行 Mac OS 14.2.1,最近下载了 SDL2。这是我正在运行的精确代码:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <SDL2/SDL.h>
// Compile: gcc test.c -I/usr/local/include/SDL2 -L/usr/local/lib -lSDL2
void putPixel(SDL_Renderer *renderer, int x, int y)
{
SDL_SetRenderDrawColor(renderer, 255,255,255,255);
SDL_RenderDrawPoint(renderer, x, y);
}
int main(int argc, char* argv[]) {
int width = 640;
int height = 480;
SDL_Window *window = SDL_CreateWindow("Test", 0,0,width,height, 0);
if (window == NULL)
{
return -1;
}
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
if (renderer == NULL)
{
return -2;
}
SDL_SetRenderDrawBlendMode(renderer,SDL_BLENDMODE_BLEND);
/* Create texture for display */
SDL_Texture *display = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height);
SDL_SetRenderTarget(renderer, display);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
for(int x=0;x<8;x++)
{
SDL_SetRenderTarget(renderer, display);
for(int y=0;y<10;y++)
{
putPixel(renderer,40+x*10,50+y);
}
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderCopy(renderer, display, NULL, NULL);
SDL_RenderPresent(renderer);
sleep(1);
}
SDL_Quit();
return 0;
}
我通过反复试验找到了答案:必须处理一些初始设置事件才能显示窗口。我无法判断这是否代表 SDL2 的微妙转变或 Mac OS 问题,但我更怀疑是后者。很多年前,我在一个非常不同的 Mac OS 版本上并使用 Macintosh 本机编程库看到了这一点。操作系统在创建窗口的同时发送一些事件,在处理这些事件之前,一切都不会正常!你不需要对这些事件做任何事情,只需静静地承受它们即可。
实验表明,在这种情况下,我们得到了 10 个类型为 4352 的事件(未记录),然后是两个类型为 512 的事件,它指的是获得输入焦点的窗口(来自这个答案)。
这是修复它的代码:
// handle window creation events: A MUST!
while (SDL_PollEvent(&event)) {
}