2011-10-30 24 views
7

Tôi đang cố sửa đổi mã mẫu để tải mô hình 3D được bao gồm trong ASSIMP sample code, bằng cách sử dụng GLUT thay vì WGL. Tuy nhiên, tôi có một vấn đề với các kết cấu, như minh họa dưới đây:Kết cấu không chính xác khi tải mô hình 3D bằng ASSIMP & OpenGL

loaded 3d model

trong khi nó được coi là như minh họa dưới đây:

original 3d model

và mã để vẽ mô hình 3d được liệt kê bên dưới:

void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float scale){ 
unsigned int i; 
unsigned int n=0, t; 
struct aiMatrix4x4 m = nd->mTransformation; 
m.Scaling(aiVector3D(scale, scale, scale), m); 
// update transform 
m.Transpose(); 
glPushMatrix(); 
glMultMatrixf((float*)&m); 
// draw all meshes assigned to this node 
for (; n < nd->mNumMeshes; ++n){ 
    const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]]; 
    apply_material(sc->mMaterials[mesh->mMaterialIndex]); 
    if(mesh->mNormals == NULL){ 
     glDisable(GL_LIGHTING); 
    } 
    else { 
     glEnable(GL_LIGHTING); 
    } 
    if(mesh->mColors[0] != NULL) { 
     glEnable(GL_COLOR_MATERIAL); 
    } 
    else { 
     glDisable(GL_COLOR_MATERIAL); 
    } 

    for (t = 0; t < mesh->mNumFaces; ++t) { 
     const struct aiFace* face = &mesh->mFaces[t]; 
     GLenum face_mode; 
     switch(face->mNumIndices) { 
      case 1: face_mode = GL_POINTS; break; 
      case 2: face_mode = GL_LINES; break; 
      case 3: face_mode = GL_TRIANGLES; break; 
      default: face_mode = GL_POLYGON; break; 
     } 
     glBegin(face_mode); 
     for(i = 0; i < face->mNumIndices; i++){ 
      int vertexIndex = face->mIndices[i]; // get group index for current index 
      if(mesh->mColors[0] != NULL) 
       Color4f(&mesh->mColors[0][vertexIndex]); 
      if(mesh->mNormals != NULL) 
       if(mesh->HasTextureCoords(0)){ 
        glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, 1- mesh->mTextureCoords[0][vertexIndex].y);      
       } 
       glNormal3fv(&mesh->mNormals[vertexIndex].x); 
       glVertex3fv(&mesh->mVertices[vertexIndex].x); 
     } 
     glEnd(); 
    } 
} 
// draw all children 
for (n = 0; n < nd->mNumChildren; ++n) { 
    recursive_render(sc, nd->mChildren[n], scale); 
} 
glPopMatrix(); 

}

chức năng apply_material, gần như giống hệt nhau như ASSIMP cung cấp mẫu

void apply_material(const struct aiMaterial *mtl) 
{ 
float c[4]; 
GLenum fill_mode; 
int ret1, ret2; 
struct aiColor4D diffuse; 
struct aiColor4D specular; 
struct aiColor4D ambient; 
struct aiColor4D emission; 
float shininess, strength; 
int two_sided; 
int wireframe; 
unsigned int max; // changed: to unsigned 
int texIndex = 0; 
aiString texPath; //contains filename of texture 
if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath)) { 
    unsigned int texId = textureIdMap[texPath.data]; 
    glBindTexture(GL_TEXTURE_2D, texId); 
} 

set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f); 
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse)) 
    color4_to_float4(&diffuse, c); 
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c); 
set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f); 
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient)) 
    color4_to_float4(&ambient, c); 
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c); 
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); 
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular)) 
    color4_to_float4(&specular, c); 
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); 
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f); 
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission)) 
    color4_to_float4(&emission, c); 
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c); 

max = 1; 
ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max); 
max = 1; 
ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max); 
if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) 
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength); 
else { 
    glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f); 
    set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f); 
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); 
} 

max = 1; 
if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max)) 
    fill_mode = wireframe ? GL_LINE : GL_FILL; 
else 
    fill_mode = GL_FILL; 
glPolygonMode(GL_FRONT_AND_BACK, fill_mode); 

max = 1; 
if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided) 
    glEnable(GL_CULL_FACE); 
else 
    glDisable(GL_CULL_FACE); 
} 

và cũng loadGLtextures chức năng, tôi không nghĩ rằng nó có liên quan với tiêu huỷ khó khăn.

int LoadGLTextures(const aiScene* scene) { 
ILboolean success; 
/* initialization of DevIL */ 
ilInit(); 
/* scan scene's materials for textures */ 
for (unsigned int m=0; m<scene->mNumMaterials; ++m) { 
    int texIndex = 0; 
    aiString path; // filename 
    aiReturn texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path); 
    while (texFound == AI_SUCCESS) { 
     //fill map with textures, OpenGL image ids set to 0 
     textureIdMap[path.data] = 0; 
     // more textures? 
     texIndex++; 
     texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path); 
    } 
} 

