DOO-SABIN 細分正方體(2)利用半邊資料結構表示(一次和兩次細分)
阿新 • • 發佈:2019-01-08
最後放上效果。。如果我有時間的話一定完善之#include <windows.h> #include <math.h> #include <gl/GL.h> #include <GL/glut.h> //static const GLfloat vertex_list[][3] = { // -0.5f, -0.5f, -0.5f, // 0.5f, -0.5f, -0.5f, // 0.5f, 0.5f, -0.5f, // -0.5f, 0.5f, -0.5f, // -0.5f, -0.5f, 0.5f, // 0.5f, -0.5f, 0.5f, // 0.5f, 0.5f, 0.5f, // -0.5f, 0.5f, 0.5f, //}; //static const GLint index_list[][4] = { // 0, 1, 2, 3,//bottem // 0, 3, 7, 4,//left // 2, 3, 7, 6,//front // 1, 2, 6, 5,//right // 0, 1, 5, 4,//back // 4, 5, 6, 7//top //}; float M_PI = 3.14159265f; static float c = M_PI / 180.0f; //弧度和角度轉換引數 static int du = 90, oldmy = -1, oldmx = -1; //du是視點繞y軸的角度,opengl裡預設y軸是上方向 static float r = 3.1f, h = 0.0f; //r是視點繞y軸的半徑,h是視點高度即在y軸上的座標 float zoom = 1.0f; int Nump;//記錄當前點數 int Nume;//記錄當前半邊數 int Numf;//記錄當前面數 typedef struct HE_vert { float x; float y; float z; struct HE_edge *edge; // one of the half-edges emantating from the vertex }HE_vert; typedef struct HE_edge { struct HE_vert *vert; // vertex at the end of the half-edge struct HE_edge *pair; // oppositely oriented adjacent half-edge struct HE_face *face; // face the half-edge borders struct HE_edge *next; // next half-edge around the face }HE_edge; typedef struct HE_face { struct HE_edge *edge; // one of the half-edges bordering the face }HE_face; struct HE_vert *v[8]; struct HE_edge *e[6][4]; struct HE_face *f[6]; void idv() { for (int i = 0; i < 8; i++) { v[i] = (HE_vert*)malloc(sizeof(HE_vert)); } } void ide() { for (int i = 0; i < 6; i++) { for (int j = 0; j < 4; j++) { e[i][j] = (HE_edge*)malloc(sizeof(HE_edge)); } } } void idf() { for (int i = 0; i < 6; i++) { f[i] = (HE_face*)malloc(sizeof(HE_face)); } } struct HE_edge *en = (HE_edge*)malloc(sizeof(HE_edge)); struct HE_edge *en1 = (HE_edge*)malloc(sizeof(HE_edge));//用來表示臨時邊 void idd()//用於初始化矩陣 { idv(); ide(); idf(); }; void id1()//初始化函式 { //初始化點 v[0]->x = -0.5f; v[0]->y = -0.5f; v[0]->z = -0.5f; v[0]->edge = e[0][0]; v[1]->x = 0.5f; v[1]->y = -0.5f; v[1]->z = -0.5f; v[1]->edge = e[0][1]; v[2]->x = 0.5f; v[2]->y = 0.5f; v[2]->z = -0.5f; v[2]->edge = e[0][2]; v[3]->x = -0.5f; v[3]->y = 0.5f; v[3]->z = -0.5f; v[3]->edge = e[0][3]; v[4]->x = -0.5f; v[4]->y = -0.5f; v[4]->z = 0.5f; v[4]->edge = e[5][0]; v[5]->x = 0.5f; v[5]->y = -0.5f; v[5]->z = 0.5f; v[5]->edge = e[5][3]; v[6]->x = 0.5f; v[6]->y = 0.5f; v[6]->z = 0.5f; v[6]->edge = e[5][2]; v[7]->x = -0.5f; v[7]->y = 0.5f; v[7]->z = 0.5f; v[7]->edge = e[5][1]; //struct HE_edge //{ // HE_vert* vert; // vertex at the end of the half-edge // HE_edge* pair; // oppositely oriented adjacent half-edge // HE_face* face; // face the half-edge borders // HE_edge* next; // next half-edge around the face //}; //初始化邊 //初始化face for (int i = 0; i < 6; i++) { for (int j = 0; j < 4; j++) { e[i][j]->face = f[i]; } } //初始化next for (int i = 0; i < 6; i++) { for (int j = 0; j < 4; j++) { if (j != 3) { e[i][j]->next = e[i][j+1]; } else { e[i][j]->next = e[i][0]; } } } e[0][0]->vert = v[1]; e[0][1]->vert = v[2]; e[0][2]->vert = v[3]; e[0][3]->vert = v[0]; e[1][1]->vert = v[7]; e[1][2]->vert = v[4]; e[1][3]->vert = v[0]; e[1][0]->vert = v[3]; e[2][0]->vert = v[6]; e[2][1]->vert = v[7]; e[2][2]->vert = v[3]; e[2][3]->vert = v[2]; e[3][0]->vert = v[5]; e[3][1]->vert = v[6]; e[3][2]->vert = v[2]; e[3][3]->vert = v[1]; e[4][0]->vert = v[4]; e[4][1]->vert = v[5]; e[4][2]->vert = v[1]; e[4][3]->vert = v[0]; e[5][0]->vert = v[7]; e[5][1]->vert = v[6]; e[5][2]->vert = v[5]; e[5][3]->vert = v[4]; e[0][0]->pair = e[4][3]; e[0][1]->pair = e[3][3]; e[0][2]->pair = e[2][3]; e[0][3]->pair = e[1][0]; e[1][1]->pair = e[2][2]; e[1][2]->pair = e[5][0]; e[1][3]->pair = e[4][0]; e[1][0]->pair = e[0][3]; e[2][0]->pair = e[3][2]; e[2][1]->pair = e[5][1]; e[2][2]->pair = e[1][1]; e[2][3]->pair = e[0][2]; e[3][0]->pair = e[4][2]; e[3][1]->pair = e[5][2]; e[3][2]->pair = e[2][0]; e[3][3]->pair = e[0][1]; e[4][0]->pair = e[1][3]; e[4][1]->pair = e[5][3]; e[4][2]->pair = e[3][0]; e[4][3]->pair = e[0][0]; e[5][0]->pair = e[1][2]; e[5][1]->pair = e[2][1]; e[5][2]->pair = e[3][1]; e[5][3]->pair = e[4][1]; //struct HE_edge //{ // HE_vert* vert; // vertex at the end of the half-edge // HE_edge* pair; // oppositely oriented adjacent half-edge // HE_face* face; // face the half-edge borders // HE_edge* next; // next half-edge around the face //}; f[0]->edge = e[0][0]; f[1]->edge = e[1][0]; f[2]->edge = e[2][0]; f[3]->edge = e[3][0]; f[4]->edge = e[4][0]; f[5]->edge = e[5][0]; } //做第一次細分 struct HE_vert *v1[30]; struct HE_edge *e1[50][4]; struct HE_face *f1[30]; struct HE_edge *ep1[3]; void idv1() { for (int i = 0; i < 30; i++) { v1[i] = (HE_vert*)malloc(sizeof(HE_vert)); } } void ide1() { for (int i = 0; i < 50; i++) { for (int j = 0; j < 4; j++) { e1[i][j] = (HE_edge*)malloc(sizeof(HE_edge)); } } } void idf1() { for (int i = 0; i < 30; i++) { f1[i] = (HE_face*)malloc(sizeof(HE_face)); } } void idep1() { for (int i = 0; i < 3; i++) { ep1[i] = (HE_edge*)malloc(sizeof(HE_edge)); } } void idd1()//用於初始化矩陣 { idv1(); ide1(); idf1(); idep1(); }; void id2()//一次細分函式 { id1();//繪製初始化矩陣 //細分一次 int nf = 6;//表示上一次細分的面數 //以下部分計算點 int t = 0; for (int i = 0; i < nf; i++) { en = f[i]->edge; do { v1[t]->x = (en->pair->vert->x) * 9 / 16 + (en->next->pair->vert->x + en->next->next->next->pair->vert->x) * 3 / 16 + (en->next->next->pair->vert->x) * 1 / 16; v1[t]->y = (en->pair->vert->y) * 9 / 16 + (en->next->pair->vert->y + en->next->next->next->pair->vert->y) * 3 / 16 + (en->next->next->pair->vert->y) * 1 / 16; v1[t]->z = (en->pair->vert->z) * 9 / 16 + (en->next->pair->vert->z + en->next->next->next->pair->vert->z) * 3 / 16 + (en->next->next->pair->vert->z) * 1 / 16; en = en->next; t = t + 1; } while (en != f[i]->edge); } //點還沒有最後的一個指標 Nump = t ; t = 0; for (int i = 0; i < nf; i++) { int t1 = 0; en = f[i]->edge; do { e1[i][t1]->face = f1[i]; if (t1 != 3) { e1[i][t1]->next = e1[i][t1 + 1]; e1[i][t1]->vert = v1[t + 1];//因為是指向末尾點 } else { e1[i][t1]->next = e1[i][0]; e1[i][t1]->vert = v1[t - 3];//指向開頭 } v1[t]->edge = e1[i][t1];//補充好點的最後一個資訊 en = en->next; t = t + 1; t1++; } while (en != f[i]->edge); } //面邊還沒有對邊的資訊 //面面已經確定好 for (int i = 0; i < nf; i++) { f1[i]->edge = e1[i][0]; } ////開始做邊面 for (int i = 0; i < 6; i++) { for (int j = 0; j < 4; j++) { int sub = e[i][j]->pair - e[i][j]; for (int u = 0; u < 6; u++) { for (int v = 0; v < 4; v++) { if (e1[u][v] - e1[i][j] == sub) { e1[i][j]->pair = e1[u][v]; goto ss; } } } ss:; } } //以上程式碼實現的作用和下面的賦值是一樣的,可是看起來複雜度有點高 /*e1[0][0]->pair = e1[4][3]; e1[0][1]->pair = e1[3][3]; e1[0][2]->pair = e1[2][3]; e1[0][3]->pair = e1[1][0]; e1[1][1]->pair = e1[2][2]; e1[1][2]->pair = e1[5][0]; e1[1][3]->pair = e1[4][0]; e1[1][0]->pair = e1[0][3]; e1[2][0]->pair = e1[3][2]; e1[2][1]->pair = e1[5][1]; e1[2][2]->pair = e1[1][1]; e1[2][3]->pair = e1[0][2]; e1[3][0]->pair = e1[4][2]; e1[3][1]->pair = e1[5][2]; e1[3][2]->pair = e1[2][0]; e1[3][3]->pair = e1[0][1]; e1[4][0]->pair = e1[1][3]; e1[4][1]->pair = e1[5][3]; e1[4][2]->pair = e1[3][0]; e1[4][3]->pair = e1[0][0]; e1[5][0]->pair = e1[1][2]; e1[5][1]->pair = e1[2][1]; e1[5][2]->pair = e1[3][1]; e1[5][3]->pair = e1[4][1];*/ int a[6][4];//一條邊和其對邊只算一次 for (int i = 0; i < 6; i++) { for (int j = 0; j < 4; j++) { a[i][j] = 0; } } int t2 = 6;//記錄邊表的資料 for (int i = 0; i < 6; i++) { for (int j = 0; j < 4; j++)//每面上的四個邊 { if (a[i][j] == 1)//如果其對邊已經用過了,那麼直接跳過 { continue; } else { e1[t2][0]->vert = e1[i][j]->next->next->next->vert;//邊面的第一條邊 e1[t2][0]->pair = e1[i][j];//補齊了一半的對邊 a[i][j] = 1; en = e1[i][j]->pair; e1[t2][1]->vert = e1[i][j]->pair->vert;//邊面的第二條邊 e1[t2][2]->vert = en->next->next->next->vert;//邊面的第三條邊 e1[t2][2]->pair = en; for (int u = i; u < 6; u++) { for (int v = 0; v < 4; v++) { if ((&a[u][v] - &a[i][j]) == (e1[i][j]->pair - e1[i][j]) / 5) { a[u][v] = 1; goto sss;//跳出兩重迴圈 } } } sss:; //為了測試陣列間距離,實驗證明距離是5 //int sub = (e[i][j]->pair - e[i][j]) / 5; //int sub1 = (&a[1][0] - &a[0][3]) ; //int sub2 = (e[4][3] - e[i][j]); //int sub3 = (e[0][3] - e[i][j]); //int sub4 = (e[1][0] - e[0][3]); //int sub5 = (e[2][3] - e[i][j]); e1[t2][3]->vert = e1[i][j]->vert;//邊面的第四條邊 e1[i][j]->pair = e1[t2][0];//補全對邊 en->pair = e1[t2][2];//補全另一條對邊 e1[t2][0]->next = e1[t2][1]; e1[t2][1]->next = e1[t2][2]; e1[t2][2]->next = e1[t2][3]; e1[t2][3]->next = e1[t2][0]; e1[t2][0]->face = f1[t2]; e1[t2][1]->face = f1[t2]; e1[t2][2]->face = f1[t2]; e1[t2][3]->face = f1[t2]; f1[t2]->edge = e1[t2][0]; t2++; } } } //最後的就是三角面以及對邊 for (int i = 0; i < 8; i++) { int nn = 0; for (int u = 0; u < 6; u++) { for (int s = 0; s < 4; s++) { if (v[i] != e[u][s]->vert) { continue; } else { ep1[nn] = e1[u][s]; nn = nn + 1; } } } e1[t2][0]->vert = ep1[0]->vert; e1[t2][0]->pair = ep1[0]->next->pair->next; ep1[0]->next->pair->next->pair = e1[t2][0]; if (ep1[2]->vert == ep1[0]->next->pair->next->vert) { e1[t2][2]->vert = ep1[2]->vert; e1[t2][2]->pair = ep1[2]->next->pair->next; e1[t2][1]->vert = ep1[1]->vert; e1[t2][1]->pair = ep1[1]->next->pair->next; ep1[2]->next->pair->next->pair = e1[t2][2]; ep1[1]->next->pair->next->pair = e1[t2][1]; } else if (ep1[1]->vert == ep1[0]->next->pair->next->vert) { e1[t2][2]->vert = ep1[1]->vert; e1[t2][2]->pair = ep1[1]->next->pair->next; e1[t2][1]->vert = ep1[2]->vert; e1[t2][1]->pair = ep1[2]->next->pair->next; ep1[1]->next->pair->next->pair = e1[t2][2]; ep1[2]->next->pair->next->pair = e1[t2][1]; } e1[t2][0]->next = e1[t2][1]; e1[t2][1]->next = e1[t2][2]; e1[t2][2]->next = e1[t2][0]; e1[t2][0]->face = f1[t2]; e1[t2][1]->face = f1[t2]; e1[t2][2]->face = f1[t2]; f1[t2]->edge = e1[t2][0]; t2++; } Numf = t2; Nume = Numf * 4; } //做第二次細分 struct HE_vert *v2[100]; struct HE_edge *e2[150][4]; struct HE_face *f2[100]; struct HE_edge *ep2[3]; void idv2() { for (int i = 0; i < 100; i++) { v2[i] = (HE_vert*)malloc(sizeof(HE_vert)); } } void ide2() { for (int i = 0; i < 150; i++) { for (int j = 0; j < 4; j++) { e2[i][j] = (HE_edge*)malloc(sizeof(HE_edge)); } } } void idf2() { for (int i = 0; i < 100; i++) { f2[i] = (HE_face*)malloc(sizeof(HE_face)); } } void idep2() { for (int i = 0; i < 3; i++) { ep2[i] = (HE_edge*)malloc(sizeof(HE_edge)); } } void idd2()//用於初始化矩陣 { idv2(); ide2(); idf2(); idep2(); }; int Nump1; int Nume1; int Numf1; void id3()//一次細分函式 { id1(); id2(); //以下部分計算點 int t = 0; for (int i = 0; i < Numf-8; i++) { en = f1[i]->edge; do { v2[t]->x = (en->pair->vert->x) * 9 / 16 + (en->next->pair->vert->x + en->next->next->next->pair->vert->x) * 3 / 16 + (en->next->next->pair->vert->x) * 1 / 16; v2[t]->y = (en->pair->vert->y) * 9 / 16 + (en->next->pair->vert->y + en->next->next->next->pair->vert->y) * 3 / 16 + (en->next->next->pair->vert->y) * 1 / 16; v2[t]->z = (en->pair->vert->z) * 9 / 16 + (en->next->pair->vert->z + en->next->next->next->pair->vert->z) * 3 / 16 + (en->next->next->pair->vert->z) * 1 / 16; en = en->next; t = t + 1; } while (en != f1[i]->edge); } //點還沒有最後的一個指標 for (int i = Numf - 8; i < Numf ; i++) { en = f1[i]->edge; do { v2[t]->x = (en->pair->vert->x) * 2 / 3 + (en->next->pair->vert->x + en->next->next->pair->vert->x) * 1 / 6 ; v2[t]->y = (en->pair->vert->y) * 2 / 3 + (en->next->pair->vert->y + en->next->next->pair->vert->y) * 1 / 6; v2[t]->z = (en->pair->vert->z) * 2 / 3 + (en->next->pair->vert->z + en->next->next->pair->vert->z) * 1 / 6; en = en->next; t = t + 1; } while (en != f1[i]->edge); } Nump1 = t; Numf1 = Nume / 2 + Nump + Numf; t = 0; for (int i = 0; i < Numf-8; i++) { int t1 = 0; en = f1[i]->edge; do { e2[i][t1]->face = f1[i]; if (t1 != 3) { e2[i][t1]->next = e2[i][t1 + 1]; e2[i][t1]->vert = v2[t + 1];//因為是指向末尾點 } else { e2[i][t1]->next = e2[i][0]; e2[i][t1]->vert = v2[t - 3];//指向開頭 } v2[t]->edge = e2[i][t1];//補充好點的最後一個資訊 en = en->next; t = t + 1; t1++; } while (en != f1[i]->edge); } //面邊還沒有對邊的資訊 //三角面另說 for (int i = Numf - 8; i < Numf ; i++) { int t1 = 0; en = f1[i]->edge; do { e2[i][t1]->face = f1[i]; if (t1 != 2) { e2[i][t1]->next = e2[i][t1 + 1]; e2[i][t1]->vert = v2[t + 1];//因為是指向末尾點 } else { e2[i][t1]->next = e2[i][0]; e2[i][t1]->vert = v2[t - 2];//指向開頭 } v2[t]->edge = e2[i][t1];//補充好點的最後一個資訊 en = en->next; t = t + 1; t1++; } while (en != f1[i]->edge); } //面面已經確定好 for (int i = 0; i < Numf; i++) { f2[i]->edge = e2[i][0]; } //開始繪製邊面 for (int i = 0; i < Numf; i++) { for (int j = 0; j < 4; j++) { int sub = e1[i][j]->pair - e1[i][j]; for (int u = 0; u < Numf; u++) { for (int v = 0; v < 4; v++) { if (e2[u][v] - e2[i][j] == sub) { e2[i][j]->pair = e2[u][v]; goto ss; } } } ss:; } } ////開始做邊面 int a[18][4];//一條邊和其對邊只算一次 for (int i = 0; i < 18; i++) { for (int j = 0; j < 4; j++) { a[i][j] = 0; } } int t2 = Numf;//記錄邊表的資料 for (int i = 0; i < 18; i++) { for (int j = 0; j < 4; j++)//每面上的四個邊 { if (a[i][j] == 1)//如果其對邊已經用過了,那麼直接跳過 { continue; } else { e2[t2][0]->vert = e2[i][j]->next->next->next->vert;//邊面的第一條邊 e2[t2][0]->pair = e2[i][j];//補齊了一半的對邊 a[i][j] = 1; en = e2[i][j]->pair; e2[t2][1]->vert = e2[i][j]->pair->vert;//邊面的第二條邊 do { en1 = en; en = en->next; } while (en != e2[i][j]->pair);//找到一條邊的起始 e2[t2][2]->vert = en1->vert;//邊面的第三條邊 e2[t2][2]->pair = en; for (int u = 0; u < 18; u++) { for (int v = 0; v < 4; v++) { if ((&a[u][v] - &a[i][j]) == (e2[i][j]->pair - e2[i][j]) / 5) { a[u][v] = 1; goto sss;//跳出兩重迴圈 } } } sss:; //為了測試陣列間距離,實驗證明距離是5 //int sub = (e[i][j]->pair - e[i][j]) / 5; //int sub1 = (&a[1][0] - &a[0][3]) ; //int sub2 = (e[4][3] - e[i][j]); //int sub3 = (e[0][3] - e[i][j]); //int sub4 = (e[1][0] - e[0][3]); //int sub5 = (e[2][3] - e[i][j]); e2[t2][3]->vert = e2[i][j]->vert;//邊面的第四條邊 e2[i][j]->pair = e2[t2][0];//補全對邊 en->pair = e2[t2][2];//補全另一條對邊 e2[t2][0]->next = e2[t2][1]; e2[t2][1]->next = e2[t2][2]; e2[t2][2]->next = e2[t2][3]; e2[t2][3]->next = e2[t2][0]; e2[t2][0]->face = f2[t2]; e2[t2][1]->face = f2[t2]; e2[t2][2]->face = f2[t2]; e2[t2][3]->face = f2[t2]; f2[t2]->edge = e2[t2][0]; t2++; } } } Nume1 = t2; } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(80.0f, 1.0f, 1.0f, 1000.0f); glMatrixMode(GL_MODELVIEW); id1(); id2(); id3(); glLoadIdentity(); gluLookAt(r*cos(c*du)*cos(c*h)*zoom, r*sin(c*h)*zoom, r*sin(c*du)*cos(c*h)*zoom, 0, 0, 0, 0, 1, 0); //從視點看遠點,y 軸方向(0, 1, 0)是上方向 //glColor3f(1, 0, 0); //for (int i = 0; i < 6; i++) //{ // en = f[i]->edge; // do { // glBegin(GL_LINES); // { // glVertex3f(en->vert->x, en->vert->y, en->vert->z);//其中每條邊由兩點組成 // glVertex3f(en->pair->vert->x, en->pair->vert->y, en->pair->vert->z);//其中每條邊由兩點組成 // } // glEnd(); // en = en->next; // } while (en != f[i]->edge); // //} glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);//只讓多邊形繪製邊框 //glColor3f(1, 0, 0); ////繪製面面 //for (int i = 0; i < 26; i++) //{ // en = f1[i]->edge; // glBegin(GL_POLYGON); // do { // { // glVertex3f(en->vert->x, en->vert->y, en->vert->z);//其中每條邊由兩點組成 // } // en = en->next; // } while (en != f1[i]->edge); // glEnd(); //} //glColor3f(1, 0, 0); //for (int i = 0; i < 26; i++) //{ // en = f1[i]->edge; // do { // glBegin(GL_LINES); // { // glVertex3f(en->vert->x, en->vert->y, en->vert->z);//其中每條邊由兩點組成 // glVertex3f(en->pair->vert->x, en->pair->vert->y, en->pair->vert->z);//其中每條邊由兩點組成 // } // glEnd(); // en = en->next; // } while (en != f1[i]->edge); //} //繪製細分點 //for (int i = 0; i < 24; i++) //{ // glPointSize(2); // glColor3f(1, 1, 0); // glBegin(GL_POINTS); // { // glVertex3f(v1[i]->x, v1[i]->y, v1[i]->z);//繪製點 // } // glEnd(); //} for (int i = 0; i < Nump1; i++) { glPointSize(2); glColor3f(1, 1, 0); glBegin(GL_POINTS); { glVertex3f(v2[i]->x, v2[i]->y, v2[i]->z);//繪製點 } glEnd(); } for (int i = 0; i <26; i++) { en = f2[i]->edge; glBegin(GL_POLYGON); do { { glVertex3f(en->vert->x, en->vert->y, en->vert->z);//其中每條邊由兩點組成 } en = en->next; } while (en != f2[i]->edge); glEnd(); } glColor3f(0,1,1); for (int i = 26; i <74; i++) { en = f2[i]->edge; glBegin(GL_POLYGON); do { { glVertex3f(en->vert->x, en->vert->y, en->vert->z);//其中每條邊由兩點組成 } en = en->next; } while (en != f2[i]->edge); glEnd(); } glFlush(); glutSwapBuffers(); } void Mouse(int button, int state, int x, int y) //處理滑鼠點選 { if (state == GLUT_DOWN) //第一次滑鼠按下時,記錄滑鼠在視窗中的初始座標 oldmx = x, oldmy = y; if (state == GLUT_UP && button == GLUT_WHEEL_UP) { zoom = zoom + 0.2; if (zoom >= 2)zoom = 2; //glutPostRedisplay(); } if (state == GLUT_UP && button == GLUT_WHEEL_DOWN) { zoom = zoom - 0.2; if (zoom <= 0.6) zoom = 0.6; //glutPostRedisplay(); } } void onMouseMove(int x, int y) //處理滑鼠拖動 { //printf("%d\n",du); du += x - oldmx; //滑鼠在視窗x軸方向上的增量加到視點繞y軸的角度上,這樣就左右轉了 h += (y - oldmy); //滑鼠在視窗y軸方向上的改變加到視點的y座標上,就上下轉了 if (h > 90) { h = 90; } else if (h < -90) { h = -90; } //if (h>1.0f) h = 1.0f; //視點y座標作一些限制,不會使視點太奇怪 //else if (h<-1.0f) h = -1.0f; oldmx = x, oldmy = y; //把此時的滑鼠座標作為舊值,為下一次計算增量做準備 } int main(int argc, char *argv[]) { idd(); idd1(); idd2(); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowPosition(100, 100); glutInitWindowSize(400, 400); glutCreateWindow("OpenGL"); glutDisplayFunc(display); glutIdleFunc(display); //設定不斷呼叫顯示函式 glutMouseFunc(Mouse); glutMotionFunc(onMouseMove); glutMainLoop(); return 0; }