Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

lip.cpp

Last updated at Posted at 2018-12-05
lip.cpp
//g++ lip.cpp -framework OpenGL -framework GLUT -Wno-deprecated (左記のコードをターミナルにコピーしてコンパイル)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <GLUT/glut.h>

#define SPEED 3//リップシンク速度
#define TIME 13//リップシンク移行時間

//関数名の宣言
void initGL();
void display();
void resize(int w, int h);
void timer(int value);
void mouse(int button, int state, int x, int y);
void motion(int x, int y);
void keyboard(unsigned char key, int x, int y);


//グローバル変数
double eDist, eDegX, eDegY;
int winW, winH;  //ウィンドウサイズ
int mButton, mState, mX, mY;


int si=0;//動作フラグ
double px=0,py=0.5,pz=0.5;//唇上部座標
double px2=-5.0,py2=0,pz2=-1;//唇左部座標
double px3=5.0,py3=0,pz3=-1;//唇右部座標
double px4=0,py4=0.5,pz4=0.5;//唇下部座標
double lips[30]={};//リップシンク配列(30音まで)
int l_num=0;//リップシンク配列保存用
int l_num2=0;//リップシンク配列呼び出し用
int move=0;//現在の経過時間

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);  //OpenGL,GLUTの初期化
    
    initGL();
    
    glutMainLoop();
    
    return 0;
}

//初期設定関数
void initGL()
{
    //チュートリアル
    printf("a,i,u,e,o,nを自由に入力した後、1キーを入力すると動作を開始します\n");
    printf("動作途中で2キーを入力すると動作を強制終了します\n");
    printf("一度に発声できるのは30音までです\n");

    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
    glutInitWindowSize(600, 600);
    glutCreateWindow("CG");
    
    glutDisplayFunc(display);
    glutReshapeFunc(resize);
    glutTimerFunc(33, timer, 0);
    glutMouseFunc(mouse);
    glutMotionFunc(motion);
    glutKeyboardFunc(keyboard);
    
    //各種設定
    glClearColor(1.0, 0.95, 0.9, 1.0);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_NORMALIZE);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glAlphaFunc(GL_GREATER, 0.6);
    
    //光源
    GLfloat col[4];
    col[0] = 0.9; col[1] = 0.9; col[2] = 0.9; col[3] = 1.0;
    glEnable(GL_LIGHTING);
    //0
    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, col);
    glLightfv(GL_LIGHT0, GL_SPECULAR, col);
    col[0] = 0.1; col[1] = 0.1; col[2] = 0.1; col[3] = 1.0;
    glLightfv(GL_LIGHT0, GL_AMBIENT, col);
    glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.001);
    //1
    glEnable(GL_LIGHT1);
    col[0] = 0.9; col[1] = 0.9; col[2] = 0.9; col[3] = 1.0;
    glLightfv(GL_LIGHT1, GL_DIFFUSE, col);
    glLightfv(GL_LIGHT1, GL_SPECULAR, col);
    col[0] = 0.1; col[1] = 0.1; col[2] = 0.1; col[3] = 1.0;
    glLightfv(GL_LIGHT1, GL_AMBIENT, col);
    glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.001);

    eDist = 120.0;
    eDegX = 20.0; eDegY = 0.0;
}

void resize(int w, int h)
{
    glViewport(0, 0, w, h);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(30.0, (double)w/(double)h, 1.0, 1000.0);
    
    winW = w; winH = h;
}

