图形学实验二:画个火柴人

由于接下来的实验要实现火柴人的动作,所以实验要求要采用分层设计,如下图所示:

这样转动hip(臀部),整个火柴人就整体转动。比如如果要动左腿,那么在相对hip上进行自己的操作,这样设计对火柴人的动作实现很方便。

                                                 



贴上自己的代码,程序用递归来实现分层设计,此外还增添了火柴人旋转功能:


#define _STDCALL_SUPPORTED
#include <GL/glut.h>
GLUquadricObj   *uquadric;  //二次曲面声明类型

void drawTorso();
void drawLeftleg1();
void drawRightleg1();
void drawLeftarm1();
void drawLefttarm2();
void drawRightarm1();
void drawRightarm2();
void drawNeck();
void drawHead();
void selfRotateRL1();
//画臀部,根节点
void drawHip(){
    glScalef(2.0,0.5,1.0);
    glPushMatrix();
    glTranslatef(0.0,-1.0,0.0);
    glutWireCube(0.3);
    drawTorso();

    drawLeftleg1();
    drawRightleg1();
    glPopMatrix();
}

//画肩膀
void drawShoulder(){
    glScalef(2.0,0.5,2.0);  //先还原成1:1
    glScalef(2.0,0.5,1.0);
    glPushMatrix();

    glTranslatef(0.0,1.45,0.0);
    glutWireCube(0.4);

    drawRightarm1();
    drawLeftarm1();
    drawNeck();
    drawHead();

    glPopMatrix();
}
//画躯干
void drawTorso(){
    glScalef(0.5,2.0,1.0);  //先还原成1:1
    glScalef(0.5,2.0,0.5);  //躯干Z轴方向缩短一半,不然躯干太粗
    glPushMatrix();

    glTranslatef(0.0,0.35,0.0);
    glutWireCube(0.6);
    drawShoulder();

    glPopMatrix();
}
void drawRightarm2(){
    glPushMatrix();

    //差点忘记了,arm1是绕x轴旋转了90度,所以三维坐标也跟着旋转了90度
    //这里第二个是“z轴”,负的往里,正的往外
    //第三个是“y轴”,负的网上,正的往下
    glTranslatef(0.0,0.0,0.7);

    glRotatef(15,0.0,-1.0,0.0);
    gluCylinder(uquadric, 0.08, 0.08, 0.6, 20.0, 8.0);

    glPopMatrix();
}
void drawRightarm1(){
    glScalef(0.5,2.0,1.0);  //还原成1:1
    glPushMatrix();

    //gluQuadricDrawStyle(uquadric, GLU_FILL);  //控制绘图风格
    glTranslatef(-0.3,-0.05,0.0);
    glRotatef(90,1.0,0.0,0.0);


    gluCylinder(uquadric, 0.08, 0.08, 0.7, 20.0, 8.0);

    drawRightarm2();

    glPopMatrix();
}

void drawLeftarm2(){
    glPushMatrix();

    glTranslatef(0.0,0.0,0.7);

    glRotatef(15,0.0,1.0,0.0);
    gluCylinder(uquadric, 0.08, 0.08, 0.6, 20.0, 8.0);

    glPopMatrix();
}
void drawLeftarm1(){
    glPushMatrix();

    glTranslatef(0.3,-0.05,0.0);
    glRotatef(90,1.0,0.0,0.0);
    gluCylinder(uquadric, 0.08, 0.08, 0.7, 20.0, 8.0);

    drawLeftarm2();

    glPopMatrix();
}
//画头
void drawHead(){
    glPushMatrix();

    glTranslatef(0.0,0.65,0.0);
    glutWireCube(0.40);

    glPopMatrix();
}
//画脖子
void drawNeck(){
    glPushMatrix();

    glTranslatef(0.0,0.40,0.0);
    glRotatef(90,1.0,0.0,0.0);
    gluCylinder(uquadric, 0.10, 0.10, 0.30, 20.0, 8.0);

    glPopMatrix();
}

