Moving 3d shapes with keyboard in OpenGL with C++

Viewed 2850

I'm trying to move the pyramid and cubic "separately" to front-back , up-down and right-left using arrows and page-up, page-down keys but I couldn't make it yet , none of the tow shape are moving my 2 questions are : how can i chose witch one of these shapes i want to move , and why none of them are moving ? Thanks.

#include <GL/glut.h>
float xmove = 0, ymove = 0, zmove = 0;
float degree = 0;
float xscale = 1, yscale = 1, zscale = 1;
void right(void)
{
    glLoadIdentity();//koordinat sistemimizetkilenmesin
    xmove += 0.1;
}
void left(void)
{
    glLoadIdentity();
    xmove -= 0.1;
}
void up(void)
{
    glLoadIdentity();
    ymove += 0.1;
}
void down(void)
{
    glLoadIdentity();
    ymove -= 0.1;
}
void front(void)
{
    glLoadIdentity();
    zmove -= 0.1;
}
void back(void)
{
    glLoadIdentity();
    zmove += 0.1;
}
void keyboard(int button, int x, int y)
{
    switch (button)
    {
    case GLUT_KEY_LEFT:left(); break;
    case GLUT_KEY_RIGHT:right(); break;
    case GLUT_KEY_UP:up(); break;
    case GLUT_KEY_DOWN:down(); break;
    case GLUT_KEY_PAGE_UP:front(); break;
    case GLUT_KEY_PAGE_DOWN:back(); break;
    glutPostRedisplay();
    }
}
void Settings()
{
    glClearColor(1,1,1,0);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glShadeModel(GL_SMOOTH);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST);
}
void polygons(void)
{
    glColor3f(1.0, 0.0, 0.0);
    glRotatef(degree, 0.0, 1.0, 0.0);
    glScalef(xscale, yscale, zscale);
    glTranslatef(1.5, 0.0, -8.0);
    glBegin(GL_TRIANGLES);//pyramid
    // fronat face
    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(1.0f, -1.0f, 1.0f);
    // down face
    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(1.0f, -1.0f, 1.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(1.0f, -1.0f, -1.0f);
    //back
    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(1.0f, -1.0f, -1.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(-1.0f, -1.0f, -1.0f);
    //left 
    glColor3f(1.0f, 0.0f, 0.0f); //reed
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glEnd();
    glLoadIdentity();
    glTranslatef(-1.5, 0.0, -8.0); 
    glBegin(GL_QUADS); //cubic
    glColor3f(1.0f, 0.0f, 1.0f); //pink
    glVertex3f(1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(1.0f, 1.0f, 1.0f);
    //down face
    glColor3f(1.0f, 0.5f, 0.0f); //orange
    glVertex3f(1.0f, -1.0f, 1.0f);
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(1.0f, -1.0f, -1.0f);
    //front face
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glVertex3f(1.0f, -1.0f, 1.0f);
    //back
    glColor3f(1.0f, 1.0f, 0.0f); //yellow
    glVertex3f(1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(1.0f, 1.0f, -1.0f);

    //left
    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, 1.0f);
    //right
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(1.0f, 1.0f, -1.0f);
    glVertex3f(1.0f, 1.0f, 1.0f);
    glVertex3f(1.0f, -1.0f, 1.0f);
    glVertex3f(1.0f, -1.0f, -1.0f);
    glEnd();
}
void DrawingFunction()//painting
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    gluLookAt(0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    polygons();
    glutSwapBuffers();
}
void AppearanceAdjustment(int x, int y)
{
    int aspect = x / y;
    glViewport(0, 0, x, y);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45,aspect,0.1,20);

}
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE); 
    glutInitWindowPosition(50, 50);
    glutInitWindowSize(800, 600);
    glutCreateWindow("3d shapes");
    glutDisplayFunc(DrawingFunction);
    glutReshapeFunc(AppearanceAdjustment);
    glutSpecialFunc(keyboard);
    Settings();
    glutMainLoop();
    return 0;
}
2 Answers

You need to use a key press to pick one of the shapes similar to how you trigger the up, down, left, right ... Etc functions. Say press a for the first shape then set a global int ishape= 1 or ishape=2 if b is pressed. The draw function will then check the value of ishape to see which shape it should move. But really you need a vector of move for each shape else their displacements will be mixed up.Then you need to apply gltranslate on the shape that needs to be displaced using the move vector.

glLoadIdentity() has to be called in DrawingFunction:

void DrawingFunction()//painting
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity(); // <----
    gluLookAt(0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    polygons();
    glutSwapBuffers();
}

Add an array of offsets and an object number:

int object = 0;
float xmove[]{ 0, 0 };
float ymove[]{ 0, 0 };
float zmove[]{ 0, 0 };

Add object selection buttons and change the offset of the selected object. glutPostRedisplay() has to be executed after the switch statement:

void keyboard(int button, int x, int y)
{
    switch (button)
    {
        case GLUT_KEY_F1: object = 0; break;
        case GLUT_KEY_F2: object = 1; break;
        case GLUT_KEY_LEFT: xmove[object] -= 0.1; break;
        case GLUT_KEY_RIGHT: xmove[object] += 0.1; break;
        case GLUT_KEY_DOWN:  ymove[object] -= 0.1; break;
        case GLUT_KEY_UP: ymove[object] += 0.1; break;
        case GLUT_KEY_PAGE_UP: zmove[object] -= 0.1; break;
        case GLUT_KEY_PAGE_DOWN: zmove[object] += 0.1; break;
    }
    glutPostRedisplay();
}

