代写CS 5310 Computer Graphics Graphics System Specification (C)代写C/C++编程

- 首页 >> OS编程

CS 5310 Computer Graphics

Graphics System Specification (C)

1    Overview

The purpose of a computer graphics system is to enable a user to construct scenes and views to achieve a desired result.  Often, speed or real-time performance is also a major concern.  Building complex systems requires careful software design in order to minimize complexity, unexpected effects of changes, readability, and expandability. Modularityin computer graphics system design is an important component of achieving these goals.

The following document specifies the data structures, functions, and functionality for a basic 3D rendering system using C. The data types within the system include the following.

•  Pixel - data structure for holding image data for a single point

•  Image - data structure for holding the data for a single image

•  Z-buffer - a depth image, usually part of the Image data structure

•  Point - a 2D or 3D location in model space

•  Line - a line segment in 2D or 3D model space

•  Circle - a 2D circle

•  Ellipse - a 2D ellipse

•  Polygon - a closed shape consisting of line segments

•  Polyline - a sequence of connected line segments

•  Color - a representation of light energy

•  Light - a light source

•  Vector - a direction in 2D or 3D model space

•  Matrix - a 2D or 3D transformation matrix

•  Element - a element of a model of a scene

•  Module - a collection of elements

•  View2D - information required for a 2D view of a scene

•  ViewPerspective - information required for a perspective view of a scene

•  ViewOrthographic - information required for an orthographic view of a scene

Over the course of the semester, you will implement each of the above data structures using a C struct data type.  The required fields and their purposes are given in the specification below.  For each data type, you will also implement a set of functions. The function prototypes and and a description of the purpose of each required function are also included in the specification, and you are free to add additional functionality. If your code supports the required data types and functionality, then you will be able to run a series of test programs to evaluate and debug your system.

1.1    C versus C++

Many aspects of computer graphics are appropriate for an object-based approach to software design. Primi- tives such as lines, circles, points and polygons naturally exist as objects that need to be created, manipulated, drawn into an image, and destroyed.  We may also want to store a symbolic representation of a scene by saving lists of primitives to a file, which is a natural part of an object-oriented approach.

The ideas of modularity and object-based design are possible to implement in either C or C++. The features of C++ give more structure and exibility to the object-based approach; C gives the programmer lower-level control of information and forces a deeper understanding of how the information flow occurs. A continuum of possible software system structures are possible between the two extremes of a pure object-based C++ design and a modular, but strict C implementation.

As an example, consider the action of drawing a line into an image. Using C++, we might have a class and method prototyped as below. Creating a Line object and calling line .draw(src,  color) would draw a line into the image of the specified color.

class  Line   { public:

Point  a; Point  b;

Line(const  Point  &a,  const  Point  &b);

int  draw(Image  &src,  const  Color  &c); };

int  Line::draw(Image  &src,  const  Color  &c)  {

//  all  of  the  required  information  is  in  the  Line  class  or  Image  class //  draw  the  line  from  a  to  b  with  color  c

return(0); }

The straight C code below has identical functionality and about the same level of modularity.  In the main program, calling lineDraw(line,  src,  color) with a Line structure, an Image and a Color will draw the line in the image.

typedef  struct   { Point  a;

Point  b; }  Line;

int  lineDraw(Line  *line,  Image  *src,  Color  *b)  {

//  all  of  the  required  information  is  in  the  Line  or  Image  structures //  draw  the  line  from  a  to  b  with  color  c

return(0); }

The difference between the two is that in C all of the information required by a function must be explicitly passed through the parameters. In C++, the object on which a method is called can provide some, if not all of the information. Note also that in C passing by reference is not an option:  all C parameters are passed by value, which means copies of the parameters get passed to the function. In C++, passing by reference is possible. Note that in both C and C++ we want to avoid passing whole data structures.

2    Image

The image is a basic object in computer graphics. Conceptually, it is a canvas on which object primitives can draw themselves. A useful way of thinking about the image is to treat it as a storage device that holds color data. In graphics we may want our image to also hold depth data–distance from the camera.  Other objects can write to or read from the image as necessary, modifying the values stored in the image. An image needs to know how to read from and write itself to a le. Note that the data type of the le does not need to match the internal data type of the image.

To represent a single pixel, we need at least three numbers for color images: R, G, and B, corresponding to the red, green, and blue values of the pixel. In graphics, we are also often mixing images together through the use of an alpha channel. The alpha value of a pixel indicates its transparency. We are also often dealing with objects that have an associated depth, so we know what surfaces are in front of what other surfaces. You will want to use a float type to represent the RGB, alpha, and depth values in your image.  You can organize the data as you see fit.

One possible organization method is to create an FPixel type like the following with all five values inter- leaved through the image data structure. An alternative approach would be to have an FPixel data structure that has just the RGB values and then create separate alpha and z fields in your Image data structure (pre-ferred).


