Now that we have put a graphic on the screen, we want to make it do something. Perhaps we want to make it move on the screen. First off, in the last example we created a variable inside the Draw method to hold the position of our image. This wont do, because we need to update that value. If we leave it inside the Draw function, it gets recreated every time draw is called. So instead, lets move it out to be a class member of our game class. Just under our declaration of Texture2D alien, we will add
Vector2 position = Vector2.Zero;
This will create a variable accessible to our game class the can persist through our game. We also need to remove the Vector2 line from the draw function. This will also initialize our position to 0,0.
Now in the initialize method, lets set our initial position.
position.Y = graphics.GraphicsDevice.Viewport.Height / 2;
This sets the Y (vertical component) to 1/2 the height our game's viewport, which we access through the graphics.GraphicsDevice.Viewport object. We will leave the X component alone for now. You can run the program to see what you have accomplished so far. The top left corner of your image should be at (0, 1/2 window height)
Now lets move the image in time. To do this we alter the position variable during the update method call. Lets move our image on a sine wave for kicks. Inside the update method, right above base.Update(gameTime); add some code to update our position
position.X += 0.15f;
position.X is a float so we will add 0.15f to its current value;
position.Y = position.Y + (float)Math.Sin(position.X);
Here we take position.Y and add the Sine of the X component. Sin() returns a double, so we need to cast it to a float and add it to Y so that we end up with a float to assign to position.Y.
Now if you run your program your image should oscillate up and down as it wiggles from left to right.
Tuesday, October 07, 2008
XNA Part 2 - Some Simple Drawing
Now that we have a very basic understanding of the framework of our game, we will do something equally as simple. Taking an image, bringing it into our content manager and drawing it on the screen.
There are many image formats that you can use in XNA, but I am going to suggest the PNG format for a couple of reasons. The first is that it supports variable transparency. That is parts of the image can be between 0% and 100% transparent. As opposed to GIF which is either 0% or 100% transparent or JPG or BMP which has no transparency. XNA will respect the transparency of your image, so it is a good choice. It is also a lossless format which me
ans that it does not have the same type of artifacts that JPG has from it's compression.
So the image I'll use in today's example is one I whipped up in Blender and saved as an RGBA PNG file.
So, let's draw this guy on the screen.
First we need to add the image file to the project. First, under the content folder in the Solution Explorer, right click and choose Add, then choose "New Folder". We will make a folder called "sprites". Sprites are small graphics elements that we can use/reuse in our game. So we make a folder for them in our "content pipeline". Once we have a folder called sprites, right click on it, and choose Add, then choose Existing Item(since our graphic file already exists). Browse to your image file and double click it. You will then see the image listed in your Solution Explorer under the content->sprites folder. Right click on it and change the name of the file to "alien.png".
When your game is compiled, XNA will take the resources in the content pipeline and put them in a format it can use in your game.
Now for some code. We store an image in a XNA object called Texture2D. So first we will add a private member to our game class called alien. Go to the top of your game class and just below "SpriteBatch spriteBatch;" add the line
Texture2D alien;
This creates a class variable in our game class to hold a 2d texture (an image). Now in our "LoadContent" method we will load content into this "alien" variable. Go to the LoadContent method and just below
spriteBatch = new SpriteBatch(GraphicsDevice);
add the line
alien = Content.Load("sprites\\alien");
"Content" is the content manager, so we are telling it to load the sprites\alien file. (notice we leave off the extention, and have to escape the backslash) This returns a reference to a texture2d object and puts that reference into the alien variable.
So now we have an object containing our image data ready to be drawn.
So if we want to draw something we do it in the draw method. Scroll down to it. After the line
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
We will add the following code.
Vector2 position = new Vector2(10,10);
spriteBatch.Begin();
spriteBatch.Draw(alien, position, Color.White);
spriteBatch.End();
Line 1 creates a Vector2 object with the coordinates 10,10. We will use this to position our image. Later we will move this code out of the draw method since it really doesn't belong here. All coordinates in XNA are drawn from the upper left hand corner as 0,0. Keep that in mind.
Line 2 takes our spriteBatch object and calls it's begin method. spriteBatch lets us create a batch of graphical elements and write them to the graphics card in an orderly and efficient manner. So this line begins our batch.
Line 3 adds our image drawing to the batch. There are 7 different ways you can call the spriteBatch.Draw method. The one we have used here takes our Texture2D object, a Vector2 for location, and a color from the Color enumeration that acts as a "tint" for our image. If we do not want to tint our image, we choose Color.White.
Line 4 ends our batch so it can be sent to the graphics card.
This is all the code we need to Draw our image to the game. We can compile and run our program to see the results. You should see your image drawn in your game window.
Here is the complete code for the Game1.cs file
There are many image formats that you can use in XNA, but I am going to suggest the PNG format for a couple of reasons. The first is that it supports variable transparency. That is parts of the image can be between 0% and 100% transparent. As opposed to GIF which is either 0% or 100% transparent or JPG or BMP which has no transparency. XNA will respect the transparency of your image, so it is a good choice. It is also a lossless format which me
ans that it does not have the same type of artifacts that JPG has from it's compression.So the image I'll use in today's example is one I whipped up in Blender and saved as an RGBA PNG file.
So, let's draw this guy on the screen.
First we need to add the image file to the project. First, under the content folder in the Solution Explorer, right click and choose Add, then choose "New Folder". We will make a folder called "sprites". Sprites are small graphics elements that we can use/reuse in our game. So we make a folder for them in our "content pipeline". Once we have a folder called sprites, right click on it, and choose Add, then choose Existing Item(since our graphic file already exists). Browse to your image file and double click it. You will then see the image listed in your Solution Explorer under the content->sprites folder. Right click on it and change the name of the file to "alien.png".
When your game is compiled, XNA will take the resources in the content pipeline and put them in a format it can use in your game.
Now for some code. We store an image in a XNA object called Texture2D. So first we will add a private member to our game class called alien. Go to the top of your game class and just below "SpriteBatch spriteBatch;" add the line
Texture2D alien;
This creates a class variable in our game class to hold a 2d texture (an image). Now in our "LoadContent" method we will load content into this "alien" variable. Go to the LoadContent method and just below
spriteBatch = new SpriteBatch(GraphicsDevice);
add the line
alien = Content.Load
"Content" is the content manager, so we are telling it to load the sprites\alien file. (notice we leave off the extention, and have to escape the backslash) This returns a reference to a texture2d object and puts that reference into the alien variable.
So now we have an object containing our image data ready to be drawn.
So if we want to draw something we do it in the draw method. Scroll down to it. After the line
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
We will add the following code.
Vector2 position = new Vector2(10,10);
spriteBatch.Begin();
spriteBatch.Draw(alien, position, Color.White);
spriteBatch.End();
Line 1 creates a Vector2 object with the coordinates 10,10. We will use this to position our image. Later we will move this code out of the draw method since it really doesn't belong here. All coordinates in XNA are drawn from the upper left hand corner as 0,0. Keep that in mind.
Line 2 takes our spriteBatch object and calls it's begin method. spriteBatch lets us create a batch of graphical elements and write them to the graphics card in an orderly and efficient manner. So this line begins our batch.
Line 3 adds our image drawing to the batch. There are 7 different ways you can call the spriteBatch.Draw method. The one we have used here takes our Texture2D object, a Vector2 for location, and a color from the Color enumeration that acts as a "tint" for our image. If we do not want to tint our image, we choose Color.White.
Line 4 ends our batch so it can be sent to the graphics card.
This is all the code we need to Draw our image to the game. We can compile and run our program to see the results. You should see your image drawn in your game window.
Here is the complete code for the Game1.cs file
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace TutorialGame
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D alien;
Vector2 position = Vector2.Zero;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
position.Y = graphics.GraphicsDevice.Viewport.Height / 2;
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
alien = Content.Load("sprites\\alien");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
position.X += 0.15f;
position.Y = position.Y + (float)Math.Sin(position.X);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(alien, position, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Monday, October 06, 2008
XNA Part 1 - Program Structure
To begin, we fire up C# 2005 and choose to create a new project. We will choose a Windows Game 2.0 project.
A new project is created for us with the boilerplate for a basic Windows XNA game. The file Game1.cs is opened for us (dbl click it if it is not already open) you will see at the top a block of using statements
These import several namespaces from the XNA framework into our current namespace to make coding a little easier.
Now, lets look at some more code.
Our primary game class is a derived class of Microsoft.Xna.Framework.Game
We have some private members for our class to work with, a GraphicsDeviceManager called graphics and a SpriteBatch called spriteBatch (imagine that) We will talk about what those are for a little later.
Now we define our default constructor for our Game1 class. The constructor does 2 things, it allocates a GraphicsDeviceManager for our class and sets a root directory for our game assets. You will notice in the "Solution Explorer" a part called
"Content". This is the base folder for our content pipeline. We will talk more about our content pipeline in the future. It makes your life a little easier.
Now for the instance methods of our game class that we override from the base class. There are only 5 of them, not too tough!
Initialize is called once at the beginning after the constructor, but before LoadContent, so we can set stuff up non content stuff if we need to.
LoadContent is called once for loading content of all things
UnloadContent is called once at the end for unloading content
Update is called with a target rate of 60 times per second, we update our game objects here. We check for keyboard, mouse or gamepad state and update our game accordingly.
Draw is called once after the updates, then waits for the next update. So optimally it is called 60 times a second as well.
Now click your compile button to build and run your game, and you should get a little blue screen "CornflowerBlue" to be exact. That is all your game does at the moment. Click the red X to end it.
If you got an error rather than the game, you may not have a graphics card capable of running XNA games. For this I apologize for your wasted time. If your game ran, than you will be ready for our next installment.
A new project is created for us with the boilerplate for a basic Windows XNA game. The file Game1.cs is opened for us (dbl click it if it is not already open) you will see at the top a block of using statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
These import several namespaces from the XNA framework into our current namespace to make coding a little easier.
Now, lets look at some more code.
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
Our primary game class is a derived class of Microsoft.Xna.Framework.Game
We have some private members for our class to work with, a GraphicsDeviceManager called graphics and a SpriteBatch called spriteBatch (imagine that) We will talk about what those are for a little later.
Now we define our default constructor for our Game1 class. The constructor does 2 things, it allocates a GraphicsDeviceManager for our class and sets a root directory for our game assets. You will notice in the "Solution Explorer" a part called
"Content". This is the base folder for our content pipeline. We will talk more about our content pipeline in the future. It makes your life a little easier.
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back ==
ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
}
}
}
Now for the instance methods of our game class that we override from the base class. There are only 5 of them, not too tough!
Initialize is called once at the beginning after the constructor, but before LoadContent, so we can set stuff up non content stuff if we need to.
LoadContent is called once for loading content of all things
UnloadContent is called once at the end for unloading content
Update is called with a target rate of 60 times per second, we update our game objects here. We check for keyboard, mouse or gamepad state and update our game accordingly.
Draw is called once after the updates, then waits for the next update. So optimally it is called 60 times a second as well.
Now click your compile button to build and run your game, and you should get a little blue screen "CornflowerBlue" to be exact. That is all your game does at the moment. Click the red X to end it.
If you got an error rather than the game, you may not have a graphics card capable of running XNA games. For this I apologize for your wasted time. If your game ran, than you will be ready for our next installment.
Getting Started with XNA
So you want to be a game programmer? Well my answer is yes, so I'm picking up the Microsoft XNA framework for C# as my first step. Some people agree with this and some don't but hey you gotta start somewhere. So I'm gonna take you, my loyal reader on this trip with me.
Right now XNA 2.0 is the current release, but 3.0 is in beta. If you want to use XNA 2.0 you need Visual C# 2005, 3.0 requires Visual C# 2008.
So lets install a couple of things to get going on this...
1. Visual C# 2005 Express
You can pick MS's free version of the visual c# here, get that installed and then get...
2. XNA Game Studio 2.0
Installing XNA will add the XNA classes/framework into Visual C#
Now something to keep in mind is that XNA requires a graphics card that can support shader model v1.1
3. While you are at it, you can visit http://creators.xna.com/ and sign up for an account there. The forums there seem like they are active and people are willing to give tips.
So, do that stuff and we will start looking at some code in our next installment.
Right now XNA 2.0 is the current release, but 3.0 is in beta. If you want to use XNA 2.0 you need Visual C# 2005, 3.0 requires Visual C# 2008.
So lets install a couple of things to get going on this...
1. Visual C# 2005 Express
You can pick MS's free version of the visual c# here, get that installed and then get...
2. XNA Game Studio 2.0
Installing XNA will add the XNA classes/framework into Visual C#
Now something to keep in mind is that XNA requires a graphics card that can support shader model v1.1
3. While you are at it, you can visit http://creators.xna.com/ and sign up for an account there. The forums there seem like they are active and people are willing to give tips.
So, do that stuff and we will start looking at some code in our next installment.
How it all started...
What got me "into" computers? I hadn't thought too much about it. It was always something that I was interested in and was drawn towards. But what was it that made it 'click' with me. Well the other night was movie night at our house and there was nothing good on TV. So out of the blue I suggested we watch an old favorite of mine from 1982. TRON. So I dug out my VHS copy and put it in and my kids were amazed by the (now very dated) special effects. They LOVED the light cycles and the tanks and thought 'bit' was hillarious. Then it hit me. This may be it. The movie that convinced me that computers were an exciting area, and that making computer games would be a very cool way to make a living (just like Flynn)
So, here I am 26 years later. I work with computers every day, but am not a game programmer. That brings me to my next series of upcoming posts. I've recently started learning the Microsoft XNA framework. Which is a .NET extension of classes for game programming on the PC, XBOX360 and Zune platforms. I have always found that teaching something helps me learn it better, so I will teach you how to use XNA and take another step closer to my childhood dreams of taking down the MCP with my identity disc.
Thursday, June 26, 2008
Web Programming Toolkit
I am not a "web guru" but I can generally get things done. But I am always on the lookout for tools that will make things easier. Here are some of the tools that I've been using lately in both my primary job and side projects that I work on.
Content Creation - Text Editing
In this area I am 'old school', I'm a text editor kinda guy. Right now my text editor of choice is notepad++. This is a great notepad replacement with line numbering and syntax highlighting and lots of other goodies for a programming editor.
Content Creation - Graphics
As I have mentioned in other posts, I am a big fan of Blender 3d for graphics creation both 3d and 2d. Also Inkscape for vector graphics is another great tool. Paint.Net is also good for getting those 2d images ready for the web.
Database
It is no small suprise that my database of choice would be MySQL. Here is a web standard if I ever saw one. Easy to set up and use and has always been very PHP friendly. I am also doing some looking at SQLite to see if it may hold some possibilities for use in the future for me. Actually I mention this because I've tinkered a little lately with Google Gears which is a component from Google that allows you to create a local site specific database on a client machine (with their permission of course) to let you store relational database information OFFLINE so that they can cache your web based application on their computer and use it while they are disconnected. This is actually how Google Docs and Reader are doing their offline modes. It uses a SQLite engine to accomplish this.
Code
PHP & PEAR
Most of the files you will see coming from my editor are coded in PHP. PHP has become one of the foremost used scripting languages used online these days. It is versatile for mixing dynamic content with static, making it easy to design websites that reuse a lot of code rather than duplicating it page after page. PHP also allows for easy integration with databases. This point brings me to PEAR. PEAR is the PHP Extension and Application Repository. This is a readily available library of tools written to extend the capabilities of PHP. One example is the MDB2 library which allows you to write database applications that don't really care what kind of database is backing it up (as long as the database tables are there) so your application can be just as happy talking to a mysql database as to an mssql or SQLite database. It also allows for "lazy" database connections. You can set up your database connection in a header file then when you code you always have a $db object ready to talk to the database for you. It also makes it easy to get the data back from queries really simple to do in various formats. I'll probably do a example in my next blog post.
JavaScript
I've been using a Javascript Framework called Prototype lately that is really helpful. I've mentioned it before. If all you are looking for is an easy way to get into AJAX, check it out. Also an extention to Prototype called Script.aculo.us makes doing user interfaces easy with JavaScript and AJAX. From animated effects to Edit-In-Place fields to Drag and Drop support it is a great library to get to know.
A recent javascript library that I found for making HTML tables sortable is called Standardista Table Sorting it is very simple to implement in your code and is very fast. I'll have to show you how I added it to a function to take a MDB2 result set and turn it into a sortable database table (based on an idea implemented by a co-worker) in a later post.
So, in short, yes I am firmly planted in the LAMP (Linux Apache Mysql PHP) camp. But I am certainly open to other tools and technologies. Really whatever makes my job easier.
What are your favorite tools, languages, database engines and libraries? Leave a post and let me know!
Content Creation - Text Editing
In this area I am 'old school', I'm a text editor kinda guy. Right now my text editor of choice is notepad++. This is a great notepad replacement with line numbering and syntax highlighting and lots of other goodies for a programming editor.
Content Creation - Graphics
As I have mentioned in other posts, I am a big fan of Blender 3d for graphics creation both 3d and 2d. Also Inkscape for vector graphics is another great tool. Paint.Net is also good for getting those 2d images ready for the web.
Database
It is no small suprise that my database of choice would be MySQL. Here is a web standard if I ever saw one. Easy to set up and use and has always been very PHP friendly. I am also doing some looking at SQLite to see if it may hold some possibilities for use in the future for me. Actually I mention this because I've tinkered a little lately with Google Gears which is a component from Google that allows you to create a local site specific database on a client machine (with their permission of course) to let you store relational database information OFFLINE so that they can cache your web based application on their computer and use it while they are disconnected. This is actually how Google Docs and Reader are doing their offline modes. It uses a SQLite engine to accomplish this.
Code
PHP & PEAR
Most of the files you will see coming from my editor are coded in PHP. PHP has become one of the foremost used scripting languages used online these days. It is versatile for mixing dynamic content with static, making it easy to design websites that reuse a lot of code rather than duplicating it page after page. PHP also allows for easy integration with databases. This point brings me to PEAR. PEAR is the PHP Extension and Application Repository. This is a readily available library of tools written to extend the capabilities of PHP. One example is the MDB2 library which allows you to write database applications that don't really care what kind of database is backing it up (as long as the database tables are there) so your application can be just as happy talking to a mysql database as to an mssql or SQLite database. It also allows for "lazy" database connections. You can set up your database connection in a header file then when you code you always have a $db object ready to talk to the database for you. It also makes it easy to get the data back from queries really simple to do in various formats. I'll probably do a example in my next blog post.
JavaScript
I've been using a Javascript Framework called Prototype lately that is really helpful. I've mentioned it before. If all you are looking for is an easy way to get into AJAX, check it out. Also an extention to Prototype called Script.aculo.us makes doing user interfaces easy with JavaScript and AJAX. From animated effects to Edit-In-Place fields to Drag and Drop support it is a great library to get to know.
A recent javascript library that I found for making HTML tables sortable is called Standardista Table Sorting it is very simple to implement in your code and is very fast. I'll have to show you how I added it to a function to take a MDB2 result set and turn it into a sortable database table (based on an idea implemented by a co-worker) in a later post.
So, in short, yes I am firmly planted in the LAMP (Linux Apache Mysql PHP) camp. But I am certainly open to other tools and technologies. Really whatever makes my job easier.
What are your favorite tools, languages, database engines and libraries? Leave a post and let me know!
Thursday, June 19, 2008
Free / Open Source DVD Creation Workflow
Occasionally I will have the need to create a DVD. I'll do slide shows for weddings or special events, videos for family or church. My DVD drive came with it's own burning software but I've been looking for a more portable solution, since I use other computers with DVD burners in them, but no pre-installed burning software. Here is a rundown of how I might put together a slide show DVD with no commercial software.
First I'll need to scan in my images, for this you can use Paint.NET. If you haven't seen Paint.Net yet, it is a great light Photoshop replacement. If all you are doing is scanning, rotating and cropping images and doing minor work on them, it is super. Others would say to use Gimp here, but it has always felt clunky to me. Paint.NET is Windows only, so Mac and Linux users will need to look elsewhere for this part of the chain.

