2009-11-05 3 views
3

this paper을 구현하려고합니다. 나는 그것의 대부분을 가지고 있지만, 기하학적 인 모서리를 결정하고 표시하는데 사용하기 위해 임의의 비 기하 데이터를 쉐이더에 보내는 것에 관한 부분이 나에게 문제를 일으킨다. VBO에 대해 알고있는 것을 사용하여 대부분의 데이터를 정상적으로 성공적으로 보낼 수있었습니다. 그러나 많은 양의 데이터를 전송해야하므로 여러 개의 텍스처 좌표가 필요합니다.데이터 쉐이더와 함께 사용하기 위해 OpenGL 인덱싱 된 버퍼 배열에서 여러 텍스처를 어떻게 처리합니까?

저는 이미 여러 세트의 텍스처 좌표를 설정하는 올바른 방법이라고 생각되는 여러 변형을 구현했으며 많은 포럼 포스터의 지침을 따랐습니다. 지금까지는 해결책이 없습니다.

컨텍스트의 경우 프로그램에서 모델의 각 고유 한 가장자리에 대해 4 개의 정점 집합, 2 개의 법선 벡터, 부동 소수점 및 정수 (부동 소수점으로 저장된)의 4 개의 거의 동일한 복사본을 보냅니다. 나는이 같은 데이터를 배치했습니다

v0 is stored in gl_Vertex (vec3) 
v1 is stored in gl_Color (vec3) 
v2 is stored in gl_MultiTexCoord0 (vec3) 
v3 is stored in gl_MultiTexCoord1 (vec3) 
n0 is stored in gl_Normal (vec3) 
n1 is stored in gl_SecondaryColor (vec3) 
r and i are stored in gl_MultiTexCoord2 (vec2) 

4 개 복사본 사이의 유일한 차이점은 언제 그릴 수 가장자리가 발견되면 정점을 구성하는 방법을 결정하는 데 도움이 난 값입니다.

보시다시피, 적어도 3 개의 텍스처 좌표가 필요합니다. 첫 번째 작업 (gl_MultiTexCoord0)을 정상적으로 처리 할 수 ​​있었지만 그래픽 카드의 다음 텍스처 좌표는 제어 할 수없는 동작 (때때로 작동하지만 일반적으로 그렇지 않은 것)이있는 것처럼 보입니다. 같이하는 데 사용

내 렌더링 기능 :

void Mesh::RenderLineEdgesGPU() 
{ 
    // Enable client state 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_NORMAL_ARRAY); 
    glEnableClientState(GL_COLOR_ARRAY); 
    glEnableClientState(GL_SECONDARY_COLOR_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    // Turn on edge shader 
    edgeProgram.Activate(); 

    // Link buffers 
    // v0 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[0]); 
    glVertexPointer(3, GL_FLOAT, 0, 0); 

    // v1 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[1]); 
    glColorPointer(3, GL_FLOAT, 0, 0); 

    // v2 
    glClientActiveTextureARB(GL_TEXTURE0_ARB); 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[2]); 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); 

    // v3 
    glClientActiveTextureARB(GL_TEXTURE1_ARB); 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[3]); 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); 

    // n0 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[4]); 
    glNormalPointer(GL_FLOAT, 0, 0); 

    // n1 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[5]); 
    glSecondaryColorPointer(3, GL_FLOAT, 0, 0); 

    // r and i 
    glClientActiveTextureARB(GL_TEXTURE2_ARB); 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[6]); 
    glTexCoordPointer(2, GL_FLOAT, 0, 0); 

    // Indicies 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, edgeMeshHandles[7]); 

    // Draw 
    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0); 

    // Turn off edge shader 
    edgeProgram.Deactivate(); 

    // Disable client state 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_NORMAL_ARRAY); 
    glDisableClientState(GL_COLOR_ARRAY); 
    glDisableClientState(GL_SECONDARY_COLOR_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
} 

이 내 원래 하나였다. 확실히 v0, v1 및 v2에서 작동합니다. 그것은 "r과 i"에서 효과가있는 것처럼 보입니다.하지만 그것은 환상 일 수 있습니다. 아직 n0 또는 n1을 테스트 할 능력이 없습니다. v3은 확실히 작동하지 않습니다. 보시다시피, 저는 그것들을 포인트로 그리기 때문에, 거기에 있는지 없는지 (쉐이더를 통해) 알려줍니다. v0, v1 및 v2가 모두 있습니다. v3에서 동일한 작업을 시도하면 원래 위치의 단일 점 또는 전혀없는 점이 생깁니다. 나는 목록을 좌표 각 텍스처의 실제 "로드"주위 glEnableClientState/ glDisableClientState 전화를했던 방법

void Mesh::RenderLineEdgesGPU() 
{ 
    // Enable client state 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_NORMAL_ARRAY); 
    glEnableClientState(GL_COLOR_ARRAY); 
    glEnableClientState(GL_SECONDARY_COLOR_ARRAY); 

    // Turn on edge shader 
    edgeProgram.Activate(); 

    // Link buffers 
    // v0 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[0]); 
    glVertexPointer(3, GL_FLOAT, 0, 0); 

    // v1 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[1]); 
    glColorPointer(3, GL_FLOAT, 0, 0); 

    // v2 
    glClientActiveTextureARB(GL_TEXTURE0_ARB); 

    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glActiveTextureARB(GL_TEXTURE0_ARB); 
    glEnable(GL_TEXTURE_2D); 

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[2]); 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); 

    glDisable(GL_TEXTURE_2D); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    // v3 
    glClientActiveTextureARB(GL_TEXTURE1_ARB); 

    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glActiveTextureARB(GL_TEXTURE1_ARB); 
    glEnable(GL_TEXTURE_2D); 

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[3]); 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); 

    glDisable(GL_TEXTURE_2D); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    // n0 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[4]); 
    glNormalPointer(GL_FLOAT, 0, 0); 

    // n1 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[5]); 
    glSecondaryColorPointer(3, GL_FLOAT, 0, 0); 

    // r and i 
    glClientActiveTextureARB(GL_TEXTURE2_ARB); 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[6]); 
    glTexCoordPointer(2, GL_FLOAT, 0, 0); 

    // Indicies 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, edgeMeshHandles[7]); 

    // Draw 
    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0); 

    // Turn off edge shader 
    edgeProgram.Deactivate(); 

    // Disable client state 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_NORMAL_ARRAY); 
    glDisableClientState(GL_COLOR_ARRAY); 
    glDisableClientState(GL_SECONDARY_COLOR_ARRAY); 
} 

