Class: 專題展示
2018年1月12日 星期五
詠銓_Week17_Note
Class: 專題製作
1.承上進度:
a.上次以完成了點擊發射球以及將由插入球串中
b.這次一開始先解決消除判定,讓同色且超過3顆相連的球可以消除。
c.同色回吸
d.背景及軌道顯示
e.終點製作
f.debug
2.卡關部分:
a.同色回吸,因為球串的前進方式是讓後面的球推著前面的球跑,所以回吸必須找出尾端的
球。但如果球串是多段的話,不能單純地找鏈結串列的尾端
b.debug:有各種bug,不一一贅述,比較大的是回吸時的插入判斷問題
3.解決問題:
a.將球串的鏈結串列分成順序以及相連的雙向串列,順序可以記錄下一顆球,相連的雙向鏈
結串列只記錄有相連的前後的球,所以要回吸的話只要找到該串球鏈的尾端,再用一開始
的方法,用後面推前面的球就可以往回吸。
b.因為軌道的位置判斷中有用到速度,但回吸時速度是反向,所以造成判斷錯誤,所以將軌
道的位置判斷全部改成用位置來判斷,例如用當時的x座標算出y座標,而不用到速度。
1.承上進度:
a.上次以完成了點擊發射球以及將由插入球串中
b.這次一開始先解決消除判定,讓同色且超過3顆相連的球可以消除。
c.同色回吸
d.背景及軌道顯示
e.終點製作
f.debug
2.卡關部分:
a.同色回吸,因為球串的前進方式是讓後面的球推著前面的球跑,所以回吸必須找出尾端的
球。但如果球串是多段的話,不能單純地找鏈結串列的尾端
b.debug:有各種bug,不一一贅述,比較大的是回吸時的插入判斷問題
3.解決問題:
a.將球串的鏈結串列分成順序以及相連的雙向串列,順序可以記錄下一顆球,相連的雙向鏈
結串列只記錄有相連的前後的球,所以要回吸的話只要找到該串球鏈的尾端,再用一開始
的方法,用後面推前面的球就可以往回吸。
b.因為軌道的位置判斷中有用到速度,但回吸時速度是反向,所以造成判斷錯誤,所以將軌
道的位置判斷全部改成用位置來判斷,例如用當時的x座標算出y座標,而不用到速度。
詠銓_Week16_Note
Class: 專題製作
1.承上進度:
a.上次以完成了砲管以及球串軌道的製作
b.這次一開始先用Timer定速,讓軌道速度能一致。
c.接著寫mouse函式,使得在點擊左鍵時能將砲管中的球發射。
d.為了讓 c. 方便製作,將砲管也寫成物件,當中包含了發射球跟準備球。
e.接著想辦法讓發射出去的球插入球串。
2.卡關部分:
a.如何記錄發射出去的球與此球的動畫?
b.如何顯示插入球串的動畫?
3.解決問題:
a.另寫了一個freeball的結構,為一個鏈結串列,只要發射一顆球,就把該球保存到一個節點
中,解決了一次多顆球在畫面上的問題,也方便動畫呈現。
b.準備了碰撞偵測函式、判斷插入方向函式、插入位置設定函式等來輔助freeball插入ballist
的動作。
1.承上進度:
a.上次以完成了砲管以及球串軌道的製作
b.這次一開始先用Timer定速,讓軌道速度能一致。
c.接著寫mouse函式,使得在點擊左鍵時能將砲管中的球發射。
d.為了讓 c. 方便製作,將砲管也寫成物件,當中包含了發射球跟準備球。
e.接著想辦法讓發射出去的球插入球串。
2.卡關部分:
a.如何記錄發射出去的球與此球的動畫?
b.如何顯示插入球串的動畫?
3.解決問題:
a.另寫了一個freeball的結構,為一個鏈結串列,只要發射一顆球,就把該球保存到一個節點
中,解決了一次多顆球在畫面上的問題,也方便動畫呈現。
b.準備了碰撞偵測函式、判斷插入方向函式、插入位置設定函式等來輔助freeball插入ballist
的動作。
詠銓_Week15_Note
Class: 專題製作
1.專題目標:祖瑪遊戲 參考資料:https://www.youtube.com/watch?v=-Ou5Bco1sHM
2.開始製作:
a. 首先參考 freeglut 的原始碼,畫出一個砲管當作球的發射器(原遊戲中的青蛙),如下圖

b.接著查詢資料,找到 glutPassiveMotionFunc 函式,可以吃滑鼠座標。再自行撰寫函式使得
砲管可以跟著滑鼠的位置旋轉。

c.接著為了方便,自行寫了一個 Ball 的物件,方便之後撰寫功能的時候使用

d.再來,實作一串球的軌道。
3.第一個卡關:軌道製作
a.原因:一開始用三角函數模擬,球的速度為當時位置的一次微分。而這雖然使球可以順利
的在軌道上運動,但是會因為速度不同而有斷開的情況。
b.解決:賦予第一顆球較快的速度,再依序檢查每顆球,如果前一顆球與自己重疊,則再多
移動幾次,直到與前一顆球分開為止。
1.專題目標:祖瑪遊戲 參考資料:https://www.youtube.com/watch?v=-Ou5Bco1sHM
2.開始製作:
a. 首先參考 freeglut 的原始碼,畫出一個砲管當作球的發射器(原遊戲中的青蛙),如下圖

