How to Keep Rotating Without Holding Key ?

I want to make a fan with start, Stop, Fast Rotate, Slow Rotate etc. Problem is i need to hold the key to do so. How can i manage those key stroke ,until another one pressed or program exist.
Here is the Code


#include <stdio.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

float _angle = 0.0f, // For rotating the fan
  xpos = 0.0f, // For moving the fan in the X axis
  ypos = 0.0f, // For moving the fan in the Y axis
  cameraheight = -10.0f; // For zoom or unzoom the camera

bool upKeyPressed;

// handleKeypress
void handleKeypress (unsigned char key, int x, int y)
{
  switch (key) {
    case 'a': _angle -= 5; break;
    case 'r': _angle += 5;
/*for(int i=5; i>30; i--){
  _angle = i;
  } */ break;

    case 'A': _angle -= 10; break;
    case 'R': _angle += 10; break;
    case '1': cameraheight -= 5.0f; break;
    case '2': cameraheight += 5.0f; break;
    case 'v': xpos += 1.0f; break;
    case 'l': xpos -= 1.0f; break;
    case 'g': ypos += 1.0f; break;
    case 'b': ypos -= 1.0f; break;

    case 'w': xpos = 0.0f;
      ypos = 0.0f;
      _angle = 0.0f;
      cameraheight = -10.0f; break;

    case 27: exit(0); break; // esc
  }

  glutPostRedisplay ();
}

// initRendering
void initRendering (void)
{
  glEnable (GL_DEPTH_TEST);
  glEnable (GL_COLOR_MATERIAL);
  glClearColor (0.2f, 0.2f, 0.2f, 1.0f);
}

// handleResize
void handleResize (int w, int h)
{
  glViewport (0, 0, w, h);
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  gluPerspective (45.0, (double)w / (double)h, 0.01, 500.0);
}

// Draw_Car
void Draw_Fan (void)
{
  glPushMatrix();
  glBegin(GL_POLYGON);
  glColor3f(0.0,1.0,0.0);
  for(int i=0;i<200;i++)
  {
    float pi=3.1416;
    float A=(i*2*pi)/100;
    float r=0.60;
    float x = r * cos(A);
    float y = r * sin(A);
    glVertex2f(x,y );
  }
  glEnd();
  glPopMatrix();

  glPushMatrix();
  glTranslatef(0.0, 0.28, 0.0);
  glScalef(0.40, 3.50, 0.0);
  glBegin(GL_POLYGON);
  glColor3f(0.0,.1,0.0);
  glVertex3f(0.6, 0.0, 0.0);
  glVertex3f(-0.6, 0.0, 0.0);
  glColor3f(0.0,1.0,0.0);
  glVertex3f(-0.6, 0.6, 0.0);
  glVertex3f(0.6, 0.6, 0.0);
  glEnd();
  glPopMatrix();

  glPushMatrix();
  glRotatef(-120.0, 0.0, 0.0, 1.0f);
  glPushMatrix();
  glTranslatef(0.0, 0.29, 0.0);
  glScalef(0.40, 3.50, 0.0);
  glBegin(GL_POLYGON);
  glColor3f(0.0,.0,1.0);
  glVertex3f(0.6, 0.0, 0.0);
  glVertex3f(-0.6, 0.0, 0.0);
  glColor3f(0.0,1.0,0.0);
  glVertex3f(-0.6, 0.6, 0.0);
  glVertex3f(0.6, 0.6, 0.0);
  glEnd();
  glPopMatrix();
  glPopMatrix();

  glPushMatrix();
  glRotatef(115.0, 0.0, 0.0, 1.0f);
  glPushMatrix();
  glTranslatef(0.0, 0.29, 0.0);
  glScalef(0.40, 3.50, 0.0);
  glBegin(GL_POLYGON);
  glColor3f(0.0,.0,1.0);
  glVertex3f(0.6, 0.0, 0.0);
  glVertex3f(-0.6, 0.0, 0.0);
  glColor3f(0.0,6.0,0.0);
  glVertex3f(-0.6, 0.6, 0.0);
  glVertex3f(0.6, 0.6, 0.0);
  glEnd();
  glPopMatrix();
  glPopMatrix();

}

