如果只是有顶点缓冲的话(即使有glDrawArray进行绘制),会存储顶点冗余。例如:显示一个矩形,要画2个三角形,每个三角形3个顶点,就要准备6个顶点传递到glDrawArray函数中。其实,画一个矩形只需要4个顶点就可以了,不是吗?
你可能认为,这有什么的?不就是多传递了2个顶点吗?其实不然,你现在只是画2个三角形,当你画一个吃鸡的场景时,里面的人物,地形,建筑,枪械等等,所有的物体都需要使用三角形进行绘制,如果存储顶点冗余的话,则会降低帧率。
为什么会降低帧率?因为在渲染的时候,顶点数据是从CPU发送到GPU进行顶点计算的,GPU的内存(显存)是十分宝贵的,想想现在的显卡卖多贵。所以,我们要利用有限的显存,绘制尽可能多的物体,且在运行的帧率范围内。
说了这么多,就是让你不要再使用glDrawArray了。当然,如果你画GUI的话,那无所谓。反正也没多少个点嘛。
ok。开始代码了。
修改Loader.java的代码,绑定索引缓存。
// 增加 int[] indices
public RawModel loadToVAO(float[] positions, int[] indices){
int vaoID = createVAO();
bindIndicesBuffer(indices);
//配置vao
storeDataInAttributesList(0, 3,positions);
unbindVAO();
return new RawModel(vaoID, indices.length);
}
// 增加绑定索引缓存函数
private void bindIndicesBuffer(int[] indices){
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
IntBuffer buffer = storeDataInIntBuffer(indices);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
}
// 替换Renderer.java中的render函数中的glDrawArray函数
//GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(),GL11.GL_UNSIGNED_INT,0);
// 测试
// 现在我们只需要4个顶点就够了
float[] positions = {
-0.5f,0.5f,0.0f,
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f,
0.5f,0.5f,0.0f
};
int []indices = {
0,1,3,
3,1,2
RawModel model = loader.loadToVAO(positions,indices);
运行效果和之前的一样。
ok。结束。
下篇预告:使用Shader。
欢迎大家关注我的公众号【OpenGL编程】,定期分享OpenGL相关的3D编程教程、算法、小项目。欢迎大家一起交流。