2020年6月29日 星期一

會跳舞的機器人

#include <GL/glut.h>
#include "glm.h"
#include<stdio.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include<windows.h>///定義DWORD

#include<mmsystem.h>///playsound


#include "CMP3_MCI.h"

CMP3_MCI myMP3;
#include <stdlib.h>

static int slices = 16;
static int stacks = 16;
static void resize(int width, int height)///留下resize()
{
    const float ar = (float) width / (float) height;

    glViewport(0, 0, width, height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, ar, 0.01, 1000);///我們改了它!!!

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity() ;///原本只有2行, 沒有運鏡
    ///需要運鏡時, 要加上第3行 gluLookAt()
}

GLMmodel* body = NULL;///指標body
GLMmodel* head= NULL;///指標head
GLMmodel* armleft = NULL;///指標armleft
GLMmodel* armright = NULL;///指標armright
GLMmodel* handleft = NULL;///指標handleft
GLMmodel* handright = NULL;///指標handright
GLMmodel* legright = NULL;///指標legright
GLMmodel* legleft= NULL;///指標legleft
GLMmodel* footright = NULL;///指標footright
GLMmodel* footleft= NULL;///指標footright
GLMmodel* background= NULL;///指標background
float anglelegr=0;
float anglelegl=0;
float anglearmr=0;
float anglearml=0;
float anglehandr=0;
float anglehandl=0;
float anglebody=0;
float anglehead=0;
float anglefoot=0;
int t=0;
int count=1;
int change=1;
int time=0;
int y=-0;
double x=0;
double z=0;

///打光0 : 宣告陣列,裡面是光的屬性值
const GLfloat light_ambient[]  = { 0.0f, 0.0f, 0.0f, 1.0f };
const GLfloat light_diffuse[]  = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat light_position[] = { 2.0f, 5.0f, 5.0f, 0.0f };
const GLfloat mat_ambient[]    = { 0.7f, 0.7f, 0.7f, 1.0f };
const GLfloat mat_diffuse[]    = { 0.8f, 0.8f, 0.8f, 1.0f };
const GLfloat mat_specular[]   = { 1.0f, 1.0f, 1.0f, 1.0f };
const GLfloat high_shininess[] = { 100.0f };


void display()
{
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);///清背景

            if (body ==NULL) {
            body = glmReadOBJ("body.obj");///讀入3D模型
            glmUnitize(body);///調整單位大小
            glmFacetNormals(body);///正確法向量
            glmVertexNormals(body, 90.0);///算出頂點(先有面才有點)
            }
            if (head==NULL) {///head
            head = glmReadOBJ("head.obj");///讀入3D模型
            glmUnitize(head);///調整單位大小
            glmFacetNormals(head);///正確法向量
            glmVertexNormals(head, 90.0);///算出頂點(先有面才有點)
            }
            if (handleft==NULL) {///hand
            handleft = glmReadOBJ("hand.obj");///讀入3D模型
            glmUnitize(handleft);///調整單位大小
            glmFacetNormals(handleft);///正確法向量
            glmVertexNormals(handleft, 90.0);///算出頂點(先有面才有點)
            }
            if (handright==NULL) {///hand
            handright = glmReadOBJ("hand.obj");///讀入3D模型
            glmUnitize(handright);///調整單位大小
            glmFacetNormals(handright);///正確法向量
            glmVertexNormals(handright, 90.0);///算出頂點(先有面才有點)
            }
            if (armleft==NULL) {///arm
            armleft = glmReadOBJ("arm.obj");///讀入3D模型
            glmUnitize(armleft);///調整單位大小
            glmFacetNormals(armleft);///正確法向量
            glmVertexNormals(armleft, 90.0);///算出頂點(先有面才有點)
            }
            if (armright==NULL) {///arm
            armright = glmReadOBJ("arm.obj");///讀入3D模型
            glmUnitize(armright);///調整單位大小
            glmFacetNormals(armright);///正確法向量
            glmVertexNormals(armright, 90.0);///算出頂點(先有面才有點)
            }
            if (legright==NULL) {///leg
            legright = glmReadOBJ("leg.obj");///讀入3D模型
            glmUnitize(legright);///調整單位大小
            glmFacetNormals(legright);///正確法向量
            glmVertexNormals(legright, 90.0);///算出頂點(先有面才有點)
            }
            if (legleft==NULL) {///leg
            legleft = glmReadOBJ("leg.obj");///讀入3D模型
            glmUnitize(legleft);///調整單位大小
            glmFacetNormals(legleft);///正確法向量
            glmVertexNormals(legleft, 90.0);///算出頂點(先有面才有點)
            }
            if (footright==NULL) {///leg
            footright = glmReadOBJ("foot.obj");///讀入3D模型
            glmUnitize(footright);///調整單位大小
            glmFacetNormals(footright);///正確法向量
            glmVertexNormals(footright, 90.0);///算出頂點(先有面才有點)
            }
            if (footleft==NULL) {///leg
            if (background==NULL) {///head
            background = glmReadOBJ("back.obj");///讀入3D模型
            glmUnitize(background);///調整單位大小
            glmFacetNormals(background);///正確法向量
            glmVertexNormals(background, 90.0);///算出頂點(先有面才有點)
            }


            footleft = glmReadOBJ("foot.obj");///讀入3D模型
            glmUnitize(footleft);///調整單位大小
            glmFacetNormals(footleft);///正確法向量
            glmVertexNormals(footleft, 90.0);///算出頂點(先有面才有點)
            }
