How do I move individual 3D objects in OpenGL?

Please help with my C++ OpenGL code!
I am trying to make a simple game in OpenGL with C++ (my first). The issue I'm having is that the WSAD keys move the sphere AND the cube. Since the goal of the game is going to be to get points by placing the sphere over the cube, how would I make the sphere move all by itself? glTranslatef() is moving both at the same time, and I don't know how to tell it to move only one. Although that is my main/largest problem, I was also wondering two more things. How do I overlay text, so I could show the user the elapsed time and their score? Also, how do I make the sphere move smoothly, as opposed to going one pixel, stopping, then going again when you hold down a key? Right now I'm using SPI_SETKEYBOARDDELAY, but it's not working well at all. Thanks for all the help!
P.S.: If you provide an explanation, could you please explain it? Also, could someone explain glutPostRedisplay, glutIdleFunc, glutMainLoop, glPushMatrix, glPopMatrix, and glutSwapBuffers? Thanks everyone!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98



#include <glut.h>
#include <cmath>
#include <time.h>
#include <string>
using namespace std;
 
int genrandom();
GLfloat tplayer;
GLfloat tobject;

double angle = 0;
double angleadd = 0.2;
int c = 0;
int d = 0;
int random;

void display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glClear(GL_DEPTH_BUFFER_BIT);
    glPushMatrix(); 
    glRotatef(angle, 0, 0.5, 1);
	glColor3f (0, 0.2, 1);
    glutWireSphere(5, 10, 10);
    glPopMatrix();
	glPushMatrix();
	glTranslatef(10, 10, 0);
    glRotatef(angle, 0, 0.5, 1);
	glColor3f (1, 0, 0);
    glutWireCube(3);
    glPopMatrix();
    glutSwapBuffers();
}

int genrandom(){
srand ( time(NULL) );
random = rand() % 95 + -95;
return random;
}
 
void KeySet() { DWORD old = 0;
SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &old, 0);
SystemParametersInfo(SPI_SETKEYBOARDDELAY,0, &old, 0);
}

void keyboard(unsigned char key, int x, int y)
{
	KeySet();
    if(key == 27) exit (0);
	else if( (key == 119) && (95 > d) ){
	glTranslatef(0, 1, 0);
	d = d + 1;
	}
	else if( (key == 115) && (d > -95) ){
	glTranslatef(0, -1, 0);
	d = d - 1;
	}
	else if( (key == 97) && (c > -95) ){
	glTranslatef(-1, 0, 0);
	c = c - 1;
	}
	else if( (key == 100) && (95 > c) ){
	glTranslatef(1, 0, 0);
	c = c + 1;
	}
}

void idle()
{
    angle += angleadd;
    glutPostRedisplay();
}
 
int main (int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize (800, 800);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("Space Journey");
    glClearColor (0, 0, 0, 0);
    glColor3f (1, 1, 1);
    glEnable (GL_DEPTH_TEST);
    glMatrixMode (GL_MODELVIEW);
    glOrtho(-100, 100, -100, 100, -100, 100);
    glutDisplayFunc (display);
	glutKeyboardFunc (keyboard);
	glutIdleFunc (idle);
	glutFullScreen ();
    glutMainLoop ();
    return 0;
}


glTranslatef and similar functions are used to set object's position just before you draw it. Unless you surround transformations with glPushMatrix and glPopMatrix, you'll transform your whole world. You have to save the coordinates somewhere.

Since this is c++, why don't you write a class:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Sphere{
public:
    float x, y, angle;

    void draw(){
        glPushMatrix();
        glRotatef(angle, 0, 0.5, 1);
        glTranslatef(x, y, 0);
        glColor3f (0, 0.2, 1);
        glutWireSphere(5, 10, 10);
        glPopMatrix();
    }
}
Call draw() in your display function, and when you need to change coordinates, simply change x and y.

I've never used glut, so I can't help you with some of your questions, but I bet glut has something for text. Also, I don't know how does glut handle keys, but to move your sphere smoothly you have to have a boolean that tells you if a key is down at the moment and add a small amount to x or y (like 0.01, note that I made x and y floats).

glutPostRedisplay: this seems to call your display function
glutIdleFunc: this seems to set the function that is supposed to be called when no events occur (60 times every second)
glutMainLoop: this handles all the events and calls appropriate functions (the ones that you assign with glutIdleFunc, glutDisplayFunc and so on)
glPushMatrix and glPopMatrix: when you call glPushMatrix currently active matrix is saved into a special stack (you could think of these as an std::vector::push_back() and std::vector::pop_back())
glutSwapBuffers: in modern graphics two buffers are used. The front buffer is the one you see, and the back buffer is the one OpenGL renders everything on. glutSwapBuffers swaps the two so the you can see what you rendered. This is to prevent screen tearing.
Chaos3737 wrote:
The issue I'm having is that the WSAD keys move the sphere AND the cube. Since the goal of the game is going to be to get points by placing the sphere over the cube, how would I make the sphere move all by itself? glTranslatef() is moving both at the same time, and I don't know how to tell it to move only one.

Don't use glTranslatef in your keyboard function. Instead, declare three global variables (x,y,z) that represent the sphere's coordinates in space, and modify these in the keyboard function. Then, in display, draw the sphere, translate according to these x,y,z variables, then draw the cube, then do any extra translation you want.

For your other questions my answer is simple -> google is your friend :D

EDIT: Apparently, hamsterman is your friend too! :D
Last edited on
Topic archived. No new replies allowed.