使用 JOGL 使用 VBO 渲染随机引发异常
Posted
技术标签:
【中文标题】使用 JOGL 使用 VBO 渲染随机引发异常【英文标题】:Rendering with VBO using JOGL trows exception at random 【发布时间】:2014-09-12 09:28:33 【问题描述】:我一直在尝试使用 JOGL 编写我的渲染应用程序。但我遇到了 VBO 的问题。在linux下它每次都运行良好,但在windows下它总是崩溃。我不知道我错过了什么。我编写了为 VBO 提供服务的代码,结合了各种教程,因为 Java 很少,而不是谈论 JOGL。
我已阅读:
http://www.java-gaming.org/index.php?topic=25672.0 我修改了我的代码,所以我从我的类的 init 函数传递 GL2 实例,它从 GLEventListener 作为函数参数一直派生到我的 VBOClass 函数。 (我不将 GL2 实例存储为类属性) 但这并没有帮助
所以我的班级:
public class VBOMesh
private int vertexVBOId;
private int normalVBOId;
private int texCoordVBOId;
public VBOMesh(GL2 gl)
IntBuffer ib = IntBuffer.allocate(4);
gl.glGenBuffers(4, ib);
vertexVBOId = ib.get(0);
normalVBOId = ib.get(1);
texCoordVBOId = ib.get(2);
public void setVetices(GL2 gl, List<Vector3> vetices)
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, vertexVBOId);
gl.glBufferData( GL.GL_ARRAY_BUFFER, vetices.size()*3*Float.SIZE, VectorListToFloatBuffer(vetices,3), GL.GL_STATIC_DRAW);
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, 0);
public void setTexCoords(GL2 gl, List<Vector3> texCoords)
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, texCoordVBOId);
gl.glBufferData( GL.GL_ARRAY_BUFFER, texCoords.size()*2*Float.SIZE, VectorListToFloatBuffer(texCoords,2), GL.GL_STATIC_DRAW);
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, 0);
public void setNormals( GL2 gl, List<Vector3> normals)
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, normalVBOId);
gl.glBufferData( GL.GL_ARRAY_BUFFER, normals.size()*3*Float.SIZE, VectorListToFloatBuffer(normals,3), GL.GL_STATIC_DRAW);
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, 0);
public void Draw( GL2 gl, List<Integer> indices)
IntBuffer indiceBuffer = Buffers.newDirectIntBuffer( indices.size() );
for (int ind : indices)
indiceBuffer.put(ind);
gl.glEnableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.glEnableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
gl.glEnableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, normalVBOId);
gl.glNormalPointer( GL.GL_FLOAT, 0, 0);
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, texCoordVBOId);
gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, 0);
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, vertexVBOId);
gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
gl.glDrawElements(GL.GL_TRIANGLES, indiceBuffer.capacity(), GL.GL_UNSIGNED_INT, indiceBuffer.rewind());
//gl.glDrawArrays(GL.GL_LINES, 0, 24);
gl.glBindBuffer( GL.GL_ARRAY_BUFFER, 0);
gl.glDisableClientState(GLPointerFunc.GL_VERTEX_ARRAY);
gl.glDisableClientState(GLPointerFunc.GL_NORMAL_ARRAY);
gl.glDisableClientState(GLPointerFunc.GL_TEXTURE_COORD_ARRAY);
private Buffer VectorListToFloatBuffer(List<Vector3> vectors, int floatsToTake)
if(floatsToTake > 4)
throw new InvalidParameterException("floats to take greater than 4");
FloatBuffer buffer = Buffers.newDirectFloatBuffer(vectors.size()*3);
for (Vector3 vector : vectors)
float [] arr = 0.f,0.f,0.f;
if(vector != null)
arr = vector.getVector3AsGLArray();
for (int i = 0; i < floatsToTake; i++)
buffer.put(arr[i]);
return buffer.rewind();
异常发生在glBufferData。
我没有想法,所以我问。
【问题讨论】:
这是来自生成的输出文件:# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x697c851e, pid=6476, tid=7160
来自堆栈跟踪:j jogamp.opengl.gl4.GL4bcImpl.glBufferData(IJLjava/nio/Buffer;I)V+67 j SceneTools.VBOMesh.setNormals (Ljavax/media/opengl/GL2;Ljava/util/List;)V+35
end 如果你debug step through,参数check out?
normalVBOId 大约是 3,看起来是正确的,然后我正在测试的模型的缓冲区容量是 942,它是包含向量的列表大小的 3 倍,所以看起来还可以。但是由于 Float.SIZE,我作为大小传递给 glBufferData 的是一个很大的数字,我不确定它是否应该存在。
指责 JOGL 而不是假设问题可能来自您的代码不是很聪明。如果您使用通过 com.jogamp.common.nio.Buffers 创建的直接 NIO 浮点缓冲区,那么它从一开始就可以在任何地方工作。如果您阅读了该方法的文档,您会发现自己的错误。
【参考方案1】:
Float.SIZE 返回单个浮点数 (32) 中的 bits 数,而您想要浮点数中的 bytes 数。
将Float.SIZE
的每个实例替换为(Float.SIZE/Byte.SIZE)
或只是4
,或自定义常量BYTES_IN_FLOAT
。
【讨论】:
非常感谢!有效。我相信,我读过的那些 Java VBO 教程完全错过了这一点。以上是关于使用 JOGL 使用 VBO 渲染随机引发异常的主要内容,如果未能解决你的问题,请参考以下文章