PDA

View Full Version : Macbook Air running this smoother than Mac Pro tower?? (OpenGL code)




chrono1081
May 7, 2011, 05:23 PM
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)

//
// 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;
}



Cromulent
May 7, 2011, 05:46 PM
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.

jiminaus
May 7, 2011, 05:55 PM
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.

chrono1081
May 8, 2011, 03:40 AM
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 :)