void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    double ex = eDist*cos(eDegX*M_PI/180.0)*sin(eDegY*M_PI/180.0);
    double ey = eDist*sin(eDegX*M_PI/180.0);
    double ez = eDist*cos(eDegX*M_PI/180.0)*cos(eDegY*M_PI/180.0);
    
    gluLookAt(ex, ey, ez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    
    GLfloat lightPos0[] = {10.0, 40.0, 30.0, 1.0};
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
    GLfloat lightPos1[] = {15.0, 10.0, 15.0, 1.0};
    glLightfv(GL_LIGHT1, GL_POSITION, lightPos1);
    
    GLfloat col[4], spe[4], shi[1];
    
    glPushMatrix();//唇
    col[0] = 1.0; col[1] = 0.0; col[2] = 0.0; col[3] = 1.0;
    spe[0] = 0.7; spe[1] = 0.7; spe[2] = 0.7; spe[3] = 1.0;
    shi[0] = 100;
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, col);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spe);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shi);
    glScaled(4,4,4);
    
    if(si==1){
        if(lips[l_num2]==1){//a
            py+=(3.0-py)/SPEED;
            px2+=(-5-px2)/SPEED;
            px3+=(5-px3)/SPEED;
            py4+=(-1.5-py4)/SPEED;
            move++;
            if(move==TIME){
                l_num2++;
                move=0;
            }
        }
        if(lips[l_num2]==2){//i
            py+=(2-py)/SPEED;
            px2+=(-6.0-px2)/SPEED;
            px3+=(6.0-px3)/SPEED;
            py4+=(-0.5-py4)/SPEED;
            move++;
            if(move==TIME){
                l_num2++;
                move=0;
            }
        }
        if(lips[l_num2]==3){//u
            py+=(2-py)/SPEED;
            px2+=(-2.5-px2)/SPEED;
            px3+=(2.5-px3)/SPEED;
            py4+=(-1.0-py4)/SPEED;
            move++;
            if(move==TIME){
                l_num2++;
                move=0;
            }
        }
        if(lips[l_num2]==4){//e
            py+=(2-py)/SPEED;
            px2+=(-5.5-px2)/SPEED;
            px3+=(5.5-px3)/SPEED;
            py4+=(-1.0-py4)/SPEED;
            move++;
            if(move==TIME){
                l_num2++;
                move=0;
            }
        }
        if(lips[l_num2]==5){//o
            py+=(3.0-py)/SPEED;
            px2+=(-4.0-px2)/SPEED;
            px3+=(4.0-px3)/SPEED;
            py4+=(-1.5-py4)/SPEED;
            move++;
            if(move==TIME){
                l_num2++;
                move=0;
            }
        }
        if(lips[l_num2]==6){//n
            py+=(0.5-py)/SPEED;
            px2+=(-5-px2)/SPEED;
            px3+=(5-px3)/SPEED;
            py4+=(0.5-py4)/SPEED;
            move++;
            if(move==TIME){
                l_num2++;
                move=0;
            }
        }
        if(l_num2==l_num){//終了
            py+=(0.5-py)/SPEED;
            px2+=(-5-px2)/SPEED;
            px3+=(5-px3)/SPEED;
            py4+=(0.5-py4)/SPEED;
            move++;
            if(move==TIME){
                l_num=0;
                l_num2=0;
                move=0;
                si=0;
                for(int i=0;i<30;i++){
                    lips[i]=9;
                }
            }
        }
    }
    
    glBegin(GL_QUADS);
    glNormal3d(0.4, 0.2, 0.7);
    glVertex3d(px-2,py+1.5,pz+0.5);
    glVertex3d(px+2,py+1.5,pz+0.5);
    glVertex3d(px+1,py,pz);
    glVertex3d(px-1,py,pz);
    glEnd();

    glBegin(GL_TRIANGLES);
    glNormal3d(0.7, 0.1, 0.9);
    glVertex3d(px-2,py+1.5,pz+0.5);
    glVertex3d(px-1,py,pz);
    glVertex3d(px2,py2,pz2);
    glEnd();
    
    glBegin(GL_TRIANGLES);
    glNormal3d(0.1, 0.1, 0.5);
    glVertex3d(px+2,py+1.5,pz+0.5);
    glVertex3d(px+1,py,pz);
    glVertex3d(px3,py3,pz3);
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(0.3, 0.2, 0.5);
    glVertex3d(px4,py4,pz4);
    glVertex3d(px2,py2,pz2);
    glVertex3d(px2+2,py2-1,pz2+0.5);
    glVertex3d(px4,py4-2,pz+0.5);
    glEnd();
    
    glBegin(GL_QUADS);
    glNormal3d(-0.1, 0.2, 0.5);
    glVertex3d(px4,py4,pz4);
    glVertex3d(px3,py3,pz3);
    glVertex3d(px3-2,py3-1,pz3+0.5);
    glVertex3d(px4,py4-2,pz4+0.5);
    glEnd();
    
    col[0] = 0.0; col[1] = 0.0; col[2] = 0.0; col[3] = 1.0;
    spe[0] = 0.0; spe[1] = 0.0; spe[2] = 0.0; spe[3] = 1.0;
    shi[0] = 0;
    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col);
    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, col);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spe);
    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shi);
    
    glBegin(GL_QUADS);
    glVertex3d(px-2,py+1.5,pz+0.5);
    glVertex3d(px+2,py+1.5,pz+0.5);
    glVertex3d(px3,py3,pz3);
    glVertex3d(px2,py2,pz2);
    glEnd();
    
    glBegin(GL_POLYGON);
    glVertex3d(px3,py3,pz3);
    glVertex3d(px2,py2,pz2);
    glVertex3d(px2+2,py2-1,pz2+0.5);
    glVertex3d(px4,py4-2,pz4+0.5);
    glVertex3d(px3-2,py3-1,pz3+0.5);
    glEnd();
    
    glPopMatrix();
    
    glutSwapBuffers();
}

