2
\$\begingroup\$

I'm building a 3D game, and i'm trying to load some assets with the nice Assimp library. The model should look like the one in the first picture, but instead, it takes the form of some kind of avant-garde sculpture, as the second picture shows.

Blender render My OpenGL & Assimp powered render

At least i'm proud that i get to see something, but hey, i can do better.

It's not a problem with shaders (it simply isn't, i pass no normals and no textures, just the vertex coordinate, since i set a static colour). Here is my code:

MODEL LOADING (only vertex coordinates)

void Mesh::open(const std::string file)
{
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(file, aiProcess_Triangulate);
if(!scene)
    throw STREAM("Could open mesh '" << file << "'!");

std::vector<float> g_vp;
count = 0;

for(uint m_i = 0; m_i < scene->mNumMeshes; m_i++)
{
    const aiMesh* mesh = scene->mMeshes[0];
    g_vp.reserve(3 * mesh->mNumVertices);
    count += mesh->mNumVertices;

    for(uint v_i = 0; v_i < mesh->mNumVertices; v_i++)
    {
        if(mesh->HasPositions())
        {
            const aiVector3D* vp = &(mesh->mVertices[v_i]);
            g_vp.push_back(vp->x);
            g_vp.push_back(vp->y);
            g_vp.push_back(vp->z);
        }
    }
}

glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, count * 3 * sizeof(float), &g_vp[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL);
}

SCENE RENDERING

void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

program.use();
program.setUniform("transformMat", modelMat);
glBindBuffer(GL_ARRAY_BUFFER, m.vbo);
glDrawArrays(GL_TRIANGLES, 0, m.count);

SDL_GL_SwapWindow(window->mWin);
}

Depth testing is enabled, and i'm using OpenGL 4.0 with v400 shaders too.

The error will possibly be stupid, but i can't find it, and my head is all boiling at this very moment.

Thanks for your help!

\$\endgroup\$
8
  • \$\begingroup\$ Quick note: you should probably put your if statement testing if the mesh has positions outside of the for loop for vertices. That way it won't test every iteration of the loop. \$\endgroup\$
    – chbaker0
    Commented Jan 5, 2014 at 20:42
  • \$\begingroup\$ I see you made it in Blender. What file format are you loading from? Personally, I've had issues loading from .blend files, so I usually export a Collada (.dae) file from Blender and load from that. \$\endgroup\$
    – chbaker0
    Commented Jan 5, 2014 at 20:46
  • \$\begingroup\$ First thing to do if you can't see something you expect to is to diable back-face culling; your normals might just be flipped (there is a flag in Assimp to have it try to fix them, though it may not work). Bad input gives bad output. \$\endgroup\$ Commented Jan 5, 2014 at 20:49
  • \$\begingroup\$ I haven't made the model, but nevertheless i load the DAE file, both in Blender and the engine itself. And i guess that back-face culling is not a problem if i just don't load the normals, as i've stated in the original post. \$\endgroup\$ Commented Jan 5, 2014 at 21:02
  • \$\begingroup\$ @PolGomezRiquelme backface culling is still a problem if you don't load normals: backface culling doesn't care about normals, it looks at which way the vertices "wind" in each triangle (i.e., counterclockwise or clockwise), depending on the vertex ordering in your array, and doesn't render triangles that wind in the direction you specify as the "back" winding order. \$\endgroup\$
    – chbaker0
    Commented Jan 5, 2014 at 21:52

1 Answer 1

2
\$\begingroup\$

Reposting comment as answer.

In the for loop below you are only ever reading from the first mesh in the scene. Depending on how you've modeled it, it may be composed of multiple meshes. I have fixed the loop below replacing scene->mMeshes[0] with scene->mMeshes[m_i] to ensure that all meshes' positions are added to the vertex buffer.

for(uint m_i = 0; m_i < scene->mNumMeshes; m_i++)
{
    const aiMesh* mesh = scene->mMeshes[m_i];
    g_vp.reserve(3 * mesh->mNumVertices);
    count += mesh->mNumVertices;

    for(uint v_i = 0; v_i < mesh->mNumVertices; v_i++)
    {
        if(mesh->HasPositions())
        {
            const aiVector3D* vp = &(mesh->mVertices[v_i]);
            g_vp.push_back(vp->x);
            g_vp.push_back(vp->y);
            g_vp.push_back(vp->z);
        }
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .