内部OpenGL调用在sfml窗口的Texture.cpp(98)向量中失败

问题描述 投票:1回答:1

所以我有一个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;
}

谢谢你们

c++ sfml
1个回答
0
投票

在您的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(); } }

© www.soinside.com 2019 - 2024. All rights reserved.