2017電腦圖學 Computer Graphics 授課教師: 葉正聖 銘傳大學資訊傳播工程系 每週主題: 程式環境、點線面顏色、移動/旋轉/縮放與矩陣(Matrix)、階層性關節轉動(T-R-T)、做出機器人、打光、貼圖、glu/glut函式、鍵盤、滑鼠、計時器(timer)、讀入3D模型、粒子系統、聲音、特效、投影矩陣、攝影機與運鏡、機器人2.0、期末作品
2017年7月4日 星期二
2017年6月19日 星期一
郭羽筆記week17
1. 糾正貼圖出現的錯誤:
貼圖部分的程式碼如下:
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;
}
void display(){
...
glPushMatrix();
glBegin(GL_POLYGON);
//前面是贴图坐标,后面是3d坐标
glTexCoord2f(0,0); glVertex3f(-2.5,+2,-1);
glTexCoord2f(1,0); glVertex3f(+2.5,+2,-1);
glTexCoord2f(1,1); glVertex3f(+2.5,-2,-1);
glTexCoord2f(0,1); glVertex3f(-2.5,-2,-1);
glEnd();
glPopMatrix();
...
}
int main(){
....
id = myTexture("image.jpg");
glutMainLoop();
}
但是貼圖完成後會出現原來的機器人色彩變暗的現象。原因是貼圖和3D模型部分使用的是不同的光效方式,所以需要在貼圖前後進行轉換。
修改後的程式碼如下:
void display(){
...
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glPushMatrix();
glBegin(GL_POLYGON);
//前面是贴图坐标,后面是3d坐标
glTexCoord2f(0,0); glVertex3f(-2.5,+2,-1);
glTexCoord2f(1,0); glVertex3f(+2.5,+2,-1);
glTexCoord2f(1,1); glVertex3f(+2.5,-2,-1);
glTexCoord2f(0,1); glVertex3f(-2.5,-2,-1);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
....
}