b.接著查詢資料,找到 glutPassiveMotionFunc 函式,可以吃滑鼠座標。再自行撰寫函式使得
砲管可以跟著滑鼠的位置旋轉。

c.接著為了方便,自行寫了一個 Ball 的物件,方便之後撰寫功能的時候使用

d.再來,實作一串球的軌道。
3.第一個卡關:軌道製作
a.原因:一開始用三角函數模擬,球的速度為當時位置的一次微分。而這雖然使球可以順利
的在軌道上運動,但是會因為速度不同而有斷開的情況。
b.解決:賦予第一顆球較快的速度,再依序檢查每顆球,如果前一顆球與自己重疊,則再多
移動幾次,直到與前一顆球分開為止。
2017年12月14日 星期四
詠銓_Week14_Note
詠銓_Week13_Note
Class: HSB
1.在圖學中,除了RGB的色系之外,還有其他種色系,其中一種叫做HSB的色系。
2.我們這次用processing 中提供的HSB來實作
3.打開processing,輸入以下程式碼
size(255, 255);
colorMode(HSB, 255); //使用HSB色系
for(int x = 0; x<255; x++){
for(int y = 0; y<255; y++){
stroke(x, y, 255);
point(x, y);
}
}
Note:
HSB的顏色為(Hue, Saturation, Brightness) //色相,飽和度,明度
4.執行結果如下

Class: Timer 控制
1.因為在每台電腦的display函式的執行頻率不一,所以如果要定速來顯示動畫效果,要使用Timer來實作。
2.Timer實作如以下程式碼:
int main(){
/******code******/
glutTimerFunc(500, timer, 0); //過了500ms後,呼叫Timer副程式
/******code******/
}
void timer(int t)
{
/******code******/ //執行你要定速的程式碼
glutTimerFunc(100, timer, t+1); //過了100ms後,再呼叫一次Timer副程式
glutPostRedisplay();
}
Note:
因為每過一段時間都會呼叫Timer副程式,所以Timer裡面的程式碼就會每過一段時間就會執
行,而有定速的效果。
3.如此即可定速
1.在圖學中,除了RGB的色系之外,還有其他種色系,其中一種叫做HSB的色系。
2.我們這次用processing 中提供的HSB來實作
3.打開processing,輸入以下程式碼
size(255, 255);
colorMode(HSB, 255); //使用HSB色系
for(int x = 0; x<255; x++){
for(int y = 0; y<255; y++){
stroke(x, y, 255);
point(x, y);
}
}
Note:
HSB的顏色為(Hue, Saturation, Brightness) //色相,飽和度,明度
4.執行結果如下

Class: Timer 控制
1.因為在每台電腦的display函式的執行頻率不一,所以如果要定速來顯示動畫效果,要使用Timer來實作。
2.Timer實作如以下程式碼:
int main(){
/******code******/
glutTimerFunc(500, timer, 0); //過了500ms後,呼叫Timer副程式
/******code******/
}
void timer(int t)
{
/******code******/ //執行你要定速的程式碼
glutTimerFunc(100, timer, t+1); //過了100ms後,再呼叫一次Timer副程式
glutPostRedisplay();
}
Note:
因為每過一段時間都會呼叫Timer副程式,所以Timer裡面的程式碼就會每過一段時間就會執
行,而有定速的效果。
3.如此即可定速
2017年12月10日 星期日
詠銓_Week12_Note
Class:讀openGL程式碼
1.在moodle下載老師準備的 myGL_Frustrum221_MultiView_2012_1221程式碼
2.開啟一個新的openGL專案,移除本來的檔案新增下載的程式碼

3.按編譯,如果有錯誤訊息,逐條處理。
Note: 此程式的錯誤訊息有:
(a)M_PI,去Compiler裡面取消 C++11 ISO 的勾選,即可使用此參數
(b)此為舊的openGL ,須在 int main() 括弧裡面加 int argc, char *argv[],並在主程式裡面加
glutInit(&argc, argv);
4.編譯成功

Class: Model
1.下載P語言,執行
2.新增兩個程式庫

3.打開範例 viewer2D ,尋找讀取模型相關的程式碼。
Class: Scene
1.打開範例 Simple ,尋找場景相關程式碼。
Note:
a.Scene 的概念類似資料結構中的"樹",也就是說這個場景會連結許多子樹。
1.在moodle下載老師準備的 myGL_Frustrum221_MultiView_2012_1221程式碼
2.開啟一個新的openGL專案,移除本來的檔案新增下載的程式碼

3.按編譯,如果有錯誤訊息,逐條處理。
Note: 此程式的錯誤訊息有:
(a)M_PI,去Compiler裡面取消 C++11 ISO 的勾選,即可使用此參數
(b)此為舊的openGL ,須在 int main() 括弧裡面加 int argc, char *argv[],並在主程式裡面加
glutInit(&argc, argv);
4.編譯成功

Class: Model
1.下載P語言,執行
2.新增兩個程式庫