Option 1                           Option 2


typedef struct {                 typedef struct {

float rgb[3];                           float rgb[3];

float a;                               } FPixel;

float z;

} FPixel;




Then you can use a single or double pointer ofFPixel type to represent all of the necessary image data.

Image Fields

•  data: pointer or double pointer to space for storing Pixels (e.g. FPixel type)

•  rows: number of rows in the image

•  cols: number of columns in the image

•  depth: (optional) store your z values here, this would be a oat pointer (array)

•  alpha: (optional) store your alpha values here, this would be a oat pointer (array)

•  maxval: (optional) maximum value for a pixel

•  filename: (optional) char array to hold the lename of the image

2.1    Image Functions

All of the Image functions either take in an Image pointer (Image *) as an argument or return a new Image pointer.  You never want to pass an Image into a function, always pass in an Image pointer.  In general, if you’re passing around any data structure bigger than a float or a double, use a pointer to avoid copying the contents of the struct.

Constructors and destructors:

•  Image  *image   create(int  rows,  int  cols) – Allocates an Image structure and initializes the top level fields to appropriate values.  Allocates space for an image of the specified size, unless rows or cols is 0, in which case it should set both rows and cols to 0 and the data pointers to NULL. Returns a pointer to the allocated Image structure. Returns a NULL pointer only if a malloc operation fails.

•  void  image   free(Image  *src) – de-allocates image data and frees the Image structure.

•  void  image   init(Image  *src) – given an uninitialized Image structure, sets the rows and cols fields to zero and the data field to NULL.

•  int  image   alloc(Image  *src,  int  rows,  int  cols) – allocates space for the image data given rows and columns and initializes the image data to appropriate values, such as 0.0 for RGB and 1.0 for A and Z. Returns 0 if the operation is successful.  Returns a non-zero value if the operation

fails. This function should free existing memory if rows and cols are both non-zero.

•  void  image dealloc(Image  *src) –  de-allocates image  data and resets the Image structure fields. The function does not free the Image structure.

I/O functions:

•  Image  *image   read(char  *filename) – reads a PPM image from the given filename.  An op- tional extension is to determine the image type from the filename and permit the use of different file types.  Initializes the alpha channel to 1.0 and the z channel to 1.0.  Returns a NULL pointer if the operation fails.

•  int  image write(Image  *src,  char  *filename) – writes a PPM image to the given file- name.  Returns 0 on success.  Optionally, you can look at the filename extension and write different file types.

Access

•  FPixel  image getf(Image  *src,  int  r,  int  c) – returns the FPixel at (r, c).

•  float  image getc(Image  *src,  int  r,  int  c,  int  b) – returns the value of band b at pixel (r, c).

•  float  image geta(Image  *src,  int  r,  int  c) – returns the alpha value at pixel (r, c).

•  float  image getz(Image  *src,  int  r,  int  c) – returns the depth value at pixel (r, c).

•  void  image   setf(Image  *src,  int  r,  int  c,  FPixel  val) – sets the values of pixel (r,

c) to the FPixel val. If your FPixel contains just r, g, b values then this function should not modify the corresponding alpha or z values.

•  void  image   setc(Image  *src,  int  r,  int  c,  int  b,  float  val) – sets the value of pixel (r, c) band b to val.

•  void  image   seta(Image  *src,  int  r,  int  c,  float  val) – sets the alpha value of pixel (r, c) to val.

•  void  image   setz(Image  *src,  int  r,  int  c,  float  val) – sets the depth value of pixel (r, c) to val.

•  The programmer can also access to the image data directly. You may choose whether to organize the image data as a 1-D single pointer or a 2-D double-pointer.

•  You are welcome to define macros for access functions instead of true functions.  You can also try using the inline keyword, which tells the compiler to substitute the code in the function for the function

call (eliminating the function call) at compile time.

Utility

•  void  image   reset(Image  *src) – resets every pixel to a default value (e.g. Black, alpha value of 1.0, z value of 1.0).

•  void  image   fill(Image  *src,  FPixel  val) – sets every FPixel to the given value.

•  void  image   fillrgb(Image  *src,  float  r,  float  g,  float  b) – sets the (r, g, b) val- ues of each pixel to the given color.

•  void  image   filla(Image  *src,  float  a) – sets the alpha value of each pixel to the given value.

•  void  image   fillz(Image  *src,  float  z) – sets the z value of each pixel to the given value.

3    Color

As we move into shading and 3D color calculations, it will be important to use oating point math rather than integer math to represent colors. The Color type is the same as the RGB component of an FPixel. You may also want to create functions that convert between an integer and a float representation, doing appropriate scaling.  Colors, which are used for calculating shading, use a range of [0,  1], while Pixels for writing to an integer-based le format generally use a range of [0, 255], although 16-bits per pixel is becoming more common.