int numTextures = textureIdMap.size(); 
/* create and fill array with DevIL texture ids */ 
ILuint* imageIds = new ILuint[numTextures]; 
ilGenImages(numTextures, imageIds); 
/* create and fill array with GL texture ids */ 
GLuint* textureIds = new GLuint[numTextures]; 
glGenTextures(numTextures, textureIds); /* Texture name generation */ 

/* get iterator */ 
std::map<std::string, GLuint>::iterator itr = textureIdMap.begin(); 
printf("TextureIDMap Begin %i\n", textureIdMap.begin()); 
int i=0; 
for (; itr != textureIdMap.end(); ++i, ++itr) { 
    //save IL image ID 
    std::string filename = (*itr).first; // get filename 
    (*itr).second = textureIds[i]; // save texture id for filename in map 
    printf("Texture loaded: %s\n",filename.c_str()); 
    printf("Texture ID Map End: %i\n",textureIdMap.end()); 
    ilBindImage(imageIds[i]); /* Binding of DevIL image name */ 
    ilEnable(IL_ORIGIN_SET); 
    ilOriginFunc(IL_ORIGIN_LOWER_LEFT); 
    success = ilLoadImage((ILstring)filename.c_str()); 

    if (success) { 
     /* Convert image to RGBA */ 
     ilConvertImage(IL_RGBA, IL_UNSIGNED_BYTE); 

     /* Create and load textures to OpenGL */ 
     glBindTexture(GL_TEXTURE_2D, textureIds[i]); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ilGetInteger(IL_IMAGE_WIDTH), 
      ilGetInteger(IL_IMAGE_HEIGHT), 0, GL_RGBA, GL_UNSIGNED_BYTE, 
      ilGetData()); 
    } 
    else 
     printf("Couldn't load Image: %s\n", filename.c_str()); 
} 
/* Because we have already copied image data into texture data we can release memory used by image. */ 
ilDeleteImages(numTextures, imageIds); 
//Cleanup 
delete [] imageIds; 
delete [] textureIds; 
//return success; 
return true; 
} 

Lighthouse 3D đã cho an example để làm điều này, tuy nhiên, tại thời điểm này tôi không thể thực hiện GLSL và VAO để chương trình của tôi. Bất kì giải pháp nào? Cảm ơn trước.

+0

Tôi có thể sai nhưng có thể vấn đề không phải là kết cấu mà là với vật liệu. –

+0

bạn có bất kỳ ý tưởng gì có thể gây ra vấn đề vật chất? cảm ơn .. – snowball147

+0

Tôi đã thử hướng dẫn của Lighthouse 3D, nhưng tôi không thể tải xuống mô hình – SpicyWeenie

Trả lời

8

Tôi đã tìm được giải pháp thay thế. Tôi đã thay đổi như thế nào để truy cập vào kết cấu trong recursive_render chức năng sử dụng đoạn mã sau:

glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, mesh->mTextureCoords[0][vertexIndex].y); 

thay vì:

glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, 1-mesh->mTextureCoords[0][vertexIndex].y); 
+0

Tôi đang sử dụng Assimp với GLSL, kết cấu UV từ các mô hình mà tôi cung cấp cho Assimp chỉ hoạt động khi tôi sử dụng 'glTexCoord2f (mesh-> mTextureCoords [0] [vertexIndex] .x, 1- (mesh-> mTextureCoords [0] [ vertexIndex] .y)); ' Khác tôi nhận được hành vi kỳ lạ với kết cấu.Tôi nghĩ rằng 1-y là cần thiết cho chỉ một vài mô hình – 2am

2

Đây không phải là vấn đề với kết cấu. Vấn đề của bạn là đến từ việc tiêu hủy ngược (ít nhất nó có vẻ như nó vì bạn có thể nhìn thấy bên trong con vịt). Một trong hai đa giác của bạn bị thương theo thứ tự sai hoặc việc tách khuôn mặt của bạn được thiết lập không chính xác. Nếu bạn đăng mã nơi bạn đặt cùn, chúng ta có thể thấy chính xác những gì là sai.

Cũng có thể có khả năng là một số chuẩn mực của bạn đang hướng vào trong (cũng có thể do cuộn dây đa giác). Điều đó sẽ giải thích tại sao mỏ vịt của bạn có màu đen.

+0

Cảm ơn câu trả lời của bạn. Bật/tắt culling được đặt ở cuối hàm 'apply_material'. Tôi không chắc chắn nếu vấn đề là về culling, bởi vì ngay cả khi tôi đã vô hiệu hóa các culling, vẫn còn, kết cấu sẽ không tải lên một cách chính xác. (CMIIW). Tôi đã chỉnh sửa mã. – snowball147

+0

Bạn đã thử tắt tính năng hủy hoàn toàn chưa? I E. loại bỏ câu lệnh if và chỉ đặt glDisable (GL_CULL_FACE)? – NickLH

+0

Tôi có, nhưng nó không hoạt động. – snowball147

1

Tôi chắc rằng vấn đề là kết cấu đang được 'lật' cùng Y trục. Đó là lý do tại sao '1-y' của bạn hoạt động. Nó có thể được cố định bằng cách lật kết cấu dọc theo Y trong khi tải. Mặc dù tôi vẫn chưa chắc tại sao vì chỉ có tình cờ gặp vấn đề này ngày hôm nay.

Các vấn đề liên quan