OpenGL,DevIL,带纹理的obj加载器

时间:2013-11-01 13:50:28

标签: c++ opengl textures devil

我写了一个obj加载器,据我所知,所有加载工作都很好,但是当我尝试绘制纹理时,它不起作用。

我看着魔鬼,加载后没有任何错误,一切都有数据,但是当我绘制它时不会显示图像只是黑色。

你们有什么可以推荐的吗? 我已经看了几件事,但找不到解决办法。

我如何做事 我有一个纹理创建的mtl

Loader.h

#pragma once
#include "typedef.h"
#include <string>
#include <vector>
#include <fstream>

#include "MTL.h"
#include "../freeglut.h"

#include <iostream> // this is just for testing, you can remove this with all the cout's

class Loader
{
public:
    /**
     *  \brief string location of the obj file
     *  
     *  In Order for you to Load the 3D object you need to specify its location 
     *  in a string. 
     *  
     *  
     */
    Loader( std::string input);

    ~Loader(void);


    void draw(); // this function takes the obj file and draws it

    //this can be ignored, it does not make any changes to the problem
    void move(float x, float y, float z);
    void getPos();
    void setPos(float x, float y, float z); // set position
    void find_box(float &maxX,float &minX,float &maxY, float &minY, float &maxZ,float &minZ);

private:




    std::ifstream m_inFile;

    // the list of vectors that i will be using
    std::vector<points> m_points;
    std::vector<normal> m_normals;
    std::vector<coordinate> m_coords;

    std::vector<MTL> m_mtl;

    std::vector<face> m_faces;

    void process(std::string input);
    void processMTL(std::string input);

    void inputPoints(points temp);
    void inputNormals(normal temp);
    void inputCoordinates(coordinate temp);
    void createFaces(face temp);


};

Loader.cpp

void Loader::process(std::string input)
{
    std::string identifier; //used to identify where the input should go


    points temppoint;
    normal tempnormal;
    coordinate tempcoord;
    face tempface; 


    std::string read;       // used to read the curent line

    int readNum; // this is the number that has just been read in
    char skip; // a char to skip thr /
    int i;
    int count= 1;

    //other things to take into account
    //****************************************
    std::string l_name;
    bool firstRun = true;
    std::string parse;
    //**************************************


    m_inFile.open(input);



    //creation of the reading loop

    m_inFile >> identifier;

    do {
         // check to see what the opening is

        if (identifier =="#")
        {
            getline(m_inFile,read); // use this to read the whole line

        }
        else if(identifier == "v")
        {
            m_inFile >> temppoint.x >> temppoint.y >> temppoint.z;
            inputPoints(temppoint);
        }
        else if(identifier == "vn")
        {
            m_inFile >> tempnormal.vn[0] >> tempnormal.vn[1] >> tempnormal.vn[2];
            inputNormals(tempnormal);
        }
        else if (identifier == "vt")
        {
            m_inFile >> tempcoord.vt[0] >> tempcoord.vt[1] >> tempcoord.vt[2];
            inputCoordinates(tempcoord);
        }
        else if(identifier == "f")
        {


            for( i =0; i < 3; i++)
            {
                count++;


                m_inFile >> readNum;
                if(readNum == 0)
                    break;
                readNum--;
                tempface.p[i].x = m_points[readNum].x;
                tempface.p[i].y = m_points[readNum].y;
                tempface.p[i].z = m_points[readNum].z;


                m_inFile >> skip >> readNum;
                readNum--;
                tempface.coord[i].vt[0] = m_coords[readNum].vt[0];
                tempface.coord[i].vt[1] = m_coords[readNum].vt[1];
                tempface.coord[i].vt[2] = m_coords[readNum].vt[2];


                m_inFile >> skip >> readNum;
                readNum--;
                tempface.norm[i].vn[0] = m_normals[readNum].vn[0];
                tempface.norm[i].vn[1] = m_normals[readNum].vn[1];
                tempface.norm[i].vn[2] = m_normals[readNum].vn[2];



            }

            tempface.name = l_name; // this gives the mtl name to the face so it can be compared and applied later

            createFaces(tempface);

        }
        else if(identifier =="mtllib")
        {
            m_inFile >> identifier;
            identifier = "test/" + identifier;
            processMTL(identifier);
        }

        else if(identifier == "usemtl")
        {
        // chnages the mtl that is being applied
            m_inFile >> read;

            l_name = read; // so the face can have 

        }
        else 
        {
            getline(m_inFile,read);
            std::cout << "Not Processed From Loader" << identifier << " " << read <<std::endl;
        }

        m_inFile >> identifier;

    } while (!m_inFile.eof());
    //m_inFile.close();
    //m_inFile.~basic_ifstream();
}