Once you have you images ready, you may need some extra slides as intro or ending slides. For this I go to my old stand by, Blender. Here for instance is a pair of wedding bands that I made for a wedding slide show. I added the text after the fact. You could also use Blender to create menu graphics for your DVD. It has a built in non-linear video editor if you wanted to do any motion video or animation as well. Blender is cross-platform: Windows, Mac and Linux can all use it.
So at this point, I have a folder full of images that I have named numerically in the order I want them (this speeds up the process later) ready to be made into a slide show. Now in the past I have used Windows Movie Maker, but I wanted to get away from that because it really has it's limitations. So in doing a little searching I found SSMM which is a really handy slide show tool. It has a pretty wide selection of transition effects and a pretty simple layout. You can also sync up audio as well (as long as it is in WAV format, see the section on FFMPEG later for help) Once you have all your settings done, it will render an AVI file of your slide show. SSMM is Windows only, so Mac and Linux users will need to look elsewhere. It may run under Wine for you Linux folk, but I don't know.
Now I needed to get this AVI onto a DVD. I found DVDStyler, a Windows/Linux DVD authoring package (Mac users could of course use iDVD). It lets you build your menus and insert movies into your DVD project and burn the DVD as well. There is only one problem with DVDStyler, for videos, it only accepts mpeg and SSMM only outputs AVI. But have no fear, there is always a solution.
If you do any work with video files, FFMPEG can be your best friend. One of the tools in the ffmpeg package is a command line converter. It can convert a TON of formats, including wmv and quicktime. It also does audio formats, so if you have an MP3 file that you want to convert to a WAV so you can use it in SSMM, it'll do that too! So with this simple command I can convert my AVI from SSMM to an mpeg usable by DVDStyler.
Now that it is converted, DVDStyler can add it, I can finish the menus and burn my DVD.
So there you have it it may not be the quickest solution, but if you have a scanner and a DVD burner already, you are good to go. Do you have any suggestions for this production chain? Any tools in your toolbox that you would like to share?
First I'll need to scan in my images, for this you can use Paint.NET. If you haven't seen Paint.Net yet, it is a great light Photoshop replacement. If all you are doing is scanning, rotating and cropping images and doing minor work on them, it is super. Others would say to use Gimp here, but it has always felt clunky to me. Paint.NET is Windows only, so Mac and Linux users will need to look elsewhere for this part of the chain.

