Search code examples
c++openglfreeglut

change 2D object to 3D object OpenGl


I have a code to find the cell mouse clicked in chess board then a 2D Triangle shape go to the cell position, Now I want to change 2D Triangle to 3D cube but I don't know how to do that.

This my code

#include <string>
#include <stdlib.h>
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <iostream>
using namespace std;

void init()
{
    glClearColor (1.0, 0.0, 1.0, 0.0);
    glShadeModel (GL_FLAT);
}
const int scl = 80 ;
const int STEP_SIZE = 80;
const int WIN_WIDTH = 800;
const int WIN_HEIGHT = 800;
int LeftRight = 0 ;
int UpDown = 0;

void moveRight()
{
    LeftRight+=STEP_SIZE;
}
void moveLeft()
{
    LeftRight-=STEP_SIZE;
}
void moveUp()
{
    UpDown+=STEP_SIZE;
}
void moveDown()
{
    UpDown-=STEP_SIZE;
}
void DrawBoard()
{
    int x , y , color = 0;
    glClear (GL_COLOR_BUFFER_BIT);
    for(x=1; x<=8; x++)
    {
        if(color==0)
            glColor3f (1.0, 0.0, 0.0), color++;

        else
            glColor3f (1.0, 1.0, 1.0),color=0;

        for(y=1; y<=8; y++)
        {
            if(color==0)
                glColor3f (0.0, 0.0, 0.0),color++;
            else
                glColor3f (1.0, 1.0, 1.0),color=0;

            glBegin(GL_QUADS);
            glVertex2f(scl+scl*x, scl+scl*y);
            glVertex2f(scl*x, scl+scl*y);
            glVertex2f(scl*x, scl*y);
            glVertex2f(scl+scl*x, scl*y);
            glEnd();
        }
    }
  // This is the Triangle that will change to cube 
    glBegin(GL_QUADS);
    glColor3f (1.0, 0.5, 0.0);
    glVertex2f(90+LeftRight,100+UpDown);
    glVertex2f(90+LeftRight,100+UpDown);
    glVertex2f(120+LeftRight,140+UpDown);
    glVertex2f(150+LeftRight,100+UpDown);
    glEnd();
//--------------------------------------
    glFlush ();


}
int mouse_x = -1  ;
int mouse_y = -1 ;
int object_x = -1  ;
int object_y = -1 ;

void moveObjectToFrom()
{
    if (mouse_x > 8 || mouse_x < 1 || mouse_y > 8 || mouse_y < 1 )
        return ;
    if(object_x > mouse_x )
    {
        object_x-- ;
        moveUp();
    }
    if(object_x < mouse_x )
    {
        object_x++;
        moveDown();

    }
    if(object_y > mouse_y )
    {
        object_y-- ;
        moveLeft();

    }
    if(object_y < mouse_y)
    {
        object_y++ ;
        moveRight();
    }

}

void mouseClicks( int button , int key, int x, int y )
{
    // this variables related to chessboard
    mouse_x =  y / scl ;
    mouse_y = 9 - (WIN_HEIGHT - x)/scl ;
    object_x = 9 - (100 + UpDown)/ scl  ;
    object_y = 9 - (WIN_HEIGHT - (LeftRight+90))/scl ;

    if (button !=0 || mouse_x > 8 || mouse_x < 1 || mouse_y > 8 || mouse_y < 1 )
        return ;

    glutPostRedisplay();
}


void reshape (int w, int h)
{
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h);
}

void update(int value)
{

    moveObjectToFrom();
    glutTimerFunc(50, update, 0);
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    //  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
    glEnable(GL_DEPTH_TEST);
    glutInitWindowSize (WIN_WIDTH, WIN_HEIGHT);
    glutInitWindowPosition (100,100);
    glutCreateWindow (argv[0]);
    glutTimerFunc(25, update, 0);
    glutMouseFunc(mouseClicks);
    init ();
    glutDisplayFunc(DrawBoard);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;
}

