(C++) OpenGL 渲染瓦片映射会导致丢帧
(C++) OpenGL renderering tilemap causes framedrops
我正在使用OpenGL绘制当前由50 x 50图块组成的大型图块地图。我正在使用GLFW,GLEW和GLM来处理大多数OpenGL功能。当我尝试绘制地图时,它只会以大约 30 fps 的速度渲染,而不是以 1000+ fps 的速度绘制一个对象。即使我为每个瓷砖绘制一种颜色而不是纹理,也是如此。为了绘制我在地图上循环绘制的瓷砖并绘制对单个 VBO 应用转换,诸如此类的答案似乎暗示即使这不是渲染大量项目的最有效方法,我仍然应该能够获得不错的帧速率。我不知道如何在不减少正在绘制的瓷砖数量的情况下提高帧速率。以下是绘制瓷砖的相关代码:
绘制磁贴的代码(称为每帧(:
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,因此您应该使用着色器并绑定一次 VAO(在两个循环之前(。这应该确实可以提高您的表现。
为了更进一步,我再次命令您查看函数glDrawArraysInstanced,它允许仅使用一次绘制调用来绘制所有瓷砖。
您需要将所有模型矩阵传递给着色器(通过纹理或着色器存储缓冲区,具体取决于您面向的 OpenGL 版本(,并使用gl_InstanceID来检索矩阵。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 将函数类成员映射到类本身内部
- 如何在 C# 中映射双 C 结构指针?
- 如何在C++中使用结构生成映射
- 使用std::函数映射对象方法
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- C++映射分割错误(核心转储)
- 内联映射初始化的动态atexit析构函数崩溃
- 使用"std::unordereded_map"映射到"std::list"对象
- 如何从多映射中删除特定的重复项
- 在未初始化映射的情况下,将值插入到映射的映射中
- QT通过C++添加映射QML项目
- 在c++中访问int到类对象的映射时出错
- 在C++中搜索嵌套多映射值
- 错误处理.将系统错误代码映射到泛型
- C++匿名结构作为std::映射值
- 如何从存储在std::映射中的std::集中删除元素
- 递归无序映射
- 正在VS调试器中监视映射条目