“底线”原因
未处理异常的原因是因为您将 Articx::window 定义为静态变量。
技术说明
抛出异常是因为构造 sf:RenderWindow 按以下顺序调用以下构造函数:
渲染窗口::渲染窗口()
窗口::窗口()
GlResource::GlResource()
GlResource::GlResource() 构造函数尝试锁定全局互斥体:
namespace
{
// OpenGL resources counter and its mutex
unsigned int count = 0;
sf::Mutex mutex;
}
namespace sf
{
////////////////////////////////////////////////////////////
GlResource::GlResource()
{
{
// Protect from concurrent access
Lock lock(mutex);
// If this is the very first resource, trigger the global context initialization
if (count == 0)
priv::GlContext::globalInit();
// Increment the resources counter
count++;
}
// Now make sure that there is an active OpenGL context in the current thread
priv::GlContext::ensureContext();
}
问题是你俩Arctix::窗口和 SFML 的sf::互斥体 互斥体是在程序初始化时构造的全局/静态变量。哪个先建造?在你的情况下你的window首先构造,因此 GlResource::GlResource() 构造函数尝试锁定无效的 sf::Mutex。由于全局/静态变量的构造顺序可能无法预测,因此最好在非全局位置创建 sf::RenderWindow 对象。
解决方案
在 main.cpp 中,在 main() 中创建 sf::RenderWindow 对象,并将引用传递给window通过 Articx::Start():
#include "Articx.h"
using namespace std;
int main(int argc, char** argv)
{
sf::RenderWindow window;
Articx::Start(window);
return 0;
}
在Articx.h中,删除静态成员变量window,并展开Start() and 游戏循环()接受 sf::RenderWindow 引用:
#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
class Articx
{
public:
static void Start(sf::RenderWindow &window);
private:
static void GameLoop(sf::RenderWindow &window);
static bool isExiting();
enum ScreenState {before, splash1, splash2, splash3, menu, pause, playing, exit};
static ScreenState currentState;
};
在Articx.cpp中,删除全局定义window并修改Start() and 游戏循环()接受并使用传递的 sf::RenderWindow 引用:
void Articx::Start(sf::RenderWindow &window)
{
Message("Articx Engine 1.0 Initializing...");
if(currentState != before)
return;
window.create(sf::VideoMode(800,600,32), "Articx Engine 1.0");
currentState = playing;
while (!isExiting())
{
Message("Engine Initialized");
Articx::GameLoop(window);
}
window.close();
}
. . .
void Articx::GameLoop(sf::RenderWindow &window)
{
. . .
}
现在运行它可以正确显示窗口:
该窗口似乎有一个无限循环打印“引擎已初始化”,但我将其留给您:-)。