2013-04-07 2 views
1

묶음 사각형을 그려야합니다.OpenGL에서 정점/요소 목록으로 std :: vector 사용

지금은 문제가 있습니다. 드로잉은 훌륭하게 작동하지만 빠르지 만 표준을 사용하고 있습니다. : 벡터를 내 쿼드 컨테이너로 사용하면 정말 느립니다. XNA에서 나는 SpriteBatch와 같은 것을 만들어서 DrawQuick()을 호출하여 주어진 쿼드를 목록에 추가 한 다음 End()를 호출하여 모든 쿼드를 그릴 수 있도록해야한다고 생각했습니다.

DrawQuad(): 77 
End(): 0 

또 다시 :

내 현재 코드는 일반적으로 콘솔에 이런 식으로 뭔가를 인쇄합니다.

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; 
} 

어떻게 그들이 무슨 일을하는지 아는 사람이이 문제를 해결 않습니다

하여 Main.cpp

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 (SF : 시계 SFML의 시계 클래스입니다)? 10000 개의 쿼드는 실제로 문제가되어서는 안됩니다.

이 모든 것을 쓰고 나면 (100, 100)에서 (1000, 100)으로 루핑을 늘렸고 이제 드로잉에 4-5 밀리 초가 걸렸습니다. 나는 아무 생각도하지 않고있다. ...

+0

을 4ms는 약 250fps입니다. 너무 느린가요? –

+0

나는 DrawQuad에 주어진 "A"인수에 대해 논평해야한다. 처음 엔 텍스트를 그릴 수있는 무언가를 만들고 싶었지만 이것으로 시작했다. 로저 : 몰라요. 그래서 제가 물었습니다. 그러나 DrawQuad를 호출하는 데 800ms가 걸리므로 많은 시간이 너무 많습니다 – Semicolon

+0

100k 쿼드에 대해 4-5ms는 모든 프레임에 대해 버텍스 배열을 다시 작성한다고 생각하면 좋습니다. OpenGL은 내용을 변경하지 않는 한 훨씬 빠르게 작동하는 정적 정점 버퍼를 만드는 방법이 있어야합니다. – riv

답변

0

이것은 죽었 기 때문에 나는 단지 내 질문에 답하고 누군가를 도울 것이다.

벡터를 사용하는 대신 크기가 설정된 배열을 사용했습니다. 이로 인해 텍스쳐가있는 100,000 개의 쿼드에 대한 총 렌더링 시간이 평균 ~ 3.260ms로 줄어 들었습니다.

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 파일의 관련 부분 :

내 .H는 이제 다음과 같습니다

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;