如何将SDL_BlitSurface()与SDL_CreateRGBSurface()一起正确使用
How to properly use SDL_BlitSurface() with SDL_CreateRGBSurface()?
(有关解决方案,请参阅下面的"编辑2"。)
我需要从头开始创建SDL曲面,而不是从文件中加载它们。不幸的是,当与通过SDL_CreateRGBSurface()
生成的曲面一起使用时,SDL_BlitSurface()
似乎将所有颜色渲染为黑色。这是我的代码:
int main(int argc, char** argv)
{
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE);
SDL_Surface* layer = SDL_CreateRGBSurface(SDL_HWSURFACE, 100, 100,
screen->format->BitsPerPixel,
screen->format->Rmask,
screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask
);
SDL_Rect rect;
rect.x = 0;
rect.y = 0;
rect.w = 100;
rect.h = 100;
Uint32 blue = SDL_MapRGB(screen->format, 0, 0, 255);
SDL_FillRect(layer, &rect, blue);
SDL_BlitSurface(screen, NULL, layer, NULL);
SDL_Flip(screen);
SDL_Delay(3000);
return 0;
}
我得到的是一个黑色屏幕,而不是一个100x100的蓝色矩形。我在谷歌上搜索到的似乎对我没有帮助,因为这些问题要么适用于8位曲面(以及设置调色板——我的bpp在这里是32),要么没有答案。
所以,我想知道我应该如何正确地将生成的曲面闪电战到SDL屏幕上。
编辑:我看到这是参数排序中的一个错误。有问题的行应该是
SDL_BlitSurface(layer, NULL, screen, NULL);
尽管如此,我还是很难在我更复杂的C++程序中实现同样的效果。我将在这里张贴代码的相关部分:
main.cpp:
int main(int argc, char** argv)
{
SDLScreen screen(1024, 700, "Hello, SDL!");
SDL_Event event;
SDLMenu menu;
bool shouldQuit = false;
menu.setBounds(200, 100, 200, 600);
menu.setFontName("NK211.otf");
menu.setFontSize(36);
menu.setEffect(sdlteShadowText);
menu.addItem("New game");
menu.addItem("Load game");
menu.addItem("Save game");
menu.addItem("Exit");
menu.render();
while (!shouldQuit)
{
menu.draw(screen.getSurface());
SDL_Flip(screen.getSurface());
SDL_Delay(10);
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
shouldQuit = true;
}
else if (event.type == SDL_KEYUP)
{
if (event.key.keysym.sym == SDLK_q)
{
shouldQuit = true;
}
}
}
}
}
SDLMenu.cpp:
void
SDLMenu::setSelectionColorRGB(int r, int g, int b)
{
SDL_VideoInfo* info = (SDL_VideoInfo*)SDL_GetVideoInfo();
selectionColor = SDL_MapRGB(info->vfmt, r, g, b);
}
void
SDLMenu::render()
{
SDLText* current = NULL;
SDL_VideoInfo* info = (SDL_VideoInfo*)SDL_GetVideoInfo();
if (!items->empty())
{
current = getItemAt(currentItem);
selectionRect = getItemRect(current);
setSelectionColorRGB(0,0,255);
selectionCanvas = SDL_CreateRGBSurface(SDL_HWSURFACE,
selectionRect->w, selectionRect->h,
info->vfmt->BitsPerPixel,
info->vfmt->Rmask,
info->vfmt->Gmask,
info->vfmt->Bmask,
info->vfmt->Amask);
SDL_FillRect(selectionCanvas, selectionRect, selectionColor);
SDL_SaveBMP(selectionCanvas, "selection.bmp"); // debug
}
for (list<SDLText*>::iterator i = items->begin();
i != items->end(); i++)
{
(*i)->render();
}
}
void
SDLMenu::draw(SDL_Surface* canvas)
{
int currentY = bounds.y;
if (selectionCanvas != NULL)
{
SDL_BlitSurface(selectionCanvas, NULL, canvas, selectionRect);
}
for (list<SDLText*>::iterator i = items->begin();
i != items->end(); i++)
{
(*i)->draw(bounds.x, currentY, canvas);
currentY += fontSize + itemGap;
}
}
SDLScreen.cpp:
SDLScreen::SDLScreen(int w, int h, string t, int d)
: width(w), height(h), depth(d), title(t)
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_WM_SetCaption(title.c_str(), NULL);
refresh();
}
void
SDLScreen::refresh()
{
screen = SDL_SetVideoMode(width, height, 32, SDL_HWSURFACE);
}
活动菜单项的选择矩形应为蓝色,但显示为黑色。文件selection.bmp
也是全黑的。
编辑2:我发现了问题的根源。selectionRect
是相对于屏幕设置的,而selectionCanvas
具有特定菜单项的宽度和高度。因此,填充是在selectionCanvas
的边界之外进行的。添加单独的SDL_Rect
进行填充解决了问题。
SDL_Rect fillRect;
fillRect.x = 0;
fillRect.y = 0;
fillRect.w = selectionRect->w;
fillRect.h = selectionRect->h;
SDL_FillRect(selectionCanvas, &fillRect, selectionColor);
// and later...
SDL_BlitSurface(selectionCanvas, NULL, canvas, selectionRect);
您反转了源和目标。要在屏幕上闪电战,应该是
SDL_BlitSurface(layer, NULL, screen, NULL);
SDL_BlitSurface 的文档
相关文章:
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 如何将enable-if与模板参数和参数包一起使用
- 如何将PERF_AMPLE_READ与mmap一起使用
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- SDL 窗口不会弹出
- 如何将C++中的库和头与MinGW一起使用
- 将--whole archive链接器选项与CMake和具有其他库依赖项的库一起使用
- 为什么我不能将 rand() 与数组的大小一起使用?
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 不能将复制初始化与隐式转换的多个步骤一起使用
- 将fold表达式与std::一起用于两个元组
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 将 std::allocate_shared 与多态资源分配器一起使用
- 如何将SDL与Win32菜单一起使用
- 我可以将SDL-1.2.15与SDL2-Image Extension一起使用
- SDL_TTF和SDL 2不在一起工作.给出未处理的异常
- 如何将SDL_MapRGB与SDL 2.0一起使用
- SDL 控制台输出在调试时有效,但在与 exe 一起运行时无效
- 视觉C++ 将SDL_ttf与 SDL 和 SDL2 一起使用时出现访问冲突