Once you have you images ready, you may need some extra slides as intro or ending slides. For this I go to my old stand by, Blender. Here for instance is a pair of wedding bands that I made for a wedding slide show. I added the text after the fact. You could also use Blender to create menu graphics for your DVD. It has a built in non-linear video editor if you wanted to do any motion video or animation as well. Blender is cross-platform: Windows, Mac and Linux can all use it.
So at this point, I have a folder full of images that I have named numerically in the order I want them (this speeds up the process later) ready to be made into a slide show. Now in the past I have used Windows Movie Maker, but I wanted to get away from that because it really has it's limitations. So in doing a little searching I found SSMM which is a really handy slide show tool. It has a pretty wide selection of transition effects and a pretty simple layout. You can also sync up audio as well (as long as it is in WAV format, see the section on FFMPEG later for help) Once you have all your settings done, it will render an AVI file of your slide show. SSMM is Windows only, so Mac and Linux users will need to look elsewhere. It may run under Wine for you Linux folk, but I don't know.
Now I needed to get this AVI onto a DVD. I found DVDStyler, a Windows/Linux DVD authoring package (Mac users could of course use iDVD). It lets you build your menus and insert movies into your DVD project and burn the DVD as well. There is only one problem with DVDStyler, for videos, it only accepts mpeg and SSMM only outputs AVI. But have no fear, there is always a solution.
If you do any work with video files, FFMPEG can be your best friend. One of the tools in the ffmpeg package is a command line converter. It can convert a TON of formats, including wmv and quicktime. It also does audio formats, so if you have an MP3 file that you want to convert to a WAV so you can use it in SSMM, it'll do that too! So with this simple command I can convert my AVI from SSMM to an mpeg usable by DVDStyler.
ffmpeg -i inputmovie.avi -b 1600kb outputmovie.mpgNow that it is converted, DVDStyler can add it, I can finish the menus and burn my DVD.
So there you have it it may not be the quickest solution, but if you have a scanner and a DVD burner already, you are good to go. Do you have any suggestions for this production chain? Any tools in your toolbox that you would like to share?
Wednesday, June 04, 2008
Settling In
Well, I'm into my 3rd week at Greenville College. Week one was spent getting re-acclimated to how the IT department was set up, getting my accounts set up as well as my computer
and learning that I may well get pegged in the head at any time with a nerf rocket. My second week at the college was not spent there, but in Nashville, TN at the JAM 2008 convention. This is the annual conference for a company called Jenzabar who makes software for higher education. I went with Dan Coulter and Kris Truitt. We went to a lot of sessions about the core software we use at the college, but also spent a bunch of time hanging out. We watched a bunch of RiffTrax and ate ate this a hole in the wall BBQ place called Hog Heaven. So really a great time!
and learning that I may well get pegged in the head at any time with a nerf rocket. My second week at the college was not spent there, but in Nashville, TN at the JAM 2008 convention. This is the annual conference for a company called Jenzabar who makes software for higher education. I went with Dan Coulter and Kris Truitt. We went to a lot of sessions about the core software we use at the college, but also spent a bunch of time hanging out. We watched a bunch of RiffTrax and ate ate this a hole in the wall BBQ place called Hog Heaven. So really a great time!So now the hard work begins, but I'm looking foward to it.
Monday, April 14, 2008
Getting into AJAX with Prototype
I've been working with PHP for about 5 or 6 years. I first got into using it while working as a Database Admin at Greenville College, trying to write a web based reporting interface for the college's student data system. I had previously been using Perl for everything CGI and PHP made working with databases a lot easier. After taking a job as a network admin at a bank, I had a lot less use for PHP. I used it when I could to 'keep my skills up' on freelance work and Bank intranet stuff. Now I had been hearing about AJAX for a couple years and knew it was something I should pick up. I tried reading a few tutorials on it and learned quickly that it was a little different between browsers and took a bunch of code to get working. All the tutorials I found were more about getting it set up rather than what you did with it. They all started with the Asynchronos JavaScript and XML bit, explained the first half and never said what to do with the XML. Well, after a little playing I put it aside for a while. I recent picked it up again and found the same old tutorials and still no luck. I asked an old co-worker of mine Dan Coulter who wrote the phpflickr class if he could give me some assistance. He pointed me to Prototype which is a JavaScript framework that makes dealing with AJAX much nicer. At first I thought it was all about the AJAX, but it isn't. It really makes JavaScript much easier to use cross-platform. First of all there is a utility function for accessing DOM elements. It looks like this
$('myelement')
This returns the element with the ID of myelement. Want to change the content of a DIV called stuff?
$('myelement').update('New Content');
even better the $$() function lets you get lists of objects like
But what about AJAX?
As I have learned recently AJAX is less about the acronym and more about making calls to other web pages without reloading the current page. This is where PHP & AJAX really make nice friends. With Prototype, making an AJAX call is this simple:
new Ajax.Request('mypage.php',{method:'get'});
This basically opens a call to the mypage.php page and returns the results to the browser. Now this example doesn't do anything with that result. For that you have to extend things a little, and add in the $() stuff
new Ajax.Request('mypage.php',{
method:'get',
onSuccess: function(r){
$('mydiv').update(r.responeText);
}});
This code runs the mypage.php page, takes the results of that page and replaces the contents of the element mydiv with it.
I am still digging into Prototype, and find new things to do with it each time I sit down with it. So, if you are interested in picking up AJAX or just beefing up your JavaScript programming, I would highly recommend it.
$('myelement')
This returns the element with the ID of myelement. Want to change the content of a DIV called stuff?
$('myelement').update('New Content');
even better the $$() function lets you get lists of objects like
$$('div');
Would return an array of all the div tags in your document or
$('div.myclass');
would return all divs with the class 'myclass'
But what about AJAX?
As I have learned recently AJAX is less about the acronym and more about making calls to other web pages without reloading the current page. This is where PHP & AJAX really make nice friends. With Prototype, making an AJAX call is this simple:
new Ajax.Request('mypage.php',{method:'get'});
This basically opens a call to the mypage.php page and returns the results to the browser. Now this example doesn't do anything with that result. For that you have to extend things a little, and add in the $() stuff
new Ajax.Request('mypage.php',{
method:'get',
onSuccess: function(r){
$('mydiv').update(r.responeText);
}});
This code runs the mypage.php page, takes the results of that page and replaces the contents of the element mydiv with it.
I am still digging into Prototype, and find new things to do with it each time I sit down with it. So, if you are interested in picking up AJAX or just beefing up your JavaScript programming, I would highly recommend it.
Friday, April 11, 2008
Backstage Meetings
I have to say that I am not easily starstruck. My dad was in charge of a lot of conventions when I was young and I met a lot of special guest speakers, in college I was the stage manager or assistant stage manager of the Agape music festival for 3 years and saw and dealt with a lot of artistist there. I ran sound and was stage manager for Nashville North in Taylorville, IL for a couple years, where a lot of big name country acts came through. All that to say I'm generally not impressed by fame. Well, that is until it becomes personal. One of the first cassette tapes I ever owned was Phil Keaggy's Find Me in These Fields and over the years his style has been a major influence of my playing (not that I can play like Phil ) I have seen him in concert a few times. Once on his Crimson and Blue tour back in 1994, on the Keaggy, King, Dente tour, once in a masterclass and concert at Greenville College and last night at Harvester Christian Church. We arrived to find that the "Artist Circle" seating area which we had tickets for was oversold and we had to sit in an "artist circle overflow" area. They were not bad seats, I wasn't really upset by this. At intermission we were told that because of this error, the people who had to sit there would get to have a personal meet and greet with Phil after the show. So after the show we went back and I got to meet Phil. Pretty much a handshake, a couple stupid sounding compliments from me, and a picture. He also gave us all signed copies of his recent CD set, but it was enough. You listen and idolize someone for that long and when you get a chance to meet them face to face, it's pretty cool.So although I don't easily get starstruck, I do make exceptions.
Monday, November 19, 2007
My Robot has 10,000 Views!
Well, I know it's small change for some, but I was pretty excited to see that my Gibson Robot Guitar Video has over 10,000 views. For those of you who are wondering, I did the animation with Blender. Which is an open source 3d package. Well, Thanks to all who have watched and I'll let you know when you can go vote :)
Sunday, November 18, 2007
Accepting Undeserved Gifts
I recently received a gift. Now mind you, I like gifts, a lot. Who doesn't really? But this was one of those take your breath away sorts of gifts. A gift I did not want to touch in case it was some sort of mistake. But soon it sank in that this brand new guitar in front of me was in fact sent to me by...anonymous. There was no card or tag or from or anything. It did not say who paid the bill or ordered it. It was just sitting there waiting to be picked up, plugged in and played. Being the inquisitive person I am, I immediately called my parents, neither knew a thing about it and so I started trying to figure out who would have done this and WHY! I have ideas of who may have been invovled in this, but I came to a realization. Finding out who sent this gift is not the point. If they wanted a phone call saying thanks, they would have put in a note or called to make sure it arrived intact. Instead, I think the sender of this gift wants me to do what the gift calls for, to be pulled from it's case, tuned up, turned up and played on. To be used in worship is the type of thanks this type of anonymous gift calls for.
Now why has this hit me so hard? I do not deserve this kind of gift. Sure there I days when I feel like I deserve everything I want and then there are days when I know what I have coming and know I deserve every bit of it. Usually the latter is true. But I think that this gift I have received outlines something important. Christ came to earth to die in our place as the biggest undeserved gift ever. We spend so much time trying to figure out why or wrestle with the nuts and bolts of Christian life and forget to just pick up the gift with a greatful heart and use it to the best of our ability. Does Christ expect our thanks? Yes, but I think the thanks he wants is not the thanks that we generally say in our bedtime prayers, but instead using of his gift to glorify his name.
Now why has this hit me so hard? I do not deserve this kind of gift. Sure there I days when I feel like I deserve everything I want and then there are days when I know what I have coming and know I deserve every bit of it. Usually the latter is true. But I think that this gift I have received outlines something important. Christ came to earth to die in our place as the biggest undeserved gift ever. We spend so much time trying to figure out why or wrestle with the nuts and bolts of Christian life and forget to just pick up the gift with a greatful heart and use it to the best of our ability. Does Christ expect our thanks? Yes, but I think the thanks he wants is not the thanks that we generally say in our bedtime prayers, but instead using of his gift to glorify his name.
Wednesday, November 14, 2007
Gibson Robot Guitar
Gibson is releasing a self-tuning guitar called the Gibson Robot Guitar. They are having a make your own video contest to win one. So here is my entry....
Hopefully they will add my video to their site soon for voting. I already have over 1000 views on YouTube so at least some people have seen it :) Enjoy.
The Gibson page is here
Wednesday, October 17, 2007
Out with the Old...

