user2577609
user2577609

Reputation: 23

Android OpenGL ES Not Drawing

I started learning OpenGL ES a couple months ago, but got into some problems when I tried to create a class for drawing multiple triangles.

private Level l;
private Triangle t;

public Game()
{

    Bitmap b = BitmapFactory.decodeResource(MainProgram.res, R.drawable.black);
    //TEMP ARGUMENT
    l = new Level(b);
}

public void update()
{
    //TEMP!
    l.update();
}

Level

private int size;
private Color[] colorList;
private TriangleList triangleList;

public Level(Bitmap b)
{
    size = b.getWidth()/16;
    colorList = new Color[size];
    for(int i = 0;i<size;i++)
    {
        int pixColor = b.getPixel(i*16, 1);
        float r = (pixColor&0x00FF0000)>>16;
        float g = (pixColor&0x0000FF00)>>8;
        float blue = (pixColor&0x000000FF);
        colorList[i] = new Color(r,g,blue);
    }
    triangleList = new TriangleList(size,colorList);
    colorList = null;
}

public void update()
{
    triangleList.draw();
}

TriangleList

private float[] color;
private FloatBuffer vertexBuffer;
private ShortBuffer[] indicesBuffer;

public TriangleList(int size,Color[] colorList)
{
    float[] vertices = null;
    short[] indices = null;

    if(size == 1)
    {
        vertices = TriangleSize.stageOne;
        indices = TriangleSize.stageOneIndices;
    }



    color = new float[colorList.length*4];

    for(int i = 0;i<colorList.length;i++)
    {
        color[3*i] = colorList[i].getR();
        color[3*i+1] = colorList[i].getG();
        color[3*i+2] = colorList[i].getB();
        color[3*i+3] = 1.0f;

    }


    ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
    bb.order(ByteOrder.nativeOrder());

    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(vertices);
    vertexBuffer.position(0);

    bb = null;

    bb = ByteBuffer.allocateDirect(indices.length * 4);
    bb.order(ByteOrder.nativeOrder());

    indicesBuffer = new ShortBuffer[indices.length/3];

    for(int i = 0;i<indices.length;i+=3)
    {
        bb = ByteBuffer.allocateDirect(6);
        ShortBuffer b = bb.asShortBuffer();
        b.put(new short[]{indices[i],indices[i+1],indices[i+2]});
        b.position(0);
        indicesBuffer[i/3] = b;
    }

}

public void draw()
{
    for(int i = 0;i<color.length/4;i++)
    {
        int positionHandle = Renderer.shader.getAttribute("vPosition");

        int colorHandle = Renderer.shader.getUniform("vColor");

        glEnableVertexAttribArray(positionHandle);
        glVertexAttribPointer(positionHandle, 3, GL_FLOAT, false, 0, vertexBuffer);

        glUniform4fv(colorHandle, 1, new float[]{1.0f,1.0f,1.0f,1.0f}, 0);

        glDrawElements(GL_TRIANGLES, 3,GL_UNSIGNED_SHORT,indicesBuffer[i]);

        glDisableVertexAttribArray(positionHandle);

    }


}

It doesn't give me an error, but nothing is drawn.

Upvotes: 0

Views: 340

Answers (1)

Savail
Savail

Reputation: 867

There are a few problems in your code. First of all, you don't need an array of ShortBuffers as your index list buffer.

private FloatBuffer vertexBuffer;
private ShortBuffer indicesBuffer;

You should pack tightly all of the data into vertexBuffer and indicesBuffer and do just 1 draw call. Here's an example of preparing data for drawing 2 triangles forming a rectangle:

// The vertex buffer.
            vertexBuffer = ByteBuffer.allocateDirect(4 * 3 * 4) //amount of vertices * amount of coordinates * sizeof(float)
                .order(ByteOrder.nativeOrder()).asFloatBuffer();

            // initialize byte buffer for the draw list
            indicesBuffer = ByteBuffer.allocateDirect(6 * 2) // amount of indices * sizeof(short)
                .order(ByteOrder.nativeOrder()).asShortBuffer();

        vertexBuffer.position(0);
        indicesBuffer.position(0);

        float [] vertices = new float[] 
                {200f, 400f, 100f, //vertex 0
                 200f, 200f, 100f, //vertex 1
                 400f, 200f, 100f, //vertex 2
                 400f, 400f, 100f}; //vertex 3
        //indices of vertices above that will be used to draw
        short indices[] = new short[] {0, 1, 2, 0, 2, 3};

        vertexBuffer.put(vertices);                 
        indicesBuffer.put(indices);

        vertexBuffer.position(0);
        indicesBuffer.position(0);

Also delete the loop in your render function and use just a single a draw call:

public void draw()
{
        int positionHandle = Renderer.shader.getAttribute("vPosition");

        int colorHandle = Renderer.shader.getUniform("vColor");

        glEnableVertexAttribArray(positionHandle);
        glVertexAttribPointer(positionHandle, 3, GL_FLOAT, false, 0, vertexBuffer);

        glUniform4fv(colorHandle, 1, new float[]{1.0f,1.0f,1.0f,1.0f}, 0);

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, indicesBuffer.capacity(),
                 GLES20.GL_UNSIGNED_SHORT, indicesBuffer);

        glDisableVertexAttribArray(positionHandle);


}

If there's still something unclear please let me know and I'll try to clarify.

Upvotes: 1

Related Questions