Pregunta

Estoy tratando de representar algunas mallas con la proyección Frustum sobre una imagen de fondo (proyección ortográfica). No importa lo que haga, la imagen de fondo sigue estando en la cima de la escena (ocultando las mallas).

He probado una pequeña prueba, cuando los he presentado a ambos con la misma matriz de proyección que estaban en el orden correcto, la imagen de fondo estaba detrás de las mallas.

Estas son las matrices de proyección y el inicio de profundidad: Buffer:

glEnable(GL_DEPTH_TEST);
glClearDepthf( 1.0f );
glDepthFunc( GL_LEQUAL );
glDepthMask (GL_TRUE);

EGLConfig eglconfig;
EGLint const attrib_list[] = {
    EGL_DEPTH_SIZE, 16,
    EGL_NONE
};
EGLint numreturned;
CHECK(eglChooseConfig(esContext.eglDisplay, attrib_list, &eglconfig, 1, &numreturned) != EGL_FALSE);

float fieldOfView = 60.0;
float znear = 0.1f;
float zfar = 100000;
float size = (float)(znear * tanf((fieldOfView * M_PI /180.0f) / 2.0f)); 

m_orthoProjMatrix.loadOrtho(0, 
                            screenWidth, 
                            0, 
                            screenHeight, 
                            znear, 
                            zfar);

m_frustProjMatrix.loadFrustum(-size, 
                               size, 
                              -size / (screenWidth / screenHeight), 
                               size / (screenWidth / screenHeight), 
                               znear, 
                               zfar);

