2013-09-02 1 views
0

OBJMesh 로더에서 텍스처를 얻으려고합니다. 지금까지이 작업을 수행하는 방법에 대한 온라인 자습서를 살펴 보았습니다. 가장 명확한 예제는 내가 이해 한 큐브/상자 예제입니다. 그러나 꼭지점이 하나 이상의 텍스처 좌표를 사용하거나 가질 수있는이 문제를 보았습니다. 예를 들어DirectX9/C++에서 OBJMesh 용 텍스처 좌표로드

: 당신은, 인덱스 정점 번호 (711)는 텍스처 좌표를 사용하고 볼 수있는 숫자 1과 9 및 인덱스 정점 수 (712)는 텍스처 좌표를 사용하기 때문에

f 711/1/1 712/2/2 709/3/3 
f 711/9/1 704/10/9 712/11/2 

숫자 2, 11. 그래서 제 질문은 어떻게 여러 텍스처 좌표로 작업 할 수 있습니까? 버텍스 버퍼와 인덱스 버퍼처럼 사용할 수있는 버퍼가 있습니까?

나는 이것에 대한 인덱스를 사용하고 난 다음 정점 선언이 :

D3DVERTEXELEMENT9 vertexElement[] = { {0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0}, 
             {0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0}, 
             D3DDECL_END()}; 

device->CreateVertexDeclaration(vertexElement, &vertexDec); 

을 그리고 내 여기 내 정점 구조입니다 : 여기 보여 다른 어떤 코드도 확인

struct VERTEX{ 
    D3DXVECTOR3 position; 
    D3DXVECTOR2 uv; 

    D3DCOLOR color; 
}; 

아니지만, 내가 누락 된 것이거나 너희들이 나를 돕기 위해 뭔가를 볼 필요가 있다면 알려줘.

감사

편집

: 나는 정점 선언 대신 FVF를 사용하는 경우 더 나은 것입니까?

+0

아니요, 동일한 위치와 다른 텍스처 좌표를 가진 여러 개의 정점을 정점 버퍼에 추가해야합니다. –

+0

@NicoSchertler는이 문제를 해결할 수있는 방법이 없습니다. 나는 directX가이 문제를 해결할 어떤 것을 제공하지 않는다고 정말로 믿을 수 없다 ... – Danny

+0

정말 다른 방법은 없다. –

답변

0

DX9를 사용하면 분할 법선과 텍스처 좌표로 위치를 인스턴스화 해제해야합니다. 여기

샘플 코드

그것을 할 수 있습니다 : 물론

#include <array> 
#include <vector> 
#include <utility> 
#include <tuple> 
#include <map> 

struct Vec3f { /* put your beloved implementation here */ }; 
struct Vec2f { /* put your beloved implementation here */ }; 

// imagine your obj loaded as these set of vectors : 

// the vertices separate values 
using Positions = std::vector<Vec3f>; 
using Normals = std::vector<Vec3f>; 
using Texcoords = std::vector<Vec2f>; 

// and faces information 
struct VertexTriplet { 
    int _pos; 
    int _normal; 
    int _texcoord; 
    friend bool operator< (VertexTriplet const & a, VertexTriplet const & b) { 
     return a._pos < b._pos 
       || (a._pos == b._pos && a._normal < b._normal) 
       || (a._pos == b._pos && a._normal == b._normal && a._texcoord < b._texcoord); 
    } 
}; 

using Triangle = std::array<VertexTriplet,3>; 
using Faces = std::vector<Triangle>; 

// imagine your GPU friendly geometry as these two vectors 
using Vertex = std::tuple<Vec3f,Vec3f,Vec2f>; 
using Index = unsigned int; 

using VertexBuffer = std::vector<Vertex>; 
using IndexBuffer = std::vector<Index>; 

using GpuObject = std::pair<VertexBuffer,IndexBuffer>; 
// you can now implement the conversion : 
GpuObject Convert(Positions const & positions, Normals const & normals, Texcoords const & texcoords, Faces const & faces) { 
    GpuObject result; 

    // first, we create unique index for each existing triplet 
    auto & indexBuffer = result.second; 
    indexBuffer.reserve(faces.size() * 3); 

    std::map<VertexTriplet, Index> remap; 
    Index freeIndex = 0; 
    for (auto & triangle : faces) { 
     for (auto & vertex : triangle) { 
      auto it = remap.find(vertex); 
      if (it != remap.end()) { // index already exists 
       indexBuffer.push_back(it->second); 
      } else { // create new index 
       indexBuffer.push_back(freeIndex); 
       remap[vertex] = freeIndex++; 
      } 
     } 
    } 

    // we now have the index buffer, we can fill the vertex buffer 
    // we start by reversing the mapping from triplet to index 
    // so wee can fill the memory with monotonic increasing address 
    std::map< Index, VertexTriplet > reverseRemap; 
    for (auto & pair : remap) { 
     reverseRemap[pair.second] = pair.first; 
    } 

    auto & vertexBuffer = result.first; 
    vertexBuffer.reserve(reverseRemap.size()); 
    for (auto & pair : reverseRemap) { 
     auto & triplet = pair.second; 
     vertexBuffer.push_back(std::make_tuple(positions[triplet.m_pos], normals[triplet.m_normal], texcoords[triplet.m_texcoord])); 
    } 
    return result; 
} 
int main() { 
    // read your obj file into these four vectors 
    Positions positions; 
    Normals normals; 
    Texcoords texcoords; 
    Faces faces; 

    /* read the obj here */ 

    // then convert 
    auto gpuObject = Convert(positions, normals, texcoords, faces); 

    return 0; 
} 

, 우리는 성능을 최적화하기 위해 인덱스 및 버텍스 버퍼의 사후 처리를 상상할 수있다. ...

DX10/11에서는 입력 배열에 3 개의 인덱스를 제공하는 정점 버퍼로 Faces 벡터를 사용한다고 상상할 수 있습니다 (정점 선언 새로운 이름)을 생성하고 버텍스 쉐이더에 버퍼 유형의 3 가지 쉐이더 리소스 뷰로서 위치, 법선 및 택을 전달하고 직접 룩업을 수행합니다. 오래된 학교 버텍스 인터리빙과 비교할 때 너무 차선해서는 안되지만 오래된 학교 솔루션을 고수해야합니다.

관련 문제