Journal Entry 55 – Wind and Recording

I spent a bit of tonight working on the voxel engine, but unfortunately my priority had to be on consulting work. I decided to have a bit of fun with wind, and making it roll across the terrain. To do this, I needed something suitable to blow about in the wind. I always picture rolling plains of wheat, so I decided to make some wheat.

I created some simple wheat to place on the terrain and blow around with my shader generated wind.
I created some simple wheat to place on the terrain and blow around with my shader generated wind.

I then applied this wheat to the terrain, and applied it often! I also moved the wind calculations completely over to a shader, which was lots of fun. I just make a simple ‘skew’ matrix and then apply it to the vertex positions.

// calculate the skew matrix
mat4 wind_matrix = mat4(1.0);
wind_matrix[1].x = tan(rad / 3);
 
// get the position, normal and light position
vertex_position = (model_matrix * wind_matrix * vec4(floor(in_position), 1)).xyz;

By manipulating the value of ‘rad’ with respect to position, I can now make the wind roll across the terrain. Here’s a picture of it in action (which doesn’t really give it full justice).

Can you spot my character?  The wind blows across the terrain, making the effect look more like real wind!  Soooo pretty, and the picture doesn't do it justice.  Check out the video of the wind in action below.
Can you spot my character? The wind blows across the terrain, making the effect look more like real wind! Soooo pretty, and the picture doesn’t do it justice. Check out the video of the wind in action below.

I then spent some time on figuring out how to make perfectly smooth videos. My computer is *really* old. It is an old school Core 2 Duo E8500, and I’m in dire need of an upgrade. However, I need to make do with what I have for now, so I wrote up some quick code to write out each frame to a .png file. It works by simply reading the pixels and writing them to a Bitmap. I make sure to lock the bitmap bits to make for quick copying.

int[] pixels = new int[Width * Height];
Gl.ReadPixels(0, 0, Width, Height, PixelFormat.Rgba, PixelType.Byte, pixels);
 
// we need to process the pixels a bit to deal with the format difference between OpenGL and .NET
for (int i = 0; i < pixels.Length; i++)
{
    int p = pixels[i];
    int r = p & 0xff;
    int g = (p >> 8) & 0xff;
    int b = (p >> 16) & 0xff;
    pixels[i] = (r << 16 | g << 8 | b) << 1;
}
 
// create a new bitmap object of the correct height and width and then lock the data for quick access
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(Width, Height);
var data = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, Width, Height), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
Marshal.Copy(pixels, 0, data.Scan0, pixels.Length);
bitmap.UnlockBits(data);
 
// bitmaps are flipped in the y direction, so flip it back
bitmap.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY);
 
// write the frame out to a file
bitmap.Save("F:/capture/frame" + frameID++ + ".png", System.Drawing.Imaging.ImageFormat.Png);

I then recombine the frames back together to create a nice and smooth video. Here’s an example of a video recorded in this manner:

Until next time!

Giawa

2 thoughts on “Journal Entry 55 – Wind and Recording

  1. Ohhhh it’s so pretty!! Awesome job with this. I can’t wait to see your character impacting the windy wheat and leave a trail/part the wheat as he runs. That’s pretty much all I’m going to do in this game the first few days hehe… Just leave tons of hidden crop circle messages for people to find.

    ALSO! This ‘tall grass’ would be a perfect spot to stumble across some wild pokem–uhh–critters ^_^

  2. Hi,

    I was looking at your demos at youtube playing with sound… nice videos…

    I’m trying to convert from aif file to mp3 file. do you know how to accomplish that? i’ll really appreciate that.

    BR,
    Lior

Leave a Reply