3.打開範例 viewer2D ,尋找讀取模型相關的程式碼。
Class: Scene
1.打開範例 Simple ,尋找場景相關程式碼。
Note:
a.Scene 的概念類似資料結構中的"樹",也就是說這個場景會連結許多子樹。
2017年11月23日 星期四
詠銓_Week11_Note
Class: 播放音樂
1.開啟一個 Glut 專案,加入以下程式碼即可撥放.wav檔的音樂
#include <mmsystem.h> //include系統的多媒體涵式庫
PlaySoundA("file.wav", NULL, SND_ASYNC); //寫在main,
//播放("檔名.wav", 在哪裡, 同步播放)
2.接著是.mp3檔的音樂檔,先下載CMP3_MCI.h
3.一樣開啟一個專案,打入以下程式碼:
#include <stdio.h>
#include "CMP3_MCI.h" //使用外掛,可在FB下載
CMP3_MCI mp3;
int main()
{
mp3.Load("file.mp3"); //讀入 mp3檔
mp3.Play(); //Play播放mp3檔
printf("現在在待輸入a\n");
int a;
scanf("%d", &a); //等待輸入時,程式還沒結束
}
即可撥放.mp3音樂
Note: scanf 在此的功用是讓程式等待輸入,所以程式尚未結束,音樂就不會停下來
4.在 processing (Java) 中播放音樂,先開啟 processing
5.接著在選單中加入涵式庫,選擇 Minim

6.等他下載完後,輸入以下程式碼:
import ddf.minim.*;
Minim minim;
AudioPlayer player;
void setup(){
minim = new Minim(this);
player = minim.loadFile("file.mp3");
player.play();
}
void draw(){
}
即可撥放音樂
1.開啟一個 Glut 專案,加入以下程式碼即可撥放.wav檔的音樂
#include <mmsystem.h> //include系統的多媒體涵式庫
PlaySoundA("file.wav", NULL, SND_ASYNC); //寫在main,
//播放("檔名.wav", 在哪裡, 同步播放)
2.接著是.mp3檔的音樂檔,先下載CMP3_MCI.h
3.一樣開啟一個專案,打入以下程式碼:
#include <stdio.h>
#include "CMP3_MCI.h" //使用外掛,可在FB下載
CMP3_MCI mp3;
int main()
{
mp3.Load("file.mp3"); //讀入 mp3檔
mp3.Play(); //Play播放mp3檔
printf("現在在待輸入a\n");
int a;
scanf("%d", &a); //等待輸入時,程式還沒結束
}
即可撥放.mp3音樂
Note: scanf 在此的功用是讓程式等待輸入,所以程式尚未結束,音樂就不會停下來
4.在 processing (Java) 中播放音樂,先開啟 processing
5.接著在選單中加入涵式庫,選擇 Minim

6.等他下載完後,輸入以下程式碼:
import ddf.minim.*;
Minim minim;
AudioPlayer player;
void setup(){
minim = new Minim(this);
player = minim.loadFile("file.mp3");
player.play();
}
void draw(){
}
即可撥放音樂
詠銓_Week10_Note
Class: Android 程式
1.先下載 processing 程式
2.點選右上角的選單(預設是Java)
3.選擇 Android Mode 之後選 Install,即可編寫 Android 程式

4.範例程式: greenperple:
void setup(){
fullScreen(); //全螢幕
}
void draw(){
if(mousePressed)background(255, 0, 255); 點螢幕時,背景色變成紫色
else background(0, 255, 0); 背景色綠色
}
Note:
1.只要將 Android 手機用傳輸線插進電腦的USB孔,讓 processing 偵測到就可以在手機上建立執行檔看執行結果
2.如果沒有 Android 手機,則可以使用選單裡的 "Run in Emulator" 則可以在模擬器上執行
1.先下載 processing 程式
2.點選右上角的選單(預設是Java)
3.選擇 Android Mode 之後選 Install,即可編寫 Android 程式

4.範例程式: greenperple:
void setup(){
fullScreen(); //全螢幕
}
void draw(){
if(mousePressed)background(255, 0, 255); 點螢幕時,背景色變成紫色
else background(0, 255, 0); 背景色綠色
}
Note:
1.只要將 Android 手機用傳輸線插進電腦的USB孔,讓 processing 偵測到就可以在手機上建立執行檔看執行結果
2.如果沒有 Android 手機,則可以使用選單裡的 "Run in Emulator" 則可以在模擬器上執行
2017年11月14日 星期二
詠銓_Week09_Note
Class:Bump Mapping
1.這次的主題是要介紹凹凸面的貼圖。首先,點開https://www.openprocessing.org/sketch/249457 網頁。可以看到一個立方體,他的表面是凹凸的所以看起來比較真實,這就是Bump Mapping
2.要做到此效果的關鍵在於每個物體表面的法向量,當法向量不一致,有許多方向時,光的反射就方向不一,自然感覺就不會很光滑。
3.接著我們研讀此網站的程式碼,並介紹新的編譯環境:processing.exe
4.上面的程式碼直觀好懂,例如:打rect(10,10,50,50);就會出現一個視窗在座標(10,10)的地方有一個長方形50*50的長方形。

5.也可以載入圖檔:先把圖檔拖曳至視窗中,並輸入以下程式碼
PImage img = loadImage("檔名");//讀檔
size(200, 200);//開啟200*200視窗
image(img, 0,0, 200,200);//在(0,0)座標印出200*200大小的img

6.課堂上我們利用這個簡易的編譯環境開發了一個馬力歐的基礎程式

