Opengl problem with texture in model from obj

前端 未结 2 2020
梦谈多话
梦谈多话 2020-12-07 05:20

I writing small program in OpenGL, and I have problem ( textures are skew, and I dont know why, this model work in another obj viewer) What I have: http://img696.imageshack.

相关标签:
2条回答
  • 2020-12-07 05:58

    I think I'd just push a dummy point on the beginning of your points vector, and leave the point references 1-based. I'd also get rid of the while (!in.eof()), which will normally read the last line twice. Finally, I'd use a few overloads of operator>> to read most of the data, giving a result that looked something like this:

    #include <locale>
    #include <vector>
    #include <sstream>
    #include <string>
    #include <fstream>
    
    /* change to "#if 0" for normal compilation: */
    #if 1
    struct Triangle { float a, an, atc, b, bn, btc, c, cn, ctc; };
    struct Vector2d { float x, y; };
    struct Vector3d { float x, y, z; };
    
    std::vector<Triangle> triangles;
    std::vector<Vector3d> points, normals;
    std::vector<Vector2d> texcords;
    #endif
    
    namespace { 
    struct slashsep: std::ctype<char> {
        slashsep(): std::ctype<char>(get_table()) {}
    
        static std::ctype_base::mask const* get_table() {
            static std::vector<std::ctype_base::mask> 
                rc(std::ctype<char>::table_size,std::ctype_base::mask());
    
            rc['/'] = std::ctype_base::space; // Treat '/' as a separator between numbers.
            rc[' '] = std::ctype_base::space;
            rc['\n'] = std::ctype_base::space;
            rc['\t'] = std::ctype_base::space;
            return &rc[0];
        }
    };
    
    std::istream &operator>>(std::istream &in, Triangle &triangle) { 
        std::string str;
    
        std::getline(in, str);
        std::istringstream temp(str);
        slashsep loc;
        temp.imbue(std::locale(std::locale(), &loc));
    
        temp >> triangle.a >> triangle.an >> triangle.atc;
        temp >> triangle.b >> triangle.bn >> triangle.btc;
        temp >> triangle.c >> triangle.cn >> triangle.ctc;
        return in;
    }
    
    std::istream &operator>>(std::istream &in, Vector3d &v) { 
        return in >> v.x >> v.y >> v.z;
    }
    
    std::istream &operator>>(std::istream &in, Vector2d &v) { 
        return in >> v.x >> v.y;
    }
    }
    
    bool read_obj(std::string const &fileName) { 
        points.clear();
        points.push_back(Vector3d());
        triangles.clear();
    
        std::ifstream in(fileName.c_str());
        std::string cmd;
    
        if (!in.is_open())
            return false;
    
        while(in>>cmd) {
            if(cmd=="v") {
                Vector3d vector;
                in >> vector;
                points.push_back(vector);
            }
            if(cmd=="vt") {
                Vector2d texcord;
                in >> texcord;
                texcords.push_back(texcord);
            }
            if(cmd=="vn"){
                Vector3d normal;
                in >> normal;
                normals.push_back(normal);
            }
            if(cmd=="f") {
                Triangle triangle;
                in >> triangle;
                triangles.push_back(triangle);
            }
        }
        return true;
    }
    

    One minor point: while using the locale to treat '/' as a separator between numbers works for the specific variant of OBJ that you're looking at, it will not work for files that contain lines like:

    f a//b c//d e//f
    

    Nonetheless, the general idea (most reading with operator>>) will be fine when/if you decide to enhance it to handle this variant of the format.

    Edit: I think I just realized part of the problem. The code to read a face should be like this:

    temp >> triangle.a >> triangle.atc >> triangle.an;
    temp >> triangle.b >> triangle.btc >> triangle.bn;
    temp >> triangle.c >> triangle.ctc >> triangle.cn;
    

    I.e., in the file, it's arranged as vertex/texcoord/normal, but your code and my previous version above tried to read it as vertex/normal/texcoord). Once the code was arranged this way, checking against a reference made the problem fairly obvious.

    0 讨论(0)
  • 2020-12-07 06:00

    Ok i fix all :D:D What I do: change

    glTexCoord2f(tc.x,tc.y);
    

    to

    glTexCoord2f(tc.x,1-tc.y);
    

    and the most important thing I change image resolution to 1024x1024 ( I useing mipmaping so I think correct image resolution is important) Now: Can sameone explain me why lTexCoord2f(tc.x,1-tc.y); work ? and is it important to make every image 2^x resolution ?

    0 讨论(0)
提交回复
热议问题