如何在OpenGL中使用多个视口?

Vic*_*újo 28 opengl viewport

我需要在两个不同的视口中在OpenGL中显示相同的对象,例如,一个使用ortographic投影,另一个使用透视.为了做到这一点,我是否需要在每次调用glViewport()后再次绘制对象?

Ed *_*mes 13

Nehe有一个很好的教程如何做到这一点,他的网站通常是OpenGL问题的一个很好的资源.

  • 对我来说,链接的文章建议"是的,[你必须]"答案 - 但它的作者似乎*希望*在每个视口上绘制不同的东西.因此,如果有人用简单的话确认是否"是的,你必须在每个视口中重绘对象",或者"不,你没有 - 看到<some-link>",我仍然会感激. (3认同)

小智 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);
Run Code Online (Sandbox Code Playgroud)


Cir*_*四事件 7

最小的可运行示例

类似于这个答案,但更直接和可编译。输出:

主文件

#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;
}
Run Code Online (Sandbox Code Playgroud)

编译并运行:

gcc -o main.out main.c -lGL -lGLU -lglut
./main.out
Run Code Online (Sandbox Code Playgroud)

我认为在现代 OpenGL 4 中,您应该只渲染纹理,然后将这些纹理正交放置在屏幕上,将此视为起点:http : //www.opengl-tutorial.org/intermediate-tutorials/tutorial-14 -渲染到纹理/

在 OpenGL 4.5.0 NVIDIA 352.63、Ubuntu 15.10 上测试。

  • @CiroSantilli六四事件法轮功包卓轩:是的,但是如果没有对使用`glViewport`的*什么*进行一些解释,读者不知道为什么这个调用很重要或它有什么作用。诚然,这个问题的答案都不是很好,但是如果您要回答一个较旧的问题,您应该愿意比其他问题要好得多。这意味着全面,而不仅仅是可编译。 (2认同)