Qt魔方还原1

目的

用Qt opengl 绘制3D魔方,并用鼠标控制整体的旋转与缩放
效果如下:
这里写图片描述

准备工作

  • 学习Qt opengl绘制简单的立方体,并给立方体贴图Qt opengl教程
  • 准备六个面图片素材

实施

1.新建Qt widget工程

这里是以Qt4版本来设计代码的,在pro文件中加上

QT += opengl

2.绘制坐标轴

绘制三条线表示坐标轴,这样便于以后区分,opengl 绘制3D,且控制物体旋转跟坐标轴相关,加上这三条线可以让我们很好地区分当前在什么位置。

void GLWidget::paintGL()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glLoadIdentity();
    glTranslatef(  0.0,  0.0, zoom );

    glRotatef( xRot,  1.0,  0.0,  0.0 );
    glRotatef( yRot,  0.0,  1.0,  0.0 );

    //绘制坐标轴,方便调试
    glLineWidth(2);
    glBegin(GL_LINES);
    glColor3f(1,0,0); glVertex3f(0,0,0);//y
    glColor3f(1,0,0); glVertex3f(0,6,0);

    glColor3f(0,1,0); glVertex3f(0,0,0);//x
    glColor3f(0,1,0); glVertex3f(6,0,0);

    glColor3f(0,0,1); glVertex3f(0,0,0);//z
    glColor3f(0,0,1); glVertex3f(0,0,6);

    glEnd();
}

效果:
这里写图片描述

3.绘制一个立方体

3阶魔方共有27个小立方体组成,先绘制一个小立方体,使用opengl 主要是熟悉坐标系统,哪里是原点哪里是x,y,z轴的正方向
屏幕向外,z轴正向
屏幕向右,x轴正向
屏幕向上,y轴正向
写点代码做几个实验就可以很好的区分

//绘制一个立方体 魔方共27个
void GLWidget::drawOneCube(Cube *b, GLfloat x, GLfloat y, GLfloat z)//
{
    x=x-0.5;
    y=y-0.5;
    z=z-0.5;
    const Cube::Color *color = b->getColor();
    glBindTexture( GL_TEXTURE_2D, texture[color[0]] );
    glBegin( GL_QUADS );
    //后面 黄色
    glNormal3f( x, y, z );
    glTexCoord2f( 0,   0  );glVertex3f(x,   y, z);
    glTexCoord2f( 0+1, 0  );glVertex3f(x+1, y, z);
    glTexCoord2f( 0+1, 0+1);glVertex3f(x+1, y+1, z);
    glTexCoord2f( 0,   0+1);glVertex3f(x, y+1, z);

    glEnd();

    glBindTexture( GL_TEXTURE_2D, texture[color[1]] );
    glBegin( GL_QUADS );
    //前面 白色
    glNormal3f( x, y, z+1 );
    glTexCoord2f( 0,   0  );glVertex3f(x,   y,   z+1);
    glTexCoord2f( 0+1, 0  );glVertex3f(x+1, y,   z+1);
    glTexCoord2f( 0+1, 0+1);glVertex3f(x+1,   y+1, z+1);
    glTexCoord2f( 0,   0+1);glVertex3f(x, y+1, z+1);

    glEnd();
    glBindTexture( GL_TEXTURE_2D, texture[color[2]] );
    glBegin( GL_QUADS );

    //下面 蓝色
    glNormal3f( x, y, z);
    glTexCoord2f( 0,   0  );glVertex3f(x,   y,   z);
    glTexCoord2f( 0+1, 0  );glVertex3f(x+1, y,   z);
    glTexCoord2f( 0+1, 0+1);glVertex3f(x+1,   y, z+1);
    glTexCoord2f( 0,   0+1);glVertex3f(x, y, z+1);

    glEnd();
    glBindTexture( GL_TEXTURE_2D, texture[color[3]] );
    glBegin( GL_QUADS );

    //上面 绿色
    glNormal3f( x, y+1, z);
    glTexCoord2f( 0,   0  );glVertex3f(x,   y+1,   z);
    glTexCoord2f( 0+1, 0  );glVertex3f(x+1, y+1,   z);
    glTexCoord2f( 0+1, 0+1);glVertex3f(x+1,   y+1, z+1);
    glTexCoord2f( 0,   0+1);glVertex3f(x, y+1, z+1);

    glEnd();
    glBindTexture( GL_TEXTURE_2D, texture[color[5]] );
    glBegin( GL_QUADS );

    //左面 橙色
    glNormal3f( x, y, z);
    glTexCoord2f( 0,   0  );glVertex3f(x,   y,   z);
    glTexCoord2f( 0+1, 0  );glVertex3f(x, y+1,   z);
    glTexCoord2f( 0+1, 0+1);glVertex3f(x,   y+1, z+1);
    glTexCoord2f( 0,   0+1);glVertex3f(x, y, z+1);

    glEnd();

    glBindTexture( GL_TEXTURE_2D, texture[color[4]] );
    glBegin( GL_QUADS );

    //右面 红色
    glNormal3f( x+1, y, z);
    glTexCoord2f( 0,   0  );glVertex3f(x+1,   y,   z);
    glTexCoord2f( 0+1, 0  );glVertex3f(x+1, y+1,   z);
    glTexCoord2f( 0+1, 0+1);glVertex3f(x+1,   y+1, z+1);
    glTexCoord2f( 0,   0+1);glVertex3f(x+1, y, z+1);

    glEnd();

}

在paintGL里添加

    glColor3f(1.0f,1.0f,1.0f);

    for(int i=0;i<1;i++)
    {
        drawOneCube(&cube[i],cube[i].x,cube[i].y,cube[i].z);
    }

效果:
这里写图片描述

4.绘制全部立方体

for(int i=0;i<27;i++)
{
    drawOneCube(&cube[i],cube[i].x,cube[i].y,cube[i].z);
}

效果:
这里写图片描述

5.加上鼠标事件,控制整个魔方

//鼠标控制
void GLWidget::mousePressEvent(QMouseEvent *e)
{
    bMousePress = true;
    startPoint = e->pos();
}

void GLWidget::mouseMoveEvent(QMouseEvent *e)
{
    if(bMousePress)
    {
        QPoint tmp = startPoint - e->pos();
        if(abs(tmp.x()) > abs(tmp.y())){
            //x方向
            yRot += ((int)(4*(tmp.x()/3.0)))%360;
        }else{
            //y方向
            xRot += ((int)(4*(tmp.y()/3.0)))%360;
        }
        startPoint = e->pos();
        updateGL();
    }
}

void GLWidget::mouseReleaseEvent(QMouseEvent *)
{
    bMousePress = false;
}

/*鼠标滚轮放大缩小*/
void GLWidget::wheelEvent(QWheelEvent *e)
{
    zoom +=e->delta()/abs(e->delta());
    updateGL();
}

代码下载

https://download.csdn.net/download/gaobobo138968/10440525
运行代码时候注意data文件图片路径位置,data文件夹要放在编译运行的目录里,如
这里写图片描述

猜你喜欢

转载自blog.csdn.net/gaobobo138968/article/details/80468843