2012-05-07 6 views
1

저는 오픈 월드 게임 인 샌드 박스 (Voxel)를 만들려고합니다. 내 게임에서는 블록 데이터를 저장하기 위해 청크라고 불리는 32x32x32 블록 세트를 사용하며, 각각에는 4 개의 VBO가 있습니다. 정점, 기본 색상, 보조 색상, 텍스처 좌표입니다. 이 VBO의의는이 클래스에 저장됩니다샌드 박스 lwjgl 게임 속도를 높이려면 어떻게해야합니까?

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

} 

} 

정적 방법은 시작하고 중지 덩어리를 그리기 위해 준비하고 그리기 덩어리를 완료 세계 클래스에서 호출됩니다

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의 연장.

편집 : 문제가 해결되었습니다. VBO에서 물건을 두 배로 사용하지 말고 수레를 사용하십시오!

+2

무엇을 시도 했습니까? 문제가 정확히 무엇인가, 즉 무엇이 너무 느린 것으로 식별 했습니까? – Thomas

+0

왜 VBORenderer가 ImmediateModeRenderer를 재정의합니까? VBO는 직접 모드가 아닙니다. – aib

+0

그래서 ImmediateModeRenderer의 List에 저장된 데이터에서 FloatBuffers 및 VBO로 데이터를 전송할 수 있습니다. 나는 많은 덩어리의 렌더링과 "덩어리의 정점 계산, 그러나 또 다른 것은 모두"너무 느리다 (8-12fps) 렌더링을 확인했다. – adventurerOK

답변

4

데이터를 별도로 저장하는 대신 인터리브 VBO를 구현하는 것이 좋습니다. 이렇게하면 성능이 약간 향상됩니다.

관련 문제