【发布时间】:2019-01-11 00:38:46
【问题描述】:
我正在尝试为基于 2D 瓦片的游戏开发地图,我使用的方法是将地图图像保存在大纹理(瓦片集)中,并通过更新位置仅在屏幕上绘制所需的瓦片通过顶点着色器,然而在10x10的地图上涉及100个glDrawArrays调用,通过任务管理器查看,这消耗了5%的CPU使用率和4~5%的GPU,想象一下如果它是一个有几十个调用的完整游戏,有一个优化这一点的方法,例如准备整个场景并只进行 1 次绘制调用、一次绘制全部或其他方法?
void GameMap::draw() {
m_shader - > use();
m_texture - > bind();
glBindVertexArray(m_quadVAO);
for (size_t r = 0; r < 10; r++) {
for (size_t c = 0; c < 10; c++) {
m_tileCoord - > setX(c * m_tileHeight);
m_tileCoord - > setY(r * m_tileHeight);
m_tileCoord - > convert2DToIso();
drawTile(0);
}
}
glBindVertexArray(0);
}
void GameMap::drawTile(GLint index) {
glm::mat4 position_coord = glm::mat4(1.0 f);
glm::mat4 texture_coord = glm::mat4(1.0 f);
m_srcX = index * m_tileWidth;
GLfloat clipX = m_srcX / m_texture - > m_width;
GLfloat clipY = m_srcY / m_texture - > m_height;
texture_coord = glm::translate(texture_coord, glm::vec3(glm::vec2(clipX, clipY), 0.0 f));
position_coord = glm::translate(position_coord, glm::vec3(glm::vec2(m_tileCoord - > getX(), m_tileCoord - > getY()), 0.0 f));
position_coord = glm::scale(position_coord, glm::vec3(glm::vec2(m_tileWidth, m_tileHeight), 1.0 f));
m_shader - > setMatrix4("texture_coord", texture_coord);
m_shader - > setMatrix4("position_coord", position_coord);
glDrawArrays(GL_TRIANGLES, 0, 6);
}
--Vertex Shader
#version 330 core
layout (location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords>
out vec4 TexCoords;
uniform mat4 texture_coord;
uniform mat4 position_coord;
uniform mat4 projection;
void main()
{
TexCoords = texture_coord * vec4(vertex.z, vertex.w, 1.0, 1.0);
gl_Position = projection * position_coord * vec4(vertex.xy, 0.0, 1.0);
}
-- Fragment Shader
#version 330 core
out vec4 FragColor;
in vec4 TexCoords;
uniform sampler2D image;
uniform vec4 spriteColor;
void main()
{
FragColor = vec4(spriteColor) * texture(image, vec2(TexCoords.x, TexCoords.y));
}
【问题讨论】:
-
"在 10x10 地图上涉及 100 个 glDrawArrays 调用" 为什么?根据您的描述,您将所有图像放在同一个纹理中,因此尽管您的问题标题谈论“大量纹理”,但似乎没有理由不能在一次绘制调用中绘制所有图块.你在这些绘图调用之间做什么?
-
是否有纹理(图像)并且我正在更改顶点的位置以在每次绘图调用中一次绘制一个部分:“m_shader-> setMatrix4 ("position_coord", matrix_translations1); m_shader-> setMatrix4 ("texture_coord", matrix_translations2); glDrawArrays (GL_TRIANGLES, 0, 6);"
-
首先,将该信息连同相关代码的所有 放在您的问题中。其次,你为什么要为 2D quads 使用这样的矩阵?
-
我正在关注learnopengl系列教程,我使用了讨论矩阵变换的部分来应用于二维地图并更改图块的位置