4
votes

I'm playing around with OpenGL ES 2.0 in Android, and looking through the docs for GLES20 I came across the following methods:

public static void glDrawElements(
    int mode, int count, int type, Buffer indices)
public static void glDrawElements(
    int mode, int count, int type, int offset)

public static void glVertexAttribPointer(
    int indx, int size, int type, boolean normalized, int stride, Buffer ptr)
public static void glVertexAttribPointer(
    int indx, int size, int type, boolean normalized, int stride, int offset)

The two methods that take Buffer objects make sense to me, but the other two don't. Where do they get the indices/attibute-values (respectively), and what is offset an offset into? (I assume these two questions have the same answer.)

2
The two weird methods are both tagged "Level 9", (and I'm currently coding for level 8), so this is more to satisfy my curiosity than anything else...Laurence Gonsalves

2 Answers

6
votes

Offset in the prototype means that you are submitting the INDEX array in prior to this call.That should be used if you are using VBO's(Vertex Buffer Objects).Use glBindBuffer to bind the index buffer and specify an offset if needed in the next call.

First you need to bind the buffer(Index buffer here) and you can specify from where your elements start with an 'offset'.

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_resources.element_buffer);
glDrawElements(
    GL_TRIANGLE_STRIP,  /* mode */
    4,                  /* count */
    GL_UNSIGNED_SHORT,  /* type */
    (void*)0            /* element array buffer offset */
);

for

 public static void glVertexAttribPointer(
int indx, int size, int type, boolean normalized, int stride, int offset)

This means that you are submitting vertex buffer in prior to this call and you can specify the offset from where it should take with in the buffer. Please check the following link for additional help. http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-2.3:-Rendering.html

As you expected, The both have the same reason :) .Hope this helps!

Update: you need to create a buffer to bind it.This can be done by the following steps.

     glGenBuffers(); // create a buffer object
     glBindBuffer(); // use the buffer
     glBufferData(); // allocate memory in the buffer

Check this link for creating a VBO. http://www.opengl.org/wiki/Vertex_Buffer_Object

Regarding the Offset type: The offset is passed as a pointer, but the parameter is used for its integer value, so we pass an integer cast to void*.

0
votes

Method

public static void glDrawElements(
    int mode, int count, int type, int offset)

is used with rendering with VBO indices.

offset - is an offset to indexVBO in bytes;

Before using it you should upload indices to VBO object:

import static android.opengl.GLES20.*;

private static final int SIZEOF_SHORT = 2;

void fillIndices() {
    int indexAmount = ...;
    int sizeBytes = indexAmount * SIZEOF_SHORT;
    ShortBuffer indicesS = ByteBuffer.allocateDirect(sizeBytes).order(ByteOrder.nativeOrder()).asShortBuffer();
    indicesS.put(getShortIndices(indexAmount));

    indicesS.position(0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeBytes, indicesS, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

short[] getShortIndices(int indexAmount) {
    short[] indices = new short[indexAmount];
    // fill indices here
    return indices;
}

Then you can bind it and use it with glDrawElements()

public void draw(){
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexVBO);
    glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_SHORT, firstIndex * SIZEOF_SHORT);}
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

You can use GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT and GL_UNSIGNED_INT as indices.