multiple key input

Started by
14 comments, last by ishkabible 14 years ago
ok so im new to OpenGL... very new. I seem to be getting a bit of a grasp of it as i am playing around with the default "hello world" program for the GLUT project setup on my IDE. i actuality have decided to try and make a simple 3D top down shooter (try being the key word). so one of the things i like so far about OpenGL is how easy the Keyboard input is to learn and how simple it is but i have one major problem, it doesn't seem to support receiving multiple key's as input. for example say your using WASD keys for movement and you press W and A you should go up and left but no you go in the direction of the last one you pressed. i would like a way tofix this very much here is my code.

 /*
 * GLUT Shapes Demo
 *
 * Written by Nigel Stewart November 2003
 *
 * This program is test harness for the sphere, cone
 * and torus shapes in GLUT.
 *
 * Spinning wireframe and smooth shaded shapes are
 * displayed until the ESC or q key is pressed.  The
 * number of geometry stacks and slices can be adjusted
 * using the + and - keys.
 */

#include <windows.h>
#include <GL/glut.h>
#include <stdlib.h>

static int slices = 16;
static int stacks = 16;

/* GLUT callback Handlers */
class ball {
 public:
    float x;
    float y;
    float z;
    float XR;
    float YR;
    float ZR;
    void init(float BX, float BY, float BZ, float BXR, float BYR, float BZR);
};
void ball::init(float BX, float BY, float BZ, float BXR, float BYR, float BZR){
 x = BX;
 y = BY;
 z = BZ;
 XR = BXR;
 YR = BYR;
 ZR = BZR;
}
ball myBall;

static void resize(int width, int height)
{
    const float ar = (float) width / (float) height;

    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity() ;
}

static void display(void)
{
    const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
    const double a = t*90.0;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glColor3d(1,0,0);
    glPushMatrix();
        glTranslated(myBall.x,myBall.y,myBall.z);
        glRotated(0,0,0,0);
        glRotated(0,0,0,1);
        glutSolidCube(1);
    glPopMatrix();
    glutSwapBuffers();
}

static void key(unsigned char key, int x, int y)
{
    switch (key)
    {
        case 27 :
        case 'q':
            exit(0);
            break;

        case '+':
            slices++;
            stacks++;
            break;

        case '-':
            if (slices>3 && stacks>3)
            {
                slices--;
                stacks--;
            }
            break;
        case 'w' :
            myBall.y+= 0.1;
            break;
        case 'a' :
            myBall.x-=0.1;
            break;
        case 's' :
            myBall.y-=0.1;
            break;
        case 'd' :
            myBall.x+=0.1;
            break;
        case 'g':
            myBall.z+=0.1;
            break;
        case 'h':
            myBall.z-=0.1;
            break;
        case 'x' :
            myBall.XR=1;
            break;
        case 'y' :
            myBall.YR=1;
            break;
        case 'z' :
            myBall.ZR=1;
            break;
        case 'c' :
            myBall.XR=0;
            break;
        case 't' :
            myBall.YR=0;
            break;
        case 'v' :
            myBall.ZR=0;
            break;
    }

    glutPostRedisplay();
}

static void idle(void)
{
    glutPostRedisplay();
}

const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };

const GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };

/* Program entry point */

int main(int argc, char *argv[])
{
    myBall.init(0, -1.2, -6, 0, 0, 0);
    glutInit(&argc, argv);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(10,10);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("GLUT Shapes");

    glutReshapeFunc(resize);
    glutDisplayFunc(display);
    glutKeyboardFunc(key);
    glutIdleFunc(idle);

    glClearColor(1,1,1,1);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);

    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);

    glEnable(GL_LIGHT0);
    glEnable(GL_NORMALIZE);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);

    glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);

    glutMainLoop();

    return EXIT_SUCCESS;
}

[Edited by - ishkabible on April 19, 2010 8:13:58 PM]
Advertisement
OpenGL doesn't handle input, GLUT just does that for you, but GLUT is very limited, i don't think you can what you want with it.
What you need to do is create an array that holds the status of each key (pressed or not) which gets updated in the key method (you will also need to add a keyup method, using glutKeyboardUpFunc). Then, in your main loop (rather than in the key method), you want to check which keys are pressed down and update your data accordingly.
so are you saying to something like this in my main for every key

bool KeyArray[256];// make this global var

if(!glutKeyboardUpFunc('w', ?, ?)) {
KeyArray[0] = true;
}

o and by the way i put "?" in the function arguments cuz i don't have a clue what goes there. if this is not what your saying then please clarify. it would also seem the i have a very limited grasp of what is really happening with the input so what ever GLUT is "doing for me" i don't understand and further more i looked though the code to find where the Key() function was called on so i could figure out what those "?" where but i found that it doesn't get called on so dose it get called on like Main(). o and also if i'm anywhere close to being right is there any specific order or rhyme to how i should populate the array
Just out of curiosity, is there any particular reason you're using GLUT rather than (say) SDL?

Just recently, you posted this thread asking about handling multiple key input in SDL. I directed you to the answer, but you never returned to the thread - did that not work for you for some reason?