// drawScene
void drawScene (void)
{
  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();

  glTranslatef ( 0.0f, 0.0f, cameraheight);
  glTranslatef (xpos, ypos, 0.0f);
  glPushMatrix();
  glRotatef (-_angle, 0.0f, 0.0f, 1.0f);
  Draw_Fan ();
  glPopMatrix();

  glutSwapBuffers();
}

// update
void update (int value)
{
  _angle += 0.1f;
  if (_angle > 360 ){
    _angle -= 360;
  }

  glutPostRedisplay ();
  glutTimerFunc (16, update, 0);
}

//instruction
void instruction()
{ cout<< "r for rotate" <<endl;
  cout<< "a for anti clockwise rotate" <<endl;
  cout<< "R for fast rotate" <<endl;
  cout<< "A for fast anti clockwise rotate" <<endl;
  cout<< "g for up" <<endl;
  cout<< "b for down" <<endl;
  cout<< "l for left" <<endl;
  cout<< "v for right" <<endl;
  cout<< "1 for zoom out" <<endl;
  cout<< "2 for zoom in" <<endl;

}

// main
int main (int argc, char* argv[])
{
  glutInit (&argc, argv);
  glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowSize (640, 480);
  glutInitWindowPosition (400, 200);

  glutCreateWindow ("FAN");
  initRendering ();
  instruction();

  glutDisplayFunc (drawScene);
  glutKeyboardFunc (handleKeypress);
//glutKeyboardUpFunc (handleKeypress);
  glutReshapeFunc (handleResize);

  glutMainLoop ();
  return 0;
}

Use glutTimerFunc() or glutIdleFunc() to cause a function to be called continuously. That function should update the rotation angle then call glutPostRedisplay() to cause the window to be re-drawn.

PS: use

 tags rather than [quote] for code, in order to preserve formatting.

[QUOTE=GClements;1284902]Use glutTimerFunc() or glutIdleFunc() to cause a function to be called continuously. That function should update the rotation angle then call glutPostRedisplay() to cause the window to be re-drawn.

PS: use

 tags rather than 
>  for code, in order to preserve formatting.


Thanks for reply. will check & let u know. Thanks again.

I Have this function, see bottom of my code but it still doesn’t work. If i hold the key then it rotate . Sorry to bother u. I am really a newbie to this.

Your update() function never gets called. You need to call glutTimerFunc() from within main() to have it called the first time.

Add something like a ‘z’ key shown below.


float _angle = 0.0f;

void handleKeypress (unsigned char key, int x, int y)
{
   static short anim = 0;

   switch (key)  {
      case 'z':    anim = !anim;   break;
      case 'a':    _angle -= 5;    break;
      case 'r':    _angle += 5;    break;
      case 'A':    _angle -= 10;   break;
      .
      .
      .
      case 27:  exit(0);   break;
   }

   if (anim)  glutIdleFunc (update);
   else       glutIdleFunc ( NULL );

   glutPostRedisplay ();
}

After adding those line that doesn’t work. Shows error that “Update was not declared on that scope”



#include <stdio.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
#include <iostream>
using namespace std;


float _angle = 0.0f, // For rotating the fan
xpos = 0.0f, // For moving the fan in the X axis
ypos = 0.0f, // For moving the fan in the Y axis
cameraheight = -10.0f; // For zoom or unzoom the camera


bool upKeyPressed;


// handleKeypress
void handleKeypress (unsigned char key, int x, int y)
{
static short anim = 0;
switch (key) {
case 'z': anim = !anim; break;
case 'a': _angle -= 5; break;
case 'r': _angle += 5;
/*for(int i=5; i>30; i--){
_angle = i;
} */ break;


case 'A': _angle -= 10; break;
case 'R': _angle += 10; break;
case '1': cameraheight -= 5.0f; break;
case '2': cameraheight += 5.0f; break;
case 'v': xpos += 1.0f; break;
case 'l': xpos -= 1.0f; break;
case 'g': ypos += 1.0f; break;
case 'b': ypos -= 1.0f; break;


case 'w': xpos = 0.0f;
ypos = 0.0f;
_angle = 0.0f;
cameraheight = -10.0f; break;


case 27: exit(0); break; // esc
}

if (anim) glutIdleFunc (update);
else glutIdleFunc ( NULL );

glutPostRedisplay ();
}


