私は約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;
}
必要ですか?メタデータはxmlで、バイナリでの位置はオプションですか? – elect
その部分は本当に問題ではありません。私は実際に頂点の位置、高さ、モデルの他のプロパティをすべて保存しません。問題は、それらの静的メソッドを呼び出すことによってメモリが殺されることです。かつて100Kだったのは今1Gを超えていますか?そして、その論理は変わらなかった。 –
何千もの頂点は実際には少量ですが、あなたのコードを再確認します。何か間違っていると思います。あなたのコードのいくつかを投稿できる場合は – elect