Reputation: 33
I'm studying some very basic 3D rendering using opengl, but my teacher uses a pc under wich you can use the sleep() function for rendering each of the animation's frames.
However when i try to do the same thing on my mac i only get the last frame. if i use the sleep() function my mac goes literally to sleep mode.
I've read something about an NSTimer but i don't know how to implement it.
Here's my code, it works just fine on a pc, i only want to replace the commented sleep() with a mac equivalent that enables me to see each frame during that delay
#include<OpenGL/gl.h>
#include<OpenGL/glu.h>
#include<GLUT/glut.h>
#include <stdlib.h>
void init (void)
{
glClearColor(0.5,0.5,0.5,0);
glMatrixMode(GL_MODELVIEW);
gluLookAt(0,4,4,0,0,0,0,1,0);
glMatrixMode(GL_PROJECTION);
gluPerspective(90,1,1,12);
}
void Cubes(void)
{
int i=0;
glMatrixMode(GL_MODELVIEW);
glutInitDisplayMode(GL_DEPTH);
for (i=0; i<360;i++)
{
glRotated(1,1,0,0);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,0,0);
glutSolidSphere(1,20,20);
glColor3f(0.8,0.8,0);
glutWireSphere(1,20,20);
glColor3f(0,0,1);
glutSolidTorus(1,2,40,40);
glFlush();
glDisable(GL_DEPTH_TEST);
//Sleep(20);
}
}
int main (int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(600,600);
glutCreateWindow("Depth Buffer");
init();
glutDisplayFunc(Cubes);
glutMainLoop();
}
Upvotes: 2
Views: 9483
Reputation: 162367
Please tell your teacher that he is doing it wrong! To do a animation with GLUT don't put a animation loop into the display function, but register a idle function, that reissues a display. Also this code misses a buffer swap (which is mandatory on MacOS X if not running in full screen mode, to tell the compositor you're done with rendering).
Also you shouldn't sleep for an animation (the buffer swap will do this anyway) but measure the time between frames.
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>
#include <stdlib.h>
#include <sys/time.h>
#include <math.h>
#include <stdio.h>
double getftime(
void )
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + tv.tv_usec*1e-6;
}
static double lasttime;
void display(
void )
{
int width, height;
double finishtime, delta_t;
static float angle = 0;
width = glutGet(GLUT_WINDOW_WIDTH);
height = glutGet(GLUT_WINDOW_HEIGHT);
glClearColor( 0.5, 0.5, 0.5, 1.0 );
/* combine the clearing flags for more efficient operation */
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
glViewport(0, 0, width, height);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
gluPerspective( 90, (float)width/(float)height, 1, 12 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
gluLookAt( 0, 4, 4, 0, 0, 0, 0, 1, 0 );
glEnable( GL_DEPTH_TEST );
glRotated( angle, 1, 0, 0 );
glColor3f( 1, 0, 0 );
glutSolidSphere( 1, 20, 20 );
glColor3f( 0.8, 0.8, 0 );
glutWireSphere( 1, 20, 20 );
glColor3f( 0, 0, 1 );
glutSolidTorus( 1, 2, 40, 40 );
glDisable( GL_DEPTH_TEST );
glutSwapBuffers();
finishtime = getftime();
delta_t = finishtime - lasttime;
angle = fmodf(angle + 10*delta_t, 360);
lasttime = finishtime;
}
int main(
int argc,
char **argv )
{
glutInit( &argc, argv );
glutInitWindowSize( 600, 600 );
/* glutInitDisplayMode must be called before glutCreateWindow, flags are prefixed with GLUT_ not GL */
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutCreateWindow( "Depth Buffer" );
glutDisplayFunc( display );
/* register glutPostRedisplay for continuous animation */
glutIdleFunc(glutPostRedisplay);
lasttime = getftime();
glutMainLoop( );
}
Upvotes: 3
Reputation: 271
I concur with the above posts that your teacher is wrong. However, to answer your question, use usleep(useconds_t useconds) to sleep on mac os x. here's the man page:
https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/usleep.3.html
note that the sleep time is in microseconds instead of milliseconds like it is on windows. Also note that like on windows, it will sleep at least the time specified. It might sleep a whole lot longer, which is one of the many reasons you shouldn't use it but should measure the time between frames and update appropriately instead.
Cheers!
Upvotes: -1