0
\$\begingroup\$

I wrote an example attempting to parse blender *.obj file in OpenGl/C++ , to get it done : I have to open the file, exploding it's lines ...and returning the result.

This is how the shape.obj file looks like :

v 0.010271 -0.953897 0.097835
v 0.010271 -0.941667 0.194652
v 0.010271 -0.921285 0.289430
v 0.010271 -0.892750 0.381151

the previous file can contain lines starting with "f" as well.

and this is the c++ code (with glut include)

    #include <stdarg.h>
    #include <math.h>
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <GL/glut.h>


    using namespace std;

    void display();
    void specialKeys();
    float stringToDouble(string& s);
    vector<string> explode(const string& str,const char& ch);


    double rotate_y=0; 
    double rotate_x=0;


    void display(){

      float x,y,z;
      string v;
      string a,b,c;

      glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
      glLoadIdentity();

    /**perform object rotation using keyboard arrows in specialKeys function**/
      glRotatef( rotate_x, 1.0, 0.0, 0.0 );
      glRotatef( rotate_y, 0.0, 1.0, 0.0 );


      ifstream myfile("shape.obj"); // open file
       if (myfile.is_open())
      {

        while ( myfile.good())
        {
          string line;
          getline (myfile,line); // get current line
          vector<string> subs;
          subs=explode(line,' '); //explode line by space
          v=subs[0];
          if(v.compare("v")){ //if the line begins with v

          /***draw polygon***/
          glBegin(GL_POLYGON); 
          a=subs[1];
          b=subs[2];
          c=subs[3];
           x=stringToDouble(a);
           y=stringToDouble(b);
           z=stringToDouble(c);
           /****draw 3D vertex*****/
           glVertex3f(x,y,z); 
           glEnd();

           }

        }

      }
      myfile.close(); //close file

    glFlush();
    glutSwapBuffers();


    }



    /**** special key***/
    void specialKeys( int key, int x, int y ) {


      if (key == GLUT_KEY_RIGHT)
        rotate_y += 5;


      else if (key == GLUT_KEY_LEFT)
        rotate_y -= 5;

      else if (key == GLUT_KEY_UP)
        rotate_x += 5;

      else if (key == GLUT_KEY_DOWN)
        rotate_x -= 5;

      glutPostRedisplay();

    }



/*** main***/
    int main(int argc, char* argv[]){

      glutInit(&argc,argv);
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
      glutCreateWindow("Hello world");
      glEnable(GL_DEPTH_TEST);
      glutDisplayFunc(display);
      glutSpecialFunc(specialKeys);

      glutMainLoop();

      return 0;

    }



/**converts string to double***/
    float stringToDouble(string& s )
     {
       std::istringstream i(s);
       float x;
       if (!(i >> x))
         return 0;
       return x;
     } 




/***Explode : exploding strings***/
      vector<string> explode(const string& str, const char& ch) {
        string next;
        vector<string> result;

        // For each character in the string
        for (string::const_iterator it = str.begin(); it != str.end(); it++) {
            // If we've hit the terminal character
            if (*it == ch) {
                // If we have some characters accumulated
                if (!next.empty()) {
                    // Add them to the result vector
                    result.push_back(next);
                    next.clear();
                }
            } else {

                next += *it;
            }
        }
        if (!next.empty())
             result.push_back(next);
        return result;
    }

The previous code:

1- initializes glut. 2- defines display and specialKeys functions. 3- opens and parses the obj file. 4- creates polygons using the extracted vertex coordinates.

Note also, that the parsing works fine, because I tested it in another program and the result reads :

coordinates x:0.010271 y:-0.953897 z:0.097835
coordinates x:0.010271 y:-0.941667 z:0.194652
coordinates x:0.010271 y:-0.921285 z:0.289430
coordinates x:0.010271 y:-0.892750 z:0.381151

When I compile this exemple, there's no error, But when I execute ... the window shows nothing but the black screen. It doesn't show the 3d object I created on blender.

To those who've done this before. Is there something I missed here?

Thanks.

\$\endgroup\$
10
  • 1
    \$\begingroup\$ You can't draw a GL_POLYGON from a single vertex. Put the glBegin() before while ( myfile.good()) and the glEnd() after the while loop closes. Also, for larger files you need to use GL_TRIANGLES \$\endgroup\$
    – PeterT
    Jul 29 '13 at 21:15
  • \$\begingroup\$ Thanks, I did, but the same issue, nothing appears in the window, for GL_TRIANGLES ...same result as well \$\endgroup\$
    – SmootQ
    Jul 29 '13 at 21:28
  • 1
    \$\begingroup\$ you should probably read up on how the OBJ format works. It first lists all vertices, more or less unordered and then lists all faces (polygons) as in "here's a polygon made from the 1st,2nd and 5th vertex listed" if the line is "f 1 2 5" \$\endgroup\$
    – PeterT
    Jul 29 '13 at 21:40
  • \$\begingroup\$ Thank you so much @PeterT, I solved the problem, check the answer I added. +1 :) \$\endgroup\$
    – SmootQ
    Jul 29 '13 at 21:42
  • \$\begingroup\$ Anyway, I will use GL_TRIANGLES you suggested at first \$\endgroup\$
    – SmootQ
    Jul 29 '13 at 21:42
1
\$\begingroup\$

I found where's the problem... I wonder how I couldn't notice it before:

it's in this line

 if(v.compare("v")){ 

v.compare("v") returns always false, so I changed it to :

if(v=="v")

and it's working now

Thanks

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .