gpt4 book ai didi

c++ - (C++) tilemap 中的 OpenGL 渲染器导致丢帧

转载 作者:行者123 更新时间:2023-12-01 14:52:40 26 4
gpt4 key购买 nike

我正在使用 OpenGL 绘制当前由 50 x 50 瓦片组成的大型瓦片图。我正在使用 GLFW、GLEW 和 GLM 来处理大多数 OpenGL 函数。当我尝试绘制 map 时,它只会以大约 30 fps 的速度渲染,而不是以 1000+ fps 的速度绘制一个对象。即使我为每个图 block 而不是纹理绘制单一颜色也是如此。为了绘制我在 map 中循环并绘制的图 block ,将转换应用于单个 VBO,如 this 的答案似乎暗示即使这不是渲染大量项目的最有效方法,我仍然应该能够获得不错的帧速率。我不知道如何在不减少我正在绘制的图 block 数量的情况下增加我的帧速率。这是绘制瓷砖的相关代码:

绘制瓷砖的代码(每帧调用):

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,因此我的计算机应该能够轻松渲染此数量的对象。
我画瓷砖的方式有问题吗?或者以这种方式绘制这么多的对象不是绘制瓷砖的可行方式?

最佳答案

首先,由于每次绘制都使用相同的着色器和相同的 VAO,因此您应该使用着色器并绑定(bind)一次 VAO(在两个循环之前)。这应该真正提高你的表现。

为了更进一步,我建议您查看函数 glDrawArraysInstanced,它允许仅通过一次绘制调用绘制所有图 block 。

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

关于c++ - (C++) tilemap 中的 OpenGL 渲染器导致丢帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61879302/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com