你好,我不想做基于高度图的游戏,我有优化问题。我在 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);
}
}
还有一个问题,我怎样才能像在显示列表模式中那样为高度图着色?对不起我的英语不好。