Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am trying to load an OBJ model (http://pastebin.com/usGFkf4e) into an Android app using Assimp 3.1.1

enter image description here

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 :

enter image description here

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 :

enter image description here

I have same loading code in a desktop OpenGL 4 windows application and it works there.

share|improve this question

1 Answer 1

I got this working. Adding these two lines in my rendering function DrawFrame() :

glEnableVertexAttribArray(gvPositionHandle);
glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, 0);

solved it.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.