Solution

  • Your main problem is that your GL_PROJECTION is set to gluOrtho2D so when you render axis align cube it will always produce just square. To remedy this you should use gluProjection instead. But that will give you view centered around 0.0,0.0 instead of your current screen center coordinate (0.5*w,0.5*h) so you need also translate the GL_MODELVIEW by it.

    Here example how to do this:

    Now to render a cube you can do this:

    void render_cube()
        {
        const GLfloat a=20.0;   // cube half size
        const GLfloat pos[]=    // glVertex cube centered at (0,0,0) of size 2*a
            {
        //   x  y  z
            -a,+a,-a,
            +a,+a,-a,
            +a,-a,-a,
            -a,-a,-a,
    
            -a,-a,+a,
            +a,-a,+a,
            +a,+a,+a,
            -a,+a,+a,
    
            -a,-a,-a,
            +a,-a,-a,
            +a,-a,+a,
            -a,-a,+a,
    
            +a,-a,-a,
            +a,+a,-a,
            +a,+a,+a,
            +a,-a,+a,
    
            +a,+a,-a,
            -a,+a,-a,
            -a,+a,+a,
            +a,+a,+a,
    
            -a,+a,-a,
            -a,-a,-a,
            -a,-a,+a,
            -a,+a,+a,
            };
        const GLfloat col[]=
            {
        //  r   g   b    
            1.0,0.0,0.0,
            1.0,0.0,0.0,
            1.0,0.0,0.0,
            1.0,0.0,0.0,
    
            1.0,1.0,0.0,
            1.0,1.0,0.0,
            1.0,1.0,0.0,
            1.0,1.0,0.0,
    
            0.0,1.0,0.0,
            0.0,1.0,0.0,
            0.0,1.0,0.0,
            0.0,1.0,0.0,
    
            0.0,1.0,1.0,
            0.0,1.0,1.0,
            0.0,1.0,1.0,
            0.0,1.0,1.0,
    
            0.0,0.0,1.0,
            0.0,0.0,1.0,
            0.0,0.0,1.0,
            0.0,0.0,1.0,
    
            1.0,1.0,1.0,
            1.0,1.0,1.0,
            1.0,1.0,1.0,
            1.0,1.0,1.0,
            };
        const GLfloat nor[]=    // glNormal
            {
        //   nx   ny   nz
             0.0, 0.0,-1.0,
             0.0, 0.0,-1.0,
             0.0, 0.0,-1.0,
             0.0, 0.0,-1.0,
    
             0.0, 0.0,+1.0,
             0.0, 0.0,+1.0,
             0.0, 0.0,+1.0,
             0.0, 0.0,+1.0,
    
             0.0,-1.0, 0.0,
             0.0,-1.0, 0.0,
             0.0,-1.0, 0.0,
             0.0,-1.0, 0.0,
    
            +1.0, 0.0, 0.0,
            +1.0, 0.0, 0.0,
            +1.0, 0.0, 0.0,
            +1.0, 0.0, 0.0,
    
             0.0,+1.0, 0.0,
             0.0,+1.0, 0.0,
             0.0,+1.0, 0.0,
             0.0,+1.0, 0.0,
    
            -1.0, 0.0, 0.0,
            -1.0, 0.0, 0.0,
            -1.0, 0.0, 0.0,
            -1.0, 0.0, 0.0,
            };
        int i,i3;
        glBegin(GL_QUADS);
        for (i=0,i3=0;i<24;i++,i3+=3)
            {
            glColor3fv (col+i3);
            glNormal3fv(nor+i3);
            glVertex3fv(pos+i3);
            }
        glEnd();
        }
    

    which is supposed to render like this:

    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);
    render_cube();
    

    just set the a constant to what ever you need and translate modelview to its placement position ...

    here preview:

    cube

    Each side has its own color for debug purposes ... Look here for 3D view example:

    [Edit1] I tweaked your code a bit

    there were some inconsistencies in polygon winding. Try to swap your functions with these (they worked for me) and leave the rest of your code as is:

    //---------------------------------------------------------------------------
    void render_cube(GLfloat a) // cube half size
        {
        GLfloat pos[]=  // glVertex
            {
        //   x  y  z
            -a,+a,-a,
            +a,+a,-a,
            +a,-a,-a,
            -a,-a,-a,
    
            -a,-a,+a,
            +a,-a,+a,
            +a,+a,+a,
            -a,+a,+a,
    
            -a,-a,-a,
            +a,-a,-a,
            +a,-a,+a,
            -a,-a,+a,
    
            +a,-a,-a,
            +a,+a,-a,
            +a,+a,+a,
            +a,-a,+a,
    
            +a,+a,-a,
            -a,+a,-a,
            -a,+a,+a,
            +a,+a,+a,
    
            -a,+a,-a,
            -a,-a,-a,
            -a,-a,+a,
            -a,+a,+a,
            };
        const GLfloat col[]=    // glColor
            {
        //  r   g   b
            1.0,0.0,0.0,
            1.0,0.0,0.0,
            1.0,0.0,0.0,
            1.0,0.0,0.0,
    
            1.0,1.0,0.0,
            1.0,1.0,0.0,
            1.0,1.0,0.0,
            1.0,1.0,0.0,
    
            0.0,1.0,0.0,
            0.0,1.0,0.0,
            0.0,1.0,0.0,
            0.0,1.0,0.0,
    
            0.0,1.0,1.0,
            0.0,1.0,1.0,
            0.0,1.0,1.0,
            0.0,1.0,1.0,
    
            0.0,0.0,1.0,
            0.0,0.0,1.0,
            0.0,0.0,1.0,
            0.0,0.0,1.0,
    
            1.0,1.0,1.0,
            1.0,1.0,1.0,
            1.0,1.0,1.0,
            1.0,1.0,1.0,
            };
        const GLfloat nor[]=    // glNormal
            {
        //   nx   ny   nz
             0.0, 0.0,-1.0,
             0.0, 0.0,-1.0,
             0.0, 0.0,-1.0,
             0.0, 0.0,-1.0,
    
             0.0, 0.0,+1.0,
             0.0, 0.0,+1.0,
             0.0, 0.0,+1.0,
             0.0, 0.0,+1.0,
    
             0.0,-1.0, 0.0,
             0.0,-1.0, 0.0,
             0.0,-1.0, 0.0,
             0.0,-1.0, 0.0,
    
            +1.0, 0.0, 0.0,
            +1.0, 0.0, 0.0,
            +1.0, 0.0, 0.0,
            +1.0, 0.0, 0.0,
    
             0.0,+1.0, 0.0,
             0.0,+1.0, 0.0,
             0.0,+1.0, 0.0,
             0.0,+1.0, 0.0,
    
            -1.0, 0.0, 0.0,
            -1.0, 0.0, 0.0,
            -1.0, 0.0, 0.0,
            -1.0, 0.0, 0.0,
            };
        int i,i3;
        glBegin(GL_QUADS);
        for (i=0,i3=0;i<24;i++,i3+=3)
            {
            glColor3fv (col+i3);
            glNormal3fv(nor+i3);
            glVertex3fv(pos+i3);
            }
        glEnd();
        }
    //---------------------------------------------------------------------------
    void init()
        {
        glClearColor(1.0, 0.0, 1.0, 0.0);
        glShadeModel(GL_FLAT);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_LIGHTING);
        glEnable(GL_LIGHT0);
        glEnable(GL_COLOR_MATERIAL);
        glEnable(GL_CULL_FACE);
        glFrontFace(GL_CCW);
        }
    //---------------------------------------------------------------------------
    const int scl = 80 ;
    int LeftRight = 0 ;
    int UpDown = 0;
    void DrawBoard()
        {
        int x , y , color = 0;
        glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);  // do not forget also to clear depth buffer
        for(x=1;x<=8;x++)
            {
            if (color) glColor3f (0.0, 0.0, 0.0);           // I like this a bit better then your approach
            else       glColor3f (1.0, 1.0, 1.0); color^=1;
            for(y=1; y<=8; y++)
                {
                if (color) glColor3f (0.0, 0.0, 0.0);
                else       glColor3f (1.0, 1.0, 1.0); color^=1;
                glBegin(GL_QUADS);
                glNormal3f(0.0,0.0,+1.0);
                glVertex3f(scl+scl*x, scl+scl*y,0.0);
                glVertex3f(scl*x, scl+scl*y,0.0);
                glVertex3f(scl*x, scl*y,0.0);
                glVertex3f(scl+scl*x, scl*y,0.0);
                glEnd();
                }
            }
        // your triangle just above cube (and reversed order to match the rest of rendering)
        glBegin(GL_QUADS);
        glColor3f (1.0, 0.5, 0.0);
        glNormal3f(0.0,0.0,+1.0);
        glVertex3f(150+LeftRight,100+UpDown,scl+1.0);
        glVertex3f(120+LeftRight,140+UpDown,scl+1.0);
        glVertex3f( 90+LeftRight,100+UpDown,scl+1.0);
        glVertex3f( 90+LeftRight,100+UpDown,scl+1.0);
        glEnd();
        // cube
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();                             // remember modelview
        glTranslatef(1.5*scl+LeftRight,1.5*scl+UpDown,+0.5*scl);    // set cube position
        render_cube(0.5*scl);
        glPopMatrix();                              // restore modelview
        glFlush();
        }
    //---------------------------------------------------------------------------
    void reshape (int w, int h)
        {
        glViewport (0, 0, (GLsizei) w, (GLsizei) h);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluPerspective(60,float(w)/float(h),10.0,10000.0);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
        glTranslatef(-w/2,-h/2,-1000.0);
        }
    //---------------------------------------------------------------------------
    

    Using 800x800 window the result should look like this:

    preview

    btw. these includes are obsolete:

    #include <string>
    #include <stdlib.h>
    #include <iostream>
    using namespace std;
    

    as you are not using anything from them in your code.