2012-05-07 25 views
1

我想製作一個沙盒(Voxel),開放式的世界遊戲。我的遊戲使用稱爲塊的32x32x32塊組來存儲塊數據,其中每個塊都有4個VBO:頂點,主顏色,輔助顏色,紋理座標。這些VBO的存儲在這個類:如何加快sandbox lwjgl遊戲?

import game.vc3d.util.ArrayUtils; 

import java.nio.DoubleBuffer; 
import java.nio.FloatBuffer; 

import org.lwjgl.BufferUtils; 

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

public class VBORenderer extends ImmediateModeRenderer { 


FloatBuffer vertexData; 
FloatBuffer primColorData; 
FloatBuffer secColorData; 
DoubleBuffer texCoordData; 

FloatBuffer allData; 

int fullVBOID; 

int vboVertexID; 
int vboPrimColorID; 
int vboSecColorID; 
int vboTexCoordID; 
int amountOfVertexes = 0; 
boolean fin1ed = false; 

int texIndex = 0; 

static final int DRAW_METHOD = GL_STATIC_DRAW; 

static boolean ted = false; 

int vertexEnd; 
int primCStart; 
int primCEnd; 
int secCStart; 
int secCEnd; 




@Override 
public void setTexture(int texture) { 
    texEnabled = true; 
    texIndex = texture; 
} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#disableTexture() 
*/ 
@Override 
public void disableTexture() { 
    texEnabled = false; 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#finalize() 
*/ 
@Override 
public void finalize() { 
    amountOfVertexes = vertexes.size()/3; 

    if(amountOfVertexes < 1) return; 




    float tempVD[] = ArrayUtils.toPrimatives(vertexes.toArray(new Float[vertexes.size()])); 
    vertexData = BufferUtils.createFloatBuffer(tempVD.length); 
    vertexData.put(tempVD); 

    float tempPCD[] = ArrayUtils.toPrimatives(primaryColors.toArray(new Float[vertexes.size()])); 
    primColorData = BufferUtils.createFloatBuffer(tempPCD.length); 
    primColorData.put(tempPCD); 
    float tempSCD[] = ArrayUtils.toPrimatives(secondaryColors.toArray(new Float[vertexes.size()])); 
    secColorData = BufferUtils.createFloatBuffer(tempSCD.length); 
    secColorData.put(tempSCD); 
    double tempTCD[] = ArrayUtils.toPrimatives(texCoords.toArray(new Double[vertexes.size()])); 
    texCoordData = BufferUtils.createDoubleBuffer(tempTCD.length); 
    texCoordData.put(tempTCD); 

    vertexData.flip(); 
    primColorData.flip(); 
    secColorData.flip(); 
    texCoordData.flip(); 


    if(!fin1ed)vboVertexID = glGenBuffers(); 
    glBindBuffer(GL_ARRAY_BUFFER, vboVertexID); 
    glBufferData(GL_ARRAY_BUFFER, vertexData, DRAW_METHOD); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    if(!fin1ed)vboPrimColorID = glGenBuffers(); 
    glBindBuffer(GL_ARRAY_BUFFER, vboPrimColorID); 
    glBufferData(GL_ARRAY_BUFFER, primColorData, DRAW_METHOD); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    if(!fin1ed)vboSecColorID = glGenBuffers(); 
    glBindBuffer(GL_ARRAY_BUFFER, vboSecColorID); 
    glBufferData(GL_ARRAY_BUFFER, secColorData, DRAW_METHOD); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 

    if(!fin1ed)vboTexCoordID = glGenBuffers(); 
    glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordID); 
    glBufferData(GL_ARRAY_BUFFER, texCoordData, DRAW_METHOD); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 




    fin1ed = true; 

} 


/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#clear() 
*/ 
@Override 
public void clear() { 
    super.clear(); 
    texIndex = 0; 
} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#render() 
*/ 
@Override 
public void render() { 

    if(amountOfVertexes < 1) return; 


    glBindBuffer(GL_ARRAY_BUFFER, vboVertexID); 
    glVertexPointer(3, GL_FLOAT, 0, 0L); 

    glBindBuffer(GL_ARRAY_BUFFER, vboPrimColorID); 
    glColorPointer(4, GL_FLOAT, 0, 0L); 

    glBindBuffer(GL_ARRAY_BUFFER, vboSecColorID); 
    glSecondaryColorPointer(3, GL_FLOAT, 0, 0L); 

    glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordID); 
    glTexCoordPointer(2, GL_DOUBLE, 0, 0L); 

