Week03
電腦圖學 2023-03-01 Week03
1. 技巧: 用 mouse 幫忙寫作業
2. 主題: 移動 Translate
3. 實作: glTranslatef(x,y,z) 配合 glPushMatrix() glPopMatrix()
4. 問題與回覆Q&A: Blog, 作業
step01-0
介紹上週作業&blog的問題, 介紹今天的上課主題
step01-1
https://jsyeh.org/3dcg10/
下載
- data data.zip
- win32 windows.zip
- glut32.dll
解壓縮
- windows.zip => 下載\windows\Transformation.exe
- data.zip => 下載\windows\data\很多模型檔
執行今天的課本範例 Transformation.exe
(若有閃退,就是 data 解錯目錄了)
執行時, 可移動 x y z 的座標
step01-2
step01-2_了解Translate的意思後,我們從上週的10行GLUT程式出發, 先加glTranslate(x,y,z) 讓它下面的茶壼移動, 再把 glPushMatrix()放前面、glPopMatrix() 放後面, 把它們包起來
- 先把 freeglut 裝好
- File-New-Project, GLUT專案, 命名 week03-1_transalte 專案
- 把 177行的範例刪掉, 改成上週的10行程式
- 加上 glTranslatef(x, y, z) 把茶壼往右移
- 前面加上 glPushMatrix();
- 後面加上 glPopMatrix();
```cpp
///程式碼全刪,換我們上週教的10行
#include <GL/glut.h>
void display()
{
glPushMatrix(); ///備份矩陣
glTranslatef( 0.5, 0, 0 ); ///只有這行?還不夠
glutSolidTeapot( 0.3 );
glPopMatrix(); ///還原矩陣
glutSwapBuffers();
}
int main(int argc, char* argv[] )
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("week03");
glutDisplayFunc(display);
glutMainLoop();
}
```
step02-1
step02-1_想用mouse讓它可以一直動,所以需要研究如何有mouse的函式。先在 main()裡面加上 glutMouseFunc(mouse); 註冊它, 再回到前面寫下 void mouse(int button, int state, int x, int y){ } 裡面則是利用 printf() 來印出值, 認識這些參數。前面要記得 include stdio.h 哦
```cpp
///程式碼全刪,換我們上週教的10行
#include <GL/glut.h>
void display()
{
glPushMatrix(); ///step01-2 備份矩陣
glTranslatef( 0.5, 0, 0 ); ///step01-2 只有這行?還不夠
glutSolidTeapot( 0.3 );
glPopMatrix(); ///step01-2 還原矩陣
glutSwapBuffers();
}
#include <stdio.h>
void mouse(int button, int state, int x, int y)
{ ///step02-1 請 mouse函式幫忙
printf("%d %d %d %d\n", button, state, x, y);
}
int main(int argc, char* argv[] )
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("week03");
glutDisplayFunc(display);
glutMouseFunc(mouse); ///step02-1 請 mouse函式幫忙
glutMainLoop();
}
```
step02-2
step02-2_有了step02-1的mouse的幫忙,我們在最前面先宣告global 變數 float X=0, Y=0; 利用它來傳值。在 void display()裡面, 利用 glTranslatef(X, Y, 0) 來移動到想要的位置。而 void mouse()裡面, 則是換算出 X 及 Y 的座標, 使用減一半、除一半、y負號的技巧。
```cpp
///程式碼全刪,換我們上週教的10行
#include <GL/glut.h>
float X=0, Y=0;///step02-2 利用 global 變數,在函式之間傳值 (大寫的)
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); ///step02-2 清背景
glPushMatrix(); ///step01-2 備份矩陣
glTranslatef( X, Y, 0 ); ///step01-2 只有這行?還不夠
glutSolidTeapot( 0.3 );
glPopMatrix(); ///step01-2 還原矩陣
glutSwapBuffers();
}
///#include <stdio.h> ///step02-1 為了 printf()
void mouse(int button, int state, int x, int y) ///小寫的
{ ///step02-1 請 mouse函式幫忙
X = (x-150)/150.0; ///printf("%d %d %d %d\n", button, state, x, y);
Y = -(y-150)/150.0; ///step02-2 口訣: 減一半、除一半, y負號
}///step02-1 印出來 printf()
int main(int argc, char* argv[] )
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("week03");
glutDisplayFunc(display);
glutMouseFunc(mouse); ///step02-1 請 mouse函式幫忙
glutMainLoop();
}
```
step02-3
step02-3_老師示範 GitHub 的 Gist功能, 只要在 gist.github.com 裡面 + 新增一個不公開的小程式, 便能經由 embedded 的 HTML JavaScript的方法, 把程式用很漂亮的格式,放在你的 blog 裡。只是你要熟 HTML CSS 才能運作順利。
step03-1
step03-1_關於上週出的作業, 其實也可以利用 mouse 來幫忙描點哦。只要在 void mouse() 裡面 if(state==GLUT_DOWN) 再印出你換算出來的座標, 便能幫你寫出程式碼
``cpp
#include <GL/glut.h>
#include <stdio.h>
void display()
{
///glutSolidTeapot( 0.3 );
glBegin(GL_POLYGON);
glVertex2f(-0.268, 0.160);
glVertex2f(-0.304, 0.204);
glVertex2f(-0.332, 0.264);
glVertex2f(-0.352, 0.384);
glVertex2f(-0.344, 0.484);
glVertex2f(-0.308, 0.532);
glVertex2f(-0.236, 0.552);
glVertex2f(-0.204, 0.496);
glVertex2f(-0.204, 0.404);
glVertex2f(-0.204, 0.348);
glVertex2f(-0.180, 0.280);
glVertex2f(-0.156, 0.228);
glVertex2f(-0.156, 0.212);
glVertex2f(-0.152, 0.188);
glEnd();
glBegin(GL_POLYGON);
glVertex2f(0.040, 0.200);
glVertex2f(0.032, 0.248);
glVertex2f(0.028, 0.328);
glVertex2f(0.028, 0.404);
glVertex2f(0.040, 0.480);
glVertex2f(0.064, 0.540);
glVertex2f(0.096, 0.572);
glVertex2f(0.152, 0.616);
glVertex2f(0.208, 0.604);
glVertex2f(0.260, 0.524);
glVertex2f(0.240, 0.468);
glVertex2f(0.192, 0.428);
glVertex2f(0.164, 0.384);
glVertex2f(0.152, 0.328);
glVertex2f(0.148, 0.276);
glVertex2f(0.148, 0.244);
glVertex2f(0.140, 0.212);
glVertex2f(0.140, 0.188);
glEnd();
glBegin(GL_POLYGON);
glVertex2f(-0.196, 0.044);
glVertex2f(-0.188, 0.068);
glVertex2f(-0.112, 0.096);
glVertex2f(-0.060, 0.096);
glVertex2f(-0.048, 0.068);
glVertex2f(-0.088, 0.048);
glVertex2f(-0.140, 0.032);
glVertex2f(-0.188, 0.032);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2f(-0.212, 0.152);
glVertex2f(-0.256, 0.116);
glVertex2f(-0.272, 0.064);
glVertex2f(-0.300, -0.084);
glVertex2f(-0.292, -0.140);
glVertex2f(-0.220, -0.224);
glVertex2f(-0.124, -0.252);
glVertex2f(0.080, -0.260);
glVertex2f(0.156, -0.256);
glVertex2f(0.224, -0.224);
glVertex2f(0.264, -0.160);
glVertex2f(0.288, -0.152);
glVertex2f(0.284, 0.004);
glVertex2f(0.256, 0.092);
glVertex2f(0.232, 0.164);
glVertex2f(0.068, 0.180);
glVertex2f(0.000, 0.192);
glVertex2f(-0.144, 0.176);
glEnd();
glutSwapBuffers();
}
void mouse(int button, int state, int x, int y) ///小寫的
{
float X = (x-250)/250.0;
float Y = -(y-250)/250.0; ///口訣: 減一半、除一半, y負號
if(state==GLUT_DOWN){ ///只有按下mouse,才印出程式,等下要剪貼!
printf(" glVertex2f(%.3f, %.3f);\n", X, Y);
}
}
int main(int argc, char* argv[] )
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(500,500);
glutCreateWindow("week03");
glutDisplayFunc(display);
glutMouseFunc(mouse); ///step02-1 請 mouse函式幫忙
glutMainLoop();
}
```
step03-2
step03-2_畫出中華民國的國旗
```cpp
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
void rect(float x1, float y1, float x2, float y2)
{
glBegin(GL_POLYGON);
glVertex2f(x1,y1); glVertex2f(x1,y2); glVertex2f(x2,y2); glVertex2f(x2, y1);
glEnd();
}
void circle(float x, float y, float r)
{
glBegin(GL_POLYGON);
for(float a=0; a<3.1415926*2; a+=0.01){
glVertex2f(x+r*cos(a), y+r*sin(a)/4*5);
}
glEnd();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0); rect(-1, -1, +1, +1);
glColor3f(0,0,1); rect(-1, +1, 0, 0);
glColor3f(1,1,1); circle(-0.5, +0.5, 0.2);
glutSwapBuffers();
}
int main(int argc, char* argv[] )
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(500,400);
glutCreateWindow("week03");
glutDisplayFunc(display);
glutMainLoop();
}
```
```cpp
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
void rect(float x1, float y1, float x2, float y2)
{
glBegin(GL_POLYGON);
glVertex2f(x1,y1); glVertex2f(x1,y2); glVertex2f(x2,y2); glVertex2f(x2, y1);
glEnd();
}
void circle(float x, float y, float r)
{
glBegin(GL_POLYGON);
for(float a=0; a<3.1415926*2; a+=0.01){
glVertex2f(x+r*cos(a), y+r*sin(a));
}
glEnd();
}
float pinX[12], pinY[12], baseX[12], baseY[12];
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0); rect(-0.9, -0.6, +0.9, +0.6);
glColor3f(0,0,1); rect(-0.9, +0.6, 0, 0);
glColor3f(1,1,1);
for(int i=0; i<12; i++){
float angle = 2*3.1415926*i/12;
pinX[i] = -0.45+cos(angle)*0.9/4;
pinY[i] = 0.30+sin(angle)*0.9/4;
baseX[i] = -0.45+cos(angle-0.2618)*0.9/8*(1+2.0/15);
baseY[i] = 0.30 + sin(angle-0.2618)*0.9/8*(1+2.0/15);
}
for(int i=0; i<12; i++){
glBegin(GL_POLYGON);
glVertex2f(baseX[i], baseY[i]);
glVertex2f(pinX[i], pinY[i]);
glVertex2f(baseX[(i+1)%12], baseY[(i+1)%12]);
glEnd();
}
glColor3f(0,0,1); circle(-0.45, +0.3, 0.9/8*(1+2.0/15));
glColor3f(1,1,1); circle(-0.45, +0.3, 0.9/8);
glutSwapBuffers();
}
int main(int argc, char* argv[] )
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
glutInitWindowSize(800, 800);
glutCreateWindow("week03");
glutDisplayFunc(display);
glutMainLoop();
}
```
step03-3
step03-3_利用Git將今天的程式碼上傳
- 0. 安裝 Git, 開啟 Git Bash
- 1. 進入桌面,用 git clone 下載 2023graphicsa, 再進入 2023graphicsa
- 2. start . 可以開檔案總管, 整理今天的2個程式
- 3. 用 git add . 將修改加入帳冊 (git status 會秀紅色or綠色)
- 4. 用 git commit -m "你的訊息" 來確認、認可你的修改 (要先git config 設定名字及email)
- 5. 用 git push 推送上雲端
沒有留言:
張貼留言