A simple way to define a Color in C is as an array of oats. typedef  float  Color[3];

However, this representation can also be cumbersome for some tasks (like copying).  So the recommended method of making a Color type in C is as below.

typedef  struct   { float  c[3];

}  Color;

A simple assignment will copy a color if you use the struct definition.

3.1    Color Functions

Define the following functions for the Color type.

void  color   copy(Color  *to,  Color  *from)

– copies the Color data.

void  color   set(Color  *to,  float  r,  float  g,  float  b)

– sets the Color data.

In addition, add the following functions for an Image.

void  image   setColor(  Image  *src,  int  r,  int  c,  Color  val  )

– copies the Color data to the proper pixel.

Color  image getColor(  Image  *src,  int  r,  int  c  )

– returns a Color structure built from the pixel values.

4    Primitive Objects

Primitive objects like pixels, lines, circles, and polygons must hold enough information to know where and how to draw themselves in an image.  The primitives Point, Line, Circle, and Ellipse are required for this assignment. The minimum fields required for each type are listed below.  Note that on this assignment all z-values will be ignored.  However, we’ll need them for 3D in a few weeks.  Why we’re using 4-element vectors for 3D will become clear soon.

InC, while you could use typedef  double  Point[4];, it is probably easier to use a struct.

Point elds

•  double  val[4] – four element vector of doubles.

Line elds

•  int  zBuffer; – whether to use the z-buffer, should default to true (1).

•  Point  a – starting point

•  Point  b – ending point

Circle elds

•  double  r – radius,

•  Point  c – center

Ellipse elds

•  double  ra – major axis radius

•  double  rb – minor axis radius

•  Point  c – center

•  double  a – (optional) angle of major axis relative to the X-axis

Polyline elds (C)

•  int  zBuffer; – whether to use the z-buffer; should default to true (1).

•  int  numVertex – Number of vertices

  Point  *vertex – vertex information

4.1    Primitive Functions

Point

•  void  point   set2D(Point  *p,  double  x,  double  y)

set the rst two values of the vector to x and y. Set the third value to 0.0 and the fourth value to 1.0.

•  void  point   set3D(Point  *p,  double  x,  double  y,  double  z)

set the points values to x and y and z. Set the homogeneous coordinate to 1.0.

•  void  point   set(Point  *p,  double  x,  double  y,  double  z,  double  h)

set the four values of the vector to x, y, z, and h, respectively.

•  void  point normalize(Point  *p)

normalize the x and y values of a point by its homogeneous coordinate: x = x/h, y = y/h.

•  void  point   copy(Point  *to,  Point  *from)

copy the point data structure.

•  void  point draw(Point  *p,  Image  *src,  Color  c)

draw the point into src using color c.

•  void  point drawf(Point  *p,  Image  *src,  FPixel  c)

– draw the p into src using FPixel c.

•  void  point print(Point  *p,  FILE  *fp)

– use fprintf to print the contents of the Point to the stream fp. The FILE pointer fp can be an actual file opened using fopen or a standard output stream like stdout or stderr, both defined in stdio.h. The point print function doesn’t care which it is, it just uses fprintf, which takes a FILE pointer as the rst argument.

Line

•  void  line   set2D(Line  *l,  double  x0,  double  y0,  double  x1,  double  y1)

– initialize a 2D line.

•  void  line   set(Line  *l,  Point  ta,  Point  tb)

initialize a line to ta and tb.

•  void  line   zBuffer(Line  *l,  int  flag)

set the z-buffer ag to the given value.

•  void  line normalize(Line  *l)

– normalize the x and y values of the endpoints by their homogeneous coordinate.

•  void  line   copy(Line  *to,  Line  *from)

– copy the linedata structure.

•  void  line draw(Line  *l,  Image  *src,  Color  c)

draw the line into src using color c and the z-buffer, if appropriate.

Circle

•  void  circle   set(Circle  *c,  Point  tc,  double  tr)

initialize to center tc and radius tr.

•  void  circle draw(Circle  *c,  Image  *src,  Color  p)

draw the circle into src using color p.

•  void  circle drawFill(Circle  *c,  Image  *src,  Color  p)

draw a lled circle into src using color p.

Ellipse

•  void  ellipse   set(Ellipse  *e,  Point  tc,  double  ta,  double  tb)

initialize an ellipse to location tc and radii ta and tb.

•  void  ellipse draw(Ellipse  *e,  Image  *src,  Color  p)

draw into src using color p.

•  void  ellipse drawFill(Ellipse  *e,  Image  *src,  Color  p)

draw a lled ellipse into src using color p.

Polyline

The functions polyline create and polyline free manage both the Polyline data structure and the memory required for the vertex list.

•  Polyline  *polyline   create()

– returns an allocated Polyline pointer initialized so that numVertex is 0 and vertex is NULL.

