使用 Java Swing 实现一个2D的绘图引擎。
Assignment Specification
In this assignment, you will be required to implement some of the algorithms
that we have discussed in lectures. You will need to write a generic frame
buffer class that is able to represent images and display them in your
application. Using this frame buffer class, you will need to implement the
ability to draw pixels, lines, circles, templates and filled primitives
without using any existing graphics libraries. The only existing capability
which you are allowed to use is that which takes your image and displays it to
the screen - otherwise you must implement all the 2D graphics functions
yourself. For other non-graphics functions, such as sorting a list or writing
to a disk, you may use existing libraries for your implementation. You can use
Java Swing for the User Interface elements but should not use any other
external libraries or netbeans.
Requirements
You are required to implement a drawing program that is written in Java. You
should not use any other languages for this assignment.
Your program must be able to read a command file supplied at start up and then
render the specified primitives into your frame buffer class. I provide some
sample input tiles that your 2D engine should be able to render.
You must implement the frame buffer class and all primitive rendering
operations yourself, using no other libraries or classes to assist you. You
may only use other classes to display the final frame buffer to the window,
and to perform general I/O operations such as reading the text file and
printing out any debugging information. You may not use code from any other
sources - you must write everything yourself. You must implement a parser that
is able to read in the simple configuration files and render them to the
display.
Command file format
The command files that must be read by your program are based on a simple text
format to make it easy to implement. Each command is represented as a command
followed by the required arguments, using one or more space characters (or a
comma in some cases) as a separator, and a new line character to end the
command. Anything after a # character should be ignored to the end of the line
as a comment. Every command is only one line long.
As each command is parsed, you should execute the command by drawing the
primitive to the frame buffer, and then display it immediately so the user can
see the output as it is being assembled. You should also print out a line of
debugging to the console showing the operation of the program and what
operation it has just performed. When the end of the file is reached the
program is complete and should wait for the user to close down the program.
Here are the commands that you are required to implement:
- INIT [width] [height]
This will always be the first command in the file. It specifies the dimensions
of the frame buffer required. - POINT [xc] [yc] ([R],[G],[B],[A])
Draws a single pixel at (xc,yc) using the specified (R,G,B) colour. Note that
each RGB channel is 8-bits and may vary from 0 to 255. You need to complete
the functionality for this function - LINE_FLOAT [x1] [y1] [x2] [y2] ([R],[G],[B],[A])
Draws a line from (x1,y1) to (x2,y2), using the specified (R,G,B) colour. Note
that each RGB channel is 8-bits and may vary from 0 to 255. This can use
floats for the calculation i.e y=mx+c. - LINE [x1] [y1] [x2] [y2] ([R],[G],[B],[A])
Draws a line from (x1,y1) to (x2,y2), using the specified (R,G,B) colour. Note
that each RGB channel is 8-bits and may vary from 0 to 255. This should use
Bresenham’s line algorithm. - OUTLINE_POLYGON [x1] [y1] [x2] [y2] … [xN] [yN] ([R],[G],[B],[A])
Draws an outline polygon with vertices (x1,y1), (x2,y2), … (xN, yN) using the
specified RGB colour. Note that there may be an infinite number of vertices
specified, at any arbitrary location. - FILL_POLYGON [x1] [y1] [x2] [y2] … [xN] [yN] ([R],[G],[B],[A])
Draws a filled polygon with vertices (x1,y1), (x2,y2), … (xN,yN) using the
specified RGB colour. Note that there may be an infinite number of vertices
specified. It should be possible to render polygons that have degenerate or
inline vertices without experiencing problems. The polygon may be convex or
concave, and edges may cross over each other. When filling the polygon, you
should use the odd-even rule to decide on which parts to be filled. - OUTLINE_CIRCLE [xc] [yc] [radius] ([R],[G],[B],[A])
Draws an outline circle centred about the point (xc,yc) with the specified
radius (note that radius is half the diameter). The specified RGB colour
should be used for the drawing operation. - FILL_CIRCLE [xc] [yc] [radius] ([R],[G],[B],[A])
Draws a filled circle centred about the point (xc,yc) with the specified
radius (note that radius is half the diameter). The specified RGB colour
should be used for the drawing operation. - LOAD_BMP [filename.bmp] (Extension)
This method allows you to load a bmp file, extract its pixel data and store it
in your own pixel buffer. You may use existing java libraries to help with
loading the file. - PAUSE [msec]
Pause the processing of the configuration file for the specified number of
milliseconds. This is used to slow the program down so that the assembly of
the primitives can be observed more easily. - SAVE [filename.bmp]
Take the current frame buffer and save it to the specified output file. You
can find information via Google on how to implement a BMP file, which is
simply a header followed by the 24-bit raw frame buffer data. Your BMP file
should at least be viewable using the Windows file explorer. Be careful to
make sure you write the width, height, and stride values correctly for all
possible image sizes. You may either use a library to achieve this or write
out the raw binary file yourself.
Implement Image Effects
In computer graphics, image effects are filters applied to a rendered image,
usually for post-processing. Some common post-processing effects include:
Tint, Blur, Invert, Depth of Field and Bloom. You are required to implement
the Invert image effect.
Read Pixel Colours
Implement functions to retrieve a pixel’s colour’s red, green or blue
component. You MUST use bitwise operations and a mask to retrieve the values.
Function definitions are provided for getRed [xc] [yc], getGreen [xc] [yc] and
getBlue [xc] [yc]
- INVERT [x1] [y1] [x2] [y2]
Inverts the pixels within the box defined by x1, y1 and x2, y2. It is not
guaranteed that x1, y1 is the top left corner, and x2,y2 is the bottom right
corner.
Program Operation
You source code must compile and run with JDK/JRE 8. Your program should run
from the command line and be able to read its commands in from a filename that
is supplied by the user. The class name containing the main() method must be
called Assign1 with exactly this case and spelling. The command line syntax
must be as follows:
- java Assign1 [cmdfile]
If no arguments are supplied to the program then it should print out a command
line display with information about the program and its usage. It is expected
that you will check all command line arguments to ensure they are valid and
generate a suitable error message if they are not correct.
Note: You may wish to add a debug mode so you can manually enter your commands
to test their operation. To achieve this you should add a switch that allows
this operation i.e. - java Assign1 -debug
To compile your program, we will take the ZIP file you supply, extract out its
contents, compile the source code using javac *.java, and then run it as shown
above. Do not include any extra sub-directories containing code because it
will not be compiled. Do not use packages or jar files.
Make sure that if you use any Java classes, that you only use ones that are
available in the standard JDK libraries. You may implement the display of your
frame buffer class in any way you want, but you should not use existing
libraries to implement any of your primitives or file saving operations. You
may not use source code from other sources, even if referenced, because it is
not your own work.
All possible error conditions should be checked and dealt with avoiding
program crashing or null pointer exceptions being seen by a user. Any invalid
command line arguments or invalid input file strings should be handled
appropriately without exceptions or incorrect behaviour being observed. If an
unknown command is encountered, you should print a warning message but then
continue processing the file. If coordinates are specified which exceed the
canvas size, they should still be correctly rendered. If other values such as
colours are not valid then you should correct them to sensible defaults.
You should NOT use any java packages. You should not use net beans or any
other libraries.
Class Structure
Class Assign1 (Contains the main method and file parsing functions) required
Class FrameBuffer (Contains the int[]pixels and provides all the primitive
graphics functions. I suggest creating a new method for each primitive
function i.e. void init(int width, int height) void point(int xc, int yc, int
r, int g, int b) required
Class MainCanvas (Provides the ability to create a 2D graphics window and
accepts a FrameBuffer object) required
Submission Details
All assignments must be submitted via the learnonline submission system
through the course page. Create a single zip file with the name [emailID].zip
(replace emailID with your own!). When the file is unzipped it should contain
the following:
emailID (folder with the following)
- Assign1.java (required)
- FrameBuffer.java (required)
- MainCanvas.java (required)
- Test01.txt (please submit all test files you create - increment the id of each. i.e. Test01.txt, Test02.txt)
- Assessment.txt Completed self assessment
- Readme.txt any additional information you wish to share with the assessor. If you implemented a Swing GUI include the operating instructions. Also include information if you have attempted the bonus section.
Assessment Feedback
Feedback on assignments will be provided two to three weeks after submission.
Feedback will be available through the course webpage using the Gradebook
system.
Sample Input File
Copy and paste the following into a file “sample1.txt” and parse it to your
program should produce an output that looks like the image below. This file
provides basic testing and should not be considered complete - it does not
test all the functions and is only provided to help you start with your own
test files. I will run a very long and complicated test file to challenge your
rendering engine algorithm implementation.
#
#
# Sample data file provided for testing #
# Create a frame with 500x500 pixels (top left should be 0,0,255)
INIT 500 500
# Draw some red points and pause for .4seconds after all are drawn
POINT 50 50 (255,0,0,255)
POINT 450 50 (255,0,0,255)
POINT 50 450 (255,0,0,255)
POINT 450 450 (255,0,0,255)
PAUSE 400
# Draw two blue squares around the points using lines
LINE 49 49 451 49 (0,0,255,255)
LINE 451 49 451 451 (0,0,255,255)
LINE 451 451 49 451 (0,0,255,255)
LINE 49 49 49 451 (0,0,255,255)
PAUSE 400
# Draw a set of blue lines that fan out from the center
LINE 250 250 150 150 (0,0,255,255)
LINE 250 250 200 150 (0,0,255,255)
LINE 250 250 250 150 (0,0,255)
LINE 250 250 300 150 (0,0,255)
LINE 250 250 350 150 (0,0,255)
LINE 250 250 150 350 (0,0,255)
LINE 250 250 200 350 (0,0,255)
LINE 250 250 250 350 (0,0,255)
LINE 250 250 300 350 (0,0,255)
LINE 250 250 350 350 (0,0,255)
PAUSE 400
# Draw a 200x200 empty box
OUTLINE_POLYGON 150 150 350 150 350 350 150 350 (0,0,255)
PAUSE 400
# Draw two filled green polygons in a cross shape
FILL_POLYGON -10 245 510 245 510 255 -10 255 (0,255,0)
FILL_POLYGON 245 0 255 0 255 500 245 500 245 0 (0,255,0)
PAUSE 400
INVERT 240 30 480 260
# Draw three red circle of diameter 50 with a white outline
FILL_CIRCLE 100 100 50 (255,0,0)
FILL_CIRCLE 400 100 50 (255,0,0)
FILL_CIRCLE 400 400 50 (255,0,0)
FILL_CIRCLE 100 400 50 (255,0,0)
OUTLINE_CIRCLE 100 100 51 (255,255,255)
OUTLINE_CIRCLE 400 100 51 (255,255,255)
OUTLINE_CIRCLE 400 400 51 (255,255,255)
OUTLINE_CIRCLE 100 400 51 (255,255,255)
PAUSE 400
# Draw four white outline circles
OUTLINE_CIRCLE 200 300 50 (255,255,255)
OUTLINE_CIRCLE 200 200 50 (255,255,255)
OUTLINE_CIRCLE 300 200 50 (255,255,255)
OUTLINE_CIRCLE 300 300 50 (255,255,255)
PAUSE 400
# Draw a crazy polygon with crossed edges
FILL_POLYGON 0 0 160 0 160 160 40 160 40 40 200 40 200 200 0 200 (255,0,0)
PAUSE 400
# Draw a crazy zig zag polygon (highly concave)
FILL_POLYGON 0 0 50 50 100 0 150 50 200 0 200 50 150 0 100 50 50 0 0 50 (0,90,0)
PAUSE 400
# Note that all of the following commands are also legal as well
# even though they have multiple spaces and inconsistent formatting!
POINT 250 250 (90,100 ,255)#Thisisacomment
POINT -250 -250 ( 90, 100 , 255)#This is a comment
# Now save the whole lot out to a file before exiting
SAVE sample1.bmp
# Sleep so we can view the output in case they quit straight away
PAUSE 5000