OpenGL: Error moving object using keyboard - opengl

I'm new to OpenGL and I'm trying to paint a stickman and then move it using the arrow-keys from the keyboard.
My idea was to use global variables for the stickman and to change them when a certain key is pressed. Afterwards the draw-function (myDisplay()) is called again.
Unfortunately i always get the following error-message:
"Error 10 error C2371: 'myDisplay' : redefinition; different basic types "
When I replace the myDisplay()-call in the keyboard-function with glutPostRedisplay() as suggested in some tutorials I read the error message disapears and the build is successful. But the stickman doesn't move when pressing the keys.
Here's my code:
#include <GL/glut.h>
GLint x; GLint y; GLint d; //parameters for the stickman
void myKeyboard(unsigned char key, int mx, int my) {
int x1 = mx;
int y1 = 480 - my;
switch(key){
case GLUT_KEY_LEFT :
x = x-50;
myDisplay();
break;
case 'E' :
exit(-1);
break;
default:
break;
}
}
void stickman () {
glBegin(GL_LINES); //body
glVertex2i(x, y);
glVertex2i(x, y-2*d);
glVertex2i(x-d, y-d);
glVertex2i(x+d, y-d);
glVertex2i(x, y-2*d);
glVertex2i(x-d, y-3*d);
glVertex2i(x, y-2*d);
glVertex2i(x+d, y-3*d);
glEnd();
glBegin(GL_LINE_LOOP); //head
glVertex2i(x,y);
glVertex2i(x+0.5*d, y);
glVertex2i(x+0.5*d, y+0.5*d);
glVertex2i(x-0.5*d, y+0.5*d);
glVertex2i(x-0.5*d, y);
glEnd();
}
void myDisplay() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
stickman();
glFlush();
}
void myInit() {
glClearColor(1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, 640.0, 0.0, 480.0);
}
void main(int argc, char** argv) {
x = 320;
y = 350;
d = 100;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(640, 480);
glutInitWindowPosition(200, 50);
glutCreateWindow("Stickman");
glutDisplayFunc(myDisplay);
glutKeyboardFunc(myKeyboard);
glutPostRedisplay();
myInit();
glutMainLoop();
}

As I found out (GLUT Keyboard Tutorial) the problem wasn't the repaint of the picture, but rather that the left arrow key wasn't recognized.
I needed to write another keyboard-function for my special keys such as the arrow keys.
Now my code looks like this and it works:
void processNormalKeys (unsigned char key, int mx, int my) {
if (key == 'E')
exit(-1);
}
void processSpecialKeys (int key, int mx, int my) {
switch(key){
case GLUT_KEY_LEFT :
x = x-5;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT :
x = x+5;
glutPostRedisplay();
break;
case GLUT_KEY_UP :
y = y+5;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN :
y = y-5;
glutPostRedisplay();
break;
default:
break;
}
}
I also had to adjust the main function:
glutKeyboardFunc(processNormalKeys);
glutSpecialFunc(processSpecialKeys);
But thanks for your help anyways!

glutPostRedisplay() is used to tell mark that the current window needs to be redisplayed as said in the documentation. That means that you need to call this function at the end of your myKeyboard function.
I will also recommend you to use double or tripple buffer to avoid undesired results. For double buffer you need to change glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB ); with glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB ); and then at the end of your display function you need to add glutSwapBuffers();. You can find more info here http://www.swiftless.com/tutorials/opengl/smooth_rotation.html.

Related

drawing program with glut/openGL not working

This program is able to create a window and locate my mouse when it is on the window, however the display function does seem to work. What am I missing here?
float pointSize = 10.0f;
bool leftBottState;
float xvalue;
float yvalue;
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
}
void dots()
{
glBegin(GL_POINTS);
glVertex3f(xvalue, yvalue, 0.0);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 1);
dots();
glEnd();
glFlush();
}
void mouse(int button, int state, int x, int y)
{
y = 600 - y;
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
leftBottState = true;
}
else
{
leftBottState = false;
}
}
void motion(int x, int y)
{
if (leftBottState)
{
std::cout << "LEFt bUTTON " << std::endl;
xvalue = x;
yvalue = y;
glutPostRedisplay();
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(600, 600);
glutCreateWindow("test");
glutMotionFunc(motion);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMainLoop();
return(0);
}
You're using a double buffered window (see glutInitDisplayMode).
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
Therefore you must call glutSwapBuffers to swaps the buffers after rendering the scene:
void dots()
{
glBegin(GL_POINTS);
glVertex3f(xvalue, yvalue, 0.0);
glEnd();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1, 0, 1);
dots();
// glFlush();
glutSwapBuffers();
}
Note, a glBegin \ glEnd sequence delimits the vertices of a primitive. I recommend to call this instructions in the same function, immediately before and after specifying the vertices.
glClear clears the buffers and thus the entire scene. If you want to draw the points permanently, you have to remove the glClear instruction from the display function.
glClear(GL_COLOR_BUFFER_BIT);

