This is an introductory project in which we will write the input and output related code for our ray tracer. The input will be an XML file describing the scene and the output will be an image in PPM format.
Requirements
[program_name] [scene_file].xml [output_file].ppm
XML Scene Format
Here we define a basic XML format for describing the scene. Upcoming projects will have additional descriptions and we will define them as we need them.
Here is an example scene file:
<xml> <scene> <object type="sphere" name="sphere1"> <scale value="25.0"/> <translate x="0" y="50" z="-25"/> </object> <object type="sphere" name="sphere2"> <scale value="5.0"/> <translate x="0" y="50" z="5.1"/> <object type="sphere" name="sphere3"> <scale value="0.2"/> <translate x="0" y="0" z="1.2"/> </object> </object> </scene> <camera> <position x="0" y="0" z="0"/> <target x="0" y="20" z="0"/> <up x="0" y="0" z="1"/> <fov value="40"/> <width value="800"/> <height value="600"/> </camera> </xml>
Notice that all the objects are declared inside the "scene" tag with an "object" tag. The only object type we will have in this project is "sphere" which denotes a unit size (radius = 1 unit) sphere centered at the origin. The object transformations can be translate, rotate, and scale (in this project translate and scale only) that are declared under the object tag. The transformations are applied in the order that they appear in the XML file. Multiple "scale" and "translate" tags can be defined for the same object. Examples of transformations are given below.
<!-- Translate --> <translate x="3.04" y="50" z="-25"/> <!-- Translate in y direction only --> <translate y="7.8"/> <!-- Rotation around an axis (30 deg) --> <rotate value="30.0" x="1" y="1" z="0"/> <!-- Rotation around z axis --> <rotate value="-10" z="1"/> <!-- Uniform Scale --> <scale value="5.0"/> <!-- Nonuniform Scale --> <scale x="1.5" y="0.5" z="2.1"/>
Object descriptions can also be nested. In that case, all transformations of the parent object also apply to all of the child objects. Child objects can appear before or after (or in between) transformations in the XML file. Regardless of the order, all transformations of the parent object are applied to all of the child objects.
The scene file also includes a "camera" tag that describes the view angle. The size of the final image to be rendered is defined along with other camera parameters (see the example above).
You can use the TinyXML library (or any other library that you prefer) for parsing the XML files.
PPM Image Format
We will use the PPM image format for saving the rendered images. The PPM format was chosen for its simplicity.
The particular PPM variant we will use has an ASCII header followed by the BINARY image data. Here is an example header:
P6 200 150 255
The header begins with the magic number "P6" that defines the PPM format followed by a whitespace. In the example above the whitespace is a new-line character. The following two numbers indicate the width and the height of the image respectively separated by a space character and followed by another new-line character. The next number indicates the largest integer value in the image, which is 255 for our files. Right after 255 we place a single new-line character, which concludes the header. Note that the PPM header format is slighly more general than this description (it can include comments and additional white spaces), but the description provided here is enough for writing a valid PPM header.
Right after this header, the binary image data is written. The binary data will be 8-bit values (0 to 255) for each color component, red, green, and blue respectively. The pixel data is written starting from the top-left corner of the image towards the bottom-right in the English reading order.
Resources
Here is a header file that includes classes for keeping the scene definition in the memory. It uses the point and matrix classes from cyCodeBase. You are free (but not obligated) to make use of these files.
Optional Feature Suggestions
Here are some suggestions for overachievers. You are encouraged but not required to complete any of these. Feel free to add extra features that are not included below.