.obj Loader

I'm trying to create a simple .obj loader but whenever I use it, the model displayed has it's texture messed up. I've loaded the same file using a loader created by someone else so I know that the problem isn't with the texture itself. I've checked the data loaded and compared it to the data stored in the file and they appear to be the same thing so I'm unsure of what's causing the problem. My function is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
void LoadOBJ( string Path, vector<vec3>& Verticies, vector<vec3>& Normals, vector<vec2>& UVs )
{
    vector<unsigned short> VIndex, NIndex, UVIndex;
    vector<vec3> TempNorms, TempVerts;
    vector<vec2> TempUVs;

    Verticies.clear();
    Normals.clear();
    UVs.clear();

    string Data;
    ifstream File(Path.c_str());
    while ( !File.eof() )
    {
        getline(File, Data);
        string Temp = "";
        if ( Data[0] == 'v' and Data[1] != 't' and Data[1] != 'n' )
        {
            vec3 Current;

            bool Negative[3] = {false, false, false};
            Negative[0] = ( Data[2] == '-' ) ? true : false;
            for ( int x = 0; x < 8 + Negative[0]; x++ )
                Temp += Data[ x+2 ];
           Current[0] = StringToFloat(Temp);

            for ( int vertex = 1; vertex < 3; vertex++ )
            {
                Temp = "";
                int Push = 0;
                for ( int n = 0; n < vertex; n++ )
                    Push += Negative[n];
                Negative[vertex] = ( Data[ 2 + 9*vertex + Push ] == '-' ) ? true : false;
                for ( int x = 0; x < 8 + Negative[vertex]; x++ )
                    Temp += Data[ x + 2 + 9*vertex + Push ];
                Current[vertex] = StringToFloat(Temp);
            }
            TempVerts.push_back(Current);
            /*
            cout<<"Stored: "<<TempVerts.back()<<endl;
            cout<<"Actual: "<<Data<<endl;
            */
        }
        else if ( Data[0] == 'v' and Data[1] == 't' )
        {
            vec2 Current;
            for ( int v = 0; v < 2; v++ )
            {
                Temp = "";
                for ( int i = 0; i < 8; i++ )
                    Temp += Data[3 + i + v*9];
                Current[v] = StringToFloat(Temp);
                TempUVs.push_back(Current);
            }
            /*
            cout<<"Stored: "<<TempUVs.back()<<endl;
            cout<<"Actual: "<<Data<<endl;
            */
        }
        else if ( Data[0] == 'v' and Data[1] == 'n' )
        {
            vec3 Current;
            bool Negative[3] = {false,GL_FALSE,0};
            Negative[0] = ( Data[3] == '-' ) ? true : false;
            for ( int i = 0; i < 8 + Negative[0]; i++ )
                Temp += Data[3 + i];
            Current[0] = StringToFloat(Temp);

            for ( int v = 1; v < 3; v++ )
            {
                Temp = "";

                int Push = 0;
                for ( int n = 0; n < v; n++ )
                    Push += Negative[n];
                Negative[v] = ( Data[ 3 + 9*v + Push ] == '-' ) ? true : false;
                for ( int i = 0; i < 8 + Negative[v]; i++ )
                    Temp += Data[ 3 + 9*v + Push + i ];
                Current[v] = StringToFloat(Temp);
                TempNorms.push_back(Current);
            }
            /*
            cout<<"Stored: "<<TempNorms.back()<<endl;
            cout<<"Actual: "<<Data<<endl;
            */
        }
        else if ( Data[0] == 'f' )
        {
            int position = 2;
            for ( int i = 0; i < 3; i++ )
            {
                while ( IsNumber(Data[position]) )
                {
                    Temp += Data[position];
                    position++;
                }
                StringToFloat(Temp); ///For some reason it only works if I call it once beforehand
                VIndex.push_back(StringToFloat(Temp));

                Temp = "";
                position++;
                while ( IsNumber(Data[position]) )
                {
                    Temp += Data[position];
                    position++;
                }
                StringToFloat(Temp);
                UVIndex.push_back(StringToFloat(Temp));

                Temp = "";
                position++;
                while ( IsNumber(Data[position]) )
                {
                    Temp += Data[position];
                    position++;
                }
                StringToFloat(Temp);
                NIndex.push_back( StringToFloat(Temp) );

                Temp = "";
                position++;
            }
            /*
            cout<<"Actual: "<<Data<<endl;
            cout<<"Stored: ";
            for ( int x = 3; x > 0; x-- )
            {
                cout<<VIndex[VIndex.size() - x]<<'/'<<UVIndex[UVIndex.size() - x]<<'/'<<NIndex[NIndex.size() - x];
                cout<<' ';
            }
            cout<<endl;
            */
        }
    }
    for ( int i = 0; i < VIndex.size(); i++ )
    {
        Verticies.push_back( TempVerts[ VIndex[i] - 1 ] );
        Normals.push_back  ( TempNorms[ NIndex[i] - 1 ] );
        UVs.push_back      ( TempUVs [ UVIndex[i] - 1 ] );
    }
}
I don't know if it's the same problem I had. In blender, the UV coordinates seamed to be measured from a different corner of the texture than when I render in blender. Separate copies of the texture flipped vertically, one for blender one to load in openGL, fixed my problem.

I was using the basic loader from opengl-tutorial.org.
Last edited on
I tried flipping the texture but it still isn't working right.
Maybe try flipping it in different ways to account for all possible corners the UV coordinates could be measure from?
I already tried that but it didn't help. Right now I'm trying to find any small mistakes in my code that I could have previously looked over. Also, here is a link that compares what I get to what I should be getting:
http://imageshack.us/a/img849/569/7pj5.png
Last edited on
Here is a link to the source code of a simple objloader from OpenGL-tutorial.org. Maybe it will help comparing it to your code?

http://code.google.com/p/opengl-tutorial-org/source/browse/common/objloader.cpp

When exporting in blender, for it to work, you need to check trianglular faces and include normals, and uncheck include edges.
Last edited on
I've looked at that function and tested it (it works perfectly) but can't figure out what he's doing to read the file that makes it different from mine enough that it works.

Edit: I finally found the problem. Where I was loading the UV coordinates for the texture, I added the vec2 before it was completely filled. i.e If one of the UV coordinates was (3,2) it would add (3,who knows) to the vector.
Last edited on
Topic archived. No new replies allowed.