我正在尝试使用Menu类显示菜单。但是在该类的函数draw()
中,SDL_BlitSurface
不起作用,并且在执行以下行时抛出了默认的分段:
SDL_BlitSurface(el.surfaceNormal, NULL, surface, &el.rect);
以下是该函数的代码:
void Menu::draw(SDL_Surface* surface) {
for(int i=0; i<menuElementList.size(); i++){
auto el = menuElementList.at(i);
SDL_BlitSurface(el.surfaceNormal, NULL, surface, &el.rect);
}
}
我在vector中使用的结构:
struct menuElement{
SDL_Surface* surfaceNormal;
SDL_Surface* surfaceHover;
SDL_Rect rect;
std::string text;
};
通常,我应该能够渲染矢量中存在的所有表面,但是由于我无法弄清楚它不起作用的原因。
填充矢量的代码:
void Menu::addMenu(std::string name, int x, int y) {
menuElement m;
TTF_Font* Sans = TTF_OpenFont("OpenSans-Light.ttf", 25);
if(!Sans){
std::cout << TTF_GetError() << std::endl;
}
SDL_Color White = {255, 255, 255};
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, name.c_str(), White);
m.surfaceNormal = surfaceMessage;
SDL_Color Red = {255, 0, 0};
SDL_Surface* hoverMessage = TTF_RenderText_Solid(Sans, name.c_str(), Red);
m.surfaceHover = hoverMessage;
SDL_Rect rect;
rect.x = rect.y = 50;
m.rect = rect;
m.text = name;
SDL_FreeSurface(surfaceMessage);
SDL_FreeSurface(hoverMessage);
menuElementList.push_back(m);
}
我知道填充了向量,因为我可以显示其中每个元素的text属性。怎么了?
答案 0 :(得分:1)
如果调试了一下,错误就会很简单,这是您应该做的MVCE。
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <iostream>
#include <vector>
#include <string>
#define HEIGHT 600
#define WIDTH 800
using namespace std;
struct menuElement{
SDL_Surface* surfaceNormal;
SDL_Surface* surfaceHover;
SDL_Rect rect;
std::string text;
};
std::vector<menuElement> menuElementList;
void add_element(std::string name, int x, int y) {
menuElement m;
TTF_Font* Sans = TTF_OpenFont("OpenSans-Light.ttf", 25);
if(!Sans){
std::cout << TTF_GetError() << std::endl;
}
SDL_Color White = {255, 255, 255};
SDL_Surface* surfaceMessage = TTF_RenderText_Solid(Sans, name.c_str(), White);
m.surfaceNormal = surfaceMessage;
SDL_Color Red = {255, 0, 0};
SDL_Surface* hoverMessage = TTF_RenderText_Solid(Sans, name.c_str(), Red);
m.surfaceHover = hoverMessage;
SDL_Rect rect{x, y, 50, 50}; // You were never using x and y before now it draws at that position with a rect of size 50x50
m.rect = rect;
m.text = name;
// SDL_FreeSurface(surfaceMessage); << how is this not crashing in your system when blitting, I don't know
// SDL_FreeSurface(hoverMessage);
menuElementList.push_back(m);
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
TTF_Init();
SDL_Window *window = SDL_CreateWindow("TextFail", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
SDL_Surface *surface = SDL_GetWindowSurface(window);
bool quit = false;
SDL_Event event;
add_element("ello", 20, 20);
add_element("Bye", 40, 40);
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
for (auto &el : menuElementList)
SDL_BlitSurface(el.surfaceNormal, NULL, surface, &el.rect);
SDL_UpdateWindowSurface(window);
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
我评论了困扰您的两行内容,即使向量已经填充,因为自从释放表面以来,填充了未初始化的数据,也应该在释放menuElement时执行此操作(如果您在menuElement中使用C ++例如,析构函数或在free_menu_element(menuElement * e){..}函数(如果为C)上
请记住,当您复制指针时,您复制的是它们指向的内存方向,而不是其内容。
您也从未使用过x和y!