PDA

View Full Version : how to add key functions



02-26-2002, 12:34 AM
Would appreciate any help in coding for x, y and S. When x is pushed it rotates around the x axis and y likewise for the y axis, and when S is pushed the rotation stops. this newbie has been at this on for 8 straight hours and the brain is fried. Help please..........

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <math.h>


// Define a constant for the value of PI
#define GL_PI 3.1415f

// Rotation amounts
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;

// Flags for effects
#define MODE_SOLID 0
#define MODE_LINE 1
#define MODE_POINT 2

int iMode = MODE_SOLID;
GLboolean bEdgeFlag = TRUE;

///////////////////////////////////////////////////////////////////////////////
// Reset flags as appropriate in response to menu selections
void ProcessMenu(int value)
{
switch(value)
{
case 1:
iMode = MODE_SOLID;
break;

case 2:
iMode = MODE_LINE;
break;

case 3:
iMode = MODE_POINT;
break;

case 4:
bEdgeFlag = TRUE;
break;

case 5:
default:
bEdgeFlag = FALSE;
break;
}

glutPostRedisplay();
}


// Called to draw scene
void RenderScene(void)
{
// Clear the window
glClear(GL_COLOR_BUFFER_BIT);


// Draw back side as a polygon only, if flag is set
if(iMode == MODE_LINE)
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

if(iMode == MODE_POINT)
glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);

if(iMode == MODE_SOLID)
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);


// Save matrix state and do the rotation
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);


// Begin the triangles
glBegin(GL_TRIANGLES);

glEdgeFlag(bEdgeFlag);
glVertex2f(-20.0f, 0.0f);
glEdgeFlag(TRUE);
glVertex2f(20.0f, 0.0f);
glVertex2f(0.0f, 40.0f);

glVertex2f(-20.0f,0.0f);
glVertex2f(-60.0f,-20.0f);
glEdgeFlag(bEdgeFlag);
glVertex2f(-20.0f,-40.0f);
glEdgeFlag(TRUE);

glVertex2f(-20.0f,-40.0f);
glVertex2f(0.0f, -80.0f);
glEdgeFlag(bEdgeFlag);
glVertex2f(20.0f, -40.0f);
glEdgeFlag(TRUE);

glVertex2f(20.0f, -40.0f);
glVertex2f(60.0f, -20.0f);
glEdgeFlag(bEdgeFlag);
glVertex2f(20.0f, 0.0f);
glEdgeFlag(TRUE);

// Center square as two triangles
glEdgeFlag(bEdgeFlag);
glVertex2f(-20.0f, 0.0f);
glVertex2f(-20.0f,-40.0f);
glVertex2f(20.0f, 0.0f);

glVertex2f(-20.0f,-40.0f);
glVertex2f(20.0f, -40.0f);
glVertex2f(20.0f, 0.0f);
glEdgeFlag(TRUE);
glEnd();
// Done drawing Triangles

//Drawing lines around the star

glBegin(GL_LINES);
glVertex2f(0.0f, 40.0f);
glVertex2f(60.0f, -20.0f);
glVertex2f(60.0f, -20.0f);
glVertex2f(0.0f, -80.0f);
glVertex2f(0.0f, -80.0f);
glVertex2f(-60.0f, -20.0f);
glVertex2f(-60.0f,-20.0f);
glVertex2f(0.0f, 40.0f);
glEnd();


glColor3f(1.0, 0.0, 0.0);
glTranslatef(70.0f, -20.0f, 0.0f);
glutSolidSphere(10.0f, 10, 10);

glColor3f(0.0, 0.0, 1.0);
glTranslatef(-70.0f, 0.0f, 0.0f);
glutSolidSphere(10.0f, 10, 10);
glEnd();
glColor3f(0.0, 1.0, 0.0);

// Restore transformations
glPopMatrix();

// Flush drawing commands
glutSwapBuffers();
}

// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );

// Set drawing color to green
glColor3f(0.0f, 1.0f, 0.0f);
}
void keys(unsigned char key, int x, int y)
{

if(key == 'x')xRot-=5.0f;
if(key == 'y')yRot-=5.0f;
//display();
}
void SpecialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
xRot-= 5.0f;

if(key == GLUT_KEY_DOWN)
xRot += 5.0f;

if(key == GLUT_KEY_LEFT)
yRot -= 5.0f;

if(key == GLUT_KEY_RIGHT)
yRot += 5.0f;

if(key > 356.0f)
xRot = 0.0f;

if(key < -1.0f)
xRot = 355.0f;

if(key > 356.0f)
yRot = 0.0f;

if(key < -1.0f)
yRot = 355.0f;

// Refresh the Window
glutPostRedisplay();
}


void ChangeSize(int w, int h)
{
GLfloat nRange = 100.0f;

// Prevent a divide by zero
if(h == 0)
h = 1;

// Set Viewport to window dimensions
glViewport(0, 0, w, h);

// Reset projection matrix stack
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
else
glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);

// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main(int argc, char* argv[])
{
int nModeMenu;
int nEdgeMenu;
int nMainMenu;

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("Solid and Outlined Star");

// Create the Menu
nModeMenu = glutCreateMenu(ProcessMenu);
glutAddMenuEntry("Solid",1);
glutAddMenuEntry("Outline",2);
glutAddMenuEntry("Points",3);

nEdgeMenu = glutCreateMenu(ProcessMenu);
glutAddMenuEntry("On",4);
glutAddMenuEntry("Off",5);

nMainMenu = glutCreateMenu(ProcessMenu);
glutAddSubMenu("Mode", nModeMenu);
glutAddSubMenu("Edges", nEdgeMenu);
glutAttachMenu(GLUT_RIGHT_BUTTON);

glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();

return 0;
}

02-26-2002, 02:55 AM
I tried to do as few changes to your code as possible.



#include <GL/glut.h>
#include <math.h>


// Define a constant for the value of PI
#define GL_PI 3.1415f
#define TRUE 1
#define FALSE 0

// Rotation amounts
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;

// flags for start/stop rotation
int doX = 0;
int doY = 0;

// Flags for effects
#define MODE_SOLID 0
#define MODE_LINE 1
#define MODE_POINT 2

int iMode = MODE_SOLID;
GLboolean bEdgeFlag = TRUE;

///////////////////////////////////////////////////////////////////////////////
// Reset flags as appropriate in response to menu selections
void ProcessMenu(int value)
{
switch (value) {
case 1:
iMode = MODE_SOLID;
break;

case 2:
iMode = MODE_LINE;
break;

case 3:
iMode = MODE_POINT;
break;

case 4:
bEdgeFlag = TRUE;
break;

case 5:
default:
bEdgeFlag = FALSE;
break;
}

glutPostRedisplay();
}


// Called to draw scene
void RenderScene(void)
{
// Clear the window
glClear(GL_COLOR_BUFFER_BIT);


// Draw back side as a polygon only, if flag is set
if (iMode == MODE_LINE)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

if (iMode == MODE_POINT)
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);

if (iMode == MODE_SOLID)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);


// Save matrix state and do the rotation
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);

if (doX)
xRot -= 5.0f;
if (doY)
yRot -= 5.0f;
// Begin the triangles
glBegin(GL_TRIANGLES);

glEdgeFlag(bEdgeFlag);
glVertex2f(-20.0f, 0.0f);
glEdgeFlag(TRUE);
glVertex2f(20.0f, 0.0f);
glVertex2f(0.0f, 40.0f);

glVertex2f(-20.0f, 0.0f);
glVertex2f(-60.0f, -20.0f);
glEdgeFlag(bEdgeFlag);
glVertex2f(-20.0f, -40.0f);
glEdgeFlag(TRUE);

glVertex2f(-20.0f, -40.0f);
glVertex2f(0.0f, -80.0f);
glEdgeFlag(bEdgeFlag);
glVertex2f(20.0f, -40.0f);
glEdgeFlag(TRUE);

glVertex2f(20.0f, -40.0f);
glVertex2f(60.0f, -20.0f);
glEdgeFlag(bEdgeFlag);
glVertex2f(20.0f, 0.0f);
glEdgeFlag(TRUE);

// Center square as two triangles
glEdgeFlag(bEdgeFlag);
glVertex2f(-20.0f, 0.0f);
glVertex2f(-20.0f, -40.0f);
glVertex2f(20.0f, 0.0f);

glVertex2f(-20.0f, -40.0f);
glVertex2f(20.0f, -40.0f);
glVertex2f(20.0f, 0.0f);
glEdgeFlag(TRUE);
glEnd();
// Done drawing Triangles

//Drawing lines around the star

glBegin(GL_LINES);
glVertex2f(0.0f, 40.0f);
glVertex2f(60.0f, -20.0f);
glVertex2f(60.0f, -20.0f);
glVertex2f(0.0f, -80.0f);
glVertex2f(0.0f, -80.0f);
glVertex2f(-60.0f, -20.0f);
glVertex2f(-60.0f, -20.0f);
glVertex2f(0.0f, 40.0f);
glEnd();


glColor3f(1.0, 0.0, 0.0);
glTranslatef(70.0f, -20.0f, 0.0f);
glutSolidSphere(10.0f, 10, 10);

glColor3f(0.0, 0.0, 1.0);
glTranslatef(-70.0f, 0.0f, 0.0f);
glutSolidSphere(10.0f, 10, 10);
glEnd();
glColor3f(0.0, 1.0, 0.0);

// Restore transformations
glPopMatrix();

// Flush drawing commands
glutSwapBuffers();
}

// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