1.這次的主題是要介紹凹凸面的貼圖。首先,點開https://www.openprocessing.org/sketch/249457 網頁。可以看到一個立方體,他的表面是凹凸的所以看起來比較真實,這就是Bump Mapping
2.要做到此效果的關鍵在於每個物體表面的法向量,當法向量不一致,有許多方向時,光的反射就方向不一,自然感覺就不會很光滑。
3.接著我們研讀此網站的程式碼,並介紹新的編譯環境:processing.exe
4.上面的程式碼直觀好懂,例如:打rect(10,10,50,50);就會出現一個視窗在座標(10,10)的地方有一個長方形50*50的長方形。

5.也可以載入圖檔:先把圖檔拖曳至視窗中,並輸入以下程式碼
PImage img = loadImage("檔名");//讀檔
size(200, 200);//開啟200*200視窗
image(img, 0,0, 200,200);//在(0,0)座標印出200*200大小的img

6.課堂上我們利用這個簡易的編譯環境開發了一個馬力歐的基礎程式

2017年11月6日 星期一
詠銓_Week08_Note
Class: Texture
1.先從moodle下載openCV2.1,安裝
Note: 注意!PATH請選第3個: Add OpenCV to the system PATH for current user
2.打開codeblocks開起Console application專案

3.打入以下程式碼
#include<opencv/highgui.h>
int main()
{
IplImage *img = cvLoadImage("earth.jpg");
cvNamedWindow("hello opencv");
cvShowImage("hello opencv", img);
cvWaitKey(0);
return 0;
}
4.執行,發現error,找不到 opencv/highgui.h

4.為了解決此問題,在專案點右鍵,點Build option,點選Search directories

5.分別在compiler和linker中增加C:\OpenCV2.1\include及C:\OpenCV2.1\lib


6.接著點Linker settings中增加cv210, cxcore210, 及highgui210

7.設定完後,執行如圖

Note: 記得要有圖片檔在專案資料夾中
8.接著打開一個GLUT專案,同樣在此專案上設定上述設定,則此專案即可執行openCV的程式碼

9.接著想要做出一個會轉動的地球,首先我們重寫GLUT專案,先寫出3D圖形的基本框架。

Note:記得此專案也要如先前一樣設定openCV,且要多#include <opencv/cv.h>
10.接著準備貼圖副程式,程式碼如下:
int myTexture(char *filename)
{
IplImage * img = cvLoadImage(filename); ///OpenCV讀圖
cvCvtColor(img,img, CV_BGR2RGB); ///OpenCV轉色彩 (需要cv.h)
glEnable(GL_TEXTURE_2D); ///1. 開啟貼圖功能
GLuint id; ///準備一個 unsigned int 整數, 叫 貼圖ID
glGenTextures(1, &id); /// 產生Generate 貼圖ID
glBindTexture(GL_TEXTURE_2D, id); ///綁定bind 貼圖ID
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
/// 貼圖參數, 超過包裝的範圖T, 就重覆貼圖
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
/// 貼圖參數, 超過包裝的範圖S, 就重覆貼圖
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/// 貼圖參數, 放大時的內插, 用最近點
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
/// 貼圖參數, 縮小時的內插, 用最近點
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height,
0, GL_RGB, GL_UNSIGNED_BYTE, img->imageData);
return id;
}
11.為了能讓地球自轉,我們先準備全域變數:
float angle=0;
接著準備一個timer副程式如下:
void timer(int t)
{
glutTimerFunc(20, timer, 0);/// 1000 msec 50fps:20msec
angle+=1;///隨著時間轉動角度增加
glutPostRedisplay();
}
12.接著初始化貼圖副程式,程式碼如下
GLUquadric * quad;
GLuint id;
void myInit()
{
quad = gluNewQuadric(); ///用剛才宣告的quad變數,將2D座標轉到2次曲面的座標上
id = myTexture("earth.jpg"); ///將貼圖副程式回傳的貼圖ID直送給全域變數id
}
Note:這個id變數可再多張貼圖的時候依照id的值用glBindTexture(GL_TEXTURE_2D, id); 綁定
不同的id來更換貼圖。
13.而這次的display()函式為:
void display()
{
glEnable(GL_DEPTH_TEST); ///要啟動 Detph Test 深度值的測試,3D顯示才正確
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(90, 1,0,0);
glRotatef(angle, 0,0,1);//依Z軸轉angle的角度,angle會隨時間增加,有自轉效果
gluQuadricTexture(quad, 1);
gluSphere(quad, 1, 30, 30);
glPopMatrix();
glFlush();
}
14.最後完成主程式:
int main(int argc, char**argv)
{
glutInit(&argc, argv);
glutCreateWindow("3D");
glutDisplayFunc(display);
glutTimerFunc(0, timer, 0);
myInit(); ///初始化 把貼圖準備好 前面OpenCV 2行, 後面 OpenGL 9行
glutMainLoop();
}
15.執行結果如圖

1.先從moodle下載openCV2.1,安裝
Note: 注意!PATH請選第3個: Add OpenCV to the system PATH for current user
2.打開codeblocks開起Console application專案

3.打入以下程式碼
#include<opencv/highgui.h>
int main()
{
IplImage *img = cvLoadImage("earth.jpg");
cvNamedWindow("hello opencv");
cvShowImage("hello opencv", img);
cvWaitKey(0);
return 0;
}
4.執行,發現error,找不到 opencv/highgui.h

4.為了解決此問題,在專案點右鍵,點Build option,點選Search directories

5.分別在compiler和linker中增加C:\OpenCV2.1\include及C:\OpenCV2.1\lib


6.接著點Linker settings中增加cv210, cxcore210, 及highgui210

