3DS File Doesn’t Render Correctly OpenGL

  3ds, 3dsmax, c++, opengl, rendering

I’m having a rendering issue with my .3DS model that I’m trying to draw:
enter image description here

It’s supposed to be a blender, but as you can see it does not resemble that at all.
Here’s my loading code:

void Model::load(std::string fileName)
{
    unsigned short chunkID;
    unsigned int chunkLength;

    FILE* file = fopen(fileName.c_str(), "rb");
    if (file == NULL) { std::cout << "Cannot open file: " << fileName << std::endl; exit(1); }
    else
    {
        int filelength;
        fseek(file, 0, SEEK_END);
        filelength = ftell(file);
        fseek(file, 0, SEEK_SET);

        while (ftell(file) < filelength)
        {
            fread(&chunkID, 2, 1, file);
            fread(&chunkLength, 4, 1, file);
            switch(chunkID)
            {
                case 0x4d4d:
                break;

                case 0x3d3d:
                break;

                case 0x4000:
                {
                    char nextCharacter;
                    do
                    {
                        fread(&nextCharacter, 1, 1, file);
                        modelName += nextCharacter;
                    } while (nextCharacter != '{$content}');
                }
                break;

                case 0x4100:
                break;

                case 0x4110:
                {
                    unsigned short vertexCount;
                    fread(&vertexCount, sizeof(unsigned short), 1, file);
                    this->vertexCount = vertexCount;
                    std::cout << "Number of vertices in model: " << this->vertexCount << std::endl;
                    Vertex nextVertex;
                    for (int i = 0; i < this->vertexCount; i++)
                    {
                        fread(&nextVertex.position.x, sizeof(float), 1, file);
                        fread(&nextVertex.position.y, sizeof(float), 1, file);
                        fread(&nextVertex.position.z, sizeof(float), 1, file);
                        //nextVertex.position.z *= -1;
                        vertices.push_back(nextVertex);
                    }
                }
                break;

                case 0x4120:
                {
                    unsigned short polygonCount;
                    fread(&polygonCount, sizeof(unsigned short), 1, file);
                    this->polygonCount = polygonCount;
                    std::cout << "Number of Polygons in model: " << this->polygonCount << std::endl;
                    Face nextFace;
                    unsigned short faceFlags;
                    for (int i = 0; i < this->polygonCount; i++)
                    {
                        fread(&nextFace.a, sizeof(unsigned short), 1, file);
                        fread(&nextFace.b, sizeof(unsigned short), 1, file);
                        fread(&nextFace.c, sizeof(unsigned short), 1, file);
                        fread(&faceFlags, sizeof(unsigned short), 1, file);
                        faces.push_back(nextFace);
                    }
                }
                break;

                case 0x4140:
                {
                    unsigned short uvCount;
                    fread(&uvCount, sizeof(unsigned short), 1, file);
                    this->uvCount = uvCount;
                    std::cout << "Number of UV Coordinates in model: " << this->uvCount << std::endl;
                    for (int i = 0; i < this->uvCount; i++)
                    {
                        fread(&vertices[i].uv.x, sizeof(float), 1, file);
                        fread(&vertices[i].uv.y, sizeof(float), 1, file);
                    }
                }
                break;

                default:
                    fseek(file, chunkLength - 6, SEEK_CUR);
                break;
            }
        }
        fclose(file);
    }

Here’s how I set up my VBO and prepared the data for rendering:

glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    bufferData = new float[9 * faces.size()]; // 3 vertexes (3 floats each) per face, so 9 * faces.size()

    for (int i = 0; i < (int)faces.size(); i++)
    {
        // --------------- First Vertex -------------------
        bufferData[i + 0] = vertices[faces[i].a].position.x;
        bufferData[i + 1] = vertices[faces[i].a].position.y;
        bufferData[i + 2] = vertices[faces[i].a].position.z;

        // --------------- Second Vertex -------------------
        bufferData[i + 3] = vertices[faces[i].b].position.x;
        bufferData[i + 4] = vertices[faces[i].b].position.y;
        bufferData[i + 5] = vertices[faces[i].b].position.z;

        // --------------- Third Vertex -------------------
        bufferData[i + 6] = vertices[faces[i].c].position.x;
        bufferData[i + 7] = vertices[faces[i].c].position.y;
        bufferData[i + 8] = vertices[faces[i].c].position.z;
    }

    // Array buffer with 9 verts per face all of which are floats
    glBufferData(GL_ARRAY_BUFFER, 9 * faces.size() * sizeof(float), bufferData, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0); // Enabled for positions

    // Start at element 0, 3 coordinates per vertex, not normalized, our stride is 3 * sizeof(float)
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);

And here’s how I draw the data:

    // Draws triangles. Starts at index 0 and draws as many triangles as we have faces (1 face = 1 triangle)
    glDrawArrays(GL_TRIANGLES, 0, faces.size());

Any ideas why this could be happening?

Source: Windows Questions C++

LEAVE A COMMENT