// initRendering
void initRendering (void)
{
glEnable (GL_DEPTH_TEST);
glEnable (GL_COLOR_MATERIAL);
glClearColor (0.2f, 0.2f, 0.2f, 1.0f);
}


// handleResize
void handleResize (int w, int h)
{
glViewport (0, 0, w, h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45.0, (double)w / (double)h, 0.01, 500.0);
}


// Draw_Car
void Draw_Fan (void)
{
glPushMatrix();
glBegin(GL_POLYGON);
glColor3f(0.0,1.0,0.0);
for(int i=0;i<200;i++)
{
float pi=3.1416;
float A=(i*2*pi)/100;
float r=0.60;
float x = r * cos(A);
float y = r * sin(A);
glVertex2f(x,y );
}
glEnd();
glPopMatrix();


glPushMatrix();
glTranslatef(0.0, 0.28, 0.0);
glScalef(0.40, 3.50, 0.0);
glBegin(GL_POLYGON);
glColor3f(0.0,.1,0.0);
glVertex3f(0.6, 0.0, 0.0);
glVertex3f(-0.6, 0.0, 0.0);
glColor3f(0.0,1.0,0.0);
glVertex3f(-0.6, 0.6, 0.0);
glVertex3f(0.6, 0.6, 0.0);
glEnd();
glPopMatrix();


glPushMatrix();
glRotatef(-120.0, 0.0, 0.0, 1.0f);
glPushMatrix();
glTranslatef(0.0, 0.29, 0.0);
glScalef(0.40, 3.50, 0.0);
glBegin(GL_POLYGON);
glColor3f(0.0,.0,1.0);
glVertex3f(0.6, 0.0, 0.0);
glVertex3f(-0.6, 0.0, 0.0);
glColor3f(0.0,1.0,0.0);
glVertex3f(-0.6, 0.6, 0.0);
glVertex3f(0.6, 0.6, 0.0);
glEnd();
glPopMatrix();
glPopMatrix();


glPushMatrix();
glRotatef(115.0, 0.0, 0.0, 1.0f);
glPushMatrix();
glTranslatef(0.0, 0.29, 0.0);
glScalef(0.40, 3.50, 0.0);
glBegin(GL_POLYGON);
glColor3f(0.0,.0,1.0);
glVertex3f(0.6, 0.0, 0.0);
glVertex3f(-0.6, 0.0, 0.0);
glColor3f(0.0,6.0,0.0);
glVertex3f(-0.6, 0.6, 0.0);
glVertex3f(0.6, 0.6, 0.0);
glEnd();
glPopMatrix();
glPopMatrix();


}


// drawScene
void drawScene (void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();


glTranslatef ( 0.0f, 0.0f, cameraheight);
glTranslatef (xpos, ypos, 0.0f);
glPushMatrix();
glRotatef (-_angle, 0.0f, 0.0f, 1.0f);
Draw_Fan ();
glPopMatrix();


glutSwapBuffers();
}


// update
void update (int value)
{
_angle += 0.1f;
if (_angle > 360 ){
_angle -= 360;
}


glutPostRedisplay ();
glutTimerFunc (0, update, 0);
}


//instruction
void instruction()
{ cout<< "r for rotate" <<endl;
cout<< "a for anti clockwise rotate" <<endl;
cout<< "R for fast rotate" <<endl;
cout<< "A for fast anti clockwise rotate" <<endl;
cout<< "g for up" <<endl;
cout<< "b for down" <<endl;
cout<< "l for left" <<endl;
cout<< "v for right" <<endl;
cout<< "1 for zoom out" <<endl;
cout<< "2 for zoom in" <<endl;


}


// main
int main (int argc, char* argv[])
{
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (640, 480);
glutInitWindowPosition (400, 200);


glutCreateWindow ("FAN");
initRendering ();
instruction();


glutDisplayFunc (drawScene);
glutKeyboardFunc (handleKeypress);
//glutKeyboardUpFunc (handleKeypress);
glutReshapeFunc (handleResize);


glutMainLoop ();
return 0;
}

After adding those line that doesn’t work. Shows error that "Update was not declared on that scope

Move the Update routine above the handleKeypress routine.