ObjLoader!!!

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • ObjLoader!!!

      Greetings guys,

      so I was making an ObjLoader and am loading the vertices correct , but when am trying to draw it's not working at all , it gives me a white rectangle :s, here is the source code:

      Source Code

      1. //loader
      2. struct Model
      3. {
      4. double X,Y,Z;
      5. std::vector<std::array<float,3>> Vertices;
      6. std::vector<std::array<float,3>> Faces;
      7. std::vector<std::array<float,3>> VerticesNormals;
      8. std::vector<std::array<float,3>> VerticesTexture;
      9. };
      10. class ModelsLoader
      11. {
      12. public:
      13. ModelsLoader(void);
      14. ~ModelsLoader(void);
      15. Model LoadModel(const char * ModelName);
      16. std::vector<Model> GetModels();
      17. private:
      18. unsigned int Split(const std::string &txt, std::vector<std::string> &strs, char ch);
      19. std::vector<Model> Models;
      20. };
      21. Model ModelsLoader::LoadModel(const char * ModelName){
      22. std::ifstream fs(ModelName);
      23. std::string line;
      24. Model m;
      25. if(fs.is_open()){
      26. std::vector<std::string> strs;
      27. std::vector<std::string> faces;
      28. std::array<float,3> temp;
      29. m.X=0;
      30. m.Y=0;
      31. m.Z=0;
      32. while (std::getline(fs,line))
      33. {
      34. Split(line,strs,' ');
      35. if (line.compare(0, 2, "v ") == 0 ){
      36. temp[0] = ::atof(strs[2].c_str());
      37. temp[1] = ::atof(strs[3].c_str());
      38. temp[2] = ::atof(strs[4].c_str());
      39. m.Vertices.push_back(temp);
      40. }
      41. if (line.compare(0, 1, "f") == 0 ){
      42. for (int i = 1; i < 4; i++)
      43. {
      44. Split(strs[i],faces, '/');
      45. temp[0] = ::atof(faces[0].c_str());
      46. temp[1] = ::atof(faces[1].c_str());
      47. temp[2] = ::atof(faces[2].c_str());
      48. m.Faces.push_back(temp);
      49. }
      50. }
      51. if (line.compare(0, 2, "vn") == 0 ){
      52. temp[0] = ::atof(strs[1].c_str());
      53. temp[1] = ::atof(strs[2].c_str());
      54. temp[2] = ::atof(strs[3].c_str());
      55. m.VerticesNormals.push_back(temp);
      56. }
      57. if (line.compare(0, 2, "vt") == 0 ){
      58. temp[0] = ::atof(strs[2].c_str());
      59. temp[1] = ::atof(strs[3].c_str());
      60. temp[2] = 0.0f;
      61. m.VerticesTexture.push_back(temp);
      62. }
      63. }
      64. Models.push_back(m);
      65. fs.close();
      66. }
      67. return m;
      68. }
      Display All


      Source Code

      1. //drawing
      2. void handleResize(int w, int h) {
      3. //Tell OpenGL how to convert from coordinates to pixel values
      4. glViewport(0, 0, w, h);
      5. glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
      6. //Set the camera perspective
      7. glLoadIdentity(); //Reset the camera
      8. gluPerspective(45.0, //The camera angle
      9. (double)w / (double)h, //The width-to-height ratio
      10. 1.0, //The near z clipping coordinate
      11. 200.0); //The far z clipping coordinate
      12. }
      13. void initRendering() {
      14. //Makes 3D drawing work when something is in front of something else
      15. glEnable(GL_DEPTH_TEST);
      16. }
      17. void drawScene() {
      18. //Clear information from last draw
      19. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      20. glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
      21. glLoadIdentity(); //Reset the drawing perspective
      22. auto model = loader.GetModels()[0];
      23. glBegin(GL_TRIANGLES); //Begin quadrilateral coordinates
      24. for (int i = 0; i < model.Vertices.size(); i++)
      25. {
      26. glVertex3f(model.Vertices[i][0],model.Vertices[i][1],model.Vertices[i][2]);
      27. }
      28. glEnd(); //End triangle coordinates
      29. glutSwapBuffers(); //Send the 3D scene to the screen
      30. }
      31. int main(int argc, char** argv) {
      32. //Initialize GLUT
      33. loader.LoadModel("test.obj");
      34. glutInit(&argc, argv);
      35. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
      36. glutInitWindowSize(400, 400); //Set the window size
      37. //Create the window
      38. glutCreateWindow("test the loader");
      39. initRendering(); //Initialize rendering
      40. //Set handler functions for drawing, keypresses, and window resizes
      41. glutDisplayFunc(drawScene);
      42. glutKeyboardFunc(handleKeypress);
      43. glutReshapeFunc(handleResize);
      44. glutMainLoop(); //Start the main loop. glutMainLoop doesn't return.
      45. return 0; //This line is never reached
      46. }
      Display All



      where the vertices are :

      Source Code

      1. v 12.1160 39.0194 -24.8301
      2. v -11.2262 0.0050 -7.8920
      3. v 35.4582 0.0050 -7.8920
      4. v 35.4582 0.0050 -41.7682
      5. v -11.2262 0.0050 -41.7682
      6. v 12.1160 0.0050 -24.8301
      7. # 6 vertices


      and am loading it correctly , what am doing wrong here !?

      here is an image with the issue
      [IMG:http://i48.tinypic.com/i1lf2a.jpg]

      The post was edited 1 time, last by Abanoub ().

    • The only thing I noticed after skimming through it is that there is no projection matrix setup, if you're not sure what that is, when you say glMatrixMode(GL_MODELVIEW);
      you are setting the matrix to the model/view matrix which you use to positions your vertices to their final locations. you need to make sure your projection matrix is set up as well, which converts your vertices into homogenous clip space coordinates.

      I am unsure as to wether GLUT set's this up for you, but it wouldn't be a bad idea to do this yourself just to be sure, to do this use the following code.

      Source Code

      1. glMatrixMode(GL_PROJECTION);
      2. glLoadIdentity();
      3. gluPerspective(60.0f, (float)Width/(float)height, 0.001f, 1000.0f);


      The first line sets the current matrix to the projection matrix, the second resets this matrix to the identity matrix, and the 3rd sets up a perspective matrix, which is what you want for 3D, as objects move into the distance they appear smaller.

      If you don't have this set up and it is an identity matrix, you will get unwanted results (maybe what you are seeing now)
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • OpenGL does have defaults for pretty much everything including ClearColor, and current colour for vertices.

      Is it the colour that you are having issues with or the shape? If it is the colour then you will need to follow column_vector's advice, be sure each vertice is getting the appropriate colour value (or texel value),

      Otherwise if it is the shape, you need to follow my advice, it is like having a missing component in the transformation pipeline but OpenGL won't care it will still pump vertices through. The final stage of the pipeline is meant to take those homogenous clip space coordinates, which are between -1 and 1 in both the horizontal and vertical directions, if they are passed anything greater they definately won't work right.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • I thought default values for both clearcolor and vertexColor might be black. So black + black = black would be the result :) .
      I didn't look at the vertex positions which are way larger/smaller than the 1.0/-1.0 for both x,z and y coordinates. I aggre that he totally needs a "custom" projection.

      The post was edited 2 times, last by column_vector ().

    • RE: ObjLoader!!!

      I have

      Source Code

      1. glMatrixMode(GL_PROJECTION);
      inside the reshape method! and it's not the color!

      EDIT: well I have used

      Source Code

      1. glScalef(-0.5,0.5,5.0);
      and it worked!

      the question here , what is the correct way to load a model which fits the screen?

      The post was edited 1 time, last by Abanoub ().

    • well, I'm not sure how to really answer that question, If you are doing 3D you shouldn't really scale your model (not for any real purpose), but instead you should move it into the world. I would recommend taking a look at some 3D math (which the GCC4 book has), NeHe tutorials (for OpenGL), and the OpenGL Red Book.

      Once you have the basic concepts down you will be ok, but essentially when you use scalef you are making a 'scale' matrix on the modelview, when your vertices are passed in they are scaled down into a smaller object, this may or may not be desirable, I would simply translate the object into your screen rather than scale, you will get the same effect, and in my experience scaling never quite does what I want, especially for cameras and stuff.
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • It sounds like you're basically poking at values until something looks about right. At this point, I would stop, take a step back, and understand exactly what every single line of code is doing and how each value you're passing into each function is effecting your scene. You'll have to read up on the math behind 3D graphics, but it's really worth understanding exactly what's happening before digging yourself in too deep. Things will inevitably break again and if you just keep rushing in blindly, you'll get stuck won't know how to proceed. It's also possible that you only got it to work in this one isolated case and that it'll all fall apart when you get some game objects in there.

      Now that it works, take a breath and try to figure why it's working. Trust me, it'll save you from a huge headache down the line.

      -Rez
    • Here's how to load an object so that it will be in the camera frame.

      1. Find out your camera's field of view (typically around 45 degrees), and divide that by 2.0, and divide THAT your screen's aspect ratio. If you have a 4:3 screen like a lot of older PCs that would be 4/3=1.333, A 16:10 screen would be 16/10=1.6. We'll use that angle in a moment.
      2. Find the approximate radius of the circle that would enclose your object. You should be able to look at the vertices, average them to find the center, find the vertex that is farthest from that center, and call that your radius.
      3. Place the center of the object at the origin, (0,0,0). Place your camera there as well.
      4. Find the appropriate distance your camera should be placed away from the object with the formula: radius / tan(field of view angle) = distance. See diagram!
      5. Find your camera's forward vector (hopefully you have a nice matrix class like the one in GCC that will find this for you!)
      6. Move the camera backwards along the forward vector by the distance you found above.

      Whew!

      I hope I didn't just ruin your day with all that math.
      Files
      • ObjInCamera.jpg

        (67.57 kB, downloaded 419 times, last: )
      Mr.Mike
      Author, Programmer, Brewer, Patriot