void timer(int value)
{
    glutPostRedisplay();
    glutTimerFunc(33, timer, 0);
}

void mouse(int button, int state, int x, int y)
{
    mButton = button; mState = state; mX = x; mY = y;
}

void motion(int x, int y)
{
    if (mButton==GLUT_RIGHT_BUTTON){
        eDegY += (mX-x)*0.1;
        eDegX += (y-mY)*0.1;
    }
    
    else if (mButton==GLUT_LEFT_BUTTON){
        GLfloat winX, winY, winZ;
        GLdouble objX, objY, objZ;
        GLdouble model[16], proj[16];
        GLint view[4];
        
        winX = x;
        winY = winH-y;
        glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
        
        glGetDoublev(GL_MODELVIEW_MATRIX, model);
        glGetDoublev(GL_PROJECTION_MATRIX, proj);
        glGetIntegerv(GL_VIEWPORT, view);
        
        gluUnProject(winX, winY, winZ, model, proj, view, &objX, &objY, &objZ);
    }

    mX = x; mY = y;
}

void keyboard(unsigned char key, int x, int y)
{

    switch (key) {
        case 27:  //ESC
            exit(0);
            break;
            
        case '1':
            if(si==0){
                si=1;
            }
            break;
            
        case '2':
            if(si==1){
                l_num2=l_num;
                move=0;
            }
            break;
            
            
        case 'a':
            if(si==0&&l_num<30){
                lips[l_num]=1;
                l_num++;
            }else if(si==0&&l_num>=30){
                printf("\n発音は30回までです\n");
            }
            break;
            
        case 'i':
            if(si==0&&l_num<30){
                lips[l_num]=2;
                l_num++;
            }else if(si==0&&l_num>=30){
                printf("\n発音は30回までです\n");
            }
            break;
            
        case 'u':
            if(si==0&&l_num<30){
                lips[l_num]=3;
                l_num++;
            }else if(si==0&&l_num>=30){
                printf("\n発音は30回までです\n");
            }
            break;
            
        case 'e':
            if(si==0&&l_num<30){
                lips[l_num]=4;
                l_num++;
            }else if(si==0&&l_num>=30){
                printf("\n発音は30回までです\n");
            }
            break;
            
        case 'o':
            if(si==0&&l_num<30){
                lips[l_num]=5;
                l_num++;
            }else if(si==0&&l_num>=30){
                printf("\n発音は30回までです\n");
            }
            break;
            
        case 'n':
            if(si==0&&l_num<30){
                lips[l_num]=6;
                l_num++;
            }else if(si==0&&l_num>=30){
                printf("\n発音は30回までです\n");
            }
            break;

        default:
            break;
    }
}
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?