文章目錄
- 圖形幾何變換及裁剪
-
- 圖形的幾何變換
- 掌握OpenGL中三維觀察、透視投影、正交投影的參數設定。
- 線段裁剪的Cohen-Sutherland算法
- 定義裁剪平面對網狀球體裁剪
- 真實感圖形繪制
-
- 1.了解程式架構
- 2.産生一個三維物體,進行消隐處理
- 3.移動光源
- 4.一維紋理映射,畫彩虹
- 互動技術與計算機動畫
-
- 繪制折線
- 繪制矩形
- 模型函數繪制示例(菜單)
- 動畫:日地月模型
圖形幾何變換及裁剪
圖形的幾何變換
-
把模型矩陣複位,
即通過給模型視圖矩陣加載上機關矩陣來複位原點。下面的代碼把機關矩陣加載到模型視圖矩陣中:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
第一個函數用于指定目前操作的矩陣,其函數原型如下:
glMatrixMode(GLenum mode);
其中參數mode 用于确定将哪個矩陣堆棧用于矩陣操作,它的取值有:GL_MODELVIEW
(模型視圖矩陣堆棧),GL_PROJECTION(投影矩陣堆棧)和GL_TEXTURE(紋理矩陣堆
棧)。一旦設定了目前操作矩陣,它就将保持為活動的矩陣,直到你修改它為止。
第二個函數作用就是給目前操作矩陣加載上機關矩陣,。
#include<GL/glut.h>
//初始化視窗
void Initial();
void ChangeSize(int w, int h);
void Display();
//繪制三角形
void DrawTriangle();
int main(int argc, char* argv[])
{
//初始化工具包
glutInit(&argc, argv);
//設定顯示模式
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
//視窗設定
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("1812030065-李詩雨");
//調用繪圖函數,回調函數,不斷監聽
glutReshapeFunc(ChangeSize);
glutDisplayFunc(Display);
Initial();//必要的其他初始化函數
glutMainLoop();//進入循環
return 0;
}
void Initial(void)
{
//設定視窗背景色
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void DrawTriangle(void)
{
glBegin(GL_TRIANGLES);
glVertex2f(0.0f, 0.0f);
glVertex2f(40.0f, 0.0f);
glVertex2f(20.0f, 40.0f);
glEnd();
}
void ChangeSize(int w, int h)
{
if (h == 0) h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-120.0f, 120.0f, -120.0f * h / w, 120.0f * h / w, -120.0f, 120.0f);
else
glOrtho(-120.0f * w / h, 120.0f * w / h, -120.0f, 120.0f, -120.0f, 120.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//繪制黑色坐标軸
glColor3f(0.0f, 0.0f, 0.0f);
//不裁剪視窗的話,螢幕的坐标位于視窗中心
glBegin(GL_LINES);
glVertex2f(-120.0f, 0.0f);
glVertex2f(120.0f, 0.0f);
glVertex2f(0.0f, -120.0f);
glVertex2f(0.0f, 120.0f);
glEnd();
//繪制紅色的三角形
glColor3f(1.0f, 0.0, 0.0f);
DrawTriangle();
//畫一個逆時針旋轉200度的綠色三角形
//第一個參數表示逆時針旋轉的度數,後三個參數指定旋轉的矢量坐标
glRotatef(200.0f, 0.0f, 0.0f, 1.0f);//以z軸為旋轉軸(垂直螢幕方向),旋轉的是坐标系
glColor3f(0.0f, 1.0f, 0.0f);
DrawTriangle();
//畫沿着x軸負向平移80的黃色三角形
//因為旋轉的是坐标系,是以經過一次旋轉之後要重置一下
glLoadIdentity();
glTranslatef(-80.0f, 0.0f, 0.0f);
glColor3f(1.0, 1.0f, 0.0f);
DrawTriangle();
//畫出沿x軸對稱,沿x軸正向平移10,沿y軸負向平移10,縮放因子為 1.5,2.0,1.0的藍色三角形
glLoadIdentity();
glTranslatef(10.0f, -10.0f, 0.0f);
glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
glScalef(1.5f, 2.0f, 1.0f);
glColor3f(0.0f, 0.0f, 1.0f);
DrawTriangle();
glFlush();
}

掌握OpenGL中三維觀察、透視投影、正交投影的參數設定。
-
關于幾何變換抵消坐标積累變換的方法
glPushMatrix 變換 glPopMatrix 這個可以了解為把目前坐标狀态(未作變換的)入棧,經過變換後坐标狀态(未作變換的)出棧
具體參考glPushMatrix ,glPopMatrix 的了解
-
定義視景轉換
視點中心由eye[]控制,場景中心由center[]控制,y軸向上
gluLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], 0, 1, 0);
函數原型
void gluLookAt(GLdouble eyex,GLdouble eyey,GLdouble eyez,GLdouble centerx,GLdouble centery,GLdouble centerz,GLdouble upx,GLdouble upy,GLdouble upz);
該函數定義一個視圖矩陣,并與目前矩陣相乘。
第一組eyex, eyey,eyez 相機在世界坐标的位置
第二組centerx,centery,centerz 相機鏡頭對準的物體在世界坐标的位置
第三組upx,upy,upz 相機向上的方向在世界坐标中的方向
你把相機想象成為你自己的腦袋:
第一組資料就是腦袋的位置
第二組資料就是眼睛看的物體的位置
第三組就是頭頂朝向的方向(因為你可以歪着頭看同一個物體)
如果我們向前或向後移動,則相應的圖像會變大或變小,這裡其實就是運用了透視原理,近處的物體大,遠處的物體小,實際物體的大小是不變的,
同理改變center坐标(眼睛看去的那個點,可簡單了解為視線的終點)也會影響球的大小,同樣可以認為是改變了物體與觀察點的距離所緻。
gluLookAt函數詳解
- gluPerspective 透視投影 gluperspective詳解
- glortho 建立一個正交平行的視景體(正投影),詳解
關于裡面的旋轉不懂。。。
#include <GL/glut.h>
float fTranslate;
float fRotate; //場景自轉角度
float fScale = 1.0f;
bool bPersp = false; //透視模式
bool bAnim = false; //場景自轉
bool bWire = false;//邊緣填充
int wHeight = 0;
int wWidth = 0;
//通過改變下面參數來控制茶壺
bool isTeapotRotate = false;
float teapotRotate = 0.0;//茶壺旋轉
float teapotPos[] = { 0,0 }; //茶壺的位置
//視窗形狀改變時調用
void reshape(int width, int height);
void updateView(int width, int height);
//繪圖
void redraw();
void Draw_leg();
void Draw_Scene();
//按鍵調整參數
void key(unsigned char k, int x, int y);
//動畫
void idle();
int main(int argc, char* argv[]) {
//初始化工具包
glutInit(&argc, argv);
//設定顯示模式
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGB);
//視窗設定
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("1812030065-李詩雨");
//全局回調函數,不斷監聽
glutReshapeFunc(reshape);
glutDisplayFunc(redraw);
glutKeyboardFunc(key);
glutIdleFunc(idle);//動畫渲染的關鍵
glutMainLoop();//進入循環
return 0;
}
void reshape(int width, int height) {//參數是視窗的寬和高
if (height == 0) {
height = 1;
}// 視窗太小時的處理
wHeight = height;
wWidth = width;
updateView(wHeight, wWidth);
}
void updateView(int width,int height) {
glViewport(0, 0, width, height);//重置目前視口
//投影
glMatrixMode(GL_PROJECTION);//選擇投影矩陣
glLoadIdentity();//重置投影矩陣
//計算寬高比
float whRatio = (GLfloat)width / (GLfloat)height;
//是否開啟透視模式
if (bPersp) {
gluPerspective(45.0f, whRatio, 0.1f, 100.0f);
}
else
glOrtho(-3, 3, -3, 3, -100, 100);//建立修剪空間的範圍
glMatrixMode(GL_MODELVIEW);//選擇模型視圖矩陣
}
void idle() {
glutPostRedisplay();//渲染動畫
}
float eye[] = { 0,0,8 };
float center[] = { 0,0,0 };
void key(unsigned char k, int x, int y) {
switch (k)
{
case 'q':exit(0); break;//退出
case 'p':bPersp = !bPersp; updateView(wHeight, wWidth);break;//開啟或關閉透視模式
case ' ':bAnim = !bAnim;break;//開啟或關閉場景自轉
case'o':bWire = !bWire;break;//開啟或關閉邊緣填充
case 'a':eye[0] += 0.2; center[0] += 0.2; break;//更改eye和center在x軸上的坐标
case 'd':eye[0] -= 0.2; center[0] -= 0.2; break;//更改eye和center在x軸上的坐标
case 'w':eye[1] -= 0.2; center[1] -= 0.2; break;//更改eye和center在y軸上的坐标
case 's':eye[1] += 0.2; center[1] += 0.2; break;//更改eye和center在y軸上的坐标
case 'z':eye[2] -= 0.2; break;//更改eye在z軸上的坐标
case 'c':eye[2] += 0.2; break;//更改eye在z軸上的坐标
//茶壺相關操作
case'l':if (teapotPos[0] < 2.0)teapotPos[0] += 0.1;break;
case'j':if (teapotPos[0] > -2.0)teapotPos[0] -= 0.1; break;
case'i':if (teapotPos[1] < 1.5)teapotPos[1] += 0.1; break;
case'k':if (teapotPos[1] > -1.5)teapotPos[1] -= 0.1; break;
case'e':isTeapotRotate = !isTeapotRotate; break;//開啟或關閉茶壺自轉
default:
break;
}
}
void Draw_leg() {
//畫一個比例為1:1:3的桌子腿
glScalef(1, 1, 3);
glutSolidCube(1.0);
}
void Draw_Scene() {
//畫茶壺
glPushMatrix();//目前坐标狀态(未作變換的)入棧
glTranslatef(teapotPos[0], 0, 4 + 1+teapotPos[1]);
glRotatef(teapotRotate, 0, 0, 1);
glRotatef(90, 1, 0, 0);
glutSolidTeapot(1);
glPopMatrix();//坐标狀态(未作變換的)出棧
//畫桌子闆
glPushMatrix();//目前坐标狀态(未作變換的)入棧
glTranslatef(0, 0, 3.5);
glScalef(5, 4, 1);
glRotatef(90, 1, 0, 0);
glutSolidCube(1.0);
glPopMatrix();
//畫桌子腿
glPushMatrix();
glTranslatef(1.5, 1, 1.5);
Draw_leg();
glPopMatrix();
glPushMatrix();
glTranslatef(-1.5, 1, 1.5);
Draw_leg();
glPopMatrix();
glPushMatrix();
glTranslatef(1.5, -1, 1.5);
Draw_leg();
glPopMatrix();
glPushMatrix();
glTranslatef(-1.5, -1, 1.5);
Draw_leg();
glPopMatrix();
}
void redraw() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();//重置目前modelview
//定義視景轉換,視點中心由eye[]控制,場景中心由center[]控制,y軸向上
gluLookAt(eye[0], eye[1], eye[2], center[0], center[1], center[2], 0, 1, 0);
//是否開啟邊緣繪制模式
if (bWire) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//設定兩面均為邊緣繪制方式
}
else {
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);//設定兩面均為填充繪制方式
}
// 用來開啟更新深度緩沖區的功能,也就是,如果通過比較後深度值發生變化了,
//會進行更新深度緩沖區的操作。啟動它,OpenGL就可以跟蹤再Z軸上的像素,
//這樣,它隻會再那個像素前方沒有東西時,才會繪畫這個像素。
//在做繪畫3D時,這個功能最好啟動,視覺效果比較真實。
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);//啟動光照
//設定光源LIGHT0的參數
GLfloat white[] = { 1.0,1.0,1.0,1.0 };
GLfloat light_pos[] = { 5,5,5,1 };
glLightfv(GL_LIGHT0, GL_POSITION, light_pos); //設定光源位置
glLightfv(GL_LIGHT0, GL_AMBIENT, white);//設定環境光顔色
glEnable(GL_LIGHT0);//啟動光源LIGHT0
glRotatef(fRotate, 0, 1.0f, 0);//場景自轉
glRotatef(-90, 1, 0, 0);
glScalef(0.2, 0.2, 0.2);
Draw_Scene();
if (bAnim) fRotate += 0.5f;
if (isTeapotRotate) teapotRotate += 0.5f;//茶壺轉角增加
glutSwapBuffers();
}
線段裁剪的Cohen-Sutherland算法
#include<stdio.h>
#include<stdlib.h>
#include<GL/glut.h>
#define LEFT_EDGE 1
#define RIGHT_EDGE 2
#define BOTTOM_EDGE 4
#define TOP_EDGE 8
void LineGL(int x0, int y0, int x1, int y1)
{
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(x0, y0);
glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(x1, y1);
glEnd();
}
//螢幕rect
struct Rectangle_
{
float xmin, xmax, ymax, ymin;
};
Rectangle_ rect;
void Init();
void Reshape(int w, int h);
void keyboard(unsigned char key, int x, int y);
//繪制螢幕和未裁剪的直線段
void myDisplay();
int x0, y0, x1, y1;//直線段兩端頂點坐标
//給點編碼,D3D2D1D0,如果x小于rect.xmin,則D0=1否則為0,編碼從右往左,比較順序:左右下上
int CompCode(int x, int y, Rectangle_ rect);
//Cohen Sutherland 裁剪算法,畫出裁剪後的線段
int cohensutherlandlineclip(Rectangle_ rect, int& x0, int& y0, int& x1, int& y1);
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(640, 480);
glutCreateWindow("1812030065李詩雨");
Init();
glutDisplayFunc(myDisplay);
glutReshapeFunc(Reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}
void Init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
rect.xmin = 100;
rect.xmax = 300;
rect.ymin = 100;
rect.ymax = 300;
x0 = 450, y0 = 0, x1 = 0, y1 = 450;
printf("Press key 'c' to Clip!\nPress key 'r' to Restore!\n");
}
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glRectf(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
//繪制未裁剪的直線段
LineGL(x0, y0, x1, y1);
glFlush();
}
void Reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h);
}
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'c'://Cohen Sutherland 裁剪
cohensutherlandlineclip(rect, x0, y0, x1, y1);
glutPostRedisplay();
break;
case 'r'://恢複
Init();
glutPostRedisplay();
break;
case 'x':
exit(0);
break;
default:
break;
}
}
int CompCode(int x, int y, Rectangle_ rect)
{
//二進制或運算 把符合條件的的位編碼置1
int code = 0;
if (y < rect.ymin)
code = code | 4;
if (y > rect.ymax)
code = code | 8;
if (x > rect.xmax)
code = code | 2;
if (x < rect.xmin)
code = code | 1;
return code;
}
int cohensutherlandlineclip(Rectangle_ rect, int& x0, int& y0, int& x1, int& y1)
{
int accept, done;
float x, y;
accept = 0;//=1表示取得裁剪範圍内的線段
done = 0;//=1表示裁剪完畢
//給直線的兩個頂點編碼
int code0, code1, codeout;
code0 = CompCode(x0, y0, rect);
code1 = CompCode(x1, y1, rect);
//隻要沒裁剪完就繼續求交裁剪
do
{
if (!(code0 | code1))
{//簡取
accept = 1;
done = 1;
}
else if (code0 & code1)
{//簡棄
done = 1;
}
else
{
//選擇一個不在裁剪範圍内的頂點,把編碼賦給codeout
if (code0 != 0)
codeout = code0;
else
codeout = code1;
//根據codeout和邊界按位&的結果來确定直線跟那條邊界相交并求交點
if (codeout & LEFT_EDGE)
{
y = y0 + (y1 - y0) * (rect.xmin - x0) / (x1 - x0);
x = (float)rect.xmin;
}
else if (codeout & RIGHT_EDGE)
{
y = y0 + (y1 - y0) * (rect.xmax - x0) / (x1 - x0);
x = (float)rect.xmax;
}
else if (codeout & BOTTOM_EDGE)
{
x = x0 + (x1 - x0) * (rect.ymin - y0) / (y1 - y0);
y = (float)rect.ymin;
}
else if (codeout & TOP_EDGE)
{
x = x0 + (x1 - x0) * (rect.ymax - y0) / (y1 - y0);
y = (float)rect.ymax;
}
//把跟邊界的交點編碼
if (codeout == code0)
{
x0 = x; y0 = y;
code0 = CompCode(x0, y0, rect);
}
else {
x1 = x; y1 = y;
code1 = CompCode(x1, y1, rect);
}
}
} while (!done);
//如果裁剪範圍内有線段,就畫出來
if (accept)
LineGL(x0, y0, x1, y1);
return accept;
}
定義裁剪平面對網狀球體裁剪
#include <GL\glut.h>
// 旋轉參數
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
void Initial(void);
void ChangeSize(GLsizei w, GLsizei h);
// 在視窗中繪制圖形
void Display(void);
void SpecialKeys(int key, int x, int y);
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("1812030065李詩雨");
glutDisplayFunc(Display);
glutSpecialFunc(SpecialKeys);
glutReshapeFunc(ChangeSize);
Initial();
glutMainLoop();
return 0;
}
void Initial(void)
{
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glShadeModel(GL_FLAT);
}
void ChangeSize(GLsizei w, GLsizei h)
{
if (h == 0) h = 1;
// 設定視區尺寸
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// 建立修剪空間的範圍
gluPerspective(60.0f, (GLfloat)w / (GLfloat)h, 1.0f, 20.0f);
glMatrixMode(GL_MODELVIEW);
}
void Display(void)
{
//定義裁減平面方程系數
GLdouble eqn[4] = { 1.0, 1.0, 0.0, 1.0 };
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glPushMatrix();
//沿 z 軸負向平移一段距離,保證良好的觀察效果
glTranslatef(0.0, 0.0, -5.0);
//設定裁減平面
glClipPlane(GL_CLIP_PLANE0, eqn);
glEnable(GL_CLIP_PLANE0);
//使球體旋轉
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glutWireSphere(2.0f, 20, 20);
glPopMatrix();
glFlush();
}
void SpecialKeys(int key, int x, int y)
{
if (key == GLUT_KEY_UP) xRot -= 5.0f;
if (key == GLUT_KEY_DOWN) xRot += 5.0f;
if (key == GLUT_KEY_LEFT) yRot -= 5.0f;
if (key == GLUT_KEY_RIGHT) yRot += 5.0f;
if (xRot > 356.0f) xRot = 0.0f;
if (xRot < -1.0f) xRot = 355.0f;
if (yRot > 356.0f) yRot = 0.0f;
if (yRot < -1.0f) yRot = 355.0f;
glutPostRedisplay();
}
真實感圖形繪制
1.了解程式架構
體會遮擋關系
#include<GL/glut.h>
enum{FILL,WIRE};
enum{SPHERE=1,CONE,WALLS};
int rendermode = FILL;
GLUquadricObj* sphere, * cone, * base;
static GLfloat lightpos[] = { 50.f,50.f,-320.f,1.f };
static GLfloat wall_mat[] = { 0.8f,0.8f,0.8f,1.f };
static GLfloat sphere_mat[] = { 1.0f,0.2f,0.2f,1.f };
static GLfloat cone_mat[] = { 0.2f,1.0f,0.2f,1.f };
void Initial();
void Display();
void menu(int );
void drawscene();
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(500, 500);
glutCreateWindow("Wireframe and ZBuffer 1812030065-李詩雨");
glutDisplayFunc(Display);
glutCreateMenu(menu);
glutAddMenuEntry("Solid Fill", FILL);//把FILL這個位置的參數傳入到menu函數中
glutAddMenuEntry("Wireframe", WIRE);
glutAttachMenu(GLUT_RIGHT_BUTTON);//按右鍵顯示菜單
Initial();//必要的其他初始化函數
glutMainLoop();//進入循環
return 0;
}
void Initial() {
glMatrixMode(GL_PROJECTION);
glFrustum(-100.0, 100.0, -100.0, 100.0, 320.0, 640.0);//透視顯示:左右下上近遠
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);//打開深度緩沖設定
glDepthFunc(GL_LEQUAL);//判斷遮擋關系時,離視點近的遮擋離視點遠的物體。GL-NEVER不判斷,GL_ALWAYS,GL_LESS,GL_LEQUAL
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
glNewList(SPHERE, GL_COMPILE);
sphere = gluNewQuadric();//建立一個對象
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, sphere_mat);
gluSphere(sphere, 50.f, 40, 40);//讓該對象畫球,參數:球體,半徑,經度分割線,緯度分割線
gluDeleteQuadric(sphere);//釋放對象
glEndList();
glNewList(CONE, GL_COMPILE);
cone = gluNewQuadric();
base = gluNewQuadric();
glPushMatrix();
glRotatef(-90.f, 1.f, 0.f, 0.f);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, cone_mat);
gluQuadricOrientation(base, GLU_INSIDE);
gluDisk(base, 0., 40., 20, 1);//碟盤(圓錐的底,如果畫圓柱需要兩個底)參數:對象,内環半徑,外環半徑,分割線,同心圓線
gluCylinder(cone, 40., 0., 120., 20, 20);//圓錐,參數:對象,下半徑,上半徑,高,經度分割線,緯度分割線
glPopMatrix();
gluDeleteQuadric(cone);
gluDeleteQuadric(base);
glEndList();
//WALLS
glNewList(WALLS,GL_COMPILE);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, wall_mat);
glBegin(GL_QUADS);
glNormal3f(0.f, 1.f, 0.f);
glVertex3f(-100.f, -100.f, -320.f);
glVertex3f(100.f, -100.f, -320.f);
glVertex3f(100.f, -100.f, -520.f);
glVertex3f(-100.f, -100.f, -520.f);
//left wall
glNormal3f(1.f, 0.f, 0.f);
glVertex3f(-100.f, -100.f, -320.f);
glVertex3f(-100.f, -100.f, -520.f);
glVertex3f(-100.f, 100.f, -520.f);
glVertex3f(-100.f, 100.f, -320.f);
//right wall
glNormal3f(-1.f, 0.f, 0.f);
glVertex3f(100.f, -100.f, -320.f);
glVertex3f(100.f, 100.f, -320.f);
glVertex3f(100.f, 100.f, -520.f);
glVertex3f(100.f, -100.f, -520.f);
//ceiling
glNormal3f(0.f, -1.f, 0.f);
glVertex3f(-100.f, 100.f, -320.f);
glVertex3f(-100.f, 100.f, -520.f);
glVertex3f(100.f, 100.f, -520.f);
glVertex3f(100.f, 100.f, -320.f);
//back wall
glNormal3f(0.f, 0.f, 1.f);
glVertex3f(-100.f, -100.f, -520.f);
glVertex3f(100.f, -100.f, -520.f);
glVertex3f(100.f, 100.f, -520.f);
glVertex3f(-100.f, 100.f, -520.f);
glEnd();
glEndList();
}
void menu(int selection) {
rendermode = selection;
glutPostRedisplay();
}
void drawscene() {
glCallList(WALLS);
glPushMatrix();
glTranslatef(-20.f, -40.f, -400.f);
glCallList(SPHERE);
glPopMatrix();
glPushMatrix();
glTranslatef(40.f, -100.f, -420.f);
glCallList(CONE);
glPopMatrix();
glPushMatrix();
glTranslatef(-40.f, -40.f, -400.f);
glCallList(CONE);
glPopMatrix();
}
void Display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
switch (rendermode)
{
case FILL:
drawscene(); break;
case WIRE:
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//GL_POINTS,GL_FILL
glColor4f(0.0, 0.0, 0.0, 1.0);
drawscene();
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_LIGHTING);
break;
default:
break;
}
glFlush();
}
2.産生一個三維物體,進行消隐處理
#include<GL/glut.h>
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
void RenderScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_DEPTH_TEST);//深度測試
glDepthFunc(GL_LEQUAL);
glPushMatrix();
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glBegin(GL_QUADS);
glColor3f(1.0, 0.0, 0.0);//red
glVertex3f(10.0f, 10.0f, 10.0f);//上面
glVertex3f(-10.0f, 10.0f, 10.0f);
glVertex3f(-10.0f, -10.0f, 10.0f);
glVertex3f(10.0f, -10.0f, 10.0f);
glColor3f(0.0, 1.0, 0.0);//green
glVertex3f(10.0f, 10.0f, -10.0f);//右面
glVertex3f(10.0f, 10.0f, 10.0f);
glVertex3f(10.0f, -10.0f, 10.0f);
glVertex3f(10.0f, -10.0f, -10.0f);
glColor3f(0.0, 0.0, 1.0);//blue
glVertex3f(10.0f, -10.0f, -10.0f);//下面
glVertex3f(-10.0f, -10.0f, -10.0f);
glVertex3f(-10.0f, 10.0f, -10.0f);
glVertex3f(10.0f, 10.0f, -10.0f);
glColor3f(1.0, 1.0, 0.0);//yellow
glVertex3f(-10.0f, 10.0f, 10.0f);//left
glVertex3f(-10.0f, 10.0f, -10.0f);
glVertex3f(-10.0f, -10.0f, -10.0f);
glVertex3f(-10.0f, -10.0f, 10.0f);
glColor3f(0.0, 1.0, 1.0);
glVertex3f(10.0f, 10.0f, -10.0f);//back
glVertex3f(-10.0f, 10.0f, -10.0f);
glVertex3f(-10.0f, 10.0f, 10.0f);
glVertex3f(10.0f, 10.0f, 10.0f);
glColor3f(1.0, 0.0, 1.0);
glVertex3f(10.0f, -10.0f, 10.0f);//front
glVertex3f(-10.0f, -10.0f, 10.0f);
glVertex3f(-10.0f, -10.0f, -10.0f);
glVertex3f(10.0f, -10.0f, -10.0f);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
void Init() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glShadeModel(GL_FLAT);
glFrontFace(GL_CW);
}
void SpecialKeys(int key, int x, int y) {
if (key == GLUT_KEY_UP)
xRot -= 5.0f;
if (key == GLUT_KEY_DOWN)
xRot += 5.0f;
if (key == GLUT_KEY_RIGHT)
yRot -= 5.0f;
if (key == GLUT_KEY_LEFT)
yRot += 5.0f;
if (key > 356.0f)
xRot = 0.0f;
if (key < -1.0f)
xRot = 355.0f;
if (key > 356.0f)
yRot = 0.0f;
if (key < -1.0f)
yRot = 355.0f;
glutPostRedisplay();
}
void ChangeSize(int w, int h)
{
GLfloat nRange = 30.0f;
if (h == 0) h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-nRange, nRange, -nRange * h / w, nRange * h / w, -nRange, nRange);
else
glOrtho(-nRange * w / h, nRange * w / h, -nRange, nRange, -nRange, nRange);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int main(int argc, char* argv[])
{
//初始化工具包
glutInit(&argc, argv);
//設定顯示模式
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB|GLUT_DEPTH);
//視窗設定
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("cube 1812030065-李詩雨");
//調用繪圖函數,回調函數,不斷監聽
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
Init();//必要的其他初始化函數
glutMainLoop();//進入循環
return 0;
}
3.移動光源
#include<GL/glut.h>
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
static GLfloat xRot1 = 0.0f;
static GLfloat yRot1 = 0.0f;
void Initial() {
GLfloat light_diffuse[] = { 1.0,1.0,1.0,1.0 };
GLfloat light_ambient[] = { 0.0,0.5,0.5,1.0 };
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);//設定環境光顔色
GLfloat light1_diffuse[] = { 1.0,1.0,1.0,1.0 };
GLfloat light1_ambient[] = { 0.0,0.5,0.5,1.0 };
glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient);//設定環境光顔色
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);//啟動光源LIGHT0
glEnable(GL_LIGHT1);//啟動光源LIGHT1
glEnable(GL_DEPTH_TEST);//深度測試
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
void ChangeSize(int w, int h)
{
if (h == 0) h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40.0f, (GLfloat)w / (GLfloat)h, 1.0f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLfloat light0_position[] = { 0.0f,0.0f,1.5f,1.0f };//最後一個參數1.0指前面設定的點位置,0.0為無限遠處
GLfloat light1_position[] = { 0.0f,0.0f,1.5f,1.0f };
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
glRotated(yRot, 0.0f, 1.0f, 0.0f);
glRotated(xRot, 1.0f, 0.0f, 0.0f);
//設定光源的位置
glLightfv(GL_LIGHT0, GL_POSITION, light0_position);
glTranslatef(0.0f, 0.0f, 1.5f);
//繪制一個黃色的光球
glDisable(GL_LIGHTING);
glColor3f(1.0f, 1.0f, 0.0f);
glutSolidSphere(0.1f, 50.0f, 50.0f);
glEnable(GL_LIGHTING);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -5.0f);
glRotated(yRot1, 0.0f, 1.0f, 0.0f);
glRotated(xRot1, 1.0f, 0.0f, 0.0f);
//設定光源的位置
glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
glTranslatef(0.0f, 0.0f, 1.5f);
//繪制一個紅色的光球
glDisable(GL_LIGHTING);
glColor3f(1.0f, 0.0f, 0.0f);
glutSolidSphere(0.1f, 50.0f, 50.0f);
glEnable(GL_LIGHTING);
glLoadIdentity();
//設定材質屬性
GLfloat mat_diffuse[] = { 0.0f,0.5f,1.0f,1.0f };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glTranslatef(0.0f, 0.0f, -5.0f);
glutSolidTorus(0.275, 0.85, 50, 50);
glLoadIdentity();
glutSwapBuffers();
}
void Keys(unsigned char key, int x, int y) {
switch (key)
{
case 'i':xRot -= 5.0f; break;
case 'k':xRot += 5.0f; break;
case 'j':yRot -= 5.0f; break;
case 'l':yRot += 5.0f; break;
case 'w':xRot1 -= 5.0f; break;
case 's':xRot1 += 5.0f; break;
case 'a':yRot1 -= 5.0f; break;
case 'd':yRot1 += 5.0f; break;
default:
break;
}
if (key > 356.0f)
xRot = 0.0f;
if (key < -1.0f)
xRot = 355.0f;
if (key > 356.0f)
yRot = 0.0f;
if (key < -1.0f)
yRot = 355.0f;
if (key > 356.0f)
xRot1 = 0.0f;
if (key < -1.0f)
xRot1 = 355.0f;
if (key > 356.0f)
yRot1 = 0.0f;
if (key < -1.0f)
yRot1 = 355.0f;
glutPostRedisplay();
}
int main(int argc, char* argv[])
{
//初始化工具包
glutInit(&argc, argv);
//設定顯示模式
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
//視窗設定
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("移動光源 1812030065-李詩雨");
//調用繪圖函數,回調函數,不斷監聽
glutReshapeFunc(ChangeSize);
glutDisplayFunc(Display);
glutKeyboardFunc(Keys);
Initial();//必要的其他初始化函數
glutMainLoop();//進入循環
return 0;
}
4.一維紋理映射,畫彩虹
#include<GL/glut.h>
#include <math.h>
#ifndef M_pI
#define M_PI 3.141592649
#endif
static GLubyte roygbiv_image[8][3] = {
{0x3f,0x00,0x3f},//深藍紫色
{0x7f,0x00,0x7f},//藍紫色
{0xbf,0x00,0xbf},//靛藍
{0x00,0x00,0xff},//藍色
{0x00,0xff,0x00},//綠色
{0xff,0xff,0x00},//黃色
{0xff,0x7f,0x00},//橙色
{0xff,0x00,0x00},//紅色
};
void ChangeSize(int width, int height) {
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(30.0, (float)width / (float)height, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
}
void Initial() {
glClearColor(0.3, 0.8, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//最基本的執行紋理映射的步驟
//1.定義紋理,2.控制紋理,3.說明紋理映射的方式,4.繪制場景
//1.定義紋理
glTexImage1D(GL_TEXTURE_1D, 0, 3, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, roygbiv_image);
//2.控制紋理,設定紋理如何對應螢幕像素,實作紋理縮放紋理重複
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//3.說明紋理映射方式
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
//表示使用最靠近使用紋理像素的四個紋素的權重平均值
//定義一維紋理,顔色分量為RGB
//寬度為8,邊界為0,使用無符号整數
//定義紋理環境參數,使用紋理圖像
}
void Display() {
GLfloat x, y, z, th;
//draw ground
glDisable(GL_TEXTURE_1D);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glPushMatrix();
glRotatef(10.0f, 0.0f, 1.0f, 0.0f);
glTranslatef(0.0, -40.0, -100.0);
glColor3f(0.0, 0.8, 0.0);
glBegin(GL_POLYGON);
for (th = 0.0; th < (2.0 * M_PI); th += (0.03125 * M_PI)) {
x = cos(th) * 200.0;
z = sin(th) * 200.0;
glVertex3f(x, 0.0, z);
}
glEnd();
//draw rainbow
glEnable(GL_TEXTURE_1D);
glBegin(GL_QUAD_STRIP);//共享四邊形
for (th = 0.0; th < (2.0 * M_PI); th += (0.03125 * M_PI)) {
x = cos(th) * 50.0;
y = sin(th) * 50.0;
z = -50.0;
glTexCoord1f(0.0);
glVertex3f(x, y, z);
x = cos(th) * 55.0;
y = sin(th) * 55.0;
z = -50.0;
glTexCoord1f(1.0);
glVertex3f(x, y, z);
}
glEnd();
glPopMatrix();
glFlush();
}
int main(int argc, char *argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH);
glutInitWindowPosition(100, 100);
glutInitWindowSize(792, 753);
glutCreateWindow("rainbow 1812030065-李詩雨");
//調用繪圖函數,回調函數,不斷監聽
glutReshapeFunc(ChangeSize);
glutDisplayFunc(Display);
Initial();//必要的其他初始化函數
glutMainLoop();//進入循環
return 0;
}
互動技術與計算機動畫
繪制折線
#include<gl/glut.h>
#include <iostream>
using namespace std;
int iPointNum = 0;
int a[100], b[100], w1, h1, w2, h2;
int winwidth = 400, winHeight = 300;
//變量的定義
void Initial() {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void ChangeSize(int w, int h) {
winwidth = w;
winHeight = h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, winwidth, 0.0, winHeight);
}
void Display() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
//繪制折線
if (iPointNum > 1) {
glBegin(GL_LINE_STRIP);
for (int i = 0; i < iPointNum; i++)
glVertex2i(a[i], b[i]);
glEnd();
glBegin(GL_LINES);
glVertex2i(w1, h1);
glVertex2i(w2, h2);
glEnd();
}
glutSwapBuffers();
}
void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse) {
//滑鼠函數
//按下滑鼠左鍵繪制折線
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
if (iPointNum == 0) {
w1 = xMouse; h1 = winHeight - yMouse;
a[iPointNum] = w1; b[iPointNum] = h1;
iPointNum++;
}
else {
w2 = xMouse; h2 = winHeight - yMouse;
a[iPointNum] = w2; b[iPointNum] = h2;
w1 = w2; h1 = h2;
iPointNum++;
glutPostRedisplay();
}
}
/*按下滑鼠右鍵結束繪制*/
if (button == GLUT_RIGHT_BUTTON && action == GLUT_DOWN) {
iPointNum = 0;
}
}
void PassiveMouseMove(GLint xMouse, GLint yMouse) {
//滑鼠移動函數
//記錄滑鼠指針 的目前位置
if (iPointNum) {
w2 = xMouse;
h2 = winHeight - yMouse;
glutPostRedisplay();
}
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 100);
glutCreateWindow("橡皮筋技術 181203065 李詩雨");
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize);
glutMouseFunc(MousePlot);//指定滑鼠響應函數
glutPassiveMotionFunc(PassiveMouseMove);//指定滑鼠移動響應函數
Initial();
glutMainLoop();
return 0;
}
繪制矩形
#include<gl/glut.h>
#include <iostream>
using namespace std;
int iPointNum = 0;
int w1, h1, w2, h2;
int winwidth = 400, winHeight = 300;
//變量的定義
void Initial() {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
}
void ChangeSize(int w, int h) {
winwidth = w;
winHeight = h;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0, winwidth, 0.0, winHeight);
}
void Display() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
//繪制
glBegin(GL_LINES);
glVertex2i(w1, h1);
glVertex2i(w2, h1);
glEnd();
glBegin(GL_LINES);
glVertex2i(w2, h1);
glVertex2i(w2, h2);
glEnd();
glBegin(GL_LINES);
glVertex2i(w1, h1);
glVertex2i(w1, h2);
glEnd();
glBegin(GL_LINES);
glVertex2i(w1, h2);
glVertex2i(w2, h2);
glEnd();
glutSwapBuffers();
}
void MousePlot(GLint button, GLint action, GLint xMouse, GLint yMouse) {
//滑鼠函數
//按下滑鼠左鍵繪制
if (button == GLUT_LEFT_BUTTON && action == GLUT_DOWN) {
if (iPointNum == 0||iPointNum==2) {
iPointNum = 1;
w1 = xMouse; h1 = winHeight - yMouse;
}
else {
w2 = xMouse; h2 = winHeight - yMouse;
iPointNum = 2;
glutPostRedisplay();
}
}
}
void PassiveMouseMove(GLint xMouse, GLint yMouse) {
//滑鼠移動函數
//記錄滑鼠指針 的目前位置
if (iPointNum==1) {
w2 = xMouse;
h2 = winHeight - yMouse;
glutPostRedisplay();
}
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 100);
glutCreateWindow("橡皮筋技術 181203065 李詩雨");
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize);
glutMouseFunc(MousePlot);//指定滑鼠響應函數
glutPassiveMotionFunc(PassiveMouseMove);//指定滑鼠移動響應函數
Initial();
glutMainLoop();
return 0;
}
模型函數繪制示例(菜單)
#include <GL/glut.h>
static GLsizei iMode = 1;
//x,y 方向旋轉參數
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;
void Initial() {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glColor3f(0.0f, 0.0f, 0.0f);
}
void ChangeSize(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1.5f, 1.5f, -1.5f, 1.5f);
}
void Display() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//繞x軸旋轉
//繞y軸旋轉
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
/*指定要繪制的圖元*/
switch (iMode)
{
case 1:
/*繪制線框正四面體*/
glutWireTetrahedron(); break;
case 2:
/*繪制實體正四面體*/
glutSolidTetrahedron(); break;
case 3:
/*繪制線框正八面體*/
glutWireOctahedron(); break;
case 4:
/*繪制實體正八面體*/
glutSolidOctahedron(); break;
case 5:
/*繪制線框球面*/
glutWireSphere(1.0f,15,15); break;
case 6:
/*繪制實體球面*/
glutSolidSphere(1.0f, 15, 15); break;
case 7:
/*繪制線框茶壺*/
glutWireTeapot(1.0f); break;
case 8:
/*繪制實體茶壺*/
glutSolidTeapot(1.0f); break;
default:break;
}
glFlush();
}
void ProcessMenu(int value) {
//選擇繪制模式
iMode = value;
glutPostRedisplay();
}
//鍵盤繪制函數
void SpecialKeys(int key, int x, int y) {
//繞x軸旋轉的角度變化
if (key == GLUT_KEY_UP) xRot -= 0.5f;
if (key == GLUT_KEY_DOWN) xRot += 0.5f;
//繞y軸旋轉的角度的變化
if (key == GLUT_KEY_LEFT) yRot -= 0.5f;
if (key == GLUT_KEY_RIGHT) yRot += 0.5f;
if (xRot > 356.0f) xRot = 0.0f;
if (xRot < -1.0f) xRot = 355.0f;
if (yRot > 356.0f) yRot = 0.0f;
if (yRot < -1.0f) yRot = 355.0f;
glutPostRedisplay();
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 100);
glutCreateWindow("openGl模型繪制函數示例 181203065 李詩雨");
/*建立菜單并定義菜單的回調函數*/
/*創造GLUT多面體繪制菜單*/
int nGLutPolyMenu = glutCreateMenu(ProcessMenu);
glutAddMenuEntry("線框正四面體", 1);
glutAddMenuEntry("實體正四面體", 2);
glutAddMenuEntry("線框正八面體", 3);
glutAddMenuEntry("實體正八面體", 4);
/*建立GLUT曲面繪制菜單*/
int nGLutCurveMenu = glutCreateMenu(ProcessMenu);;
glutAddMenuEntry("線框球面", 5);
glutAddMenuEntry("實體球面", 6);
glutAddMenuEntry("線框茶壺", 7);
glutAddMenuEntry("實體茶壺", 8);
/*建立主菜單*/
int nMainMenu = glutCreateMenu(ProcessMenu);
glutAddSubMenu("GLUT多面體繪制", nGLutPolyMenu);
glutAddSubMenu("GLUT曲面繪制", nGLutCurveMenu);
/*單擊右鍵顯示菜單*/
glutAttachMenu(GLUT_RIGHT_BUTTON);
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
Initial();
glutMainLoop();
return 0;
}
動畫:日地月模型
#include <GL/glut.h>
float fsunangle;
float fearthangle;
void Initial() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GLfloat diffuse[] = { 1.0f,1.0f,0.0f,1.0f };
GLfloat position[] = { 0.0f,0.0f,-250.0f,1.0f };
glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
glLightfv(GL_LIGHT1, GL_POSITION, position);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1); //黃色光
glEnable(GL_DEPTH_TEST);
}
void Display() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除顔色和深度緩沖區
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -250.0f); //将圖形沿z軸負方向移動
//太陽
GLfloat mat_diffuse[] = { 0.2f,0.8f,1.0f,1.0f };
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
GLfloat mat_emission1[] = { 0.98,0.25,0.12,1.0 };
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission1);//設定太陽顔色為紅
glutSolidSphere(30.0f, 40, 50);
glEnable(GL_LIGHTING);
//earth
GLfloat mat_diffuse2[] = { 0.8,0.8,0.8,1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse2);
GLfloat mat_emission2[] = { 0.0,0.0,1.0,1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emission2);//地球顔色設定為藍色
glRotatef(fsunangle, 0.0f, 1.0f, 0.0f);//繞y軸旋轉--地球繞太陽轉
glTranslatef(100.f, 0.0f, 0.0f);//平移一段距離
glutSolidSphere(8.0f, 40, 50);//draw earth
//moon
GLfloat mat_diffuse3[] = { 0.4, 0.4, 0.4, 1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse3);
GLfloat mat_emission3[] = { 0.25,0.25,0.25,1.0 };
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_emission3);
glRotatef(fearthangle, 0.0f, 1.0f, 1.0f);//繞斜軸旋轉
glTranslatef(20.f, 0.0f, 0.0f);//在地球的基礎上再往外平移一段距離
glutSolidSphere(4.0f, 40, 50);//draw moon
fsunangle += 4.0f;//地球旋轉步長
fearthangle += 36.0f;//月球旋轉步長
if (fsunangle > 360.0f) {
fsunangle = 4.0f;
}
if (fearthangle > 360.0f) {
fearthangle = 36.0f;
}
glutSwapBuffers();
}
void ChangeSize(int w, int h) {
GLfloat nRange = 80.f;
if (h == 0) h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)w / (GLfloat)h, 1.0f, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void TimerFunc(int value) {
glutPostRedisplay();
glutTimerFunc(80, TimerFunc, 1);//80 ms restart
}
int main(int argc, char* argv[]) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutInitWindowPosition(100, 100);
glutCreateWindow("日地月模型 181203065 李詩雨");
glutDisplayFunc(Display);
glutReshapeFunc(ChangeSize);
glutTimerFunc(500,TimerFunc,1);
Initial();
glutMainLoop();
return 0;
}