2014-09-30 4 views
0

enter image description hereOpenGL은

내가 믹서기 2.66에서 만든 메쉬 파일에서 읽고 표준에 데이터를로드하는 .OBJ 로더를 만들 .OBJ 로더에 메쉬에 여분의 정점을 추가 : 벡터를 그 OpenGL은 VBO로 전달됩니다. 메쉬 파일의 어떤 정점도 (0,0,0)의 위치를 ​​갖지 않습니다. 그러면 메쉬가 센터에서 여분의 버텍스를 얻는 이유는 무엇입니까? 원래 메쉬는 정점이 4 개인 삼각형 평면입니다.

struct Vertex 
{ 
    //Position 
    GLfloat m_X; 
    GLfloat m_Y; 
    GLfloat m_Z; 

    //Normal 
    GLfloat m_NX; 
    GLfloat m_NY; 
    GLfloat m_NZ; 

    //TexCoords 
    GLfloat m_U; 
    GLfloat m_V; 
}; 

void Mesh::loadMesh(std::string Filename) 
{ 
    ... 

    const unsigned int PositionAttribute = 0; 
    const unsigned int NormalAttribute = 1; 
    const unsigned int TexCoordAttribute = 2; 

    //Create a new VBO and use the variable id to store the VBO id 
    glGenBuffers(1, &MeshVBO); 

    //make the new VBO active 
    glBindBuffer(GL_ARRAY_BUFFER, MeshVBO); 

    //Pass the Mesh's vertex data into the VBO to be transferred to super fast Video RAM 
    glBufferData(GL_ARRAY_BUFFER, m_Vertices.size() * sizeof(Vertex), &m_Vertices[0], GL_STATIC_DRAW); 

    glEnableVertexAttribArray(PositionAttribute); 
    glEnableVertexAttribArray(NormalAttribute); 
    glEnableVertexAttribArray(TexCoordAttribute); 

    //specifies the location and data of an array of vertex 
    glVertexAttribPointer(PositionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0); 
    glVertexAttribPointer(NormalAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(GLfloat) * 3)); //12 byte offset 
    glVertexAttribPointer(TexCoordAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)(sizeof(GLfloat) * 6)); //24 byte offset 

    //make the new VBO active 
    glBindBuffer(GL_ARRAY_BUFFER, MeshVBO); 

    glGenBuffers(1, &MeshIBO); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, MeshIBO); 

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, (sizeof(GLushort) * m_IndexList.size()), &m_IndexList[0], GL_STATIC_DRAW); 

    //Cleanup 
    delete[] m_VertexArray; 
    delete[] m_Indices; 
    m_VertexArray = NULL; 
    m_Indices = NULL; 

    return Success; 
} 

void Mesh::drawMesh() 
{ 
    glDrawElements(GL_POINTS, (GLsizei)m_IndexList.size() + 1, GL_UNSIGNED_SHORT, 0); 
} 

Plane.obj

# Blender v2.66 (sub 1) OBJ File: '' 
# www.blender.org 
mtllib plane.mtl 
o Plane 
v 0.622129 -0.622129 0.000000 
v -0.622129 -0.622129 0.000000 
v 0.622129 0.622129 -0.000000 
v -0.622129 0.622129 -0.000000 
vn 1.000000 0.000000 0.000000 
usemtl None 
s off 
f 2//1 1//1 3//1 
f 4//1 2//1 3//1 
+8

아마도'glDrawElements()'의 두 번째 인수에서'+ 1 '입니다. 당신이 가진 것보다 한 가지 더 많은 포인트를 명시 적으로 렌더링하는 것 같습니다. –

+0

생성 된 메쉬 파일을 게시 할 수 있습니까? 네 개 이상의 꼭지점이 지정되면 문제가 어디서 발생하는지 확인할 수 있습니다. @Reto Koradi에 동의하지만 +1 – Daniel

+0

@ Retekoradi gldrawelements()에서 "+1"을 제거하면 메쉬에서 오른쪽 아래 정점이 제거됩니다. 내 벡터가 어떻게 든 지표를 적절하게 전달하지 않을 가능성이 있습니까? 디버그에서 검사 된 색인은 파일의 색인과 일치합니다. –

답변

4

귀하의 주요 문제는 OpenGL을 0 기반 인덱스를 사용하는 반면 OBJ 파일의 인덱스는 1부터 시작이라는 것이다. 즉, OBJ 파일에서 읽은 색인에서 1을 빼야합니다. 이것은 대부분의 프로그래밍 언어와 API가 0 기반 색인을 사용하기 때문에 파싱 코드에서 색인을 읽은 직후에 가장 편리하게 수행됩니다.

넓은 범위의 OBJ 파일을 읽을 수 있도록하려면 입력 파일에서 음수 인덱스 값을 처리해야합니다. 이것은 일반적으로 사용되는 것 같지 않으며 파일이 잘 제어 된 소스 (예 : 항상 동일한 소프트웨어로 직접 생성 한 경우)에서 가져온 파일 인 경우 건너 뛸 수 있습니다. 존재하는 경우 음수 인덱스는 지금까지 읽은 버텍스의 끝을 기준으로합니다. 예 :

glDrawElements(GL_POINTS, (GLsizei)m_IndexList.size() + 1, GL_UNSIGNED_SHORT, 0); 

내가 의심 : 인덱스 -1 게시 된 코드에서 최신 버텍스 읽기, -2 번째 최신 등

, 당신은 추첨 전화에서 사용할 수있는 인덱스의 수에 1을 추가 잘못된 색인 값을 보완하기 위해이 작업을 수행했을 수 있습니다. 올바른 색인 값을 얻은 후에는 + 1을 제거해야합니다.

OBJ 형식에 대한 자세한 내용은 Wikipedia 페이지 (http://en.wikipedia.org/wiki/Wavefront_.obj_file)의 개요를 참조하십시오. 제가 발견 한 가장 상세하고 철저한 정의는 여기에 있습니다 : http://www.martinreddy.net/gfx/3d/OBJ.spec. OBJ 형식에는 NURBS와 같이 상당히 고급 기능이 포함될 수 있습니다. 자신 만의 파서와 렌더러를 작성한다면 아마도 하위 집합에 정착하기를 원할 것입니다. 그렇지 않으면 꽤 오랫동안 바쁠 것입니다. 효율적 OBJ 파일에서 메시를 렌더링하는 방법에 대한 더 자세한 정보를 원하는 경우

, 여기에 그 이전의 질문에 내 관련 답변을 몇 가지 더 있습니다