2016-06-21 3 views
0

돌을 잘 그리기 위해 원통에 텍스처를 추가하려고합니다. 나는 실린더로 시작해서 돌 질감을 매핑하는데, ​​here을 발견했지만 이상한 결과를 얻고 있습니다. 여기에 내가 사용하고있는 기능입니다 :OpenGL : 실린더 주위의 텍스처 감싸기

void draw_well(double x, double y, double z, 
    double dx, double dy, double dz, 
    double th) 
{ 
    // Set specular color to white 
    float white[] = {1,1,1,1}; 
    float black[] = {0,0,0,1}; 
    glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shinyvec); 
    glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,white); 
    glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,black); 

    glPushMatrix(); 

    // Offset 
    glTranslated(x,y,z); 
    glRotated(th,0,1,0); 
    glScaled(dx,dy,dz); 

    // Enable textures 
    glEnable(GL_TEXTURE_2D); 
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); 

    glBindTexture(GL_TEXTURE_2D,texture[0]); // Stone texture 

    glBegin(GL_QUAD_STRIP); 
    for (int i = 0; i <= 359; i++) 
    { 
     glNormal3d(Cos(i), 1, Sin(i)); 

     glTexCoord2f(0,0); glVertex3f(Cos(i), -1, Sin(i)); 
     glTexCoord2f(0,1); glVertex3f(Cos(i), 1, Sin(i)); 
     glTexCoord2f(1,1); glVertex3f(Cos(i + 1), 1, Sin(i + 1)); 
     glTexCoord2f(1,0); glVertex3f(Cos(i + 1), -1, Sin(i + 1)); 
    } 
    glEnd(); 

    glPopMatrix(); 
    glDisable(GL_TEXTURE_2D); 
} 


// Later down in the display function 
draw_well(0, 0, 0, 1, 1, 1, 0); 

는 내가받을 출력은 아직도 OpenGL을 꽤 새로 온 사람보다 특별히 텍스처 나의 이해는 매우 제한되어

enter image description here

입니다. 여기 내 생각 과정은 실린더를 만드는 데 사용 된 QUAD 각각에 텍스처를 매핑하는 것이지만 분명히 잘못된 것을하고 있습니다. 이 이상한 출력을 일으키는 원인과 해결 방법에 대한 설명은 크게 감사하겠습니다.

+0

모든 쿼드마다 텍스쳐 좌표를 적용하는 방법이 전체 텍스쳐에 적용됩니다. 그건 분명히 당신이 원하는 것이 아닙니다. – datenwolf

답변

2

그리기 루틴에는 세 가지 주요 문제점이있을 수 있습니다. 쿼드 - 스트립 인덱싱, 텍스처 좌표가 너무 자주 반복되며 삼각 함수의 잘못된 사용 가능성;

삼각 함수은 일반적으로 각도가 아닌 라디안으로 표현 된 각도를 나타내는 값을 허용합니다. 사용중인 Sin 및 Cos 함수의 매개 변수를 다시 확인하십시오.

Quadstrip 색인 생성이 잘못되었습니다. 인덱싱은 쿼드는 그러나 대각선 정점 순차적으로 정의하는 시계 방향 방식으로 정의하는 방법을

enter image description here

공지 사항 ... 이런 식으로 가야한다. v0, v1, v2, v3 대신 v0, v1, v3, v2로 쿼드를 정의하므로 네 개의 마지막 두 정점을 서로 바꿉니다. 또한 정점을 올바르게 공유하지 못하는 또 다른 오류가 발생합니다. 하나의 루프에 동일한 꼭짓점 세트 (i + 1)를 그리면 각 수직 에지를 따라 복제됩니다 (즉, 이제는 1 씩 증가하므로).

텍스처 좌표은 각 쿼드에 대해 0, 1 범위에 있습니다. 즉, 360 배로 분할 된 원통을 정의하고이 텍스처가 원통 주위로 360 번 반복됩니다. 나는 텍스쳐가 실린더에 1 : 1로 맵핑되고 반복되지 않아야한다고 가정하고 있습니까?

입력하신 내용을 사용하는 코드 예입니다. 나는 세그먼트의 수를 64 개로 줄였습니다. 그래도 360을 가지고 싶다면 그에 따라 numberOfSegments을 수정하십시오.

float pi = 3.141592654f; 

unsigned int numberOfSegments = 64; 
float angleIncrement = (2.0f * pi)/static_cast<float>(numberOfSegments); 
float textureCoordinateIncrement = 1.0f/static_cast<float>(numberOfSegments); 

glBegin(GL_QUAD_STRIP); 
for (unsigned int i = 0; i <= numberOfSegments; ++i) 
{ 
    float c = cos(angleIncrement * i); 
    float s = sin(angleIncrement * i); 

    glTexCoord2f(textureCoordinateIncrement * i, 0); glVertex3f(c, -1.0f, s); 
    glTexCoord2f(textureCoordinateIncrement * i, 1.0f); glVertex3f(c, 1.0f, s); 
} 
glEnd(); 

N.B 이전 버전의 OpenGL (glBegin/glVertex 등 사용)을 사용하고 있습니다.

+0

감사합니다. 좌표 중복은 의미가 있습니다. OpenGL은 다음 QUAD를 만들기 위해 2 개의 새로운 점만 필요하다는 것을 잊었습니다. 좌표의 인덱싱에 관해서는 (0, 1)에서 (1, 0)으로 뛰어 올랐는지 모르지만 점들을 연결하는 것과 비슷한 점을 생각했습니다. 실제로 루프의 두 줄을 바꿔서 실린더 모양을 얻었지만 텍스처는 여전히 이상했습니다. 그래도 코드는 작동합니다. – steveclark

+0

기쁜 '더 나은';) 텍스처 매핑에 관해서.텍스처는 0,0 (텍스처의 왼쪽 아래 모서리)에서 1,1 (텍스처의 오른쪽 위 모서리)까지 매핑되므로, 텍스처가 반복되지 않도록 한 번 실린더 주위로 정확하게 텍스처를 매핑하려면 플롯해야합니다 텍스쳐 좌표의 x 성분은 꼭지점 인 원통 주위의 거리로 좌표화됩니다. 이것이 텍스쳐 좌표 증가분이 각도 증가분과 다른 이유입니다. 텍스처를 반복하려면 제공된 코드의 textureCoordinateIncrement 정의에서 분자를 증가 시키십시오. – lfgtm

+0

그 quadstrip 다이어그램은 불행합니다. 토폴로지는 정확하지만 시계 방향으로 정점을 표시하지만 OpenGL의 기본 와인 더 순서는 반 시계 방향입니다. –