How to get smooth input for game in glut C++?

how do I get my C++ glut project to have smooth input?
the only way I could get input was with a slight delay, which is annoying. I am new to C++ glut so pls help me.
#include <windows.h>
#include <GL/glut.h>
#include <GL/glu.h>
#include <stdio.h>
#include <iostream>
GLboolean upPressed = false;
using namespace std;
void display();
void reshape(int,int);
void timer(int);
void keyboard_callback(int, int, int);
void SpecialKeysUp(int, int, int);
void update();
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
}
int main(int argc, char**argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowPosition(200, 100);
glutInitWindowSize(500, 500);
glutCreateWindow("window");
glutSpecialFunc(keyboard_callback);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutTimerFunc(0,timer,0);
glutSpecialUpFunc(SpecialKeysUp);
glutIdleFunc(update);
init();
glutMainLoop();
}
// sy is the first squares y position. no x value needed since the x value is static.
// also note that the "s" in sy stands for square, squarey_position
float x_position = 0.0;
float sy_position = -4.0;
int state = 1;
char input;
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glBegin(GL_QUADS);
glColor3f(1.0,0.0,0.0);
glVertex2f(x_position,1.0);
glVertex2f(x_position,-1.0);
glVertex2f(x_position+2.0,-1.0);
glVertex2f(x_position+2.0,1.0);
glColor3f(1.0,0.0,0.0);
glVertex2f(-8.0,sy_position);
glVertex2f(-9.0,sy_position);
glVertex2f(-9.0,sy_position+8.0);
glVertex2f(-8.0,sy_position+8.0);
glEnd();
glutSwapBuffers();
}
void reshape(int w,int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-10, 10, -10, 10);
glMatrixMode(GL_MODELVIEW);
}
void timer(int)
{
glutPostRedisplay();
glutTimerFunc(1000/60,timer,0);
switch(state)
{
case 1:
if(x_position<8)
x_position+=0.15;
else
state = -1;
break;
case -1:
if(x_position>-10)
x_position-=0.15;
else
state=1;
break;
}
}
void keyboard_callback(int key, int, int)
{
if(GLUT_KEY_UP == key)
upPressed = true;
}
void SpecialKeysUp(int key, int, int)
{
if(GLUT_KEY_UP == key)
upPressed = false;
}
void update()
{
// glutPostRedisplay();
// glutTimerFunc(1000/60,update,0);
if(upPressed)
sy_position+=0.15;
}
It is a ping pong game and currently the ball is working fine, however I am trying to get smooth input for the rectangle but the only way I could was with input delay.
I am new to glut C++ so pls help me
Actually I figured out how to do it. The glutTimerFunc updates and resets every 1000/60 milliseconds so valuing a bool at "true" whilst the up key is pressed(with GLUT_KEY_UP) and then valuing a bool at "false" when the key is not pressed(with the SpecialUpFunc) makes for smoother input since the update function resets must faster than just holding the key down.

Open GL setting an orthographic projection