void drawRightLeg2(){
    glPushMatrix();

    glTranslatef(0.0,0.0,0.8);
    //glRotatef(10,0.0,-1.0,0.0);
    gluCylinder(uquadric, 0.1, 0.1, 0.8, 20.0, 8.0);


    glPopMatrix();
}
void drawRightleg1(){
    //glScalef(2.0,0.5,1.0);  //先还原成1:1

    glPushMatrix();

    glTranslatef(0.20,-0.05,0.0);
    //注意这里坐标轴绕x旋转了90度,leg2的坐标会变化
    glRotatef(90,1.0,0.0,0.0);
    gluCylinder(uquadric, 0.1, 0.1, 0.8, 20.0, 8.0);

    drawRightLeg2();

    glPopMatrix();
}

void drawLeftLeg2(){
    glPushMatrix();

    glTranslatef(0.0,0.0,0.8);
    //glRotatef(10,0.0,-1.0,0.0);
    gluCylinder(uquadric, 0.1, 0.1, 0.8, 20.0, 8.0);


    glPopMatrix();
}

void drawLeftleg1(){
    glScalef(2.0,0.5,1.0);  //先还原成1:1

    glPushMatrix();

    glTranslatef(-0.20,-0.05,0.0);
    //注意这里坐标轴绕x旋转了90度,leg2的坐标会变化
    glRotatef(90,1.0,0.0,0.0);
    gluCylinder(uquadric, 0.1, 0.1, 0.8, 20.0, 8.0);

    drawLeftLeg2();

    glPopMatrix();
}
static float rotateAngle = 0;
static int times1 = 0;
void selfRotateWhole(){
    times1++;
    if(times1 > 50)
    {
        times1 = 0;
    }

    if(times1 % 50 == 0)
    {
        rotateAngle += 0.5;
    }

    glRotatef(rotateAngle, 0, 1, 0);
    glRotatef(rotateAngle, 1, 0, 0);
}

//自由旋转转动
void renderScene()
{
    glClear(GL_COLOR_BUFFER_BIT); //清除当前可写的颜色缓冲
    glColor3f(1.0,0.0,0.0);
	glLoadIdentity();
    gluLookAt(0.0,0.0,0.0,0.0,0.0,-1.0,0.0,1.0,0.0);
    glLoadIdentity();
    /*
    glMatrixMode设置当前矩阵模式:
    GL_MODELVIEW,对模型视景矩阵堆栈应用随后的矩阵操作.
    GL_PROJECTION,对投影矩阵应用随后的矩阵操作.
    GL_TEXTURE,对纹理矩阵堆栈应用随后的矩阵操作.
    与glLoadIdentity()一同使用
    */
    glMatrixMode(GL_MODELVIEW);
    glScalef(0.5,0.5,1.0); //先缩放下,不然木头人会很大。。。
    glPushMatrix();

    selfRotateWhole();
    drawHip();

    glPopMatrix();
    glFlush();
    //glutSwapBuffers();
}

void init(){
    glClearColor(0.0,0.0,0.0,0.0); //glClearColor(R,G,B,AFA)清空当前颜色,并且设定颜色值
    glShadeModel(GL_FLAT);  //设置着色模式。
    uquadric = gluNewQuadric();
}

int main(int argc, char *argv[])

{

     glutInit(&argc, argv);
     /*
     GLUT_RGB:指定 RGB 颜色模式的窗口
     GLUT_SINGLE:指定单缓存窗口
     */
     glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

     glutInitWindowPosition(100, 100);
     glutInitWindowSize(500, 500);
     glutCreateWindow("太空漂浮");

     init();

     //glutDisplayFunc(display);

	 glutDisplayFunc(renderScene);
     glutIdleFunc(renderScene);
     //glutReshapeFunc(reshape);
     glutMainLoop();

     return 0;

}


附上几张运行图片:

扫描二维码关注公众号,回复: 3133234 查看本文章


      

   


                                                

猜你喜欢

转载自blog.csdn.net/sunny_xsc1994/article/details/41682905