Computer Graphics
CSCI 490J, CSCI 630
Bezier Curves and Patches
Your assignment should consist of the following parts:
Bezier Curves
Implement the code to display Bezier curves. This code will be added to the
rd_view program. See the documentation page on the RD language for details on
the Curve command.
Bezier Patches
Implement code to display Bezier patches. This code will be added to the rd_view
program. See the documentation page on the RD language for details on the
Patch command.
Implementation
The bulk of the rd_view program is found in the file libcs630.a You will write some
extra code which when linked with this library will give you a working rd_view
complete with Bezier curves and patches. This library and its associated header
file can be found on the support page of the course web site.
Some explanation is in order. You must implement the routines
render_bezier_curve() and render_bezier_patch . The renderer will call these routines
automatically. Of course you may write any other functions you need to help
implement your program. Everything else in the header file is provided as a
resource to you in your program.
The renderer works on attributed points which contain x, y, z, and possibly
much more. These points are represented by the attr_point data structure which
is essentially just an array of floats. In most cases, many possible attributes will
not be needed, so a mechanism has been created to help pack the points as
tightly as possible and only process as much of the internal array as needed.
The meta_attribute structure contains information about where certain attributes
NIU – CSCI 490J/630 Assignment 4
1 of 5
can be found in the array of an attributed point. For this project this is found in
the global variable render_m_attr. For example, by checking render_m_attr.color, I
can find out that the RGB color information associated with an attributed point
can be found starting at element 5 in the coord array of the attributed point.
The values in render_m_attr will remain constant for any given curve or patch, but
may change from curve to curve or from patch to patch.
Most of the algorithms used in this assignment do not depend on the position of
particular attributes in an attributed point. Rather the same operations (usually
interpolation, right?) must be performed on all valid positions in the coordinate
array. render_m_attr.size indicates how many positions in the array are used.
If you are drawing your curves and patches using subdivision into small lines
and polygons, you may find the global variable n_divisions useful. It was designed
to indicate how many divisions some things should be divided into. It has a
default value of 20 and can be set in any scene file by using the OptionReal
command. An example is given below.
OptionReal “Divisions” 10
Your program should not change the n_divisions variable directly.
The functions line_pipeline and poly_pipeline form the core interface to the
rendering engine found in libcs630.a The line_pipeline command must be called
once for each point in a sequence of points. For the first point in the sequence a
draw_flag value of 0 or MOVE is used. For each subsequent point, a draw_flag
value of 1 or DRAW is used. A line segment from the previous point to the
current point will be drawn.
The poly_pipeline() is used to draw polygons. A sequence of vertices is passed in
one at a time to the pipeline. A draw flag of MOVE is used for all vertices except
the last one, which uses DRAW. The pipeline will save all vertices of the polygon
and not actually draw anything until the last vertex comes through.
The attr_points passed to the pipelines need a little extra attention before the
pipelines are called. In addition to the locations indicated by render_m_attr, the
geometry values (x, y, z) need to be stored in postions 0, 1, and 2 of the
attributed point. 1.0 should be stored in positions 3 and 4 of the attributed
point. This will need to be done for every point passed in to the pipeline. The
pipeline may change the values in the attributed point.
For this assignment, drawing the control polygon can be ignored. A proper
implementation requires access to too many internal points of rd_view to worry
NIU – CSCI 490J/630 Assignment 4
2 of 5
about at this point.
In your Bezier curve and patch routines, you will need to set the data_m_attr and
render_m_attr structures. These are not set prior to calling your routines.
Below is code for each routine to take care of the missing functionality for the
meta attributes
render_bezier_curve()
// At the beginning of the function
data_m_attr.clear();
err = data_m_attr.set_data_indices(vertex_type);
err = render_m_attr.set_render_indices(vertex_type);
render_m_attr.add_shading_offset();
…
render_bezier_patch()
// At the beginning of the function
data_m_attr.clear();
err = data_m_attr.set_data_indices(vertex_type);
err = render_m_attr.set_render_indices(vertex_type);
render_m_attr.add_normal();
render_m_attr.add_shading_offset();
if(err)
return err;
…
Patch Normals
The rendering engine allows interpolation of vertex normals between polygon
vertices in order to produce smooth shading effects. In order for this to happen,
a vertex normal value must be set in the attributed point passed to
poly_pipeline(). The starting location for the normal within the attributed point
can be found with render_m_attr.normal. To calculate vertex normals, you will most
likely need the vertex XYZ positions. These can be found in elments 0, 1, and 2
respectively of the attributed point coordinate array passed in.
In addition to vertex normals, a normal vector that is constant for an entire
polygon must be calculated. The value of this normal is stored in the global
variable poly_normal, an array of 3 floats for the x, y, and z components of the
NIU – CSCI 490J/630 Assignment 4
3 of 5
normal vector. This vector must be set before the last polygon vertex is sent to
the poly_pipeline() with the DRAW flag.
Namespaces
The line_pipeline() and poly_pipeline() functions are found in the render_direct
namespace. What’s more, the draw_bezier_curve() and draw_bezier_patch() that you
will write must reside in that same namespace. If you’ve never created your
own namespace before, the process is actually quite simple. In your source code
file, around the entire body of code implementing your functions, place
namespace render_direct
{
at the beginning and an additional closing curly brace at the end of the source
code file.
Implementation Order
Get curves working first. Write an empty stub for render_bezier_patch.
Write the patch routines, but don’t worry about surface normals at first.
Simply compute the poly_normal for each polygon sent through the pipeline.
Use the OptionBool “Interpolate” off in your scene files to have the per-vertex
vertex normals ignored (they’re garbage at this point.)
Tackle vertex normals.
Linking
To produce a working rd_view use the following command:
g++ -o rd_view libcs630.a your_object_files_here -lX11 -lm
Extra Goodies
The renderer has some extra features placed in it that you might want to play
with.
Control polygons for Bezier curves and surfaces will be drawn
automatically when
OptionBool “Control” on
is placed in a scene file. The color used for the control polygons will be the
color in effect when the OptionBool command is given.
NIU – CSCI 490J/630 Assignment 4
4 of 5
There is a ray tracer built in. It’s alpha code at this point, but it will work
with spheres and polygons. To access it, place
Engine “raytrace”
as the first line in the scene file. Make sure that the render mode for the
Display command is “rgbsingle” or you’ll be waiting a long time to actually
see anything.
Artistic
Make a scene file showing off some of your new objects. Use some nice lighting
and material properties.
NIU – CSCI 490J/630 Assignment 4