2

ハイトマップをコーディングしましたが、クライアントに遅れがあるようです。fpsを上げる方法がわかりません。ハイトマップで約3〜6fpsになります。高さマップにかなり大きな bmp を使用しています。1024x1024 だと思います。小さい方をうまく使用すると、コードを効果的に使用していないだけかもしれません。この高さマップをコーディングするより良い方法はありますか、それともコーディングが間違っていましたか? ハイトマップに取り組んだのは初めてです。ありがとう

public class HeightMap {
    private final float xScale, yScale, zScale;
    private float[][] heightMap;

    private FloatBuffer vertices, normals, texCoords;
    private IntBuffer indices;

    private Vector3f[] verticesArray, normalsArray;
    private int[] indicesArray;
    private int width;
    private int height;

    public float getHeight(int x, int y) {
            return heightMap[x][y] * yScale;
    }

    public HeightMap(String path, int resolution) {
            heightMap = loadHeightmap("heightmap.bmp");

            xScale = 1000f / resolution;
            yScale = 8;
            zScale = 1000f / resolution;

            verticesArray = new Vector3f[width * height];
            vertices = BufferUtils.createFloatBuffer(3 * width * height);
            texCoords = BufferUtils.createFloatBuffer(2 * width * height);
            for (int x = 0; x < width; x++) {
                    for (int y = 0; y < height; y++) {
                            final int pos = height * x + y;
                            final Vector3f vertex = new Vector3f(xScale * x, yScale * heightMap[x][y], zScale * y);

                            verticesArray[pos] = vertex;
                            vertex.store(vertices);

                            texCoords.put(x / (float) width);
                            texCoords.put(y / (float) height);
                    }
            }
            vertices.flip();
            texCoords.flip();

            normalsArray = new Vector3f[height * width];
            normals = BufferUtils.createFloatBuffer(3 * width * height);
            final float xzScale = xScale;
            for (int x = 0; x < width; ++x) {
                    for (int y = 0; y < height; ++y) {
                            final int nextX = x < width - 1 ? x + 1 : x;
                            final int prevX = x > 0 ? x - 1 : x;
                            float sx = heightMap[nextX][y] - heightMap[prevX][y];
                            if (x == 0 || x == width - 1) {
                                    sx *= 2;
                            }

                            final int nextY = y < height - 1 ? y + 1 : y;
                            final int prevY = y > 0 ? y - 1 : y;
                            float sy = heightMap[x][nextY] - heightMap[x][prevY];
                            if (y == 0 || y == height - 1) {
                                    sy *= 2;
                            }

                            final Vector3f normal = new Vector3f(-sx * yScale, 2 * xzScale, sy * yScale).normalise(null);
                            normalsArray[height * x + y] = normal;
                            normal.store(normals);
                    }
            }
            normals.flip();

            indicesArray = new int[6 * (height - 1) * (width - 1)];
            indices = BufferUtils.createIntBuffer(6 * (width - 1) * (height - 1));
            for (int i = 0; i < width - 1; i++) {
                    for (int j = 0; j < height - 1; j++) {
                            int pos = (height - 1) * i + j;

                            indices.put(height * i + j);
                            indices.put(height * (i + 1) + j);
                            indices.put(height * (i + 1) + (j + 1));

                            indicesArray[6 * pos] = height * i + j;
                            indicesArray[6 * pos + 1] = height * (i + 1) + j;
                            indicesArray[6 * pos + 2] = height * (i + 1) + (j + 1);

                            indices.put(height * i + j);
                            indices.put(height * i + (j + 1));
                            indices.put(height * (i + 1) + (j + 1));

                            indicesArray[6 * pos + 3] = height * i + j;
                            indicesArray[6 * pos + 4] = height * i + (j + 1);
                            indicesArray[6 * pos + 5] = height * (i + 1) + (j + 1);

                    }
            }
            indices.flip();
    }

    private float[][] loadHeightmap(String fileName) {
            try {
                    BufferedImage img = ImageIO.read(ResourceLoader.getResourceAsStream(fileName));
                    width = img.getWidth();
                    height = img.getHeight();
                    float[][] heightMap = new float[width][height];
                    for (int x = 0; x < width; x++) {
                            for (int y = 0; y < height; y++) {
                                    heightMap[x][y] = 0xFF & img.getRGB(x, y);
                            }
                    }
                    return heightMap;
            } catch (IOException e) {
                    System.out.println("Nincs meg a heightmap!");
                    return null;
            }
    }

    public void render() {

            glEnableClientState(GL_NORMAL_ARRAY);
            glEnableClientState(GL_VERTEX_ARRAY);
            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            glNormalPointer(0, normals);
            glVertexPointer(3, 0, vertices);
            glTexCoordPointer(2, 0, texCoords);
            glDrawElements(GL_TRIANGLE_STRIP, indices);
            glDisableClientState(GL_NORMAL_ARRAY);
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
            glDisableClientState(GL_VERTEX_ARRAY);

    }

}
4

1 に答える 1

0

古いトピックを持ち出して申し訳ありませんが、多くの人が次のように尋ねます。

ハイトマップを毎回作り直す代わりに、ディスプレイリストを使用してください。TheCodingUniverse には、これを行う方法に関する優れたチュートリアルがあります。

于 2013-11-13T16:19:04.477 に答える