Texture.cpp(98) sfml windows 向量中的内部 OpenGL 调用失败
An internal OpenGL call failed in Texture.cpp(98) Vector of sfml windows
所以我有一个 sfml 程序,我试图同时打开多个 windows。我知道我有一个正常运行的代码,但我一次不能有一个以上的主循环 运行ning。我制作了一个指向 windows 的指针向量和一个我制作的结构向量。在函数内部,我试图用它来替换 while 循环,该循环在每个打开 window 中都是 运行ning 我在函数内部有一个 for 循环,应该 运行 通过整个向量和渲染一切。我已将生成错误的代码缩小到 stepWindows 函数或添加新 window 的函数。我不知道我做错了什么,但是没有编译器错误,调试控制台出现错误:
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.
这是我在 class MakeKey
中创建的 StepWindows 函数
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();
}
}
这是制作新的部分 window
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 方法中,你似乎在每次按下一个键 时创建一个新的 window(作为临时的,它将在 DrawKey returns)
sf::RenderWindow window(sf::VideoMode(Key.Img.getSize().x, Key.Img.getSize().y, 32), "Key", sf::Style::None);
然后获取该临时地址并存储它的地址。
WindowArray->push_back(&window);
这意味着 WindowArray 现在拥有一个指向死对象的指针。在我看来,整个设置有些可疑。
我不是 sfml 方面的专家,但我假设如果您需要打开多个 windows,这就是实现它的方法:
// 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 函数进行了一些更改(我假设其目的是在每次按下某个键时创建一个新的 window??)。您可能会发现传递对向量的引用比传递指向向量的指针更容易。
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
}
您的步骤 windows 函数有点令人困惑,所以我假设您正在尝试做这样的事情?
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();
}
}
所以我有一个 sfml 程序,我试图同时打开多个 windows。我知道我有一个正常运行的代码,但我一次不能有一个以上的主循环 运行ning。我制作了一个指向 windows 的指针向量和一个我制作的结构向量。在函数内部,我试图用它来替换 while 循环,该循环在每个打开 window 中都是 运行ning 我在函数内部有一个 for 循环,应该 运行 通过整个向量和渲染一切。我已将生成错误的代码缩小到 stepWindows 函数或添加新 window 的函数。我不知道我做错了什么,但是没有编译器错误,调试控制台出现错误:
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.
这是我在 class MakeKey
中创建的 StepWindows 函数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();
}
}
这是制作新的部分 window
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 方法中,你似乎在每次按下一个键 时创建一个新的 window(作为临时的,它将在 DrawKey returns)
sf::RenderWindow window(sf::VideoMode(Key.Img.getSize().x, Key.Img.getSize().y, 32), "Key", sf::Style::None);
然后获取该临时地址并存储它的地址。
WindowArray->push_back(&window);
这意味着 WindowArray 现在拥有一个指向死对象的指针。在我看来,整个设置有些可疑。
我不是 sfml 方面的专家,但我假设如果您需要打开多个 windows,这就是实现它的方法:
// 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 函数进行了一些更改(我假设其目的是在每次按下某个键时创建一个新的 window??)。您可能会发现传递对向量的引用比传递指向向量的指针更容易。
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
}
您的步骤 windows 函数有点令人困惑,所以我假设您正在尝试做这样的事情?
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();
}
}