
Youtube:https://www.youtube.com/watch?v=NNkT6gX1CFI
程式碼:
///匯入source裡的glm.h, glm.c, transform.c
#include <GL/glut.h>
#include <stdio.h>
//#include <stdlib.h>
#include<mmsystem.h>
#include "glm.h"///glm外掛
GLMmodel*pmodel=NULL;///glm指標
GLMmodel*pmodel2=NULL;
GLMmodel*pmodel3=NULL;
GLMmodel*pmodel4=NULL;
GLMmodel*pmodel5=NULL;
GLMmodel*pmodel6=NULL;
GLMmodel*pmodel7=NULL;
GLMmodel*pmodel8=NULL;
GLMmodel*pmodel9=NULL;
GLMmodel*pmodel10=NULL;
GLMmodel*pmodel11=NULL;
GLMmodel*pmodel12=NULL;
GLMmodel*pmodel13=NULL;
GLMmodel*pmodel14=NULL;
GLMmodel*pmodel15=NULL;
GLMmodel*pmodel16=NULL;
GLMmodel*pmodel17=NULL;
FILE * fout=NULL;///宣告(output)檔案的指標,一開始是空的
FILE * fin=NULL;///宣告(input)檔案的指標,一開始是空的
float angle[20], angleNew[20], angleOld[20];///準備20個角度的值 (陣列如果宣告在 外面,default都是0)
float oldX, oldY;
int now=0;///用keyboard的數字鍵,來切換關節
void timer(int t)
{
glutTimerFunc(28, timer, t+1);
if(t%10==0)
{
for(int i=0;i<20;i++)
{
angleOld[i]=angleNew[i];
fscanf(fin, "%f", &angleNew[i]);
}
}
float alpha=(t%10)/10.0;
for(int i=0;i<20;i++)
{
angle[i]=alpha*angleNew[i]+(1-alpha)*angleOld[i];
}
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{
if(key=='1') now=1;///用keyboard的數字鍵,來切換關節
if(key=='2') now=2;
if(key=='3') now=3;
if(key=='4') now=4;
if(key=='5') now=5;
if(key=='6') now=6;
if(key=='7') now=7;
if(key=='8') now=8;
if(key=='9') now=9;
if(key=='0') now=10;
if(key=='q') now=11;
if(key=='w') now=12;
if(key=='e') now=13;
if(key=='r') now=14;
if(key=='t') now=15;
if(key=='y') now=16;
if(key=='u') now=17;
if(key=='s' || key=='S')
{
if(fout==NULL) fout=fopen("output.txt", "w+");
///上面這行,只有第一次按s鍵,才會還沒有值,才fopen
///因為第二次按s鍵,fout名花有主,不會再重覆開檔案
for(int i=0; i<20; i++)
{
printf("%.3f ", angle[i]);///把每一個陣列裡的角度,都寫一次
fprintf(fout, "%.3f ", angle[i]);///把每一個陣列裡的角度,都寫一次
}///小心,寫檔 vs. 讀檔,要完全一樣
printf("\n");///最後要印個跳行,才不會畫面亂掉
fprintf(fout,"\n");///最後要印個跳行,才不會畫面亂掉
}///3個角度的值,印到檔案去
if(key=='d' || key=='D')
{
if(fin==NULL) fin=fopen("output.txt", "r");///Now4: 第一次讀檔時,要先開檔
for(int i=0; i<20; i++)
{
fscanf(fin, "%f ", &angle[i]);///Now5: 把每一個陣列裡的角度,都讀一次
printf("%.3f ", angle[i]);///Now5: 順便印一下
}///小心,寫檔 vs. 讀檔,要完全一樣
glutPostRedisplay();///Now4: 重畫畫面
}
if(key=='p'||key=='P')
{
PlaySound("BGM.wav", NULL, SND_ASYNC);
if(fin==NULL) fin=fopen("output.txt", "r");
for(int i=0;i<20;i++)
{
fscanf(fin, "%f", &angleNew[i]);
}
glutTimerFunc(100, timer, 0);
}
}
/*static void resize(int width, int height)
{
const float ar=(float)width/(float)height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAT(0.3, 10, 0.3, 0, 0.1, 0, 0, 1, 0);
}*/
void motion(int x, int y)
{
angle[now]+=(x-oldX);
oldX=x;
glutPostRedisplay();///改角度
}
void mouse(int button, int state, int x, int y)
{
oldX=x; oldY=y;
}
static void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (!pmodel) ///讀入Body模型
{
pmodel = glmReadOBJ("Body.obj");
if (!pmodel) exit(0);
glmUnitize(pmodel);///不管模型原大小,通通變成-1~+1
glmFacetNormals(pmodel);///面的法向量
glmVertexNormals(pmodel, 90.0);///頂點法向量
}
if (!pmodel2) ///讀入ArmRight
{
pmodel2 = glmReadOBJ("ArmRight.obj");
if (!pmodel2) exit(0);
glmUnitize(pmodel2);///不管模型原大小,通通變成-1~+1
glmFacetNormals(pmodel2);///面的法向量
glmVertexNormals(pmodel2, 90.0);///頂點法向量
}
if (!pmodel3) ///讀入HandRight
{
pmodel3 = glmReadOBJ("HandRight.obj");
if (!pmodel3) exit(0);
glmUnitize(pmodel3);///不管模型原大小,通通變成-1~+1
glmFacetNormals(pmodel3);///面的法向量
glmVertexNormals(pmodel3, 90.0);///頂點法向量
}
if (!pmodel4) ///讀入ArmLeft
{
pmodel4 = glmReadOBJ("ArmLeft.obj");
if (!pmodel4) exit(0);
glmUnitize(pmodel4);///不管模型原大小,通通變成-1~+1
glmFacetNormals(pmodel4);///面的法向量
glmVertexNormals(pmodel4, 90.0);///頂點法向量
}
if (!pmodel5) ///讀入HandLeft
{
pmodel5 = glmReadOBJ("HandLeft.obj");
if (!pmodel5) exit(0);
glmUnitize(pmodel5);///不管模型原大小,通通變成-1~+1
glmFacetNormals(pmodel5);///面的法向量
glmVertexNormals(pmodel5, 90.0);///頂點法向量
}
if (!pmodel6)///讀入LegRight
{
pmodel6 = glmReadOBJ("LegRight.obj");
if (!pmodel6) exit(0);
glmUnitize(pmodel6);///不管模型原大小,通通變成-1~+1
glmFacetNormals(pmodel6);///面的法向量
glmVertexNormals(pmodel6, 90.0);///頂點法向量
}
if (!pmodel7)///讀入LegLeft
{
pmodel7 = glmReadOBJ("LegRight.obj");
if (!pmodel7) exit(0);
glmUnitize(pmodel7);///不管模型原大小,通通變成-1~+1
glmFacetNormals(pmodel7);///面的法向量
glmVertexNormals(pmodel7, 90.0);///頂點法向量
}
if (!pmodel8)///讀入EyeRight
{
pmodel8 = glmReadOBJ("EyeRight.obj");
if (!pmodel8) exit(0);
glmUnitize(pmodel8);///不管模型原大小,通通變成-1~+1
glmFacetNormals(pmodel8);///面的法向量
glmVertexNormals(pmodel8, 90.0);///頂點法向量
}
if (!pmodel9)///讀入EyeLeft
{
pmodel9 = glmReadOBJ("EyeLeft.obj");
if (!pmodel9) exit(0);
glmUnitize(pmodel9);///不管模型原大小,通通變成-1~+1
glmFacetNormals(pmodel9);///面的法向量
glmVertexNormals(pmodel9, 90.0);///頂點法向量
}
glPushMatrix();///畫Body
glRotatef(angle[1],0,1,0);
glRotatef(angle[2],1,0,0);
glRotatef(angle[3],0,0,1);
glTranslatef(0,0.1,0);
glRotatef(180,0,1,0);
glScalef(0.6,0.6,0.6);
glmDraw(pmodel, GLM_SMOOTH | GLM_MATERIAL);
glPushMatrix();///畫ArmRight
glTranslatef(0.68,-0.15,0);
glRotatef(angle[4],1,0,0);
glRotatef(angle[5],1,0,0);
glTranslatef(0,-0.35,0);
glRotatef(180,0,1,0);
//glScalef(0.5,0.5,0.5);
glmDraw(pmodel2, GLM_SMOOTH | GLM_MATERIAL);
glPushMatrix();///畫HandRight
glTranslatef(-0.05,-0.1,0);
glRotatef(angle[6],0,1,0);
glTranslatef(0,-0.6,0);
glRotatef(180,0,1,0);
glScalef(0.8,0.8,0.8);
glmDraw(pmodel3, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
glPopMatrix();
glPushMatrix();///畫ArmLeft
glTranslatef(-0.68,-0.15,0);
glRotatef(angle[7],1,0,0);
glRotatef(angle[8],1,0,0);
glTranslatef(0,-0.35,0);
glRotatef(180,0,1,0);
//glScalef(0.5,0.5,0.5);
glmDraw(pmodel4, GLM_SMOOTH | GLM_MATERIAL);
glPushMatrix();///畫HandLeft
glTranslatef(0.05,-0.1,0);
glRotatef(angle[9],0,1,0);
glTranslatef(0,-0.6,0);
glRotatef(180,0,1,0);
glScalef(0.8,0.8,0.8);
glmDraw(pmodel5, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
glPopMatrix();
glPushMatrix();///畫LegRight
glTranslatef(0.78,-1.13,0);
glRotatef(angle[10],1,0,0);
glRotatef(angle[11],0,0,1);
glRotatef(angle[12],0,1,0);
glTranslatef(0,0.07,0);
glScalef(0.9,0.9,0.9);
glmDraw(pmodel6, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
glPushMatrix();///畫LegLeft
glTranslatef(-0.78,-1.13,0);
glRotatef(angle[13],1,0,0);
glRotatef(angle[14],0,0,1);
glRotatef(angle[15],0,1,0);
glTranslatef(0,0.07,0);
glScalef(0.9,0.9,0.9);
glmDraw(pmodel7, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
glPushMatrix();///畫EyeRight
glTranslatef(0.3,0.9,0);
glRotatef(angle[16],0,0,1);
glTranslatef(0,0,0);
glScalef(1.5,1.5,1.5);
glmDraw(pmodel9, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
glPushMatrix();///畫EyeLeft
glTranslatef(-0.3,0.9,0);
glRotatef(angle[17],0,0,1);
glTranslatef(0,0,0);
glScalef(1.5,1.5,1.5);
glmDraw(pmodel8, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
glPopMatrix();
glutSwapBuffers();
}
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[] = { 1.5f, 1.0f, -10.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[] = { 200.0f };
/* Program entry point */
int main(int argc, char *argv[])
{
//PlaySound("BGM.wav", NULL, SND_ASYNC);
glutInit(&argc, argv);
glutInitWindowSize(500,500);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("05160824");
//glutReshapeFunc(resize);
glutDisplayFunc(display);
glClearColor(1,1,1,1);
glutMotionFunc(motion);
glutMouseFunc(mouse);
glutKeyboardFunc(keyboard);
glEnable(GL_DEPTH_TEST);///3D的測試,知遠近
glDepthFunc(GL_LESS);
glEnable(GL_LIGHT0);///打光的函式
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);///打光:光
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);///打光:meterial
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv(GL_FRONT, GL_SHININESS, high_shininess);
//printf("before main loop\n");
glutMainLoop();
//printf("after main loop\n");
}
沒有留言:
張貼留言