将2D对象更改为3D对象OpenGl

时间:2017-04-25 18:08:43

标签: c++ opengl freeglut

我有一个代码,用于找到在棋盘中单击的单元格鼠标,然后2D三角形状转到单元格位置,现在我想将2D三角形更改为3D立方体,但我不知道该怎么做。

这是我的代码

#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 个答案:

答案 0 :(得分:1)

您的主要问题是GL_PROJECTION设置为gluOrtho2D,因此当您渲染轴对齐立方体时,它将始终生成正方形。要解决此问题,您应该使用gluProjection代替。但是,这会以0.0,0.0为中心,而不是当前的屏幕中心坐标(0.5*w,0.5*h),因此您还需要翻译GL_MODELVIEW

此处示例如何执行此操作:

现在要渲染一个立方体,你可以这样做:

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

应该像这样呈现:

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

只需将a常量设置为您需要的值,并将modelview转换为其展示位置......

这里预览:

cube

每一面都有自己的颜色用于调试目的...在这里查看3D视图示例:

[Edit1]我稍稍调整了你的代码

多边形绕组存在一些不一致之处。尝试将这些函数与这些函数交换(它们对我有效)并保留其余代码:

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

使用800x800窗口,结果应如下所示:

preview

btw。这些包含已过时:

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

因为您没有在代码中使用任何内容。