无法在OpenGL的2D(Ortho)顶部绘制3D(Frustum)
-
26-10-2019 - |
题
我正在尝试在背景图像之上渲染一些网格(正拼图投影)。无论我做什么,背景图像都在场景的顶部(隐藏网眼)。
我已经尝试了一些测试 - 当我用相同的投影矩阵渲染它们时,其顺序正确 - 背景图像在网眼后面。
这些是投影矩阵和深度缓冲的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);
我正在使用以下方式清洁缓冲区(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);
这就是我如何用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);
解决方案
如果我正确理解,您想做以下不同的事情:
- 绘制一个带有纹理的全屏四胎
- 做某事,以便在Z-Buffer中不考虑这四倍
- 之后,在其顶部绘制网格(带有任何投影,视图和模型矩阵)。
“当我禁用gl_depth_test时,网眼被绘制在背景图像的前面,因为背景是先称为。因此,VBO设置,矩阵,纹理和东西都很好。错过的只是第2点。
- 解决方案1:
像往常一样清除新框架的所有内容。 Z-Buffer到处都是1.0
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
绘制背景。您的颜色缓冲区还可以,但是它很烂,因为Z-Buffer将包含四边形的深度,假设0.5。因此,当您渲染网格时,您必须足够幸运,以使新的深度值小于0.5,否则深度测试将失败。但是我们可以对此做些事情:只需再次将Z-Buffer清除到1.0:
glClear(GL_DEPTH_BUFFER_BIT);
现在,像往常一样绘制其他网格。 ModelViewProctoction矩阵已经改变,但是OpenGL不知道:它所知道的是深度为1.0。因此,深度测试将始终为您的网眼成功。因此,您将看到您的网格在位置,并具有正确的Z值,以及其他任何地方的背景四边形。
- 解决方案2
在这里,当绘制全屏四边形时,您可以防止深度值更新。
禁用在深度缓冲区上写入:
glDepthMask(GL_FALSE);
绘制背景。颜色缓冲区会没事,Z-Buffer仍然将到处包含1.0个,如Glclear()上方几行设置的那样。
现在重新启用深度缓冲区:
glDepthMask(GL_TRUE);
绘制另一个网眼。和以前一样,Z-Buffer到处都是1.0,就像您刚刚称为Glclear()一样,如果您的网格在flustum中(显然必须是),则它的Z将为0.5,它将被画下来。
- 解决方案3
只需将您的背景远离相机,靠近遥远的剪裁平面。 (即带有大Z组件)。它的Z组件将为0.9999或类似的东西,就像以前一样,网眼将变得无所适从。
我真的,真的无法解释更多细节。抱歉,如果仍然不清楚,我试图通过几种方式重新重新重新制定每个想法,不能做更多的事情。