Modeling
This presentation is the property of its rightful owner.
Sponsored Links
1 / 31

Modeling PowerPoint PPT Presentation


  • 76 Views
  • Uploaded on
  • Presentation posted in: General

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. 何謂多邊形?.

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Modeling

Modeling

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


Modeling

大綱

  • 何謂多邊形?

  • 多邊形的種類

  • 多邊形的正面與反面

  • 填滿多邊形

  • OpenGL 多邊形相關函式

  • 範例


Modeling

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) 所組成。


Modeling

多邊形的種類

  • 簡單多邊形(simple polygon)

    • 邊線都不相交而且沒有洞的多邊形。又可分成:

    • 凸多邊形(convex polygon)

      • 假定 a和 b是多邊形中任意的兩點。線段 ab上所有的點也都在多邊形中。

    • 凹多邊形(concave polygon)

      • 不是凸的簡單多邊形即為凹多邊形。

  • 非簡單多邊形(non-simple polygon)

    • 邊線相交或有洞的多邊形。


Modeling

凸多邊形

凹多邊形

非簡單的多邊形


Modeling

v3

v2

反面

正面

v4

v1

多邊形的正面與反面

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


Opengl

OpenGL 多邊形相關函式

  • glRect*()

  • glPolygonMode()

  • glFrontFace()

  • glCullFace()


Modeling

(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: 用來存第二個端點的陣列


Modeling

  • glBegin(type)

  • /* 一連串的 glVertex*() 呼叫 */

  • glEnd()

  • 參數 type可以是下面的常數值:

    • GL_TRIANGLES

    • GL_TRIANGLE_STRIP

    • GL_TRIANGLE_FAN

    • GL_QUADS

    • GL_QUAD_STRIP

    • GL_POLYGON


Modeling

  • glPolygonMode (GLenumface, GLenummode)

    • 控制多邊形的繪製的方式。

  • 參數 face設定繪製多邊形的正面或反面,其值為:

    • GL_FRONT_AND_BACK正反面都畫

  • 參數 mode設定繪製的模式,其值可為:

    • GL_FILL填滿多邊形內部(此為預設的模式)

    • GL_LINE只畫多邊形的框線

    • GL_POINT只畫多邊形的端點


Modeling

  • glFrontFace (GLenummode)

    • 設定多邊形正面的決定方式。

  • 參數 mode設定正面的方向,其值可為:

    • GL_CCW逆時針方向為正面(此為預設值)

    • GL_CW順時針方向為正面

v3

v3

v2

v2

正面

GL_CCW

GL_CW

正面

v4

v4

v1

v1


Modeling

  • glCullFace (GLenummode)

    • 設定多邊形那一個面被剔除(cull)。

  • 參數 mode選擇那一面被剔除,其值可為:

    • GL_FRONT正面

    • GL_BACK反面

    • GL_FRONT_AND_BACK正面和反面

  • 呼叫此函式之前,你必須已經呼叫

    • glEnable(GL_CULL_FACE)

  • 來啟動此 OpenGL 的剔除功能。

  • 若要關閉此功能,則可呼叫:

    • glDisable(GL_CULL_FACE)


Cube triangles

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);

}


Modeling

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 );

  • }


Triangle strips with winding order

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.


Cube triangle strips

範例: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


Draw elements

Draw Elements

  • glDrawElements()

  • glMultiDrawElements()

  • glDrawRangeElements()


Modeling

vertex arrays

index array


Cube elements

範例: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] );


Modeling

  • 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


Sphere

範例: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);

  • }


Modeling

glBufferData( GL_ARRAY_BUFFER, nVertices*sizeof(vec3),vertexList, GL_STATIC_DRAW );

glVertexAttribPointer( loc, 3, GL_FLOAT, GL_FALSE, 0,BUFFER_OFFSET(0) );


Modeling

  • // 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));


Modeling

  • // 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));

  • }


Modeling

  • // 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


Hidden line removal with polygon offset

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);


Icosahedron

範例: 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}

  • };


Sphere subdivision

範例:Sphere 繪製方法(subdivision)

Icosahedron


Modeling

  • 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


Modeling

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


Modeling

參考資料

  • OpenGL Programming Guide, 7E Version 3.0 and 3.1 (2010)

  • OpenGL Shading Language 3rd Edition (2010)


  • Login