奇怪的 OpenGL 立方体

Posted

技术标签:

【中文标题】奇怪的 OpenGL 立方体【英文标题】:Weird OpenGL cube 【发布时间】:2014-06-05 17:41:47 【问题描述】:

我只是尝试使用 VBO。所以我渲染了一个立方体,这就是正在发生的事情。

如果我不旋转它,一切正常:

但是当我旋转它时,这个东西会出现:

看起来立方体是半透明的,而且……我真的不知道,它在搅乱我的大脑。

这是我的代码:

internal class CubeRenderer

    private VertexBuffer vertexBuffer;
    private IndexBuffer indexBuffer;

    public CubeRenderer()
    
        vertexBuffer = new VertexBuffer(new[]
        
            // front
            new Vertex(-1.0f, -1.0f, 1.0f, Color.Red),
            new Vertex(1.0f, -1.0f, 1.0f, Color.Beige),
            new Vertex(1.0f, 1.0f, 1.0f, Color.SaddleBrown),
            new Vertex(-1.0f, 1.0f, 1.0f, Color.AliceBlue), 
            //back
            new Vertex(-1.0f, -1.0f, -1.0f, Color.DarkBlue),
            new Vertex(1.0f, -1.0f, -1.0f, Color.Firebrick),
            new Vertex(1.0f, 1.0f, -1.0f, Color.IndianRed),
            new Vertex(-1.0f, 1.0f, -1.0f, Color.Yellow)
        );

        indexBuffer = new IndexBuffer(new uint[]
        
            // front
            0, 1, 2,
            2, 3, 0,
            // top
            3, 2, 6,
            6, 7, 3,
            // back
            7, 6, 5,
            5, 4, 7,
            // bottom
            4, 5, 1,
            1, 0, 4,
            // left
            4, 0, 3,
            3, 7, 4,
            // right
            1, 5, 6,
            6, 2, 1
        );
    

    public void Draw()
    
        // 1) Ensure that the VertexArray client state is enabled.
        GL.EnableClientState(ArrayCap.VertexArray);
        GL.EnableClientState(ArrayCap.NormalArray);
        GL.EnableClientState(ArrayCap.TextureCoordArray);
        GL.EnableClientState(ArrayCap.ColorArray);

        // 2) Bind the vertex and element (=indices) buffer handles.
        GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer.Id);
        GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer.Id);

        GL.VertexPointer(3, VertexPointerType.Float, vertexBuffer.Stride, IntPtr.Zero);
        GL.NormalPointer(NormalPointerType.Float, vertexBuffer.Stride, new IntPtr(Vector3.SizeInBytes));
        GL.TexCoordPointer(2, TexCoordPointerType.Float, vertexBuffer.Stride, new IntPtr(Vector3.SizeInBytes*2));
        GL.ColorPointer(4, ColorPointerType.UnsignedByte, vertexBuffer.Stride, new IntPtr(Vector3.SizeInBytes*2 + Vector2.SizeInBytes));

        // 4) Call DrawElements. (Note: the last parameter is an offset into the element buffer and will usually be IntPtr.Zero).
        GL.DrawElements(PrimitiveType.Triangles, indexBuffer.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);

        //Disable client state
        GL.DisableClientState(ArrayCap.VertexArray);
        GL.DisableClientState(ArrayCap.NormalArray);
        GL.DisableClientState(ArrayCap.TextureCoordArray);
        GL.DisableClientState(ArrayCap.ColorArray);
    

编辑 1:

看起来是深度缓冲区的问题。我尝试启用 DepthTest,但它仍然做同样的事情。

编辑 2:

这可能来自我旋转矩阵的方式...?

        GL.Ortho(-Zoom * ratio, Zoom * ratio, -Zoom, Zoom, 0, 100);

【问题讨论】:

第一个看起来像一个奇怪的剪辑,第二个看起来你没有剔除面部并且没有深度缓冲区,所以背景平面可能会绘制在前面的平面之上。 我看起来适合深度缓冲区。它看起来很像this page上的第一个示例 我更新了帖子,当我更改 glOrtho 的 zNear 和 zFar 时,故障看起来不同...... 如果可能,也使用剔除,而不仅仅是深度缓冲区。例如,立方体剔除将消除绘制一半表面的需要,总是(不考虑奇怪的 FOV 值或其他边缘情况)。使用深度缓冲区,它们只是不显示,但它们要么被绘制(非常慢),要么至少被认为是被绘制的(也很慢)。 【参考方案1】:

好吧,我自己找到了答案。问题来自于我使用 glOrtho 进行缩放,并且不知何故使用了错误的值。我切换到 glScale,现在一切都很好!

【讨论】:

以上是关于奇怪的 OpenGL 立方体的主要内容,如果未能解决你的问题,请参考以下文章

立方体贴图上的 OpenGL 奇怪的红绿蓝线并重复三次

OpenGL Cube 奇怪的错误

OpenGL 显示一个正方形而不是一个立方体

OpenGL:物体旋转异常

无法在opengl中绘制多个对象

立方体旋转 - OpenGL