在OpenGL中,如何使一个对象始终位于所有其他对象之前?

在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

我有这个功能,它在屏幕左下角绘制一个小的3D轴坐标系,但根据我面前的内容,它可能会被剪裁

例如,我在地面上绘制了一个平面地形,在XZ平面上Y=0。相机的位置为Y=1.75(模拟普通人的身高)。如果我向上看,它工作正常,如果我向下看,它会被地平面夹住

正在查找:
俯视:

我调用的在拐角处绘制轴系统的函数如下:

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