1 / 31

Modeling

Modeling. 靜宜大學資工系 蔡奇偉副教授. 大綱. 何謂多邊形? 多邊形的種類 多邊形的正面與反面 填滿多邊形 OpenGL 多邊形相關函 式 範例. v 7. v 1. v 1. v 5. v 6. v 2. v 2. v 3. v 4. v 3. v 3. v 1. v 1. v 4. v 5. v 4. v 2. v 3. v 2. 何謂多邊形?.

otis
Download Presentation

Modeling

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Modeling 靜宜大學資工系 蔡奇偉副教授

  2. 大綱 • 何謂多邊形? • 多邊形的種類 • 多邊形的正面與反面 • 填滿多邊形 • OpenGL 多邊形相關函式 • 範例

  3. v7 v1 v1 v5 v6 v2 v2 v3 v4 v3 v3 v1 v1 v4 v5 v4 v2 v3 v2 何謂多邊形? n邊的多邊形(polygon)是由 n個共平面的端點 v1, v2, …, vn和 n條邊線 (v1, v2),(v2, v3), …, (vn-1, vn), (vn, v1) 所組成。

  4. 多邊形的種類 • 簡單多邊形(simple polygon) • 邊線都不相交而且沒有洞的多邊形。又可分成: • 凸多邊形(convex polygon) • 假定 a和 b是多邊形中任意的兩點。線段 ab上所有的點也都在多邊形中。 • 凹多邊形(concave polygon) • 不是凸的簡單多邊形即為凹多邊形。 • 非簡單多邊形(non-simple polygon) • 邊線相交或有洞的多邊形。

  5. 凸多邊形 凹多邊形 非簡單的多邊形

  6. v3 v2 反面 正面 v4 v1 多邊形的正面與反面 在三度空間中,多邊形有正反兩面。通常我們把端點順序符合逆時針方向的那一面稱為正面,另一面稱為反面。

  7. OpenGL 多邊形相關函式 • glRect*() • glPolygonMode() • glFrontFace() • glCullFace()

  8. (x2, y2) (x1, y1) (x1, y1) (x2, y2) • glRect{sifd} (TYPE x1, TYPE y1, TYPE x2, TYPE y2) • 在 z = 0 的平面上,畫一個以 (x1, y1) 和 (x2, y2) 為對角端點的矩形。 • glRect{sifd}v (TYPE *v1, TYPE *v2) • v1: 用來存第一個端點的陣列 • v2: 用來存第二個端點的陣列

  9. glBegin(type) • /* 一連串的 glVertex*() 呼叫 */ • glEnd() • 參數 type可以是下面的常數值: • GL_TRIANGLES • GL_TRIANGLE_STRIP • GL_TRIANGLE_FAN • GL_QUADS • GL_QUAD_STRIP • GL_POLYGON

  10. glPolygonMode (GLenumface, GLenummode) • 控制多邊形的繪製的方式。 • 參數 face設定繪製多邊形的正面或反面,其值為: • GL_FRONT_AND_BACK正反面都畫 • 參數 mode設定繪製的模式,其值可為: • GL_FILL填滿多邊形內部(此為預設的模式) • GL_LINE只畫多邊形的框線 • GL_POINT只畫多邊形的端點

  11. glFrontFace (GLenummode) • 設定多邊形正面的決定方式。 • 參數 mode設定正面的方向,其值可為: • GL_CCW逆時針方向為正面(此為預設值) • GL_CW 順時針方向為正面 v3 v3 v2 v2 正面 GL_CCW GL_CW 正面 v4 v4 v1 v1

  12. glCullFace (GLenummode) • 設定多邊形那一個面被剔除(cull)。 • 參數 mode選擇那一面被剔除,其值可為: • GL_FRONT正面 • GL_BACK 反面 • GL_FRONT_AND_BACK 正面和反面 • 呼叫此函式之前,你必須已經呼叫 • glEnable(GL_CULL_FACE) • 來啟動此 OpenGL 的剔除功能。 • 若要關閉此功能,則可呼叫: • glDisable(GL_CULL_FACE)

  13. 2 vertex list 6 3 7 0 1 2 3 4 5 6 7 back 1 5 front 0 4 範例:cube 繪製方法(使用 triangles) y x z void make_cube_vertices ( GLfloat size ) { GLfloathalf_size = size / 2.0f; vertexList[0] = vec3(-half_size, -half_size, half_size); vertexList[1] = vec3(-half_size, -half_size, -half_size); vertexList[2] = vec3(-half_size, half_size, -half_size); vertexList[3] = vec3(-half_size, half_size, half_size); vertexList[4] = vec3( half_size, -half_size, half_size); vertexList[5] = vec3( half_size, -half_size, -half_size); vertexList[6] = vec3( half_size, half_size, -half_size); vertexList[7] = vec3( half_size, half_size, half_size); }

  14. 2 6 3 7 back 1 5 front 0 4 • void draw_cube01 (void) • { • vec3 tv[36]; // vertices of triangles • tv[0] = vertexList[2]; tv[1] = vertexList[3]; tv[2] = vertexList[7]; • tv[3] = vertexList[7]; tv[4] = vertexList[6]; tv[5] = vertexList[2]; • ...... • tv[30] = vertexList[4]; tv[31] = vertexList[0]; tv[32] = vertexList[5]; • tv[33] = vertexList[0]; tv[34] = vertexList[1]; tv[35] = vertexList[5]; • glBufferData( GL_ARRAY_BUFFER, 36*sizeof(vec3), tv, GL_STATIC_DRAW ); • glVertexAttribPointer( loc, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) ); • glDrawArrays( GL_TRIANGLES, 0, 36 ); • }

  15. Triangle Strips with Winding Order Triangle strips do face culling differently. For every second triangle, the one who's winding order is opposite from the first triangle's order, the winding order is considered backwards for culling purposes. So if you have set the front face to be clockwise, and have face culling cull back-facing triangles, everything will work exactly as you expect so long as the order of the first triangle is correct. Every even numbered triangle will be culled if it has a clockwise winding, and every odd numbered triangle will be culled if it has a counter-clockwise winding.

  16. 範例:cube 繪製方法(使用 triangle strips) • void draw_cube02 (void) • { • vec3 tv[18]; // vertices of triangles • tv[0] = vertexList[3]; tv[1] = vertexList[0]; tv[2] = vertexList[7]; • tv[3] = vertexList[4]; tv[4] = vertexList[6]; tv[5] = vertexList[5]; • tv[6] = vertexList[2]; tv[7] = vertexList[1]; tv[8] = vertexList[3]; • tv[9] = vertexList[0]; • tv[10] = vertexList[2]; tv[11] = vertexList[3]; • tv[12] = vertexList[6]; tv[13] = vertexList[7]; • tv[14] = vertexList[0]; tv[15] = vertexList[1]; • tv[16] = vertexList[4]; tv[17] = vertexList[5]; • glBufferData( GL_ARRAY_BUFFER, 18*sizeof(vec3), tv, GL_STATIC_DRAW ); • glVertexAttribPointer( loc, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) ); • glDrawArrays( GL_TRIANGLE_STRIP, 0, 10 ); • glDrawArrays( GL_TRIANGLE_STRIP, 10, 4 ); • glDrawArrays( GL_TRIANGLE_STRIP, 14, 4 ); • } 2 6 3 7 1 5 0 4

  17. Draw Elements • glDrawElements() • glMultiDrawElements() • glDrawRangeElements()

  18. vertex arrays index array

  19. 範例:cube 繪製方法(使用 elements) 建立 Buffer Objects GLuint buffer[2]; // Buffer object ID’s enum {VERTEX_ARRAY, ELEMENT_ARRAY}; glGenBuffers( 2, buffer ); glBindBuffer( GL_ARRAY_BUFFER, buffer[VERTEX_ARRAY] ); glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, buffer[ELEMENT_ARRAY] );

  20. void draw_cube (void) • { • GLushortidx[18] = { • 3, 0, 7, 4, 6, 5, 2, 1, 3, 0, • 2, 3, 6, 7, • 0, 1, 4, 5 • }; • glBufferData( GL_ARRAY_BUFFER, 8*sizeof(vec3), vertexList, GL_STATIC_DRAW ); • glVertexAttribPointer( loc, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) ); • glBufferData( GL_ELEMENT_ARRAY_BUFFER, 18*sizeof(GLushort), idx, GL_STATIC_DRAW ); • glDrawElements( GL_TRIANGLE_STRIP, 10, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0)); • glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, BUFFER_OFFSET(10*sizeof(GLushort))); • glDrawElements( GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, BUFFER_OFFSET(14*sizeof(GLushort))); • } 2 6 3 7 1 5 0 4

  21. 範例:Sphere 繪製方法 • void make_sphere_vertices ( GLdouble radius, GLint slices, GLint stacks) • { • nVertices= slices * (stacks - 1) + 2; // two poles • vertexList = new vec3[nVertices]; • vertexList[0] = vec3(0.0f, radius, 0.0f); • GLdouble ds = 2 * radius / stacks; • GLdoubleyval = radius, dtheta = 2.0 * M_PI / slices; • intk = 1; • for (inti = 1; i < stacks; i++) • { • yval -= ds; • GLdouble r = std::sqrt(radius*radius - yval*yval); • GLdoubleang = 0.0; • for (int j = 0; j < slices; j++) • { • vertexList[k] = vec3(r*std::cos(ang), yval, r*std::sin(ang)); • k++; • ang += dtheta; • } • } • vertexList[k] = vec3(0.0f, -radius, 0.0f); • }

  22. glBufferData( GL_ARRAY_BUFFER, nVertices*sizeof(vec3),vertexList, GL_STATIC_DRAW ); glVertexAttribPointer( loc, 3, GL_FLOAT, GL_FALSE, 0,BUFFER_OFFSET(0) );

  23. // North pole • nv = nSlices+2; // number of vertices • idx[0] = 0; • for (i = 1; i <= nSlices; i++) • idx[i] = i; • idx[i] = 1; • glBufferData( GL_ELEMENT_ARRAY_BUFFER, nv*sizeof(GLushort),idx, GL_STATIC_DRAW ); • glDrawElements( GL_TRIANGLE_FAN, nv, GL_UNSIGNED_SHORT,BUFFER_OFFSET(0));

  24. // inside stacks • nv = 2*nSlices+2; // number of vertices • for (int k = 1; k < nStacks - 1; k++) { • int k1 = nSlices * (k -1) + 1; • int k2 = nSlices * k + 1; • for (int j = 0; j < 2*nSlices; j+=2) { • idx[j] = k1++; • idx[j+1] = k2++; • } • idx[nv-2] = idx[0]; • idx[nv-1] = idx[1]; • glBufferData( GL_ELEMENT_ARRAY_BUFFER, nv*sizeof(GLushort), idx,GL_STATIC_DRAW ); • glDrawElements( GL_TRIANGLE_STRIP, nv, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0)); • }

  25. // South pole • nv = nSlices+2; // number of vertices • idx[0] = nVertices - 1; • for (i = 1; i <= nSlices; i++) • idx[i] = nVertices - nSlices - 2 + i; • idx[i] = nVertices - nSlices - 1; • glBufferData( GL_ELEMENT_ARRAY_BUFFER, nv*sizeof(GLushort), idx,GL_STATIC_DRAW ); • glDrawElements( GL_TRIANGLE_FAN, nv, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0)); vertex list nVertices– 1 –nSlices nVertices –1

  26. Hidden-Line Removal with Polygon Offset glEnable(GL_DEPTH_TEST); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); set_color(foreground); draw_object_with_filled_polygons(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(1.0, 1.0); set_color(background); draw_object_with_filled_polygons(); glDisable(GL_POLYGON_OFFSET_FILL);

  27. 範例: Icosahedron 繪製方法 • #define X .525731112119133606 • #define Z .850650808352039932 • void make_icosahedron_vertices ( GLdouble radius) • { • vdata[0] = radius * vec3(-X, 0.0, Z); • vdata[1] = radius * vec3(X, 0.0, Z); • vdata[2] = radius * vec3(-X, 0.0, -Z); • vdata[3] = radius * vec3(X, 0.0, -Z); • vdata[4] = radius * vec3(0.0, Z, X); • vdata[5] = radius * vec3(0.0, Z, -X); • vdata[6] = radius * vec3(0.0, -Z, X); • vdata[7] = radius * vec3(0.0, -Z, -X); • vdata[8] = radius * vec3(Z, X, 0.0); • vdata[9] = radius * vec3(-Z, X, 0.0); • vdata[10] = radius * vec3(Z, -X, 0.0); • vdata[11] = radius * vec3(-Z, -X, 0.0); • } • GLushorttindices[20][3] = { • {1,4,0}, {4,9,0}, {4,5,9}, {8,5,4}, {1,8,4}, {1,10,8}, {10,3,8},{8,3,5}, {3,2,5}, {3,7,2}, {3,10,7}, {10,6,7}, {6,11,7}, {6,0,11},{6,1,0}, {10,1,6}, {11,0,9}, {2,11,9}, {5,2,9}, {11,2,7} • };

  28. 範例:Sphere 繪製方法(subdivision) Icosahedron

  29. void subdivide(vec3 v1, vec3 v2, vec3 v3) • { • vec3 v12, v23, v31; • GLinti; • v12 = (v1+v2)/2.0; • v23 = (v2+v3)/2.0; • v31 = (v3+v1)/2.0; • // 映射至球面上 • v12 = radius * normalize(v12); • v23 = radius * normalize(v23); • v31 = radius * normalize(v31); • drawtriangle(v1, v12, v31); • drawtriangle(v2, v23, v12); • drawtriangle(v3, v31, v23); • drawtriangle(v12, v23, v31); • } v2 v23 v12 v1 v3 v31

  30. Recursive Subdivision • void subdivide(vec3 v1, vec3 v2, vec3 v3, intdepth) • { • GLfloatv12, v23, v31; • GLinti; • if (depth == 0) { • drawtriangle(v1, v2, v3); • return; • } • v12 = (v1+v2)/2.0; • v23 = (v2+v3)/2.0; • v31 = (v3+v1)/2.0; • // 映射至球面上 • v12 = radius * normalize(v12); • v23 = radius * normalize(v23); • v31 = radius * normalize(v31); • subdivide(v1, v12, v31, depth-1); • subdivide(v2, v23, v12, depth-1); • subdivide(v3, v31, v23, depth-1); • subdivide(v12, v23, v31, depth-1); • } v2 v23 v12 v1 v3 v31

  31. 參考資料 • OpenGL Programming Guide, 7E Version 3.0 and 3.1 (2010) • OpenGL Shading Language 3rd Edition (2010)

More Related