void Loader::draw()
{
    int i;
    int j;
    int k;

    std::string currentTex;

    glEnable(GL_TEXTURE_2D);
    //glDisable(GL_TEXTURE_2D);
    //glBegin(GL_TRIANGLES);

    for (i=0; i < m_faces.size();i++)
    {
        //bind a certain image 
        for (k=0; k<m_mtl.size();k++)
        {
            if (m_mtl[k].compare(m_faces[i].name) == true)
            {
                //these next two lines do the same thing
                //m_mtl[k].draw();
                glBindTexture(GL_TEXTURE_2D,m_mtl[k].getGLID());
                //break; // break out of the loop
            }

        }

        glBegin(GL_TRIANGLES);

        for(j = 0 ; j < 3; j++)
        {
            glNormal3f(m_faces[i].norm[j].vn[0],m_faces[i].norm[j].vn[1],m_faces[i].norm[j].vn[2]);
            glTexCoord2f(m_faces[i].coord[j].vt[0],m_faces[i].coord[j].vt[1]);
            glVertex3f(m_faces[i].p[j].x,m_faces[i].p[j].y,m_faces[i].p[j].z);
        }
        glEnd();

    }

}





void Loader::processMTL(std::string input)
{

    std::string identifier;
    std::string read; //for reading whole lines

    MTL mtlTemp;
    std::ifstream l_inMtl;

    //for reading in numbers to give to the mtl
    float ka0, ka1, ka2;
    float kd0, kd1, kd2;
    float ks0, ks1, ks2;

    //so that an empty mtl is not pushed back into the vector
    bool firstRun = true;

    l_inMtl.open(input);
    l_inMtl >> identifier;

    do{
        if(identifier == "#")
        {
            getline(l_inMtl,read);
        }
        else if(identifier == "newmtl")
        {
            //checks to see if it has run before if it has not run before don't push back the last read
            if (firstRun == false)
                m_mtl.push_back(mtlTemp);
            else 
                firstRun = false;


            l_inMtl >> identifier;
            mtlTemp.setName(identifier);
        }
        else if(identifier == "Ka")
        {
            l_inMtl >>ka0 >> ka1 >> ka2;
            mtlTemp.setKa(ka0,ka1,ka2);
        }
        else if(identifier == "Kd")
        {
            l_inMtl >> kd0 >>kd1 >> kd2;
            mtlTemp.setKd(kd0,kd1,kd2);
        }
        else if(identifier =="Ks")
        {
            l_inMtl >> ks0 >> ks1 >> ks2;
            mtlTemp.setKs(ks0, ks1, ks2);
        }
        else if(identifier == "map_Ka")
        {
            getline(l_inMtl,identifier);
            //l_inMtl >> identifier;
            mtlTemp.setLoc(identifier);
        }
        else
        {
            getline(l_inMtl,read);
            std::cout << "Not Processed MTL" << identifier << " " << read << std::endl;
        }
        l_inMtl >> identifier;
    }while(!l_inMtl.eof());

    l_inMtl.close();
    m_mtl.push_back(mtlTemp); // so the last one is pushed back

}

MTL.h

 #pragma once 