2. 糾正視角轉換中出現的錯誤:
剛開始的時候我的(個人)機器人模型在使用gluPerspective函式透視效果後會出現機器人模型色彩混亂的現象,在小葉老師的幫助下,我知道了這是由於我找的模型有打光正反向混亂的問題。解決的方法是使內外兩面都給光就好了,並且修改原來的打光方向:
display函式中添加:glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
全局光效數組:
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[] = { 2.0f, 5.0f, 5.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[] = { 100.0f };
貼圖部分的程式碼如下:
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;
}
void display(){
...
glPushMatrix();
glBegin(GL_POLYGON);
//前面是贴图坐标,后面是3d坐标
glTexCoord2f(0,0); glVertex3f(-2.5,+2,-1);
glTexCoord2f(1,0); glVertex3f(+2.5,+2,-1);
glTexCoord2f(1,1); glVertex3f(+2.5,-2,-1);
glTexCoord2f(0,1); glVertex3f(-2.5,-2,-1);
glEnd();
glPopMatrix();
...
}
int main(){
....
id = myTexture("image.jpg");
glutMainLoop();
}
但是貼圖完成後會出現原來的機器人色彩變暗的現象。原因是貼圖和3D模型部分使用的是不同的光效方式,所以需要在貼圖前後進行轉換。
修改後的程式碼如下:
void display(){
...
glEnable(GL_TEXTURE_2D);
glDisable(GL_LIGHTING);
glPushMatrix();
glBegin(GL_POLYGON);
//前面是贴图坐标,后面是3d坐标
glTexCoord2f(0,0); glVertex3f(-2.5,+2,-1);
glTexCoord2f(1,0); glVertex3f(+2.5,+2,-1);
glTexCoord2f(1,1); glVertex3f(+2.5,-2,-1);
glTexCoord2f(0,1); glVertex3f(-2.5,-2,-1);
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
....
}
2. 糾正視角轉換中出現的錯誤:
剛開始的時候我的(個人)機器人模型在使用gluPerspective函式透視效果後會出現機器人模型色彩混亂的現象,在小葉老師的幫助下,我知道了這是由於我找的模型有打光正反向混亂的問題。解決的方法是使內外兩面都給光就好了,並且修改原來的打光方向:
display函式中添加:glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
全局光效數組:
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[] = { 2.0f, 5.0f, 5.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[] = { 100.0f };
2017年6月18日 星期日
2017年5月22日 星期一
郭羽筆記week14
上節課的作業動起來:
使用透視效果來實現機器人的旋轉:
float eyeX=0, eyeY= 0, eyeZ= 2;
float centerX=0, centerY=0, centerZ=0;
float upX=0, upY=1, upZ=0;
float angle=0, dir=1;
bool flag = true;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,1,0.001,10000);
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
angle+= 0.01;
if(eyeY > 1) flag = true;
if(eyeY < -1) flag = false;
if(!flag) eyeY += 0.01;
else eyeY -= 0.01;
eyeX = sin(angle);
eyeZ = cos(angle);
glPushMatrix();
gluLookAt(eyeX, eyeY, eyeZ,
centerX, centerY, centerZ,
upX, upY, upZ);
加入定時器:
void timer(int t)
{
glutTimerFunc(100, timer, t+1);
angle+= 0.1;
if(eyeY > 1) flag = true;
if(eyeY < -1) flag = false;
if(!flag) eyeY += 0.01;
else eyeY -= 0.01;
eyeX = sin(angle);
eyeZ = cos(angle);
glutPostRedisplay();
}
這樣將隨時間變化的角度通過計時器進行了時間控制。
TRT:
glTranslatef(-0.14,0.19,-0.02);
glRotatef(-angle *5, 0,0,1);
glTranslatef(-0.01,-0.04,0);
glmDraw(pmodel_arm_high_right, GLM_SMOOTH | GLM_MATERIAL);
glutWireSphere(0.01,15,15);
glPushMatrix();
glTranslatef(-0.01,-0.05,0.05);
glRotatef(-angle *5, 0,0,1);
glTranslatef(-0.09,-0.15,0);
glmDraw(pmodel_arm_low_right, GLM_SMOOTH | GLM_MATERIAL);
glPopMatrix();
2017年5月15日 星期一
郭羽week13筆記
2017年5月8日 星期一
郭羽week12筆記
下載支持文件data,win32,glut32.dll
打開projection,調整gluLookAt的前三個參數進行調試
分別調整左右,上下,前後三個方向
接下來畫出一個茶壺使用代碼調整視角
gluPerspective(float fovy, float aspect, float zNear, float zFar);
这个函数是用來控制透視效果的。四個參數分別表示:
fovy:視野的角度,一般設置為60,視角越大物體越小,對應看到的東西就越多
aspect:視野橫向的縮放,1.0為正常大小
zNear:z軸方向的開始位置
zFar:z軸方向的最遠位置
zNear和zFar兩個參數控制視野的遠近。
gluLookAt最後三個參數控制視角的旋轉角度,類比照相機拍照。
static void display(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60,1,0.01,10);
glMatrixMode(GL_MODELVIEW);
angle+= 0.01;
if(eyeY > 1) flag = true;
if(eyeY < -1) flag = false;
if(!flag) eyeY += 0.01;
else eyeY -= 0.01;
eyeX = sin(angle);
eyeZ = cos(angle);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1,0,0);
glPushMatrix();
gluLookAt(eyeX, eyeY, eyeZ,
centerX, centerY, centerZ,
upX, upY, upZ);
glutSolidTeapot(0.3);
glPopMatrix();
glutSwapBuffers();
}
最後是小葉老師的手臂,TRT旋轉
自己改了一下,腿出來了哦哈哈 茶壺怪誕生!
郭羽week11筆記
2017年4月24日 星期一
郭羽的筆記,week10
1.打遊戲,一個看起來非常low的射擊小遊戲nehe lesson 32,搶灘登陸的畫風。PS:還有聲音哦!

2.為glut專案的的demo添加聲音(就是搶灘登陸的設計聲音orz)
- 首先要去lesson32窺一下cpp代碼,找到哪一行代碼控制聲音的產生。

