开发者

Increasing drawing performance with a hexagon grid

I'm working on my very first openGL game, inspired by the game "Greed Corp" on the playstation network. It's a turn based strategy game that is based on a hex grid. Each hexagon tile has it's own height and texture.

I'm currently drawing a hexagon based on some examples and tutorials I've read. Here's my hextile class:

public class HexTile
{
    private float height;

    private int[] textures = new int[1];

    private float vertices[] = {     0.0f,   0.0f, 0.0f,    //center
                                     0.0f,   1.0f, 0.0f,    // top
                                    -1.0f,   0.5f, 0.0f,    // left top
                                    -1.0f,  -0.5f, 0.0f,    // left bottom
                                     0.0f,  -1.0f, 0.0f,    // bottom
                                     1.0f,  -0.5f, 0.0f,    // right bottom
                                     1.0f,  0.5f, 0.0f,     // right top
    };

    private short[] indices = {      0, 1, 2, 3, 4, 5, 6, 1};

    //private float texture[] = { };

    private FloatBuffer vertexBuffer;
    private ShortBuffer indexBuffer;
    //private FloatBuffer textureBuffer;    

    public HexTile()
    {
        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
        vbb.order(ByteOrder.nativeOrder());
        vertexBuffer = vbb.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
        ibb.order(ByteOrder.nativeOrder());
        indexBuffer = ibb.asShortBuffer();
        indexBuffer.put(indices);
        indexBuffer.position(0);

        /*ByteBuffer tbb = ByteBuffer.allocateDirect(texture.length * 4);
        tbb.order(ByteOrder.nativeOrder());
        textureBuffer = tbb.asFloatBuffer();
        textureBuffer.put(texture);
        textureBuffer.position(0);*/
    }

    public void setHeight(float h)
    {
        height = h;
    }
    public float getHeight()
    {
        return height;
    }

    public void draw(GL10 gl)
    {
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
        //gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

        gl.glDrawElements(GL10.GL_TRIANGLE_FAN, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);
    }

    public void loadGLTexture(GL10 gl, Context context)
    {
        textures[0] = -1;
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.hex);

        while(textures[0] <= 0)
            gl.glGenTextures(1, textures, 0); 

        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

        bitmap.recycle();
    }
}

Every frame I'm looping through all visible tiles to draw them, that would be 11 * 9 tiles MAX. This however drops my framerate to 38, and that is without even drawing textures on them, just the flat hexagons.

Now I'm trying to figure out how to increase performance. I figured drawing the whole grid at once could be faster, but I have no idea how to do that, since each tile can have a different height, and 开发者_StackOverflow中文版will most likely have a different texture than a neighboring tile.

I'd really appreciate some help on this, because I'd like to get started on the actual game ^.^


Assuming your hex grid is static you can just spin over all your hexagons once, generate their geometry, and append everything to one (or more, if you have more than 2^16 vertices) large VBO that you can draw in one go.

As far as textures go you may be able to use a texture atlas.


I'm currently learning OpenGL as well, I've produced one Android OpenGL application called 'Cloud Stream' where I found similar issues with performance.

As a general answer to performance concerns, there are a few things which can help. The Vertex pipeline for Graphics at a hardware level apparently is more efficient when passed larger amounts of vertices at once. Calling glVertexPointer for each Hex tile is not as efficient as calling it once with the vertices of all tiles.

This makes things harder to code as you essentially draw all your tiles at once, but it does seem to speed things up a bit. In my application, all of the clouds are drawn in the one call.

Other avenues to try would be to save the Vertice positions in a VBO which I found to be quite tricky, at least it was when trying to cater for 2.1 users. These days things might be easier, I'm not sure. With that the idea is to save the Vertice array for your tile into Video Memory and you get back a pointer like you do with your Textures. As you can imagine, not sending your Vertice Array Buffer up each frame speeds things up a little for each tile draw. Even if things aren't static its a good approach as I doubt things are changing for each frame.

Another suggestion I came across online was to use Short instead of Float for your Vertices. And then to change the scale of your finished rendering to get your desired size. This would lower the size of your vertices and speed things up a little... not a huge amount but still worth trying I would say.

One last thing I would like to add, if you end up using any Transparency... be aware that you must paint back to front for it to work which has a performance impact as well. If you draw front to back, the Rendering engine automatically knows not to draw when coordinates are not visible... drawing back to front means everything is drawn. Keep this in mind and always try to draw front to back when possible.

Good luck with your game, I'd love to know how you got on... I'm just starting my game and I'm quite excited to start. If you haven't already come across this... I think it's worth a read. http://www.codeproject.com/KB/graphics/hexagonal_part1.aspx

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