texture mapping with lib3ds and SOIL help

Posted by Adam West on Game Development See other posts from Game Development or by Adam West
Published on 2012-04-01T10:37:18Z Indexed on 2012/04/01 17:44 UTC
Read the original article Hit count: 459

Filed under:
|

I'm having trouble with my project for loading a texture map onto a model. Any insight into what is going wrong with my code is fantastic. Right now the code only renders a teapot which I have assinged after creating it in 3DS Max.

3dsloader.cpp

#include "3dsloader.h"


Object::Object(std:: string filename)
{
m_TotalFaces = 0;
m_model = lib3ds_file_load(filename.c_str());
// If loading the model failed, we throw an exception
if(!m_model)
{
    throw strcat("Unable to load ", filename.c_str());
}

    // set properties of texture coordinate generation for both x and y coordinates
        glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
        glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
        // if not already enabled, enable texture generation
        if(! glIsEnabled(GL_TEXTURE_GEN_S))
            glEnable(GL_TEXTURE_GEN_S);
        if(! glIsEnabled(GL_TEXTURE_GEN_T))
        glEnable(GL_TEXTURE_GEN_T);




}

Object::~Object()
{
    if(m_model) // if the file isn't freed yet
        lib3ds_file_free(m_model); //free up memory
    glDisable(GL_TEXTURE_GEN_S);
    glDisable(GL_TEXTURE_GEN_T);
}


void Object::GetFaces()
{
    m_TotalFaces = 0;
    Lib3dsMesh * mesh;

    // Loop through every mesh.

    for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
    {
        // Add the number of faces this mesh has to the total number of faces.

        m_TotalFaces += mesh->faces;
    }    

}

void Object::CreateVBO()
    {
        assert(m_model != NULL);

        // Calculate the number of faces we have in total
        GetFaces();

        // Allocate memory for our vertices and normals
        Lib3dsVector * vertices = new Lib3dsVector[m_TotalFaces * 3];
        Lib3dsVector * normals = new Lib3dsVector[m_TotalFaces * 3];
        Lib3dsTexel* texCoords = new Lib3dsTexel[m_TotalFaces * 3];

        Lib3dsMesh * mesh;
        unsigned int FinishedFaces = 0;
        // Loop through all the meshes
        for(mesh = m_model->meshes;mesh != NULL;mesh = mesh->next)
        {
            lib3ds_mesh_calculate_normals(mesh, &normals[FinishedFaces*3]);
            // Loop through every face
            for(unsigned int cur_face = 0; cur_face < mesh->faces;cur_face++)
            {
                Lib3dsFace * face = &mesh->faceL[cur_face];
                for(unsigned int i = 0;i < 3;i++)
                {


                memcpy(&texCoords[FinishedFaces*3 + i], mesh->texelL[face->points[ i ]], sizeof(Lib3dsTexel)); 

                memcpy(&vertices[FinishedFaces*3 + i], mesh->pointL[face->points[ i ]].pos, sizeof(Lib3dsVector));
                }

                FinishedFaces++;
            }
        }



        // Generate a Vertex Buffer Object and store it with our vertices
        glGenBuffers(1, &m_VertexVBO);
        glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, vertices, GL_STATIC_DRAW);

        // Generate another Vertex Buffer Object and store the normals in it
        glGenBuffers(1, &m_NormalVBO);
        glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsVector) * 3 * m_TotalFaces, normals, GL_STATIC_DRAW);

        // Generate a third VBO and store the texture coordinates in it. 

        glGenBuffers(1, &m_TexCoordVBO);
        glBindBuffer(GL_ARRAY_BUFFER, m_TexCoordVBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(Lib3dsTexel) * 3 * m_TotalFaces, texCoords, GL_STATIC_DRAW);


        // Clean up our allocated memory
        delete vertices;
        delete normals;
        delete texCoords;


        // We no longer need lib3ds
        lib3ds_file_free(m_model);
        m_model = NULL;
    }

void Object::applyTexture(const char*texfilename)
{

    float imageWidth;
    float imageHeight;

        glGenTextures(1, & textureObject); // allocate memory for one texture

         textureObject = SOIL_load_OGL_texture(texfilename,SOIL_LOAD_AUTO,SOIL_CREATE_NEW_ID,SOIL_FLAG_MIPMAPS);

        glPixelStorei(GL_UNPACK_ALIGNMENT,1);
        glBindTexture(GL_TEXTURE_2D,  textureObject); // use our newest texture
        glGetTexLevelParameterfv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&imageWidth);
        glGetTexLevelParameterfv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&imageHeight);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // give the best result for texture magnification
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //give the best result for texture minification
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); // don't repeat texture 
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // don't repeat textureglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); // don't repeat texture
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_MODULATE);
        glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,imageWidth,imageHeight,0,GL_RGB,GL_UNSIGNED_BYTE,& textureObject);

}


void Object::Draw() const
{
    // Enable vertex, normal and texture-coordinate arrays.

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);  

    // Bind the VBO with the normals.

    glBindBuffer(GL_ARRAY_BUFFER, m_NormalVBO);

    // The pointer for the normals is NULL which means that OpenGL will use the currently bound VBO.

    glNormalPointer(GL_FLOAT, 0, NULL);

    glBindBuffer(GL_ARRAY_BUFFER, m_TexCoordVBO);    
    glTexCoordPointer(2, GL_FLOAT, 0, NULL);    

    glBindBuffer(GL_ARRAY_BUFFER, m_VertexVBO);
    glVertexPointer(3, GL_FLOAT, 0, NULL);

    // Render the triangles.

    glDrawArrays(GL_TRIANGLES, 0, m_TotalFaces * 3);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);    
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

3dsloader.h

#include "main.h"
#include "lib3ds/file.h"
#include "lib3ds/mesh.h"
#include "lib3ds/material.h"


class Object
{
public:
    Object(std:: string filename);
    virtual ~Object();
     virtual void Draw() const;
    virtual void CreateVBO();
    void applyTexture(const char*texfilename);

protected:
    void GetFaces();
    unsigned int m_TotalFaces;
    Lib3dsFile * m_model;
    Lib3dsMesh* Mesh;
    GLuint textureObject;
    GLuint m_VertexVBO, m_NormalVBO, m_TexCoordVBO;

};

Called in the main cpp file with: VBO,apply texture and draw (pretty simple, how ironic) and thats it, please help me forum :)

© Game Development or respective owner

Related posts about c++

Related posts about opengl