3

I've been trying to use

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

to draw 4 points on my screen with a vertex buffer, but I can't get it to work. All I want to draw is points, because eventually I want to make a point cloud display. If I have a large number of points (eventually), is vertex buffer the way to go? They won't be changing, but I will want to change the perspective and scale at which they are viewed.

vertexBuffer setup:

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);

This is my current draw call for my points (I don't want indices because shape drawing order doesn't matter to me):

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);
}

The program currently crashes when I call draw();

Thank you!

RedLeader
  • 657
  • 1
  • 15
  • 28

1 Answers1

5

You make completely wrong use of glDrawElements. This function wants an index array containing indices into the vertex arrays and not the vertex data itself (that's what glVertexPointer is for). Either use

private unsigned byte indices[] = { 0, 1, 2, 3 };
...
gl.glDrawElements(GL10.GL_POINTS, 4, GL10.GL_UNSIGNED_BYTE, indices);

But in your case you just render all points and don't need any indices, so you can just call

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

instead of glDrawElements.

EDIT: The specific reason it crashes is that glDrawElements interprets the supplied vertexBuffer as an array of 4 bytes and these bytes reference vertices out of the range of your vertex data (0 to 3).

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
  • Thanks Christian, what you said does make sense. However, it still crashes. After researching a lot, I can't figure out why. I threw up the small java file here, if you can scan it for me: http://www.qfpost.com/download.do?get=02700a1c0975664801e60c1cccfd6d02 – RedLeader Jun 16 '11 at 17:35
  • @RedLeader You don't have to draw `vertices.length` (12) vertices but only 4, as every vertex is made of 3 floats (as specified in your `glVertexPointer` call). So either use `vertices.length/3` or just `4` as third argument to `glDrawArrays`. – Christian Rau Jun 16 '11 at 17:40
  • Understood. Both ways result in Null Pointer exception though. I'm calling the draw(gl) function directly and it fails at some point in the call. – RedLeader Jun 16 '11 at 17:42
  • @RedLeader By the way, no need to set the front face convention when just drawing points (which don't have an orientation). – Christian Rau Jun 16 '11 at 17:45
  • @Christian Rau Yeah I know I've been trimming down the code as I go getting rid of what I shouldn't need. It seems like it should be working fine but IDK anymore. – RedLeader Jun 16 '11 at 17:47
  • @Christian Rau Calling .draw() on this file (which I based it off of) works fine, so it has to be something in the PointCloud.java file I linked earlier See working file: http://www.qfpost.com/download.do?get=49f5c7c63d36000ebdcca298c9ffee20 – RedLeader Jun 16 '11 at 17:49
  • @RedLeader Another reason could be, that at another point of your program you enable another vertex array (like e.g. GL_COLOR_ARRAY or something) and don't disable it again. So glDrawArrays tries to use an array, whose data might have already been destroyed. I could look at your other parts of the code, but only if it's not too much. – Christian Rau Jun 16 '11 at 17:52
  • @Christian Rau Thank you. This would be the last file, and the direct run out of my Activity. You can see I commented out the drawing of the Square and drew my point cloud instead(ln 66). LINK: http://www.qfpost.com/download.do?get=45e01a4ad7c412474c0fdb228da75e18 – RedLeader Jun 16 '11 at 17:56
  • @RedLeader I think you forgot to construct the `ptCloud` object. Just add `ptCloud = new PointCloud()` to the constructor of your activity. So the error is not in the `draw` function, but the function call itself. – Christian Rau Jun 16 '11 at 18:04
  • @Christian Rau -- Good lord. I'm so sorry for wasting your time and so thankful for your help. Yes, that works now. Thank you! – RedLeader Jun 16 '11 at 18:06