Extra Feature: Graphical User Interface
When all tier-3 functionality was done, we thought about what extra features we could add and one of the things that came to mind was a Graphical User Interface (GUI). The command line interface with the renderer is pretty basic and there are no options for scene modification, unless you edit the (sometimes very cryptic) gml file itself. So it would be nice to have some control over the render properties, before the actual rendering takes place. This is our main goal for the GUI: influence the rendering parameters to create different images from the same gml source files.
The GUI is created with wxHaskell, based on wxWidgets. The controls, layout and painting make up most of the code, the rest is firing up the renderer with the right parameters. For the GUI to be able to 'intercept' the rendering process, a hack was needed though. The whole program was set up to be a pipeline: Parser -> Evaluator -> Renderer. Now we want to stop the process after evaluation and go on when we're ready. A change in the evaluator made this possible, but this was not very nice for the 'normal' process, so we made a copy of the Evaluator, for use with the GUI only, see the source files for more details. This is also not an ideal solution of course and we could do it more clean, but considering the limited time, we thought it was the best option available.
The chosen solution is to provide an extra TVar (Maybe RenderData
) argument to the evaluator (where RenderData
is a type synonym for a tuple of all render parameters). When the evaluator encounters the gml 'render' function, it will set all evaluated data for the rendering in that variable, instead of calling our own render function. Now the evaluator is done and the GUI has access to the render parameters. These include filename, width, height, field of view, ambient light, scene object, etc. The user can change these values with the user interface and when done click the render button. The GUI will now call the internal render function with the 'new' parameter values. The result is rendered to a ppm file as normal, and the gui will display that file when rendering is complete.
The user interface of the LightSpeed
ray tracer GUI is pretty much self explanatory, but for completeness a list of all components and their usage is given below.
1. File menu:
- Open GML: open a gml file for use with the program
- About: an info box about the program
- Quit: quit the program
2. This panel will display a reference image of a rendering (if available) with all settings as in the gml file.
3. You can change the filename of the rendered file in this box.
4. This slider controls the image size. When you slide the size slider, you can see a preview of the output size, indicated by a red rectangle. The minimum size is tiny, the maximum size is the width of the right panel (height according to ratio). Larger images should be created with the command line. This GUI is not meant for rendering huge images.
5. The value for the ambient color of the scene. Every scene has an ambient color, and changing it can lead to interesting and funny results. Just use the sliders for red, green and blue to create the color of your choice! :)
6. The angle of the field of view, in degrees. Smaller values will lead to 'more narrow' vision, and larger values lead to a wider vision of the scene.
7. The tracing depth is the amount of 'bouncing' performed by a ray, before the final color is produced. Important to keep above 0 to see reflection effects. Larger values for more dramatic reflection, only if the scene has reflective objects of course.
8. Rendering controls: enlargement, anti-aliasing and the render button. The enlargement drop down can increase the display size of an image, without more precision. This is especially handy if a scene has a long render time, so you decrease the resolution, but you still want to be able to see what's on the picture. Anti-aliasing is another extra feature. You can activate it by checking this box. Be aware though, render time will increase significantly. Finally, if you're happy with all settings, hit the render button to view the result.
9. Some stats about the process of parsing, evaluating and rendering.
10. These 12 buttons give you (limited) control over the camera. Actually, they modify the scene, not the camera, since that is fixed. The move buttons work pretty much as expected, but the turn buttons require some experimentation. The result depends on the position of the scene relative to the origin. A turn is performed for the whole scene, around an axis. Try out some stuff and see what interesting new viewpoints you can reach. :)
NB: These buttons will automatically trigger rendering, so make sure the other settings are as you want them, before you click one of these.
11. This panel displays the rendered image. Upon loading a gml file, a very crude preview is rendered automatically. If you changed the size since your last render, you'll also see the edges of the new rendered image indicated by a red rectangle.
Question: The GUI seems to be frozen, I can't do anything!
Answer: This is probably, because the rendering is i progress. Unfortunately, there is no progress bar on screen, but you can see a text based progress indication in the terminal where you started the program. If it takes too long, you'll have to kill the process. Sorry, cancelling options have a lot of impact on existing code.
Question: What can I use this GUI for exactly?
Answer: You can create interesting and funny variations on the standard gml fil renderings. One particular nice way to work with the GUI is: set the rendering size to a very low value, and set the enlargement to x8, so you can still see something on screen. Now use the move & turn buttons to 'navigate' around the scene. Since the image size is so small, this should go pretty fast. When you found a nice spot, increase the rendering size to the maximum value (with enlargement back to x1) and wait some time to discover you nice and cool new rendering of the scene!
Question: How does the GUI handle gml files with multiple calls to 'render'?
Answer: The GUI does not support multiple renderings for one gml file. Only the last call to 'render' is considered.
Question: How can I get some sample gml files and renderings?
Answer: Download gml-data.zip
and run the program from within the unzipped gml-data folder. You'll get a collection of files the GUI is capable of handling in an acceptable time. Experimenting with bigger files is also possible of course. Browse to the appropriate folder and try the gml file of your choice.
Question: I never get a reference image in the left window, how can I fix that?
Answer: See the question above. If you follow those instructions, you should see reference images for the GUI selected gml files.