2
\$\begingroup\$

Edit

After initially thinking that my sprite batch test was faster than calling each sprite individually, it appears that is not the case!! :-(

With a single set of GL calls for a each sprite, I can get about 90 quads to move with no performance degradation.

With my batching test I can get about 12 (all in one call).

The problem is that I can't find any examples (code) anywhere for how this can be achieved using Android (Java) and OpenGL ES 2.0.

My method involved passing in an array of coordinate sets instead of a single set of coordinates, and then the method would build an array to store these coordinates in and then render the relevant amount of vertices. Like I say, it works but the performance is awful!! Is this the right approach?

Could anyone help? Thanks!

I'm using Android with openGLES 2.0 and I can't work out how to draw 2 (or more, but for the sake of simplicity, lets say 2 for the time being) textured quads using only 1 call to glDrawArrays.

My shaders are fairly standard and take into account sprite opacity as follows:

//vertex shader
    String strVShader =  
              "uniform mat4 uMVPMatrix;" +
              "attribute vec4 a_position;\n"+
              "attribute vec2 a_texCoords;" +
              "varying vec2 v_texCoords;" +
              "void main()\n" +
              "{\n" +
              "gl_Position = uMVPMatrix * a_position;\n"+  
              "v_texCoords = a_texCoords;" +
              "}";

//Fragment shader

    String strFShader =
        "precision mediump float;" +
        "uniform float opValue;"+
        "varying vec2 v_texCoords;" +
        "uniform sampler2D u_baseMap;" +
        "void main()" +
        "{" +
        "gl_FragColor = texture2D(u_baseMap, v_texCoords);" +
        "gl_FragColor *= opValue;"+
        "}";

Then my rendering method takes in vertices that set the position and size of the quad, set the texture, apply rotation (if any) etc...

And then draws with the following line:

GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);

I've been looking for a couple of days now for examples of how this can be achieved, but nothing seems to explain how it is actually done.

Can anyone give me any clues?

Note: To keep the question short, I have omitted my actual draw method. If this is required to give a fuller answer, please just ask and I will post.

Also please note that I need to do this as I'm trying to work out how to batch my sprites to increase performance.

\$\endgroup\$
2
  • \$\begingroup\$ Are you working in a 2D or 3D environment? \$\endgroup\$
    – Mokosha
    Commented Apr 13, 2013 at 13:45
  • \$\begingroup\$ Sorry @Mokosha, it's a 2d game I'm writing, so my quads are basically being used as sprites. \$\endgroup\$ Commented Apr 13, 2013 at 14:33

1 Answer 1

3
\$\begingroup\$

glDrawArrays claims that the passed in values for glDrawArrays specify a primitive type, a start index, and an index count. Assuming each index represents a vertex, you would need to specify more than 4 indices for it to draw more than one quad.

http://www.opengl.org/sdk/docs/man/xhtml/glDrawArrays.xml

\$\endgroup\$
7
  • \$\begingroup\$ Thanks @Evan. Could you please elaborate by way of example? I'm having trouble understanding. I've added another set of vertices to my array and changed the number in my glDrawArrays call to 8 from 4, however there are 2 problems here, 1 is that although it draws 2 quads, it also draws a 3rd quad between the two (this 3rd quad remains 'connected' to the other 2 , if I move those other 2, it 'stretches' between them), the 2nd issue is that doing this doesn't seem to increase performance, I still can only draw X amount of quads before I get noticeable slow down. Your help is appreciate. \$\endgroup\$ Commented Apr 13, 2013 at 15:17
  • 1
    \$\begingroup\$ The issue you are having is because you are using the primitive type TriangleStrip. When you specify this, the rasterizer will attempt to connect all of the vertices as if they are a collection of connected triangles. You can change it to a triangle list and ensure your vertex list matches, or try using a vertex buffer or alternative draw call. \$\endgroup\$
    – Evan
    Commented Apr 13, 2013 at 15:23
  • \$\begingroup\$ Note, using vertex buffers, and texture atlas' is a common approach to rendering multiple objects in the same draw call, this will simply require a vertex and index buffer to ensure you dont get the same behavior you are currently getting. \$\endgroup\$
    – Evan
    Commented Apr 13, 2013 at 15:27
  • \$\begingroup\$ Just so I understand, drawing 2 triangles using GL_Triangles, requires 6 vertices rather than 4 and thus is less efficient than using GL_TRIANGLE_STRIP?? Also regarding your other comment, are you referring to VBO's? I will look into these but the problem is that I want to target Froyo and VBO's don't work properly with Froyo, hence I'm avoiding them at the moment, so want to optimise my simple quads as much as I can. Thanks again. \$\endgroup\$ Commented Apr 13, 2013 at 15:35
  • 3
    \$\begingroup\$ VBO is the way things work these days, get used to them now =) Side note: you really want to draw this all out on paper to get your basics straight right now before writing any more code. Draw the quads, show the numbered verts, then read up on the various GL_TRIANGLE calls to see what data OpenGL wants from you then take all those and show how they would fit into an array that matches. Then go write some code, you'll be much happier =) \$\endgroup\$ Commented Apr 13, 2013 at 16:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .