OpenGL Problem: Camera won't rotate around cube & screen doesn't refresh

Discussion in 'Mac Programming' started by RPGamerL99, Mar 10, 2008.

  1. macrumors newbie

    Joined:
    Mar 10, 2008
    #1
    I made this with Xcode 3, running Santa Rosa MacBook. All the frameworks and such are linked properly. When I run the code, the window pops up, but the screen is white. When I move another window over it or bring up widgets, it seems to refresh the screen and i can see the cube. The second problem is that the camera is supposed to rotate around the cube but doesn't, it seems to only call glutDisplayFunc once.

    I gave my teacher my code, and he ran it on his Linux environment and it worked fine. I don't understand what is happening. I can run a simple program I have just displaying a square, so i know how to compile OpenGL code correctly. Any help?


    double transform_eyex()
    {
    tempx = (cos(theta) * eyex) + (sin(theta) * eyez);
    return tempx;
    }

    double transform_eyez()
    {
    tempz = (-sin(theta) * eyex) + (cos(theta) * eyez);
    return tempz;
    }

    void display(void)
    {
    theta += 0.1;
    eyex = transform_eyex();
    eyez = transform_eyez();

    // set up new view
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(40.0, 1.0, 1.0, 10000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    gluLookAt(eyex, 5.0, eyez, //eye
    0.0, 0.0, 0.0, //target
    0.0, 1.0, 0.0); // up

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // draw triangles
    draw_cube_face();
    draw_cube_back();

    glFlush();
    glutSwapBuffers();
    }

    int main(int argc, char** argv)
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutCreateWindow("cube");
    init_mod();
    glEnable(GL_DEPTH_TEST);
    glutDisplayFunc(display);
    glutIdleFunc(glutPostRedisplay);
    glutMainLoop();
    }
     
  2. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #2
    Hi

    Is it a glut program? If it is then it sounds like you may have missed putting GLUT_DOUBLE in your glutInitDisplayMode() call.

    How about posting some code, I'm sure you'll get a lot of help from the folks here.

    EDIT: Ah your code has magically appeared!

    b e n
     
  3. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #3
    Hi I think the problem to do with the white screen is because you haven't set the colour before you clear the screen. I guess white is left over from drawing your cube… can't tell because you haven't included that bit of code.
    So try:-

    Code:
    glClearColor( 0.0, 0.0, 0.0, 0.0 ) ;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    b e n
     
  4. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #4
    Just tried your program. Put my own model stuff in and it works ok, though I did take out your eye transformations and used glRotate() instead. By the way, I think it best that you use the gl transformations instead of doing them yourself.

    b e n
     
  5. thread starter macrumors newbie

    Joined:
    Mar 10, 2008
    #5
    This is my whole program:

    Code:
    #include <GLUT/glut.h>  /* includes gl.h and glu.h for Mac OS X */
    #include <math.h>
    
       int edgeLen = 1;
       GLfloat x1[13] = {-0.5, 0.0, 0.0, 0.0, 0.0,
                              0.0, 0.0, 0.0, 0.0,
    						  0.0, 0.0, 0.0, 0.0};
       GLfloat x2[13] = {0.0, 0.0, 0.0, 0.0, 0.0,
    				          0.0, 0.0, 0.0, 0.0,
    						  0.0, 0.0, 0.0, 0.0};
    
       GLfloat yy[13] = {-0.5, 0.0, 0.0, 0.0, 0.0,
                              0.0, 0.0, 0.0, 0.0,
    						  0.0, 0.0, 0.0, 0.0};
       GLfloat y2[13] = {0.0, 0.0, 0.0, 0.0, 0.0,
    				          0.0, 0.0, 0.0, 0.0,
    						  0.0, 0.0, 0.0, 0.0};
    						
       GLfloat z1[13] = {0.5, 0.0, 0.0, 0.0, 0.0,
                              0.0, 0.0, 0.0, 0.0,
    					      0.0, 0.0, 0.0, 0.0};
       GLfloat z2[13] = {0.0, 0.0, 0.0, 0.0, 0.0,
    				          0.0, 0.0, 0.0, 0.0,
    					      0.0, 0.0, 0.0, 0.0};
       double eyex = 5.0;
       double eyez = 5.0;
       double tempx = 0.0;
       double tempz = 0.0;
       double theta = 0.1;
    
    /* 
       Calculates points of the cube given the bottom left
       point on the front face of the cube and the length of
       the sides.  Stores points in arrays for future use.
    */
    void init_mod()
    {
       int sidesDrawn = 0;
       int axis1 = 0;
       int axis2 = 1;
       int loc = 1;
       int m, n, q, r;
       
       for(n = 0; n < 3; n++)
       {
          for(m = 0; m < 2; m++)
          {  
             switch (axis1) {
                case 0:
    			   x1[loc] = x1[0] + edgeLen;
    			   yy[loc] = yy[0];
    			   z1[loc] = z1[0];
    			   break;
    			case 1:
    			   x1[loc] = x1[0];
    			   yy[loc] = yy[0] + edgeLen;
    			   z1[loc] = z1[0];
    			   break;
    			case 2:
    			   x1[loc] = x1[0];
    			   yy[loc] = yy[0];
    			   z1[loc] = z1[0] - edgeLen;
    			   break;
    		 }
             loc++;
    			
    			switch (axis2) {
    			   case 0:
    			      x1[loc] = x1[loc - 1] + edgeLen;
    			      yy[loc] = yy[loc - 1];
    			      z1[loc] = z1[loc - 1];
    				  break;
    			   case 1:
    			      x1[loc] = x1[loc - 1];
    			      yy[loc] = yy[loc - 1] + edgeLen;
    			      z1[loc] = z1[loc - 1];
    				  break;
    			   case 2:
    			      x1[loc] = x1[loc - 1];
    			      yy[loc] = yy[loc - 1];
    			      z1[loc] = z1[loc - 1] - edgeLen;
    				  break;
    			}
    			loc++;
    
    		    axis2 = axis1;
    		    axis1 = (axis1 + 1) % 3;
          }
    	  
    	  if(axis2 == 0){  //------------------------------
    	     axis2 = 2;}    // reverse "(changept2 + 1) % 3"
    	  else{axis2--;}   //------------------------------
       }
       
       x2[0] = x1[0] + edgeLen;
       y2[0] = yy[0] + edgeLen;
       z2[0] = z1[0] - edgeLen;
       loc = 1;
       axis1 = 0;
       axis2 = 1;
       
       for(q = 0; q < 3; q++)
       {
          for(r = 0; r < 2; r++)
          {  
             switch (axis1) {
                case 0:
    			   x2[loc] = x2[0] - edgeLen;
    			   y2[loc] = y2[0];
    			   z2[loc] = z2[0];
    			   break;
    			case 1:
    			   x2[loc] = x2[0];
    			   y2[loc] = y2[0] - edgeLen;
    			   z2[loc] = z2[0];
    			   break;
    			case 2:
    			   x2[loc] = x2[0];
    			   y2[loc] = y2[0];
    			   z2[loc] = z2[0] + edgeLen;
    			   break;
    		 }
             loc++;
    			
    			switch (axis2) {
    			   case 0:
    			      x2[loc] = x2[loc - 1] - edgeLen;
    			      y2[loc] = y2[loc - 1];
    			      z2[loc] = z2[loc - 1];
    				  break;
    			   case 1:
    			      x2[loc] = x2[loc - 1];
    			      y2[loc] = y2[loc - 1] - edgeLen;
    			      z2[loc] = z2[loc - 1];
    				  break;
    			   case 2:
    			      x2[loc] = x2[loc - 1];
    			      y2[loc] = y2[loc - 1];
    			      z2[loc] = z2[loc - 1] + edgeLen;
    				  break;
    			}
    			loc++;
    
    		    axis2 = axis1;
    		    axis1 = (axis1 + 1) % 3;
          }
    	  
    	  if(axis2 == 0){  //------------------------------
    	     axis2 = 2;}    // reverse "(changept2 + 1) % 3"
    	  else{axis2--;}   //------------------------------
       }
    }
    
    /*
       Draws the 3 faces that touch the front bottom left corner
    */
    void draw_cube_face()
    {
       int sidesDrawn1 = 0;
       int i;
       int a = 0;
       float color1[3] = {1.0, 0.0, 0.0};
       float color2[3] = {0.0, 1.0, 0.0};
       float color3[3] = {0.0, 0.0, 1.0};
    
       while(sidesDrawn1 < 3)
       {
          glColor3f(color1[sidesDrawn1], color2[sidesDrawn1], color3[sidesDrawn1]);
    	  
    	  for(i = 0; i < 2; i++)  // allows both triangles on one side to be drawn
    	  {
    	     glBegin(GL_TRIANGLES);
                glVertex3f(x1[0], yy[0], z1[0]);
    			a++;
    			glVertex3f(x1[a], yy[a], z1[a]);
    			a++;
    			glVertex3f(x1[a], yy[a], z1[a]);
             glEnd;
    	  }
    	  sidesDrawn1++;
       }
    }
    
    /*
       Draws the 3 faces that touch the back upper right corner
    */
    void draw_cube_back()
    {
       int sidesDrawn2 = 0;
       int k;
       int a = 0;
       float color1[3] = {1.0, 0.0, 0.0};
       float color2[3] = {0.0, 1.0, 0.0};
       float color3[3] = {0.0, 0.0, 1.0};
    
       while(sidesDrawn2 < 3)
       {
          glColor3f(color1[sidesDrawn2], color2[sidesDrawn2], color3[sidesDrawn2]);
    	  
    	  for(k = 0; k < 2; k++)  // allows both triangles on one side to be drawn
    	  {
    	     glBegin(GL_TRIANGLES);
                glVertex3f(x2[0], y2[0], z2[0]);
    			a++;
    			glVertex3f(x2[a], y2[a], z2[a]);
    			a++;
    			glVertex3f(x2[a], y2[a], z2[a]);
             glEnd;
    	  }
    	  sidesDrawn2++;
       }
    }
    
    double transform_eyex()
    {
       tempx = (cos(theta) * eyex) + (sin(theta) * eyez);
       return tempx;
    }
    
    double transform_eyez()
    {
       tempz = (-sin(theta) * eyex) + (cos(theta) * eyez);
       return tempz;
    }
    
    void display(void)
    {
       theta += 0.1;
       eyex = transform_eyex();
       eyez = transform_eyez();
       
       // set up new view
       glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       gluPerspective(40.0, 1.0, 1.0, 10000.0);
       glMatrixMode(GL_MODELVIEW);
       glLoadIdentity();
       
       gluLookAt(eyex, 5.0, eyez, //eye
    		     0.0, 0.0, 0.0,   //target
    	         0.0, 1.0, 0.0);  // up
       
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       
       // draw triangles
    	draw_cube_face();
    	draw_cube_back();
        
    	glFlush();
    	glutSwapBuffers();
    }
    
    int main(int argc, char** argv)
    {
       glutInit(&argc, argv);
       glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
       glutCreateWindow("cube");
       init_mod();
       glEnable(GL_DEPTH_TEST);
       glutDisplayFunc(display);
       glutIdleFunc(glutPostRedisplay);
       glutMainLoop();
    }
    I will try your suggestions.
    Thanks =)
     
  6. thread starter macrumors newbie

    Joined:
    Mar 10, 2008
    #6
    I tried the glClearColor but it didn't help. I have to rotate the camera myself because its part of the assignment in my graphics class. it's very weird that you were able to compile it and also my teacher, but I get these weird problems...
     
  7. macrumors 6502

    Joined:
    May 27, 2007
    Location:
    Montreal Canada
    #7
    try putting "glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);" before any line of code in the display function. Or at least before any gl or glut function calls in the display function.
     
  8. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #8
    Ah, I see something wrong… you have glEnd; instead of glEnd() ;


    b e n

    EDIT: The reason why it worked earlier for me was because I'd replaced your draw routines with ones that didn't have your typo!
     
  9. thread starter macrumors newbie

    Joined:
    Mar 10, 2008
    #9
    OMG, YOU ARE A GENIUS!

    THANK YOU =D I don't believe I missed that!
     
  10. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #10
    How would that have gotten past the compiler? is glEnd defined as something else?
     
  11. macrumors 68040

    Joined:
    Apr 22, 2005
    #11
    The name of a variable or function is a legal statement in C.
     
  12. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #12
    Thanks. I think it's weird though. When would this ever be useful?
     
  13. thread starter macrumors newbie

    Joined:
    Mar 10, 2008
    #13
    Now that it works correctly, I now realize my transformations are off lol If anyone wants to give hints on how to fix it, that would be great. I will try to correct the transformations now.
     
  14. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #14
    I may be wrong about this, but I think you can drop opcodes, or data, into your code this way.

    b e n
     
  15. thread starter macrumors newbie

    Joined:
    Mar 10, 2008
    #15
    nevermind, I figured it out! cube spins perfect and gracefully now =)

    thanks for the help!
     
  16. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #16

    Had a quick look at your transformations. I think the problem is you are using an incremental transformation for the eye coordinates, but you update theta as though it is an absolute angle. Try:-

    Code:
    void display(void)
    {
       // theta = 0.1; changed to...
       theta = 0.01 ;
    
    This way, you are rotating the camera by 0.01 radians each frame. The way you had it before, your were rotating the camera each frame by ever increasing amounts.

    An easier way though would be to calculate the eye coordinates from theta and a radius. The radius is the distance of the camera from the centre of your scene.

    b e n
     
  17. macrumors 68020

    Krevnik

    Joined:
    Sep 8, 2003
    #17
    It is how you get a function pointer. :)

    glEnd is a pointer to a function.
    glEnd() calls the function given by the pointer 'glEnd'. :)

    EDIT: Note that this is short-hand in C/C++ rather than the desirable way to do it.
     
  18. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #18
    But why is glEnd; a valid statement? When would this ever be necessary to have a statement doing nothing?
     
  19. macrumors 68020

    Krevnik

    Joined:
    Sep 8, 2003
    #19
    Because it simply is. :)

    A statement that is 100% empty (';' by itself for example) is perfectly valid. As are statements that don't assign. Without this, void function calls become complex for the compiler to handle as it adds rules that you need to keep track of.

    To help people write good code isn't always the same thing as keeping the compiler simple. In this case, it was simpler to let statements that don't assign exist, to handle void function calls, statements that do something yet don't assign, and so on, then it was to create an error out of 'functionNameHere;'

    EDIT: To be clear, I wouldn't say I don't think the design has its problems, but at the time C was being designed, they were thinking about how to make the parser efficient and small... and not so much on how they could make the programmer's job easier.
     
  20. macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #20
    Oops… I was talking rubbish (again), :) It was very late last night though!

    b e n
     

Share This Page