OpenTK深度测试不起作用

时间:2014-06-23 01:50:33

标签: c# opengl 3d opentk

我在我的Computer Graphics类中有一个使用openTK编写2.5D地图的作业。当我试图为我的绘图启用gl_Depth_Test时,它没有按预期工作。当我改变Lequal和Always之间的DepthFunc时,3D形状相互重叠,结果相同。我试图把深度缓冲区拿出来。当我改变x旋转xrot时它会改变,但对于DepthFunc Always和Lequal总是相同。当我将DepthFunc更改为除Less和Equal之外的所有其他内容时,不会显示任何内容。我的init和render的代码如下。在这个代码cameraPos Z是非常大的意思。顶点是Oxy平面上的2D点。方式是Oxy平面中的2D多边形或3D形状。在形状的情况下,它们仅仅是Oxy平面中的2D多边形,通过z轴拉伸它们具有假3D效果。 initWorld代码基本上意味着将Vertex坐标移动到Oxy平面的原点周围以便于旋转。我从LookAt / gluLookat函数中获取了GLU.LookAt http://www.opentk.com/files/Glu.cs

我的程序图像没有在Oxy平面中绘制2D多边形,请点击此处:http://bayimg.com/NAOaDAafo

帮助我让我的深度测试工作。

初​​始化:

    static Vector3 cameraPos = new Vector3(0, 0, (int)(3 * Const.MaxZoom * Const.EarthRadius));
    static Vector3 refPoint = new Vector3(0, 0, 0);
    static Vector3 upVector = new Vector3(0, 1, 0);        
    public static void initWorld()
    {
        float dx = (float)(Vertex.minX + Vertex.maxX) / 2;
        float dy = (float)(Vertex.minY + Vertex.maxY) / 2;
        double greaterEdge = Math.Max((double)(Vertex.maxX - Vertex.minX), (double)(Vertex.maxY - Vertex.minY)) / 2;
        foreach (Vertex v in node)
        {
            v.p.X -= dx;
            v.p.X *= (float)(Const.WindowSize / greaterEdge);
            v.p.Y -= dy;
            v.p.Y *= (float)(Const.WindowSize / greaterEdge);
        }
        Vertex.minX -= dx; Vertex.minX *= (float)(Const.WindowSize / greaterEdge);
        Vertex.maxX -= dx; Vertex.maxX *= (float)(Const.WindowSize / greaterEdge);
        Vertex.minY -= dy; Vertex.minY *= (float)(Const.WindowSize / greaterEdge);
        Vertex.maxY -= dy; Vertex.maxY *= (float)(Const.WindowSize / greaterEdge);
        left = -Const.WindowSize;
        right = Const.WindowSize;
        bot = -Const.WindowSize;
        top = Const.WindowSize;
        near = 0.000001;
        far = 1000000000;
        foreach (Way w in way)
            w.makePointList();
    }

渲染:

    window.RenderFrame += (sender, e) =>
        {
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(left, right, bot, top, near, far);
            GL.Enable(EnableCap.DepthTest);
            GL.DepthMask(true);
            GL.DepthFunc(DepthFunction.Lequal);
            GL.ClearColor(Color.LightGray);
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
            GLU.LookAt(cameraPos, refPoint, upVector);                
            GL.Rotate(xrot, 1, 0, 0);
            GL.Rotate(zrot, 0, 0, 1);
            GL.Scale(zoom, zoom, zoom);
            GL.Translate(mapTranslate);
            for (int i = 1; i >= 0; --i)
                foreach (Way w in way)
                    if (w.drawID == i) w.draw(zoom);
            for (int i = 2; i >= 2; --i)
                foreach (Way w in way)
                    if (w.drawID == i) w.draw(zoom);
            window.SwapBuffers();
        };

2 个答案:

答案 0 :(得分:2)

您的深度值范围太大:

near = 0.000001;
far = 1000000000;

near为10 ^ -6,far 10 ^ 9,相对范围为10 ^ 15。如果范围很大,则无法以合理的精度表示深度值。深度缓冲区通常具有16位或24位精度。

您通常希望在1:10或1:100之间具有近似远比,以获得良好的深度精度。尝试以下值,您的结果应该更好:

near = 0.1;
far = 10.0;

当然,您需要确保几何体的坐标在此范围内,因此您可能需要根据具体用途调整确切的值。

如果您遇到过真正需要极大深度范围的情况,那么有更先进的方法可以解决这个问题。它们部分涉及使用多个渲染通道,或将深度值映射到深度缓冲区范围的不同方式(例如,对数深度缓冲区)。我非常怀疑原始海报的学校作业需要这个,但我提到它只是为了更完整(基于@vesan的建议)。

答案 1 :(得分:0)

我发现了我做错了什么。事实证明,z cordinates对我认为的是负面的。将DepthFunc更改为Greater并使用GL.ClearDepth(-1.0F)解决了问题。我仍然不知道为什么我的坐标是相反的原因。