2013-02-19 2 views
0

블렌더에서 모델 (Suzie)을 생성하고 법선으로 .obj 파일로 내 보냅니다. 내 애플 리케이션에 모드를로드하는 동안 나는 정점과 법선의 숫자가 다른 (2012 및 1967) 것으로 나타났습니다.GLSL이 쉐이더에 지시 된 법선을 전달합니다.

Model details

나는 간단한 세포 음영을 구현하려고합니다. 문제는 쉐이더에 법선을 전달하는 것입니다. 버텍스 데이터를 저장하기 위해 glm의 벡터를 사용합니다.

std::vector<unsigned int> face_indices; 
std::vector<unsigned int> normal_indices; 
std::vector<glm::vec3> geometry; 
std::vector<glm::vec3> normals; 

결과 내가 렌더링 조각

,536 지금까지

Wrong normals

버퍼 레이아웃

glBindVertexArray(VAO); 

    glEnableVertexAttribArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID); 
    glBufferData(GL_ARRAY_BUFFER, geometry.size() * sizeof(glm::vec3), &geometry[0], GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    glEnableVertexAttribArray(1); 
    glBindBuffer(GL_ARRAY_BUFFER, NormalVBOID); 
    glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_DYNAMIC_DRAW); 
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0); 

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, VIndexVBOID); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, face_indices.size() * sizeof(unsigned int), &face_indices[0], GL_DYNAMIC_DRAW); 

    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glBindVertexArray(0); 

있어

glBindVertexArray(VAO); glPolygonMode(GL_FRONT_AND_BACK, GL_QUADS); glDrawElements(GL_QUADS, face_indices.size(), GL_UNSIGNED_INT, (void*)0); glBindVertexArray(0); 
+1

정확히 무엇이 문제입니까? 아니요, 진지하게 - 전혀 명확하지 않습니다! – enhzflep

+0

문제는 적절한 방법으로 법선을 glsl에 전달하는 방법입니다. 얼굴 정의에서 정점 위치의 순서와 일치하도록 정렬하려고했습니다. 성공하지 못했습니다. –

+1

좋아, 그 경우에는 내가 당신이라면이 튜토리얼을 보도록하겠다. http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/ 당신이하려고하는 것보다 더 많은 일을하지만 중요한 점은 GLSL 셰이더에 법선을 넘겨주는 것입니다. 전체 자습서 시리즈의 코드는 약 20MB이며 잘 볼만한 가치가 있다고 생각합니다. 이상적으로, 당신은 내가 따라야 할 코드를 이미 가지고 있어야합니다. 희망이 도움이됩니다! – enhzflep

답변

1

그런 까다로운 문제가있는 이유는 일부 법선이 디스크 공간을 보존하기 위해 두 번 이상 사용되어 적절한 순서로 다시 정렬해야했기 때문입니다. 그래서 해결책은 꽤 trival입니다.

geometry.clear(); 
normals.clear(); 

geometry.resize(vv.size()); 
normals.resize(vv.size()); 

for (unsigned int i = 0; i < face_indices.size(); i++) 
{ 
    int vi = face_indices[i]; 
    int ni = normal_indices[i]; 
    glm::vec3 v = vv [vi]; 
    glm::vec3 n = vn [ni]; 
    geometry[vi] = v ; 
    normals[vi] = n ; 
    indices.push_back(vi); 
} 
0
또한 수출하기 전에 블렌더에서 부드럽게 수정을 사용하는 경우에 당신이 정점 당 보통 1 (당신은 나 또한 당 높이 요 기본보기 설정이 필요하지 않을 수도 있습니다 있음을 확인하는 데 도움이됩니다 있다는 사실을 숙지

얼굴 정상적인보기 대신 ... 당신은 시험을해야 할 것입니다. 이는 기본적으로 블렌더가 얼굴마다 법선을 사용하기 때문입니다. 부드러운 수정 자 ("w"단축키 메뉴) 은 버텍스 별 기준으로 전환합니다. 그런 다음 내보낼 때 평소와 같이 verts 및 norm을 내보내고 번호가 일치해야합니다. 항상 그런 것은 아니지만 이것은 과거에 저에게 효과적이었습니다. 이것은 가져 오는 동안 불필요한 데이터 저글링을 덜 수 있습니다.