无法在OpenGL中的2D(Ortho)上绘制3D(Frustum)

我试图在背景图像(正投影)上渲染一些带有Frustum投影的网格。 无论我做什么,背景图像都保持在场景的顶部(隐藏网格)。

我试过了一点测试 - 当我用相同的投影矩阵将它们渲染成正确的顺序时 - 背景图像位于网格后面。

这些是投影矩阵和Depth-Buffer init:

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

我正在清理缓冲区:glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

最后一件事..当我禁用GL_DEPTH_TEST时,网格被绘制在背景图像的前面,因为背景首先被调用。

我无法确定哪一个深度缓冲区或投影矩阵导致了这个问题.. screenWidth = 960和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);

我究竟做错了什么? 阿米尔。

编辑:这是我如何绘制与正交投影的图像:

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

这就是我用截锥投影绘制网格的方式:

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

如果我理解正确,你想做以下单独的事情:

  • 绘制一个全屏幕的四边形上有纹理
  • 做一些事情,以便在z缓冲区中不考虑这个四元组
  • 之后,在其上绘制一个网格(使用任何投影,视图和模型矩阵)。
  • “当我禁用GL_DEPTH_TEST时,网格被绘制在背景图像的前面,因为背景首先被调用。” - >我认为你可以分别绘制你的全屏四边形和我们的网格。 所以VBO的设置,矩阵,纹理和东西都很好。 这只是错过了第二点。

  • 解决方案1:
  • 像往常一样清除一个新的框架的一切。 Z缓冲区到处都是1.0

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    

    绘制背景。 你的颜色缓冲区是好的,但它很吸引人,因为z缓冲区将包含你的四边形的深度,比方说0.5。 所以当你渲染网格时,你必须足够幸运,以便新的深度值小于0.5,否则深度测试将失败。 但我们可以做一些事情:只需将z缓冲区再次清除为1.0即可:

    glClear(GL_DEPTH_BUFFER_BIT);
    

    现在,像往常一样绘制其他网格。 ModelViewProjection矩阵已经改变,但OpenGL并不知道:它所知道的是深度在任何地方都是1.0。 所以深度测试将总是成功的为您的网格。 这样你就可以看到你的网格应该在哪里,具有正确的z值,还有其他地方的背景四边形。

  • 解决方案2
  • 在这里,您可以防止在绘制全屏四元组时更新来自更新的深度值。

    禁止在深度缓冲区写入:

    glDepthMask(GL_FALSE);
    

    绘制背景。 颜色缓冲区是可以的,并且z-buffer将仍然包含1.0到处的任何地方,如上面几行glClear()所设置的。

    现在重新启用对深度缓冲区的写入:

    glDepthMask(GL_TRUE);
    

    绘制另一个网格。 和以前一样,z-buffer在任何地方都是1.0,就像刚刚调用glClear()一样,所以如果你的网格在平截头体中(它显然必须是),那么它的z就是0.5,它会被画下来。

  • 解决方案3
  • 简单地将您的背景远离相机,在远剪裁平面附近绘制。 (即具有大的Z分量)。 它的Z分量将是0.9999或类似的东西,和以前一样,网格将渲染好。

    我真的,真的无法解释更多细节。 对不起,如果还不清楚,我试图用几种方法来重新构思每一个想法,不能做更多的事情。

    链接地址: http://www.djcxy.com/p/33967.html

    上一篇: Unable to Draw 3D (Frustum) on top of 2D (Ortho) in OpenGL

    下一篇: Drawing a smaller texture on a larger OpenGL texture on iPhone