Data Shader와 함께 사용하기 위해 OpenGL 인덱스 버퍼 배열에서 여러 텍스처를 어떻게 처리합니까?

StackOverflow https://stackoverflow.com/questions/1678925

문제

나는 구현을 시도하고있다 이 종이. 나는 대부분의 것이 있지만, 기하학적 모서리를 결정하고 표시하는 데 사용하기 위해 임의의 비 초 지명 데이터를 셰이더로 전송하는 것에 대한 부분은 문제를 일으킨다. VBOS에 대해 알고있는 것을 사용하여 대부분의 데이터를 잘 보냈습니다. 그러나 많은 양의 데이터를 보내야하므로 여러 텍스처 좌표를 사용해야합니다.

나는 이미 여러 세트의 텍스처 좌표를 설정하는 올바른 방법이라고 생각하는 몇 가지 변형을 이미 구현했으며 많은 포럼 포스터의 지침을 따랐습니다. 지금까지 솔루션이 작동하지 않습니다.

컨텍스트를 위해이 프로그램은 모델의 각 고유 한 가장자리에 대해 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 개의 사본의 유일한 차이점은 I 값으로,이 값이 값을 찾을 수있는 경우 정점을 구성하는 방법을 결정하는 데 도움이됩니다.

보시다시피 적어도 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에 대해 동일한 작업을 시도하면 원점에서 단일 지점 또는 전혀 아무것도 생성됩니다.

온라인 제안을 살펴본 후 다음은 새로운 설정입니다.

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

내가 어떻게했는지 주목하십시오 glEnableClientState / glDisableClientState 각 텍스처 좌표 목록의 실제 "로드"주변을 호출합니다. 나도 사용합니다 glActiveTextureARB 그리고 glEnable(GL_TEXTURE_2D). 나는 그 이유를 이해할 수 있다고 생각하지만 glActiveTextureARB 여기서 필요합니다. 다른 하나는 나를 당황하게합니다. 에 따르면 GLSL 일반적인 실수 페이지, 당신은 사용해서는 안됩니다 glEnable(GL_TEXTURE_2D) 자신만의 셰이더를 만들 때 셰이더를 사용하면 어쨌든이 호출을 무시하기 때문입니다.

그래서 그게 다야. 나는 텍스처 좌표로 비 텍스트 좌표 데이터를 보내는 방법을 다루는 튜토리얼을 찾을 수 없었습니다. 아마도 누군가가 그것에 대한 튜토리얼을 알고 있다면 내 문제가 완화 될 것입니다. 시간 내 줘서 고마워!

도움이 되었습니까?

해결책

glClientActiveTextureARB 호출 후 특정 텍스처 좌표 단위를 변경합니다 glEnableClientState(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 가지 문제 :

  • 드로우를 실행하기 전에 고객 상태를 비활성화합니다
  • 텍스처에 대한 활성화 비트를 설정하지 않습니다 2

무엇을 써야합니까? 그 줄을 따라 무언가 : (조심하십시오. 각 포인터 호출에 bindbuffer 호출을 추가해야합니다) : :

    // 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에 대한 더 많은 의견 : glBindBufferARB(GL_ARRAY_BUFFER_ARB,...) 하다 ~ 아니다 영향을받습니다 glClientActiveTextureARB, 그러나 그러나 그것은 하다 다음에 영향을 미칩니다 glTexCoordPointer 전화. 본질적으로 생각하십시오 glClientActiveTextureARB 그리고 glBindBufferARB 추가 논쟁을 제공합니다 glTexCoordPointer.

마지막으로, 당신은 아마도 그 VBO 중 일부를 덜 버퍼로 그룹화하고 싶을 것입니다. 또 다른 질문에 대한 것이 있습니까? (힌트, 두 가지 논쟁 glTexCoordPointer 0이 될 필요는 없습니다)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top