安卓OpenGL点云

3

我一直在尝试使用

gl.glDrawElements(GL10.GL_POINTS, 4, GL10.GL_UNSIGNED_BYTE, vertexBuffer);

我想使用顶点缓冲区在屏幕上绘制4个点,但是我无法使其正常工作。我只想绘制点,因为最终我想要显示一个点云。如果我有大量的点(最终),顶点缓冲区是否是正确的选择?它们不会改变,但我希望能够更改查看它们时的透视和比例。

顶点缓冲区设置:

private float vertices[] = {
    -3.0f,  1.0f, -2.0f,  // 0, Top Left
    -3.0f, -1.0f, 0.0f,  // 1, Bottom Left
    -2.0f, -1.0f, -2.0f,  // 2, Bottom Right
    -2.0f,  1.0f, 0.0f,  // 3, Top Right
    };


// Our vertex buffer.
private FloatBuffer vertexBuffer;
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);

这是我的点的当前绘制调用(我不想使用索引,因为形状绘制顺序对我来说并不重要):

public void draw(GL10 gl) {
    // Enabled the vertices buffer for writing and to be used during 
    // rendering.
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    gl.glPointSize(3);

    // Specifies the location and data format of an array of vertex
    // coordinates to use when rendering.
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

    gl.glDrawElements(GL10.GL_POINTS, 4, 
             GL10.GL_UNSIGNED_BYTE, vertexBuffer);

    // Disable the vertices buffer.
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    // Disable face culling.
    gl.glDisable(GL10.GL_CULL_FACE);
}

当我调用draw()时,该程序目前会崩溃。

谢谢!

1个回答

5
你完全错误地使用了glDrawElements函数。这个函数需要一个索引数组,其中包含对顶点数组的索引,而不是顶点数据本身(这就是glVertexPointer的作用)。要么使用正确的索引数组,要么使用glDrawArrays函数。
private unsigned byte indices[] = { 0, 1, 2, 3 };
...
gl.glDrawElements(GL10.GL_POINTS, 4, GL10.GL_UNSIGNED_BYTE, indices);

但在您的情况下,您只需呈现所有点,不需要任何索引,因此您可以直接调用

gl.glDrawArrays(GL10.GL_POINTS, 0, 4);

可以使用glDrawArrays代替glDrawElements

编辑:它崩溃的具体原因是glDrawElements将提供的vertexBuffer解释为4字节数组,这些字节引用超出您的顶点数据范围(0至3)的顶点。


谢谢Christian,你说的确有道理。然而,它仍然崩溃。经过大量研究,我无法弄清楚原因。我在这里上传了一个小的Java文件,如果你能帮我扫描一下:http://www.qfpost.com/download.do?get=02700a1c0975664801e60c1cccfd6d02 - RedLeader
明白了。但两种方式都会导致空指针异常。我直接调用draw(gl)函数,但在调用的某个点上失败了。 - RedLeader
是的,我知道我一直在简化代码,逐步摆脱不必要的部分。看起来应该可以正常工作,但我也不确定了。 - RedLeader
@RedLeader 我认为你忘记构造 ptCloud 对象了。只需将 ptCloud = new PointCloud() 添加到您的活动构造函数中即可。因此,错误并不在 draw 函数中,而是在函数调用本身。 - Christian Rau
@Christian Rau -- 天哪。非常抱歉浪费了您的时间,同时也非常感谢您的帮助。现在可以了。谢谢! - RedLeader
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接