2015-07-15 6 views
2

У меня есть программа, которая читает панорамную панораму 360 и читает IMU, рисуя правильную часть панорамы на основе местоположения головы.рендеринг двух перекрытых FOV с использованием glFrustum без GLUT_STEREO

Я создаю два окна, по одному на дисплей, и не хочу полагаться на GLUT_STEREO. Поэтому призывы draw() для каждого дисплея независимы, но сейчас они отображают одно и то же, что и gluSphere для представления панорамы. Чтобы нарисовать правильную часть сферы, данные ИДУ (кватернион) становятся матрицей вращения и эта матрица умножается на проекцию.

Я хотел бы создать немного перекрытия с двумя изображениями, как показано на следующем рисунке: overlapped

Например, красный прямоугольник является мой левый дисплей и синий прямоугольник является мой правый дисплей, но в середине есть некоторое перекрытие.

Я читал статью о стереоизображении, и я решил, что решение будет заключаться в замене вызова gluPerspective() на glFrustum() и просто изменить оба параметра слева и справа одновременно. Я подумал о вычитании значения на левый/правый параметр glFrustum() на дисплее, и добавление некоторого значения в параметр слева/справа glFrustum() могло бы сделать трюк. Я изменил матрицу проекции на glutReshapeFunc() Обратный вызов, чтобы сделать именно это:

void resize(int width, int height) 
{ 
    glViewport(0, 0, width, height); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    GLdouble near = 0.1; 
    GLdouble far = 100.0; 

    GLdouble aspect = (double) width/(double) height; 
    GLdouble top = tan(FOVY/360 * M_PI) * near; 
    GLdouble bottom = -top; 
    GLdouble right = top * aspect; 
    GLdouble left = -right; 

    // TODO: Canned value for testing 
    left += 0.5; 
    right += 0.5; 

    glFrustum(left, right, bottom, top, near, far); 
    // gluPerspective(FOVY, aspect, near, far); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
} 

К сожалению, это не то, что я ожидал (и я действительно не знаю, почему). Я бы подумал, что изменение левого и правого параметра glFrustum() будет поддерживать одно и то же горизонтальное FOV, но перемещать его влево или вправо. Кажется, что либо растягивает изображение в или из.

Я играл с glTranslatef() на ModelView или glLookAt(), но место мне не ясно. Почему glFrustum() не имеет правильного поведения, пожалуйста, и чего мне не хватает?

ответ

1

Изменить усечку и Камера.

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

3D Stereo Rendering Using OpenGL (and GLUT):

/* Misc stuff */ 
ratio = camera.screenwidth/(double)camera.screenheight; 
radians = DTOR * camera.aperture/2; 
wd2  = near * tan(radians); 
ndfl = near/camera.focallength; 

/* Derive the two eye positions */ 
CROSSPROD(camera.vd,camera.vu,r); 
Normalise(&r); 
r.x *= camera.eyesep/2.0; 
r.y *= camera.eyesep/2.0; 
r.z *= camera.eyesep/2.0; 

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
left = - ratio * wd2 - 0.5 * camera.eyesep * ndfl; 
right = ratio * wd2 - 0.5 * camera.eyesep * ndfl; 
top = wd2; 
bottom = - wd2; 
glFrustum(left,right,bottom,top,near,far); 

glMatrixMode(GL_MODELVIEW); 
glDrawBuffer(GL_BACK_RIGHT); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glLoadIdentity(); 
gluLookAt(camera.vp.x + r.x,camera.vp.y + r.y,camera.vp.z + r.z, 
      camera.vp.x + r.x + camera.vd.x, 
      camera.vp.y + r.y + camera.vd.y, 
      camera.vp.z + r.z + camera.vd.z, 
      camera.vu.x,camera.vu.y,camera.vu.z); 
MakeLighting(); 
MakeGeometry(); 

glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
left = - ratio * wd2 + 0.5 * camera.eyesep * ndfl; 
right = ratio * wd2 + 0.5 * camera.eyesep * ndfl; 
top = wd2; 
bottom = - wd2; 
glFrustum(left,right,bottom,top,near,far); 

glMatrixMode(GL_MODELVIEW); 
glDrawBuffer(GL_BACK_LEFT); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glLoadIdentity(); 
gluLookAt(camera.vp.x - r.x,camera.vp.y - r.y,camera.vp.z - r.z, 
      camera.vp.x - r.x + camera.vd.x, 
      camera.vp.y - r.y + camera.vd.y, 
      camera.vp.z - r.z + camera.vd.z, 
      camera.vu.x,camera.vu.y,camera.vu.z); 
MakeLighting(); 
MakeGeometry(); 

glutSwapBuffers(); 

Заменить glDrawBuffer() вызовы с соответствующими FBO привязок.

+0

Спасибо большое! Как левое, так и правое - это то, что мне нужно. Я все еще не совсем понимаю это, но, похоже, работает! Большое спасибо! – Jary316