OpenGL:如何让“Polyman”的嘴巴张开

时间:2015-10-01 18:40:01

标签: c++ opengl translation polygon

我正在写一个程序,有一个多边形“男人”从屏幕的一侧走到中间,张开嘴,跳起来翻转,降落,闭上嘴,然后离开屏幕。我对如何让小伙子的嘴巴张开有点困惑。我以为我可以创建一个与背景颜色相同的适当大小的三角形,并慢慢地将它转换到他的嘴巴所在的位置。我需要采取哪些步骤才能实现这一目标,我将把代码放在哪里?

    #include<Windows.h>
#include<GL/glut.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>
#include<stdio.h>
#include<iostream>
#include<iomanip>
#include<gl/glut.h>

using namespace std;

//***********************GLOBAL VALUES*********************************************

float theta=00.0; //global angular value for rotation
float scale1=1.0; //global scaling value
float dx=7.0,dy=-3.0;
int frame = 1;

void init(void); //This is a function to initialize the window clear color
void RenderScene(void); //This a function to draw polyman in an opened window
void loadicon(float[],float[],float[],float[], float[], float[]); //Load the polyman icon
void drawicon(float[],float[],float[],float[], float[], float[]); //Draw the icon the two first float for the square and the others for the line
void settrans(float[][3],float,float,float); //Sets the transformation matrix for desired scale, rotation, new pos
float xprime(float,float,float[][3]); //Calculates x' from x and transform
float yprime(float,float,float[][3]); //Calculates y' from y and transform
void transform(float[],float[],float[],float[], float[], float[], float[][3],float[],float[],float[],float[], float[], float[]); //performs the transformation on the icon pattern  
void myidle(void);
void SetupRC(void); //Sets up the clear color
void TimerFunction(int); //This call back function is called each 30ms and changes the location, scale and rotation

//***********************MAIN PROGRAM**********************************************

int main(int argc, char** argv)
{
    //Set up window title
    char header[]="Polyman's journey";
    glutInit(&argc,argv);

    //Set up the display mode with two buffers and RGB colors
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);

    //Initialize window size and position
    glutInitWindowSize(560,440);
    glutInitWindowPosition(140,20);

    //Initialize background color of the window
    SetupRC();

    //Open and label window
    glutCreateWindow(header);
    glutDisplayFunc(RenderScene);
    glutTimerFunc(30,TimerFunction, 1); //Call the TimerFunction each 30s

    //Now draw the scene
    glutMainLoop();
    return 0;
}

//*************************RenderScene Function*************************************

void RenderScene(void)
{
    float xdel=0.25;
    float px[7],py[7],plx[4],ply[4], pl2x[4], pl2y[4];// These variables hold the pattern for the icon square plus line
    float pxp[7],pyp[7],plxp[4],plyp[4], pl2xp[4], pl2yp[4],t[3][3]; //These varables hold the pattern after transformation, t is the transformation matrix

    //clear the window with the current background color
    cout<<"in RenderScene"<<endl;

    //set the current drawing color to white
    glColor3f(1.0,1.0,1.0);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    //set the viewport to the window dimensions
    glViewport(0,0,560,440);

    //Establish the clipping volumn in user units, first clear all the translation matrices
    glOrtho(-7.0,7.0,-7.0,7.0,1.0,-1.0);
    loadicon(px,py,plx,ply, pl2x, pl2y);

    //draw the icon untransformed
    settrans(t,scale1,dx,dy);
    transform(pxp,pyp,plxp,plyp,pl2xp,pl2yp, t,px,py,plx,ply, pl2x, pl2y);

    //clear the window with the background color
    glClear(GL_COLOR_BUFFER_BIT);

    //set the current drawing color to white
    glColor3f(1.0,1.0,1.0);

    //now draw the figure
    drawicon(pxp,pyp,plxp,plyp,pl2xp, pl2yp);
    glEnd();
    glutSwapBuffers();
    return;
}//end of render scene

//************************LOAD ICON FUNCTION***********************************

void loadicon(float px[],float py[],float plx[],float ply[],float pl2x[],float pl2y[]) //Loads the polyman
{
    //Set the coordinates of the square
    px[0]=-0.625   ;    py[0]=0.625      ;
    px[1]=0.625    ;    py[1]=0.625      ;
    px[2]=1.0      ;    py[2]=0.0        ;
    px[3]=0.625    ;    py[3]=-0.625     ;
    px[4]=-0.625   ;    py[4]=-0.625     ;
    px[5]= -1.0    ;    py[5]= 0.0       ;
    px[6]=-0.625   ;    py[6]=0.625      ;

    //set the right foot
    plx[0]=  0.25   ;    ply[0]= -0.625    ;
    plx[1]= 0.25    ;    ply[1]= -0.875    ;
    plx[2]= 0.0    ;    ply[2]= -0.875   ;
    plx[3] = 0.25 ;     ply[3] = -0.875;

    //set the left foot
    pl2x[0]= -0.125 ;    pl2y[0]= -0.375   ;
    pl2x[1]= -0.125 ;    pl2y[1]= -0.875   ;
    pl2x[2]= -0.375 ;    pl2y[2]= -0.875   ;
    pl2x[3]= -0.125 ;    pl2y[3]= -0.875   ;
    return;
} //end of loadicon

//************************FUNCTION DRAWICON***********************************

