Macbook Air running this smoother than Mac Pro tower?? (OpenGL code)

Discussion in 'Mac Programming' started by chrono1081, May 7, 2011.

  1. macrumors 604

    chrono1081

    Joined:
    Jan 26, 2008
    Location:
    Isla Nublar
    #1
    Hi guys,

    I am straight up confused. I have code that renders a utah teapot and moves it up and down the screen on the y axis while rotating it. For some reason its jerky on the Mac Pro in my sig and silky smooth on my Macbook Air. I am at a complete loss as to why. Does anyone have any suggestions on how I can improve this or to why its happening? I'm newish to OpenGL (I've used it but I'm not an expert by any means).

    Here is the code that I have: (I know its full of bad programming practices but its just to learn the OpenGL concepts and none that I see should affect rendering but I could be wrong).

    Any help would be greatly appreciated:) Also I've checked for vid card and cpu hogs like Maya running in the background of my Mac Pro and haven't found any. (Mayas rendered finished and nothing else is running)

    Code:
    //
    //  main.cpp
    //  NewGL2
    //
    //  Created by Scott Nelson on 5/6/11.
    //  Copyright 2011 NA. All rights reserved.
    //
    
    #include <GLUT/glut.h>
    #include <OpenGL/gl.h>
    #include <OpenGL/glu.h>
    #include <iostream>
    
    //Arrays for key presses
    bool* keyStates = new bool[256]; //Regular keys
    bool* keySpecialStates = new bool[256]; //Special keys
    
    //Globals for objects
    bool movingUp = false; //Whether object is moving up or down
    float yLocation = 0.0f; //Keep track of position on Y axis
    float yRotationAngle = 0.0f; //The objects angle of rotation
    
    //======================================================================
    //                  Functions to manage windows and input
    //======================================================================
    //Function to handle character key down events
    void keyDown(unsigned char key, int x, int y)
    {
        //Set key to 'pressed'
        keyStates[key] = true;
        
        //Call to redraw the screen (this can be removed if an animation is present)
        glutPostRedisplay();
    }
    
    //Function to handle key up events
    void keyUp(unsigned char key, int x, int y)
    {
        //Set key to 'not pressed'
        keyStates[key] = false;
        
        //Call to redraw the screen (this can be removed if an animation is present)
        glutPostRedisplay();
    }
    
    //Function to handle special key down events
    void keySpecialDown(int key, int x, int y)
    {
        //Set key to 'pressed'
        keySpecialStates[key] = 1;
        
        //Call to redraw the screen (this can be removed if an animation is present)
        glutPostRedisplay();
    }
    
    //Function to handle special key up events
    void keySpecialUp(int key, int x, int y)
    {
        //Set key to 'not pressed'
        keySpecialStates[key] = 0;
        
        //Call to redraw the screen (this can be removed if an animation is present)
        //glutPostRedisplay();
    }
    
    //Function to control what happens on key state changes for regular keys
    void keyOperations(void)
    {
        //These can obviously be changed and added to to provide UI functionality
        if(keyStates['a']) {printf("A is pressed.\n");}
        //if(!keyStates['a']) {printf("A is not pressed.\n");}
        
        if(keyStates['b']) {printf("B is pressed.\n");}
        //if(!keyStates['b']) {printf("B is not pressed.\n");}
    }
    
    //Function to control what happens on special key state changes
    void keySpecialOperations(void)
    {
        //These can obviously be changed and added to to provide UI functionality
        if(keySpecialStates[GLUT_KEY_LEFT]) {printf("The Left Key was pressed.\n");}
        //if(!keySpecialStates[GLUT_KEY_LEFT]) {printf("The Left Key was not pressed.\n");}
        
        if(keySpecialStates[GLUT_KEY_RIGHT]) {printf("The Right Key was pressed.\n");}
        //if(!keySpecialStates[GLUT_KEY_RIGHT]) {printf("The Right Key was not pressed.\n");}
        
        if(keySpecialStates[GLUT_KEY_UP]) {printf("The Up Key was pressed.\n");}
        //if(!keySpecialStates[GLUT_KEY_UP]) {printf("The Up Key was not pressed.\n");}
        
        if(keySpecialStates[GLUT_KEY_DOWN]) {printf("The Down Key was pressed.\n");}
        //if(!keySpecialStates[GLUT_KEY_DOWN]) {printf("The Down Key was not pressed.\n");}
    }
    
    //Function to create shapes
    void renderPrimitive(void)
    {
        /*
        //SQUARE 
        glBegin(GL_LINE_LOOP); //Start drawing quad primitive
            glColor3f(1.0f, 0.0f, 0.0f);
            glVertex3f(-1.0f, -1.0f, 0.0f); //bottom left
            glColor3f(0.0f, 1.0f, 0.0f);
            glVertex3f(-1.0f, 1.0f, 0.f);   //top left
            glColor3f(0.0f, 0.0f, 1.0f);
            glVertex3f(1.0f, 1.0f, 0.0f);   // top right
            glColor3f(1.0f, 0.0f, 1.0f);
            glVertex3f(1.0f, -1.0f, 0.0f);  //bottom right
        glEnd(); */
        
        /*
        //SQUARE OUTLINE
        glBegin(GL_QUADS); //Start drawing quad primitive
            glColor3f(1.0f, 0.0f, 0.0f);
            glVertex3f(-1.0f, -1.0f, 0.0f); //bottom left
            glColor3f(0.0f, 1.0f, 0.0f);
            glVertex3f(-1.0f, 1.0f, 0.f);   //top left
            glColor3f(0.0f, 0.0f, 1.0f);
            glVertex3f(1.0f, 1.0f, 0.0f);   // top right
            glColor3f(1.0f, 0.0f, 1.0f);
            glVertex3f(1.0f, -1.0f, 0.0f);  //bottom right
        glEnd();*/
        
        /*
        //POINTS
        glPointSize(20.0f);
        glBegin(GL_POINTS);
            glVertex3f(-1.0f, -1.0f, 0.0f); //bottom left
            glVertex3f(-1.0f, 1.0f, 0.0f);  //top left
            glVertex3f(1.0f, 1.0f, 0.0f);   //top right
            glVertex3f(1.0f, -1.0f, 0.0f);  //bottom right
        glEnd(); */
        
        /*
        //SQUARE FROM TRIANGLE STRIPS
        glBegin(GL_TRIANGLE_STRIP); // Start drawing a triangle strip primitive  
            // The first triangle  
            glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner  
            glVertex3f(-1.0f, 1.0f, 0.0f); // The top left corner  
            glVertex3f(1.0f, 1.0f, 0.0f); // The top right corner  
            // The end of the second triangle  
            glVertex3f(1.0f, -1.0f, 0.0f); // The bottom right corner  
            glVertex3f(-1.0f, -1.0f, 0.0f); // The bottom left corner  
        glEnd(); */
        
        //glutWireSphere(2, 30, 30);
        //glutWireCube(2);
        //glutWireTorus(1, 2, 30, 30);
        glutWireTeapot(1);
    }
    
    //Function to draw the scene
    void display(void)
    {
        //Check for key operations each frame to avoid multiple keypresses per frame
        keyOperations();
        keySpecialOperations();
        
        //Handle drawing
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f); //Clear background of window
        glClear(GL_COLOR_BUFFER_BIT); //Clear the color buffer
        glLoadIdentity(); //Load identity matrix to reset drawing locations
        
        //Translate scene back
        glTranslatef(0.0f, 0.0f, -6.0f);
        
        //Move objects in scene
        glTranslatef(0.0f, yLocation, 0.0f); //Translate object along y-axis.
        glRotatef(yRotationAngle, 0.0f, 1.0f, 0.0f); //Rotate object along y-axis
        
        renderPrimitive();
        
        glutSwapBuffers(); //Swap buffers to the window
        
        //Control object movement
        
        //Control speed
        if(movingUp) //If object is moving up
            yLocation -= 0.005f; //Move up along yLocation
        
        else
            yLocation += 0.005f; //Moving down along yLocation
        
        //Control up or down direction
        if(yLocation < -3.0f) //If we went up to far
            movingUp = false; //Reverse direction
       
        else if(yLocation > 3.0f) //If we went down to far
            movingUp = true; //Reverse direction
        
        //Control rotation angle
        yRotationAngle += 0.05f; //Increment rotation value
        
        if(yRotationAngle > 360.0f) //If rotation is beyond bounds
            yRotationAngle -= 360.0f; //Subtract 360 from rotation
    }
    
    //Function to reshape the window when dragged
    void reshape(int width, int height)
    {
        //Set viewport to window size
        glViewport(0, 0, (GLsizei)width, (GLsizei)height); 
        
        // Switch to projection matrix to manipulate how scene is viewed
        glMatrixMode(GL_PROJECTION); 
        glLoadIdentity(); //Reset projection matrix to avoid artifacts
        
        //Set FOV, + Near and Far clip planes
        gluPerspective(60, (GLfloat)width / (GLfloat)height, 1.0, 100.0);
        
        //Switch back to modelview matrix
        glMatrixMode(GL_MODELVIEW);
    }
    //----------------------------------------------------------------------
    
    //======================================================================
    //                              Main Function
    //======================================================================
    int main(int argc, char** argv)
    {
    	glutInit(&argc, argv); //Initialize GLUT
        
        //Initialize key state arrays
        for(int i = 0; i < 256; ++i)
        {  
            keyStates[i] = false;
            keySpecialStates[i] = false;
        }
    	
        //Set display properties
        glutInitDisplayMode(GLUT_DOUBLE); //Set up a double display buffer
        glutInitWindowSize(500, 500); //Set the width and height of the window
        glutInitWindowPosition(100, 100); //Set window position
        glutCreateWindow("GSP 420"); //Set window caption
        
        //Window Control Functions
        glutDisplayFunc(display); //Tell glut to draw window based on function
        glutIdleFunc(display);    //Tell glut to use display as idle method as well
        glutReshapeFunc(reshape); //Tell glut to reshape the window when dragged
        
        //Keyboard Control Functions
        glutKeyboardFunc(keyDown); //Tell glut to use keyDown function to handle key presses
        glutKeyboardUpFunc(keyUp); //Tell glut to use keyUp function to handle key releases
        glutSpecialFunc(keySpecialDown); //Tell glut to use keySpecialDown function to handle special key events
        glutSpecialUpFunc(keySpecialUp); //Tell glut to use keySpecialUp function to handle special key up events
        
        
        //Glutloop to keep program running
        glutMainLoop();
    	
    	
    	return 0;
    }
     
  2. macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #2
    You really shouldn't use immediate mode in OpenGL. Stick to using VBOs and PBOs if you want to use modern features. I doubt driver writers bother doing too much optimisation in regards to immediate mode.

    This is the number one reason why OpenGL 4+ support is so important in Mac OS X. It is the first version (OpenGL 3.3 does as well to some degree) that deprecates all the old cruft that has built up in OpenGL over the years. Alas unless things have changed since I last looked it appears that we will be stuck with OpenGL 3.2 on Mac OS X Lion.

    The OpenGL Red book doesn't help much either (I have the OpenGL 2.1 version) as it literally describes everything without much of an indication of best practices.
     
  3. macrumors 65816

    jiminaus

    Joined:
    Dec 16, 2010
    Location:
    Sydney
    #3
    Further to what cromulent says, it seems the NVidia drivers are optimised better than the ATI drivers for immediate mode. On my 2.93 Ghz iMac9,1 with an NVidia GT 120 it runs smooth.
     
  4. thread starter macrumors 604

    chrono1081

    Joined:
    Jan 26, 2008
    Location:
    Isla Nublar
    #4
    Thanks guys!

    I'm not really sure what your responses mean yet (I'm still really new to OpenGL) but it will give me a starting point to look at. Thank you :)
     

Share This Page