在OpenGL中,如何使一个对象始终位于所有其他对象之前?
我有这个功能,它在屏幕左下角绘制一个小的3D轴坐标系,但根据我面前的内容,它可能会被剪裁 例如,我在地面上绘制了一个平面地形,在XZ平面上Y=0。相机的位置为Y=1.75(模拟普通人的身高)。如果我向上看,它工作正常,如果我向下看,它会被地平面夹住 正在查找:在OpenGL中,如何使一个对象始终位于所有其他对象之前?,opengl,viewport,clipping,foreground,depth,Opengl,Viewport,Clipping,Foreground,Depth,我有这个功能,它在屏幕左下角绘制一个小的3D轴坐标系,但根据我面前的内容,它可能会被剪裁 例如,我在地面上绘制了一个平面地形,在XZ平面上Y=0。相机的位置为Y=1.75(模拟普通人的身高)。如果我向上看,它工作正常,如果我向下看,它会被地平面夹住 正在查找: 俯视: 我调用的在拐角处绘制轴系统的函数如下: void Axis3D::DrawCameraAxisSystem(float radius, float height, const Vector3D rotation) { if
俯视: 我调用的在拐角处绘制轴系统的函数如下:
void Axis3D::DrawCameraAxisSystem(float radius, float height, const Vector3D rotation) {
if(vpHeight == 0) vpHeight = 1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, vpWidth, vpHeight);
gluPerspective(45.0f, 1.0 * vpWidth / vpHeight, 1.0f, 5.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
glRotatef(-rotation.x, 1.0f, 0.0f, 0.0f);
glRotatef(-rotation.y, 0.0f, 1.0f, 0.0f);
DrawAxisSystem(radius, height);
}
现在,我认为有两个主要功能与问题相关:
glutDisplayFunc(renderScene);
glutReshapeFunc(changeSize);
void changeSize(int width, int height) {
if(height == 0) height = 1;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, width, height);
gluPerspective(60.0f, 1.0 * width / height, 1.0f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
}
void renderScene(void) {
glClearColor(0.7f, 0.7f, 0.7f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
changeSize(glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));
glLoadIdentity();
SceneCamera.Move(CameraDirection, elapsedTime);
SceneCamera.LookAt();
SceneAxis.DrawCameraAxisSystem(0.03f, 0.8f, SceneCamera.GetRotationAngles());
glutSwapBuffers();
}
建议?您想禁用深度测试(这样就不会被任何东西打断): 如果已经预变换了点(看起来没有),请将视图和投影矩阵设置为“标识” 编辑:
如果需要轴位保持测试和有序,则可能需要在渲染它和主场景之间清除深度缓冲区(
glClear(GL\u depth\u buffer\u bit)
)。这将重置深度缓冲区,以便绘制标记(并显示在前面),但仍然正确地剔除标记。您不必禁用深度测试,只需glClear(GL\u depth\u buffer\u位)代码>在渲染覆盖之前。然后不管深度信息是什么都消失了,但像素仍然存在。但是,您的覆盖仍将正确渲染。您可以尝试启用混合,然后在片段着色器中手动设置alpha和color。但这可能有点过分;-) 您还可以为3D轴保留一小部分深度范围。其余的都是你的场景。像这样:
// reserve 1% of the front depth range for the 3D axis
glDepthRange(0, 0.01);
Draw3DAxis();
// reserve 99% of the back depth range for the 3D axis
glDepthRange(0.01, 1.0);
DrawScene();
// restore depth range
glDepthRange(0, 1.0);
`glGetBooleanv(GL_混合和m_原始混合)
glGetBooleanv(GL_深度测试和m_原点深度)
glGetBooleanv(GL_CULL_FACE和m_origin_CULL)
设置字母混合(真)
setDepthTest(假)
设定面(假)//一成不变
//您的绘图()
SetAlphaBlend(m_origin_blend>0?真:假)
setDepthTest(m_原点深度>0?真:假)
setCullFace(m_原点_cull>0?真:假)` 如果我在绘制轴系统之前禁用深度测试,轴本身将看起来很奇怪,3轴之间没有深度。是否可以仅在两个视口之间禁用深度测试?我不知道你所说的“预变换点”是什么意思,但在设置每个矩阵模式后都会加载单位矩阵,我是否遗漏了什么?如果你的几何体是正确的,那么矩阵是正确的。要在不打断轴的情况下修复场景,请参见编辑:你已经得到了恰当的回答。但有一件事你必须明白:OpenGL不把几何体当作“对象”(OpenGL对象是不同的东西,例如纹理或顶点缓冲区)。OpenGL是一个光栅化器,图片一次只生成一个三角形。因为问“如何把一个物体放在前面”虽然完全可以理解,但并不能解决实际问题。您想知道的是,如何在仍然能够使用深度测试的情况下,在帧缓冲区的现有内容之上可靠地绘制一些内容。
// reserve 1% of the front depth range for the 3D axis
glDepthRange(0, 0.01);
Draw3DAxis();
// reserve 99% of the back depth range for the 3D axis
glDepthRange(0.01, 1.0);
DrawScene();
// restore depth range
glDepthRange(0, 1.0);