我试图在游戏中使用VBO和VAO编辑3D网格中的顶点,所以我可以制作一个自定义的地形编辑器,然后保存以加载到我的真实游戏中。
我创建了一个Mesh类,它创建了VBO并且还有内存分配(在另一个类中)
我真的只需要在Y轴上向上或向下移动顶点并保持x和z相同。
public Mesh(float[] positions, float[] textCoords, float[] normals, int[] indices, int[] jointIndices, float[] weights) {
FloatBuffer posBuffer = null;
FloatBuffer textCoordsBuffer = null;
FloatBuffer vecNormalsBuffer = null;
FloatBuffer weightsBuffer = null;
IntBuffer jointIndicesBuffer = null;
IntBuffer indicesBuffer = null;
try {
vertexCount = indices.length;
vboIdList = new ArrayList();
vaoId = glGenVertexArrays();
glBindVertexArray(vaoId);
// Position VBO
int vboId = glGenBuffers();
vboIdList.add(vboId);
posBuffer = MemoryUtil.memAllocFloat(positions.length);
posBuffer.put(positions).flip();
VBOBuffer = posBuffer; // Save position buffer to edit later??
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, posBuffer, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
// Texture coordinates VBO
vboId = glGenBuffers();
vboIdList.add(vboId);
textCoordsBuffer = MemoryUtil.memAllocFloat(textCoords.length);
textCoordsBuffer.put(textCoords).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, textCoordsBuffer, GL_STATIC_DRAW);
glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0);
// Vertex normals VBO
vboId = glGenBuffers();
vboIdList.add(vboId);
vecNormalsBuffer = MemoryUtil.memAllocFloat(normals.length);
vecNormalsBuffer.put(normals).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, vecNormalsBuffer, GL_DYNAMIC_DRAW);
glVertexAttribPointer(2, 3, GL_FLOAT, false, 0, 0);
// Weights
vboId = glGenBuffers();
vboIdList.add(vboId);
weightsBuffer = MemoryUtil.memAllocFloat(weights.length);
weightsBuffer.put(weights).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, weightsBuffer, GL_DYNAMIC_DRAW);
glVertexAttribPointer(3, 4, GL_FLOAT, false, 0, 0);
// Joint indices
vboId = glGenBuffers();
vboIdList.add(vboId);
jointIndicesBuffer = MemoryUtil.memAllocInt(jointIndices.length);
jointIndicesBuffer.put(jointIndices).flip();
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, jointIndicesBuffer, GL_DYNAMIC_DRAW);
glVertexAttribPointer(4, 4, GL_FLOAT, false, 0, 0);
// Index VBO
vboId = glGenBuffers();
vboIdList.add(vboId);
indicesBuffer = MemoryUtil.memAllocInt(indices.length);
indicesBuffer.put(indices).flip();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
} finally {
if (posBuffer != null) {
MemoryUtil.memFree(posBuffer);
}
if (textCoordsBuffer != null) {
MemoryUtil.memFree(textCoordsBuffer);
}
if (vecNormalsBuffer != null) {
MemoryUtil.memFree(vecNormalsBuffer);
}
if (weightsBuffer != null) {
MemoryUtil.memFree(weightsBuffer);
}
if (jointIndicesBuffer != null) {
MemoryUtil.memFree(jointIndicesBuffer);
}
if (indicesBuffer != null) {
MemoryUtil.memFree(indicesBuffer);
}
}
}
我尝试过使用这种方法..
public void updateVBOData(Vector3f[] vertices, int vbo) {
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferSubData(GL_ARRAY_BUFFER, 0, updateFlippedBuffer(VBOBuffer, vertices)); //replace data in VBO with new data
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
public static FloatBuffer updateFlippedBuffer(FloatBuffer buffer, Vector3f[] vectors) {
buffer.clear();
for(int i = 0; i < vectors.length; i ++)
{
buffer.put(vectors[i].x);
buffer.put(vectors[i].y);
buffer.put(vectors[i].z);
}
buffer.flip();
return buffer;
}
我有一个带鼠标的游戏物品(网格)选择器,我在代码中添加了当我按下键盘时运行方法updateVBOData,但没有任何反应.. 这样的事情。
int vbo = gameItems[i].getMesh().getVaoId();
gameItems[i].getMesh().updateVBOData(vertices, vbo);
也许它与我如何呈现?
有关protected void initRender() {
Texture texture = material != null ? material.getTexture() : null;
if (texture != null) {
// Activate first texture bank
glActiveTexture(GL_TEXTURE0);
// Bind the texture
glBindTexture(GL_TEXTURE_2D, texture.getId());
}
Texture normalMap = material != null ? material.getNormalMap() : null;
if (normalMap != null) {
// Activate second texture bank
glActiveTexture(GL_TEXTURE1);
// Bind the texture
glBindTexture(GL_TEXTURE_2D, normalMap.getId());
}
// Draw the mesh
glBindVertexArray(getVaoId());
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
}
protected void endRender() {
// Restore state
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(3);
glDisableVertexAttribArray(4);
glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
}
public void render() {
initRender();
glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);
endRender();
}
public void renderList(List<GameItem> gameItems, Consumer<GameItem> consumer) {
initRender();
for (GameItem gameItem : gameItems) {
if (gameItem.isInsideFrustum()) {
// Set up data requiered by gameItem
consumer.accept(gameItem);
// Render this game item
glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);
}
}
endRender();
}
先谢谢!