Estoy limpiando los buffers con: GLCLEAR (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Una última cosa ... Cuando deshabilito GL_DEPTH_TEST, las mallas se dibujan frente a la imagen de fondo porque el fondo se llama primero.

No puedo decir cuál, el buffer de profundidad o las matrices de proyección, causando este problema. Los valores de las matrices con screenwidth = 960 y screenHeight = 640:

Orthographic Proj Matrix:
0.00208 0.00000 0.00000 -1.00000
0.00000 0.00313 0.00000 -1.00000
0.00000 0.00000 0.00000 -1.00000
0.00000 0.00000 0.00000  1.00000

Frustum Proj Matrix:
1.73205 0.00000  0.00000  0.00000
0.00000 2.59808  0.00000  0.00000
0.00000 0.00000 -1.00000 -0.20000
0.00000 0.00000 -1.00000  0.00000

Camera Settings:
Vector3 pos(0,10,50);
Vector3 at(0,0,0);
Vector3 up(0,1,0);
LookAt(pos,at,up);

Scene Settings:
Vector3 BackgroundImagePosition (0,0, -430);
Vector3 SomeMesh(0,0,0);

¿Qué estoy haciendo mal? Amir.

Editar: Así estoy dibujando las imágenes con la proyección ortográfica:

GLfloat verts[] = { 
image->x + image->width  , image->y                , image->z,
image->x + image->width  , image->y + image->height, image->z,
image->x                 , image->y + image->height, image->z,
image->x                 , image->y                , image->z};
Matrix4s mv(m_camera->getCameraViewMatrix());
Matrix4f proj(ResManPtr->getOrthoProjMatrix() * mv);
glUniformMatrix4fv(prog->getUniformLocation("u_projMatrix"), 1, GL_FALSE, &(*proj));
glActiveTexture(GL_TEXTURE0);
image->tex->bind();
glUniform1i(prog->getUniformLocation("s_texture"), 0);
glEnableVertexAttribArray(prog->getAttribLocation("a_position")); 
glVertexAttribPointer(prog->getAttribLocation("a_position"), 3, GL_FLOAT, GL_FALSE, 0, verts); 
glEnableVertexAttribArray(prog->getAttribLocation("a_texCoord"));
glVertexAttribPointer(prog->getAttribLocation("a_texCoord"), 2, GL_FLOAT, GL_FALSE, 0, m_texcoord);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

Y así es como estoy dibujando las mallas con la proyección frustum:

Matrix4f mv(world->getCamera()->getCameraViewMatrix());
const btVector3& dir = getDirection();
Scalar xzAngle = atan2s(dir.x(), dir.z()) - (Scalar)M_PI_2;
btVector3 origin = getGhostObject()->getWorldTransform().getOrigin();
mv.applyTranslate(origin.x(), origin.y() - m_width/2, origin.z());
mv.applyRotateY(xzAngle);    
GLProgramPtr prog = ResManPtr->getProgramMap()[Consts::DEFAULT_PROGRAM_KEY];
Matrix4f proj(ResManPtr->getFrustProjMatrix() * mv);
glUniformMatrix4fv(prog->getUniformLocation("u_projMatrix"), 1, GL_FALSE, &(*proj));
glActiveTexture(GL_TEXTURE0);
m_texture->bind();  
glUniform1i(prog->getUniformLocation("s_texture") , 0);
m_model->render(frame_number);
¿Fue útil?

Solución

Si entiendo correctamente, desea hacer las siguientes cosas separadas:

  • Dibuja un quad de pantalla completa con una textura
  • Haz algo para que este quad no se tenga en cuenta en el z-buffer
  • Luego, dibuje una malla (con cualquier proyección, vista y matrices de modelo que desee) encima.

"Cuando deshabilito GL_DEPTH_TEST, las mallas se dibujan frente a la imagen de fondo porque el fondo se llama primero ..." -> Supongo que puede dibujar tanto su quad de pantalla completa como nuestra malla por separado. Entonces, la configuración de VBO, las matrices, las texturas y las cosas son buenas. Es el único punto #2 que falla.

  • Solución 1:

Borre todo para un nuevo marco, como de costumbre. Z-Buffer será 1.0 en todas partes

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Dibuja el fondo. Su búfer de color está bien, pero apesta porque el z-buffer contendrá la profundidad de su quad, digamos 0.5. Entonces, cuando represente su malla, tendrá que tener la suerte para que los nuevos valores de profundidad sean menores que 0.5, o la prueba de profundidad falle. Pero podemos hacer algo al respecto: simplemente borre el z-buffer nuevamente a 1.0:

glClear(GL_DEPTH_BUFFER_BIT);

Ahora, dibuja la otra malla como de costumbre. La matriz ModelViewProyección ha cambiado, pero OpenGL no sabe que: todo lo que sabe es que la profundidad es 1.0 en todas partes. Entonces, la prueba de profundidad siempre tendrá éxito para su malla. Por lo tanto, verá su malla donde debe estar, con valores Z correctos y el quad de fondo en cualquier otro lugar.

  • Solución 2

Aquí, evita que los valores de profundidad se actualicen cuando se dibuja el quad de pantalla completa.

Desactivar escrituras en el búfer de profundidad:

glDepthMask(GL_FALSE);

Dibuja el fondo. El búfer de color estará bien, y Z-Buffer aún contendrá 1.0 en todas partes, según lo establecido por GlCLear () algunas líneas arriba.

Ahora vuelva a habilitar escribe en el búfer de profundidad:

glDepthMask(GL_TRUE);

Dibuja la otra malla. Como antes, Z-Buffer será 1.0 en todas partes, como si hubiera llamado glcLear (), por lo que si su malla está en el frustum (obviamente tiene que ser), su Z será, por ejemplo, 0.5, y lo hará ser dibujado.

  • Solución 3

Simplemente dibuje su fondo lejos de la cámara, cerca del plano de recorte lejano. (es decir, con un componente Z grande). Su componente Z será de 0.9999 o algo así, y al igual que antes, Mesh dejará bien.

Realmente, realmente no puedo explicar en más detalles. Lo siento si todavía no está claro, traté de reformular cada idea de varias maneras, no puedo hacer nada más.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top