我需要在两个不同的视口中在OpenGL中显示相同的对象,例如,一个使用ortographic投影,另一个使用透视。为了做到这一点,我需要在每次调用glViewport()之后再次绘制对象吗?
答案 0 :(得分:13)
Nehe有一个很好的教程如何做到这一点,他的网站通常是OpenGL问题的好资源。
答案 1 :(得分:9)
// normal mode
if(!divided_view_port)
glViewport(0, 0, w, h);
else
{
// right bottom
glViewport(w/2, h/2, w, h);
glLoadIdentity ();
gluLookAt(5.0f, 5.0f, 5.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
display();
// left bottom
glViewport(0, h/2, w/2, h);
glLoadIdentity();
gluLookAt (5.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
display();
// top right
glViewport(w/2, 0, w, h/2);
glLoadIdentity();
gluLookAt(0.0f, 0.0f, 5.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
display();
// top left
glViewport(0, 0, w/2, h/2);
glLoadIdentity();
gluLookAt(0.0f, 5.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f);
display();
}
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-2.0, 2.0,
-2.0 * (GLfloat) h / (GLfloat) w, 2.0 * (GLfloat) h / (GLfloat) w,
-10.0, 100.0);
else
glOrtho(-2.0 * (GLfloat) w / (GLfloat) h, 2.0 * (GLfloat) w / (GLfloat) h,
-2.0, 2.0,
-10.0, 100.0);
glMatrixMode(GL_MODELVIEW);
答案 2 :(得分:3)
是,
并且您还应该更改剪刀设置,以便在两个视图位于同一窗口中时保持清晰的分离。
答案 3 :(得分:3)
最小可运行示例
与this answer类似,但更直接且可编辑。输出:
代码:
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
static int width;
static int height;
static void display(void) {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glViewport(0, 0, width/2, height/2);
glLoadIdentity();
gluLookAt(0.0, 0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glutWireTeapot(1);
glViewport(width/2, 0, width/2, height/2);
glLoadIdentity();
gluLookAt(0.0, 0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glutWireTeapot(1);
glViewport(0, height/2, width/2, height/2);
glLoadIdentity();
gluLookAt(0.0, 3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
glutWireTeapot(1);
glViewport(width/2, height/2, width/2, height/2);
glLoadIdentity();
gluLookAt(0.0, -3.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
glutWireTeapot(1);
glFlush();
}
static void reshape(int w, int h) {
width = w;
height = h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return EXIT_SUCCESS;
}
编译:
gcc -lGL -lGLU -lglut main.c
在OpenGL 4.5.0 NVIDIA 352.63,Ubuntu 15.10上进行测试。
TODO:我认为在现代OpenGL 4中你应该只渲染到纹理,然后将这些纹理正交放在屏幕上,看作是一个起点:http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/
答案 4 :(得分:1)
在GL 4中,您可以在一个渲染过程中渲染到许多视口。请参阅ARB_viewport_array及相关概念。
答案 5 :(得分:0)
将OpenGL视为准备输出到您当前正在使用的窗口的命令。
使用OpenGL有两个命令,即使是NEHE的教程也没有告诉你重要性:
wglCreateContext - 它采用窗口设备上下文DC,可以从任何窗口获取 - 无论是用户控件,窗口窗体,GL窗口还是其他应用程序窗口(如记事本)。这将创建一个OpenGL设备上下文 - 它们称为资源上下文 - 您稍后将使用它...
wglMakeCurrent - 它接受两个参数,即您正在处理的设备上下文(wglCreateContext中为Windows设备上下文传入的参数) - 以及返回的资源上下文。
仅仅利用这两件事 - 这是我的建议:
NEHE的教程提供的解决方案仅利用现有窗口并将屏幕分段以进行绘制。这是教程:http://nehe.gamedev.net/tutorial/multiple_viewports/20002/
利用glViewport,您需要在每次更新时重新绘制。
这是一种方法。
但还有另一种 - 图形和处理器强度较低的方法:
通过利用用户控件为每个视图创建一个窗口。
每个窗口都拥有它自己的hWnd。
获取DC,处理wglcreatecontext,然后在计时器上(我的每秒30帧),如果检测到状态更改,则为该视图选择wglMakeCurrent并重绘。否则,只需完全跳过该部分。
这节省了宝贵的处理能力,并且还减少了必须手动管理窗口和视口计算的代码。