7.設定完後,執行如圖

Note: 記得要有圖片檔在專案資料夾中
8.接著打開一個GLUT專案,同樣在此專案上設定上述設定,則此專案即可執行openCV的程式碼

9.接著想要做出一個會轉動的地球,首先我們重寫GLUT專案,先寫出3D圖形的基本框架。

Note:記得此專案也要如先前一樣設定openCV,且要多#include <opencv/cv.h>
10.接著準備貼圖副程式,程式碼如下:
int myTexture(char *filename)
{
IplImage * img = cvLoadImage(filename); ///OpenCV讀圖
cvCvtColor(img,img, CV_BGR2RGB); ///OpenCV轉色彩 (需要cv.h)
glEnable(GL_TEXTURE_2D); ///1. 開啟貼圖功能
GLuint id; ///準備一個 unsigned int 整數, 叫 貼圖ID
glGenTextures(1, &id); /// 產生Generate 貼圖ID
glBindTexture(GL_TEXTURE_2D, id); ///綁定bind 貼圖ID
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
/// 貼圖參數, 超過包裝的範圖T, 就重覆貼圖
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
/// 貼圖參數, 超過包裝的範圖S, 就重覆貼圖
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
/// 貼圖參數, 放大時的內插, 用最近點
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
/// 貼圖參數, 縮小時的內插, 用最近點
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->width, img->height,
0, GL_RGB, GL_UNSIGNED_BYTE, img->imageData);
return id;
}
11.為了能讓地球自轉,我們先準備全域變數:
float angle=0;
接著準備一個timer副程式如下:
void timer(int t)
{
glutTimerFunc(20, timer, 0);/// 1000 msec 50fps:20msec
angle+=1;///隨著時間轉動角度增加
glutPostRedisplay();
}
12.接著初始化貼圖副程式,程式碼如下
GLUquadric * quad;
GLuint id;
void myInit()
{
quad = gluNewQuadric(); ///用剛才宣告的quad變數,將2D座標轉到2次曲面的座標上
id = myTexture("earth.jpg"); ///將貼圖副程式回傳的貼圖ID直送給全域變數id
}
Note:這個id變數可再多張貼圖的時候依照id的值用glBindTexture(GL_TEXTURE_2D, id); 綁定
不同的id來更換貼圖。
13.而這次的display()函式為:
void display()
{
glEnable(GL_DEPTH_TEST); ///要啟動 Detph Test 深度值的測試,3D顯示才正確
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(90, 1,0,0);
glRotatef(angle, 0,0,1);//依Z軸轉angle的角度,angle會隨時間增加,有自轉效果
gluQuadricTexture(quad, 1);
gluSphere(quad, 1, 30, 30);
glPopMatrix();
glFlush();
}
14.最後完成主程式:
int main(int argc, char**argv)
{
glutInit(&argc, argv);
glutCreateWindow("3D");
glutDisplayFunc(display);
glutTimerFunc(0, timer, 0);
myInit(); ///初始化 把貼圖準備好 前面OpenCV 2行, 後面 OpenGL 9行
glutMainLoop();
}
15.執行結果如圖

2017年10月26日 星期四
詠銓_Week07_Note
Class: Mouse-Lighting
1.這次的課程是要用滑鼠改變光源。首先打開glut專案,找到lighting相關的程式碼
2.其中light_position是表示光的位址,既然我們要用滑鼠位置代表光源,所以我們使用
glutMotionFunc(motion); 來表示滑鼠位置的改變。
Note:
motion副程式如下:
2017年10月22日 星期日
詠銓_Week06_Note
Class:Lighting
1.從moodle下載week05的專案,執行後可知道會出現一個全白的圖。

2.接著打開Transformation的source code,搜尋light的相關程式碼,將其複製到此專案檔。執行

3.我們可以看到此執行解果破圖了,於是將原始碼的深度測試複製進來,執行後發現沒有畫面,這是因為此圖是背對著你,而光從前面打,所以改變打光的位置,變成從後面打,就可以出現一個背對著我們的人物了。

Note:
a.打光程式碼如下:
GLfloat pos[] = { 0.0, 0.0, -1.0, 0.0 }; //打光的位置
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
b.深度測試程式碼:
glEnable(GL_DEPTH_TEST);
Note:
a.rotateX, rotateY , rotateZ 為全域變數,可以讓我們在輸入時在對應軸作旋轉
b.但是程式並不能及時轉動,所以要在最後加glutPostRedisplay(); 讓系統重畫圖形
c.此時會動到圖形的座標,所以在display副程式中加入glPushMatrix(); glPopMatrix();
3.只要更動副程式,我們就可以得到我們想要的各種鍵盤控制
Class: Mouse
1.接著是滑鼠控制,滑鼠控制與鍵盤控制大同小異,我們一樣是呼叫函式且寫個可以讓我們確認輸入的副程式,如圖

