2013-11-29 2 views
1

그리드를 렌더링하는 데 두 가지 방법이 있습니다. 하나의 제 : 하나코드 조각 실행 속도 향상

void Grid::openglRender(){ 
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
    glBegin(GL_TRIANGLES); 
    glColor3f(1.0f, 1.0f, 0.0f); 
    Node* A, * B, * C, * D; 
    for(size_t X=0 ; X<sizeX-1 ; X++)for(size_t Z=0 ; Z<sizeZ-1; Z++){ 
    A = &nodes[X*sizeZ+Z]; 
    B = &nodes[(X+1)*sizeZ+Z]; 
    C = &nodes[X*sizeZ+(Z+1)]; 
    D = &nodes[(X+1)*sizeZ+(Z+1)]; 
    glVertex3f(A->x, A->y, A->z); 
    glVertex3f(B->x, B->y, B->z); 
    glVertex3f(C->x, C->y, C->z); 

    glVertex3f(B->x, B->y, B->z); 
    glVertex3f(D->x, D->y, D->z); 
    glVertex3f(C->x, C->y, C->z); 
    } 
    glEnd(); 
}; 

둘째 :

void Grid::openglRender(){ 
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
    glBegin(GL_TRIANGLES); 
    glColor3f(1.0f, 1.0f, 0.0f); 
    for(size_t X=0 ; X<sizeX-1 ; X++)for(size_t Z=0 ; Z<sizeZ-1; Z++){ 
    glVertex3f(nodes[X*sizeZ+Z].x, nodes[X*sizeZ+Z].y, nodes[X*sizeZ+Z].z); 
    glVertex3f(nodes[(X+1)*sizeZ+Z].x, nodes[(X+1)*sizeZ+Z].y, nodes[(X+1)*sizeZ+Z].z); 
    glVertex3f(nodes[X*sizeZ+(Z+1)].x, nodes[X*sizeZ+(Z+1)].y, nodes[X*sizeZ+(Z+1)].z); 

    glVertex3f(nodes[(X+1)*sizeZ+Z].x, nodes[(X+1)*sizeZ+Z].y, nodes[(X+1)*sizeZ+Z].z); 
    glVertex3f(nodes[(X+1)*sizeZ+(Z+1)].x, nodes[(X+1)*sizeZ+(Z+1)].y, nodes[(X+1)*sizeZ+(Z+1)].z); 
    glVertex3f(nodes[X*sizeZ+(Z+1)].x, nodes[X*sizeZ+(Z+1)].y, nodes[X*sizeZ+(Z+1)].z); 
    } 
    glEnd(); 
}; 

나를 위해 첫 번째는, 작업의 수의 용어에 더 잘 보이는 glVertex3f에 난 그냥 값을 얻기 위해 포인터를 사용합니다. 두 번째 방법에서는 곱할 필요가있을 때마다 무언가를 추가해야합니다.

그러나 실행 시간에 나는 실제로 차이를 느끼지 않습니다. 그래서 나는 처음이 더 낫다고 말할 때 맞습니까? 아니면 내가 컴파일러를 가입시 선택하신 나는 특히 선언과 파괴를 방지하기 위해 for 루프 전에 XZ를 선언하는 경우

은 어쩌면 조금 더 나은 것 ... 최선을하려면 어떻게 내가보다 더 잘 알고 Z의 sizeX 시간은

또한 나는 최고의 두 for

을 사용하는 대신 격자를 만들 이송 될 순서대로 모든 노드 (모든 프레임을 다시 사용할 수 RO 저장 한 시간) 목록을 작성하는 것, 생각
+2

'glVertex3f (...)'*** far ***의 호출 오버 헤드가이 문제에서 던질 수있는 멋진 바지 포인터 산술 해킹을 능가 할 가능성이 있습니다. 이와 같이 즉각적인 모드를 마이크로 최적화하는 것은 사실상 의미가 없습니다. 인덱싱 된 버텍스 배열로 전환하고 더 나은 시간을 소비하도록 호출해야합니다. 그러나 만약 당신이''glVertex3fv (... )'를 다른 마이크로 최적화를 위해 던집니다. 당신이 주장한다면, 당신은이 악몽을 더 오래 지속시킬 수 있습니다. –

