PDA

View Full Version : High CPU usage when animating the object



openglam
03-02-2011, 07:43 AM
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 &amp;&amp; psi<=20) psi+=2.0;
//deccelerate at the end
else if (psi>=70 &amp;&amp; psi<=90) psi+=0.2;
//Normal speed
else psi+=1.0;
showobj();
}


while(psi>-90.0){
//accelerate at the middle
if (psi>=-20 &amp;&amp; psi<=20) psi-=2.0;
//deccelerate at the end
else if (psi>=-90 &amp;&amp; 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

ZbuffeR
03-02-2011, 08:42 AM
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.

openglam
03-02-2011, 09:01 AM
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
http://i102.photobucket.com/albums/m112/ihmcjacky/2011-03-02235314.jpg

openglam
03-02-2011, 10:37 AM
Just give it a try and it seems that the texture does not appear on the floor, wanna know if anything goes wrong :(
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, &amp;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_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,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 &amp;&amp; psi<=20) psi+=2.0;
//deccelerate at the end
else if (psi>=70 &amp;&amp; psi<=90) psi+=0.2;
//Normal speed
else psi+=1.0;
showobj();
}


while(psi>-90.0){
//accelerate at the middle
if (psi>=-20 &amp;&amp; psi<=20) psi-=2.0;
//deccelerate at the end
else if (psi>=-90 &amp;&amp; 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(&amp;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();
}

Nowhere-01
03-04-2011, 12:34 AM
Add Sleep(1); (at least 1, better more) at the end of while loops; They consume all processor time.