Multiple SFML OpenGL Windows

Multiple SFML OpenGL Windows

本文关键字:Windows OpenGL SFML Multiple      更新时间:2023-10-16

如何创建两个SFML窗口,然后使用OpenGL绘制到它们两个?

如果你想知道如何用OpenGL创建和使用两个或更多的SFML窗口,那么这里是解决方案。我在互联网上找不到关于如何做到这一点的信息,所以在这里。我希望有一天这将对某人有用。

作为题外话,您可能想知道为什么这可能是一个有用的事情:

对于物理学家来说,能够向其他人展示系统的动画是一件非常有用的事情,因为我们经常想要编写一个演示程序来帮助我们解释它。一个简单的例子是盒子里气体粒子的行为。在一个窗口中,粒子会被绘制出来,并像它们在现实世界中那样移动,这要归功于我们奇特的物理计算,而在另一个窗口中,可能会绘制图形来显示盒子内的总能量或平均粒子速度(温度)以及其他诸如此类的东西。另一个很好的例子是对太阳系的模拟。关于行星的数据可以绘制到一个窗口,而太阳系的视图可以绘制到另一个窗口。

要做到这一点需要几个步骤。多窗口的微妙之处在于,您必须在绘制之前调整每个窗口的大小,或者至少这是最简单的方法。对于一个窗口,您只需要在创建窗口之后调整大小,并且每次调整或重塑窗口时都要调整大小。你可能会争辩说,有更好的方法来做到这一点,通过推和弹出矩阵堆栈,在这种情况下,请评论并留下其他答案。

首先,您需要声明两个sfml窗口,正如您所期望的:sf::Window window, window2;(可能您应该检查它们在程序执行结束时也关闭!)

其次,为两者实现一个resize方法。这样就可以了。

/// Window
glViewport(0, 0, window.GetWidth(), window.GetHeight());
// Set matrix mode back again
glMatrixMode(GL_PROJECTION);
// Reset matrix stack
glLoadIdentity();
// Set drawing surface properties - either Perspective or Orthographic
///gluPerspective(45.0, (double)w / (double)h, 1.0d, 100.0d);
glOrtho(-50.0d, 50.0d, -50.0d, 50.0d, -10.0d, 10.0d);
// Put matrix mode back
glMatrixMode(GL_MODELVIEW);

现在是另一个:

/// Window2, which can be different to window!
glViewport(0, 0, window.GetWidth(), window.GetHeight());
// Set matrix mode back again
glMatrixMode(GL_PROJECTION);
// Reset matrix stack
glLoadIdentity();
// Set drawing surface properties - either Perspective or Orthographic
///gluPerspective(45.0, (double)w / (double)h, 1.0d, 100.0d);
glOrtho(-50.0d, 50.0d, -50.0d, 50.0d, -10.0d, 10.0d);
// Put matrix mode back
glMatrixMode(GL_MODELVIEW);

您可能希望将这两个代码块放在两个不同的函数中,并可能实现您选择的相机类。这样做的原因是,在使用各种OpenGL绘制方法绘制之前,您需要调用每个窗口的resize函数。

现在是有趣的部分。在绘制之前,调用要绘制到的窗口的resize方法。然后,如果您需要调用glMatrixMode(GL_MODELVIEW);(以防万一!),glLoadIdentity();glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);。显然,如果你不想清除屏幕,不要调用glClear或glloadiidentity,如果你不想重置矩阵转换堆栈…

现在画你的画:glBegin()glEnd()以及所有你需要做的事情。

最后,调用window.Display()window2.Display(),这取决于您刚刚绘制的内容。现在回到上面有趣的部分,为另一个窗口调用resize方法,并继续为第二个窗口执行所需的所有操作,就像对第一个窗口一样!

现在享受OpenGL SFML编程与多个窗口。你也可以把一堆窗口塞进vector容器或其他奇特的容器中。

[EDIT]由于某些原因sf::Windows是不可复制的,这意味着你不能将它们push_back()放入容器中,如deque或vector。这可能是由于一些OpenGL特定的东西,这将"出错",如果你试图复制所有的位从一个窗口类到另一个。(可能吗?)相反,sf::Window* = new sf::Window[number_of_windows]unsigned int number_of_windows = 2就足够了,尽管它不那么好…