我正在开发一个供个人使用的小型2D图形/游戏库,目前我正在尝试一种在绘制平铺地图时提高性能的方法。目前,我正在为地图中的每个图块创建一个静态GL_QUADS VBO,然后将其绘制到屏幕上。每个VBO都引用一个加载到内存中的纹理,该纹理被子图像化并映射到VBO。
目前,我正在测试一张20 x 20的瓷砖地图。在我当前的实现中,因为我必须绘制每个单独的tile,即每帧400 glDraw *调用。
有没有办法,例如,使瓷砖地图的每一行都是一个VBO?对于此示例,这会将glDraw *调用减少到20。我如何映射子图像?单个瓷砖可以旋转。
我见过一些使用纹理图集的参考资料。这会是一个很好的选择吗?关于如何在opengl中实现它的任何有用链接?
CODE:
当前渲染方法:
public void render() {
texture.bind();
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
for (SpriteSheet spriteSheet : spriteSheets) {
VBO vbo = spriteSheet.getVBO();
float angle = spriteSheet.getAngle();
vbo.bind();
if (angle != 0) {
glPushMatrix();
Vector2f position = spriteSheet.getPosition();
glTranslatef(position.x, position.y, 0);
glRotatef(angle, 0.0f, 0.0f, 1);
glTranslatef(-position.x, -position.y, 0);
glVertexPointer(Vertex.positionElementCount, GL_FLOAT, Vertex.stride, Vertex.positionByteOffset);
glColorPointer(Vertex.colorElementCount, GL_FLOAT, Vertex.stride, Vertex.colorByteOffset);
glTexCoordPointer(Vertex.textureElementCount, GL_FLOAT, Vertex.stride, Vertex.textureByteOffset);
glDrawArrays(vbo.getMode(), 0, Vertex.elementCount);
glPopMatrix();
}
else {
glVertexPointer(Vertex.positionElementCount, GL_FLOAT, Vertex.stride, Vertex.positionByteOffset);
glColorPointer(Vertex.colorElementCount, GL_FLOAT, Vertex.stride, Vertex.colorByteOffset);
glTexCoordPointer(Vertex.textureElementCount, GL_FLOAT, Vertex.stride, Vertex.textureByteOffset);
glDrawArrays(vbo.getMode(), 0, Vertex.elementCount);
}
vbo.unbind();
}
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
texture.unbind();
}
答案 0 :(得分:1)
你可以做几件事。
纹理图集一个选项,但您也可以使用GL_TEXTURE_2D_ARRAY
,使用第三个纹理坐标选择要使用的图层。
接下来要考虑的是 instancing :在缓冲区中有一个四边形并使OpenGL绘制几次,使用额外的缓冲区根据绘制的实例选择纹理图层和旋转。