Note:
a.滑鼠控制程式碼如下:
glutMouseFunc(mouse);// glut的滑鼠控制,連結到mouse副程式
mouse(int buttom, int state, int x, int y)// 副程式,裡面決定了滑鼠輸入時對應的動作
b.此時副程式中的內容為printf("bottom = %d, state = %d, (%d, %d)\n", buttom, state, x, y);所以
可以如圖印出輸入座標、左右中鍵及當時狀態
2.跟鍵盤控制不同的是,如果我們要依照滑鼠的動作而有對應的效果,我們需要再多呼叫一個副程式glutMotionFunc(motion); ,此副程式可以在滑鼠有動作時執行相應的效果
3.接著我們用這兩個副程式達到下面的效果
壓下滑鼠橫向滑動時,圖形繞著Y軸轉
壓下滑鼠縱向滑動時,圖形繞著X軸轉
程式碼如下:
void mouse(int buttom, int state, int x, int y)
{
if(state == GLUT_DOWN)//當壓下滑鼠按鍵
{
oldX = x; oldY = y;//設定舊座標為此時座標
}
}
void motion(int x, int y)
{
rotateY += -(x-oldX);//對著Y軸旋轉滑鼠的橫向移動量
rotateX += -(y-oldY);//對著X軸旋轉滑鼠的縱向移動量
oldX = x; oldY = y;//設定舊座標為此時座標
glutPostRedisplay();//重畫
}
Note:
a.rotateX, rotateY , rotateZ 一樣為全域變數,可以讓我們在對應軸作旋轉
b.但是程式並不能及時轉動,所以一樣要在最後加glutPostRedisplay(); 讓系統重畫圖形
c.此時會動到圖形的座標,所以在display副程式中加入glPushMatrix(); glPopMatrix();
d.經過測試後發現圖背對我們應該是座標相反了,所以在移動量那邊加負號,才會如期轉動
1.從moodle下載week05的專案,執行後可知道會出現一個全白的圖。

2.接著打開Transformation的source code,搜尋light的相關程式碼,將其複製到此專案檔。執行

3.我們可以看到此執行解果破圖了,於是將原始碼的深度測試複製進來,執行後發現沒有畫面,這是因為此圖是背對著你,而光從前面打,所以改變打光的位置,變成從後面打,就可以出現一個背對著我們的人物了。

Note:
a.打光程式碼如下:
GLfloat pos[] = { 0.0, 0.0, -1.0, 0.0 }; //打光的位置
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, pos);
b.深度測試程式碼:
glEnable(GL_DEPTH_TEST);
Class: Keyboard
1.接著引入鍵盤控制,為了確認程式可以收到我們的輸入,我們在副程式中將鍵盤的輸入顯示於螢幕(包含此時滑鼠的座標)。
Note:
a.鍵盤控制程式碼如下:
glutKeyboardFunc(keybord);// glut的鍵盤控制,連結到keyboard副程式
keyboard(unsigned char key, int x, int y)// 副程式,裡面決定了鍵盤輸入時對應的動作
b.此時副程式中的內容為printf("%c (%d, %d)\n", key, x, y);所以可以如圖印出輸入及座標
a.鍵盤控制程式碼如下:
glutKeyboardFunc(keybord);// glut的鍵盤控制,連結到keyboard副程式
keyboard(unsigned char key, int x, int y)// 副程式,裡面決定了鍵盤輸入時對應的動作
b.此時副程式中的內容為printf("%c (%d, %d)\n", key, x, y);所以可以如圖印出輸入及座標
2.接著我們將副程式的內容更改為:
輸入'1'時,繞著x軸轉
輸入'2'時,繞著y軸轉
輸入'3'時,繞著z軸轉
此時副程式如下:
void keybord(unsigned char key, int x, int y)
{
if(key == '1') rotateX++;//輸入1時,rotateX加1
if(key == '2') rotateY++;//輸入2時,rotateY加1
if(key == '3') rotateZ++;//輸入3時,rotateZ加1
glutPostRedisplay();//重畫
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(rotateX, 1, 0, 0);//對X軸旋轉rotateX度
glRotatef(rotateY, 0, 1, 0);//對Y軸旋轉rotateY度
glRotatef(rotateZ, 0, 0, 1);//對Z軸旋轉rotateZ度
drawmodel();
glPopMatrix();
glutSwapBuffers();
}
a.rotateX, rotateY , rotateZ 為全域變數,可以讓我們在輸入時在對應軸作旋轉
b.但是程式並不能及時轉動,所以要在最後加glutPostRedisplay(); 讓系統重畫圖形
c.此時會動到圖形的座標,所以在display副程式中加入glPushMatrix(); glPopMatrix();
3.只要更動副程式,我們就可以得到我們想要的各種鍵盤控制
Class: Mouse
1.接著是滑鼠控制,滑鼠控制與鍵盤控制大同小異,我們一樣是呼叫函式且寫個可以讓我們確認輸入的副程式,如圖

