Skip to main content
GameDev.net gamedev.net
🔒 Locked

OpenGL Multiple Keypresses

Started by CobyWalkerGames Aug 13, 2008 at 12:02 PM 10 replies 7k views
Original Post
CobyWalkerGames
CobyWalkerGames
Original Question: Multiple keys? I cant move/turn at the same time. /////Updated after the 9th Post///// My First Program My own camera movement. Windows XP, Vc++ Express (OpenGL + Glut) I know (Ti-83+)Asm,Ti-Basic,GML, Partial Dark Basic,Dark GDK,(Nintendo DS) c++. //INCLUDES// #include #include #include #include #include #include #include "imageloader.h" //VARIABLES// float camx=0,camy=0,camz=4; float lookx=0,looky=0,lookz=0; float dir=270; int speed=0; float pi=3.14159265; bool keys[256]; //Makes the image into a texture, and returns the id of the texture GLuint loadTexture(Image* image) { GLuint textureId; glGenTextures(1, &textureId); //Make room for our texture glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit //Map the image to the texture glTexImage2D(GL_TEXTURE_2D, //Always GL_TEXTURE_2D 0, //0 for now GL_RGB, //Format OpenGL uses for image image->width, image->height, //Width and height 0, //The border of the image GL_RGB, //GL_RGB, because pixels are stored in RGB format GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored //as unsigned numbers image->pixels); //The actual pixel data return textureId; //Returns the id of the texture } GLuint tex_stonewall; //The id of the texture GLuint tex_grass; //The id of the texture void init (void) { glEnable (GL_DEPTH_TEST); //enable the depth testing glEnable (GL_LIGHTING); //enable the lighting //glEnable (GL_LIGHT0); //enable LIGHT0, our Diffuse Light glShadeModel (GL_SMOOTH); //set the shader to smooth shader glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); } void loadtextures(){ Image* image = loadBMP("Stone Wall.bmp"); tex_stonewall = loadTexture(image); //delete image; image = loadBMP("Grass.bmp"); tex_grass = loadTexture(image); delete image; } void drawground(){ glColor3f(1,1,1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex_grass); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glPushMatrix(); glBegin(GL_QUADS); for (int x = -252; x < 260; x += 8){ for (int y = -252; y < 260; y += 8){ glNormal3f(0.0, 0.0f, 1.0f);//Front glTexCoord2f(0.0f, 0.0f);glVertex3f(x,y+8,0); glTexCoord2f(0.0f, 1.0f);glVertex3f(x,y,0); glTexCoord2f(1.0f, 1.0f);glVertex3f(x+8,y,0); glTexCoord2f(1.0f, 0.0f);glVertex3f(x+8,y+8,0); }} glEnd(); glPopMatrix(); glDisable(GL_TEXTURE_2D); /* glBegin(GL_LINES); for (int x = -252; x < 260; x += 8) { glVertex3i(x,-256,0); glVertex3i(x,256,0); } for (int y = -252; y < 260; y += 8) { glVertex3i(-256, y,0); glVertex3i(256, y,0); }*/ } void cube(float x,float y,float z,float xsize,float ysize,float zsize){ glColor3f(1,1,1); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex_stonewall); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glPushMatrix(); glBegin(GL_QUADS); glNormal3f(0.0, 1.0f, 0.0f);//Front glTexCoord2f(0.0f, 0.0f);glVertex3f(x-xsize,y+ysize,z-zsize); glTexCoord2f(0.0f, 1.0f);glVertex3f(x-xsize,y+ysize,z+zsize); glTexCoord2f(1.0f, 1.0f);glVertex3f(x+xsize,y+ysize,z+zsize); glTexCoord2f(1.0f, 0.0f);glVertex3f(x+xsize,y+ysize,z-zsize); glNormal3f(1.0, 0.0f, 0.0f);//Right glTexCoord2f(0.0f, 0.0f);glVertex3f(x+xsize,y-ysize,z-zsize); glTexCoord2f(0.0f, 1.0f);glVertex3f(x+xsize,y-ysize,z+zsize); glTexCoord2f(1.0f, 1.0f);glVertex3f(x+xsize,y+ysize,z+zsize); glTexCoord2f(1.0f, 0.0f);glVertex3f(x+xsize,y+ysize,z-zsize); glNormal3f(0.0, -1.0f, 0.0f);//Back glTexCoord2f(0.0f, 0.0f);glVertex3f(x-xsize,y-ysize,z-zsize); glTexCoord2f(0.0f, 1.0f);glVertex3f(x-xsize,y-ysize,z+zsize); glTexCoord2f(1.0f, 1.0f);glVertex3f(x+xsize,y-ysize,z+zsize); glTexCoord2f(1.0f, 0.0f);glVertex3f(x+xsize,y-ysize,z-zsize); glNormal3f(-1.0, 0.0f, 0.0f);//Left glTexCoord2f(0.0f, 0.0f);glVertex3f(x-xsize,y+ysize,z-zsize); glTexCoord2f(0.0f, 1.0f);glVertex3f(x-xsize,y+ysize,z+zsize); glTexCoord2f(1.0f, 1.0f);glVertex3f(x-xsize,y-ysize,z+zsize); glTexCoord2f(1.0f, 0.0f);glVertex3f(x-xsize,y-ysize,z-zsize); glEnd(); glTranslatef(x,y,z); glPopMatrix(); glDisable(GL_TEXTURE_2D); } void camera(){ lookx=camx+cos(dir*pi/180); looky=camy-sin(dir*pi/180); lookz=camz; gluLookAt(camx,camy,camz,lookx,looky,lookz,0,0,1); } void reshape (int w, int h) { glViewport (0, 0, (GLsizei)w, (GLsizei)h); //set the viewport to the current window specifications glMatrixMode (GL_PROJECTION); //set the matrix to projection glLoadIdentity (); gluPerspective (60, (GLfloat)w / (GLfloat)h, 1.0, 1000.0); //set the perspective (angle of sight, width, height, , depth) glMatrixMode (GL_MODELVIEW); //set the matrix back to model } void keyboardchecks() { //Move Up if (keys['w']){ camx=(camx+cos(dir*pi/180)); camy=(camy-sin(dir*pi/180));} //Move Down if (keys['s']){ camx=(camx-cos(dir*pi/180)); camy=(camy+sin(dir*pi/180));} //Left if (keys['a']){dir-=5;} //Right if (keys['d']){dir+=5;} //Escape if (keys[27]){exit(0);} //No Up/Down if (keys['w']){if (keys['s']){speed=0;}} } void display (void) { glClearColor (0.0,0.0,0.0,1.0); //clear the screen to black glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //clear the color buffer and the depth buffer glLoadIdentity(); GLfloat ambientLight[] = {0.75,0.75,0.75, 1.0f}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); keyboardchecks(); camera(); drawground(); for (int x=0;x<32;x+=8){cube(x,0,4,4,4,4);} glutSwapBuffers(); //swap the buffers } void keyboard(unsigned char key, int x, int y){ keys[(int)key] = true; } void keyboardUp(unsigned char key, int x, int y){ keys[(int)key] = false; } void keyboardSpecial(int key, int x, int y){ keys[key] = true; } void keyboardUpSpecial(int key, int x, int y){ keys[key] = false; } int main (int argc, char **argv) { glutInit (&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB| GLUT_DEPTH); glutInitWindowSize (1024,768); glutInitWindowPosition (0,0); glutCreateWindow ("Coby Walker"); init(); loadtextures(); glutDisplayFunc (display); glutIdleFunc (display); glutReshapeFunc (reshape); glutKeyboardFunc(keyboard); glutKeyboardUpFunc(keyboardUp); glutSpecialFunc(keyboardSpecial); glutSpecialUpFunc(keyboardUpSpecial); glutMainLoop (); return 0; } [Edited by - Sneftel on August 18, 2008 8:44:46 AM]
davek20
davek20
Hi.

