High CPU usage when animating the object

Dear all,
I have made the robot arm and animated it with the following function


//To animate the robot arm
void animate(void)
{
	
	while(psi<90.0){
		//accelerate at the middle
		if (psi>=-20 && psi<=20) psi+=2.0;
		//deccelerate at the end
		else if (psi>=70 && psi<=90) psi+=0.2;
		//Normal speed
		else psi+=1.0;
		showobj();
	}
	

	while(psi>-90.0){
		//accelerate at the middle
		if (psi>=-20 && psi<=20) psi-=2.0;
		//deccelerate at the end
		else if (psi>=-90 && psi<=-70) psi-=0.2;
		//Normal speed
		else psi-=1.0;
		showobj();
	}
}


But it turns out that I experienced high CPU usage making me even difficult to close the window.

I appreciate if anyone can help~
Thanks for all your attentions

What does showobj() exactly ?
Enable vsync to at least not render more frames than needed.
Low tech but easy : add a small wait between each loop iteration.

EDIT: the common way to do animation is to have a single big loop (or timed events) calling the rendering code and the action code.

Thanks ZBufferR, I will try to add wait command in the loop to see if it works~

And one more q, I want to add the texture to the floor in which the robot arm is placed, what I need to do is to draw a rectangular plane with the desired size within glBegin and glEnd command and apply the texture on the retangular plane, am I right? Please give some suggestions~

The following is my basic design

Just give it a try and it seems that the texture does not appear on the floor, wanna know if anything goes wrong :frowning:
The following is my written code


//Import library
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <GL/glut.h>
#include "gsrc.h"	
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include <gl\glaux.h>

// angles to rotate the base, lower and upper arms of the robot arm
double theta, phi, psi;	

void drawCoordinates();
void drawTexture();
//Storage of the texture
GLuint texture[1];

//Draw the base of the robot arm
void draw_base(){
	glPushMatrix();
		//to create the quadric objects
		GLUquadric *qobj,*qobjl,*qobju;
		qobj = gluNewQuadric(); 
		qobjl = gluNewQuadric(); 
		qobju = gluNewQuadric(); 

		//set the color of the cylinder
		glColor3f(1.0,0.0,0.0); 
		//Re-position the cylinder (x-z plane is the base)
		glRotatef(-90,1.0,0.0,0.0);
		//Draw the cylinder
		gluCylinder(qobj, 30.0, 30.0, 40.0, 40.0, 40.0);
		//Draw the upper disk of the base
		gluDisk(qobju,0,30,40,40);

		glPushMatrix();
			//Change the M(lowdisk<updisk)
			glTranslatef(0,0,40);
			glColor3f(0,0,0); 
			//Draw the lower disk of the base
			gluDisk(qobjl,0,30,40,40);
		glPopMatrix();
   glPopMatrix();
}

/****************************Texture Work Starts***************************************/
//Load the bmp file for texture
AUX_RGBImageRec* loadimg(char* filename){
	//set the file handle to null first
	FILE* file=NULL; 
	//check filename was actually given
	if (!filename) return NULL;
	//try to read the file
	file = fopen(filename,"r");
	//success to read the image and return the image data to the imagerec pointer
	if (file){
		//close the file pointer first
		fclose(file);
		//load the image and return the pointer
		return auxDIBImageLoad(filename);
	}
	//read fail return null
	return NULL;
}

//load the bitmaps and make it to texture for ground floor use
int loadTexture(){
	//keep track of we can load the bitmap or not
	int canload=FALSE;
	//create image record to store the texture data
	AUX_RGBImageRec *TextureImage[1];
	//set the pointer to null
	memset(TextureImage,0,sizeof(void *)*1);
	//load the bitmap here
	if (TextureImage[0]=loadimg("../floor256x256.bmp"))
	{
		//image load finished, start to deal with texture
		canload=TRUE;
		//create texture, [0] for one texture only
		glGenTextures(1, &texture[0]);					
		//bind texture name to texture data
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		//Make the texture here
		glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
		//Perform linear filtering
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);	
		glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);	
		
		//if there is any data in the ram, we erase it to make sure that the memory is freed
		if (TextureImage[0])							
			{
				if (TextureImage[0]->data)				
				{
					free(TextureImage[0]->data);				
				}

				free(TextureImage[0]);					
			}
	}

	//if everything is ok, return 0, else return 1
	return canload;
}

/****************************Texture Work Ends***************************************/

//initialize the window and everything to prepare for display
int init_gl() {
	glClearColor(1,1,1,0);//set display color to white
	//clear and enable z-buffer 
    glClear (GL_DEPTH_BUFFER_BIT);
    glEnable (GL_DEPTH_TEST);
	//clear display window
	glClear(GL_COLOR_BUFFER_BIT);
	//if texture cannot be loaded, return false
	if (!loadTexture())							
	{
		return FALSE;							
	}
	//enable Texture Mapping
	glEnable(GL_TEXTURE_2D);						
	//Smooth shading for better appearance
	glShadeModel(GL_SMOOTH);
	//Everything is ok, return true
	return TRUE;
}

