所以我有一个sfml程序,我试图一次打开多个窗口。我知道我有一个运行正常的代码,但一次不能运行多个主循环。我已经制作了指向Windows的指针的矢量和我制作的结构的矢量。在我试图用来替换将在每个打开的窗口中运行的while循环的函数内部,我在函数内部有一个for循环,该循环应贯穿整个向量并呈现所有内容。我将生成错误的代码缩小到stepWindows函数或添加新窗口的函数中。我不知道我做错了什么,但是没有编译器错误,但是,调试控制台出现错误:
An internal OpenGL call failed in Texture.cpp(98).
Expression:
glFlush()
Error description:
GL_INVALID_OPERATION
The specified operation is not allowed in the current state.
这是我的StepWindows函数,我在类MakeKey中创建了它
void MakeKey::StepWindows(vector <MakeKey::NewKey> KeyArray, vector <sf::RenderWindow*> WindowArray)
{
for (int i{ 0 }; i > KeyArray.size(); i++)
{
cout << "Inside Step Windows For Loop" << endl;
WindowArray[1]->setActive(true);
WindowArray[1]->clear(sf::Color::Transparent);
WindowArray[1]->draw(KeyArray[1].Sprite);
WindowArray[1]->display();
}
}
这里是创建新窗口的部分
void MakeKey::DrawKey(string input, vector <MakeKey::NewKey>* KeyArray, vector <sf::RenderWindow*>* WindowArray)
{
MakeKey::NewKey Key;
if (input == "A")
Key.Img.loadFromFile("Assets/Images/A.png");
else if (input == "D")
Key.Img.loadFromFile("Assets/Images/D.png");
//Ect
sf::RenderWindow window(sf::VideoMode(Key.Img.getSize().x, Key.Img.getSize().y, 32), "Key", sf::Style::None);
Key.Tex.loadFromImage(Key.Img);
Key.Sprite.setTexture(Key.Tex);
sf::RenderWindow* windowPoint = &window;
//Make Transparent
const unsigned char opacity = 1000;
KeyArray->push_back(Key);
WindowArray->push_back(&window);
cout << "KeyArray Has " << KeyArray->size() << " Elements\n" << "WindowArray Has " << WindowArray->size() << " Elements" << endl; //for debugging
}
当然还有我的主要
int main()
{
static vector <MakeKey::NewKey> KeyArray;
static vector <MakeKey::NewKey>* KeyArrayPointer = &KeyArray;
static vector <sf::RenderWindow*> WindowArray;
static vector <sf::RenderWindow*>* WindowArrayPointer = &WindowArray;
sf::RenderWindow window(sf::VideoMode(100, 100, 32), "Main Window", sf::Style::Default);
MakeKey MakeKey;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
//Key Presses
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::A)
MakeKey.DrawKey("A", KeyArrayPointer, WindowArrayPointer);
else if (event.key.code == sf::Keyboard::D)
MakeKey.DrawKey("D", KeyArrayPointer, WindowArrayPointer);
//Ect
}
if (event.type == sf::Event::Closed)
window.close();
}
MakeKey.StepWindows(KeyArray, WindowArray);
}
return EXIT_SUCCESS;
}
谢谢你们
在您的DrawKey方法中,每按一次键,您似乎正在创建一个新窗口。sf::RenderWindow window(sf::VideoMode(Key.Img.getSize().x, Key.Img.getSize().y, 32), "Key", sf::Style::None);
然后您获取该临时地址,并存储它的地址。
WindowArray->push_back(&window);
这意味着WindowArray现在拥有指向失效对象的指针。关于整个设置的一些事情对我来说似乎很糟糕。我不是sfml的专家,但我假设如果需要打开多个窗口,这将是这样做的方式:
// just store the windows in a normal array
static std::vector<sf::RenderWindow> windows;
// add main window (and do this if you need to add more windows)
windows.emplace_back(sf::VideoMode(100, 100, 32), "Main Window", sf::Style::Default);
// keep the app running while a window is open.
while(!windows.empty())
{
for(auto window = windows.begin(); window != windows.end(); ++window)
{
if(!window->isOpen())
{
// if main window closed, clear all windows (and exit main loop)
if(window == windows.begin())
{
windows.clear();
}
else
{
// erase the window that was closed
window = windows.erase(window);
}
}
else
// process all queued events for window
{
sf::Event event;
while (window->pollEvent(event))
{
//Key Presses
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::A)
MakeKey.DrawKey("A", KeyArray, windows);
else if (event.key.code == sf::Keyboard::D)
MakeKey.DrawKey("D", KeyArray, windows);
//Ect
}
if (event.type == sf::Event::Closed)
{
window->close();
break;
}
}
}
MakeKey.StepWindows(KeyArray, windows);
}
}
这意味着对您的drawkey函数进行了一些更改(我假设目的是每次按下一个键时都创建一个新窗口?)。您可能会发现将引用传递给向量,而不是将指针传递给向量,会更容易。
void MakeKey::DrawKey( std::string input, std::vector<MakeKey::NewKey>& KeyArray, //< pass by reference std::vector<sf::RenderWindow>& WindowArray) //< pass by reference { MakeKey::NewKey Key; if (input == "A") Key.Img.loadFromFile("Assets/Images/A.png"); else if (input == "D") Key.Img.loadFromFile("Assets/Images/D.png"); //Ect| /// << add the window to the array >> WindowArray.emplace_back(sf::VideoMode(Key.Img.getSize().x, Key.Img.getSize().y, 32), "Key", sf::Style::None); Key.Tex.loadFromImage(Key.Img); Key.Sprite.setTexture(Key.Tex); //Make Transparent const unsigned char opacity = 1000; KeyArray.push_back(Key); std::cout << "KeyArray Has " << KeyArray.size() << " Elements\n" << "WindowArray Has " << WindowArray.size() << " Elements" << std::endl; //for debugging }
您的步进窗口功能有些混乱,所以我想您正在尝试执行类似的操作?
void MakeKey::StepWindows(const std::vector <MakeKey::NewKey>& KeyArray, std::vector <sf::RenderWindow>& WindowArray) { for (int i{ 0 }; i < KeyArray.size(); i++) { cout << "Inside Step Windows For Loop" << endl; // are you sure you only want to do this for window 1? // It would sort of make sense to do this for window[i + 1]?? // but you will need to ensure that when you erase a window above, // you also erase the corresponding element from the key array??? WindowArray[1 + i]->setActive(true); WindowArray[1 + i]->clear(sf::Color::Transparent); WindowArray[1 + i]->draw(KeyArray[1].Sprite); WindowArray[1 + i]->display(); } }