Post date: Mar 25, 2012 9:18:03 PM
Proposal
This project will be writing shaders to make 2D and 3D visualization of Conway's Game of Life.
Simple example: Gosper's Glider Gun creating "gliders"
More information about Conway's Game of Life can be found on Wikipedia: http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
There are a lot of implementation of Conway's Game of Life out there, but most of them are running on CPU. The independency between cells when evolving makes it suit very well on GPU. When we compute the state change in parallel, we can simulate much more cells in a more fluent manner.
For this project, I probably will implement it using variants of simple evolving algorithms for the simulation, instead of more 'realistic' advanced ones.
Most effort will be made in visualization of the simulation of very large amount of cells taking the advantage of GPU's parallel architecture.
In detail, I will first write shaders to simulate the evolution process in 2D.
Then I'll make it be 3D, in which I hope the revolution happens in a sphere with two types of area - land and sea. Yes, that's the Earth. Other options will come out during the implementation phase.
After it can work, I'll be working on making the visualization beautiful and interesting.
Finally, I'll try to do some optimization work.
If possible, I'd like to make 1 or 2 more 3D visualizations.
And of course, besides this main feature, there will be extra features such as some display of state information (FPS, number of cells, etc), keyboard/mouse control and what not.
If I still have time, maybe I'll add a launch interface so users can set/change parameters, but I can't promise this is gonna happen.
Here is a webpage of a GPU course in Brown University where I found lots of inspiration: http://www.cs.brown.edu/courses/csci1950-v/projects.shtml
(The copyright of this picture belongs to the author Justin Ardini, http://www.cs.brown.edu/courses/csci1950-v/projects/life/jardini/index.html)
(The copyright of this picture belongs to the author Alicia BoucherJustin Ardini, http://www.cs.brown.edu/courses/csci1950-v/projects/life/aabouche/index.html)
These visualizations are so cool. I really hope my project can be as beautiful as theirs.
This guy simulate 4 millions cells using CUDA: http://www.youtube.com/watch?v=VEWtOac8ElU
================================================================================================================
1. What are accomplished and what not
Yes, I made it:
basic version of game of life as a kernel of opencl.
2D visualization both as a texture and as a vertex array.
3D visualization on a surface of sphere with land/ocean part.
mouse/keyboard control of rotation of the sphere, zoom in/out, pan the camera, pause/resume, reset the sphere, etc
Oh no, time is up:
the different type of seeding. (partial code can be found at about line 200 in main.cpp)
the real time switch of rendering technique between opencl and GLSL. (in the function void display() in main.cpp)
the comparison between opencl and GLSL
Here is a simple video demo of this project: http://youtu.be/G9IVhChoaTk
2. How to start
To run this demo, you must have an OpenCL compatible graphics card and Xcode 4.3 (or later version).
Installation of AMD APP SDK is required.
Then follow next steps to start:
1. Open p3.xcodeproj with Xcode;
2. Change the all file paths in main.cpp, I put them at the beginning of the project so it's not difficult;
3. Build and run.
The source code and resource files can be found at the bottom of this page or here.
3. How is it running
The basic execution process of this demo is as follows:
1 read a world map as texture;
2 seed cells according to the texture;
3 initialize opengl, opencl and set up the kernel for opencl;
4 initialize variables (some memory buffers and for excution;
5 start the loop:
5.1 draw the scene using specified technique;
5.2 draw the rendering information on screen (basically FPS);
5.3 run the kernel once.
where the kernel did following job:
1 find the location of current cell in memory buffer;
2 calculate the states of the eight neighbor cells;
(here, I made the left neighbors of left most colomn the right most colomn, and vice versa)
3 update the state of current cell;
(living cells is green, newly dead cells are either blue or red, based on how they died)
(and the illumination is depending on the z value, i.e., how far from eye)
4 map the coordinates of current cell into world coordinate;
(if rendering in 2D, it's x -> x, y -> y, z = 0, w = 1)
(if rendering in 3D, I used following functions to convert the coordinates)
and it can be manipulated by users during running (and in the intermission)
1 to pan, hold LEFT mouse button and move around
2 to zoom, hold RIGHT mouse button and move up and down
3 to start/pause a rotation of the sphere, press R
4 to toggle between 2D and 3D vision, press P
5 to scale the sphere (it's similar but different from zooming), press A/Z.
6 to start/pause a simulation, press SPACE
7 to reset the position of the scene, press M
Here is some demo snapshots:
This is the initial state
This is the 2D visualization
This is 2D visualization when zoomed in.
This is 2D visualization after running for some time.
This is 3D visualization
This is the 3D visualization when zoomed in showing the other side of the Earth.
4. Optimization
I was trying to use __local memory when the deadline approached.
But I found that the bottleneck is probably not in the kernel itself but in the application controller.
Following is some stats of this demo with 1024*768 grids and 100,000 cells.
(The number of cells is not matter actually, I tried 1,000,000 cells and get the similar result. Because what we are dealing with is the 1024*768 grids in fact)
FPS without kernel is when the simulation is paused and the rendering is not.
And it's very interesting that after zoom in or out, the FPS is different when running without kernel.
5. What I learned
1) It's not a big project but an important one to me since it is the very first time I did this kind of 'free-style' job. I really was not that comfortable with this kind of 'free-style' project. But now things are getting better. Although this project is far from perfect, but at least it is a beautiful start and I'm pround of what I did. It's a new milestone in my travel toward my dream.
2) I also learned a lesson, from a long debug process that takes 4 days only to find one error, that to find a bug, you probably should start from detail and then check the integrated code. This time, I thought the error was because of the mistake in the process of generating/bind/activate/setting attributes of a texture, while it is in fact just a wrong argument in one function call because of the auto-generation in Xcode.
(However, I think this may not always true, the best way is always accumulating experience points, getting yourself level up and increasing ability points to make the locating of a bug quicker and more accurate. If you are sure there is no mistake in the integrated process, then you'll look directly into the detail without hesitation and waste of time)
4) More about this course and Computer Science major.
Well, it's actually the most difficult course I've ever taken, and one of the most interesting course. I have done several so called computer science projects as a Mathematics major undergraduate student and these 'real computer science' projects I did (2 of 422 and 3 of 525) makes them like jokes. Now I have a better understanding of what are computer science students really doing and start to realize how effective and productive a CS student can be (and how far behind is me). I hope that at the end of the next semester, I can be a higher place in grade sheet of this type of 'so-many-projects' course.
2012/4/16