2

你好,我不想做基于高度图的游戏,我有优化问题。我在 DisplayList 中进行了实际渲染,但是当我想渲染高度图 512x512 时,我只有 20-30 fps。我在 vbo 中尝试了一些东西,但它不起作用。这是我显示列表渲染的源代码:

    public class Heightmap {
    public static final Vector2f CHUNK_XZ = new Vector2f(256, 256);

    public int CHUNK_ID;

    private float[][] chunk_data = null;
    private Vector3f[][] chunk_color_data = null;

    private Vector3f pos;
    private Vector3f scale = new Vector3f(10, 10, 10);

    private boolean visible = true;

    private int displayID;

    private Texture texture;

    public Heightmap(Vector3f pos) {
        this.pos = pos;

        chunk_data = new float[(int) CHUNK_XZ.x][(int) CHUNK_XZ.y];
        chunk_color_data = new Vector3f[(int) CHUNK_XZ.x][(int) CHUNK_XZ.y];

        for(int x = 0; x < chunk_data.length; x++) {
            for(int y = 0; y < chunk_data[0].length; y++) {
                chunk_data[x][y] = 1.0f;
                chunk_color_data[x][y] = new Vector3f(0f, 0f, (float) Math.random());
            }
        }

        try {
            texture = TextureLoader.getTexture("jpg", new FileInputStream(new File("grassy.jpg")));
        } catch (IOException e) {
            e.printStackTrace();
        }

        displayID = glGenLists(1);

        GL11.glNewList(displayID, GL11.GL_COMPILE);
        texture.bind();

        GL11.glPushMatrix();
        GL11.glScalef(scale.x, scale.y, scale.z);

        GL11.glBegin(GL11.GL_QUADS);

        int heightmapExaggeration = 10;

        for(int x=0; x < chunk_data.length; x++) {
            for(int y=0; y < chunk_data[x].length; y++) {
                GL11.glColor3f(chunk_color_data[x][y].getX(), chunk_color_data[x][y].getY(), chunk_color_data[x][y].getZ());
                GL11.glTexCoord2f(0, 0);
                GL11.glVertex3f(x*0.25f, getHeightAt(x, y)*heightmapExaggeration, y*0.25f);
                GL11.glTexCoord2f(1, 0);
                GL11.glVertex3f((x+1)*0.25f, getHeightAt(x+1, y)*heightmapExaggeration, y*0.25f);
                GL11.glTexCoord2f(1, 1);
                GL11.glVertex3f((x+1)*0.25f, getHeightAt(x+1, y+1)*heightmapExaggeration, (y+1)*0.25f);
                GL11.glTexCoord2f(0, 1);
                GL11.glVertex3f(x*0.25f, getHeightAt(x, y+1)*heightmapExaggeration, (y+1)*0.25f);
            }
        }

        GL11.glEnd();
        GL11.glPopMatrix();
        texture.release();
        GL11.glEndList();
    }
    public Chunk(float[][] chunk_data, Vector3f[][] chunk_color_data, Vector3f pos) {
        this.chunk_data = chunk_data;
        this.chunk_color_data = chunk_color_data;
        this.pos = pos;

        try {
            texture = TextureLoader.getTexture("jpg", new FileInputStream(new File("grassy.jpg")));
        } catch (IOException e) {
            e.printStackTrace();
        }

        displayID = glGenLists(1);

        GL11.glNewList(displayID, GL11.GL_COMPILE);
        texture.bind();

        GL11.glPushMatrix();
        GL11.glScalef(scale.x, scale.y, scale.z);

        GL11.glBegin(GL11.GL_QUADS);

        int heightmapExaggeration = 10;
        for(int x=0; x < chunk_data.length; x++){
            for(int y=0; y < chunk_data[x].length; y++){
                GL11.glColor3f(chunk_color_data[x][y].getX(), chunk_color_data[x][y].getY(), chunk_color_data[x][y].getZ());
                GL11.glTexCoord2f(0, 0);
                GL11.glVertex3f(x*0.25f, getHeightAt(x, y)*heightmapExaggeration, y*0.25f);
                GL11.glTexCoord2f(1, 0);
                GL11.glVertex3f((x+1)*0.25f, getHeightAt(x+1, y)*heightmapExaggeration, y*0.25f);
                GL11.glTexCoord2f(1, 1);
                GL11.glVertex3f((x+1)*0.25f, getHeightAt(x+1, y+1)*heightmapExaggeration, (y+1)*0.25f);
                GL11.glTexCoord2f(0, 1);
                GL11.glVertex3f(x*0.25f, getHeightAt(x, y+1)*heightmapExaggeration, (y+1)*0.25f);
            }
        }

        GL11.glEnd();
        GL11.glPopMatrix();
        texture.release();
        GL11.glEndList();

    }
    public float getHeightAt(int x, int z){
        try {
            return chunk_data[x][z];
        } catch(Exception e) {
            return 0;
        }
    }
    public void render() {
        glPushMatrix();
        glTranslatef(pos.x, pos.y, pos.z);
        glCallList(displayID);
        glPopMatrix();
    }
    public void setChunkDataAtCoords(int x, int y, float value) {
        this.chunk_data[x][y] = value;
    }
    public float[][] getChunk_data() {
        return chunk_data;
    }
    public Vector3f[][] getChunk_color_data() {
        return chunk_color_data;
    }
    public Vector3f getPos() {
        return pos;
    }
    public Vector3f getScale() {
        return scale;
    }
    public void setChunk_data(float[][] chunk_data) {
        this.chunk_data = chunk_data;
    }
    public void setChunk_color_data(Vector3f[][] chunk_color_data) {
        this.chunk_color_data = chunk_color_data;
    }
    public void setChunkColorDataAtCoords(int x, int y, Vector3f color) {
        chunk_color_data[x][y] = color;
    }
    public void setPos(Vector3f pos) { 
        this.pos = pos;
    }
    public void setScale(Vector3f scale) {
        this.scale = scale;
    }
    public boolean isVisible() {
        return visible;
    }
    public void setVisible(boolean visible) {
        this.visible = visible;
    }
}

