I am trying to load an OBJ model (http://pastebin.com/usGFkf4e) into an Android app using Assimp 3.1.1
Assimp model loaded like this :
bool CGameObject::LoadModelFromFile(AAssetManager *amgr, const char* sZFilePath)
{
std::string fn = sZFilePath;
std::string td = "models/";
std::string mfn = td + fn;
unsigned long size;
char* buffer;
// Load 3D model file from "assets" directory
AAsset* asset = AAssetManager_open(amgr, mfn.c_str(), AASSET_MODE_UNKNOWN);
if (asset == NULL) {
__android_log_print(ANDROID_LOG_ERROR, APPNAME, "Failed to load asset %s", mfn.c_str());
return false;
} else {
size = AAsset_getLength(asset);
buffer = new char[sizeof(char) * size];
AAsset_read(asset, buffer, size);
buffer[size] = '\0'; // !!! Important, NULL terminate the buffer
__android_log_print(ANDROID_LOG_INFO, APPNAME, "Successfully loaded asset [%s] of [SIZE] = %ld", mfn.c_str(), size);
}
Assimp::Importer importer;
const aiScene* scene = importer.ReadFileFromMemory(buffer,
size,
aiProcess_CalcTangentSpace |
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType);
if (!scene) {
return false;
}
const int iVertexTotalSize = sizeof(aiVector3D) * 2 + sizeof(aiVector2D);
int iTotalVertices = 0;
for(int i = 0; i < scene->mNumMeshes; i++) {
_Mesh* m = new _Mesh;
aiMesh* mesh = scene->mMeshes[i];
int iMeshFaces = mesh->mNumFaces;
for (int f = 0; f < iMeshFaces; f++) {
const aiFace* face = &mesh->mFaces[f];
for (int k = 0; k < 3; k++) {
aiVector3D pos = mesh->mVertices[face->mIndices[k]];
m->vertices.push_back(pos.x);
m->vertices.push_back(pos.y);
m->vertices.push_back(pos.z);
} // END face loop
// VBO
glGenBuffers(1, &m->m_vbo);
UcheckGLError("glGenBuffers");
glBindBuffer(GL_ARRAY_BUFFER, m->m_vbo);
UcheckGLError("glBindBuffer");
glBufferData(GL_ARRAY_BUFFER, m->vertices.size() * sizeof(GLfloat), &m->vertices[0], GL_STATIC_DRAW);
UcheckGLError("glBufferData");
glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, 0);
UcheckGLError("glVertexAttribPointer");
glEnableVertexAttribArray(gvPositionHandle);
UcheckGLError("glEnableVertexAttribArray");
// unbind buffers
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
m->Name.assign(mesh->mName.data, mesh->mName.length);
Meshes.push_back(m);
}
// return success when everything is loaded
return true;
}
bool UcheckGLError(const char* functionName) {
GLenum __GLerr = glGetError();
if (__GLerr != GL_NO_ERROR) {
__android_log_print(ANDROID_LOG_ERROR, APPNAME, "OpenGL failed at : %s", functionName);
}
}
Set data for frame :
void GLEngine::SetData() {
cameraX = 3.0f; cameraY = 3.0f; cameraZ = 5.0f;
// Camera/View matrix
View = glm::lookAt(
glm::vec3(cameraX, cameraY, cameraZ), // Camera position
glm::vec3(0, 0, 0), // Pointing at
glm::vec3(0, 1, 0) // Angle
);
Projection = glm::perspective(45.0f, aspect, 0.1f, 10000.0f);
CGameObject *xyz = new CGameObject(glm::vec3(0, 0, 0), gvPositionHandle);
bool st = xyz->LoadModelFromFile(this->amgr, "box_simple.obj");
if (st == true) {
__android_log_print(ANDROID_LOG_ERROR, APPNAME, "box_simple.obj load SUCCESS");
} else {
__android_log_print(ANDROID_LOG_ERROR, APPNAME, "box_simple.obj load FAILED !!!");
}
gObjects.push_back(xyz);
xyz = NULL;
delete xyz;
}
inside constructor of CGameObject
CGameObject(glm::vec3 pos, GLuint gvPositionHandle) {
// Model Matrix
glm::mat4 Model = glm::translate(mat4(1.0), pos);
MVP = Projection * View * Model;
Meshes->position = MVP;
Rendering loop
void GLEngine::DrawFrame() {
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glUseProgram(programObject);
// Draw of VBO ---BEGIN
for (GameObjects::iterator i = gObjects.begin(); i != gObjects.end(); ++i)
{
CGameObject* pObj = *i;
/////////////////
for (int x = 0; x < pObj->Meshes.size(); x++)
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
// bind VBO you want to draw
glBindBuffer(GL_ARRAY_BUFFER, pObj->Meshes[x]->m_vbo);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &pObj->Meshes[x]->position[0][0]);
glDrawArrays(GL_TRIANGLES, 0, pObj->Meshes[x]->vertices.size());
// unbind VBO
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
/////////////////
}
// Draw of VBO ---END
// unbind program
glUseProgram(0);
}
This is what I get :
But if I specify position for second mesh in my DrawFrame() like this :
if (x == 1) // 1 for second mesh, loop starts from 0
{
glm::mat4 _Model = glm::translate(mat4(1.0), glm::vec3(0.0f, 2.0f, 0.0f));
pObj->Meshes[x]->position = Projection * View * _Model;
}
the I get result like this :
I have same loading code in a desktop OpenGL 4 windows application and it works there.