You need to set up a bool array for the keys, say bool keyPressed[256]. Then in your keyboard function, just set the correct value in the array to true (true meaning it was pressed) then in a key up functions, set it to false. Then in your display/update function, you do all your checks for the key presses, so:

if(keyPressed['w']){
move forward
}

and so on.
CobyWalkerGames
CobyWalkerGames
I get what your saying
but also don't,

Could you edit my code or
give me a piece of example code?

Thanks for the reply.

[Edited by - CobyWalkerGames on August 13, 2008 8:45:06 PM]
empirical2
empirical2
You need to have an array of of bools that represent the current key state (false=up, true=down)

I dont know how those functions work as I repond to window events.

Typically it would be like this.

bool KeyDown[256];void OnKeyDown(unsigned char Key){KeyDown[Key]=true;return;}void OnKeyUp(unsigned char Key){KeyDown[Key]=0;return;}void OnInitalise(){memset(Key,0,sizeof(Key));return;}void OnEachFrame() //Do this each frame{if (KeyDown[VK_UP]) MoveForwards();if (KeyDown[VK_LEFT]) TurnLeft();if (KeyDown[VK_RIGHT]) TurnRight();//Draw stuff//Swap the buffers}


This allows the player to hold down the buttons too. If you want it to be single presses only set the KeyDown eliment to 0 when responding to it in OnEachFrame
Rasmadrak
Rasmadrak
You also need to point the appropriate GLUT-callbacks for keydown and keyup as well.