//Draw the 2x2x2 cube with center (0,1,0)
void cube(){ 
	glPushMatrix();
		glTranslatef(0,1,0);
		glutSolidCube(2);
	glPopMatrix();	
}

//Draw the lower arm
void draw_lower_arm(){
	glPushMatrix();
	glScalef(15.0/2.0,70.0/2.0,15.0/2.0);//scale half is enough (some part is in the negative side)
	cube();
	glPopMatrix();
}

//Draw the upper arm
void draw_upper_arm(){
	glPushMatrix();
	glScalef(15.0/2.0,40.0/2.0,15.0/2.0);//scale half is enough (some part is in the negative side)
	cube();
	glPopMatrix();
}

//Our drawing starts here
void showobj(void) {
   //set the projection and perspective parameters/arguments
    GLint viewport[4];
    glGetIntegerv( GL_VIEWPORT, viewport );
    glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective( 45, double(viewport[2])/viewport[3], 0.1, 1000 );
    glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
      gluLookAt( 0, 0, 400, 0, 0, 0, 0,1,0 );

	  // get the rotation matrix from the rotation user-interface
	  glMultMatrixf( gsrc_getmo() );  
	  //Draw coordinates
	  drawCoordinates();
	  
	  //Clear the display and ready to show the robot arm
	  int success;
	  success=init_gl();

	  //Place the texture
	  drawTexture();

	  //Robot Drawing Starts
	  //Rotate the base by theta degrees
	  glRotatef(theta,0.0,1.0,0.0); 
	  //Draw the base
	  draw_base();
	  //M(B<La)
	  glTranslatef(0.0,40.0,0.0);
	  //Rotate the lower arm by phi degree
	  glRotatef(phi,0.0,0.0,1.0);
	  //change the color of the lower arm
	  glColor3f(0.0,0.0,1.0);
	  //Draw the lower arm
	  draw_lower_arm();
	  //M(La<Ua)
	  glTranslatef(0.0,70.0,0.0);
	  //Rotate the upper arm by psi degree
	  glRotatef(psi,0.0,0.0,1.0);
	  //change the color of the upper arm
	  glColor3f(0.0,1.0,0.0);
	  //Draw the upper arm
	  draw_upper_arm();
	  //Drawing Finish  
	  glFlush ();
	  glutSwapBuffers();
}

//draw texture on floor
void drawTexture(){
	glBindTexture(GL_TEXTURE_2D, texture[0]);
	glBegin(GL_QUADS);
		glTexCoord2f(1.0f, 1.0f); 
		glVertex3f(-1.0f, -1.0f, -1.0f);	
		glTexCoord2f(0.0f, 1.0f); 
		glVertex3f( 1.0f, -1.0f, -1.0f);	
		glTexCoord2f(0.0f, 0.0f); 
		glVertex3f( 1.0f, -1.0f,  1.0f);	
		glTexCoord2f(1.0f, 0.0f); 
		glVertex3f(-1.0f, -1.0f,  1.0f);
	glEnd();
}

void drawCoordinates(){
	glBegin (GL_LINES);
		glColor3f (1,0,0);
		glVertex3f (0,0,0);
		glVertex3f (1,0,0);

		glColor3f (0,1,0);
		glVertex3f (0,0,0);
		glVertex3f (0,1,0);

		glColor3f (0,0,1);
		glVertex3f (0,0,0);
		glVertex3f (0,0,1);
	glEnd();
}

//To animate the robot arm
void animate(void)
{
	
	while(psi<90.0){
		//accelerate at the middle
		if (psi>=-20 && psi<=20) psi+=2.0;
		//deccelerate at the end
		else if (psi>=70 && psi<=90) psi+=0.2;
		//Normal speed
		else psi+=1.0;
		showobj();
	}
	

	while(psi>-90.0){
		//accelerate at the middle
		if (psi>=-20 && psi<=20) psi-=2.0;
		//deccelerate at the end
		else if (psi>=-90 && psi<=-70) psi-=0.2;
		//Normal speed
		else psi-=1.0;
		showobj();
	}
}


//Deal with shadow matrix
void showshadow(){

}

void main (int argc, char** argv)
{ 
	glutInit(&argc, argv); 
	//DOUBLE mode better for animation
	// Set display mode.
	glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH);
	
	glutInitWindowPosition( 50, 100 ); // Set top-left display-window position.
	glutInitWindowSize( 400, 300 ); // Set display-window width and height.
	glutCreateWindow( "EE5808 Mini-Project" ); // Create display window.

	  // Register mouse-click and mouse-move glut callback functions
	  // for the rotation user-interface.
	  //Allow user to drag the mouse and view the object
	  glutMouseFunc( gsrc_mousebutton );
	  glutMotionFunc( gsrc_mousemove );   

	//set the initial value of the 3 angles
	  theta = phi = 0.0;
	  psi = -90.0;

	// Display everything in showobj function
    glutDisplayFunc(showobj); 
	//Perform background processing tasks or continuous animation
	glutIdleFunc(animate);
	glutMainLoop(); 
}

Add Sleep(1); (at least 1, better more) at the end of while loops; They consume all processor time.