在 jogl 中使用顶点缓冲区,当三角形太多时崩溃

Posted

技术标签:

【中文标题】在 jogl 中使用顶点缓冲区,当三角形太多时崩溃【英文标题】:Using vertex buffers in jogl, crash when too many triangles 【发布时间】:2011-01-22 16:59:26 【问题描述】:

我使用 Jogl 用 Ja​​va 编写了一个简单的应用程序,它可以绘制 3d 几何图形。可以通过拖动鼠标来旋转相机。应用程序运行良好,但使用 glBegin(GL_TRIANGLE) 绘制几何图形...调用太慢了。

所以我开始使用顶点缓冲区。这也可以正常工作,直到三角形的数量大于 1000000。如果发生这种情况,显示驱动程序会突然崩溃,我的显示器会变暗。缓冲区中的三角形数量是否有限制?我希望以合理的帧速率渲染 1000000 个三角形。

我不知道如何调试这个问题。令人讨厌的是,每次启动后我都必须重新启动 Windows,因为我没有其他方法可以让我的显示器再次工作。谁能给我一些建议?

顶点、三角形和法线存储在数组float[][] m_vertices、int[][] m_triangles、float[][] m_triangleNormals中。 我初始化了缓冲区:

        // generate a VBO pointer / handle
        if (m_vboHandle <= 0) 
            int[] vboHandle = new int[1];
            m_gl.glGenBuffers(1, vboHandle, 0);
            m_vboHandle = vboHandle[0];
        

        // interleave vertex / normal data
        FloatBuffer data = Buffers.newDirectFloatBuffer(m_triangles.length * 3*3*2);
        for (int t=0; t<m_triangles.length; t++)
            for (int j=0; j<3; j++) 
                int v = m_triangles[t][j];
                data.put(m_vertices[v]);
                data.put(m_triangleNormals[t]);
            
        data.rewind();

        // transfer data to VBO
        int numBytes = data.capacity() * 4;
        m_gl.glBindBuffer(GL.GL_ARRAY_BUFFER, m_vboHandle);
        m_gl.glBufferData(GL.GL_ARRAY_BUFFER, numBytes, data, GL.GL_STATIC_DRAW);
        m_gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

然后,场景被渲染:

        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, m_vboHandle);
        gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL2.GL_NORMAL_ARRAY);
        gl.glVertexPointer(3, GL.GL_FLOAT, 6*4, 0);
        gl.glNormalPointer(GL.GL_FLOAT, 6*4, 3*4);
        gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3*m_triangles.length);
        gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL2.GL_NORMAL_ARRAY);
        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);

【问题讨论】:

你只画这个顶点/法线数组吗?还是你的场景中发生了其他事情...... 【参考方案1】:

尝试检查调用glBufferData 的返回值。如果不能满足numBytes,它将返回GL_OUT_OF_MEMORY

【讨论】:

对不起,我应该澄清这个答案。 glBufferData 不会“返回”GL_OUT_OF_MEMORY。相反,它“产生”了错误。调用 glBufferData() 后调用 glGetError() 可以得到错误 我已经检查了错误代码。 glBufferData() 调用后为 0(无错误)。我做了一个额外的观察:显示驱动程序不会立即崩溃(第一帧渲染得很好),但是如果我尝试放大场景。当渲染的三角形过多且尺寸过大时,可能存在内部溢出? 嗯,您的驱动程序是最新的吗?它崩溃的事实表明驱动程序有问题,甚至可能是硬件问题。你在另一台电脑上试过了吗? 将三角形放入单独的数组缓冲区中,并使用多个 glDrawArray 调用绘制它们也可能会有所帮助——看看是否有帮助

以上是关于在 jogl 中使用顶点缓冲区,当三角形太多时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

JOGL/OpenGL VBO - 如何渲染顶点?

在 Java 中为 JOGL 释放直接缓冲区本机内存

OpenGL 应用程序崩溃

使用 JOGL 的 glDrawElementsInstanced() 的索引参数中的内容

顶点缓冲区对象未在 SDL 窗口中绘制

索引以及索引缓冲区