2016-03-22 2 views
-1

私は約2000個の頂点を含む6つのフィールドを画面上に描画するプログラムを持っています。これらのVBOを作成するには、バッファオブジェクト(Int/Float)を使用する必要があります。頂点の位置などをxmlファイルに保存する必要があるので、モデルオブジェクトをシリアル化し、B64に変換して文字列として保存します。バッファオブジェクトは直列化できません。VBOを作成するときに静的メソッドがメモリを起動するのはなぜですか?

この問題を回避するために、モデルオブジェクトからすべてのVBOコードを削除しました(最初は別のクラスから拡張しました)。そして、VBOを作成する静的メソッドを作成しました。だから、モデルのVBOを作成してハンドルを返すように静的メソッドを呼び出して、レンダリングや頂点の更新などを呼び出すことができます。しかし、モデルが作成されるとメモリが大幅に増加するという影響がありました。

これはなぜでしょうか?もともとメモリ使用量は目立たなかった。これでJVMがクラッシュします。私はコードロジックを変更していませんが、メソッドは静的でハンドルを返す以外は同じです。静的メソッドは、VBOを作成するときに何らかのメモリを使用しますか?私はそれが少ないだろうと思った?私は使用後にすべてのバッファーをクリアします。私はすべてのカリングしたモデルを処分します。

編集:ここ

package Drawing; 

import static org.lwjgl.opengl.GL11.GL_FLOAT; 
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; 
import static org.lwjgl.opengl.GL15.GL_DYNAMIC_DRAW; 
import static org.lwjgl.opengl.GL15.GL_ELEMENT_ARRAY_BUFFER; 
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; 
import static org.lwjgl.opengl.GL15.glBindBuffer; 
import static org.lwjgl.opengl.GL15.glBufferData; 
import static org.lwjgl.opengl.GL15.glBufferSubData; 
import static org.lwjgl.opengl.GL15.glGenBuffers; 
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; 
import static org.lwjgl.opengl.GL20.glVertexAttribPointer; 
import static org.lwjgl.opengl.GL30.glBindVertexArray; 
import static org.lwjgl.opengl.GL30.glGenVertexArrays; 

import java.nio.FloatBuffer; 
import java.nio.IntBuffer; 

import org.lwjgl.BufferUtils; 

/** 
* This class calls all vbo functions in a static way which allows me to 
* separate the Int/FloatBuffers from the model classes like Cube and 
* Quad. Int/FloatBuffers will not serialize so the Cube/Quad classes 
* cannot be saved to file. Keeping them static and separated 
* will overcome this problem. 
*/ 
public class Render { 

static int VERTEXCOUNT = 0;//((QUAD_SIZE * QUAD_SIZE) * 12); 
static FloatBuffer fbData = null;//BufferUtils.createFloatBuffer(VERTEXCOUNT); 
static FloatBuffer fbNorm = null;//BufferUtils.createFloatBuffer(VERTEXCOUNT); 
static FloatBuffer fbtex = null;//BufferUtils.createFloatBuffer((VERTEXCOUNT/12) * 8); 
static IntBuffer Indices = null; 
private static int _VAOHandle = 0; 
private static IntBuffer vboHandles; 

static final int POSITION_INDEX = 0; // index of vertex attribute "in_Position" 
static final int NORMALS_IDX = 1; 
static final int TEXTURE_IDX = 2; 
static final int IBO_IDX = 3; 

public static VBOIndexes createVBO(int QUAD_SIZE, 
     float[] vertBuffer, 
     float[] normals, 
     float[] UVs, 
     int[] idxBuffer) throws Exception { 

    VBOIndexes vboINDEXES = new VBOIndexes(); 

    try{ 

     VERTEXCOUNT = (int) ((QUAD_SIZE * QUAD_SIZE) * 12); 
     fbData = BufferUtils.createFloatBuffer(VERTEXCOUNT); 
     fbNorm = BufferUtils.createFloatBuffer(VERTEXCOUNT); 
     fbtex = BufferUtils.createFloatBuffer((VERTEXCOUNT/12) * 8); 
     Indices = BufferUtils.createIntBuffer(VERTEXCOUNT/2); 


     _VAOHandle = glGenVertexArrays(); 

     vboINDEXES.VAOHandle = _VAOHandle; 

     System.out.println("VAOHandle is : " + _VAOHandle); 

     glBindVertexArray(_VAOHandle); 

     vboHandles = BufferUtils.createIntBuffer(4); 
     glGenBuffers(vboHandles); 

     vboINDEXES.idxPOS = vboHandles.get(POSITION_INDEX); 
     vboINDEXES.idxNORM = vboHandles.get(NORMALS_IDX); 
     vboINDEXES.idxTEX = vboHandles.get(TEXTURE_IDX); 
     vboINDEXES.idxIBO = vboHandles.get(IBO_IDX); 

     //FloatBuffer fbData = BufferUtils.createFloatBuffer(vertBuffer.length); 
     fbData.put(vertBuffer); 
     fbData.rewind(); // rewind, otherwise LWJGL thinks our buffer is empty 

     glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(POSITION_INDEX)); 

     glBufferData(GL_ARRAY_BUFFER, fbData, GL_DYNAMIC_DRAW); 
     fbData.clear(); //don't need this anymore 


     //populate the normals buffer 
     //FloatBuffer fbNorm = BufferUtils.createFloatBuffer(normalsBuffer.length); 
     fbNorm.put(normals); 
     fbNorm.rewind(); 
     glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(NORMALS_IDX)); //the vertex data 
     glBufferData(GL_ARRAY_BUFFER, fbNorm, GL_STATIC_DRAW); 
     fbNorm.clear(); //don't need this anymore 