// Set drawing color to green
glColor3f(0.0f, 1.0f, 0.0f);
}
void keys(unsigned char key, int x, int y)
{

if (key == 'x')
doX = 1;
if (key == 'y')
doY = 1;
if (key == 'S') {
doX = 0;
doY = 0;
}
}
void SpecialKeys(int key, int x, int y)
{
if (key == GLUT_KEY_UP)
xRot -= 5.0f;

if (key == GLUT_KEY_DOWN)
xRot += 5.0f;

if (key == GLUT_KEY_LEFT)
yRot -= 5.0f;

if (key == GLUT_KEY_RIGHT)
yRot += 5.0f;

if (key > 356.0f)
xRot = 0.0f;

if (key < -1.0f)
xRot = 355.0f;

if (key > 356.0f)
yRot = 0.0f;

if (key < -1.0f)
yRot = 355.0f;

// Refresh the Window
glutPostRedisplay();
}


void ChangeSize(int w, int h)
{
GLfloat nRange = 100.0f;

// Prevent a divide by zero
if (h == 0)
h = 1;

// Set Viewport to window dimensions
glViewport(0, 0, w, h);

// Reset projection matrix stack
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -nRange,
nRange);
else
glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -nRange,
nRange);

// Reset Model view matrix stack
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void idleFun()
{
glutPostRedisplay();
}
int main(int argc, char *argv[])
{
int nModeMenu;
int nEdgeMenu;
int nMainMenu;

glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutCreateWindow("Solid and Outlined Star");

// Create the Menu
nModeMenu = glutCreateMenu(ProcessMenu);
glutAddMenuEntry("Solid", 1);
glutAddMenuEntry("Outline", 2);
glutAddMenuEntry("Points", 3);

nEdgeMenu = glutCreateMenu(ProcessMenu);
glutAddMenuEntry("On", 4);
glutAddMenuEntry("Off", 5);

nMainMenu = glutCreateMenu(ProcessMenu);
glutAddSubMenu("Mode", nModeMenu);
glutAddSubMenu("Edges", nEdgeMenu);
glutAttachMenu(GLUT_RIGHT_BUTTON);

glutReshapeFunc(ChangeSize);
glutKeyboardFunc(keys);
glutIdleFunc(idleFun);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();

return 0;
}

02-26-2002, 11:51 AM
Thanx a million. Appreciate the help.

02-26-2002, 12:16 PM
Just made the changes you suggested and the x, y and s key still do not work. Any other ideas? Anyone else got any ideas how to make it work?

zeckensack
02-26-2002, 01:02 PM
I have absolutely ZERO knowledge of GLUT.

That being said:

Snip:
if (key == 'x')
doX = 1;
if (key == 'y')
doY = 1;
if (key == 'S') {
doX = 0;
doY = 0;
}
}

If x and y are lowercase, shouldn't s be as well?

So change the last if to:
if (key == 's') {
doX = 0;
doY = 0;
}

Another snip:
if (key > 356.0f)
xRot = 0.0f;

if (key < -1.0f)
xRot = 355.0f;

if (key > 356.0f)
yRot = 0.0f;

if (key < -1.0f)
yRot = 355.0f;

What does key do in here? I believe you wanted to put xRot and yRot in there, like this:
if (xRot > 356.0f)
xRot = 0.0f;

if (xRot < -1.0f)
xRot = 355.0f;

if (yRot > 356.0f)
yRot = 0.0f;

if (yRot < -1.0f)
yRot = 355.0f;

I don't fully understand what you were trying to do here, this effectively sets all values to 355.0f as soon as the SpecialKeys function is called.

You might instead try something like this:

while (xRot>=360.0f)
{
xRot-=360.0f;
}
while (xRot<0.0f)
{
xRot+=360.0f;
}
while (yRot>=360.0f)
{
yRot-=360.0f;
}
while (yRot<0.0f)
{
yRot+=360.0f;
}

This will make the rotation values fall between 0.0f and 360.0f but will make the motion continuous.

Please explain what exactly happens on your screen http://www.opengl.org/discussion_boards/ubb/smile.gif
All blank? Stuff missing? Stuff not turning at all?

02-26-2002, 04:10 PM
Everything works like it is supposed to except the x,y and s key functions. The scene rotates on the x and y axis with the up/down and left/right keys but not the x,y and S keys. Everything is there and where it should be.
This is one of the exercises in my OpenGL class and I cannot find any material that talks about how to do the x,y and S keys and make them work.

02-26-2002, 09:15 PM
The modified code is OK, I just checked that with a copy->paste->rebuild. If the specification says "When x is pushed it rotates around the x axis and y likewise for the y axis, and when S is pushed the rotation stops." do they probably mean that x/y starts a animation and S should stop it.

To implement this did I first add two varibles called doX and doY for the current x and y spinning status.
The next step is to let the user change the values with keyboard input so a callback function must be given. The line "glutKeyboardFunc(keys); " gives a modified version of the keys function.
The third step is to enable animations. I used "glutIdleFunc(idleFun);" and let idleFun just post redisplay messages. The actual updates of the rotations is in the rendering function. This works but a better solution is to let the idle function, idleFun, check doX and doY and update the angles and post a redisplay message only if needed.

I must admit that I never looked closer at your code and zeckensack is right. I had to add defines for TRUE and FALSE, perhaps did you mean GL_TRUE and GL_FALSE? Using a switch statement is also prettier than a sequence of if statements checking the same variable.