简体   繁体   English

OpenTK深度测试不起作用

[英]OpenTK Depth test not working

I'm having an assignment in my Computer Graphics class to write a 2.5D map using openTK. 我在我的计算机图形学课程中有个作业要使用openTK编写2.5D地图。 When I tried to to enable gl_Depth_Test for my drawing, it's doesn't work as expected. 当我尝试为绘图启用gl_Depth_Test时,它无法按预期方式工作。 The 3D shapes overlap each other and the result is the same when I change DepthFunc between Lequal and Always. 当我在Lequal和Always之间更改DepthFunc时,3D形状彼此重叠,结果是相同的。 I tried to get the depth buffer out. 我试图使深度缓冲出来。 It change when I change the x rotation xrot but is always the same for DepthFunc Always and Lequal. 当我更改x旋转xrot时,它会更改,但对于DepthFunc Always和Lequal总是相同的。 When I change DepthFunc to everything else except Less and Equal, nothing is displayed. 当我将DepthFunc更改为Less和Equal以外的其他所有内容时,什么也不显示。 The code for my init and render is below. 我的初始化和渲染的代码如下。 In this code cameraPos Z is mean to be very big. 在此代码中,cameraPos Z意味着非常大。 Vertex are 2D points on the Oxy plane. 顶点是Oxy平面上的2D点。 Way are 2D polygons in the Oxy plane or 3D shapes. 方式是Oxy平面中的2D多边形或3D形状。 In case of shapes, they're just 2D polygons in Oxy planes with fake 3D effect by streching them by the z axis. 对于形状,通过在z轴上拉伸它们,它们只是在Oxy平面中具有伪3D效果的2D多边形。 The initWorld code basically mean to move the Vertex cordinates to around the origins of the Oxy plane for easier rotate. initWorld代码基本上是指将顶点坐标移动到Oxy平面的原点附近,以便于旋转。 The GLU.LookAt I took from the LookAt/gluLookat function here http://www.opentk.com/files/Glu.cs 我从这里的LookAt / gluLookat函数获取的 GLU.LookAt是http://www.opentk.com/files/Glu.cs

An image of my program without drawing 2D polygons in the Oxy plane is here: http://bayimg.com/NAOaDAafo 我的程序的图像未在Oxy平面上绘制2D多边形,请点击此处: http : //bayimg.com/NAOaDAafo

Help me to get my Depth test to work. 帮助我进行深度测试。

Init: 在里面:

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

Render: 渲染:

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

Your range of depth values is way too large: 您的深度值范围太大:

near = 0.000001;
far = 1000000000;

With near being 10^-6, and far 10^9, that's a relative range of 10^15. near为10 ^ -6, far 10 ^ 9,则相对范围为10 ^ 15。 You can't represent depth values with reasonable precision if the range is this large. 如果范围太大,则不能以合理的精度表示深度值。 Depth buffers typically have 16 or 24 bit precision. 深度缓冲器通常具有16或24位精度。

You typically want to have the near to far ratio at something like 1:10, or maybe 1:100, to get good depth precision. 为了获得良好的深度精度,您通常希望将近远比设置为1:10或1:100。 Try values like the following, and your results should be a whole lot better: 尝试使用以下值,您的结果应该会好得多:

near = 0.1;
far = 10.0;

Of course you will need to make sure that the coordinates of your geometry are within this range, so you may have to adjust the exact values to your specific use. 当然,您需要确保几何坐标在此范围内,因此您可能必须针对特定用途调整确切的值。

If you ever encounter a situation where you really need an extremely large depth range, there are more advanced methods of dealing with that. 如果遇到确实需要非常大的深度范围的情况,则有更高级的处理方法。 They partly involve using multiple rendering passes, or different ways of mapping depth values to the depth buffer range (eg logarithmic depth buffers). 它们部分涉及使用多个渲染通道,或将深度值映射到深度缓冲区范围(例如对数深度缓冲区)的不同方式。 I very much doubt that this will be needed for the school assignment of the original poster, but I'm mentioning it just to be more complete (based on suggestion by @vesan). 我非常怀疑原始海报的学校作业是否需要这样做,但是我要说的是为了使其更加完整(基于@vesan的建议)。

I've found out what I was doing wrong. 我发现自己在做什么错。 It turned out that z cordinates were negative of what I thought they were. 原来,z坐标对我以为是负数。 Changed the DepthFunc to Greater and use GL.ClearDepth(-1.0F) solved the problem. 将DepthFunc更改为Greater并使用GL.ClearDepth(-1.0F)解决了该问题。 Still I don't know why the reason why my z cordinates were the opposite though. 但是我仍然不知道为什么我的z坐标相反。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM