title: How to speed up sandbox lwjgl game?
body: <p>I am trying to make a sandbox (Voxel), open-world game. My game uses 32x32x32 block sets called chunks to store block data, each of these has 4 VBOs: vertex, primary color, secondary color, texture coords. These VBO's are stored in this class:</p>
  
  <pre><code>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 &lt; 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 &lt; 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 &gt; 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;
      }
  
  
  }
  
  }
  </code></pre>
  
  <p>Which extends ImmediateModeRenderer:</p>
  
  <pre><code>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&lt;Float&gt; vertexes = new ArrayList&lt;Float&gt;();
  public ArrayList&lt;Boolean&gt; textures = new ArrayList&lt;Boolean&gt;();
  public ArrayList&lt;Float&gt; primaryColors = new ArrayList&lt;Float&gt;();
  public ArrayList&lt;Float&gt; secondaryColors = new ArrayList&lt;Float&gt;();
  public ArrayList&lt;Double&gt; texCoords = new ArrayList&lt;Double&gt;();
  public ArrayList&lt;Integer&gt; currentTextures = new ArrayList&lt;Integer&gt;();
  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&lt;Float&gt;();
      textures = new ArrayList&lt;Boolean&gt;();
      primaryColors = new ArrayList&lt;Float&gt;();
      secondaryColors = new ArrayList&lt;Float&gt;();
      texCoords = new ArrayList&lt;Double&gt;();
      currentTextures = new ArrayList&lt;Integer&gt;();
      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 &lt; 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);
  
  }
  
  }
  </code></pre>
  
  <p>The static methods to start and stop are called from the world class to prepare for drawing chunks and to finish drawing chunks.</p>
  
  <p>EDIT: PROBLEM FIXED! Dont use doubles for stuff in VBOs, use floats!</p>