주의 사항 : 온라인 제안을보고 한 후

, 여기에 나의 새로운 설정입니다. 또한 glActiveTextureARBglEnable(GL_TEXTURE_2D)을 사용합니다. 내가 왜 glActiveTextureARB이 필요한지 이해할 수 있다고 생각하지만, 다른 하나는 나를 당황하게합니다. GLSL Common Mistakes page에 따르면 셰이더를 사용하면이 호출을 무시하기 때문에 자신의 셰이더를 만들 때 glEnable(GL_TEXTURE_2D)을 사용하지 않아도됩니다.

그래서 그게 전부입니다. 텍스쳐 좌표로 비 텍스처 좌표 데이터를 보내는 방법을 구체적으로 설명하는 튜토리얼을 찾을 수 없으면이 정도까지 얻을 수 있습니다. 아마도 누군가가 그것에 대한 지침서를 알고 있다면 내 문제는 완화 될 것입니다. 시간 내 줘서 고마워!

답변

8

glClientActiveTextureARBglEnableClientState(GL_TEX_COORD_ARRAY)glTexCoordPointer을 호출 한 후 특정 텍스처 좌표 단위가 변경됩니다.

glActiveTextureARB은 위에서 언급 한 것처럼 셰이더를 필요로하지 않으므로 glEnable(GL_TEXTURE_2D)에 영향을줍니다.

당신은 만 5 전화 (및 해당 사용 안 함) 따기, 밀접하게 코드를 보면이 여기에 당신이 무엇을 :

glClientActiveTextureARB(GL_TEXTURE0_ARB); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glActiveTextureARB(GL_TEXTURE0_ARB); 
    glEnable(GL_TEXTURE_2D); 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); 
    glDisable(GL_TEXTURE_2D); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glClientActiveTextureARB(GL_TEXTURE1_ARB); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glActiveTextureARB(GL_TEXTURE1_ARB); 
    glEnable(GL_TEXTURE_2D); 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); 
    glDisable(GL_TEXTURE_2D); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
    glClientActiveTextureARB(GL_TEXTURE2_ARB); 
    glTexCoordPointer(2, GL_FLOAT, 0, 0); 
    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0); 

이 좋아, 우리는 이미 glActiveTextureARB과 glEnable이 (유용하지 않습니다 말했다 그런데, 당신이 그들을)이 유용 아니라, 그 사이에 어떤 무승부없이/GL_TEXTURE_2D를 사용하거나 사용하지 않도록 설정할 수 있으므로 제거 :

glClientActiveTextureARB(GL_TEXTURE0_ARB); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    glClientActiveTextureARB(GL_TEXTURE1_ARB); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    glClientActiveTextureARB(GL_TEXTURE2_ARB); 
    glTexCoordPointer(2, GL_FLOAT, 0, 0); 

    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0); 

지금 눈에 띄는 무엇입니까? 2 문제 :

  • 혹시
  • 당신은 당신이 무엇을 작성해야 TEXTURE2

의 실행 비트를 설정하지 그리기 실행하기 전에 클라이언트 상태를 해제? 그 라인을 따라 뭔가 : glBindBufferARB(GL_ARRAY_BUFFER_ARB,...)하지glClientActiveTextureARB에 의해 영향을받을 않지만 :

// texture coord 0 
    glClientActiveTextureARB(GL_TEXTURE0_ARB); // program texcoord unit 0 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); // enable array data to shader 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); // say what data 

    // texture coord 1 
    glClientActiveTextureARB(GL_TEXTURE1_ARB); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glTexCoordPointer(3, GL_FLOAT, 0, 0); 

    // texture coord 2 
    glClientActiveTextureARB(GL_TEXTURE2_ARB); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 
    glTexCoordPointer(2, GL_FLOAT, 0, 0); 

    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0); 

    // done with those texcoord units, turn them off 
    glClientActiveTextureARB(GL_TEXTURE0_ARB); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    glClientActiveTextureARB(GL_TEXTURE1_ARB); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    glClientActiveTextureARB(GL_TEXTURE2_ARB); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

좀 더 의견을 BindBuffer에 : (당신이 BindBuffer 각 포인터 호출에 다시 호출을 추가해야합니다,주의) 에 영향을 미치므로 다음 glTexCoordPointer에 영향을줍니다. 본질적으로 glClientActiveTextureARBglBindBufferARBglTexCoordPointer에 대한 추가 인수로 생각하십시오.

마지막으로, 더 적은 버퍼에 VBO 중 일부를 그룹화하려고합니다. 어쩌면 다른 질문을 할거야? (힌트, glTexCoordPointer에 대한 2 개의 인수는 0 일 필요는 없습니다.)

+0

늦은 응답을 드려 죄송합니다. 네, 물론, 당신의 대답은 정확했습니다. 도와 주셔서 감사합니다. – Dwight

관련 문제