void drawicon(float pxp[],float pyp[],float plxp[],float plyp[], float pl2xp[], float pl2yp[])
{
    //draw the square icon at the transformed position

    int i;
    cout<<"in drawicon"<<endl;
    glBegin(GL_LINE_STRIP);

    //move to first point in the icon
    glVertex2f(pxp[0],pyp[0]);

    //now draw the rest of the box
    for(i = 1; i <= 6; i++)
    {
        glVertex2f(pxp[i],pyp[i]);
    }
    glEnd();

    //now draw the line
    glBegin(GL_LINES);
    glVertex2f(plxp[0],plyp[0]);
    for (i=1; i <=3; i++)
        {
            glVertex2f(plxp[i],plyp[i]);
        }//glVertex2f(plxp[2],plyp[2]);
    glEnd();

    glBegin(GL_LINES);
    glVertex2f(pl2xp[0], pl2yp[0]);
    for (i=1; i <=3; i++)
    {
        glVertex2f(pl2xp[i], pl2yp[i]);
    }
    glEnd();

    //now fill the rectangle which is made by half of the square

    //set the shading color to green
    glColor3f(0.0,1.0,0.0);
    glShadeModel(GL_FLAT);

    //redraw the polygon
    glBegin(GL_POLYGON);

    //Firts point is where the line intersects the top of the square
    glVertex2f(pxp[0], pyp[0]);
    //rigth corner upper
    glVertex2f(pxp[1],pyp[1]);
    //right corner lower
    glVertex2f(pxp[2],pyp[2]);
    //left intersect
    glVertex2f(pxp[3],pyp[3]);
    glVertex2f(pxp[4],pyp[4]);
    glVertex2f(pxp[5],pyp[5]);
    glVertex2f(pxp[6],pyp[6]);
    return;
} //end of draw icon

//************************FUNCTION SETTRANS***********************************

void settrans(float t[][3],float scale1,float dx,float dy)
{
    cout<<"in settrans"<<endl;
    int i,j;
    float ts,ct,st;
    double theta1;

    //setup identity matrix
    for(i=0;i<=2;i++)
    {
        for(j=0;j<=2;j++)
        {
            t[i][j]=0.0;
            if(i==j) t[i][j]=1.0; 
        }
    }

    //set scale parameters
    if(scale1!=-9.0)
    {
        t[0][0]=scale1;
        t[1][1]=scale1;
    }
    if(theta!=-9.0)
    {
        theta1=(3.1416/180.0)*theta;
        ct=cos(theta1);
        st=sin(theta1);
        ts=t[0][0];
        t[0][0]=ts*ct;
        t[0][1]=ts*st;
        ts=t[1][1];
        t[1][0]=-ts*st;
        t[1][1]=ts*ct;
    }

    //translate the figure

    if((dx+dy) != -18.0)
    {
        t[2][0]=dx;
        t[2][1]=dy;
    }
    return;
}//end of settrans

//************************FUNCTION XPRIME***********************************

float xprime(float x1,float y1, float t[][3])
{
    //this function pultiples the x vector by the transformation matrix
    float xp1;
    xp1=x1*t[0][0]+y1*t[1][0]+t[2][0];
    return xp1;
}

//************************FUNCTION YPRIME***********************************

float yprime(float x1,float y1, float t[][3])
{
    //this function pultiples the y vector by the transformation matrix
    float yp1;
    yp1=x1*t[0][1]+y1*t[1][1]+t[2][1];
    return yp1;
}

//************************FUNCTION TRANSFORM***********************************

void transform(float pxp[],float pyp[],float plxp[],float plyp[],float pl2xp[],float pl2yp[],float t[][3],float px[],float py[],float plx[],float ply[], float pl2x[], float pl2y[])
{
    int i;
    cout<<"in transform"<<endl;

    //transform the figure
    for(i=0;i<=6;i++)
    {
        pxp[i] = xprime(px[i],py[i],t);
        pyp[i] = yprime(px[i],py[i],t);
    }

    //transform the line
    for(i=0;i<=3;i++)
    {
        plxp[i] = xprime(plx[i],ply[i],t);
        plyp[i] = yprime(plx[i],ply[i],t);
    }

    for(i=0;i<=3;i++)
    {
        pl2xp[i] = xprime(pl2x[i],pl2y[i],t);
        pl2yp[i] = yprime(pl2x[i],pl2y[i],t);
    }
    return;
}//end of transform

//************************ FUNCTION SetupRC***********************************

void SetupRC(void)
{
    //sets the clear color of an open window and clears the open window
    //set clear color to green
    glClearColor(0.0,1.0,0.0,1.0);
    return;
}//end of setupRC

//************************ FUNCTION Timer***********************************

void TimerFunction(int value)
{
    //this call back function is called each 30ms and changes the location, scale and rotation 
    static float swc=0.1,sdx=0.1,sdy=0.1;
    switch(frame)
    {
        case 1:
            //theta+=5.0;
            dx-=0.15;
            if(dx<=0.0)
            {
                dx=0.0;
                frame=2;
            }
            break;

        case 2:
            dy+=0.2;
            if(dy>5.0)
            {
                dy=5.0;
                frame=3;
            }
            break;

        case 3:
            theta+=5.0;

            if(theta>360.0)
            {
                frame=4;
                theta=0.0;
                scale1=1.0;
            }
            break;

        case 4:
            dy-=0.2;
            if(dy<=-3.0)
            {
                dy=-3.0;
                frame=5;
            }
            break;

        case 5:
            dx-=0.15;
            //theta+=5.0;
            if(dx<=-8.0) dx=-8.0;
            break;
    }

    //redraw the scene with new coordinate
    glutPostRedisplay();
    glutTimerFunc(33,TimerFunction,1);
}

此外,我们不允许使用OpenGL提供的任何内置翻译,旋转或缩放功能,因为它是我们的第一个任务。感谢所有的帮助,我真的很感激。

0 个答案:

没有答案