1. 程式人生 > >[計算機圖形學 with OpenGL] Chapter10 OpenGL三維觀察程序示例

[計算機圖形學 with OpenGL] Chapter10 OpenGL三維觀察程序示例

chap 而不是 max argv func open position style windows

  10.10節書中給出了一個程序示例,有一個填充正方形,從側面的角度觀察並畫到屏幕上。

  技術分享圖0

  這裏進一步畫出一個立方體,將相機放入立方體中心,旋轉相機,達到在立方體中旋轉看到不同畫面的效果。

步驟:

  1 使用的是4.9節中的OpenGL頂點數組方法。創建一個立方體100*100*100,坐標範圍(0, 0, 0)到(100, 100, 100)。

  2 立方體各面使用不同的顏色,調整頂點順序以確保相機看到的都是填充面而不是線框圖。

  3 將投影觀察點(即觀察系原點)設置在矩形中心P0 = (50, 50, 50)。

  4 視點Pref為相機朝向的點(註意,這個不是觀察點),初始設置為Pref =(0, 50, 0)。

  5 修改Pref的坐標,使其繞x=z=50進行逆時針旋轉(與y軸平行的旋轉公式(9.9)),最終實現相機在立方體中逆時針旋轉,看到不同面的效果。

備註:

  1 與y軸平行的旋轉公式,先將旋轉軸平移到與y軸重合,再進行旋轉:z‘ = z * cosθ - x * sinθ, x‘ = z * sinθ + x * cosθ, y‘=y;

  2 近平面距離投影觀察點不能為0,近平面和遠平面的坐標會影響畫面的效果,調整範圍以確保畫面不太離譜(並不真實)

問題:這個投影效果看起來並不真實。

  1 調整dnear和dfar時,會影響投影效果。dnear

離P0越近,投影效果強度更大,離得遠的點看著更小。見圖2。

  2 當調整近裁剪面大小且當立方體旋轉時,投影畫面會改變寬度,看起來會更奇怪。見圖3。

技術分享
  1 include <GLUT/GLUT.h>
  2 #include <math.h>
  3 
  4 GLint winWidth = 600, winHeight = 600;
  5 GLfloat x0 = 50.0, y00 = 50.0, z0 = 50.0; // 這是觀察參考點,與觀察系原點重合
  6 GLfloat xref = 0.0, yref = 50.0, zref = 0.0; // camera要瞄準的點,不是觀察參考點
7 GLfloat Vx = 0.0, Vy = 1.0, Vz = 0.0; 8 GLfloat xwMin = -40.0, ywMin = -40.0, xwMax = 40.0, ywMax = 40.0; 9 GLfloat dnear = 25, dfar = 75; 10 GLdouble radianAngle = 1.0/360.0 * 3.14159; 11 GLfloat cos1 = cos(radianAngle); 12 GLfloat sin1 = sin(radianAngle); 13 14 typedef GLint vertex3 [3]; 15 vertex3 pt [8] = {{0, 0, 0}, {0, 100, 0}, {100, 0, 0}, {100, 100, 0}, 16 {0, 0, 100}, {0, 100, 100}, {100, 0, 100}, {100, 100, 100}}; 17 18 void init (void) 19 { 20 glClearColor(1.0, 1.0, 1.0, 0.0); 21 22 glMatrixMode(GL_MODELVIEW); 23 gluLookAt(x0, y00, z0, xref, yref, zref, Vx, Vy, Vz); 24 25 glMatrixMode(GL_PROJECTION); 26 glFrustum(xwMin, xwMax, ywMin, ywMax, dnear, dfar); 27 } 28 29 void quad (GLint n1, GLint n2, GLint n3, GLint n4) 30 { 31 glBegin(GL_QUADS); 32 glVertex3iv(pt[n1]); 33 glVertex3iv(pt[n2]); 34 glVertex3iv(pt[n3]); 35 glVertex3iv(pt[n4]); 36 glEnd(); 37 } 38 39 void cube () 40 { 41 glColor3f(0.0, 1.0, 0.0); // back 42 quad(0, 2, 3, 1); 43 glColor3f(1.0, 0.0, 0.0); // left 44 quad(0, 1, 5, 4); 45 glColor3f(0.0, 0.0, 1.0); // top 46 quad(1, 3, 7, 5); 47 glColor3f(1.0, 1.0, 0.0); // front 48 quad(4, 5, 7, 6); 49 glColor3f(0.0, 1.0, 1.0); // right 50 quad(2, 6, 7, 3); 51 glColor3f(1.0, 0.0, 1.0); // bottom 52 quad(0, 4, 6, 2); 53 } 54 55 void displayFcn (void) 56 { 57 glClear(GL_COLOR_BUFFER_BIT); 58 59 glColor3f(0.0, 1.0, 0.0); 60 glPolygonMode(GL_FRONT, GL_FILL); 61 glPolygonMode(GL_BACK, GL_LINE); 62 // glFrontFace(GL_CW); // show the back 63 64 cube(); 65 66 glutSwapBuffers(); 67 } 68 69 void reshapeFcn (GLint newWidth, GLint newHeight) 70 { 71 glViewport(0, 0, newWidth, newHeight); 72 73 winWidth = newWidth; 74 winHeight = newHeight; 75 } 76 77 void idleFcn (void) 78 { 79 GLfloat xref1, zref1; 80 xref = xref - x0; 81 zref = zref - z0; 82 zref1 = zref * cos1 - xref * sin1 + z0; 83 xref1 = zref * sin1 + xref * cos1 + x0; 84 xref = xref1; 85 zref = zref1; 86 87 glMatrixMode(GL_MODELVIEW); 88 glLoadIdentity(); 89 gluLookAt(x0, y00, z0, xref, yref, zref, Vx, Vy, Vz); 90 91 displayFcn(); 92 } 93 94 int main(int argc, char * argv[]) 95 { 96 glutInit(&argc, argv); 97 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); 98 glutInitWindowSize(winWidth, winHeight); 99 glutInitWindowPosition(50, 50); 100 glutCreateWindow("Perspective View of A Square"); 101 102 init(); 103 glutDisplayFunc(displayFcn); 104 glutReshapeFunc(reshapeFcn); 105 glutIdleFunc(idleFcn); 106 glutMainLoop(); 107 108 return 0; 109 }
View Code

技術分享圖1 技術分享圖2 技術分享圖3

[計算機圖形學 with OpenGL] Chapter10 OpenGL三維觀察程序示例