You have to translate the objects object by glTranslatef(xmove[i], ymove[i], zmove[i]). I recommend to use glPushMatrix/glPopMatrix:

void polygons(void)
{
    glPushMatrix();

    glColor3f(1.0, 0.0, 0.0);
    glRotatef(degree, 0.0, 1.0, 0.0);
    glScalef(xscale, yscale, zscale);
    glTranslatef(1.5, 0.0, -8.0);

    glTranslatef(xmove[0], ymove[0], zmove[0]); // <--- translate pyramid

    // draw pyramid
    glBegin(GL_TRIANGLES);//pyramid
    // [...]
    glEnd();

    glTranslatef(-1.5, 0.0, -8.0); 
    glTranslatef(xmove[1], ymove[1], zmove[1]); // <--- translate cube

    glBegin(GL_QUADS); //cubic
    // [...]
    glEnd();

    glPopMatrix();
} 

Example code:

int object = 0;
float xmove[]{ 0, 0 };
float ymove[]{ 0, 0 };
float zmove[]{ 0, 0 };

float degree = 0;
float xscale = 1, yscale = 1, zscale = 1;

void keyboard(int button, int x, int y)
{
    switch (button)
    {
        case GLUT_KEY_F1: object = 0; break;
        case GLUT_KEY_F2: object = 1; break;
        case GLUT_KEY_LEFT: xmove[object] -= 0.1; break;
        case GLUT_KEY_RIGHT: xmove[object] += 0.1; break;
        case GLUT_KEY_DOWN:  ymove[object] -= 0.1; break;
        case GLUT_KEY_UP: ymove[object] += 0.1; break;
        case GLUT_KEY_PAGE_UP: zmove[object] -= 0.1; break;
        case GLUT_KEY_PAGE_DOWN: zmove[object] += 0.1; break;
    }
    glutPostRedisplay();
}

void Settings()
{
    glClearColor(1,1,1,0);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    glShadeModel(GL_SMOOTH);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST);
}

void polygons(void)
{
    glPushMatrix();

    glColor3f(1.0, 0.0, 0.0);
    glRotatef(degree, 0.0, 1.0, 0.0);
    glScalef(xscale, yscale, zscale);
    glTranslatef(1.5, 0.0, -8.0);

    glTranslatef(xmove[0], ymove[0], zmove[0]); // <--- translate pyramid

    glBegin(GL_TRIANGLES);//pyramid
    // fronat face
    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(1.0f, -1.0f, 1.0f);
    // down face
    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(1.0f, -1.0f, 1.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(1.0f, -1.0f, -1.0f);
    //back
    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(1.0f, -1.0f, -1.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(-1.0f, -1.0f, -1.0f);
    //left 
    glColor3f(1.0f, 0.0f, 0.0f); //reed
    glVertex3f(0.0f, 1.0f, 0.0f);
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glEnd();

    glPopMatrix();
    glPushMatrix();


    glTranslatef(-1.5, 0.0, -8.0); 
    glTranslatef(xmove[1], ymove[1], zmove[1]); // <--- translate cube


    glBegin(GL_QUADS); //cubic
    glColor3f(1.0f, 0.0f, 1.0f); //pink
    glVertex3f(1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(1.0f, 1.0f, 1.0f);
    //down face
    glColor3f(1.0f, 0.5f, 0.0f); //orange
    glVertex3f(1.0f, -1.0f, 1.0f);
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(1.0f, -1.0f, -1.0f);
    //front face
    glColor3f(0.0f, 0.0f, 1.0f); //blue
    glVertex3f(1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, -1.0f, 1.0f);
    glVertex3f(1.0f, -1.0f, 1.0f);
    //back
    glColor3f(1.0f, 1.0f, 0.0f); //yellow
    glVertex3f(1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(1.0f, 1.0f, -1.0f);

    //left
    glColor3f(1.0f, 0.0f, 0.0f); //red
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, -1.0f);
    glVertex3f(-1.0f, -1.0f, 1.0f);
    //right
    glColor3f(0.0f, 1.0f, 0.0f); //green
    glVertex3f(1.0f, 1.0f, -1.0f);
    glVertex3f(1.0f, 1.0f, 1.0f);
    glVertex3f(1.0f, -1.0f, 1.0f);
    glVertex3f(1.0f, -1.0f, -1.0f);
    glEnd();

    glPopMatrix();
}

void DrawingFunction()//painting
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    polygons();
    glutSwapBuffers();
}

void AppearanceAdjustment(int x, int y)
{
    int aspect = x / y;
    glViewport(0, 0, x, y);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45,aspect,0.1,20);
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE); 
    glutInitWindowPosition(50, 50);
    glutInitWindowSize(800, 600);
    glutCreateWindow("3d shapes");
    glutDisplayFunc(DrawingFunction);
    glutReshapeFunc(AppearanceAdjustment);
    glutSpecialFunc(keyboard);
    Settings();
    glutMainLoop();
    return 0;
}
Related