如何创建两个SFML窗口,然后使用OpenGL绘制它们两个?
如果您想知道如何使用OpenGL创建和使用两个或更多SFML窗口,那么这就是解决方案。我无法在互联网上的任何其他地方找到有关如何做到这一点的信息,所以就是这样。我希望有一天这对某人有用。
另外,您可能想知道为什么这可能是有用的事情:
物理学家能够向其他人展示系统动画是一件非常有用的事情,因为我们经常想要编写一些东西的演示来帮助我们解释它。一个简单的例子就是盒子中气体颗粒的行为。在窗口中,由于我们花哨的物理计算,粒子将像在现实世界中一样被绘制和移动,而在另一个窗口中,可能会绘制图形以显示盒子内的总能量或平均粒子速度(温度)和其他这样的事情。另一个很好的例子是太阳系的模拟。有关行星的数据可以绘制到一个窗口,太阳系的视图可以被绘制到另一个窗口。
答案 0 :(得分:2)
完成这项工作需要几个步骤。巧妙地有多个窗口的事实是你必须在绘制之前调整每个窗口的大小,或者至少这是最简单的做事方式。只有一个窗口,您只能在创建窗口后调整大小,并且每次调整窗口大小或重新整形时。你可能会争辩说有更好的方法可以通过从矩阵堆栈推送和弹出来实现这一点,在这种情况下,请发表评论并留下其他答案。
首先,您需要声明两个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或glLoadIdentity,如果您不想重置矩阵转换堆栈...
现在做你的绘图:glBegin()
和glEnd()
以及你需要做的所有其他事情。
最后,请致电window.Display()
或window2.Display()
,具体取决于您刚刚绘制的内容。现在回到上面的有趣部分,并为另一个窗口调用resize方法,并继续为第二个窗口执行您需要做的所有事情,就像第一个窗口一样!
现在享受带有多个窗口的OpenGL SFML编程。您可能希望将一大堆窗口插入到矢量或其他花哨的容器中。
[编辑]出于某种原因,sf :: Windows是不可复制的,这意味着你不能将它们推送到像deque或vector这样的容器中。这可能是由于一些OpenGL特定的东西,如果你试图将所有位从一个窗口类复制到另一个窗口类,这将“出错”。 (也许?)相反,sf::Window* = new sf::Window[number_of_windows]
和unsigned int number_of_windows = 2
就足够了,虽然不是很好......