【问题标题】:Opengl Exception after glBufferDataglBufferData 后的 Opengl 异常
【发布时间】:2020-01-28 15:12:18
【问题描述】:

我从我的 jogl 程序中得到一个 Exception_access_violation。代码示例包含根据日志引发错误的点(并使用 Sys out 进行测试)。我恰好在glBufferData 调用顶点时发生。

所以目前我正在通过组合顶点并调整索引将较小的网格合并为一个较大的网格。该程序可以使用分布在多个网格(vaos)上的相同数量的顶点运行,但是在我将它们组合起来之后,我得到了这个错误。当我渲染具有较少顶点的组合网格时,它也可以工作。

当它崩溃时,我正在加载一个包含 24834 个顶点和 12618 个索引的网格。这对缓冲区来说太大了吗?

public static int loadToGPU(Mesh mesh){


    GL4 gl = GLContext.getCurrentGL().getGL4();

    int[] vaoids = new int[1];
    gl.glGenVertexArrays(1,vaoids,0);


    int[] vboids = new int[3];
    gl.glGenBuffers(3,vboids,0);

    gl.glBindVertexArray(vaoids[0]);

    FloatBuffer verticesBuffer = FloatBuffer.allocate(mesh.vertices.length);
    verticesBuffer.put(mesh.vertices);
    verticesBuffer.flip();

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[0]);
    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.vertices.length * gl.GL_FLOAT ,verticesBuffer,gl.GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(0);
    gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, false, 0, 0);

    verticesBuffer.clear();
    verticesBuffer = null;

    IntBuffer indicesBuffer = IntBuffer.allocate(mesh.indices.length);
    indicesBuffer.put(mesh.indices);
    indicesBuffer.flip();

    gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, vboids[1]);
    gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * gl.GL_UNSIGNED_INT ,indicesBuffer,gl.GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(1);
    gl.glVertexAttribPointer(1, 3, gl.GL_UNSIGNED_INT, false, 0, 0);

    indicesBuffer.clear();
    indicesBuffer = null;

    FloatBuffer normalBuffer = FloatBuffer.allocate(mesh.normals.length);
    normalBuffer.put(mesh.normals);
    normalBuffer.flip();

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vboids[2]);
    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.normals.length * gl.GL_FLOAT ,normalBuffer,gl.GL_STATIC_DRAW);
    gl.glEnableVertexAttribArray(2);
    gl.glVertexAttribPointer(2, 3, gl.GL_FLOAT, false, 0, 0);

    normalBuffer.clear();
    normalBuffer = null;

    gl.glBindBuffer(gl.GL_ARRAY_BUFFER,0);
    gl.glBindVertexArray(0);


    return vaoids[0];

}

【问题讨论】:

    标签: opengl jogl vbo vao


    【解决方案1】:

    mesh.vertices.length * gl.GL_FLOAT 不做,你期望它做的事情。
    gl.GL_FLOAT 是一个枚举常数,它的值不是 4(分别是 0x1406 5126)。你实际做的是计算mesh.vertices.length * 5126
    您必须以字节为单位计算缓冲区的大小,因此您必须将元素的数量乘以数据类型的大小float

    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.vertices.length * gl.GL_FLOAT, ...); gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.vertices.length * 4, ...);

    同样的问题是当你创建和初始化元素缓冲区的数据存储时:

    gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * gl.GL_UNSIGNED_INT, ...);
    gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, mesh.indices.length * 4, ...);

    以及法线向量的顶点缓冲区:

    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.normals.length * gl.GL_FLOAT, ...)
    gl.glBufferData(gl.GL_ARRAY_BUFFER, mesh.normals.length * 4, ...)

    【讨论】:

    • 啊,谢谢。因此,在它刚刚工作之前具有较小的顶点计数,因为缓冲区不是“那么”大,但仍然比需要的大。我没有意识到这一点。我不记得在哪里,但我想我看到了 GL_FLOAT 用于此。会不会是原生 opengl 中的不同?
    • @AlexanderW 不,在这种情况下GL_FLOAT 在这种情况下总是错误的。在 c++ 中,您可能已经看到类似 sizeof(GLfloat) 的内容
    猜你喜欢
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 2014-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多