i am trying to draw and a simple cube and move it along the screen on Left Arrow key and Right key down (left direction and right direction respectively). I donot have exact idea of gluOrtho2d(leftortho,rightortho,bottomortho,toportho). i have tried glOrtho(leftortho,rightortho,bottomortho,toportho,-1.0,1.0) with six parameters but the result is same. The cube moves to upper right corner and vanishes.. I need help in this regard..
double leftortho=5.0,rightortho=1.0,bottomortho=5.0,toportho=1.0;
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glutWireCube (1.0);
gluOrtho2D(leftortho,rightortho,bottomortho,toportho);
glFlush ();
}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
}
float move_unit = 0.001;
void keyboardown(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_RIGHT:
{
leftortho+=move_unit;
rightortho+=move_unit;
//bottomortho+=move_unit;
//toportho+=move_unit;
break;
}
case GLUT_KEY_LEFT:
{
leftortho-=move_unit;
rightortho-=move_unit;
//bottomortho-=move_unit;
//toportho-=move_unit;
break;
}
case GLUT_KEY_UP:
//posY+=move_unit;;
break;
case GLUT_KEY_DOWN:
// posY-=move_unit;;
break;
default:
break;
}
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutSpecialFunc(keyboardown);
glutMainLoop();
return 0;
}
Give this a shot:
#include <GL/glut.h>
double leftortho=-1.0;
double rightortho=1.0;
double bottomortho=-1.0;
double toportho=1.0;
float move_unit = 0.01;
void keyboardown(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_RIGHT:
leftortho-=move_unit;
rightortho-=move_unit;
break;
case GLUT_KEY_LEFT:
leftortho+=move_unit;
rightortho+=move_unit;
break;
case GLUT_KEY_UP:
toportho-=move_unit;
bottomortho-=move_unit;
break;
case GLUT_KEY_DOWN:
toportho+=move_unit;
bottomortho+=move_unit;
break;
default:
break;
}
glutPostRedisplay();
}
void display(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glClear (GL_COLOR_BUFFER_BIT);
glShadeModel (GL_FLAT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(leftortho,rightortho,bottomortho,toportho, -10, 10);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3f (1.0, 1.0, 1.0);
glutWireCube (1.0);
glutSwapBuffers();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
glutDisplayFunc(display);
glutSpecialFunc(keyboardown);
glutMainLoop();
return 0;
}
I think the problem is that you are not resetting the projection matrix before calling gluOrtho2d(), so your moves are accumulating. I think you need to do this:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2d(left,right,bottom,top);
Note also that your left and right appear to be swapped, as do your bottom and top. This is legal, but it may end up causing the left and right arrow keys to seem reversed. It basically sets your transformation to be backwards and upside down.

glulookat() - move camera with keyboard( OpenGL)

I am trying to move the camera with the use of the keyboard. I am calling the glulookat function in the draw method as follows:
gluLookAt(posx,posy,posz,lookx,looky,lookz,upx,upy,upz);
Also I have, for example, for moving the position of the camera on the X axis the following code:
void keyboard(unsigned char key, int x, int y) {
switch(key) {
case 'w' :
break;
case 'a' :
posx-=1.0;
break;
case 's' :
break;
case 'd' :
posx+=1.0;
break;
}
}
The posx,posy,posz,lookx,looky,lookz,upx,upy,upz variables are declared as global double variables. I have tried to initialize them in two ways: when declaring them, as well as in the init() method, but with no success. The camera isn't moving, although the program receives the keyboard input properly, as I have tested this aspect separately. Any ideas of what I am doing wrong?
EDIT: I provided the main code for a better understanding:
Outer_space* space;
Light* sceneLight;
Light* sceneLight2;
Light* sceneLight3;
Satelite* satelite1;
double posx=35.0,posy=35.0,posz=35.0,lookx=0,looky=1,lookz=0,upx=0,upy=0,upz=-1;
void init(void) {
//random number generator
srand(time(NULL));
space = new Outer_space(12, 12,12, new Vector3D(0.5f, 0.7f, 0.9f));
sceneLight = new Light(0, 0);
sceneLight->setTranslation(new Vector3D(0, 20, 0));
sceneLight->setConstantAttenuation(0.09f);
sceneLight->setLinearAttenuation(0.08f);
sceneLight2 = new Light(1, 0);
sceneLight2->setTranslation(new Vector3D(20, 0, 0));
sceneLight2->setConstantAttenuation(0.09f);
sceneLight2->setLinearAttenuation(0.08f);
sceneLight3 = new Light(2, 0);
sceneLight3->setTranslation(new Vector3D(0, 0, 20));
sceneLight3->setConstantAttenuation(0.09f);
sceneLight3->setLinearAttenuation(0.08f);
satelite1 = new Satelite(2,new Vector3D(0.2f,0.3f,0.5f));
satelite1->setTranslation(new Vector3D(10,10,10));
satelite1->setRotation(new Vector3D(-90, 0, 0));
satelite1->setScale(new Vector3D(10, 10, 10));
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
}
void draw(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0,20,0, 0, 0, 0, 0, 1, 0);
gluLookAt(posx,posy,posz,lookx,looky,lookz,upx,upy,upz);
space->draw();
sceneLight->draw();
sceneLight2->draw();
sceneLight3->draw();
satelite1->draw();
glPushMatrix();
glRasterPos3f(-8.5, 4, -6);
glutSwapBuffers();
}
void update(void){
glutPostRedisplay();
}
void resize(int w, int h) {
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
GLfloat aspect = (GLfloat)w / (GLfloat)h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 1.0, 60);
}
void keyboard(unsigned char key, int x, int y) {
switch (key)
{
case 'w' :
break;
case 'a' :
posx-=1.0;
break;
case 's' :
break;
case 'd' :
posx+=1.0;
break;
}
}
void specialKeyboard(int key, int x, int y) {
switch (key)
{
case GLUT_KEY_RIGHT:
posx+=1;
break;
case GLUT_KEY_LEFT:
posx-=1;
break;
case GLUT_KEY_UP:
break;
case GLUT_KEY_DOWN:
break;
}
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(800, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("Asteroid Escape");
init();
glutIdleFunc(update);
glutDisplayFunc(draw);
glutReshapeFunc(resize);
glutKeyboardFunc(keyboard);
glutSpecialFunc(specialKeyboard);
glutMainLoop();
return 0;
}
EDIT2:
I have commented out the glPushMatrix(); call from the draw() method and now the camera seems to be moving. What is the explanation?
glPushMatrix is supposed to be followed by glPopMatrix.
It seems that you overflow the matrix stack, did you check glGetError result ?
Besides, jour call to glPushMatrix seems pretty useless like this, what do you expect it to do ?

How to move triangle on plane in opengl

I want to move triangle on plane.How will i do it.I am using opengl "glut" and also i want to keep co-ordinate position of triangle.first time it will start at point (0,0,-6) and then when i will press "a" this will move left and when i will press "d" this will move "right".I know the keyoperation definition in opengl of "w" and "s".But my main concern is with movment and knwoing of co-ordinate points.
Thankie
Use global variables to store your programs state. One of these states is the triangle position. Modify this variable in the keyboard handler, then call glutPostRedisplay. In the display function draw the scene according to the program's state.
Important hints: OpenGL is "merely" a sophisticated rasterizer API, which means it "lives for the moment", i.e. you just draw triangles with it, and after you sent the rendering command and they've been processed OpenGL has no "persistency" about the sent geometry and the only trace left are the changes in the framebuffer.
If what you're looking for is more along the lines of "I want to describe a scene consisting of geometric objects and those shall interact through some black box mechanism" you're looking for a so called scene graph, which OpenGL is not (but many scene graphs use OpenGL as a backend).
EDIT: Full example source code
#include <GL/gl.h>
#include <GL/glut.h>
#define ORTHO_SCALE 10.
GLfloat triangle_vertices[] = {
-0.5, 0.0,
0.5, 0.0,
0.0, 1.0
};
struct {
struct {
struct {
GLfloat x, y;
} pos;
GLfloat rot;
} triangle;
} sceneinfo;
void display(void);
void keyboard(unsigned char key, int x, int y);
void special(int key, int x, int y);
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("simple triangle test");
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
glutMainLoop();
return 0;
}
void display(void)
{
GLuint win_width, win_height;
GLfloat win_aspect;
win_width = glutGet(GLUT_WINDOW_WIDTH);
win_height = glutGet(GLUT_WINDOW_HEIGHT);
win_aspect = (float)win_width/(float)win_height;
glViewport(0, 0, win_width, win_height);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-win_aspect * ORTHO_SCALE,
win_aspect * ORTHO_SCALE,
-ORTHO_SCALE,
ORTHO_SCALE,
-1., 1.);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef(sceneinfo.triangle.pos.x, sceneinfo.triangle.pos.y, 0.);
glRotatef(sceneinfo.triangle.rot, 0, 0, 1.);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, triangle_vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glPopMatrix();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
switch(key) {
case '+':
sceneinfo.triangle.rot += 2.;
break;
case '-':
sceneinfo.triangle.rot -= 2.;
break;
}
glutPostRedisplay();
}
void special(int key, int x, int y)
{
switch(key) {
case GLUT_KEY_LEFT:
sceneinfo.triangle.pos.x -= 0.2;
break;
case GLUT_KEY_RIGHT:
sceneinfo.triangle.pos.x += 0.2;
break;
case GLUT_KEY_UP:
sceneinfo.triangle.pos.y += 0.2;
break;
case GLUT_KEY_DOWN:
sceneinfo.triangle.pos.y -= 0.2;
break;
}
glutPostRedisplay();
}