     //populate the texture buffer 

     fbtex.put(UVs); 
     fbtex.rewind(); 
     glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(TEXTURE_IDX)); 
     glBufferData(GL_ARRAY_BUFFER, fbtex, GL_DYNAMIC_DRAW); 
     fbtex.clear(); //don't need this anymore 

     Indices.put(idxBuffer); 
     Indices.rewind(); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandles.get(IBO_IDX)); 

     glBufferData(GL_ELEMENT_ARRAY_BUFFER, Indices, GL_STATIC_DRAW); 

     glEnableVertexAttribArray(POSITION_INDEX); 
     glEnableVertexAttribArray(NORMALS_IDX); 
     glEnableVertexAttribArray(TEXTURE_IDX); 

     glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(POSITION_INDEX)); 
     glVertexAttribPointer(0,3, GL_FLOAT, false,0,0);  

     //normals 
     glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(NORMALS_IDX)); 
     glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0); 

     glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(TEXTURE_IDX)); 
     glVertexAttribPointer(2, 2, GL_FLOAT, false, 0, 0); 

     //bind IBO 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandles.get(IBO_IDX)); 

     glBindVertexArray(0); 

     glBindBuffer(GL_ARRAY_BUFFER, 0); 


     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

     Indices.clear(); 

    }catch (Exception ex){ 
     System.out.println("createVBO: " + ex.getMessage()); 
     throw ex; 
    } 
    return vboINDEXES; 
} 

public static VBOIndexes createLineVBO(float[] vertBuffer, 
          int[] idxBuffer) throws Exception { 

    VBOIndexes vboINDEXES = new VBOIndexes(); 

    try{ 

     fbData = BufferUtils.createFloatBuffer(vertBuffer.length); 
     Indices = BufferUtils.createIntBuffer(vertBuffer.length/2); 

     _VAOHandle = glGenVertexArrays(); 

     vboINDEXES.VAOHandle = _VAOHandle; 

     glBindVertexArray(_VAOHandle); 

     vboHandles = BufferUtils.createIntBuffer(4); 
     glGenBuffers(vboHandles); 

     vboINDEXES.idxPOS = vboHandles.get(POSITION_INDEX); 
     vboINDEXES.idxIBO = vboHandles.get(IBO_IDX); 

     fbData.put(vertBuffer); 
     fbData.rewind(); // rewind, otherwise LWJGL thinks our buffer is empty 

     glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(POSITION_INDEX)); 

     glBufferData(GL_ARRAY_BUFFER, fbData, GL_STATIC_DRAW); 
     fbData.clear(); //don't need this anymore 

     //IntBuffer Indices = BufferUtils.createIntBuffer(idxBuffer.length); 
     Indices.put(idxBuffer); 
     Indices.rewind(); 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandles.get(IBO_IDX)); 
     //Util.checkGLError(); 
     glBufferData(GL_ELEMENT_ARRAY_BUFFER, Indices, GL_STATIC_DRAW); 

     glEnableVertexAttribArray(POSITION_INDEX); 
     glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(POSITION_INDEX)); 
     glVertexAttribPointer(0,3, GL_FLOAT, false,0,0);  

     //bind IBO 
     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandles.get(IBO_IDX)); 

     Indices.clear(); 

     glBindVertexArray(0); 

     glBindBuffer(GL_ARRAY_BUFFER, 0); 
     //Util.checkGLError(); 

     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); 

    }catch (Exception ex){ 
     System.out.println("createVBO: " + ex.getMessage()); 
     throw ex; 
    } 
    return vboINDEXES; 
} 

    public static void updateVertices(int offset, 
          float[] vertBuffer, 
          int idxPOS) 
    { 
     //populate the vertex buffer 
     FloatBuffer fbData = BufferUtils.createFloatBuffer(vertBuffer.length); 
     fbData.put(vertBuffer); 
     fbData.rewind(); 
     //glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(POSITION_INDEX)); //the vertex data 
     glBindBuffer(GL_ARRAY_BUFFER, idxPOS); 
     glBufferSubData(GL_ARRAY_BUFFER, offset, fbData); 
     fbData.clear(); //don't need this anymore 
    } 

    public static void updateNormals(int offset, 
           float[] normals, 
           int idxNORM) 
    { 

     //populate the vertex buffer 
     FloatBuffer fbData = BufferUtils.createFloatBuffer(normals.length); 
     fbData.put(normals); 
     fbData.rewind(); 
     //glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(NORMALS_IDX)); //the vertex data 
     glBindBuffer(GL_ARRAY_BUFFER, idxNORM); 
     glBufferSubData(GL_ARRAY_BUFFER, 0, fbData); 
     fbData.clear(); //don't need this anymore 
    } 

    public static void updateTexture(int offset, 
      float[] UVs, 
      int idxTEX) 
    { 

     //populate the texture buffer 
     FloatBuffer fbtex = BufferUtils.createFloatBuffer(UVs.length); 
     fbtex.put(UVs); 
     fbtex.rewind(); 

     //glBindBuffer(GL_ARRAY_BUFFER, vboHandles.get(TEXTURE_IDX)); //the texture data 
     glBindBuffer(GL_ARRAY_BUFFER, idxTEX); 
     glBufferSubData(GL_ARRAY_BUFFER, offset, fbtex); 
     fbtex.clear(); //don't need this anymore 
    } 

    public Render(){ 

    } 

} 