I ask because it seems to me you might have better luck with SDL, since it offers the functionality that you seem to be after here. (If you're constrained to using GLUT for some reason though - e.g. because it's part of an assignment of some sort - then ignore this post :)
o crap i forgot about that thread thanks a million it worked.
but still i would like to know in GLUT as well do the 3D aspect of this little adventure plus i'm really trying to use SDL as a kind of steeping stone to OpenGL. Not that i don't like SDL it's just my interests lie in creating things my friends can't witch for the most part know means some type of 3D acceleration or Multi-Threading for more speed to do more things that namely flash cant (me and a bunch of my friends took an AS2 class and took it way beyond what was intended of it and lots of competition fulled it and now AS2 and AS3 are just way too slow for what we want. plus i would be the First to get a 3D game of some sort working if i could learn OpenGL first. so any way i still want help with GLUT.
Quote:but still i would like to know in GLUT as well do the 3D aspect of this little adventure plus i'm really trying to use SDL as a kind of steeping stone to OpenGL. Not that i don't like SDL it's just my interests lie in creating things my friends can't witch for the most part know means some type of 3D acceleration or Multi-Threading for more speed to do more things that namely flash cant (me and a bunch of my friends took an AS2 class and took it way beyond what was intended of it and lots of competition fulled it and now AS2 and AS3 are just way too slow for what we want. plus i would be the First to get a 3D game of some sort working if i could learn OpenGL first. so any way i still want help with GLUT.
It sounds like you may be misunderstanding some things about both SDL and GLUT.

You can use OpenGL with SDL in much the same way as you can with GLUT. There's also a number of other cross-platform windowing libraries available, such as SFML and GLFW, that you might look into as well.

In short, I really kind of doubt that GLUT is the best choice here; in my experience at least, it's really not very well suited for developing non-trivial applications. Any of the other libraries mentioned (SDL, SFML, GLFW) should provide all of the functionality you need, and would probably be more suitable for what you're wanting to do.
i am aware of "SDL_OpenGL.h" but i cant get it to work so i tried OpenGL. i tried GLUT just because it's what i stumbled across first. i am still having major problems with key input and would like a way to remedy it. in this program it doesn't resize the quad at all and i don't know why, i'm thinking it's keyboard stuff again.
#include <iostream>#include <stdlib.h> //Needed for "exit" function#include <windows.h>//Include OpenGL header files, so that we can use OpenGL#include <GL/gl.h>#include <GL/glut.h>float ey;float ex;using namespace std;//Called when a key is pressedvoid handleKeypress(unsigned char key, //The key that was pressed					int x, int y) {    //The current mouse coordinates	if(key=='q') {	 exit(0);	}	if(key=='w') {	  ey+=10;	}	if(key=='a') {	  ex-=10;	}	if(key=='s') {	  ey-=10;	}	if(key=='d') {	  ex+=10;	}}//Initializes 3D renderingvoid initRendering() {	//Makes 3D drawing work when something is in front of something else	glEnable(GL_DEPTH_TEST);}//Called when the window is resizedvoid handleResize(int w, int h) {	//Tell OpenGL how to convert from coordinates to pixel values	glViewport(0, 0, w, h);	glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective	//Set the camera perspective	glLoadIdentity(); //Reset the camera	gluPerspective(45.0,                  //The camera angle				   (double)w / (double)h, //The width-to-height ratio				   1.0,                   //The near z clipping coordinate				   200.0);                //The far z clipping coordinate}//Draws the 3D scenevoid drawScene() {	//Clear information from last draw	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective	glLoadIdentity(); //Reset the drawing perspective	glBegin(GL_QUADS); //Begin quadrilateral coordinates	//Trapezoid	glVertex3f(ex, ey,-5.0f);	glVertex3f(-ex, ey, -5.0f);	glVertex3f(-ex, -ey, -5.0f);	glVertex3f(ex, -ey, -5.0f);	glEnd(); //End quadrilateral coordinates	glutSwapBuffers(); //Send the 3D scene to the screen}int main(int argc, char** argv) {	ey = 1;	ex = 1;	//Initialize GLUT	glutInit(&argc, argv);	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);	glutInitWindowSize(400, 400); //Set the window size	//Create the window	glutCreateWindow("Basic Shapes - videotutorialsrock.com");	initRendering(); //Initialize rendering	//Set handler functions for drawing, keypresses, and window resizes	glutDisplayFunc(drawScene);	glutKeyboardFunc(handleKeypress);	glutReshapeFunc(handleResize);	glutMainLoop(); //Start the main loop.  glutMainLoop doesn't return.	return 0; //This line is never reached}


[Edited by - ishkabible on April 19, 2010 8:03:32 PM]
Quote:i am aware of "SDL_OpenGL.h" but i cant get it to work so i tried OpenGL.
That doesn't make any sense :/

Anyway, that's a terrible way to go about doing things, IMO. If you're new to game development or programming in general (or even if you're experienced), you will often find things not working as you expect for one reason or another. Giving up immediately and moving on to something else is the wrong thing to do when this happens. A much better alternative would be to, say, ask here on GDNet and get some help. I'm quite certain that whatever problem you were having with SDL_opengl.h, your friendly neighborhood GDNet'ers would've been able to help you solve it.
Quote:i am still having major problems with key input and would like a way to remedy it.
Can you repost your code using [ source ] tags (with no spaces)?

This topic is closed to new replies.

Advertisement