2010-11-21 7 views
1

내 OpenGL 작업을하고 있고 다음 단계는 섀도우 볼륨 알고리즘을 사용하여 모델을로드하고 그림자를 생성하는 것입니다. 나는 3 단계에서 할 -그림자 볼륨 - 실루엣 찾기

  1. setConnectivity - 각 삼각형의 neigh 매개 변수의 인덱스를 저장 각 삼각형의 이웃과 을 찾는

  2. markVisible(float* lp)

    - LP 빛의 의 벡터를 나타내는 경우 위치에서 삼각형은 도트 생성에 따라 visible = true 또는 visible = false으로 표시됩니다. 정상 벡터 및 표시 등 위치,

  3. markSilhoutte(float *lp) - 실루엣 가장자리를 표시하고 볼륨 자체를 구축하고 빛을 반대 방향으로 실루엣을 무한대 (100 단위로 충분)까지 확장합니다.

나는 모든 단계를 확인했으며 그 문제는 제 2의 기능이므로 제 질문에 포함 시켰습니다. 이 튜토리얼에서 소개 한 알고리즘을 사용합니다. http://www.3dcodingtutorial.com/Shadows/Shadow-Volumes.html

간단히 볼 수있는 삼각형과 보이지 않는 삼각형에 속하면 가장자리가 실루엣에 포함됩니다. 당신이 볼 수 있듯이 http://prntscr.com/17dmg, http://prntscr.com/17dmq

, 녹색 영역은 빛의 위치를 ​​나타내며, 이러한 추한 녹색 - 파란색 다각형 "섀도우 볼륨"의 얼굴입니다 여기 무슨 잘못을 보여주는 스크린 샷의 한 쌍이다. 또한이 함수를 큐브 모델에 적용하고 볼륨 측면 중 하나가 누락 된 것을 볼 수 있습니다 (닫혀 있지 않지만 반드시 있어야합니다). 누군가 내 코드에 무슨 문제가 있다고 제안 할 수 있습니까? 어떻게 해결할 수 있습니까?

나는 모든 것이 괜찮다는 생각
void Model::markSilhouette(float* lp){ 
     glBegin(GL_QUADS); 
     for (int i = 0; i < m_numMeshes; i++) 
     { 
      for (int t = 0; t < m_pMeshes[i].m_numTriangles; t++) 
      { 
       int triangleIndex = m_pMeshes[i].m_pTriangleIndices[t]; 
       Triangle* pTri = &m_pTriangles[triangleIndex]; 
       if (pTri->visible){ 

        for(int j=0;j<3;j++){ 
         int triangleIndex = m_pMeshes[i].m_pTriangleIndices[pTri->neigh[j]-1]; 
         Triangle* pTrk = &m_pTriangles[triangleIndex]; 
         if(!pTrk->visible){ 
          int p1j=pTri->m_vertexIndices[j]; 
          int p2j=pTri->m_vertexIndices[(j+1)%3]; 
          float* v1=m_pVertices[p1j].m_location; 
          float* v2=m_pVertices[p2j].m_location; 

          float x1=m_pVertices[p1j].m_location[0]; 
          float y1=m_pVertices[p1j].m_location[1]; 
          float z1=m_pVertices[p1j].m_location[2]; 

          float x2=m_pVertices[p2j].m_location[0]; 
          float y2=m_pVertices[p2j].m_location[1]; 
          float z2=m_pVertices[p2j].m_location[2]; 

          t=100; 

          float xl1=(x1-lp[0])*t; 
          float yl1=(y1-lp[1])*t; 
          float zl1=(z1-lp[2])*t; 

          float xl2=(x2-lp[0])*t; 
          float yl2=(y2-lp[1])*t; 
          float zl2=(z2-lp[2])*t; 
          glColor3f(0,0,1); 

          glVertex3f(x1 + xl1, 
           y1 + yl1, 
           z1 + zl1); 
          glVertex3f(x1, 
           y1, 
           z1); 
          glColor3f(0,1,0); 

          glVertex3f(x2 + xl2, 
           y2 + yl2, 
           z2 + zl2); 
          glVertex3f(x2, 
           y2, 
           z2); 
         } 
        } 

       } 

      } 
     } 
     glEnd(); 
    } 

답변

1

찾았습니다. 며칠 동안 명백한 알고리즘 실수를 보지 않으면 어리석은 실수를 저지른 것처럼 보입니다.

