2

我正在开发我的第一个 openGL 游戏,灵感来自 playstation 网络上的游戏“Greed Corp”。这是一款基于六角网格的回合制策略游戏。每个六边形瓷砖都有自己的高度和纹理。

我目前正在根据我读过的一些示例和教程绘制一个六边形。这是我的hextile类:

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

每一帧我都在循环所有可见的瓷砖来绘制它们,这将是 11 * 9 瓷砖 MAX。然而,这会将我的帧速率降低到 38,这甚至没有在它们上绘制纹理,只是平坦的六边形。

现在我想弄清楚如何提高性能。我认为一次绘制整个网格可能会更快,但我不知道该怎么做,因为每个图块可以有不同的高度,并且很可能与相邻的图块具有不同的纹理。

我真的很感激这方面的一些帮助,因为我想开始真正的游戏^.^

4

2 回答 2

1

假设您的六边形网格是静态的,您只需旋转一次所有六边形,生成它们的几何图形,然后将所有内容附加到一个(或更多,如果您有超过 2^16 个顶点)大 VBO,您可以一次绘制。

就纹理而言,您可以使用纹理图集

于 2011-06-06T19:09:57.797 回答
0

我目前也在学习 OpenGL,我制作了一个名为“Cloud Stream”的 Android OpenGL 应用程序,在那里我发现了类似的性能问题。

作为对性能问题的一般回答,有一些事情可以提供帮助。当一次传递大量顶点时,硬件级别的图形顶点管道显然更有效。为每个 Hex 瓦片调用 glVertexPointer 不如使用所有瓦片的顶点调用一次高效。

这使得代码更难编码,因为您基本上一次绘制所有图块,但它似乎确实加快了速度。在我的应用程序中,所有的云都是在一次调用中绘制的。

其他尝试的方法是将顶点位置保存在 VBO 中,我发现这非常棘手,至少在尝试迎合 2.1 用户时是这样。这些天事情可能会更容易,我不确定。有了这个想法,您可以将 tile 的 Vertice 数组保存到 Video Memory 中,然后您可以像处理纹理一样获取指针。正如您可以想象的那样,不将您的顶点数组缓冲区发送到每一帧都会加快每次平铺绘制的速度。即使事情不是静态的,它也是一个好方法,因为我怀疑每一帧的事情都在变化。

我在网上看到的另一个建议是使用 Short 而不是 Float 作为顶点。然后更改完成渲染的比例以获得所需的大小。这会降低你的顶点的大小并加快速度......不是很大,但我会说仍然值得尝试。

我想补充的最后一件事是,如果您最终使用任何透明度...请注意,您必须从前向后绘制才能使其正常工作,这也会对性能产生影响。如果你从前到后绘制,当坐标不可见时,渲染引擎会自动知道不绘制......从前到后绘制意味着所有内容都已绘制。请记住这一点,并尽可能尝试从前到后画。

祝你的比赛好运,我很想知道你的进展如何……我刚刚开始我的比赛,我很高兴能开始。如果您还没有遇到过这个......我认为它值得一读。 http://www.codeproject.com/KB/graphics/hexagonal_part1.aspx

于 2011-12-29T21:18:03.423 回答