静的コールがASフィールド(タイルオブジェクトの配列)のコンストラクタで作られている静的メソッドが含まれているレンダリングクラスは、以下である:

public Quad(Map<Integer, Cube> c, int SIZE) throws Exception{ 
//public Quad(ArrayList<Cube> c, int SIZE) throws Exception{ 
    QUAD_SIZE = SIZE; 
    initArrays(); 
    initVBOData(SIZE); 
    createVBO(); 
    cubes = c; 

} 
+0

必要ですか?メタデータはxmlで、バイナリでの位置はオプションですか? – elect

+0

その部分は本当に問題ではありません。私は実際に頂点の位置、高さ、モデルの他のプロパティをすべて保存しません。問題は、それらの静的メソッドを呼び出すことによってメモリが殺されることです。かつて100Kだったのは今1Gを超えていますか?そして、その論理は変わらなかった。 –

+0

何千もの頂点は実際には少量ですが、あなたのコードを再確認します。何か間違っていると思います。あなたのコードのいくつかを投稿できる場合は – elect

答えて

0

静的クラスではGCが提供されないと答えています。すべてのデータがVBOの作成に渡されているので、Gは実際に積み重なるようになります。

+0

正確に正しい。静的クラスは、私の知る限り、プログラムの継続時間のための割り当てです。彼らは移動しません、彼らはゴミ収集されていない、彼らはちょうど呼び出しを待ってそこに座る。 – sova

+0

正確には間違っています*。オブジェクトの存続期間は、そのクラスが「静的」であるかどうかとまったく関係ありません。 @sova – EJP

+0

@EJP、まだ私はまだ初心者ですので大丈夫ですが、静的な最終オブジェクトはどうですか? – sova

0

コードは非常に混乱していますが、OpenGLの仕組みを理解し、よりきれいで読みやすい。 this sampleからインスピレーションを受けることをお勧めします。

少数の考慮事項:

  • あなたは私がLWJGLを知っていないすべての
  • で静的必要はありませんが、私はそれが直接のバッファを必要と推測し、あなたは彼らがすることによって除去されようとしている保証はありませんガーベッジコレクタは、自分で割り当てて、不要になったら解放してください。私は小さなクラスを作成して、直接バッファを解放しました。here
  • OpenGLリソースの名前をvboINDEXESの中に保存することで冗長性を避けました。あなたはすでにあまりにもclear()にこのような理由のために
  • それらを必要としない、あなたのバッファの大きさが変化しない場合には、(fbDatafbNormfbTex)を一度にそれらを割り当て、それらを保つ直接vboHandles
  • を使用している、ときあなたが最初の引数の変数保持としてglVertexAttribPointerパスを呼び出すときに、新しいバッファをインスタンス化し、すでにビューの論理ポイントで
  • を始めるでインスタンス1を使用していないupdateNormals()IBO_INDEXvboINDEXES
  • の一部であってはなりません属性インデックス(など)

PS:インデックスの複数のは、あなたが本当にプレーンXML内の位置を指標

関連する問題