CS代写 COSC363

Object Modelling
R. Mukundan Department of Computer Science and Software Engineering University of Canterbury, .

Drawing Polygonal Lines

Copyright By PowCoder代写 加微信 powcoder

glColor3f(1, 0, 0); glLineWidth(4); glBegin(GL_LINES);
glVertex3f(0, -5, 0.01);
glVertex3f(0, 5, 0.01);
When drawing a line on a polygon, use a small depth offset to avoid depth fighting.
glBegin(GL_LINE_STRIP); for(int i = 0; i < 5; i++) { glVertex3f(x[i], y[i], z[i]); glBegin(GL_LINE_LOOP); for(int i = 0; i < 5; i++) { glVertex3f(x[i], y[i], z[i]); Drawing Polygonal Lines Drawing a circle of radius 5 units: glLineWidth(4); float toRadians = M_PI / 180.0; glBegin(GL_LINE_LOOP); for (int i = 0; i < 36; i++) angle = 10 * i * toRadians; glVertex3f(5*cos(angle), 5*sin(angle), 0); Drawing smooth (antialiased) lines: (Include the following code in “initialize” function) glEnable(GL_LINE_SMOOTH); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); Drawing Polygonal Lines glBegin(GL_LINE_LOOP); for (int i = 0; i < 6; i++) angle = 60 * i * toRadians; glVertex3f(5*cos(angle), 5*sin(angle), 0); angle = angle + 30 * toRadians; glVertex3f(3*cos(angle), 3*sin(angle), 0); } glEnd();  You may draw circles and polygonal shapes using gluDisk() gluDisk(q, 5, 5.5, 36, 2); gluDisk(q, 5, 5.5, 3, 2); gluDisk(q, 5, 5.5, 7, 2); General Polygon Definition  A polygon defined using OpenGL primitive type GL_POLYGON will be rendered correctly only if it is a planar and convex glColor3f(0, 1, 1); glBegin(GL_POLYGON); glVertex3f(x0, y0, z0); glVertex3f(x1, y1, z1); glVertex3f(x2, y2, z2); glVertex3f(x3, y3, z3); glVertex3f(x4, y4, z4); glVertex3f(x5, y5, z5); ... • Convex polygon • Correctly rendered • Non-convex polygon • Incorrectly rendered  Vertex sequence: V0, V1,... Vn-1  A general polygon may have to be subdivided into triangles and quads and rendered using corresponding primitive types.. Primitive Types for Triangulation  The following primitive types are useful for subdividing polygonal regions into triangles or quads:  GL_TRIANGLE_FAN, GL_TRIANGLE_STRIP, GL_QUAD_STRIP  Advantages:  Provides a compact representation of a subdivision in terms of vertices of polygonal lines (usually specified using for-loops)  No need to define each triangle of quad individually. Avoids repetition of vertices. V1 V2 V V2 V V2 V0 V1 V1 V Vn-1 P Triangle fan 0 n-1 W1 W2 Quad strip W0 W Triangle strip n = size of the V (or W) array. Triangle Fan  This primitive type is useful for triangulating a polygon from a single point (central vertex), P. glBegin(GL_TRIANGLE_FAN); normal(...); glVertex3f(px, py, pz); glVertex3f(x0, y0, z0); glVertex3f(x1, y1, z1); glVertex3f(x2, y2, z2); glVertex3f(x3, y3, z3); glVertex3f(x4, y4, z4); glVertex3f(x5, y5, z5); ... Vertex Sequence Central vertex Open vs. closed polygons: Vn-1 V0 V1 COSC363 Primitive definition: P,V0,V1 ,...Vn-1 Primitive definition: P,V0,V1 ,...Vn-1 ,V0 Triangle Fan (Examples) Vertex Sequence Central vertex V11 V23 :: Polygon Strips  Triangle and quad strips are convenient primitive types for the construction of surfaces between two polygonal chains (“slices”) with the same number of vertices.  One polygonal chain is usually a translated version of the other V2 W W1 W2 Vertex Sequence V0 glBegin(GL_TRIANGLE_STRIP); for (int i = 0; i < n; i++) { glVertex3f(vx[i], vy[i], vz[i]); glVertex3f(wx[i], wy[i], wz[i]); Quad strip Triangle strip glBegin(GL_QUAD_STRIP); for (int i = 0; i < n; i++) { glVertex3f(vx[i], vy[i], vz[i]); glVertex3f(wx[i], wy[i], wz[i]); Vn-1 W1 W2  Triangle Strip: VV Polygon Strips glBegin(GL_TRIANGLE_STRIP); glVertex3f(vx[0], vy[0], glVertex3f(wx[0], wy[0], Vn-1 glVertex3f(vx[1], vy[1], glVertex3f(wx[1], wy[1], glVertex3f(vx[2], vy[2], glVertex3f(wx[2], wy[2], wz[0]); Triangle V W V vz[1]); 0 0 1 wz[1]); Triangle W0V1W1 vz[2]); Triangle V1W1V2 wz[2]); Triangle W1V2W2 Triangle strip  Quad Strip ... glEnd(); glBegin(GL_QUAD_STRIP); glVertex3f(vx[0], vy[0], vz[0]); glVertex3f(wx[0], wy[0], wz[0]); glVertex3f(vx[1], vy[1], vz[1]); glVertex3f(wx[1], wy[1], wz[1]); glVertex3f(vx[2], vy[2], vz[2]); glVertex3f(wx[2], wy[2], wz[2]); ... Quad strip Vn-1 W1 W2 Quad W0V0V1W1 Quad W1V1V2W2 Note: First quad formed when W1 is processed. Quad Strip  Rendering in 3D space requires normal vector definitions to be associated with the vertices of the quad strip V Vi-1V 1i glBegin(GL_QUAD_STRIP); for (int i = 1; i < n; i++) { normal(vx[i-1], vy[i-1], vz[i-1], wx[i-1], wy[i-1], wz[i-1], wx[i], wy[i], wz[i]); if(i==1) { glVertex3f(vx[0], vy[0], vz[0]); glVertex3f(wx[0], wy[0], wz[0]); glVertex3f(vx[i], vy[i], vz[i]); glVertex3f(wx[i], wy[i], wz[i]); Each face’s normal vector is associated with a pair of corresponding vertices (except for the first quad). Quad Strip  The order in which vertices are input to the normal() function will depend on the vertex definition of the quad glBegin(GL_QUAD_STRIP); for (int i = 1; i < n; i++) { normal(vx[i-1], vy[i-1], vz[i-1], vx[i], vy[i], vz[i], wx[i], wy[i], wz[i]); if(i == 1) { glVertex3f(vx[0], vy[0], vz[0]); glVertex3f(wx[0], wy[0], wz[0]); glVertex3f(vx[i], vy[i], vz[i]); glVertex3f(wx[i], wy[i], wz[i]); Quad Strip  Using face normal definitions in a quad strip will result in discontinuities in shades of colour rendered on the surface, and will clearly show the underlying polygonal structure.  The following surface is constructed using quad strips between consecutive slices, with face normal vectors associated with vertices as shown on previous slides. Quad Strip Examples A polygonal line V on the xz-plane is given by vertices (x[i], 0, z[i]), and is translated along the z direction by a distance d to get another polygonal line W. The vertices of W are given by (x[i], 0, z[i] + d ) (x[i], 0, z[i]) Common normal vector glNormal3f(0, 1, 0); glBegin(GL_QUAD_STRIP); for (int i = 0; i < n; i++) { glVertex3f(x[i], 0, z[i]); glVertex3f(x[i], 0, z[i]+d); } glEnd(); A polygonal curve V on the xz-plane is given by vertices (x[i], 0, z[i]), and is translated along the y direction by a distance h to get another polygonal curve W. The vertices of W are given by (x[i], h, z[i]) glBegin(GL_QUAD_STRIP); for (int i = 0; i < n; i++) { glVertex3f(x[i], 0, z[i]); glVertex3f(x[i], h, z[i]); } glEnd(); Quad Strip Examples A set of points (x[i], y[i], 0) on the xy plane form a circle V. This circle is translated along the z direction by a distance d to get another circle W. The vertices of W are given by (x[i], y[i], d ) w1 v1 w0 v0 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_QUAD_STRIP); for (int i = 0; i < 18; i++) { glVertex3f(x[i], y[i], 0); glVertex3f(x[i], y[i], d); To get a closed surface, we must add the initial pair of points to the quad strip glBegin(GL_QUAD_STRIP); for (int i = 0; i < 18; i++) { glVertex3f(x[i], y[i], 0); glVertex3f(x[i], y[i], d); glVertex3f(x[0], y[0], 0); glVertex3f(x[0], y[0], d); Modelling Surfaces in 3D In many surface modelling applications, a polygonal line Vi is transformed into Wi, and the points connected by a triangle or quad strip. The transformation is repeated multiple times (with the Wi polygon as the new Vi ) to generate different layers (slices) of a 3D model. A translation along y-direction A translation along z-direction A scale transformation and a rotation Surfaces generated by repeatedly transforming a COSC363 polygonal element are known as Sweep Surfaces. Sweep Surface With Multiple Slices  Transform the points on V to W  Generate a quad strip between V and W (including normal vectors)  Update V by copying the coordinates of points in W to V  Update W by transforming V  Generate a quad strip between V and W (including normal vectors)  Repeat the above steps till the required number of slices are generated. Render the surface by assigning normal vectors to points and enabling lighting. Sweep Surfaces Main Steps for (int slice = 0; slice < nslices; slice++) { for (int i = 0; i < npoints; i++) wx[i] = vx[i] * cos(angle) + vz[i] * sin(angle); wy[i] = vy[i]; wz[i] = vz[i] * cos(angle) - vx[i] * sin(angle); } glBegin(GL_QUAD_STRIP); for (int i = 0; i < npoints; i++) glVertex3f(vx[i], vy[i], vz[i]); glVertex3f(wx[i], wy[i], wz[i]); for (int i = 0; i < npoints; i++) vx[i] = wx[i]; vy[i] = wy[i]; vz[i] = wz[i]; Transformation of VtoW Quad strip construction Updating V for next iteration Sweep Surfaces  In general, the vertices of a polygonal line V may be transformed using a combination of rotation, scaling and translation.  We require the coordinates of points on W, and therefore we cannot use OpenGL transformation functions.  Surfaces of revolution are commonly generated using a rotation about the y-axis by an angle  : (x, y, z) (xi, yi, zi) Rotation about x axis: Rotation about y axis: Useful Formulae 𝑦′ =𝑦𝑐𝑜𝑠𝜃−𝑧𝑠𝑖𝑛𝜃 𝑧′ =𝑦𝑠𝑖𝑛𝜃+𝑧𝑐𝑜𝑠𝜃 Rotation about z axis: 𝑥′ =𝑥𝑐𝑜𝑠𝜃−𝑦𝑠𝑖𝑛𝜃 𝑦′ =𝑥𝑠𝑖𝑛𝜃+𝑦𝑐𝑜𝑠𝜃 𝑧′ = 𝑧 Surface of Revolution  A surface of revolution is obtained by revolving a polygonal curve (base curve) about an axis.  The points on the curve V are rotated about an axis to get the W curve. Base Curve x Example 1 VW i-1 i-1 for(int j = 0; j < nSlices; j++) { for(int i = 0; i < N; i++) { wx[i] = cos(angStep)*vx[i] + sin(angStep)*vz[i]; wy[i] = vy[i]; wz[i] = -sin(angStep)*vx[i] + cos(angStep)*vz[i]; glBegin(GL_QUAD_STRIP); for(int i = 0; i < N; i++) { glVertex3f(vx[i], vy[i], vz[i]); glVertex3f(wx[i], wy[i], wz[i]); Surface of Revolution Only rotation for(int i = 0; i < N; i++) { vx[i] = wx[i]; vy[i] = wy[i]; vz[i] = wz[i]; //Update vertices The above code is used only for wireframe rendering. Normal vectors are not computed. Surface of Revolution  The only transformation between slices V and W is a rotation.  We can rotate the normal vectors computed at points on V to get the normal vectors at the corresponding points on W  Since the base curve is a 2D curve on a principal plane, the normal vectors at its vertices can be easily computed. Vertex normals provide a smooth rendering of a surface. Rotation Unit direction vector (ux , uy) Perpendicular vector (uy , -ux) Vertex normal (sum of perp vectors) ni mi Wi Base curve ni is the vertex normal at Vi mi is the vertex normal at Wi Vi Rotation Wi ni Rotation mi Surface of Revolution Assumption: Coordinatesandnormalvectorsatpointsonthebasecurvearegiven. for(int j = 0; j < nSlices; j++) { //Transform verts and normals for(int i = 0; i < N; i++) { wx[i] = cos(angStep)*vx[i] + sin(angStep)*vz[i]; wy[i] = vy[i]; wz[i] = -sin(angStep)*vx[i] + cos(angStep)*vz[i]; mx[i] = cos(angStep) * nx[i] + sin(angStep) * nz[i]; my[i] = ny[i]; mz[i] = -sin(angStep) * nx[i] + cos(angStep) * nz[i]; //Generate quad strip glBegin(GL_QUAD_STRIP); for(int i = 0; i < N; i++) { glNormal3f(nx[i], ny[i], nz[i]); glVertex3f(vx[i], vy[i], vz[i]); glNormal3f(mx[i], my[i], mz[i]); glVertex3f(wx[i], wy[i], wz[i]); } glEnd(); for(int i = 0; i < N; i++) { //Update verts and normals vx[i] = wx[i]; vy[i] = wy[i]; nx[i] = mx[i]; ny[i] = my[i]; vz[i] = wz[i]; nz[i] = mz[i]; Computing Texture Coordinates  Texture coordinates for Vi :  Texture coordinates for Wi : Texture Mapped Quad Strip i/(n-1), 0 i/(n-1), 1 glBegin(GL_QUAD_STRIP); for(inti=0; i parList;

Particle Update
 Iterate over the entire list and update each particle’s attributes based on ‘t’.
 Remove particles that have exceeded lifetime.
void update () {
list::iterator it;
particle p;
//Remove particles that have passed lifetime
if (!parList.empty()) {
p = parList.front();
if (p.t > T) parList.pop_front();
//Update parameters
for (it = parList.begin(); it != parList.end(); it++) { (it->t)++;
for (int i = 0; i < 3; i++) (it->pos[i]) += (it->dir[i]) * speed;
it->size = …;
it->delta = …; COSC363

Particle Update
Timer Callback
void timer(int value)
counter++;
if (counter % m == 0) newParticle(); update();
glutTimerFunc(30, timer, 0); glutPostRedisplay();
void display()
Particle List

Particle Rendering
 A particle may be rendered as a set of texture mapped quads. Two quads mutually perpendicular to each other, are commonly used.
Sample textures
Texture mapped Quads Without Blending
Particle Model With Blending

Particle Rendering
 A particle may be rendered using a set of basic primitives Triangle Fan
Edge vertices: glColor4f(1, 1, 1, 0); Central vertex: glColor4f(1, 0, 0, 1);
Particle Model Without Blending
Particle Model With Blending

Particle Rendering
 Blending: The particle’s colour (source or foreground) must be blended with the colour of the fragment (destination or background) at the position where the particle is rendered.
The alpha value of source is commonly used for blending:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); output:  s+(1- )d
The source colour itself may be used for blending (if alpha channel is not available):
glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR); output: ss+(1-s)d
Source + Destination:
glBlendFunc(GL_ONE, GL_ONE);
output: s + d
No blending
glBlendFunc(GL_ONE, GL_ZERO);
output: s

程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com