2015-01-08 103 views
2

你好我不想做基於高度圖的遊戲,我有優化問題。我acctualy呈現在DisplayList,但是當我想渲染高度圖512x512我只有20-30幀/秒。我在vbo中嘗試了一些東西,但不起作用。這是我的源代碼,以顯示列表渲染:Java LWJGL高度圖渲染

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

還有一個問題我怎麼能在顯示列表模式顏色高度圖是怎樣的?對不起我的英語不好。

回答

0

你渲染了多少塊?如果你不需要四邊形的所有邊,也許你應該看看face culling