C++ 深度测试的奇怪结果
在渲染对象时启用GL_DEPTH_TEST时,我遇到了一个问题,下面是发生的情况: GL_CULL_面在该面上禁用 它只发生在透视视图中!有人知道发生了什么事吗 我正在使用Qt4.8进行此操作 当然,如果我禁用深度测试,它看起来很好,但是对象以错误的方式覆盖,正如预期的那样 更新 我用以下方法创建投影矩阵:C++ 深度测试的奇怪结果,c++,qt,opengl,qt4,depth-testing,C++,Qt,Opengl,Qt4,Depth Testing,在渲染对象时启用GL_DEPTH_TEST时,我遇到了一个问题,下面是发生的情况: GL_CULL_面在该面上禁用 它只发生在透视视图中!有人知道发生了什么事吗 我正在使用Qt4.8进行此操作 当然,如果我禁用深度测试,它看起来很好,但是对象以错误的方式覆盖,正如预期的那样 更新 我用以下方法创建投影矩阵: ProjectionMatrix.setToIdentity(); ProjectionMatrix.perspective(45, float(width) / float(height
ProjectionMatrix.setToIdentity();
ProjectionMatrix.perspective(45, float(width) / float(height), 0, 20.0);
其中,宽度和高度与视口大小相关
以下是我绘制场景的代码:
void GLWidget::paintGL()
{
glClearColor(0.4765625, 0.54296875, 0.6171875, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
editor->setUniformValue("projectMatrix", controller->getProjectionMatrix());
editor->setUniformValue("viewMatrix", controller->getViewMatrix());
/** Dibujemos los grids **/
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
for (int i=0; i<3; i++)
{
if ((front && i==1) || (side && i==2) || (i==0))
{
editor->setUniformValue("modelMatrix", Objects.at(i).modelMatrix);
editor->setUniformValue("normalMatrix", Objects[i].getNormalMatrix());
editor->setUniformValue("texture", textureon);
glEnableClientState(GL_VERTEX_ARRAY);
editor->enableAttributeArray("vertices");
Objects[i].vertexbuffer->bind();
editor->setAttributeBuffer("vertices", GL_FLOAT, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
editor->enableAttributeArray("texuv");
Objects[i].uvbuffer->bind();
editor->setAttributeBuffer ("texuv", GL_FLOAT, 0, 2);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
editor->enableAttributeArray("normals");
Objects[i].normalbuffer->bind();
editor->setAttributeBuffer ("normals", GL_FLOAT, 0, 3);
glDisableClientState(GL_NORMAL_ARRAY);
Objects[i].elementbuffer->bind();
glBindTexture(GL_TEXTURE_2D, Objects[i].texture);
glDrawElements(GL_TRIANGLES, Objects[i].indices.size(), GL_UNSIGNED_SHORT, (void*)0);
}
}
/** Ahora para las operaciones especificas de cada objeto **/
glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
for (int i=3; i<Objects.size(); i++)
{
//Objects[i].modelMatrix.scale(1.0, 1.0, 1.0);
//Objects[i].modelMatrix.rotate(1.0, 0.0, 1.0, 0.0);
editor->setUniformValue("modelMatrix", Objects.at(i).modelMatrix);
editor->setUniformValue("normalMatrix", Objects[i].getNormalMatrix());
editor->setUniformValue("texture", textureoff);
editor->setUniformValue("diffuseColor", Objects.at(i).diffuseColor);
editor->setUniformValue("shininess", Objects.at(i).shininess);
editor->setUniformValue("hardness", Objects.at(i).hardness);
editor->setUniformValue("LPos1", Objects.at(i).L1Pos);
editor->setUniformValue("LPos2", Objects.at(i).L2Pos);
editor->setUniformValue("LPos3", Objects.at(i).L3Pos);
editor->setUniformValue("LPos4", Objects.at(i).L4Pos);
glEnableClientState(GL_VERTEX_ARRAY);
editor->enableAttributeArray("vertices");
Objects[i].vertexbuffer->bind();
editor->setAttributeBuffer("vertices", GL_FLOAT, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
editor->enableAttributeArray("normals");
Objects[i].normalbuffer->bind();
editor->setAttributeBuffer ("normals", GL_FLOAT, 0, 3);
glDisableClientState(GL_NORMAL_ARRAY);
Objects[i].elementbuffer->bind();
glDrawElements(GL_TRIANGLES, Objects[i].indices.size(), GL_UNSIGNED_SHORT, (void*)0);
}
}
void GLWidget::paintGL()
{
glClearColor(0.4765625,0.54296875,0.6171875,1.0);
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
编辑器->设置UniformValue(“projectMatrix”,控制器->getProjectionMatrix());
编辑器->设置UniformValue(“viewMatrix”,控制器->getViewMatrix());
/**Dibujemos los网格**/
glDisable(GLU深度测试);
glDisable(GLU消隐面);
对于(int i=0;isetUniformValue(“modelMatrix”,Objects.at(i).modelMatrix);
编辑器->设置UniformValue(“normalMatrix”,对象[i].getNormalMatrix());
编辑器->设置UniformValue(“纹理”,textureon);
glEnableClientState(GL_顶点_数组);
编辑器->启用属性阵列(“顶点”);
对象[i].vertexbuffer->bind();
编辑器->设置属性缓冲(“顶点”,GL_浮点,0,3);
glDisableClientState(GL_顶点_数组);
glEnableClientState(GL_纹理_坐标_阵列);
编辑器->启用属性array(“texuv”);
对象[i].uvbuffer->bind();
编辑器->设置属性缓冲(“texuv”,GL_FLOAT,0,2);
glDisableClientState(GL_纹理_坐标_数组);
glEnableClientState(GL_普通_阵列);
编辑器->启用属性array(“法线”);
对象[i].normalbuffer->bind();
编辑器->设置属性缓冲(“法线”,GL_浮点,0,3);
glDisableClientState(GL_NORMAL_数组);
对象[i].elementbuffer->bind();
glBindTexture(GL_TEXTURE_2D,对象[i].纹理);
glpaurements(GL_三角形,对象[i].index.size(),GL_UNSIGNED_SHORT,(void*)0);
}
}
/**阿霍拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕拉·帕**/
glEnable(GLU深度试验);
//glEnable(GL_CULL_面);
对于(int i=3;isetUniformValue(“modelMatrix”,Objects.at(i).modelMatrix);
编辑器->设置UniformValue(“normalMatrix”,对象[i].getNormalMatrix());
编辑器->设置UniformValue(“纹理”,textureoff);
编辑器->设置UniforMValue(“diffuseColor”,Objects.at(i).diffuseColor);
编辑器->设置UniformValue(“反光度”,Objects.at(i).shininess);
编辑器->设置UniformValue(“硬度”,Objects.at(i).hardware);
编辑器->setUniformValue(“LPos1”,Objects.at(i).L1Pos);
编辑器->setUniformValue(“LPos2”,Objects.at(i).L2Pos);
编辑器->setUniformValue(“LPos3”,Objects.at(i).L3Pos);
编辑器->setUniformValue(“LPos4”,Objects.at(i).L4Pos);
glEnableClientState(GL_顶点_数组);
编辑器->启用属性阵列(“顶点”);
对象[i].vertexbuffer->bind();
编辑器->设置属性缓冲(“顶点”,GL_浮点,0,3);
glDisableClientState(GL_顶点_数组);
glEnableClientState(GL_普通_阵列);
编辑器->启用属性array(“法线”);
对象[i].normalbuffer->bind();
编辑器->设置属性缓冲(“法线”,GL_浮点,0,3);
glDisableClientState(GL_NORMAL_数组);
对象[i].elementbuffer->bind();
glpaurements(GL_三角形,对象[i].index.size(),GL_UNSIGNED_SHORT,(void*)0);
}
}
简而言之,我首先根据相机面对的位置绘制网格,以提供类似Blender的功能。然后,我绘制所有对象。我使用索引VBO来实现这一点
我也在CCW中绘制它们,我99%确定三角形是以这种方式传递给OpenGL的。投影矩阵的[EDIT perspective]近似值为零。这会导致透视分割后所有深度值等于一(.xyz
/.w
)。@Raxvan显然有正确的想法。试试这个
ProjectionMatrix.perspective(45, float(width) / float(height), 0.01, 20.0);
当然,对于大型场景,你需要一个大的深度范围,但是如果你把它做得太大,你会得到z-fighting,不同距离的碎片仍然具有相同的深度值,并且会在第一次获胜时被光栅化(这似乎是你面临的问题)。我尝试将我的深度范围保持在10000倍以内
如果您有非常大的场景,您可能需要寻找其他方法。首先,请使用更高精度的深度缓冲区。如果这还不够,可以使用两个投影矩阵,将场景分割为近距离和远距离对象。如果对象与边界相交,有时会导致问题。以下是一些相关链接
zNear
值0.0。问题实际上是使用透视投影矩阵;0.0在正字法中完全有效。