void Model3D::loadModel(const char* fileName) { std::string fn(fileName); foldername = fn.substr(0, fn.find_last_of("/\\") + 1); //printf("%s foldername\n", foldername.c_str()); scene = aiImportFile(fileName, aiProcessPreset_TargetRealtime_Quality); recursiveTextureLoad(scene, scene->mRootNode); get_bounding_box(&min, &max); if ((max.x - min.x > max.y - min.y) && (max.x - min.x > max.z - min.z)) scale = max.x - min.x; else if ((max.y - min.y > max.x - min.x) && (max.y - min.y > max.z - min.z)) scale = max.y - min.y; else if ((max.z - min.z > max.y - min.y) && (max.z - min.z > max.x - min.x)) scale = max.z - min.z; }
/* ---------------------------------------------------------------------------- */ int Model::loadasset (const char* path) { math::Clock clock; math::tick_t t1 = clock.Tick(); /* we are taking one of the postprocessing presets to avoid spelling out 20+ single postprocessing flags here. */ scene = aiImportFile(path,aiProcessPreset_TargetRealtime_MaxQuality); if (scene) { get_bounding_box(&scene_min,&scene_max); scene_center.x = (scene_min.x + scene_max.x) / 2.0f; scene_center.y = (scene_min.y + scene_max.y) / 2.0f; scene_center.z = (scene_min.z + scene_max.z) / 2.0f; std::cout << "ms loadasset: " << path << " " << clock.MillisecondsSinceF(t1) << " ms\n"; recursiveTextureLoad(scene, scene->mRootNode); return 1; } std::cout << "ms loadasset failed: " << clock.MillisecondsSinceF(t1) << " ms\n"; return 0; }
// basado en http://www.gamedev.net/topic/582240-assimp-drawing-textured-model/ void Model::recursiveTextureLoad(const struct aiScene *sc, const struct aiNode* nd) { int i; unsigned int n = 0, t; aiMatrix4x4 m = nd->mTransformation; // update transform aiTransposeMatrix4(&m); glPushMatrix(); glMultMatrixf((float*)&m); // draw all meshes assigned to this node for (; n < nd->mNumMeshes; ++n) { const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[n]]; unsigned int cont = aiGetMaterialTextureCount(sc->mMaterials[mesh->mMaterialIndex], aiTextureType_DIFFUSE); struct aiString* str = (aiString*)malloc(sizeof(struct aiString)); if(cont > 0) { //aiGetMaterialString(sc->mMaterials[mesh->mMaterialIndex],AI_MATKEY_TEXTURE_DIFFUSE(0),str); aiGetMaterialTexture(sc->mMaterials[mesh->mMaterialIndex],aiTextureType_DIFFUSE,0,str,0,0,0,0,0,0); // See if another mesh is already using this texture, if so, just copy GLuint instead of remaking entire texture bool newTextureToBeLoaded = true; for(int x = 0; x < texturesAndPaths.size(); x++) { if(texturesAndPaths[x].pathName == *str) { TextureAndPath reusedTexture; reusedTexture.hTexture = texturesAndPaths[x].hTexture; reusedTexture.pathName = *str; texturesAndPaths.push_back(reusedTexture); newTextureToBeLoaded = false; std::cout << "Texture reused." << std::endl; break; } } if(newTextureToBeLoaded) { FREE_IMAGE_FORMAT formato = FreeImage_GetFileType(str->data,0); //Automatocally detects the format(from over 20 formats!) FIBITMAP* imagen = FreeImage_Load(formato, str->data); FIBITMAP* temp = imagen; imagen = FreeImage_ConvertTo32Bits(imagen); FreeImage_Unload(temp); int w = FreeImage_GetWidth(imagen); int h = FreeImage_GetHeight(imagen); //Some debugging code char* pixeles = (char*)FreeImage_GetBits(imagen); //FreeImage loads in BGR format, so you need to swap some bytes(Or use GL_BGR). //Now generate the OpenGL texture object TextureAndPath newTexture; newTexture.pathName = *str; glGenTextures(1, &newTexture.hTexture); glBindTexture(GL_TEXTURE_2D, newTexture.hTexture); glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, w, h, 0, GL_BGRA_EXT,GL_UNSIGNED_BYTE,(GLvoid*)pixeles ); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, newTexture.hTexture); GLenum huboError = glGetError(); if(huboError) { std::cout<<"There was an error loading the texture"<<std::endl; } std::cout << "texture loaded." << std::endl; texturesAndPaths.push_back(newTexture); } } } // Get textures from all children for (n = 0; n < nd->mNumChildren; ++n) recursiveTextureLoad(sc, nd->mChildren[n]); }
void Model3D::recursiveTextureLoad(const struct aiScene *sc, const struct aiNode* nd) { int i; unsigned int n = 0, t; struct aiMatrix4x4 m = nd->mTransformation; // update transform aiTransposeMatrix4(&m); glPushMatrix(); glMultMatrixf((float*) &m); // draw all meshes assigned to this node for (; n < nd->mNumMeshes; ++n) { const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[n]]; unsigned int cont = aiGetMaterialTextureCount(sc->mMaterials[mesh->mMaterialIndex], aiTextureType_AMBIENT); struct aiString* str = (aiString*) malloc(sizeof(struct aiString)); if (cont > 0) { //aiGetMaterialString(sc->mMaterials[mesh->mMaterialIndex],AI_MATKEY_TEXTURE_DIFFUSE(0),str); aiGetMaterialTexture(sc->mMaterials[mesh->mMaterialIndex], aiTextureType_AMBIENT, 0, str, 0, 0, 0, 0, 0, 0); // See if another mesh is already using this texture, if so, just copy GLuint instead of remaking entire texture bool newTextureToBeLoaded = true; for (int x = 0; x < texturesAndPaths.size(); x++) { if (texturesAndPaths[x].pathName == *str) { TextureAndPath reusedTexture; reusedTexture.hTexture = texturesAndPaths[x].hTexture; reusedTexture.pathName = *str; //printf("%s pathnm \n", reusedTexture.pathName.data); texturesAndPaths.push_back(reusedTexture); newTextureToBeLoaded = false; std::cout << "Texture reused." << std::endl; break; } } if (newTextureToBeLoaded) { texturename.clear(); texturename.append(foldername.c_str()); texturename.append(str->data); std::cout << texturename.c_str() << " strname \n"; Mat imagen=imread(texturename.c_str()); int w = imagen.cols; int h = imagen.rows; int dataSize=imagen.cols*imagen.rows*3; unsigned char* data=new unsigned char[dataSize]; int j=0; for( int y = 0; y < imagen.rows; y++ ) { for( int x = 0; x < imagen.cols; x++ ) { for( int c = 0; c < 3; c++ ) { data[j] = imagen.at<Vec3b>(y,x)[c]; j++; } } } //Now generate the OpenGL texture object TextureAndPath newTexture; newTexture.pathName = *str; glGenTextures(1, &newTexture.hTexture); glBindTexture(GL_TEXTURE_2D, newTexture.hTexture); //glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA, w, h, 0, GL_BGR,GL_UNSIGNED_BYTE,(GLvoid*)pixeles ); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imagen.cols, imagen.rows, GL_BGR_EXT, GL_UNSIGNED_BYTE, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindTexture(GL_TEXTURE_2D, newTexture.hTexture); GLenum huboError = glGetError(); if (huboError) { std::cout << "There was an error loading the texture" << std::endl; } std::cout << "texture loaded." << std::endl; texturesAndPaths.push_back(newTexture); } } } // Get textures from all children for (n = 0; n < nd->mNumChildren; ++n) recursiveTextureLoad(sc, nd->mChildren[n]); }