Note:
a.滑鼠控制程式碼如下:
glutMouseFunc(mouse);// glut的滑鼠控制,連結到mouse副程式
mouse(int buttom, int state, int x, int y)// 副程式,裡面決定了滑鼠輸入時對應的動作
b.此時副程式中的內容為printf("bottom = %d, state = %d, (%d, %d)\n", buttom, state, x, y);所以
可以如圖印出輸入座標、左右中鍵及當時狀態
2.跟鍵盤控制不同的是,如果我們要依照滑鼠的動作而有對應的效果,我們需要再多呼叫一個副程式glutMotionFunc(motion); ,此副程式可以在滑鼠有動作時執行相應的效果
3.接著我們用這兩個副程式達到下面的效果
壓下滑鼠橫向滑動時,圖形繞著Y軸轉
壓下滑鼠縱向滑動時,圖形繞著X軸轉
程式碼如下:
void mouse(int buttom, int state, int x, int y)
{
if(state == GLUT_DOWN)//當壓下滑鼠按鍵
{
oldX = x; oldY = y;//設定舊座標為此時座標
}
}
void motion(int x, int y)
{
rotateY += -(x-oldX);//對著Y軸旋轉滑鼠的橫向移動量
rotateX += -(y-oldY);//對著X軸旋轉滑鼠的縱向移動量
oldX = x; oldY = y;//設定舊座標為此時座標
glutPostRedisplay();//重畫
}
Note:
a.rotateX, rotateY , rotateZ 一樣為全域變數,可以讓我們在對應軸作旋轉
b.但是程式並不能及時轉動,所以一樣要在最後加glutPostRedisplay(); 讓系統重畫圖形
c.此時會動到圖形的座標,所以在display副程式中加入glPushMatrix(); glPopMatrix();
d.經過測試後發現圖背對我們應該是座標相反了,所以在移動量那邊加負號,才會如期轉動
2017年10月12日 星期四
詠銓_Week05_Note
Class:Viewing
1.到jsyeh.org/3dcg10的網頁,下載win32、data、glut32.dll三個檔案,解壓縮後打開Transformation.exe,更改裡面的座標值,可以看到車子會隨著座標的更改而作相應的動作

2.開啟另一個叫做Projection.exe的檔案,此檔可以改變觀察著的視角,改變對應的參數及可以不同的視角觀察3D模型

Note:
(1)gluPerspective(fovy, aspect, zNear, zFar)// 透視投影法,裡面的參數可以決定視角,視野寬度以及近點與遠點。
(2)gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);// 觀察者座標、觀察對象座標、觀察者視角
(3)可更改成glOrtho,可以變成垂直投影,參數不贅述
3.去前述網站下載source,可以得到2.的程式碼,開啟一個glut專案,移除本來的main.cpp檔,加入source的projection.c與glm.c、glm.h檔,即可編譯出2.的程式
1.到jsyeh.org/3dcg10的網頁,下載win32、data、glut32.dll三個檔案,解壓縮後打開Transformation.exe,更改裡面的座標值,可以看到車子會隨著座標的更改而作相應的動作

2.開啟另一個叫做Projection.exe的檔案,此檔可以改變觀察著的視角,改變對應的參數及可以不同的視角觀察3D模型

Note:
(1)gluPerspective(fovy, aspect, zNear, zFar)// 透視投影法,裡面的參數可以決定視角,視野寬度以及近點與遠點。
(2)gluLookAt(eyex, eyey, eyez, centerx, centery, centerz, upx, upy, upz);// 觀察者座標、觀察對象座標、觀察者視角
(3)可更改成glOrtho,可以變成垂直投影,參數不贅述
3.去前述網站下載source,可以得到2.的程式碼,開啟一個glut專案,移除本來的main.cpp檔,加入source的projection.c與glm.c、glm.h檔,即可編譯出2.的程式
2017年10月8日 星期日
詠銓_Week04_Note
Class: 移動、旋轉、縮放
1.開啟一個Glut專案,找到display函式

2.觀察其程式碼,大致有以下:
glPushMatrix(); //儲存矩陣
glTranslated(-2.4,1.2,-6); //移動
glRotated(60,1,0,0); //轉動(角度,旋轉軸)
glRotated(a,0,0,1); //隨時間轉動,a = t*90.0
glutSolidSphere(1,slices,stacks); //畫出實心球
glPopMatrix(); //拿出矩陣
3.移動代表從圖的中心開始,移動到指定坐標。例如:2中的程式碼可以知道將要畫出一實心圓球,而編譯後的程式顯示此球在左上方,而當中的移動程式碼glTranslated(-2.4,1.2,-6);的x,y座標也是顯示在左上方,兩者相符。
4.轉動代表對其中一個轉軸,轉動一角度,如果此角度隨著時間變化,那此圖會一直轉動,其中 +x方向為向右,+y為向上,+z為出銀幕方向(右手坐標系)。若同時有多個座標值,則會依此向量方向轉動。
5.經過測試發現,x,y,z軸並非固定不動,而是跟著圖。
比如說,將中上的圓錐(cone)依x軸轉90度

接著讓它依z軸轉動,我們看到,它繞著現在的-y軸轉動

但對此圓錐來說,它的z軸已經依著x轉90度,成為了整個圖的-y方向,所以看到他依著-y方向轉動其實是對著z軸轉動。
6.縮放,程式碼:glScaled(1,1,2)代表各個座標軸依分別倍率縮放,此例中,z軸被放大了兩倍,為了方便觀察我們將圓錐對x軸轉動90度,可以看到此圓錐的z軸伸長了2倍,而其他座標不變。

Class:滑鼠控制
1.開啟一個Glut專案,找到display函式

2.觀察其程式碼,大致有以下:
glPushMatrix(); //儲存矩陣
glTranslated(-2.4,1.2,-6); //移動
glRotated(60,1,0,0); //轉動(角度,旋轉軸)
glRotated(a,0,0,1); //隨時間轉動,a = t*90.0
glutSolidSphere(1,slices,stacks); //畫出實心球
glPopMatrix(); //拿出矩陣
3.移動代表從圖的中心開始,移動到指定坐標。例如:2中的程式碼可以知道將要畫出一實心圓球,而編譯後的程式顯示此球在左上方,而當中的移動程式碼glTranslated(-2.4,1.2,-6);的x,y座標也是顯示在左上方,兩者相符。
4.轉動代表對其中一個轉軸,轉動一角度,如果此角度隨著時間變化,那此圖會一直轉動,其中 +x方向為向右,+y為向上,+z為出銀幕方向(右手坐標系)。若同時有多個座標值,則會依此向量方向轉動。
5.經過測試發現,x,y,z軸並非固定不動,而是跟著圖。
比如說,將中上的圓錐(cone)依x軸轉90度

