我想绘制一堆四边形。
现在我有问题;绘图工作正常,但很快,但我使用std :: vector作为我的四边形的容器,他们真的非常非常慢。来自XNA我想我应该创建类似spriteBatch的东西,这样我就可以调用DrawQuad()将给定的四边形添加到列表中,然后最后调用End()来绘制每个四边形。
我当前的代码通常会将这样的内容输出到控制台:
DrawQuad(): 77
End(): 0
一遍又一遍。
Main.cpp(sf :: Clock是SFML中的时钟类)
sf::Clock time;
for (int y = 0; y < 100; y++)
for (int x = 0; x < 100; x++)
renderer.DrawQuad("A", Vector2<GLfloat>(-1.0f + x * 0.02f, -1.0f + y * 0.02f));
std::cout << "DrawQuad(): " << time.getElapsedTime().asMilliseconds() << std::endl;
Renderer.cpp:
void TextRenderer::DrawQuad(string text, Vector2<GLfloat> position)
{
//TOP LEFT
vertexBufferVector.push_back(position.X);
vertexBufferVector.push_back(position.Y);
//TOP RIGHT
vertexBufferVector.push_back(position.X + 0.02f);
vertexBufferVector.push_back(position.Y);
//BOTTOM RIGHT
vertexBufferVector.push_back(position.X + 0.02f);
vertexBufferVector.push_back(position.Y + 0.02f);
//BOTTOM LEFT
vertexBufferVector.push_back(position.X);
vertexBufferVector.push_back(position.Y + 0.02f);
int elementCount = elementBufferVector.size() / 6;
elementBufferVector.push_back(elementCount * 4);
elementBufferVector.push_back(elementCount * 4 + 1);
elementBufferVector.push_back(elementCount * 4 + 2);
elementBufferVector.push_back(elementCount * 4 + 2);
elementBufferVector.push_back(elementCount * 4 + 3);
elementBufferVector.push_back(elementCount * 4);
}
void TextRenderer::End()
{
sf::Clock time;
GLfloat* vertexArray = &vertexBufferVector[0];
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertexBufferVector.size(), vertexArray, GL_STATIC_DRAW);
GLint* elementArray = &elementBufferVector[0];
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * elementBufferVector.size(), elementArray, GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLES, elementBufferVector.size(), GL_UNSIGNED_INT, 0);
vertexBufferVector.clear();
elementBufferVector.clear();
std::cout << "End(): " << time.getElapsedTime().asMilliseconds() << std::endl;
}
知道自己在做什么的人如何解决这个问题? 10000个四边形真的应该不是问题。
写完所有这些之后,我也将循环从(100,100)增加到(1000,100),现在绘图需要4-5毫秒,这被认为是好的吗?我在想不...
答案 0 :(得分:0)
由于这已经死了,我只会回答我的问题,也许它会对某人有所帮助。
我没有使用向量,而是使用了具有设置大小的数组。这使得100000四边形(也有纹理)的总渲染时间降至平均约3.260毫秒。
我的.h现在看起来像这样:
const int MAX_BUFFER_SIZE = 1000;
const int MAX_VERTEX_BUFFER_SIZE = MAX_BUFFER_SIZE * 16;
const int MAX_ELEMENT_BUFFER_SIZE = MAX_BUFFER_SIZE * 6;
...
GLint vertexBufferArrayInserts;
GLfloat vertexBufferArray[MAX_VERTEX_BUFFER_SIZE];
GLint elementBufferArray[MAX_ELEMENT_BUFFER_SIZE];
.cpp文件的相关部分:
void TextRenderer::DrawQuad(Vector2<GLfloat> position)
{
if(vertexBufferArrayInserts == MAX_BUFFER_SIZE)
End();
//TOP LEFT
vertexBufferArray[vertexBufferArrayInserts * 16] = position.X;
vertexBufferArray[vertexBufferArrayInserts * 16 + 1] = position.Y;
vertexBufferArray[vertexBufferArrayInserts * 16 + 2] = 0.0f;
vertexBufferArray[vertexBufferArrayInserts * 16 + 3] = 0.0f;
//TOP RIGHT
vertexBufferArray[vertexBufferArrayInserts * 16 + 4] = position.X + 16.0f;
vertexBufferArray[vertexBufferArrayInserts * 16 + 5] = position.Y;
vertexBufferArray[vertexBufferArrayInserts * 16 + 6] = 24.0f / 512.0f;
vertexBufferArray[vertexBufferArrayInserts * 16 + 7] = 0.0f;
//BOTTOM RIGHT
vertexBufferArray[vertexBufferArrayInserts * 16 + 8] = position.X + 16.0f;
vertexBufferArray[vertexBufferArrayInserts * 16 + 9] = position.Y + 16.0f;
vertexBufferArray[vertexBufferArrayInserts * 16 + 10] = 24.0f / 512.0f;
vertexBufferArray[vertexBufferArrayInserts * 16 + 11] = 32.0f / 512.0f;
//BOTTOM LEFT
vertexBufferArray[vertexBufferArrayInserts * 16 + 12] = position.X;
vertexBufferArray[vertexBufferArrayInserts * 16 + 13] = position.Y + 16.0f;
vertexBufferArray[vertexBufferArrayInserts * 16 + 14] = 0.0f;
vertexBufferArray[vertexBufferArrayInserts * 16 + 15] = 32.0f / 512.0f;
//ELEMENT BUFFER
elementBufferArray[vertexBufferArrayInserts * 6] = vertexBufferArrayInserts * 4;
elementBufferArray[vertexBufferArrayInserts * 6 + 1] = vertexBufferArrayInserts * 4 + 1;
elementBufferArray[vertexBufferArrayInserts * 6 + 2] = vertexBufferArrayInserts * 4 + 2;
elementBufferArray[vertexBufferArrayInserts * 6 + 3] = vertexBufferArrayInserts * 4 + 2;
elementBufferArray[vertexBufferArrayInserts * 6 + 4] = vertexBufferArrayInserts * 4 + 3;
elementBufferArray[vertexBufferArrayInserts * 6 + 5] = vertexBufferArrayInserts * 4;
vertexBufferArrayInserts++;
}
void TextRenderer::End()
{
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * vertexBufferArrayInserts * 16, vertexBufferArray);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(GLint) * vertexBufferArrayInserts * 6, elementBufferArray);
glDrawElements(GL_TRIANGLES, vertexBufferArrayInserts * 6, GL_UNSIGNED_INT, 0);
vertexBufferArrayInserts = 0;
}
这就是我计时的方式:
sf::Clock timer;
renderer.Begin(projMatrix);
for (int y = 0; y < 100; y++)
for(int x = 0; x < 1000; x++)
renderer.DrawQuad(Vector2<GLfloat>(16.0f * x, 16.0f * y));
renderer.End();
avgDrawTime += timer.getElapsedTime().asMicroseconds();
drawCalls++;
if(drawCalls % 100 == 0)
std::cout << avgDrawTime / drawCalls << std::endl;