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\$
  • 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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.