change 2D object to 3D object OpenGl

前提是你 提交于 2019-12-24 08:45:51

问题


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;
}

回答1:


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:

  • 2D shape in C++ by using the OpenGl library

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:

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

  • Faces missing when drawing icosahedron in OpenGL following code in redBook

[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:

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.



来源:https://stackoverflow.com/questions/43618023/change-2d-object-to-3d-object-opengl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!