¿Cómo usar múltiples viewports en OpenGL?
Necesito mostrar el mismo objeto en OpenGL en dos viewports diferentes, por ejemplo, uno usando proyección ortográfica y el otro usando perspectiva. Para hacer esto, ¿necesito dibujar de nuevo el objeto después de cada llamada a glViewport()?
6 answers
Nehe tiene un buen tutorial sobre cómo hacer esto, y su sitio es generalmente un buen recurso para preguntas OpenGL.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-07 15:39:57
// 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);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-05 15:25:05
Sí
Y también debe cambiar la configuración de tijera para tener una separación limpia entre las dos vistas si están en la misma ventana.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-07 15:54:29
Ejemplo ejecutable mínimo
Similar a esta respuesta, pero más directa y compilable. Salida:
Código:
#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;
}
Compilar con:
gcc -lGL -lGLU -lglut main.c
Probado en OpenGL 4.5.0 NVIDIA 352.63, Ubuntu 15.10.
TODO: Creo que en OpenGL 4 moderno solo debes renderizar a texturas, y luego colocar esas texturas ortogonalmente en la pantalla, ve esto como un punto de partida: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture /
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-21 22:52:51
En GL 4 puede renderizar a muchas vistas en un solo pase de renderizado. Véase ARB_viewport_array y conceptos relacionados.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-07 22:46:50
Piense en OpenGL como nada más que comandos que lo preparan para la salida a la ventana con la que está trabajando actualmente.
Hay dos comandos con OpenGL que ni siquiera los tutoriales de NEHE te dicen la importancia de:
WglCreateContext - que toma un DC context de window device, se puede obtener desde CUALQUIER ventana, ya sea un control de usuario, un formulario de windows, una ventana GL u otra ventana de aplicación (como el bloc de notas). Esto crea un contexto de dispositivo OpenGL-se refieren a como un contexto de recursos - que más tarde se utiliza con ...
WglMakeCurrent - que toma dos parámetros, el Contexto del Dispositivo con el que está tratando (el parámetro pasado para el Contexto del Dispositivo de Windows en wglCreateContext) - y el Contexto del Recurso que devuelve.
Aprovechando SOLO estas dos cosas-aquí está mi consejo:
El tutorial de NEHE proporciona una solución que aprovecha SOLO la ventana existente y segmenta la pantalla para dibujar. Aquí está el tutorial: http://nehe.gamedev.net/tutorial/multiple_viewports/20002 /
Aprovechando glViewport tendrá que volver a dibujar en cada actualización.
Ese es un método.
Pero hay otro método menos gráfico e intenso del procesador:
Cree una ventana para cada vista aprovechando un control de usuario.
Cada ventana tiene su propio hWnd.
Obtenga el DC, procese el wglcreatecontext, y luego, en un temporizador (el mío es de 30 fotogramas por segundo), si detecta el estado cambie, luego seleccione wglMakeCurrent para esa vista y vuelva a dibujar. De lo contrario, simplemente omita la sección por completo.
Esto conserva una valiosa potencia de procesamiento, y también reduce el código de tener que administrar los cálculos de ventana y vista manualmente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-23 19:53:56