((C ++)OpenGL渲染tilemap导致帧丢失

问题描述 投票:0回答:1

我正在使用OpenGL绘制一个大的瓦片地图,当前由50 x 50瓦片组成。我正在使用GLFW,GLEW和GLM处理大多数OpenGL函数。当我尝试绘制地图时,它只能以约30 fps的速度渲染,而不是以1000+ fps的速度绘制一个对象。即使我为每个图块都绘制一种颜色而不是纹理。为了绘制图块,我遍历了地图并绘制了对单个VBO的转换,诸如this之类的答案似乎暗示,即使这不是渲染大型项目组的最有效方法,我仍然应该能够获得体面的帧率。我无法弄清楚如何在不减少要绘制的图块数量的情况下提高帧速率。这是绘制磁贴的相关代码:

绘制图块的代码(称为每帧):

for (int i = 0; i < map.getWidth(); i++) {
    for (int j = 0; j < map.getHeight(); j++) {
        renderer->drawSprite(glm::vec2(i * tilesize, j * tilesize), glm::vec2(tilesize, tilesize));
    }
}

渲染器代码:

Renderer(Shader& shader) {
    this->shader = shader;
    GLuint VBO;

    GLfloat vertices[] = {
        0.0f, 1.0f, 0.0f, 1.0f,
        0.0f, 0.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 1.0f, 0.0f
    };
    glGenVertexArrays(1, &this->quadVAO);
    glGenBuffers(1, &VBO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindVertexArray(this->quadVAO);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (GLvoid*)0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

void drawSprite(int spritex, int spritey, glm::vec2 position, glm::vec2 size = glm::vec2(10, 10), GLfloat rotate = 0.0f, glm::vec3 color = glm::vec3(1.0f)) {
    this->shader.use();
    //model transformations

     this->shader.setMat4("model", model);
     glBindVertexArray(this->quadVAO);
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
     glBindVertexArray(0);
}

顶点着色器:

#version 460 core
in vec2 TexCoords; //currently not used since I'm trying to draw colors
out vec4 color;

void main() {    
    color = vec4(1.0, 0.5, 0.5, 1.0);
}  

片段着色器:

#version 460 core
layout (location = 0) in vec4 vertex; // <vec2 position, vec2 texCoords>

out vec2 TexCoords;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main() {
    TexCoords = vertex.zw;
    gl_Position = projection * view * model * vec4(vertex.xy, 0.0, 1.0);
}

glGetString(GL_RENDERER)返回程序正在使用我的gtx 1070,因此我的计算机应该可以轻松渲染此数目的对象。我绘制瓷砖的方式有问题吗?还是以这种方式绘制这么多的对象不是绘制瓷砖的可行方法?

c++ opengl 2d shader
1个回答
0
投票

首先,由于每个绘图使用相同的着色器和相同的VAO,因此应使用着色器并将VAO绑定一次(在两个循环之前)。这确实可以改善您的性能。

为了进一步讲解,我建议您查看函数glDrawArraysInstanced,该函数只用一个绘制调用就可以绘制所有图块。

您将需要将所有模型矩阵传递给着色器(通过纹理或着色器存储缓冲区,具体取决于要定位的OpenGL版本,并使用gl_InstanceID检索矩阵。

© www.soinside.com 2019 - 2024. All rights reserved.