接著讓它依z軸轉動,我們看到,它繞著現在的-y軸轉動

但對此圓錐來說,它的z軸已經依著x轉90度,成為了整個圖的-y方向,所以看到他依著-y方向轉動其實是對著z軸轉動。
6.縮放,程式碼:glScaled(1,1,2)代表各個座標軸依分別倍率縮放,此例中,z軸被放大了兩倍,為了方便觀察我們將圓錐對x軸轉動90度,可以看到此圓錐的z軸伸長了2倍,而其他座標不變。

Class:滑鼠控制
2017年9月28日 星期四
詠銓_Week03_Note
Class: 程式參考01
1.從moodle下載 hw1.c , minion.txt ,接著開啟一個Glut專案,將程式碼換成 hw1.c 裡的程式碼

2.檢視其中的程式碼:
a)此程式使用讀檔,將 minion.txt 的資料讀進程式,其中 minion.txt 的資料為每一點的顏色。
b)fscanf 與繪圖程式非常吃效能,所以最好不要寫在for loop中。
c)glPointSize(10.0f); 可以將點放大10倍,也就是當把視窗放大時,圖檔不會破圖。
3.將minion,txt 檔移到freeglut的資料夾的bin資料夾中,以便codeblock讀取。接著執行程式

Class: 程式參考02
1.從moodle下載3D Exploration 以及soccerball.obj,開啟 3D Exploration,找到soccerball檔案

註:jsyeh.org/3dcg10 裡的data有更多模型
2.另存新檔,選擇cpp檔儲存

3.選擇 Samle APP

4.開啟一個openGL專案,把main.c 改成main.cpp,接著將裡面的程式碼替換成剛才儲存的程式碼,刪除無法編譯的程式碼,執行

1.從moodle下載 hw1.c , minion.txt ,接著開啟一個Glut專案,將程式碼換成 hw1.c 裡的程式碼

2.檢視其中的程式碼:
a)此程式使用讀檔,將 minion.txt 的資料讀進程式,其中 minion.txt 的資料為每一點的顏色。
b)fscanf 與繪圖程式非常吃效能,所以最好不要寫在for loop中。
c)glPointSize(10.0f); 可以將點放大10倍,也就是當把視窗放大時,圖檔不會破圖。
3.將minion,txt 檔移到freeglut的資料夾的bin資料夾中,以便codeblock讀取。接著執行程式

Class: 程式參考02
1.從moodle下載3D Exploration 以及soccerball.obj,開啟 3D Exploration,找到soccerball檔案

註:jsyeh.org/3dcg10 裡的data有更多模型
2.另存新檔,選擇cpp檔儲存

3.選擇 Samle APP

4.開啟一個openGL專案,把main.c 改成main.cpp,接著將裡面的程式碼替換成剛才儲存的程式碼,刪除無法編譯的程式碼,執行

2017年9月21日 星期四
詠銓_Week02_Note
Class: 圖學程式01
1.承上,開啟一個Glut專案

2.刪減程式碼

note: 1.glClearColor(1,1,0,0); //代表設定背景顏色,(R,G,B,透明度)
2.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//使用上述設定顏色設定背景
3.glutSolidTeapot(0.3); //畫出茶壺
4.glColor3f(1,0,1); //可用來更改茶壺顏色,(R,G,B)
3.執行

Class: 點線面
1.通常我們不會畫茶壺,所以現在要畫出多邊形
2.程式碼:
glVertex3f(1,1,0); //a.代表畫一個頂點在(1,1,0)座標
glBegin(GL_POLYGON); //b.代表開始畫一個多邊形
glEnd(); //c.代表結束畫圖
3.我們先使用b程式碼,代表要畫一個多邊形,接著使用a程式碼決定頂點,最後用c程式碼結束畫圖,如圖

4.執行

Class: 彩色圖
1.只要在設定頂點時,在前面設定不同的顏色,如圖

2.執行
1.承上,開啟一個Glut專案

2.刪減程式碼

note: 1.glClearColor(1,1,0,0); //代表設定背景顏色,(R,G,B,透明度)
2.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//使用上述設定顏色設定背景
3.glutSolidTeapot(0.3); //畫出茶壺
4.glColor3f(1,0,1); //可用來更改茶壺顏色,(R,G,B)
3.執行

Class: 點線面
1.通常我們不會畫茶壺,所以現在要畫出多邊形
2.程式碼:
glVertex3f(1,1,0); //a.代表畫一個頂點在(1,1,0)座標
glBegin(GL_POLYGON); //b.代表開始畫一個多邊形
glEnd(); //c.代表結束畫圖
3.我們先使用b程式碼,代表要畫一個多邊形,接著使用a程式碼決定頂點,最後用c程式碼結束畫圖,如圖

4.執行

Class: 彩色圖
1.只要在設定頂點時,在前面設定不同的顏色,如圖

2.執行
訂閱:
文章 (Atom)





