我目前正在使用LWJGL编写一个用Java 1.6编写的2d自上而下的RPG.我在我的游戏中实现了VBO的使用,现在我维护了两个:一个用于顶点数据,一个用于纹理坐标.
这一切都很好,除了我还没有一个真正合理的方式更新对象.作为一个例子,如果我想要一个特定的瓷砖来改变它的纹理(改变VBO内部的纹理坐标以显示纹理图纸的另一个区域),我看不到只改变对应的纹理坐标的方法这个单一的瓷砖.我现在所能想到的可能是填充每个循环所需的所有数据的缓冲区,并且每帧都使用glBufferData上传它们.它工作但似乎不是最好的方式(或它呢?).
现在,有glBufferSubData命令,它不会分配新的内存,只会改变我告诉它改变的部分.问题是我不知道如何跟踪必须改变的区域(偏移).LWJGL提供glBufferSubData(目标,偏移,数据); 命令,只需要缓冲区的开始工作.偏移是否像索引?
因此,如果我首先将这些缓冲区上传到VBO,然后想要更改第二个float []的第二个值:
FloatBuffer vertexData = BufferUtils.createFloatBuffer(amountOfVertices * vertexSize);
vertexData.put(new float[]{100, 100, 300, 100, 300, 300, 100, 300});
vertexData.put(new float[]{400, 100, 600, 100, 600, 300, 400, 300});
vertexData.flip();
Run Code Online (Sandbox Code Playgroud)
我将生成新数据,将其放在一个小的FloatBuffer中并使用glBufferSubData(GL_VERTEX_ARRAY,10,newFloatBuffer)上传; 10是因为我想从第十个旧值改变值.
是对的吗?有没有更好的方法呢?再说一遍:如果我每帧重新上传整个数据,这样可以吗?
LWJGL glBufferSubData()期望将偏移量作为字节数,因为应该能够将任意数据写入任意缓冲区位置.如果你想在索引处更新浮点数i,那么i * 4自从java浮点数以来,偏移量将是非常常见的4个字节.将写入所有剩余的缓冲区内容,因此,目标缓冲区需要具有至少(i + floatBuffer.remaining()) * 4字节的容量.有关正确的准备,请参阅Buffers flip()方法或使用position(int)和limit(int)来指定要写入的剩余内容.
只要不使用临时FloatBuffers多次调用glBufferSubData(),此更新策略就可以了.您还可以使用相同大小的第二个目标缓冲区进行交换(乒乓),其中一个可以映射MapBuffer()用于整体更新,而另一个正在使用中.
我宁愿在客户端持有一个完整的FloatBuffer并立即上传,glBufferData()而不是glBufferSubData()多次调用.但不知道一些数字,很难说.