glPushMatrix();
{
    glTranslatef(0,0,0);
    glScalef(1,1,1);
    glmDraw(background, GLM_SMOOTH | GLM_MATERIAL);

    glPushMatrix();
    {
        glTranslatef(x,0,z);
        if(t==6)glRotatef(anglebody, 0,1,0);
    else
        glRotatef(-anglebody, 1,1,0);
    glScalef(0.05,0.1,0.05);
    glRotatef(270,0,1,0);///模型旋轉180度變成圖二
    glmDraw(body, GLM_SMOOTH | GLM_MATERIAL);///畫
    }
    glPushMatrix();///head
    {
    glTranslatef(0,1.4,0);//由下面往上做所以最後把旋轉的以下所有東西移到(0.5,0.5)的地方
    glRotatef(anglehead, 1,0,0);//以z軸旋轉
    glTranslatef(0,0,0);//由下面往上做所以會先移動把軸心以x軸移動0.25
    glScalef(0.8,0.8,0.8);
    glRotatef(270,0,1,0);///模型旋轉180度變成圖二
    glmDraw(head, GLM_SMOOTH | GLM_MATERIAL);///畫
    }
    glPopMatrix();



    glPushMatrix();///leftthand
    {
        glTranslatef(0.2,0.5,1);//由下面往上做所以最後把旋轉的以下所有東西移到(0.5,0.5)的地方
        if(t==1)glRotatef(anglearml, 0,0,1);
        if(t==3)glRotatef(anglearml, 0,0,1);
        if(t==6)glRotatef(anglearml, 0,1,0);
        glTranslatef(0,0,-0.4);//由下面往上做所以會先移動把軸心以x軸移動0.25
        glScalef(0.4,0.2,0.2);
        glRotatef(90,0,1,0);
        glRotatef(90,1,0,0);
        glmDraw(armleft, GLM_SMOOTH | GLM_MATERIAL);///畫
        glPushMatrix();///leftthand
        {
            glTranslatef(0.6,1.8,-0.7);//由下面往上做所以最後把旋轉的以下所有東西移到(0.5,0.5)的地方
            if(t==6)glRotatef(-anglehandl, 0,0,1);
            glTranslatef(0.6,0,0.5);//由下面往上做所以會先移動把軸心以x軸移動0.25
            glScalef(1.4,0.8,1.4);
            glRotatef(-90,1,0,0);
            glRotatef(90,0,0,1);
            glmDraw(handleft, GLM_SMOOTH | GLM_MATERIAL);///畫
        }
        glPopMatrix();
    }
    glPopMatrix();
    glPushMatrix();///righthand
    {
        glTranslatef(0.8,0.5,-0.05);//由下面往上做所以最後把旋轉的以下所有東西移到(0.5,0.5)的地方
        if(t==1)glRotatef(anglearmr, 0,0,1);;
        if(t==3)glRotatef(anglearmr, 0,1,0);
        if(t==6)glRotatef(anglearmr, 0,1,0);
        glTranslatef(0.6,0,-0.4);//由下面往上做所以會先移動把軸心以x軸移動0.25
        glScalef(0.4,0.2,0.2);
        //glRotatef(90,0,1,0);
        glRotatef(90,0,1,0);
        glRotatef(90,1,0,0);
        glmDraw(armright, GLM_SMOOTH | GLM_MATERIAL);///畫
        glPushMatrix();///righthand
        {
            glTranslatef(-0.6,1,0.4);//由下面往上做所以最後把旋轉的以下所有東西移到(0.5,0.5)的地方
            if(t==6)glRotatef(-anglehandr, 0,0,1);//以z軸旋轉
            glTranslatef(-1,0,-0.4);//由下面往上做所以會先移動把軸心以x軸移動0.25
            glScalef(1.4,0.8,1.4);
            //glRotatef(-90,1,0,0);
            glRotatef(-90,1,0,0);
            glRotatef(270,0,0,1);
            glmDraw(handright, GLM_SMOOTH | GLM_MATERIAL);///畫
        }
        glPopMatrix();
    }
    glPopMatrix();

    glPushMatrix();///leg
    {
    glTranslatef(0,-0.6,-0.2);//由下面往上做所以最後把旋轉的以下所有東西移到(0.5,0.5)的地方
    if(t==1)
    {
        glRotatef(anglelegr, 0,0,1);
    }//以z軸旋轉
    if(t==2 || t==3 )
    {
        glRotatef(anglelegr, 1,0,0);
    }//以z軸旋轉
     if(t==4||t==5)
        {
            glRotatef(anglelegr, 1,0,0);
    }//以z軸旋轉
    if(t==6)
    {
        glRotatef(anglelegr, 0,1,1);
    }//
    glTranslatef(0,-0.5,0);//由下面往上做所以會先移動把軸心以x軸移動0.25
    glScalef(0.5,1.2,0.5);
    glRotatef(90,0,1,0);///模型旋轉180度變成圖二
    glmDraw(legright, GLM_SMOOTH | GLM_MATERIAL);///畫

    glPushMatrix();///leg
    {
    glTranslatef(0.05,-0.5,-0.1);//由下面往上做所以最後把旋轉的以下所有東西移到(0.5,0.5)的地方
    glRotatef(anglefoot, 1,0,0);//以z軸旋轉
    glTranslatef(0,-0.5,0);//由下面往上做所以會先移動把軸心以x軸移動0.25
    glScalef(0.6,0.8,0.6);
    glRotatef(-90,0,1,0);///模型旋轉180度變成圖二
    glmDraw(footright, GLM_SMOOTH | GLM_MATERIAL);///畫
    }
    glPopMatrix();

    }
    glPopMatrix();
    glPushMatrix();///legright

    {
    glTranslatef(0,-0.6,0.2);//由下面往上做所以最後把旋轉的以下所有東西移到(0.5,0.5)的地方
    if(t==1)
        {
            glRotatef(anglelegl, 0,0,1);
        }//以z軸旋轉
    if(t==2 || t==3)
        {
            glRotatef(-anglelegl, 1,0,0);
    }//以z軸旋轉
    if(t==4||t==5)
        {
            glRotatef(anglelegl, 1,0,0);
    }//以z軸旋轉
    glTranslatef(0,-0.5,0);//由下面往上做所以會先移動把軸心以x軸移動0.25
    glScalef(0.5,1.2,0.5);
    glRotatef(90,0,1,0);///模型旋轉180度變成圖二
    glmDraw(legleft, GLM_SMOOTH | GLM_MATERIAL);///畫
    glPushMatrix();///legright

    {
    glTranslatef(0.05,-0.5,-0.1);//由下面往上做所以最後把旋轉的以下所有東西移到(0.5,0.5)的地方

    glTranslatef(0,-0.5,0);//由下面往上做所以會先移動把軸心以x軸移動0.25
    glScalef(0.6,0.8,0.6);
    glRotatef(-90,0,1,0);///模型旋轉180度變成圖二
    glmDraw(footleft, GLM_SMOOTH | GLM_MATERIAL);///畫
    }
    glPopMatrix();
    }
    glPopMatrix();
    glPopMatrix();
    }
    glPopMatrix();
