<- previous index next ->
Why did I choose to use triangles in Lecture 21,
3 point surface, rather than 4 point surface?
Answer: For efficiency and ease of coding for some renderer's.
There are many types of renderer's as covered in Lecture 18.
For this lecture I am focusing on a renderer that will use
Phong Specular Lighting and thus requires normals to surfaces
that are interpolated across the surface.
To understand relative efficiency, in this case twice as many
3 point surfaces as four point surfaces for the same object,
both the data structures and the processing must be analyzed.
The data structures, copied from working code, are:
typedef struct {GLfloat x; GLfloat y; GLfloat z;
GLfloat nx; GLfloat ny; GLfloat nz;} dpts;
static dpts * data_points; /* malloc'd space for vertices */
For example, OpenGL code using normals and vertices:
glNormal3f(data_points[k-1].nx, data_points[k-1].ny, data_points[k-1].nz);
glVertex3f(data_points[k-1].x, data_points[k-1].y, data_points[k-1].z);
With precomputed normals from:
for(i=0; i<num_pts; i++)
{
/* get &data_points[i].x, &data_points[i].y, &data_points[i].z */
data_points[i].nx = 0.0; /* normals averaged and normalized */
data_points[i].ny = 0.0;
data_points[i].nz = 0.0;
}
/* pick up three points, pts, of a polygon */
for(j=0; j<3; j++)
v[j] = data_points[kk[j]-1];
/* compute, normalize and average normals */
ax = v[2].x - v[1].x;
ay = v[2].y - v[1].y;
az = v[2].z - v[1].z;
bx = v[1].x - v[0].x;
by = v[1].y - v[0].y;
bz = v[1].z - v[0].z;
nx = ay*bz-az*by; /* cross product */
ny = az*bx-ax*bz;
nz = ax*by-ay*bx; /* technically, the normal at point [1] */
s = sqrt(nx*nx+ny*ny+nz*nz);
nx = nx / s;
ny = ny / s;
nz = nz / s;
for(j=0; j<j; j++)
{
data_points[kk[j]-1].nx += nx; /* sum normals */
data_points[kk[j]-1].ny += ny;
data_points[kk[j]-1].nz += nz;
}
for(j=3; j<pts; j++)
{
/* if more than 3 points, compute normal at every vertex */
/* repeat 13 lines above for points other than [1] */
}
I have provided the utility files to read, write and clean the
".dat" and binary form ".det" files that can be used with OpenGL
and other applications.
The basic capabilities are shown in datread.h
The code is in datread.c
Three sample uses that provide various OpenGL viewers for .dat files are
light_dat.c
light_dat2.c
light_dat3.c
Some screen shots are
Now, suppose you want to edit a 3D image.
Possibly by picking a point and pulling it.
What can we give the used to help pick the points?
a) wireframe display with color change
b) vertex display with color change
c) trimmed vertex display with color change
d) color depths with various shades
Demonstrate light_dat3 skull.dat
w h to rotate, mouse to pick a vertex
note color change to show "pick"
v now vertices, mouse to pick
t trims vertices that should be hidden
less clutter
c (work in progress) show depth as various shades
Notice that a closed volume has an inside and an outside.
Most graphics software requires the normal vector to point outward.
An open volume may have a different color on the inside from the
color on the outside. Generally surfaces are given by triangles,
rectangles or polygons. The convention is to list the vertices
in counter clockwise order ( CCW ). The figure below is a cube
with the six surfaces flattened and the eight vertices labeled.
The order of the vertices allows the computation of the normal
to be an outgoing vector.
One specific format, the .dat (ASCII) or .det (binary) is:
number-of-vertices number-of-polygons
x1 y1 z1 three floating point numbers
x2 y2 z2
...
xn yn zn n = number of vertices
c1 vi vj vk ... vc1 vertex numbers starting with 1, c1 of them
c2 vl vn vm each line can have different number of points
...
cm va vb vc m = number-of-polygons
Example file acube.dat (annotation, not part of file)
8 6
0.0 0.0 0.0 p1
1.0 0.0 0.0 p2
0.0 1.0 0.0 p3
1.0 1.0 0.0 p4
0.0 0.0 1.0 p5
1.0 0.0 1.0 p6
0.0 1.0 1.0 p7
1.0 1.0 1.0 p8
4 3 4 8 7 top
4 1 2 4 3 front
4 5 6 2 1 bottom
4 7 8 6 5 back
4 5 1 3 7 L side
4 2 6 8 4 R side
A .stl ASCII file consists of triangles and the normals
with lots of labeling as in cube2.stl
Neither of the above files contain color information.
They just define the shape of an object.
A renderer takes a control file that places many objects and
applies color and shading to the objects. One such file is
lab6_input1 shown below:
device: lab6_input1.rle
postscript: lab6_input1.ps
debug: 1
viewport: 400 400
coi: 0 0 0
hither_yon: 1 100
observer: 4 1 20
angle: 8.0
light_position: 10 30 30
light_color: 1 1 1
object: drop.dat
color_type: 1 1 0 0
illumination_parameters: .2 .8 1.0 50
shading: phong
rotate: 45 30 60
scale: 1 1 1
translate: .25 -.36 0
object: drop.dat
color_type: 1 1 1 0
illumination_parameters: .25 .75 1.0 10
shading: phong
rotate: 0 0 180
scale: 1 1 1
translate: 0 .6 0
object: cube.dat
illumination_parameters: .3 .70 0.0 10
shading: phong
color_type: 1 1 .5 .5
scale: 2 2 .1
translate: 0 0 -.5
object: cube.dat
shading: phong
color_type: 1 .2 .9 1
illumination_parameters: .25 .75 1.0 100
scale: 2.0 .2 2.0
translate: 0 -1.0 .5
end
Note: shading, color, illumination, scale and position (translate)
are given for each object. Global parameters include window size,
center of interest, truncated prism specification, files, etc.
The result of the above scene is shown below.
<- previous index next ->