/Robert
"Game Maker For Life, probably never professional thou." =)
CobyWalkerGames
CobyWalkerGames
I am so sorry I tried to use this in my
code and still cant get it to compile right.

Can someone modify my code and help me out thanks.
davek20
davek20
Here is what you need to do:

bool keys[256];   //put this in at the top of the program//here are the key up and key down functionsvoid keyboard(unsigned char key, int x, int y){	keys[(int)key] = true;}void keyboardUp(unsigned char key, int x, int y){	keys[(int)key] = false;}void keyboardSpecial(int key, int x, int y){	keys[key] = true;}void keyboardUpSpecial(int key, int x, int y){	keys[key] = false;}//then when you setup GLUT, put these along with the othersglutKeyboardFunc(keyboard);glutKeyboardUpFunc(keyboardUp);glutSpecialFunc(keyboardSpecial);glutSpecialUpFunc(keyboardUpSpecial);//Then in your display function, do all your keypress checks


We are not going to edit your code for you. If you are having compile errors, please describe them and paste the errors, and we will help you.
empirical2
empirical2
There is an issue in your Keyboard checks.

if (Key['x']=1)

= is assignment so all your keys are being set to true.

When you meant is ==

However when your testing for something being non-zero (as in this case) you can just do

if (key['x']) DoStuff();
CobyWalkerGames
CobyWalkerGames
WOW!

It works this is a lot better.

I have been trying to figure this out for weeks now.
I actually had thoughts of abandoning OpenGL.

I will update my code for others.

Thanks all that posted this was a humongous help.

DantarionX
DantarionX
This had NOTHING to do with OpenGL specificly, this had to do with GLUT.
OpenGL is a Graphics API, it doesn't have anything to do with input.

I am glad your problem is fixed, but I hope you realize that abandoning OpenGL over input trouble doesn't make sense.
~Dantar
CTPAX
CTPAX
Stop using glut... Go to NeHe's site and find out how to make a window and make your games without glut... You'll soon find out that you'll havemore freedom and it's my personal opinion that it's a little bit faster... After you write that kind of program, go to LRESULT CALLBACK WndProc(...) and to case WM_KEYDOWN: where you can monitor every keypass... That was my solution in some game... But it's a C++ thing anyway...

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.