+0

@ AndonM.Coleman은 정직한 배열을 사용하지 않았기 때문에 좋은 소리를 들었습니다. 그래서 그 코드를 작성할 때 생각조차하지 않았습니다. 나는 몇몇 책에서 그들에 대해 거의 읽지 않았다. 나는 라이브러리 tomorow –

답변

1
A = &nodes[X*sizeZ+Z]; 
B = &nodes[(X+1)*sizeZ+Z]; 
C = &nodes[X*sizeZ+(Z+1)]; 
D = &nodes[(X+1)*sizeZ+(Z+1)]; 

A = &nodes[X * sizeZ + Z]; 
B = A + sizeZ; 
C = A + 1; 
D = B + 1; 

이 될 수 있으며 이는 작업 수를 상당히 줄여 줄뿐만 아니라 노드의 관계를 좀 더 분명하게 만듭니다. 컴파일러가 얼마나 똑똑한 지, 그리고 그런 종류의 최적화 자체를 수행 할 수 있는지 여부는 알지 못합니다. 그러나 대체물이 더 명확 할 때 왜 그렇게해야 하는가?

(여기 조기 최적화에 대한 필수 경고입니다. 당신도 둘 사이의 차이를 알아 차리지하지 않는 경우, 다음은 마이크로 최적화 걱정하기에 너무 이르다.) 당신이 코드의 조각 아무튼 최적화해서

+0

에서 이것에 관해 더 많이 읽을 것이다. 나는 이것을 재사용 할 것을 좋아한다. –

0

항상 더 나은 런타임 성능을 보게 될 것입니다. 런타임 성능을 어떻게 측정하고 있습니까? 두 for 루프 내의 반복 횟수에 따라 반복 횟수가 충분하지 않으면 차이가 표시되지 않을 수도 있습니다. sizeX 및 sizeZ의 실제 값은 얼마입니까?

+0

실제로 나의 목표는 더 효율적으로 쓰기위한 몇 가지 요령을 얻는 것이다. 나는 런타임을 측정하고 있지 않다. –

+1

깨끗하고 효율적인 코드를 작성하는 것은 항상 좋은 일이지만 "조기 최적화"라는 함정에 빠지지 않도록주의하십시오. 즉, 그렇게하지 않아도 모든 종류의 코드 최적화를 수행해야합니다. . 실제로 어떤 종류의 최적화를하는지에 따라 코드가 다른 사람에게 명확하지 않게되는 경우도 있습니다. – Andrew

+0

예, 이미 좀 더 나은 것을 얻으려고 시간을 낭비합니다. 나는 항상 어린 선생님이 어렸을 때 내게 말한 것을 생각 나게합니다.«최고는 선의 모범입니다»(프랑스에서 번역 됨) –

0

이러한 호출은 더 이상 사용되지 않으며 프로그램이 느리게 실행되는 이유 중 하나입니다. 대신 VBO와 쉐이더를 조사해야합니다!

+0

오렌지 책 (쉐이더)을 읽고 있는데, 셰이더로 작성해야하며 C++로 작성해야하는 것은 셰이더가 GPU를 사용한다는 것을 알고 있으므로 그래픽과 관련된 모든 것이 셰이더에 기록되어야하는지 스스로에게 묻습니다. –

+0

@bobthemightyspellcaster : 아니요, 동적 계산에 사용되는 것만이 셰이더에 속합니다. 로드 타임에 한 번만 수행해야하는 많은 작업이 있습니다. 셰이더에 들어가기 전에 OpenGL 파이프 라인의 단계를 연구 해보길 강력히 제안합니다. 셰이더는 실제로 GPU에서 실행되고 파이프 라인의 특정 스테이지에 대한 출력을 계산하는 소형 프로그램입니다 (예 : 버텍스 변환 스테이지 = 버텍스 셰이더, 프리미티브 어셈블리 스테이지 = 기하학적 셰이더, 래스터 화 스테이지 = 프래그먼트 셰이더). 일단 파이프 라인의 흐름을 이해하면 쉐이더가 더 이해가됩니다. –

+0

@bobthemightyspellcaster : 자세한 내용은 [이 기사] (http://www.opengl.org/wiki/Rendering_Pipeline_Overview)를 참조하십시오. –