Computer Graphics/SCOP

SCOP - 4. assimp 대체 라이브러리 만들기 (1)

surkim 2024. 9. 29. 12:22

assimp 라이브러리를 대체하기 위해 개발한 sAssimp 라이브러리의 개선 사항을 포스트하겠다.

이전에 언급했던 모델이 흐릿하거나 뭉뜬그려지는 문제는 인덱스 처리 오류로 밝혀졌으며, 이를 수정했다.

내 라이브러리 (sAssimp)로 오브젝트를 로드해서 그린 backpack

 

또한, 데이터 복사에 대한 우려로 인해 깊은 복사를 사용했었으나, OpenGL 버퍼에 데이터가 이미 저장된 이후에는 C++ 코드에서 데이터 관리를 직접 하지 않아도 된다는 것을 알게 되어 코드 구조를 변경했다.

 

최대한 기존 코드를 유지하면서 불필요한 복사를 줄이고 인덱싱 과정에서 최적화를 진행했고, 그 핵심 로직은 아래 Indexing() 함수에 있다.

void sAssimp::Indexing() {
    uint32_t index = 0;

    for (auto& face : m_faces) {
        // 버텍스, 텍스처, 노멀 데이터 참조하여 인덱싱
        for (int i = 0; i < face.indices.size(); i++) {
            m_indexedVertices.push_back(&m_vertices[face.indices[i] - 1]);
            if (face.texCoords[i] != 0)
                m_indexedTexCoords.push_back(&m_texCoords[face.texCoords[i] - 1]);
            if (face.normals[i] != 0)
                m_indexedNormals.push_back(&m_normals[face.normals[i] - 1]);
        }

        // 삼각형으로 인덱스 구성
        for (int i = 0; i < face.indices.size() - 2; i++) {
            m_indices.push_back(index);
            m_indices.push_back(index + i + 1);
            m_indices.push_back(index + i + 2);
        }

        // 인덱스 증가
        index += face.indices.size();
    }
}

1. 인덱스 정렬 및 참조

Indexing() 함수는 .obj 파일에서 f (face) 요소를 파싱한 후, 각 버텍스와 텍스처, 노멀의 인덱스를 m_indexedVertices, m_indexedTexCoords, m_indexedNormals에 저장한다. 

  • 버텍스 인덱스 추가: m_vertices에 저장된 버텍스 데이터를 참조하여 m_indexedVertices에 추가한다.
  • 텍스처 및 노멀 인덱스: face.texCoords[i]face.normals[i]이 0이 아닌 경우에만(없는 경우에 임의로 0을 넣음) 해당 데이터를 참조한다. 이를 통해 유효하지 않은 인덱스를 참조하는 문제를 방지했다.

2. 삼각형 구성

.obj 파일의 f 요소는 일반적으로 다각형으로 구성되어 있다. 이 요소를 삼각형으로 분할하여 m_indices에 저장하는 과정이 중요하다.

  • 삼각형 재구성: 다각형 페이스를 삼각형으로 분할하여 인덱스 버퍼에 저장한다. 예를 들어, f 요소가 4개의 꼭짓점을 가진다면 (index, index + 1, index + 2)(index, index + 2, index + 3) 두 개의 삼각형으로 분할된다.
  • 인덱스 증가: 각 페이스를 처리할 때마다 인덱스를 증가시켜 다음 페이스의 시작점을 맞춰준다.

3. 최적화된 데이터 관리

이전에는 데이터 유실을 우려해 깊은 복사를 사용했으나, OpenGL 버퍼에 데이터를 저장한 후에는 복사할 필요가 없다는 점을 고려해 참조 기반 접근을 선택했다. 이로써 불필요한 메모리 복사를 줄이고, 렌더링 과정에서의 성능을 향상시켰다.


이렇게 Indexing() 함수를 통해 인덱스 문제를 해결함으로써 기존에 흐릿하게 렌더링되던 문제를 개선했다.

다음은 stb를 대체하는 텍스처이미지 로드 라이브러리를 만들 예정이다.