2014-07-23 1 views
0

assimp 라이브러리를 사용하여 obj 파일에서로드하는 장면이 있습니다. 나는 이것을하기 위해 튜토리얼을 따랐다. 그것은 작동하지만 텍스처는 원본과 다른 색상을 가지고 있으며, 모두 위쪽 아래쪽으로 뒤집혀있는 것처럼 보입니다. 이미지는 여기 OpenGL C++ 텍스처의 색상과 위치가 잘못되었습니다.

는 결과

enter image description here

와 커튼은 빨간색이어야한다이다 (나는 또한 모든 앨리어싱 제거하려는) 모든 TGA 있습니다

enter image description here

freeImage를 사용하여 이런 식으로 텍스처를로드합니다.

bool Texture::Load(){ 
    FIBITMAP* bitmap = FreeImage_Load(
     FreeImage_GetFileType(m_fileName.c_str(), 0), 
     m_fileName.c_str()); 
    FIBITMAP *pImage = FreeImage_ConvertTo32Bits(bitmap); 
    int nWidth = FreeImage_GetWidth(pImage); 
    int nHeight = FreeImage_GetHeight(pImage); 
    glGenTextures(1, &m_textureObj); 
    glBindTexture(m_textureTarget, m_textureObj); 
    glTexImage2D(m_textureTarget, 0, GL_RGBA, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage)); 
    glTexParameterf(m_textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameterf(m_textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    FreeImage_Unload(pImage); 
    return true; 
} 

장면이 assimp를 사용하여로드 및이 방법

void Mesh::InitMesh(const aiMesh* paiMesh, 
vector<Vector3f>& Positions, 
vector<Vector3f>& Normals, 
vector<Vector2f>& TexCoords, 
vector<unsigned int>& Indices){ 

const aiVector3D Zero3D(0.0f, 0.0f, 0.0f); 
aiMatrix4x4 Scale(0.3f, 0.0f, 0.0f, 0.0f, 
    0.0f, 0.3f, 0.0f, 0.0f, 
    0.0f, 0.0f, 0.3f, 0.0f, 
    0.0f, 0.0f, 0.0f, 1.0f); 
// Populate the vertex attribute vectors 

for (unsigned int i = 0; i < paiMesh->mNumVertices; i++) { 
    if (paiMesh->mVertices[i].x < lowX) lowX = paiMesh->mVertices[i].x; 
    if (paiMesh->mVertices[i].x > highX) highX = paiMesh->mVertices[i].x; 
    if (paiMesh->mVertices[i].y < lowY) lowY = paiMesh->mVertices[i].y; 
    if (paiMesh->mVertices[i].y > highY) highY = paiMesh->mVertices[i].y; 
    if (paiMesh->mVertices[i].z < lowZ) lowZ = paiMesh->mVertices[i].z; 
    if (paiMesh->mVertices[i].z > highZ) highZ = paiMesh->mVertices[i].z; 

    //paiMesh->mVertices[i] = Scale*paiMesh->mVertices[i]; 
    const aiVector3D* pPos = &(paiMesh->mVertices[i]); 
    const aiVector3D* pNormal = &(paiMesh->mNormals[i]); 
    const aiVector3D* pTexCoord = paiMesh->HasTextureCoords(0) ? &(paiMesh->mTextureCoords[0][i]) : &Zero3D; 

    Positions.push_back(Vector3f(pPos->x, pPos->y, pPos->z)); 
    Normals.push_back(Vector3f(pNormal->x, pNormal->y, pNormal->z)); 
    TexCoords.push_back(Vector2f(pTexCoord->x, pTexCoord->y)); 
} 
bbox[0] = Vector3f(abs(lowX), abs(lowY), abs(lowZ)); 
bbox[1] = Vector3f(abs(highX), abs(highY), abs(highZ)); 

// Populate the index buffer 
for (unsigned int i = 0; i < paiMesh->mNumFaces; i++) { 
    const aiFace& Face = paiMesh->mFaces[i]; 
    assert(Face.mNumIndices == 3); 
    Indices.push_back(Face.mIndices[0]); 
    Indices.push_back(Face.mIndices[1]); 
    Indices.push_back(Face.mIndices[2]); 
} 

}

을 처리하고 이것이 내가

bool Mesh::InitMaterials(const aiScene* pScene, const string& Filename){ 

// Extract the directory part from the file name 
string::size_type SlashIndex = Filename.find_last_of("/"); 
string Dir; 

if (SlashIndex == string::npos) { 
    Dir = "."; 
} 
else if (SlashIndex == 0) { 
    Dir = "/"; 
} 
else { 
    Dir = Filename.substr(0, SlashIndex); 
} 

bool Ret = true; 

// Initialize the materials 
for (unsigned int i = 0; i < pScene->mNumMaterials; i++) { 
    const aiMaterial* pMaterial = pScene->mMaterials[i]; 

    m_Textures[i] = NULL; 

    if (true || pMaterial->GetTextureCount(aiTextureType_DIFFUSE) > 0) { 
     aiString Path; 

     if (pMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &Path, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) { 
      string FullPath = Dir + "/" + Path.data; 
      m_Textures[i] = new Texture(GL_TEXTURE_2D, FullPath.c_str()); 

      if (!m_Textures[i]->Load()) { 
       printf("Error loading texture '%s'\n", FullPath.c_str()); 
       delete m_Textures[i]; 
       m_Textures[i] = NULL; 
       Ret = false; 
      } 
      else { 
       printf("%d - loaded texture '%s'\n", i, FullPath.c_str()); 
      } 
     } 
    } 
} 

return Ret; 

} 결국

나는 모든 렌더링 텍스처를 초기화하는 방법입니다 동안 이런 식으로

void Mesh::Render() 
{ 
    glBindVertexArray(m_VAO); 
    glActiveTexture(GL_TEXTURE0); 

    GLenum oldObj = 0; 
    if (m_Textures[m_Entries[0].MaterialIndex]){ 
     m_Textures[m_Entries[0].MaterialIndex]->Bind(GL_TEXTURE0); 
     oldObj = m_Textures[m_Entries[0].MaterialIndex]->m_textureObj; 
    } 

    vector<GLsizei> numIdx; 
    vector<GLint> baseVc; 
    vector<void*> idx; 
    unsigned int drawCount = 0; 

    for (unsigned int i = 0; i < m_Entries.size(); i++) { 
     const unsigned int MaterialIndex = m_Entries[i].MaterialIndex; 

     assert(MaterialIndex < m_Textures.size()); 

     drawCount++; 
     numIdx.push_back(m_Entries[i].NumIndices); 
     baseVc.push_back(m_Entries[i].BaseVertex); 
     idx.push_back((void*)(sizeof(unsigned int) * m_Entries[i].BaseIndex)); 

     if (i == m_Entries.size() - 1){ 
      glDrawElementsBaseVertex(GL_TRIANGLES, 
       m_Entries[i].NumIndices, 
       GL_UNSIGNED_INT, 
       (void*)(sizeof(unsigned int) * m_Entries[i].BaseIndex), 
       m_Entries[i].BaseVertex); 
     }else 
     if (m_Textures[m_Entries[i + 1].MaterialIndex] && m_Textures[m_Entries[i+1].MaterialIndex]->m_textureObj != oldObj) { 
      glMultiDrawElementsBaseVertex(GL_TRIANGLES, 
        &numIdx[0], 
        GL_UNSIGNED_INT, 
        &idx[0], 
        drawCount, 
        &baseVc[0]); 
      numIdx.clear(); 
      baseVc.clear(); 
      idx.clear(); 
      m_Textures[m_Entries[i + 1].MaterialIndex]->Bind(GL_TEXTURE0); 
      oldObj = m_Textures[m_Entries[i + 1].MaterialIndex]->m_textureObj; 
      drawCount = 0; 
     }else if (!m_Textures[m_Entries[i].MaterialIndex]){ 
      glMultiDrawElementsBaseVertex(GL_TRIANGLES, 
       &numIdx[0], 
       GL_UNSIGNED_INT, 
       &idx[0], 
       drawCount, 
       &baseVc[0]); 
     } 

    } 

    // Make sure the VAO is not changed from the outside  
    glBindVertexArray(0); 
} 

많은 양의 코드에 대해 유감스럽게 생각하지만 오류가 어디에 있는지 모르기 때문에 전체를 게시했습니다. 모두 주석 처리되었습니다

+1

에 대한 내부 형식 및 BGRA으로 RGBA를 사용했다는 것을 밝혀 플립 된 텍스처 좌표는 고정되어야합니다. –

+0

이미 해당 인수가 있습니다. aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs – tigeradol

+0

flipUvs를 제거했는데 텍스처가 정확합니다. 여전히 색상 문제 ... – tigeradol

답변

1

텍스처의 크기를 줄이려고 시도하는 동안 이런 종류의 문제가있었습니다. RGBA를 잘못된 위치에 놓았습니다. 비트 맵 텍스처를 사용합니다. 즉, 알파 채널을 저장하지 않고 GL_RGBA 모드로 설정하려고합니다 (GL_RGBA로 전송).

+0

glTexImage2D (m_textureTarget, 0, GL_RGB8, nWidth, nHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void *) FreeImage_GetBits (pImage))와 같은 것입니다. – Symeon94

+0

나는 tga를 사용하고있다. 나는 ABGR BGRA를 시도했지만 같은 resutl을 가지고있다. – tigeradol

+0

비트 채널 텍스처는 알파 채널을 제거하려고 시도했으나 비트 맵 텍스처는 24 비트로 작성되었으며 알파 채널을 저장하지 않는다. – Symeon94

0

는 그래서 내가 flippedUV을 제거했고, 난 당신이 수입의`ReadFile` 함수에`aiProcess_FlipUVs` 후 처리 비트를 추가하는 경우 다른 형식

관련 문제