    glDrawArrays(GL_QUADS, 0, amountOfVertexes); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 




} 
public static void prepareForRendering(Object...objects){ 
    if(objects.length > 0){ 
     glEnable(GL_TEXTURE_2D); 
     glBindTexture(GL_TEXTURE_2D, (Integer)objects[0]); 
     ted = true; 
    } else { 
     glDisable(GL_TEXTURE_2D); 
    } 

    glEnable(GL_COLOR_SUM); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_COLOR_ARRAY); 
    glEnableClientState(GL_SECONDARY_COLOR_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
} 
public static void finishRendering(){ 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_COLOR_ARRAY); 
    glDisableClientState(GL_SECONDARY_COLOR_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    if(ted){ 
     glDisable(GL_TEXTURE_2D); 
     ted = false; 
    } 


} 

} 

延伸ImmediateModeRenderer:

import java.util.ArrayList; 

import org.lwjgl.opengl.GL14; 
import org.lwjgl.util.vector.Vector3f; 
import org.lwjgl.util.vector.Vector4f; 

import static org.lwjgl.opengl.GL11.*; 
import static org.lwjgl.opengl.GL14.glSecondaryColor3f; 

public class ImmediateModeRenderer extends Renderer { 

private boolean canInput = true; 

public ArrayList<Float> vertexes = new ArrayList<Float>(); 
public ArrayList<Boolean> textures = new ArrayList<Boolean>(); 
public ArrayList<Float> primaryColors = new ArrayList<Float>(); 
public ArrayList<Float> secondaryColors = new ArrayList<Float>(); 
public ArrayList<Double> texCoords = new ArrayList<Double>(); 
public ArrayList<Integer> currentTextures = new ArrayList<Integer>(); 
boolean texEnabled = false; 
Vector4f primColor = new Vector4f(1, 1, 1, 1); 
Vector4f secColor = new Vector4f(0, 0, 0, 0); 
double texX = 0; 
double texY = 0; 
int currentTex = 0; 
Vector3f _trans = new Vector3f(0, 0, 0); 
Vector3f _scale = new Vector3f(1, 1, 1); 


/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#addVertex(float, float, float) 
*/ 
@Override 
public void addVertex(float x, float y, float z) { 
    if(!canInput) throw new IllegalStateException("this.canInput() must be true"); 
    vertexes.add((x + _trans.x) * _scale.x); 
    vertexes.add((y + _trans.y) * _scale.y); 
    vertexes.add((z + _trans.z) * _scale.z); 
    textures.add(texEnabled); 
    if(texEnabled){ 
     texCoords.add(texX); 
     texCoords.add(texY); 
     currentTextures.add(currentTex); 
    } 
    primaryColors.add(primColor.x); 
    primaryColors.add(primColor.y); 
    primaryColors.add(primColor.z); 
    primaryColors.add(primColor.w); 
    secondaryColors.add(secColor.x); 
    secondaryColors.add(secColor.y); 
    secondaryColors.add(secColor.z); 
    //secondaryColors.add(secColor.w); 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#primaryColor(float, float, float, float) 
*/ 
@Override 
public void primaryColor(float r, float g, float b, float a) { 
    primColor = new Vector4f(r, g, b, a); 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#setTexture(int) 
*/ 
@Override 
public void setTexture(int texture) { 
    texEnabled = true; 
    currentTex = texture; 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#texture(float, float) 
*/ 
@Override 
public void texture(double x, double y) { 
    texX = x; 
    texY = y; 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#secondaryColor(float, float, float, float) 
*/ 
@Override 
public void secondaryColor(float r, float g, float b, float a) { 
    secColor = new Vector4f(r, g, b, a); 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#disableTexture() 
*/ 
@Override 
public void disableTexture() { 
    texEnabled = true; 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#clear() 
*/ 
@Override 
public void clear() { 
    vertexes = new ArrayList<Float>(); 
    textures = new ArrayList<Boolean>(); 
    primaryColors = new ArrayList<Float>(); 
    secondaryColors = new ArrayList<Float>(); 
    texCoords = new ArrayList<Double>(); 
    currentTextures = new ArrayList<Integer>(); 
    texEnabled = false; 
    primColor = new Vector4f(1, 1, 1, 1); 
    secColor = new Vector4f(0, 0, 0, 0); 
    texX = 0; 
    texY = 0; 
    currentTex = 0; 

    _trans = new Vector3f(0, 0, 0); 
    _scale = new Vector3f(1, 1, 1); 

    canInput = true; 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#render() 
*/ 
@Override 
public void render() { 
    int amountOfVertexs = vertexes.size()/3; 
    int currentV = -1; 
    int currentPC = -1; 
    int currentSC = -1; 
    int currentTex = -1; //Current Tex Coords 
    int texInd = -1; //Current Texture No. 
    int texNoInd = -1; //Curent vert 
    int oldBoundTexture = 0; //Old texture 
    boolean oldTex = false; 
    glDisable(GL_TEXTURE_2D); 
    glEnable(GL14.GL_COLOR_SUM); 
    glBegin(GL_QUADS); 
    for(int vert = 0; vert < amountOfVertexs; vert++){ 
     if(textures.get(++texNoInd)){ 
      if(!oldTex){ 
       glEnd(); 
       glEnable(GL_TEXTURE_2D); 
       glBegin(GL_QUADS); 
      } 
      if(currentTextures.get(++texInd) != oldBoundTexture){ 
       glEnd(); 
       oldBoundTexture = currentTextures.get(texInd); 
       glBindTexture(GL_TEXTURE_2D, oldBoundTexture); 
       glBegin(GL_QUADS); 
      } 

      glTexCoord2d(texCoords.get(++currentTex), texCoords.get(++currentTex)); 


     } else { 
      if(oldTex){ 
       glEnd(); 
       glDisable(GL_TEXTURE_2D); 
       glBegin(GL_QUADS); 
      } 
     } 
     oldTex = textures.get(texNoInd); 

     //Do Colors 
     glColor4f(primaryColors.get(++currentPC), primaryColors.get(++currentPC), primaryColors.get(++currentPC), primaryColors.get(++currentPC)); 
     glSecondaryColor3f(secondaryColors.get(++currentSC), secondaryColors.get(++currentSC), secondaryColors.get(++currentSC)); 
     //Finalize the vertex 
     glVertex3f(vertexes.get(++currentV), vertexes.get(++currentV), vertexes.get(++currentV)); 
    } 
    glEnd(); 
    glDisable(GL14.GL_COLOR_SUM); 
} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#finalize() 
*/ 
@Override 
public void finalize() { 
    canInput = false; 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#canInput() 
*/ 
@Override 
public boolean canInput() { 
    return canInput; 
} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#scale(float, float, float) 
*/ 
@Override 
public void scale(float x, float y, float z) { 
    _scale = new Vector3f(x, y, z); 

} 

/* (non-Javadoc) 
* @see game.vc3d.rendering.Renderer#translate(float, float, float) 
*/ 
@Override 
public void translate(float x, float y, float z) { 
    _trans = new Vector3f(x, y, z); 

} 

} 

靜態方法來啓動和停止從世界一流的叫繪製塊準備和結束畫塊。

編輯:問題固定!不要使用雙打在VBOs的東西,使用浮動!

+2

你有什麼試過?究竟是什麼問題,即你認爲什麼太慢? – Thomas

+0

VBORenderer爲什麼會覆蓋ImmediateModeRenderer? VBOs不是直接模式。 – aib

+0

因此,我可以從ImmediateModeRenderer中列表中存儲的數據將數據傳輸到FloatBuffers和VBOs。我已經確定了許多塊的渲染「以及塊的頂點計算,但這又是另一件事情」太慢了(8-12幀/秒) – adventurerOK

回答

4

考慮實現交錯的VBO,而不是單獨存儲數據。這應該會提高性能。