it-swarm.com.de

Wie verwende ich mehrere Ansichtsfenster in OpenGL?

Ich muss dasselbe Objekt in OpenGL in zwei verschiedenen Ansichtsfenstern anzeigen, z. B. in einem mit ortografischer Projektion und im anderen mit Perspektive. Muss ich dazu das Objekt nach jedem Aufruf von glViewport () erneut zeichnen?

27
Victor Araújo

Nehe hat eine gute Anleitung dazu, und seine Seite ist im Allgemeinen eine gute Quelle für OpenGL-Fragen.

13
Ed James
 // 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);
9
p govind rao

Minimales lauffähiges Beispiel

Ähnlich wie diese Antwort , aber direkter und kompilierbarer. Ausgabe:

Code: 

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

Kompilieren mit:

gcc -lGL -lGLU -lglut main.c

Getestet mit OpenGL 4.5.0 NVIDIA 352.63, Ubuntu 15.10.

TODO: Ich denke, in modernen OpenGL 4 sollten Sie nur Texturen rendern und diese Texturen orthogonal auf dem Bildschirm platzieren. Sehen Sie dies als Ausgangspunkt: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/

ja,

sie sollten auch die Schereneinstellungen ändern, um eine saubere Trennung zwischen den beiden Ansichten zu erhalten, wenn sie sich im selben Fenster befinden.

3
fa.

In GL 4 können Sie in einem Rendering-Durchgang auf viele Ansichtsfenster rendern. Siehe ARB_viewport_array und verwandte Konzepte.

Stellen Sie sich OpenGL als nichts anderes als Befehle vor, die Sie auf die Ausgabe in das Fenster vorbereiten, mit dem Sie gerade arbeiten.

Es gibt zwei Befehle mit OpenGL, von denen selbst die NEHE-Tutorials nicht wissen, wie wichtig dies ist:

wglCreateContext - das einen Fenster-Gerätekontext DC enthält, kann über JEDES Fenster abgerufen werden - ob es sich um ein Benutzersteuerelement, ein Fensterformular, ein GL-Fenster oder ein anderes Anwendungsfenster (z. B. Notepad) handelt. Dadurch wird ein OpenGL-Gerätekontext erstellt, der als Ressourcenkontext bezeichnet wird, den Sie später mit ... verwenden.

wglMakeCurrent - nimmt zwei Parameter an, den Gerätekontext, mit dem Sie sich befassen (der für den Windows-Gerätekontext in wglCreateContext übergebene Parameter) und der zurückgegebene Ressourcenkontext. 

NUR diese beiden Dinge nutzen - hier mein Rat:

Das NEHE-Tutorial bietet eine Lösung, die NUR das vorhandene Fenster nutzt und den Bildschirm für das Zeichnen segmentiert. Hier ist das Tutorial: http://nehe.gamedev.net/tutorial/multiple_viewports/20002/

Durch die Nutzung von glViewport müssen Sie bei jedem Update erneut zeichnen. 

Das ist eine Methode. 

Aber es gibt noch eine andere - weniger grafisch und prozessorintensive Methode:

Erstellen Sie für jede Ansicht ein Fenster, indem Sie ein Benutzersteuerelement nutzen. 

Jedes Fenster hat sein eigenes HWnd. 

Holen Sie sich den DC, bearbeiten Sie den Befehl wglcreatecontext und dann, wenn Sie eine Zustandsänderung feststellen, einen Zeitgeber (mein Zeitgeber ist 30 Frames pro Sekunde), wählen Sie dann wglMakeCurrent für diese Ansicht und zeichnen Sie ihn neu. Ansonsten überspringen Sie einfach den Abschnitt vollständig. 

Dies spart wertvolle Rechenleistung und reduziert auch den Code, da die Fenster- und Viewport-Berechnungen manuell verwaltet werden müssen.