#include "../freeglut.h"

#include <string>
#include <fstream>
#include "typedef.h"
#include "../lib/IL/il.h"
#include <iostream>
//#include <IL/il.h>

class MTL
{
public:
    MTL(); //name of the file
    ~MTL(void);

    void bind(std::string bindType);// somehow set the bind type eg tile stretch ect

    void setVar(float ka0, float ka1, float ka2,float kd0, float kd1, float kd2, float ks0, float ks1, float ks2); // takes in all the inputs and sets them to the class
    void setLoc(std::string inLocation); // set the location
    void setName(std::string inName);

    void setKa(float ka0, float ka1, float ka2);
    void setKd(float kd0, float kd1, float kd2);
    void setKs(float ks0, float ks1, float ks2);

    void setNs(float inNs);

    bool compare(std::string inName); // compare the string with another
    void draw(); // change the binds
    GLuint getGLID() { return texture;};

private:

    std::string name;
    std::string location; // the location of the image

    float ka[3];
    float kd[3];
    float ks[3];


    // must have freeglut in order to use this
    BYTE *pixmap; // contains the data (not yet set)
    GLuint texture;

    //two functions that you need to load and display
    void LoadThing();
    void createTex(int width, int height, int chan);

};

MTL.cpp

#include "MTL.h"

MTL::MTL() /
{   
}
MTL::~MTL()
{

}

void MTL::setName(std::string inName)
{
    name = inName;
}







void MTL::setLoc(std::string inLocation)
{
    location = inLocation;

    LoadThing();
}
bool MTL::compare(std::string inName) // compare the string with another
{
    //return true if they are the same
    if (name == inName)
        return true;
    else
        return false;

}
void MTL::draw() // change the binds
{
    glBindTexture(GL_TEXTURE_2D, texture); 

}

void MTL::setKa(float ka0, float ka1, float ka2)
{
    ka[0] = ka0;
    ka[1] = ka1;
    ka[2] = ka2;
}

void MTL::setKd(float kd0, float kd1, float kd2)
{
    kd[0] = kd0;
    kd[1] = kd1;
    kd[2] = kd2;
}

void MTL::setKs(float ks0, float ks1, float ks2)
{
    ks[0] = ks0;
    ks[1] = ks1;
    ks[2] = ks2;
}

void MTL::LoadThing()
{
    ILuint devImg;
    ilGenImages(1,&devImg);
    ilBindImage(devImg);

    int error = ilLoadImage("marble_floor2.png");

    int e = ilGetError();

    pixmap = ilGetData();
    int width = ilGetInteger(IL_IMAGE_WIDTH);
    int height = ilGetInteger(IL_IMAGE_HEIGHT);
    int chan = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);

    createTex(width,height,chan);
}

void MTL::createTex(int width, int height, int chan)
{
    glEnable(GL_TEXTURE_2D);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    glGenTextures(1, &texture);


    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexImage2D(GL_TEXTURE_2D, 0, chan, width, height, 0, (chan == 4)?GL_RGBA: GL_RGB, GL_UNSIGNED_BYTE, pixmap);

    //no clue
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

}

编辑:首先感谢那些拒绝投票给我的人,花了我一段时间才意识到这一点,但我有很多功能,你们不需要看到它们,所以它已经减少了。

我认为可能存在问题的地方     画()     来自Loader的process() 和     画()     LoadThings()     来自MTL的createTex()

编辑: 好吧我们找到了解决方案,原因是opengl在显示纹理时使用了glColor,所以正在做的是... opengl

溶液: 在glBegin(poly?triangle)上方添加这一行     glColor3f(1.0F,1.0F,1.0F)

1 个答案:

答案 0 :(得分:0)

好吧我们找到了解决方案,原因是opengl在显示纹理时使用了glColor,所以正在做的是... opengl

解决方案:在glBegin(poly?triangle)上方添加此行glColor3f(1.0f,1.0f,1.0f)