【问题标题】:Lwjgl how to simplify heightmap to get higher fps?Lwjgl 如何简化高度图以获得更高的 fps?
【发布时间】:2014-04-18 20:25:01
【问题描述】:

我对我的游戏的 fps 有点失望。我还处于游戏开发的初期。当我第一次开始游戏时,我得到了大约 350 fps。在我向程序添加高度图和更多代码之后,fps 下降是否合乎逻辑。现在我得到了 39 fps。 我还处于起步阶段,fps已经很低了。我想知道当我完成项目后会发生什么,我认为 fps 会太低以至于令人恼火。 我知道我对程序的要求很高,高度图是个大问题。 地图的面积为 200 * 200 个顶点,每个顶点都有一个高度。 200 * 200 = 40000 个顶点,每帧。 我正在考虑简化地图。我的想法是创建一种简化整个高度图的方法。每个 4 个顶点属于一个四边形。当相邻的两个或多个四边形在每个顶点上具有相同的高度时,它们可以合并为一个四边形。 关键是应该有更少的顶点。 (我认为)

我将展示我的高度图的一些示例代码。

package rgc.area;

import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;

public class HeightMap {

    public int width;  // Vertices (width)
    public int height; // Vertices (height)

    public List<Float> map = new ArrayList<Float>();

    /**
     * 
     * @param width The width of the map (x-axis)
     * @param height The height of the map (z-axiz, NOT y-axis);
     */
    public HeightMap(int width, int height) {

        this.width = width;
        this.height = height;

        for(int i = 0; i < width * height; i++) {

            map.add(1.0f);
        }
    }

    public Dimension getSize() {

        return new Dimension(this.width, this.height);
    }

    public int getWidth() {

        return this.width;
    }

    public int getHeight() {

        return this.height;
    }

    /**
    * Set the height of a vertex of the map
    */
    public void setHeight(int x, int y, float h) {

        int index = x;

        if(y > 0) {

            index += (y - 1) * width;
        }

        map.set(index - 1, h);

        /* DEBUG
        for(int i = 0; i < map.size(); i++) {

            System.out.println(i + "   height: " + map.get(i));
        }
        */
    }

    public float getHeight(int x, int y) {

        int index = x;

        if(y > 0) {

            index += (y - 1) * width;
        }

        return map.get(index);
    }

    public float getHeight(float x, float y) {

        return this.getHeight((int)x, (int)y);
    }

    /**
     * This method simplifies the heightmap.
     * It will merge seperate quads with the same vertex heights.
     * This is to save memory and render faster.
     * 
     * This method should only be called when the heightmap is changed.
     * So this method should NOT be called every frame.
     */
    public void simplify() {

            // Don't really know how to do this.
        for(int i = 0; i < width * height; i++) {

            for(int w = 1; w < width - 1; w++) {

                if(map.get(i) == map.get(i + w)) {


                }
            }
        }
    }

}

有人有这方面的经验吗? 是否有任何想法或改进,我的做法是否正确? 提前致谢。

【问题讨论】:

  • 也许你可以得到更多帮助here
  • 好吧。那是高度图。重要的是:你如何渲染它?在现代显卡上几乎看不到 40k 顶点。但是,如果涉及到像glVertex3f(x,y,map.getHeight(x,y)) 这样的东西,那么我可以想象这非常慢。 (顺便说一句:通过用简单的float[] 数组替换List&lt;Float&gt; 已经可以实现显着的改进,但是为了真正的高性能,您应该考虑顶点缓冲区对象(VBO)和其他“现代”OpenGL 的东西)跨度>
  • 使用 VBO。这会有所帮助。

标签: java math optimization lwjgl heightmap


【解决方案1】:

首先,您应该使用固定数组而不是列表。这已经会带来一点推动。我没有看到调整高度图大小的功能,因此无论如何它可能是固定大小。你可以这样初始化一个静态数组:

float[][] map;
public HeightMap(int width, int height) {
    this.map = new float[width][height];
    ...
}

使用二维数组还可以简化您的 getHeight(x, y) 和 setHeihgt(x, y, height) 方法。除此之外,它在很大程度上取决于您的渲染方法。我建议将顶点缓冲区对象与 GL_TRIANGLE_STRIP 一起用于高度图。
有关顶点缓冲区对象的更多信息,请查看http://lwjgl.org/wiki/index.php?title=Using_Vertex_Buffer_Objects_%28VBO%29
除此之外尝试使用剔除面。这可能会进一步提高您的性能。
此外,您可能希望为更大的级别设置渲染距离以提高性能。

我知道,这可能不是您要寻找的答案,但我希望不过会有所帮助。

编辑:
哦,看来您正在使用四边形。我为高度图做的一件事是,我为每个像素分配了一个顶点并使用 GL_TRIANGLE_STRIP 连接它们(如上所述)。除此之外你仍然可以使用 QUADS,我认为它根本不会有任何区别。如果你按照上面的建议,你可能会得到一个 1000*1000 的高度图,以 200 FPS 运行。 (这就是我目前在一个项目中所做的)。

【讨论】:

    猜你喜欢
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-09
    • 2011-06-15
    • 2011-06-18
    • 2018-08-08
    相关资源
    最近更新 更多