•  Polyline  *polyline   createp(int  numV,  Point  *vlist)

– returns an allocated Polyline pointer with the vertex list initialized to the points in vlist.

•  void  polyline   free(Polyline  *p)

– frees the internal data and the Polyline pointer.

The functions polyline init, polyline set, and polyline clear work on a pre-existing Polyline data structure and manage only the memory required for the vertex list.

•  void  polyline   init(Polyline  *p)

initializes the pre-existing Polyline to an empty Polyline.

•  void  polyline   set(Polyline  *p,  int  numV,  Point  *vlist)

initializes the vertex list to the points in vlist. De-allocates/allocates the vertex list for p, as necessary.

•  void  polyline   clear(Polyline  *p)

– frees the internal data for a Polyline, if necessary, and sets numVertex to 0 and vertex to NULL.

•  void  polyline   zBuffer(Polyline  *p,  int  flag)

sets the z-buffer ag to the given value.

•  void  polyline   copy(Polyline  *to,  Polyline  *from)

– De-allocates/allocates space as necessary in the destination Polyline data structure and copies the vertex data from the source polyline (from) to the destination (to).

•  void  polyline print(Polyline  *p,  FILE  *fp)

– prints Polyline data to the stream designated by the FILE pointer.

•  void  polyline normalize(  Polyline  *p  )

normalize the x and y values of each vertex by the homogeneous coordinate.

•  void  polyline draw(Polyline  *p,  Image  *src,  Color  c)

draw the polyline using color c and the z-buffer, if appropriate.

5    Polygon

Polygons require a more complex type than the other primitive objects because they are variable sized structures. Polygons are very similar to Polylines, but they can also be filled with a color. It is assumed that the last vertex of a polygon connects back to the first.  As you develop your system, you may want to add more elds into your polygon than the required elds listed below.

Polygon elds (C)

•  int  oneSided – whether to consider the polygon one-sided (1) or two-sided (0) for shading

•  int  nVertex – Number of vertices

  Point  *vertex – vertex information

•  Color  *color – color information for each vertex.

  Vector  *normal – surface normal information for each vertex.

•  int  zBuffer; – whether to use the z-buffer; should default to true (1)

5.1    Polygon Functions

Polygon

The functions polygon create and polygon free manage both the Polygon data structure and the memory required for the vertex list.

•  Polygon  *polygon   create()

– returns an allocated Polygon pointer initialized so that numVertex is 0 and vertex is NULL.

•  Polygon  *polygon   createp(int  numV,  Point  *vlist)

– returns an allocated Polygon pointer with the vertex list initialized to a copy of the points in vlist.

•  void  polygon   free(Polygon  *p)

– frees the internal data for a Polygon and the Polygon pointer.

The functions polygon init, polygon set, and polygon clear work on a pre-existing Polygon data structure and manage only the memory required for the vertex list.

•  void  polygon   init(Polygon  *p)

– initializes the existing Polygon to an empty Polygon.

•  void  polygon   set(Polygon  *p,  int  numV,  Point  *vlist)

initializes the vertex array to the points in vlist.

•  void  polygon   clear(Polygon  *p)

frees the internal data and resets the elds.

•  void  polygon   setSided(Polygon  *p,  int  oneSided)

– sets the oneSided field to the value.

•  void  polygon   setColors(Polygon  *p,  int  numV,  Color  *clist)

– initializes the color array to the colors inclist.

•  void  polygon   setNormals(Polygon  *p,  int  numV,  Vector  *nlist)

– initializes the normal array to the vectors innlist.

•  void  polygon   setAll(Polygon  *p,  int  numV,  Point  *vlist,  Color  *clist,  Vector *nlist,  int  zBuffer,  int  oneSided)

– initializes the vertex list to the points in vlist, the colors to the colors inclist, the normals to the vectors innlist, and the zBuffer and oneSided flags to their respectively values.

•  void  polygon   zBuffer(Polygon  *p,  int  flag)

sets the z-buffer ag to the given value.

•  void  polygon   copy(Polygon  *to,  Polygon  *from)

– De-allocates/allocates space and copies the vertex and color data from one polygon to the other.

•  void  polygon print(Polygon  *p,  FILE  *fp)

– prints polygon data to the stream designated by the FILE pointer.

•  void  polygon normalize(  Polygon  *p  )

normalize the x and y values of each vertex by the homogeneous coord.

•  void  polygon draw(Polygon  *p,  Image  *src,  Color  c)

draw the outline of the polygon using color c

•  void  polygon drawFill(Polygon  *p,  Image  *src,  Color  c)

draw the lled polygon using color c with the scanline z-buffer rendering algorithm.

•  void  polygon drawFillB(Polygon  *p,  Image  *src,  Color  c)

– draw the filled polygon using color c with the Barycentric coordinates algorithm.



站长地图