if(time==1){ t=1;}//walk
if(time==2){ t=2;}//leg
if(time==3){ t=3;}//head
if(time==4){ t=1;}//walk
if(time==5){ t=2;}//leg
if(time==6){ t=3;}//head
if(time==7){ t=4;}//move
if(time==8){ t=6;}//rotate
if(time==9){ t=5;}//move
if(time==10){ t=6;}//rotate
if(t==1)
{
    if(count %2==1)
    {   z+=0.0008;
        if(change==1)
        {
            anglelegr++;
            anglearmr++;
            if(anglearmr==90)
            {
                anglearmr=90;
            }
            if(anglelegr==90)
            {
                change=2;
            }
        }
        if(change==2)
        {
            anglelegr--;
            anglearmr--;
            if(anglearmr==0)
            {
                anglearmr=0;
            }
            if(anglelegr==0)
            {
                change=1;
                count++;
            }
        }
    }
    if(count %2==0)
    {
        z-=0.001;
        if(change==1)
        {
            anglelegl++;
            anglearml++;
            if(anglearml==90)
            {
                anglearml=90;
            }
            if(anglelegl==90)
            {
                change=2;
            }
        }
        if(change==2)
        {
            anglelegl--;
            anglearml--;
            if(anglearml==0)
            {
                anglearmr=0;
            }
            if(anglelegl==0)
            {
                change=1;
                count++;
            }
        }
        }
        if (count==6)
        {
            time++;
            count=1;
        }
}
if(t==2)
{
    if(count %2==1)
    {
        if(change==1)
        {
            anglelegr++;
            if(anglelegr==40)
            {
                change=2;
            }
        }
        if(change==2)
        {
            anglelegr--;
            if(anglelegr==0)
            {
                change=1;
                count++;
            }
        }
    }
    if(count %2==0)
    {
        if(change==1)
        {
            anglelegl++;
            if(anglelegl==40)
            {
                change=2;
            }
        }
        if(change==2)
        {
            anglelegl--;
            if(anglelegl==0)
            {
                change=1;
                count++;
            }
        }
    }
    if (count==5)
    {
        time++;
        count=1;
    }


}
if(t==3)
{
    if(change==1)
    {
        anglebody++;
        if(anglebody==35)
        {
            change=2;
        }
    }
    if(change==2)
    {
        anglehead++;
        if(anglehead==45)
        {
            anglehead=45;
            change=3;
        }
    }
    if(change==3)
    {
        anglehead--;
        if(anglehead==0)
        {
            anglehead=0;
            change=4;
        }
    }
    if(change==4)
    {
        anglebody--;
        if(anglebody==0)
        {
        change=1;
        time++;
        }
    }
}