- 552粘貼代碼到自建的glut專案,粘到mouse函數裡面,使用glutMouseFunc函數調用,還有一點,include控制多媒體系統的頭文件mmsystem.h
啟動。效果如下:
8
3.添加聲音
glutKeybordFunc()
void keybord(unsigned char c, int x, int y){
if('1'==c) PlaySound("pianoC.wav",NULL,SND_ASYNC);
if('2'==c) PlaySound("pianoD.wav",NULL,SND_ASYNC);
if('3'==c) PlaySound("pianoE.wav",NULL,SND_ASYNC);
if('4'==c) PlaySound("pianoF.wav",NULL,SND_ASYNC);
if('5'==c) PlaySound("pianoG.wav",NULL,SND_ASYNC);
if('6'==c) PlaySound("pianoA.wav",NULL,SND_ASYNC);
if('7'==c) PlaySound("pianoB.wav",NULL,SND_ASYNC);
if('8'==c) PlaySound("pianoC2.wav",NULL,SND_ASYNC);
}
2.為glut專案的的demo添加聲音(就是搶灘登陸的設計聲音orz)
- 首先要去lesson32窺一下cpp代碼,找到哪一行代碼控制聲音的產生。
- 552粘貼代碼到自建的glut專案,粘到mouse函數裡面,使用glutMouseFunc函數調用,還有一點,include控制多媒體系統的頭文件mmsystem.h
啟動。效果如下:
8
3.添加聲音
glutKeybordFunc()
void keybord(unsigned char c, int x, int y){
if('1'==c) PlaySound("pianoC.wav",NULL,SND_ASYNC);
if('2'==c) PlaySound("pianoD.wav",NULL,SND_ASYNC);
if('3'==c) PlaySound("pianoE.wav",NULL,SND_ASYNC);
if('4'==c) PlaySound("pianoF.wav",NULL,SND_ASYNC);
if('5'==c) PlaySound("pianoG.wav",NULL,SND_ASYNC);
if('6'==c) PlaySound("pianoA.wav",NULL,SND_ASYNC);
if('7'==c) PlaySound("pianoB.wav",NULL,SND_ASYNC);
if('8'==c) PlaySound("pianoC2.wav",NULL,SND_ASYNC);
}
4.52332355356
76576536532
2017年4月17日 星期一
郭羽week8筆記
1.jsyeh.org/3dcg10下載
source.zip glut32.lib, data.zip windows.zip
2.切換模型
3.開啟soccerball.obj,右鍵notpad++
v開頭 vertex
vn開頭 vertex normal
vt開頭 vertex texture coordinate
f開頭 face 臉面
4. 使用Maya绘制出一个有趣的图形
借用小叶老师给的demo,将obj文件复制到专案文件夹下
修改代码,修改obj文件目录,修改图形的动作
source.zip glut32.lib, data.zip windows.zip
2.切換模型
3.開啟soccerball.obj,右鍵notpad++
v開頭 vertex
vn開頭 vertex normal
vt開頭 vertex texture coordinate
f開頭 face 臉面
4. 使用Maya绘制出一个有趣的图形
借用小叶老师给的demo,将obj文件复制到专案文件夹下
修改代码,修改obj文件目录,修改图形的动作
2017年4月10日 星期一
郭羽的筆記week07
打光:
1.建立GLUT專案:
- 從檔案下載freeglut,解壓縮到桌面上
- 打開codeblocks,新建glut專案
- 將freeglut文檔位置導入
- 運行顯示圖形
2. 修改display函式,只顯示一個茶壺:
3.將light和key去除掉:
4.運行,最後是這個樣子,打光成功!
5.加入旋轉部分
注意:main函式里display執行前面要加一行在idle時刷新:
6.再加一個 不轉的
7.再來一個圓錐
1.建立GLUT專案:
- 從檔案下載freeglut,解壓縮到桌面上
- 打開codeblocks,新建glut專案
- 將freeglut文檔位置導入
- 運行顯示圖形
2. 修改display函式,只顯示一個茶壺:
static void display(void){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glPushMatrix();glutSolidTeapot(0.3);glPopMatrix();glutSwapBuffers();}
3.將light和key去除掉:
4.運行,最後是這個樣子,打光成功!
注意:main函式里display執行前面要加一行在idle時刷新:
glutIdleFunc(display);glutDisplayFunc(display);
6.再加一個 不轉的
7.再來一個圓錐
2017年3月28日 星期二
筆記week04 郭羽
1.Translate:
code:
#include <GL/glut.h>
float mouseX=0 , mouseY=0;
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(mouseX,mouseY,0);
glutSolidTeapot(0.3);
glPopMatrix();
glutSwapBuffers();
}
void motion(int x,int y)
{
mouseX = (x-150)/150.0;
mouseY = -(y-150)/150.0;
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("guoyu");
glutDisplayFunc(display);
glutMotionFunc(motion);
glutMainLoop();
}
2.Scale
code中加入glScalef(mouseX,mouseY,0);
郭羽 week04 笔记
1.架設glut專案(茶壺Teapot)
#include <GL/glut.h>
static void display(void)
{
glutSolidTeapot(0.3);
glutSwapBuffers();
}
int main(int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("Guo Yu 05052535");
glutDisplayFunc(display);
glutMainLoop();
}run:
2017年3月27日 星期一
笔记week05 郭羽
1.練習期中試題100%
glPushMatrix(); //備份矩陣 10%2. 下載圖學的教學軟件(略)
glRotatef(angle, x, y, z); //旋轉
glTranslatef(x, y, z);//移動
glScalef(x, y, z); //縮放
glBegin(GL_POLYGON); //開始畫
glNormal3f(nx, ny, nz); //打光的法向量
glTexCoord2f(tx, ty); //貼圖的坐標
glColor3f(r, g, b); //顏色
glVertex3f(x, y, z); //頂點
glEnd(); //結束畫
glPopMatrix(); //還原矩陣
3. 學習旋轉glRotatef(angle, x, y, z)
arguments:
angle:旋轉角度。默認正角度為逆時針旋轉,負角度為順時針旋轉。(正視)當x, y, z為0時,控制angle變化時為側向旋轉。
x:控制上下旋轉。當angle遞增時,x值為正向上旋轉(右視圖為逆時針),x值為負向下旋轉(右視圖為順時針)。
y:控制側向旋轉。當angle遞增時,y值為正向右旋轉(上方透視為逆時針),y值為負向左旋轉(上方透視為順時針)。
z:控制正向旋轉。當angle遞增時,z值為正正視逆時針旋轉,z值為負正視順時針旋轉。
4. 口訣
左耳碰左肩,從下往上讀,畫圈圈。
2017年3月13日 星期一
Week03 筆記 Mouse互動
任務1:複習
code:
任務2:mouse函式
code中加入回調函式mouse,glutMouseFunc調用mouse。
執行:
任務3:通過滑鼠改顏色
code:在mouse函式中加入兩行:
執行:
通過點擊滑鼠/滑動滾輪和移動滑鼠來控制茶壺顏色變化。
任務4:拖拽動作
glutMotionFunc(motion): glutMotionFunc調用回調函式motion
橢圓:
glVertex2f(0.7*cos(angle), sin(angle));
張開嘴巴的小精靈:
code:
code:
build and run:#include<GL/glut.h>void display(){glutSolidTeapot(0.3);glutSwapBuffers();}int main(int argc, char *argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);glutCreateWindow("我的魔法會把你撕成碎片");glutDisplayFunc(display);glutMainLoop();}
任務2:mouse函式
code中加入回調函式mouse,glutMouseFunc調用mouse。
執行:
任務3:通過滑鼠改顏色
code:在mouse函式中加入兩行:
glColor3f(mouse/4.0, x/255.0, y/255.0);glutPostRedisplay();
執行:
通過點擊滑鼠/滑動滾輪和移動滑鼠來控制茶壺顏色變化。
任務4:拖拽動作
glutMotionFunc(motion): glutMotionFunc調用回調函式motion
執行:void motion(int x, int y){glColor3f(1, x/255.0, y/255.0);glutPostRedisplay();printf("%d %d\n", x, y);}
任務5:畫圓
code:在display中定義畫圓的程式
執行:glBegin(GL_POLYGON);for(float angle=0;angle<3.1415926*2;angle+=0.01)glVertex2f(cos(angle), sin(angle));glEnd();
橢圓:
glVertex2f(0.7*cos(angle), sin(angle));
張開嘴巴的小精靈:
code:
void display(){//glutSolidTeapot(0.3);glBegin(GL_POLYGON);for(float angle=0;angle<3.1415926*2;angle+=0.01)glVertex2f(cos(angle), sin(angle));glEnd();glColor3f(0,0,0);glBegin(GL_POLYGON);for(float angle=3.1415926 - 0.5;angle<3.1415926+0.5;angle+=0.01)glVertex2f(cos(angle), sin(angle));glVertex2f(0.0, 0.0);glEnd();glutSwapBuffers();}
訂閱:
文章 (Atom)

