3D Wireframe Rendering CIS 488/588 Bruce R. Maxim UM-Dearborn

Download Report

Transcript 3D Wireframe Rendering CIS 488/588 Bruce R. Maxim UM-Dearborn

3D Wireframe Rendering
CIS 488/588
Bruce R. Maxim
UM-Dearborn
5/24/2016
1
Local to World Object
Transformation
void Model_To_World_RENDERLIST4DV1
(RENDERLIST4DV1_PTR rend_list,
POINT4D_PTR world_pos,
int coord_select)
//
//
//
//
//
NOTE: Not matrix based
this function converts the local model coordinates of the
sent render list into world coordinates, the results are
stored in the transformed vertex list (tvlist) within the
renderlist
//
//
//
//
iterate thru vertex list and transform all the
model/local coords to world coords by translating the
vertex list by the amount world_pos and storing the
results in tvlist[] is this polygon valid?
5/24/2016
2
3D Engine
• Based on three data structures introduced in
the previous chapter
– Polygon structure based on a vertex list
(POLY4DV1_TYP)
– Self-contained polygon structure
(POLYF4DV1_TYP)
– Object structure containing polygons
(OBJECT4DV1_TYP)
5/24/2016
3
Master Polygon List - 1
typedef struct RENDERLIST4DV1_TYP
{
int state; // state of renderlist ???
int attr; // attributes of renderlist ???
// the render list is an array of pointers each pointing to
// a self contained "renderable" polygon face POLYF4DV1
POLYF4DV1_PTR poly_ptrs[RENDERLIST4DV1_MAX_POLYS];
// additionally to cut down on allocatation, de-allocation
// of polygons each frame, here's where the actual polygon
// faces will be stored
POLYF4DV1 poly_data[RENDERLIST4DV1_MAX_POLYS];
int num_polys; // number of polys in render list
} RENDERLIST4DV1, *RENDERLIST4DV1_PTR;
5/24/2016
4
Master Polygon List - 2
• The state and attr fields are used to track the
list state and attributes
• The arrays poly_ptrs[ ] and polydata[ ] make
up what is called an indirection list (the
pointers are sorted not the data) they are
called index vertex buffers in Direct3D
• This is defined in the new software modules
T3DLIB5 (.H and .CPP)
5/24/2016
5
Creating/Loading Objects
1.
2.
3.
4.
5.
6.
7.
8.
Perform local-world transformation
Object removal (optional)
Back-face removal (optional)
Perform world-camera transformation
3D Clipping (optional)
Perform camera-perspective projection
Perform perspective-screen transformation
Rasterize polygons
5/24/2016
6
PLX File Loader
• LaMothe has modified the PLG descriptor to
create a PLX file
• Bit
d15
d0
CSSD RRRR GGGG BBBBB
C = RGB/indexed color flag
SS = define shading mode
D = double-sided flag
RRRR GGGG BBBB = bits for RGB mode
GGGGBBBB = 8bit color index
5/24/2016
7
PLX Functions - 1
char *Get_Line_PLG(char *buffer,
int maxlength, FILE *fp);
// this little helper function simply read past
// comments and blank lines in a PLG file and always
// returns full lines with something on them or NULL
// if the file is empty
5/24/2016
8
PLX Functions - 2
int Load_OBJECT4DV1_PLG(OBJECT4DV1_PTR obj, // object pointer
char *filename,
// plg filename
VECTOR4D_PTR scale, // initial scaling factors
VECTOR4D_PTR pos,
// initial position
VECTOR4D_PTR r
// initial rotations
// this function loads a plg object in off disk, additionally
// it allows the caller to scale, position, and rotate the object
// to save extra calls later for non-dynamic objects
• Note this function basically recognizes white
space and comments delineated by #
5/24/2016
9
How it works
• First line of file controls number of vertices
and polygons to read in
• The vertex list is read and inserted in the
OBJECT4DV1 object
• Polygons are inserted with their flags and
color models which are translated to
POLY_ATTR flags
• Also computes average and maximum radius
for collection detection and removal
5/24/2016
10
Using the function
OBJECT4Dv1 obj; // object storage
VECTOR4D scale = {1,1,1,1},
pos
= {0,0,0,1},
rot
= {0,0,0,1};
// no scaling
// pos (0,0,0) in world
// no rotation
// load object
Load_OBJECT4DV1_PLG(&obj,”cube.plg”,&scale,&pos,&rot);
5/24/2016
11
Building 3D Pipeline
• You may need to keep a copy of the original
vertex data for a later pipeline phase
– In POLYF4DV1, vlist[3] contains the orginal
triangle vertices and tvlist[3] contains the
transformed vertices
– In OBJHECT4DV1, vlist_local[ ] contains the array
of original local vertices and vlist_trans[ ] contains
the array of transformed vertices
• You would also want to transform the entire
list of polygons at once
5/24/2016
12
Transforming List
void Transform_RENDERLIST4DV1
(RENDERLIST4DV1_PTR rend_list, // render list to
// transform
MATRIX4X4_PTR mt, // transformation matrix
int coord_select) // selects coords to transform
// 0 = local only
// 1 = use transformed vlist and overwrite
// 2 = transform local vlist and overwrite
//
transformed storage
// this function simply transforms all of the polygons
// vertices in the local or trans array of the render
// list by the sent matrix
5/24/2016
13
Transforming One Object
void Transform_OBJECT4DV1
(OBJECT4DV1_PTR obj,
MATRIX4X4_PTR mt,
int coord_select,
//
//
//
//
int transform_basis) //
//
//
object to transform
transformation matrix
selects coords to
transform
flags if vector
orientation should
be transformed too
// this function simply transforms all of the vertices
// in the local or trans array by the sent matrix
5/24/2016
14
Local to World Object
Transformation
void Model_To_World_RENDERLIST4DV1
(RENDERLIST4DV1_PTR rend_list,
POINT4D_PTR world_pos,
int coord_select)
//
//
//
//
//
NOTE: Not matrix based
this function converts the local model coordinates of the
sent render list into world coordinates, the results are
stored in the transformed vertex list (tvlist) within the
renderlist
//
//
//
//
iterate thru vertex list and transform all the
model/local coords to world coords by translating the
vertex list by the amount world_pos and storing the
results in tvlist[] is this polygon valid?
5/24/2016
15
Camera Model - 1
typedef struct CAM4DV1_TYP
{
int state;
// state of camera
int attr;
// camera attributes
POINT4D pos;
// world position used by both camera models
VECTOR4D dir;
// angles or look at direction of camera for
// simple euler camera models, elevation and
// heading for uvn model
VECTOR4D u;
// extra vectors to track camera orientation
VECTOR4D v;
// for more complex UVN camera model
VECTOR4D n;
VECTOR4D target; // look at target
float view_dist;
float fov;
5/24/2016
// focal length
// field of view for horiz & vert axes
16
Camera Model - 2
// 3d clipping planes
// if view volume is NOT 90 degree then general 3d clipping
// must be employed
float near_clip_z;
// near z=constant clipping plane
float far_clip_z;
// far z=constant clipping plane
PLANE3D
PLANE3D
PLANE3D
PLANE3D
rt_clip_plane;
lt_clip_plane;
tp_clip_plane;
bt_clip_plane;
float viewplane_width;
5/24/2016
//
//
//
//
the
the
the
the
right clipping plane
left clipping plane
top clipping plane
bottom clipping plane
// width and height of view plane
// to project onto
17
Camera Model - 3
float viewplane_height;
// usually 2x2 for normalized
// projection or the exact same
// size as the viewport or screen
// remember screen and viewport are synonomous
float viewport_width;
// size of screen/viewport
float viewport_height;
float viewport_center_x; // center of view port
// (final image destination)
float viewport_center_y;
float aspect_ratio;
5/24/2016
18
Camera Model - 4
//
//
//
//
//
these matrices are not necessarily needed based on the
method of transformation, for example, a manual
perspective or screen transform and or a concatenated
perspective/screen, however, having these matrices give
us more flexibility
MATRIX4X4 mcam;
// storage for the world to camera
MATRIX4X4 mper;
// storage for the camera to perspective
MATRIX4X4 mscr;
// storage for the perspective to screen
} CAM4DV1, *CAM4DV1_PTR;
5/24/2016
19
Differences Between Euler and
UNV Camera
• Euler camera defined by position and rotation
angles that make up its orientation
• In the UNV camera adds the look at the target
and uses vectors U, N, V
n – similar to z-axis always points toward target
v – “up vector” similar to y-axis (starts as <0,1,0>
once u is computed becomes v = n x u)
u – “right vector” computed as u = n x v
5/24/2016
20
UVN Matrix Muvn
• Transforming XYZ system to UNV
p’ = p(x,y,z) * Muvn = (p • u, p • v, p • n)
[x y
5/24/2016
z
1] *
|
|
|
|
ux
uy
uz
0
vx
vy
vz
0
nx
ny
nz
0
0
0
0
1
|
|
|
|
21
Camera Positioning
Tuvn = Tcam-1 * Muvn =
|
1
0
0
|
0
1
0
|
0
0
1
| -cam_x –cam_y –cam_z
0
0
0
1
|
| ux
| * | uy
|
| uz
|
| 0
vx
vy
vz
0
nx
ny
nz
0
0
0
0
1
|
| =
|
|
|
ux
vx
nx
|
uy
vy
ny
|
uz
vz
nz
|-(cam_pos • u) -(cam_pos • u) -(cam_pos • u)
5/24/2016
0
0
0
1
|
|
|
|
22
Finding u, v, n
1. n = <target position-view reference point>
2. v = <0, 1, 0>
3. u = (v x n)
4. v = (n x u)
5. (Optional) Normalize u,v,n by dividing each
vector by its length (if not already done)
5/24/2016
23
Spherical UNV Setup
• Assume camera is sitting at p(,,)
P = target vector
 = length of P
 = elevation angle  = heading angle
r = length of projection of P on the x-z plane
x = - r * sin()
y =  * cos()
z = r * cos()
• x,y,z are for rhs and require transformation
x = -y
5/24/2016
y=z
z=x
24
5/24/2016
25
Initializing Camera
void Init_CAM4DV1
(CAM4DV1_PTR cam,
// the camera object
int cam_attr,
// attributes
POINT4D_PTR cam_pos,
// initial camera position
VECTOR4D_PTR cam_dir,
// initial camera angles
POINT4D_PTR cam_target, // UVN target
float near_clip_z,
// near and far clipping planes
float far_clip_z,
float fov,
// field of view in degrees
float viewport_width,
// size of final screen viewport
float viewport_height)
// this function initializes the camera object cam, the
// function doesn't do a lot of error checking or sanity
// checking since I want to allow you to create projections
// as you wish
5/24/2016
26
Initializing Euler Camera
void Init_CAM4DV1
(&cam,
CAM_MODEL_EULER,
&cam_pos,
&cam_dir,
NULL,
50.0,
500.0,
90.0,
400,
400)
5/24/2016
//
//
//
//
//
//
the camera object
attributes
initial camera position
initial camera angles
for Euler
near and far clipping planes
// field of view in degrees
// size of final screen viewport
27
Initializing UNV Camera
void Init_CAM4DV1
(&cam,
CAM_MODEL_UNV,
&cam_pos,
&cam_dir,
&cam_target,
50.0,
500.0,
90.0,
640,
480)
5/24/2016
//
//
//
//
//
//
the camera object
attributes
initial camera position
initial camera angles
initial target for UNV
near and far clipping planes
// field of view in degrees
// size of final screen viewport
28
Position Camera
Euler
void Build_CAM4DV1_Matrix_Euler
(CAM4DV1_PTR cam, int cam_rot_seq)
// this creates a camera matrix based on Euler angles
// and stores it in the sent camera object
// we need to create a transformation matrix that looks like:
// Mcam = mt(-1) * my(-1) * mx(-1) * mz(-1)
// that is the inverse of the camera translation matrix
// mutilplied by the inverses of yxz, in that order, however,
// the order of the rotation matrices is really up to you, so
// we aren't going to force any order, thus its programmable
// based on the value of cam_rot_seq which can be any value
// CAM_ROT_SEQ_XYZ where XYZ can be in any order, YXZ, ZXY,
// etc.
5/24/2016
29
5/24/2016
30
Position Camera
UNV
void Build_CAM4DV1_Matrix_UVN(CAM4DV1_PTR cam, int mode)
// this creates a camera matrix based on a look at vector n,
// look up vector v, and a look right (or left) u and stores
// it in the sent camera object, all values are extracted out
// of the camera object itself and mode selects how uvn is
// computed
// UVN_MODE_SIMPLE - low level simple model, use the target
//
and view reference point
// UVN_MODE_SPHERICAL - spherical mode, the x,y components
//
will be used as the elevation and
//
heading of the view vector
//
respectively along with the view
//
reference point as the position
//
as usual
5/24/2016
31
World-Camera Transform
• If you want the YXZ ordering
Twc = T-1cam * R-1camy * R-1camx R-1camz
• If you want the ZYX ordering
Twc = T-1cam * R-1camz * R-1camy R-1camx
• Functions to build Euler and UNV cameras
exist so functions to apply the transformations
to objects and render lists are all that are
needed
5/24/2016
32
5/24/2016
33
World-Camera
Object
void World_To_Camera_OBJECT4DV1
(OBJECT4DV1_PTR obj, CAM4DV1_PTR cam)
// NOTE: this is a matrix based function
// this function transforms the world coordinates of an object
// into camera coordinates, based on the sent camera matrix
// but it totally disregards the polygons themselves,
// it only works on the vertices in the vlist_trans[] list
// assumes the object has already been transformed to world
// coordinates and the result is in vlist_trans[]
5/24/2016
34
World-Camera
Render List
void World_To_Camera_RENDERLIST4DV1
(RENDERLIST4DV1_PTR rend_list, CAM4DV1_PTR cam)
// NOTE: this is a matrix based function
// this function transforms each polygon in the global render
// list to camera coordinates based on the sent camera
// transform matrix you would use this function instead of the
// object based function if you decided earlier in the
// pipeline to turn each object into a list of polygons and
// then add them to the global render list the conversion of
// an object into polygons probably would have happened after
// object culling, local transforms, local to world and
// backface culling, so the minimum number of polygons from
// each object are in the list, note that the function assumes
// that at LEAST the local to world transform has been called
// and the polygon data is in the transformed list tvlist of
// the POLYF4DV1 object
5/24/2016
35
Object Culling
• Removing unnecessary objects so that they
won’t be processed during entire 3D pipeline
• Culling can be performed in world space or
camera space
• LaMothe prefers to cull in camera space by
transforming the object center and using a
bounding sphere to determine inclusion or
exclusion based on the object radius
5/24/2016
36
Object Culling
int Cull_OBJECT4DV1
(OBJECT4DV1_PTR obj,
CAM4DV1_PTR cam,
int cull_flags)
//
//
//
//
//
//
//
//
// object to cull
// camera to cull relative to
// clipping planes to consider
NOTE: is matrix based
this function culls an entire object from the viewing
frustrum by using the sent camera information and object
the cull_flags determine what axes culling should take
place x, y, z or all which is controlled by ORing the flags
together if the object is culled its state is modified
thats all this function assumes that both the camera and
the object are valid!
5/24/2016
37
Resetting Flags
void Reset_OBJECT4DV1(OBJECT4DV1_PTR obj)
//
//
//
//
//
this function resets the sent object and redies it
for future transformations, basically just resets
the culled, clipped and backface flags, but here's
where you would add stuff to ready any object for
the pipeline
5/24/2016
38
Back-face Removal
• Process of removing polygons that are facing
away from the viewport
• Test is performed on every polygon of the
object in the render list (can remove 50% of
one sided polygons before performing the
world-to-camera transform)
• The angle between the viewport direction
vector and the surface normal is computed, if
angle > 90 or n • l <= 0 then object not visible
5/24/2016
39
5/24/2016
40
Back-face Removal
Object
void Remove_Backfaces_OBJECT4DV1
(OBJECT4DV1_PTR obj, CAM4DV1_PTR cam)
// NOTE: this is not a matrix based function
// this function removes the backfaces from an object's
// polygon mesh, the function does this based on the
// vertex data in vlist_trans along with the camera
// position (only)
// note:
// that only the backface state is set in each polygon
// tests to see if the object is already culled
5/24/2016
41
Back-face Removal
Render List
void Remove_Backfaces_RENDERLIST4DV1
(RENDERLIST4DV1_PTR rend_list, CAM4DV1_PTR cam)
// NOTE: this is not a matrix based function
// this function removes the backfaces from polygon
// list the function does this based on the polygon
// list data tvlist along with camera position (only)
// note:
// that only the backface state is set in each polygon
5/24/2016
42
Camera-to-Perspective
• Basic transform is
xper = viewing_distance * x_world/z_world
yper = viewing_distance * aspect_ratio * y_world/z_world
• Two approaches: manual or matrix
• However, can’t divide by z using matrices
without first doing 4D homogeneous to
3Dconversions
• This makes the matrix version slow in
software, but hardware may provide some
acceleration for the matrix version
5/24/2016
43
5/24/2016
44
Perspective Transform
Objects
void Camera_To_Perspective_OBJECT4DV1
(OBJECT4DV1_PTR obj, CAM4DV1_PTR cam)
// NOTE: this is not a matrix based function
// this function transforms the camera coordinates of an
// object into perspective coordinates, based on the sent
// camera object, but it totally disregards the polygons
// themselves, it only works on the vertices in the
// vlist_trans[] list assumes the object has already been
// transformed to camera coordinates
//
//
//
//
//
finally this function is really for experimental reasons
only you would probably never let an object stay intact
this far down the pipeline, since it's probably that
there's only a single polygon that is visible! But this
function has to transform the whole mesh!
5/24/2016
45
Matrix Version
• To implement a matrix version we would need
to use the following call sequence
MATRIX4X4 mper;
Build_Camera_To_Perspective_Matrix4X4(&cam, &mper);
Transform_OBJECT4DV1
(&obj, &mper, TRANSFORM_TRANS_ONLY);
Convert_From_Homogeneous4D_OBJECT4DV1
(&obj);
5/24/2016
46
Build Camera Perspective
void Build_Camera_To_Perspective_MATRIX4X4
(CAM4DV1_PTR cam, MATRIX4X4_PTR m)
// function builds up camera to perspective transformation
// matrix, in most cases camera would have a 2x2 normalized
// view plane with a 90 degree FOV, since the point of the
// having this matrix must be to also have a perspective to
// screen (viewport) matrix that scales the normalized
// coordinates, also the matrix assumes that you are working
// in 4D homogenous coordinates and at some point there will
// be a 4D->3D conversion, it might be immediately after this
// transform is applied to vertices, or after the perspective
// to screen transform
5/24/2016
47
Conversion From 4D
void Convert_From_Homogeneous4D_OBJECT4DV1
(OBJECT4DV1_PTR obj)
// this function converts all vertices in the
// transformed vertex list from 4D homogeneous
// coordinates to normal 3D coordinates by dividing
// each x,y,z component by w
5/24/2016
48
Perspective Transform
Render Lists
void Camera_To_Perspective_RENDERLIST4DV1
(RENDERLIST4DV1_PTR rend_list, CAM4DV1_PTR cam)
//
//
//
//
//
//
//
NOTE: this is not a matrix based function
this function transforms each polygon in the global render
list into perspective coordinates, based on the sent camera
object, ou would use this function instead of the object
based function if you decided earlier in the pipeline to
turn each object into a list of polygons and then add them
to the global render list
//
//
//
//
transform each polygon in the render list into camera
coordinates assumes the render list has already been
transformed to world coordinates and the result is in
tvlist[] of each polygon object
5/24/2016
49
Matrix Version
• To implement a matrix version we would need
to use the following call sequence
MATRIX4X4 mper;
Build_Camera_To_Perspective_Matrix4X4(&cam, &mper);
Transform_RENDERLIST4DV1
(&rend_list, &mper, TRANSFORM_TRANS_ONLY);
Convert_From_Homogeneous4D_RENDERLIST4DV1
(&rend_list);
5/24/2016
50
Conversion From 4D
void Convert_From_Homogeneous4D_RENDERLIST4DV1
(RENDERLIST4DV1_PTR rend_list)
//
//
//
//
this function convertes all valid polygons vertices
in the transformed vertex list from 4D homogeneous
coordinates to normal 3D coordinates by dividing
each x,y,z component by w
5/24/2016
51
Perspective-to-Screen
• Often the last stage of the 3D pipeline
• Takes viewport coordinates and scales them
to screen coordinates
• Must take into consideration that most
screens have upper-left origin (0,0) and an
inverted y-axis (translation, inversion)
• Assume that during perspective transform
normalization occurred and that the aspect
ratio was taken into account
5/24/2016
52
Viewport Transformation
Object
void Perspective_To_Screen_OBJECT4DV
(OBJECT4DV1_PTR obj, CAM4DV1_PTR cam)
// NOTE: this is not a matrix based function
// this function transforms the perspective coordinates of an
// object into screen coordinates, based on the sent viewport
// info but it totally disregards the polygons themselves,
// it only works on the vertices in the vlist_trans[] list
// finally this function is really for experimental reasons
// only you would probably never let an object stay intact
// this far down the pipeline, since it's probably that
// there's only a single polygon that is visible! But this
// function has to transform the whole mesh!
// this function would be called after perspective projection
// was performed on the object and result is in vlist_trans[]
5/24/2016
53
Comments
• This function maps the normalized viewport
coordinates to the raster screen
• The 4D homogeneous conversion is not
needed, if division by z occurred during the
camera-to-perspective transformation
• If we have a have object vertices that are
already in 3D form we can use a matrix
version of the viewport transformation
5/24/2016
54
Matrix Viewport Transformation
Object
void Build_Perspective_To_Screen_MATRIX4X4
(CAM4DV1_PTR cam, MATRIX4X4_PTR m)
// this function builds a perspective to screen transformation
// matrix, the function assumes that you want to perform the
// transform in 2D/3D coordinates, that is, you have already
// converted the perspective coordinates from homogenous 4D to
// 3D before applying this matrix, additionally the point of
// this matrix to to scale and translate the perspective
// coordinates to screen coordinates, thus the matrix is built
// assuming that the perspective coordinates are in normalized
// form for 2x2 viewplane, that is, x: -1 to 1, y:-1 to 1
// the only difference between this function and the version
// that assumes the coordinates are still in homogenous format
// is thelast column doesn't force w=z
// we assume that BEFORE this matrix is applied all points are
// already converted from 4D->3D
5/24/2016
55
Viewport Transformation
Render List
void Perspective_To_Screen_RENDERLIST4DV1
(RENDERLIST4DV1_PTR rend_list,CAM4DV1_PTR cam)
// NOTE: this is not a matrix based function
// this function transforms the perspective coordinates of the
// render list into screen coordinates, based on the sent
// viewport in the camera assuming that the viewplane
// coordinates were normalized you would use this function
// instead of the object based function if you decided earlier
// in the pipeline to turn each object into a list of polygons
// and then add them to the global render list you would only
// call this function if you previously performed a normalized
// perspective transform and the result is in tvlist[]
5/24/2016
56
Hybrid Perspective Screen
Transforms
• Provides a means for optimization
• Matrices are slower than performing manual
perspective transformations
• It makes sense to combine the perspective
transform and screen mapping functions
when all you want to do is get the image into
a buffer
5/24/2016
57
Camera-to-Screen Transform
Objects
void Camera_To_Perspective_OBJECT4DV1
(OBJECT4DV1_PTR obj, CAM4DV1_PTR cam)
// NOTE: this is not a matrix based function this function
// transforms the camera coordinates of an object into
// perspective coordinates, based on the sent camera object,
// but it totally disregards the polygons themselves,
// it only works on the vertices in the vlist_trans[] list
//
//
//
//
//
finally this function is really for experimental reasons
only you would probably never let an object stay intact
this far down the pipeline, since it's probably that
there's only a single polygon that is visible! But this
function has to transform the whole mesh!
5/24/2016
58
Camera-to-Screen Transform
Render Lists
void Camera_To_Perspective_Screen_OBJECT4DV1
(OBJECT4DV1_PTR obj, CAM4DV1_PTR cam)
// NOTE: this is not a matrix based function
// this function transforms the camera coordinates of an
// objectinto Screen scaled perspective coordinates, based on
// the sent camera object, that is, view_dist_h and view_dist_v
// should be set to cause the desired (width X height)
// projection of the vertices, but the function totally
// disregards the polygons themselves,it only works on the
// vertices in the vlist_trans[] list this is one way to do it,
// finally, the function also inverts the y axis, so the
// coordinates generated from this function ARE screen
// coordinates and ready for rendering
5/24/2016
59
General Rendering Steps
Stage 0 – Load objects and position them
Stage 1 – Local-to-world transform
Stage 2 – Object and back-face removal
Stage 3 – World-to-camera transform
Stage 4 – Camera-to-perspective transform
Stage 5 – Perspective-to-screen transform
Stage 6 – Render the geometry
5/24/2016
60
Drawing Wireframe Objects
void Draw_OBJECT4DV1_Wire(OBJECT4DV1_PTR obj,
UCHAR *video_buffer, int lpitch)
// this function renders an object to the screen in wireframe,
// 8 bit mode, it has no regard at all about hidden surface
// removal, etc. the function only exists as an easy way to
// render an object without converting it into polygons, the
// function assumes all coordinates are screen coordinates,
// but will perform 2D clipping
// Just iterate thru the poly list of the object and simply
// draw each polygon
5/24/2016
61
Drawing Render Lists
void Draw_RENDERLIST4DV1_Wire(RENDERLIST4DV1_PTR rend_list,
UCHAR *video_buffer, int lpitch)
//
//
//
//
//
//
this function "executes" the render list or in other words
draws all the faces in the list in wire frame 8bit mode
note there is no need to sort wire frame polygons, but
later we will need to, so hidden surfaces stay hidden
also, we leave it to the function to determine the bitdepth
and call the correct rasterizer
// Assume that at this point, all we have is a list of
// polygons and it's time to draw them
5/24/2016
62
Demo7_1
• Name: Single 3D Triangle
• Objects Loaded: none
• Camera: Euler, fixed position, FOV = 90, normalized
viewplane
• Projection: perspective followed by viewport mapping
• 3D Math: manual function calls, no matrix
transformations
• Back-face Removal: none
• Object Removal: none
• Rendering Geometry: render list, single polygon
5/24/2016
63
Demo7_2
• Name: 3D Wireframe Cube
• Objects Loaded: cube1.plg
• Camera: Euler, fixed position, FOV = 90 normalized
viewplane 2x2 with viewport of 400x400
• Projection: perspective followed by viewport mapping
• 3D Math: manual function calls, no matrix
transformations
• Back-face Removal: none
• Object Removal: none
• Rendering Geometry: object rendering, no render list
5/24/2016
64
Demo7_3
• Name: 3D Wireframe Cube with Back-face Removal
• Objects Loaded: cube2.plg
• Camera: Euler, fixed position, FOV = 90 normalized
viewplane –1/ar to +1/ar with viewport of 640x480
• Projection: perspective followed by viewport mapping
• 3D Math: manual function calls, no matrix
transformations
• Back-face Removal: enabled
• Object Removal: none
• Rendering Geometry: object rendering, no render list
5/24/2016
65
Demo7_4
• Name: 3D Tank
• Objects Loaded: tank1.plg
• Camera: Euler, rotatable, FOV = 90 normalized
viewplane –1/ar to +1/ar with viewport of 400x400
• Projection: perspective followed by viewport mapping
• 3D Math: manual function calls, no matrix
transformations
• Back-face Removal: disabled
• Object Removal: yes
• Rendering Geometry: render list with multiple objects
5/24/2016
66
Demo7_5
• Name: 3D Tanks with Flying Camera
• Objects Loaded: tank1.plg
• Camera: UNV, rotatable, FOV = 90 normalized
viewplane –1/ar to +1/ar with viewport of 800x600,
full-screen
• Projection: perspective followed by viewport mapping
• 3D Math: manual function calls, no matrix
transformations
• Back-face Removal: disabled
• Object Removal: yes
• Rendering Geometry: render list with multiple objects
5/24/2016
67
Demo7_6
• Name: Battle Zone Walkthrough Demo
• Objects Loaded: tank1.plg, tower1.plg,
tank3.plg, marker1.plg
• Camera: UNV, rotatable, FOV = 120 normalized
viewplane –1/ar to +1/ar with viewport of 800x600, fullscreen
• Projection: perspective followed by viewport mapping
• 3D Math: manual function calls, no matrix
transformations
• Back-face Removal: disabled
• Object Removal: yes
• Rendering Geometry: render list with multiple objects
5/24/2016
68
Initialize Camera
// initialize the camera with 90 FOV, normalized coordinates
Init_CAM4DV1(&cam,
// the camera object
CAM_MODEL_EULER, // the euler model
&cam_pos, // initial camera position
&cam_dir, // initial camera angles
&cam_target,
// no target
200.0,
// near and far clipping planes
12000.0,
120.0,
// field of view in degrees
WINDOW_WIDTH,
// size of final screen viewport
WINDOW_HEIGHT);
5/24/2016
69
Load Master Objects
// load the master tank object
VECTOR4D_INITXYZ(&vscale,0.75,0.75,0.75);
Load_OBJECT4DV1_PLG(&obj_tank, "tank2.plg",&vscale, &vpos, &vrot);
// load player object for 3rd person view
VECTOR4D_INITXYZ(&vscale,0.75,0.75,0.75);
Load_OBJECT4DV1_PLG(&obj_player,"tank3.plg",&vscale,&vpos,&vrot);
// load the master tower object
VECTOR4D_INITXYZ(&vscale,1.0, 2.0, 1.0);
Load_OBJECT4DV1_PLG(&obj_tower,"tower1.plg",&vscale,&vpos,&vrot);
// load the master ground marker
VECTOR4D_INITXYZ(&vscale,3.0,3.0,3.0);
Load_OBJECT4DV1_PLG(&obj_marker,"marker1.plg",&vscale,&vpos,&vrot);
5/24/2016
70
Position Object Copies
// position the towers
for (index = 0; index < NUM_TOWERS; index++)
{
// randomly position the tower
towers[index].x = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
towers[index].y = 0; // obj_tower.max_radius;
towers[index].z = RAND_RANGE(-UNIVERSE_RADIUS, UNIVERSE_RADIUS);
} // end for
5/24/2016
71
Movement - 1
// read keyboard and other devices here
DInput_Read_Keyboard();
// game logic here...
// reset the render list
Reset_RENDERLIST4DV1(&rend_list);
// allow user to move camera
// turbo
if (keyboard_state[DIK_SPACE])
tank_speed = 5*TANK_SPEED;
else
tank_speed = TANK_SPEED;
5/24/2016
72
Movement - 2
// forward
if (keyboard_state[DIK_UP])
{
// move forward
cam.pos.x += tank_speed*Fast_Sin(cam.dir.y);
cam.pos.z += tank_speed*Fast_Cos(cam.dir.y);
} // end if
5/24/2016
73
Movement - 3
if (keyboard_state[DIK_LEFT])
{
cam.dir.y-=3;
// add a little turn to object
if ((turning-=2) < -15)
turning=-15;
} // end if
else // center heading again
{
if (turning > 0)
turning-=1;
else
if (turning < 0)
turning+=1;
} // end else
5/24/2016
74
Insert Player
// generate camera matrix
Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX);
// reset the object (for backface and object removal)
Reset_OBJECT4DV1(&obj_player);
// set position of tank
obj_player.world_pos.x = cam.pos.x+300*Fast_Sin(cam.dir.y);
obj_player.world_pos.y = cam.pos.y-70;
obj_player.world_pos.z = cam.pos.z+300*Fast_Cos(cam.dir.y);
// generate rotation matrix around y axis
Build_XYZ_Rotation_MATRIX4X4(0, cam.dir.y+turning, 0, &mrot);
// rotate the local coords of the object
Transform_OBJECT4DV1(&obj_player,&mrot,TRANSFORM_LOCAL_TO_TRANS,1);
// perform world transform
Model_To_World_OBJECT4DV1(&obj_player, TRANSFORM_TRANS_ONLY);
// insert the object into render list
Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_player);
5/24/2016
75