if(t==4)
{
    if(count %2==1)
    {x+=0.001;
        if(change==1)
        {
            anglelegr++;
            if(anglelegr==20)
            {
                change=2;
            }
        }
        if(change==2)
        {
            anglelegr--;
            if(anglelegr==0)
            {
                change=1;
                count++;
            }
        }

    }
    if(count %2==0)
    {
        if(change==1)
        {
            anglelegl--;
            if(anglelegl==-20)
            {
                change=2;
            }
        }
        if(change==2)
        {
            anglelegl++;
            if(anglelegl==0)
            {
                change=1;
                count++;
            }
        }
        x+=0.005;
    }
    if (count==4)
    {
        time++;
        count=1;
    }

}


if(t==5)
{x-=0.0001;
    if(count %2==1)
    {
        if(change==1)
        {   x-=0.01;
            anglelegr++;
            if(anglelegr==20)
            {
                change=2;
            }
        }
        if(change==2)
        {
            anglelegr--;
            if(anglelegr==0)
            {
                change=1;
                count++;
            }
        }

    }
    if(count %2==0)
    {
        if(change==1)
        {
            anglelegl--;
            if(anglelegl==-20)
            {
                change=2;
            }
        }
        if(change==2)
        {
            anglelegl++;
            if(anglelegl==0)
            {
            change=1;
            count++;
            }
        }
    }
    if (count==4)
    {
    time++;
    count=1;
    }


}
if(t==6)
{
if(change==1)
{
    anglearml--;
    anglearmr++;
    anglehandl--;
    anglehandr++;
    anglelegr++;
    anglefoot++;
    if(anglefoot==35)
    {
        anglefoot=35;
    }

    if(anglelegr==75)
    {
        anglelegr=75;
    }
    if(anglearml==-90)
    {
        change=2;
    }
}
if(change==2)
{
    anglebody++;
    if(anglebody==1080)
    {
        anglebody=0;
        change=3;
    }
}//rotate
if(change==3)
{
    anglearml++;
    anglearmr--;
    anglehandl++;
    anglehandr--;
    anglelegr--;
    anglefoot--;
    if(anglefoot==0)
    {
        anglefoot=0;
    }

    if(anglelegr==0)
    {
        anglelegr=0;
    }
    if(anglearml==0)
    {
        change=1;
        time++;
    }
}
}
if(time==11)
   time=1;
