2012-05-07 5 views
1

Я пытаюсь создать песочницу (Voxel), открытую игру. В моей игре используются наборы блоков 32x32x32, называемые кусками для хранения данных блоков, каждый из которых имеет 4 VBOs: вершину, основной цвет, вторичный цвет, текстурные координаты. Эти VBÖ хранятся в этом классе:Как ускорить игру в песочницу 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); 

} 

} 

статические методы для запуска и остановки вызываются из мирового класса, чтобы подготовить для рисования куски и закончить рисунок куски.

EDIT: ПРОБЛЕМА ИСПРАВЛЕНО! Не используйте парные вещи в VBOs, используйте поплавки!

+2

Что вы пробовали? В чем проблема, т. Е. Что вы считаете слишком медленным? – Thomas

+0

Почему VBORenderer переопределяет ImmediateModeRenderer? VBO не являются немедленным. – aib

+0

Поэтому я могу передавать данные в FloatBuffers и VBOs из данных, хранящихся в списках в ImmediateModeRenderer. Я определил рендеринг многих кусков »и вычисление вершины кусков, но это совсем другое», чтобы быть слишком медленным (8-12 кадров в секунду) – adventurerOK

ответ

4

Рассмотрите возможность внедрения чередующихся VBO вместо хранения данных отдельно. Это должно улучшить производительность.