2013-04-07 73 views
1

我想繪製一堆四邊形。使用std :: vector作爲頂點/元素列表與OpenGL

現在我有一個問題;繪圖工作正常,速度很快,但我使用std :: vector作爲我的四邊形容器,他們真的很慢。來自XNA我想我應該創建類似spriteBatch的東西,以便我可以調用DrawQuad()將給定的四元組添加到列表中,最後調用End()來繪製每個四元組。

我當前的代碼通常打印這樣的控制檯:

DrawQuad(): 77 
End(): 0 

一遍又一遍。

Main.cpp的(SF ::時鐘是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

4ms約爲250 fps,是不是太慢了? – 2013-04-07 19:14:47

+0

我應該評論給DrawQuad的「A」論點:起初我想製作一些可以繪製文字的東西,但是我從這開始,所以它就在那裏。 Roger:我不知道......這就是爲什麼我問。但是調用DrawQuad多次所需要的800ms太多了 – Semicolon 2013-04-07 19:15:37

+0

對於100k四元組,4-5ms是可以的,因爲您正在爲每一幀重新創建頂點數組。 OpenGL應該有一種方法來創建一個靜態頂點緩衝區,只要不改變它的內容,它的運行速度會更快。 – riv 2013-04-07 19:24:16

回答

0

既然這已經死了,我就回答我的問題,也許它會幫助別人。

而不是使用矢量我訴諸使用具有設置大小的數組。這使得100000個四邊形(紋理以及)的總渲染時間降至平均3.260ms。

我的.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; 
相關問題