glEnable(GL_LIGHT0);
    glEnable(GL_NORMALIZE);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);
    ///打光2 : 設定light值 (拿前面的陣列來用)
    glLightfv(GL_LIGHT0, GL_AMBIENT,  light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  light_diffuse);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    ///打光 2-2 : 設定物體material
    glMaterialfv(GL_FRONT, GL_AMBIENT,   mat_ambient);
    glMaterialfv(GL_FRONT, GL_DIFFUSE,   mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SPECULAR,  mat_specular);
    glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);

glutSwapBuffers();
}

#include <math.h>
float eyeX=0, eyeY=0, eyeZ=1;///TODO
float angle=0;
static void key(unsigned char key, int x, int y)
{
    switch (key)
    {
        case 27 :
        case 'q':
            exit(0);
            break;

        case 'z':
            angle+=0.01;
            break;

        case 'x':

                angle-=0.01;
            break;
            case 't':
            myMP3.Load("bellet.mp3");
            myMP3.Play();
            time=1;
            break;
    }

    glutPostRedisplay();
}
static void idle(void)
{
    eyeX=sin(angle);
    eyeZ=cos(angle);


    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity() ;///原本只有2行, 沒有運鏡
    gluLookAt(eyeX, eyeY, eyeZ, 0,0,0, 0,1,0); ///需要運鏡時, 要加上第3行 gluLookAt()

    glutPostRedisplay();
}
void motion(int x, int y)
{
    eyeY = (y-240)/240.0;
}
int main(int argc, char**argv) ///高手等級的main()
{
    //myMP3.Load("bellet.mp3");
    //myMP3.Play();
     glutInit(&argc,argv);///main的參數,於近來
     glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);   ///啟動3D的顯示能力,兩倍顯示buffer,有3D深度值
     glutCreateWindow("期末!!!");    ///建立3D窗子
     glutDisplayFunc(display);    ///等一下怎麼畫
      ///打光要3D的depth test
    glutIdleFunc(display);
glutKeyboardFunc(key);
     glutReshapeFunc(resize);
     glutIdleFunc(idle);
     glutMotionFunc(motion);///TODO 控制 eyeY



     glClearColor(1,1,1,1);
    glEnable(GL_DEPTH_TEST);
     glDepthFunc(GL_LESS);
    ///打光1 : 開啟光線


    glutMainLoop();    ///主要迴圈卡在這裡,不會結束
}

沒有留言:

張貼留言