去到https://jsyeh.org/3dcg10/
下載 1.[data] 2.[win32] 兩個檔案 並且解壓縮win32
將data丟進解壓縮後的windows
打開projection.exe
1.從哪去看這個模型
2.看模型的哪裡
3.就像用相機拍攝一樣 食指為up向量
每個人拍照角度都不同(有人橫的拍,斜的拍,直的拍)
1.field of view (y方向) 視野的角度
2.aspect ratio 長寬比
3.4.在z方向去決定那些範圍的內容會被投影到方塊內,再壓扁畫出來
打開git bash / cd desktop / git clone https://github.com/ritahsiao/2023graphicsa
去到雲端把2023graphicsa資料夾下載下來
開啟codeblock / file / new / project / glut專案 / 專案名稱week15-1_gluPerspective
選擇桌面後的下一步選擇桌面 / 2023graphicsa / freeglut
glOrtho(-ar*3, ar*3, -1*3, 1*3, -100, +100);(版本2)
static void resize(int width, int height)
{
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);///week15_step02_02切換成投影矩陣
glLoadIdentity();///week15_step02_02還原成單位矩陣
///glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
glOrtho(-ar*3, ar*3, -1*3, 1*3, -100, +100);
glMatrixMode(GL_MODELVIEW);///week15_step02_02切換成Model View矩陣
glLoadIdentity() ;///week15_step02_02還原成單位矩陣
}
static void resize(int width, int height)
{
const float ar = (float) width / (float) height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);///week15_step02_02切換成投影矩陣
glLoadIdentity();///week15_step02_02還原成單位矩陣
///glFrustum(-ar, ar, -1.0, 1.0, 2.0, 100.0);
///glOrtho(-ar*3, ar*3, -1*3, 1*3, -100, +100);
gluPerspective(60,ar,0.01,1000);
///week15_step02_02 角度, 比例,近的,遠的
glMatrixMode(GL_MODELVIEW);///week15_step02_02切換成Model View矩陣
glLoadIdentity() ;///week15_step02_02還原成單位矩陣
}
第二個程式(版本1)
///week15-2_glutLookAt
#include <GL/glut.h>
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glutSolidTeapot(0.3);
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0,0,w,h);///視窗內會看到的2D範圍,圖案跟著視窗放大縮小
float ar= w / (float)h;///aspect ratio長寬比
glMatrixMode(GL_PROJECTION);///先切換到projection矩陣
glLoadIdentity();///矩陣清空,成為單位矩陣(最一開始的矩陣)
gluPerspective(60,ar,0.01,1000);///現在一片空白,因為我們現在在茶壺裡
glMatrixMode(GL_MODELVIEW);///做好後馬上切回到model view矩陣
glLoadIdentity();///矩陣清空,成為單位矩陣(最一開始的矩陣)
gluLookAt(0,0,1, 0,0,0, 0,1,0);
///在0,0,1 看著茶壺0,0,0, up是0,1,0
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("week15");
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
}
///week15-2_glutLookAt
#include <GL/glut.h>
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glutSolidTeapot(0.3);
glutSwapBuffers();
}
void reshape(int w, int h)
{
glViewport(0,0,w,h);///視窗內會看到的2D範圍,圖案跟著視窗放大縮小
float ar= w / (float)h;///aspect ratio長寬比
glMatrixMode(GL_PROJECTION);///先切換到projection矩陣
glLoadIdentity();///矩陣清空,成為單位矩陣(最一開始的矩陣)
gluPerspective(60,ar,0.01,1000);///現在一片空白,因為我們現在在茶壺裡
glMatrixMode(GL_MODELVIEW);///做好後馬上切回到model view矩陣
glLoadIdentity();///矩陣清空,成為單位矩陣(最一開始的矩陣)
gluLookAt(0,0,1, 0,0,0, 0,1,0);
///在0,0,1 看著茶壺0,0,0, up是0,1,0
glutPostRedisplay();
}
float eyeX = 0,eyeY = 0;
void motion(int x, int y)
{
eyeX = (x-150.0)/150.0;
eyeY = (150.0-y)/150.0;
glMatrixMode(GL_MODELVIEW);///做好後馬上切回到model view矩陣
glLoadIdentity();///矩陣清空,成為單位矩陣(最一開始的矩陣)
gluLookAt(eyeX,eyeY,1, 0,0,0, 0,1,0);
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("week15");
glutMotionFunc(motion);
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
}
我用滑鼠將視角從右上方來看茶壺(也可以從左上,中上來看)
第三個程式(開啟final project 裡頭的.cbp檔案)
///要用keyboard mouse來控制茶壺,可存檔,可自己動
///int angle[20];angle[0] angle[1]...用它們來旋轉
#include <stdio.h>
#include <GL/glut.h>
#include "glm.h"
GLMmodel * head =NULL;///week13 step02-1
GLMmodel * body =NULL;
GLMmodel * uparmR =NULL;
GLMmodel * lowarmR =NULL;
int show[4]={1,1,1,1};///week14_step03-1
int ID=3;///0:頭 1:身體 2:上手臂 3:下手臂///week14_step03-1
void keyboard(unsigned char key,int x ,int y)
{
if(key=='0') ID = 0;///week14_step02-2
if(key=='1') ID = 1;///week14_step02-2
if(key=='2') ID = 2;///week14_step02-2
if(key=='3') ID = 3;///week14_step02-2
///if(key=='0') show[0] = !show[0];///!是將1變0,0變1
///if(key=='1') show[1] = !show[1];
///if(key=='2') show[2] = !show[2];
///if(key=='3') show[3] = !show[3];
glutPostRedisplay();
}///將原本的keyboard函式先註解掉
FILE * fout = NULL;///一開始,檔案沒有開 NULL
FILE * fin = NULL;///要讀檔用的指標,一開始也是NULL
float teapotX=0,teapotY=0;
///float angle=0, angle2=0, angle3=0;
float angle[20]={};///week15_step03_1
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glScalef(0.2, 0.2, 0.2);
if(body==NULL)
{
head=glmReadOBJ("model/head.obj");
body=glmReadOBJ("model/body.obj");
uparmR=glmReadOBJ("model/uparmR.obj");
lowarmR=glmReadOBJ("model/lowarmR.obj");
///glmUnitize(body);///這之後還會更改
}
if(ID==0) glColor3f(1,0,0);///選定的,紅色
else glColor3f(1,1,1);///沒選定,白色
if(show[0]) glmDraw(head,GLM_MATERIAL);
if(ID==1) glColor3f(1,0,0);///選定的,紅色
else glColor3f(1,1,1);///沒選定,白色
if(show[1]) glmDraw(body,GLM_MATERIAL);
glPushMatrix();
glTranslatef(-1.426666, +0.320000, 0);///week14_step03-1
glRotatef(angle[2], 0, 0, 1);///week15_step03_1改用陣列
///glTranslatef(teapotX, teapotY, 0);///week14_step03-1
glTranslatef(1.426666, -0.320000, 0);///week14_step03-1
if(ID==2) glColor3f(1,0,0);///選定的,紅色
else glColor3f(1,1,1);///沒選定,白色
if(show[2]) glmDraw(uparmR,GLM_MATERIAL);
glPushMatrix();
glTranslatef(-1.939999, +0.186667, 0);///week14_step03-1
glRotatef(angle[3], 0, 0, 1);///week15_step03_1改用陣列
//glTranslatef(teapotX, teapotY, 0);///week14_step03-1
glTranslatef(1.939999, -0.186667, 0);///week14_step03-1
if(ID==3) glColor3f(1,0,0);///選定的,紅色
else glColor3f(1,1,1);///沒選定,白色
if(show[3]) glmDraw(lowarmR,GLM_MATERIAL);
glPopMatrix();
glPopMatrix();
glPopMatrix();
glColor3f(0,1,0);///week14_step03-1
glutSolidTeapot(0.02);///week14_step03-1
glutSwapBuffers();
}
int oldX=0, oldY=0;
void motion(int x, int y)
{
teapotX += (x - oldX)/150.0;
teapotY -= (y - oldY)/150.0;
angle[ID]+=(x-oldX);///week15_step03_1
///angle= x;
oldX = x;
oldY = y;
printf("glTranslatef(%f, %f, 0);\n",teapotX, teapotY);
glutPostRedisplay();
}
void mouse(int button, int state, int x, int y)
{
if(state==GLUT_DOWN)
{
oldX = x;///teapotX = (x-150)/150.0;
oldY = y;///teapotY = (150-y)/150.0;
///angle = x;///week15_step03_1
///if(fout==NULL) fout=fopen("file4.txt","w");///沒開檔就開檔
///fprintf(fout,"%f %f\n",teapotX, teapotY);///要再存座標
}
display();
}
//void keyboard(unsigned char key, int x, int y)
//{
// if(fin==NULL)///如果檔案還沒fopen(),就開它
// {
// fclose(fout);///要關掉前面mouse開的fout指標
// fin = fopen("file4.txt","r");///沒開檔就開檔
// }
// fscanf(fin, "%f %f",&teapotX, &teapotY);///讀檔
// display();
//}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week13");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);///keyboard要開檔,讀檔
glutMainLoop();
}
第三個程式版本2(可開檔讀檔)
///要用keyboard mouse來控制茶壺,可存檔,可自己動
///int angle[20];angle[0] angle[1]...用它們來旋轉
#include <stdio.h>
#include <GL/glut.h>
#include "glm.h"
GLMmodel * head =NULL;///week13 step02-1
GLMmodel * body =NULL;
GLMmodel * uparmR =NULL;
GLMmodel * lowarmR =NULL;
int show[4]={1,1,1,1};///week14_step03-1
int ID=3;///0:頭 1:身體 2:上手臂 3:下手臂///week14_step03-1
FILE * fout = NULL;///一開始,檔案沒有開 NULL
FILE * fin = NULL;///要讀檔用的指標,一開始也是NULL
float teapotX=0,teapotY=0;
///float angle=0, angle2=0, angle3=0;
float angle[20]={};///week15_step03_1
void keyboard(unsigned char key,int x ,int y)
{
if(key=='0') ID = 0;///week14_step02-2
if(key=='1') ID = 1;///week14_step02-2
if(key=='2') ID = 2;///week14_step02-2
if(key=='3') ID = 3;///week14_step02-2
if(key=='s')
{
if (fout==NULL) fout=fopen("motion.txt","w");
for(int i=0;i<20;i++)///week15_step03_2
{
fprintf(fout,"%.2f ",angle[i]);///week15_step03_2
}
fprintf(fout,"\n");
}
else if(key=='r')
{
if (fin==NULL) fin=fopen("motion.txt","r");
for(int i=0;i<20;i++)///week15_step03_2
{
fscanf(fin,"%f",&angle[i]);///week15_step03_2
}
glutPostRedisplay();
}
///if(key=='0') show[0] = !show[0];///!是將1變0,0變1
///if(key=='1') show[1] = !show[1];
///if(key=='2') show[2] = !show[2];
///if(key=='3') show[3] = !show[3];
glutPostRedisplay();
}///將原本的keyboard函式先註解掉
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glScalef(0.2, 0.2, 0.2);
if(body==NULL)
{
head=glmReadOBJ("model/head.obj");
body=glmReadOBJ("model/body.obj");
uparmR=glmReadOBJ("model/uparmR.obj");
lowarmR=glmReadOBJ("model/lowarmR.obj");
///glmUnitize(body);///這之後還會更改
}
if(ID==0) glColor3f(1,0,0);///選定的,紅色
else glColor3f(1,1,1);///沒選定,白色
if(show[0]) glmDraw(head,GLM_MATERIAL);
if(ID==1) glColor3f(1,0,0);///選定的,紅色
else glColor3f(1,1,1);///沒選定,白色
if(show[1]) glmDraw(body,GLM_MATERIAL);
glPushMatrix();
glTranslatef(-1.426666, +0.320000, 0);///week14_step03-1
glRotatef(angle[2], 0, 0, 1);///week15_step03_1改用陣列
///glTranslatef(teapotX, teapotY, 0);///week14_step03-1
glTranslatef(1.426666, -0.320000, 0);///week14_step03-1
if(ID==2) glColor3f(1,0,0);///選定的,紅色
else glColor3f(1,1,1);///沒選定,白色
if(show[2]) glmDraw(uparmR,GLM_MATERIAL);
glPushMatrix();
glTranslatef(-1.939999, +0.186667, 0);///week14_step03-1
glRotatef(angle[3], 0, 0, 1);///week15_step03_1改用陣列
//glTranslatef(teapotX, teapotY, 0);///week14_step03-1
glTranslatef(1.939999, -0.186667, 0);///week14_step03-1
if(ID==3) glColor3f(1,0,0);///選定的,紅色
else glColor3f(1,1,1);///沒選定,白色
if(show[3]) glmDraw(lowarmR,GLM_MATERIAL);
glPopMatrix();
glPopMatrix();
glPopMatrix();
glColor3f(0,1,0);///week14_step03-1
glutSolidTeapot(0.02);///week14_step03-1
glutSwapBuffers();
}
int oldX=0, oldY=0;
void motion(int x, int y)
{
teapotX += (x - oldX)/150.0;
teapotY -= (y - oldY)/150.0;
angle[ID]+=(x-oldX);///week15_step03_1
///angle= x;
oldX = x;
oldY = y;
printf("glTranslatef(%f, %f, 0);\n",teapotX, teapotY);
glutPostRedisplay();
}
void mouse(int button, int state, int x, int y)
{
if(state==GLUT_DOWN)
{
oldX = x;///teapotX = (x-150)/150.0;
oldY = y;///teapotY = (150-y)/150.0;
///angle = x;///week15_step03_1
///if(fout==NULL) fout=fopen("file4.txt","w");///沒開檔就開檔
///fprintf(fout,"%f %f\n",teapotX, teapotY);///要再存座標
}
display();
}
//void keyboard(unsigned char key, int x, int y)
//{
// if(fin==NULL)///如果檔案還沒fopen(),就開它
// {
// fclose(fout);///要關掉前面mouse開的fout指標
// fin = fopen("file4.txt","r");///沒開檔就開檔
// }
// fscanf(fin, "%f %f",&teapotX, &teapotY);///讀檔
// display();
//}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week13");
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);///keyboard要開檔,讀檔
glutMainLoop();
}
將宣告移到上面
按下r鍵 可播放模型移動座標 讀取motion.txt




















沒有留言:
張貼留言