Как использовать несколько окон просмотра в OpenGL? - PullRequest
27 голосов
/ 07 апреля 2009

Мне нужно показать один и тот же объект в OpenGL в двух разных окнах просмотра, например, один с использованием ортографической проекции, а другой с использованием перспективы. Для этого нужно ли снова рисовать объект после каждого вызова glViewport ()?

Ответы [ 6 ]

13 голосов
/ 07 апреля 2009

Nehe имеет хороший учебник о том, как это сделать, и его сайт, как правило, хороший ресурс для вопросов OpenGL.

9 голосов
/ 25 августа 2009
 // 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);
3 голосов

Пример минимального запуска

Аналогично этому ответу , но более прямым и компилируемым. Выход:

image

Code:

#include 

#include 
#include 
#include 

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;
}

Compile with:

gcc -lGL -lGLU -lglut main.c

Tested on OpenGL 4.5.0 NVIDIA 352.63, Ubuntu 15.10.

TODO: I think that in modern OpenGL 4 you should just render to textures, and then place those textures orthogonaly on the screen, see this as a starting point: http://www.opengl -tutorial.org / промежуточный-учебники / учебник-14-рендеринга в текстуру /

3 голосов
/ 07 апреля 2009

да,

и вам также следует изменить настройки ножниц, чтобы обеспечить четкое разделение между двумя видами, если они находятся в одном окне.

1 голос
/ 08 сентября 2017

В GL 4 вы можете выполнить рендеринг для многих видовых экранов за один проход рендеринга. См. ARB_viewport_array и связанные с ним понятия.

0 голосов
/ 23 июня 2015

Думайте об OpenGL как о не более чем командах, которые готовят вас к выводу в окно, с которым вы сейчас работаете.

Есть две команды с OpenGL, которые даже в руководствах NEHE не говорят вам о важности:

wglCreateContext - который принимает DC контекста оконного устройства, может быть получен из ЛЮБОГО окна - будь то пользовательский элемент управления, форма окна, окно GL или другое окно приложения (например, блокнот). Это создает контекст устройства OpenGL - они называют контекстом ресурса - который вы позже используете с ...

wglMakeCurrent - который принимает два параметра: контекст устройства, с которым вы работаете (параметр, переданный для контекста устройства Windows в wglCreateContext) - и возвращаемый контекст ресурса.

Используя только эти две вещи - вот мой совет:

Учебное пособие NEHE предлагает решение, которое использует ТОЛЬКО существующее окно и сегментирует экран для рисования. Вот учебник: http://nehe.gamedev.net/tutorial/multiple_viewports/20002/

Используя glViewport, вам нужно будет перерисовывать каждое обновление.

Это один из методов.

Но есть и другой, менее графический и интенсивный процессор:

Создать окно для каждого вида, используя пользовательский элемент управления.

Каждое окно имеет свой собственный hWnd.

Получите DC, обработайте wglcreatecontext, а затем по таймеру (у меня 30 кадров в секунду), если вы обнаружите изменение состояния, затем выберите wglMakeCurrent для этого представления и перерисовайте. В противном случае, просто пропустите раздел полностью.

Это экономит ценную вычислительную мощность, а также избавляет код от необходимости вручную управлять вычислениями окна и области просмотра.

...