和 vbo 渲染代码,但不能正常工作:

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;


public class Terrain {

    private int width = 200;
    private int height = 200;
    private int verticies = (3*(2*height)*width);
    private int indicies = ((height*2)*width);
    private FloatBuffer vBuffer = BufferUtils.createFloatBuffer(verticies);
    private IntBuffer iBuffer = BufferUtils.createIntBuffer(indicies);
    private IntBuffer ib = BufferUtils.createIntBuffer(indicies);
    private static float[][] data;

    public Terrain() {
        glPushMatrix();
        glScalef(0.6f, 0.6f, 0.6f);
        glTranslatef(0f, 10f, 0f);
        loadHeightImage();
        loadHeightVerticies();
        drawHeightMap();
        glPopMatrix();
    }

    public void loadHeightImage() {

        try {           
            BufferedImage heightmapImage = ImageIO.read(new File("height.jpg"));
            data = new float[heightmapImage.getWidth()][heightmapImage.getHeight()];
            Color colour;

            for (int x = 0; x < data.length; x++)
            {
                for (int z = 0; z < data[x].length; z++)
                {
                    colour = new Color(heightmapImage.getRGB(x, z));
                    data[z][x] = colour.getRed();

                }
            }
        } catch (IOException e){
            e.printStackTrace();
        }
    }

    public void loadHeightVerticies() {
        for (int z = 0; z < this.data.length - 1; z++) {
            for (int x = 0; x < this.data[z].length; x++) {

                vBuffer.put(x).put(this.data[z][x]).put(z);
                vBuffer.put(x).put(this.data[z + 1][x]).put(z + 1);
            }
        }

        this.vBuffer.flip();

        for (int n = 0; n < indicies; n++) {
            this.iBuffer.put( n);
        }

        this.iBuffer.flip();
    }

    public void drawHeightMap() {

        glGenBuffers(ib);
        int vHandle = ib.get(0);
        int iHandle = ib.get(1);

        glEnableClientState(GL_VERTEX_ARRAY);
        glBindBuffer(GL_ARRAY_BUFFER, vHandle);
        glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);
        glVertexPointer(3, GL_FLOAT, 0, 0L);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iHandle);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, iBuffer, GL_STATIC_DRAW);

        for (int x = 0; x < 400; x++) {
            glDrawElements(GL_TRIANGLE_STRIP, 400, GL_UNSIGNED_SHORT, 1600 * x);
        }  

        glDisableClientState(GL_VERTEX_ARRAY);

        ib.put(0, vHandle);

        glDeleteBuffers(ib);
    }   
} 

还有一个问题,我怎样才能像在显示列表模式中那样为高度图着色?对不起我的英语不好。

4

1 回答 1

0

你渲染多少块?如果您不需要四边形的所有侧面,也许您应该查看面部剔除。

于 2015-07-21T21:03:17.787 回答