So my effects rack of 13 years finally decided to die on me. It was an ART SGX2000 and it just started flaking out. So I have started from the ground up. I have a BOSS volume pedal from many years back that still works great so to that I added a DS-1 Distortion and BD-2 Blues Driver. Also today I got in a CH-1 Chorus pedal. I built a temporary board for them and this is what it looks like. I got the 1-spot 8 pedal power kit and the CoreX2 solderless cable kit. So far I am very happy.
Saturday, July 21, 2007
Wednesday, July 11, 2007
The Wishbook
I used to love making wishlists. As a kid I would circle so many things in the Sears "Wishbook", or I would find something I wanted and work hard to save my pennies to get it.
I have kinda gotten out of the habit in recent years, because as a father of 4 I usually do not have any extra cash to spend on myself. But as I go along I have found that day to day life has actually made me stop wishing for things. I don't spend time dreaming of the what ifs. I am not talking about being materialistic, sitting around being jealous of those who have what we want is very unproductive. But I think that wishing for things can be a great motivator for us to tackle new goals, expand our horizons and go after things that may, in our current circumstance, seem unattainable. Things can certainly own us and there ARE wrong reasons for wanting things. To outdo someone or to hoard something, these are not good. On the other hand things can be symbols. Symbols are so important. Take a look at company logos. It is not enough just to have a name, you need a symbol. If we wish for things in our life that are representative symbols of who we want to become, they can not only aid us once we have them, but can motivate us to become that person who 'deserves' that thing, and perhaps help us take our lives in a new direction that we may have only dreamed or wished about.
Recently (as you can see in another blog post of mine) I entered a contest. First place prize is $57,000. I made a decent entry and so I thought "What if I won?" At first my thoughts went to how much debt I could pay off, but then for the first time in a long time I did a little dreaming. My guitar and rig are old, an old rig for a tired guitarist, but then I thought, what if I could spend $$$ on a real setup. So in the spirit of wishing, here is a link to my wishlist of choice.
Guitar Center Wishlist
As you can see, johnnyGizmo wishes to break out of his cubicle and pursue something more. I have a new excitement in my life. I realize that I very well may not win this contest, but the wishing it prompted has given me something that I needed just as much.
I have kinda gotten out of the habit in recent years, because as a father of 4 I usually do not have any extra cash to spend on myself. But as I go along I have found that day to day life has actually made me stop wishing for things. I don't spend time dreaming of the what ifs. I am not talking about being materialistic, sitting around being jealous of those who have what we want is very unproductive. But I think that wishing for things can be a great motivator for us to tackle new goals, expand our horizons and go after things that may, in our current circumstance, seem unattainable. Things can certainly own us and there ARE wrong reasons for wanting things. To outdo someone or to hoard something, these are not good. On the other hand things can be symbols. Symbols are so important. Take a look at company logos. It is not enough just to have a name, you need a symbol. If we wish for things in our life that are representative symbols of who we want to become, they can not only aid us once we have them, but can motivate us to become that person who 'deserves' that thing, and perhaps help us take our lives in a new direction that we may have only dreamed or wished about.
Recently (as you can see in another blog post of mine) I entered a contest. First place prize is $57,000. I made a decent entry and so I thought "What if I won?" At first my thoughts went to how much debt I could pay off, but then for the first time in a long time I did a little dreaming. My guitar and rig are old, an old rig for a tired guitarist, but then I thought, what if I could spend $$$ on a real setup. So in the spirit of wishing, here is a link to my wishlist of choice.
Guitar Center Wishlist
As you can see, johnnyGizmo wishes to break out of his cubicle and pursue something more. I have a new excitement in my life. I realize that I very well may not win this contest, but the wishing it prompted has given me something that I needed just as much.
Saturday, June 30, 2007
Heinz Ketchup Commercial Entry
I made an entry for the the Heinz "Top This TV Challenge". Check it out. First prize in the contest is $57,000!!! Let me know what you think :)
Download All the Videos from A Given YouTube User with a Simple Script.
I wrote a little Perl script that takes a YouTube username and with the help of FFMPEG, downloads and converts all the public videos that user has posted and converts them to any format FFMPEG supports like mpg or mov.
read more | digg story
read more | digg story
Sunday, May 27, 2007
Update and an Observation
Well, its been a while since my last post. We are now very close to completing our paperwork. We have a couple more documents to get and then a lot of photocopying and notorization to get done. The a big chunk of $$$ will get us into the "waiting phase" of the adoption. At that point things will be out of our hands until we get our referal. We are getting closer all the time and it feels like it is taking for ever. I also want to thank the people who have dontated funds either through Chipin or directly to my Paypal account. Your donations certainly have helped us with the costs of this process.
On a different note, I noticed something that I do lately. When I am around my kids, I talk about myself in the 3rd person. Why do I do this? It's not like my kids don't understand the concept of the word "I". But apparently phrases like "Daddy has to go to work" are now how I talk. Well anyway, talk to you all later because Johnny is going crazy :)
On a different note, I noticed something that I do lately. When I am around my kids, I talk about myself in the 3rd person. Why do I do this? It's not like my kids don't understand the concept of the word "I". But apparently phrases like "Daddy has to go to work" are now how I talk. Well anyway, talk to you all later because Johnny is going crazy :)
Tuesday, March 20, 2007
Our First Donation!!!
Well we had our first donation through ChipIn recently, in response to the getCals program (which is hosted here getCals if you need it) So thanks to your donation (you know who you are!) you have paid for one of our passport photos.
Subscribe to:
Posts (Atom)