내 삼각형 인덱스 변수를 t라고합니다. 맞춰봐? 내 확장 벡터 길이는 t라고도하며 동일한 범위에 있으며 첫 번째 보이는 삼각형 다음에 t = 100으로 설정합니다. 이제는 볼륨이 다음과 같이 보입니다. 바깥 쪽 http://prntscr.com/17l3n 내부 http://prntscr.com/17l40 위치 (그림자 볼륨 aglorithm에 의해, 물론 허용). 따라서 섀도우 볼륨을 그리는 작업 코드는 다음과 같습니다.

void Model::markSilouette(float* lp){ 
    glDisable(GL_LIGHTING); 
    glPointSize(4.0); 
    glEnable(GL_COLOR_MATERIAL); 
    glColorMaterial(GL_FRONT_AND_BACK,GL_FILL); 
    glBegin(GL_QUADS); 
    for (int i = 0; i < m_numMeshes; i++) 
    { 
     for (int t = 0; t < m_pMeshes[i].m_numTriangles; t++) 
     { 
      int triangleIndex = m_pMeshes[i].m_pTriangleIndices[t]; 
      Triangle* pTri = &m_pTriangles[triangleIndex]; 

      if (pTri->visible){ 
       for(int j=0;j<3;j++){ 
        Triangle* pTrk; 
        if(pTri->neigh[j]){ 
         int triangleIndex = m_pMeshes[i].m_pTriangleIndices[pTri->neigh[j]-1]; 
         pTrk = &m_pTriangles[triangleIndex]; 
        } 

         if((!pTri->neigh[j]) || !pTrk->visible){ 

          int p1j=pTri->m_vertexIndices[j]; 
          int p2j=pTri->m_vertexIndices[(j+1)%3]; 
          float* v1=m_pVertices[p1j].m_location; 
          float* v2=m_pVertices[p2j].m_location; 

          float x1=m_pVertices[p1j].m_location[0]; 
          float y1=m_pVertices[p1j].m_location[1]; 
          float z1=m_pVertices[p1j].m_location[2]; 

          float x2=m_pVertices[p2j].m_location[0]; 
          float y2=m_pVertices[p2j].m_location[1]; 
          float z2=m_pVertices[p2j].m_location[2]; 

          float f=100; // THE PROBLEM WAS HERE 

          float xl1=(x1-lp[0])*f; 
          float yl1=(y1-lp[1])*f; 
          float zl1=(z1-lp[2])*f; 

          float xl2=(x2-lp[0])*f; 
          float yl2=(y2-lp[1])*f; 
          float zl2=(z2-lp[2])*f; 
          glColor3f(0,0,0); 
          glVertex3f(x1 + xl1, 
           y1 + yl1, 
           z1 + zl1); 
          glVertex3f(x1, 
           y1, 
           z1); 
          glVertex3f(x2, 
           y2, 
           z2); 
          glVertex3f(x2 + xl2, 
           y2 + yl2, 
           z2 + zl2); 
         } 
        } 
       } 

     } 
    } 
    glEnd(); 
} 
0

, 당신은 : 여기 (변수 이름, 설명이 필요 내가 생각,하지만 당신이 생각 해달라고하면 그래서 난 그들 각각에 대한 설명을 추가 할 수 있습니다)를 포함하기로 약속 코드가 간다 심도 검사없이 볼륨 만 렌더링 =)

+0

glEnable (GL_DEPTH_TEST), 동일한 결과가 추가되었습니다. 그림에 따르면 정점 인덱스가 잘못되었거나 잘못된 순서로 있다고 생각합니다. 모든 glVertex .. 라인을 바꿔서 결과가 다양하지만 항상 나쁜 것 같습니다 : D – Anton

+0

깊이 테스트 만 사용하면 충분하지 않음 =) 다음과 같이 몇 가지 단계를 수행해야합니다. 여기 http://gpwiki.org/index.php/OpenGL_Tutorial_Framework : Adding_Depth_and_Color – shybovycha

+0

이 링크의 모든 설정을 추가했습니다 : \t glEnable (GL_DEPTH_TEST); (GL_TRUE); \t glEnable (GL_CULL_FACE); 나는 그들이 무엇을 바꿀지 전혀 모른다. 그러나이 못생긴 폴리곤조차도 사라졌다. – Anton