Loaded OBJ Model Will Not Display in OpenGL / C++ Project

Posted by Drake Summers on Game Development See other posts from Game Development or by Drake Summers
Published on 2014-04-02T20:00:03Z Indexed on 2014/06/02 21:50 UTC
Read the original article Hit count: 296

Filed under:
|

I have been experimenting with new effects in game development. The programs I have written have been using generic shapes for the visuals. I wanted to test the effects on something a bit more complex, and wrote a resource loader for Wavefront OBJ files. I started with a simple cube in blender, exported it to an OBJ file with just vertices and triangulated faces, and used it to test the resource loader.

I could not get the mesh to show up in my application. The loader never gave me any errors, so I wrote a snippet to loop through my vertex and index arrays that were returned from the loader. The data is exactly the way it is supposed to be. So I simplified the OBJ file by editing it directly to just show a front facing square. Still, nothing is displayed in the application.

And don't worry, I did check to make sure that I decreased the value of each index by one while importing the OBJ.

-

BEGIN EDIT

I also tested using glDrawArrays(GL_TRIANGLES, 0, 3 ); to draw the first triangle and it worked! So the issue could be in the binding of the VBO/IBO items.

END EDIT

-

INDEX/VERTEX ARRAY OUTPUT:

Console Output of Index/Vertex Array Data

GLOBALS AND INITIALIZATION FUNCTION:

GLuint program;
GLint  attrib_coord3d;
std::vector<GLfloat> vertices;
std::vector<GLushort> indices;
GLuint vertexbuffer, indexbuffer;
GLint uniform_mvp;


int initialize()
{
    if (loadModel("test.obj", vertices, indices))
    {
        GLfloat myverts[vertices.size()];
        copy(vertices.begin(), vertices.end(), myverts);
        GLushort myinds[indices.size()];
        copy(indices.begin(), indices.end(), myinds);

        glGenBuffers(1, &vertexbuffer);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(myverts), myverts, GL_STATIC_DRAW);

        glGenBuffers(1, &indexbuffer);
        glBindBuffer(GL_ARRAY_BUFFER, indexbuffer);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(myinds), myinds, GL_STATIC_DRAW);

        // OUTPUT DATA FROM NEW ARRAYS TO CONSOLE
        // ERROR HANDLING OMITTED FOR BREVITY
    }

    GLint link_result = GL_FALSE;
    GLuint vert_shader, frag_shader;

    if ((vert_shader = create_shader("tri.v.glsl", GL_VERTEX_SHADER))   == 0) return 0;
    if ((frag_shader = create_shader("tri.f.glsl", GL_FRAGMENT_SHADER)) == 0) return 0;

    program = glCreateProgram();
    glAttachShader(program, vert_shader);
    glAttachShader(program, frag_shader);
    glLinkProgram(program);
    glGetProgramiv(program, GL_LINK_STATUS, &link_result);
    // ERROR HANDLING OMITTED FOR BREVITY

    const char* attrib_name;
    attrib_name    = "coord3d";
    attrib_coord3d = glGetAttribLocation(program, attrib_name);
    // ERROR HANDLING OMITTED FOR BREVITY

    const char* uniform_name;
    uniform_name = "mvp";
    uniform_mvp = glGetUniformLocation(program, uniform_name);
    // ERROR HANDLING OMITTED FOR BREVITY

    return 1;
}

RENDERING FUNCTION:

glm::mat4 model      = glm::translate(glm::mat4(1.0f), glm::vec3(0.0, 0.0, -4.0));
glm::mat4 view       = glm::lookAt(glm::vec3(0.0, 0.0, 4.0), glm::vec3(0.0, 0.0, 3.0), glm::vec3(0.0, 1.0, 0.0));
glm::mat4 projection = glm::perspective(45.0f, 1.0f*(screen_width/screen_height), 0.1f, 10.0f);
glm::mat4 mvp        = projection * view * model;

int size;

glUseProgram(program);
glUniformMatrix4fv(uniform_mvp, 1, GL_FALSE, glm::value_ptr(mvp));

glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glEnableVertexAttribArray(attrib_coord3d);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(attrib_coord3d, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexbuffer);

glGetBufferParameteriv(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_SIZE, &size);
glDrawElements(GL_TRIANGLES, size/sizeof(GLushort), GL_UNSIGNED_SHORT, 0);

glDisableVertexAttribArray(attrib_coord3d);

VERTEX SHADER:

attribute vec3 coord3d;
uniform mat4 mvp;
void main(void)
{
    gl_Position = mvp * vec4(coord3d, 1.0);
}

FRAGMENT SHADER:

void main(void)
{
    gl_FragColor[0] = 0.0;
    gl_FragColor[1] = 0.0;
    gl_FragColor[2] = 1.0;
    gl_FragColor[3] = 1.0;
}

OBJ RESOURCE LOADER:

bool loadModel(const char * path, std::vector<GLfloat> &out_vertices, std::vector<GLushort> &out_indices)
{
    std::vector<GLfloat> temp_vertices;
    std::vector<GLushort> vertexIndices;
    FILE * file = fopen(path, "r");
    // ERROR HANDLING OMITTED FOR BREVITY

    while(1)
    {
        char lineHeader[128];
        int res = fscanf(file, "%s", lineHeader);
        if (res == EOF) { break; }

        if (strcmp(lineHeader, "v") == 0)
        {
            float _x, _y, _z;
            fscanf(file, "%f %f %f\n", &_x, &_y, &_z );
            out_vertices.push_back(_x);
            out_vertices.push_back(_y);
            out_vertices.push_back(_z);
        }
        else if (strcmp(lineHeader, "f") == 0)
        {
            unsigned int vertexIndex[3];
            int matches = fscanf(file, "%d %d %d\n", &vertexIndex[0], &vertexIndex[1], &vertexIndex[2]);
            out_indices.push_back(vertexIndex[0] - 1);
            out_indices.push_back(vertexIndex[1] - 1);
            out_indices.push_back(vertexIndex[2] - 1);
        }
        else
        {
            ...
        }
    }
    // ERROR HANDLING OMITTED FOR BREVITY
    return true;
}

I can edit the question to provide any further info you may need. I attempted to provide everything of relevance and omit what may have been unnecessary.

I'm hoping this isn't some really poor mistake, because I have been at this for a few days now. If anyone has any suggestions or advice on the matter, I look forward to hearing it.

As a final note:

I added some arrays into the code with manually entered data, and was able to display meshes by using those arrays instead of the generated ones. I do not understand!

© Game Development or respective owner

Related posts about opengl

Related posts about c++