This assignment makes use of the files contained in this zip file. This assignment is due Friday, September 2.
This assignment and your next assignment are about the data structures used at the two ends of the 3D graphics rendering pipeline; what goes into the beginning of the pipeline and what comes out of the end of the pipeline. Roughly, what goes into the pipeline is the Scene data structure which describes the geometry of what the renderer should draw. What comes out of the pipeline is the FrameBuffer data structure which holds the image of the scene drawn by the renderer. This assignment is about what comes out of the graphics pipeline, the FrameBuffer data structure. Assignment 2 will be about what goes into the rendering pipeline, the Scene data structure.
A FrameBuffer object holds an array of pixel data that represents an image that can be displayed on a computer's screen. For each pixel in the image, the framebuffer's array holds three integer values, one integer that represents the red component of the pixel's color, one integer that represents the green component, and one integer that represents the blue component of the pixel's color. Each of these three integers is only eight bits in size, so each of the three colors has only 256 shades (but there are 256^3 = 16,777,216 distinct colors). If a framebuffer has dimensions n rows of pixels by m columns of pixels, then the framebuffer holds 3*n*m integers. The pixel data is NOT stored as a "two-dimensional" (or "three-dimensional") array. It is stored as a one-dimensional array of length 3*n*m. This array is in "row major" form, meaning that the first 3*m integers in the array are the pixels from the image's first row. The next 3*m integers are the pixels from the images second row, etc. Each row is stored with the pixels in RGB order. That is, the very first three integers of the array are the red, green, and blue values for the first pixel if the image. Finally, the first row of the pixels is the top row of the image as its displayed on the computer's screen.
This assignment has two parts. For the first part, you are to write a program that creates a FrameBuffer
object and then fills it with pixel data so that the resulting image looks like the file Part_1_demo.ppm
from the zip file. In the zip file there is a file Part_1.java
that you need to complete. In Part_1.java
there is a brief outline of what you need to do. You should make as much use of the FrameBuffer
interface as possible when you write your code. To learn about the FrameBuffer
class's interface, look at its source code in the framebuffer
sub folder of the zip file (you can also look at the Javadoc html file for the FrameBuffer
class). Your program should produce a result that looks exactly like Part_1_demo.ppm
. There are a number of facts about the image in Part_1_demo.ppm
that you need to find out (like, what are the exact colors?). Use tools from pixel-utilities.zip to determine these details about Part_1_demo.ppm
.
For part 2 of this assignment, you will write a program that modifies the contents of a framebuffer after the contents of a PPM file have been written into the framebuffer. In the zip file there is a file Part_2.java
that you need to complete. Your program should draw a black border around the image in a PPM file. Run the demo program demo_program\Part_2_demo.cmd
to see how your program should modify the images in cow.ppm
, horse.ppm
, and starfish.ppm
.
You need to come up with an algorithm that detects which pixels are on the edge of an image and turn each of those pixels black. Your program needs to find "background pixels" in the framebuffer that are next to "image pixels" (in other words, your program needs to find the edge of the image) and turn those particular background pixels black. If you look at the three image files, cow.ppm
, horse.ppm
, and starfish.ppm
, you will see that they have different background colors. Your program can assume that the first pixel in an image (the upper left hand corner pixel) has the background color. Your program can also assume that no pixel in the image itself has the color of the background.
Your program should essentially be a pair of nested loops that iterate through the whole framebuffer, looking for pixels on the edge of the image. You need to find a (somewhat complicated) boolean expression that is true when a background pixel has one of its (eight) neighbors in the image. Change any pixel that satisfies this boolean from the background color to black. That will give you a one-pixel wide black border around the image.
But a one pixel wide border is not too noticeable. The border drawn by the demo program is three pixels wide. To get a wider border, iterate your code on the result of your first pass over the framebuffer. The result of the second pass over the framebuffer should leave a two pixel wide border around the image. (A third pass should give a three pixel wide black border.) But the second time you iterate over the framebuffer, you will need to consider the border pixels (from the first iteration) as part of the image. So your border color for the second iteration needs to be slightly different from the border color in the first iteration. I make the border color in each iteration one unit lighter that the previous iteration (I used border color (r,g,b)=(0,0,0) for the first iteration, border color (r,g,b)=(1,1,1) for the second iteration, and (r,g,b)=(2,2,2) for the third iteration, etc.) If you run the command,
demo_program\Part_2_demo.cmd 50
it tells the demo program to draw a 50 pixel wide border. You can see in the resulting pictures that the border gets lighter as it gets wider.
Your program should draw a 3 pixel wide border around the image in a PPM file. (If you want, you can try to give your program an optional command line parameter that determines the width of the border, as in the demo program.)
Turn in a zip file called CS455Hw1Surname.zip
(where Surname
is your last name) containing your versions of Part_1.java
and Part_2.java
.
This assignment is due Friday, September 2.