glBufferData 后的 Opengl 异常
Opengl Exception after glBufferData
我正在从我的 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];
}
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, ...)
我正在从我的 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];
}
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, ...)