Here are a couple of high quality agile project planning blogs I've been frequenting. The authors are very knowledgeable, and present topics in a manner that is very easy to digest and start using.
all about agile by kelly waters
Succeeding with Agile
OOH OOH EEH EEH
Saturday, April 26, 2008
Thursday, April 24, 2008
Sprint 1: Classics

So, I decided to start simple and make a game I know I could finish but would allow me to focus on process to help me produce my future projects. So I decided on a pong clone. The difference is I wanted to all elements that I think would make it fun(ner).
My development techniques are all agile based (SCRUM). I am targeting two week iterations to produce valueable functionality. My plan is to produce working demos that demonstrate the current state of the game as it is in development.
With that out, my first iteration is complete. It started on 4/11 and was scheduled to end 4/25. Fortunately, I am a day ahead of schedule which is good and bad. Good because I accomplished the items I committed to. Bad because my estimates were off, but will provide nice feedback for upcoming iterations.
At the end of each iteration I will provide links to that iteration's deliverables to give you all a chance to see the progress. I encourage everyone to provide all feedback. Any feedback is beneficial to help me make the best product I can make.
I also would like to touch on some of the things I thought went well and think that will need to be improved on. This will give me a chance to review what happened during the last iteration and also get insight from you guys on things that have happened in your projects.
Things that went well
Selected strong indie tools
- Torque Game Builder: a fully featured 2D game engine that makes rapid development of games easy and fun. You can purchase an indie license for $100. Best price on the market for the power and efficiency you get.
- Torsion: a Torquescript editor with a nice arsenal of debugging tools. It is a must for any type of Torque Game Engine develoment. It goes for $39.95.
- RallyDev: an online agile project management application. It tracks product backlogs, iteration status, and provide agile metrics to know how far along you are in your project. Best of all there is a free version.
Created a testing process
I came up with a way to test new functionality and organize it in a way that would clutter or interfere with the application. This helped verify new functionality didn't break existing functionality. Taking the time to do that helped speed up my development time.
Things that didn't go so well
Stories too detailed: Initially I created stories that were too detailed. This pigeon-holed me into thinking of only one way to approach a requirement. This present an opportunity for me to refactor my existing stories in the product backlog.
Didn't setup source control: I should be slapped for this. I started the project without having any source control. There was a point where I felt the brunt of this when I performed a large refactoring that I almost had to roll back. Luckily I found my flaw and was able to proceed with the refactoring. Otherwise I would have been is a really bad situation.
Opportunities for the next iteration
- Setup Source Control
- Refactor User Stories so they are not implementation specific
Iteration Deliverables
Inside the PowerPong root directory are too important files at this point: readMe.txt and console.log.
readMe.txt - Describes the controls because the in game input text was left generic because controls will be customizeable.
console.log - Log of what is happening in the game. Send this along with any defects to me at charles_gibson_jr@hotmail.com
UPDATE: The issues regarding the Mac distribution has been identified. In the process of updating and redistributing a Mac version. Thanks for your patience.
- PowerPong - Win32
- PowerPong - Mac
OOH OOH EEH EEH
Another joyous addition
She's here! Her name is Simone Marie Gibson. She was delivered into this world at 1:27am on April 16, 2008. She weighed 5 lbs 11 oz and was 19.5 inches long.
It all started at around 9pm on April 15th. Katie, my wife, started having contractions. They were sporadic and didn't last very long. We decided not to worry too much about them but to start tracking and timing them.
Then at around 10pm, they started to happen a bit more frequent with increased intensity. These contractions were averaging around 7 mins. We called the hospital to get their advice on whether we should come in or not. They left it up to us. Since during our previous pregnancy Katie was in labor for 8 hours after her water broke we assumed we had time. So we decided to rest.
At around 12:30am, Katie woke me indicating it was time to go. Still in control, we begin what we practiced. She starts getting dressed and I start taking the bags downstairs to put in the car. Once downstairs, I hear her call for me. I race upstairs to see that her water has broke. Slight panic, but still in control. I mean with our first born, we still had 8 hours so surely we had time to make it to the hospital.
So I call my mother to let her know we are going to drop off our oldest daughter and go into the hospital. My wife motions she needs to go to the bathroom, and I follow suit. As I am handling my business, I hear her scream. I race back into the room to see her on all fours. There is slight spotting on the floor. She begins telling me the baby is coming.
Now I'm in freak-mode. I try to get it together. I tell her to get dressed. I frantically call my mother to tell her we aren't coming. Then call my sister who lives closer to come over immediately and to let herself in because we needed to race to the hospital.
While I was calling Katie has started downstairs to get into the car. Still on the phone with my sister, I hear another scream. I immediately hang up, and jump downstairs to see my wife on the floor by the door that leads to our garage. She is really emphasizing how the baby is coming any moment now. She asks if we should call 911.
In that brief second I decided against it because I think we could make it to the hospital in time, rather than having to wait for an ambulance to get to our house risking giving birth before they get there. So she quickly gets into the car, with me right behind her.
I race down the street, at points reaching 90 mph. While the entire time my beautiful wife is trying her hardest to fight the urge to push even though her body ignores her efforts.
We pull up to the Emergency Room entrance. I dart out of the cart screaming "We need assistance, my wife is pregnant!!" There were no doctors in sight. Only two night security guards. One lazily asks, "Do you need a wheelchair?" I wanted to strangle him, so I harshly reply "YES!".
I run back to my wife to help her into the hospital. As I get to her I see her legs are weakened from her trying to fight the pushing. I catch her before she falls. She then tells me "You need to carry me."
"What? I don't think I can do that..."
Comically she replies, "No, you need to carry me...". Thinking to herself, you have been working out you better get to carrying! :)
There was no time to continue this conversation so I scooped her up and started racing down the halls screaming at the security guards for directions to the birth center.
As we round the corner toward the birth center, I never felt so alone. The hallway grew endless and pitch black. It was as if the hospital was abandoned. My wife starts to scream in fear the baby was going to come out and fall to the floor.
We reached the double doors that lead to the birth center. My wife tells me to put her down on the floor because the baby was coming now.
As I laid her down, a doctor appeared along with two nurses, one pushing a wheelchair. My wife tells him the baby is coming, but in disbelief he replies, "No, the baby isn't coming. Let's get you to a room."
Out of frustration my wife starts pulling her pants down to prove it. While she was pulling we lifted her and put her in the wheelchair and raced to the staging room. Once there, the nurse grabbed Katie's right side and I grabbed her left. We hoisted her out of the wheelchair. At that very moment Simone's head appeared. In mid lift the nurse grabbed Simone's head to catch her as we lifted Katie to the bed. Once on the bed, it only took my lovely wife three pushes and our baby girl was here.
At that moment, a new life began for all of us. She's our special jellybean! Our Simone.
Wednesday, April 09, 2008
Agile Project Management Tool
I came across a slick Agile Project Planning tool called Rally. I am using it for my current game project "PowerPong". The makers of Rally also have a nice library of videos explaining how to use their tool for agile development. I highly recommend it to anyone needing a project planning tool to streamline their product backlog and iteration releases.
OOH OOH EEH EEH
OOH OOH EEH EEH
Wednesday, March 19, 2008
XNA Testing
Finally, I've figured out a way to test my XNA rendering code.
I've created a small hierarchy. There is the GameTestBase class and the GameTester interface. My approach is very simillar to the Template Method design pattern where the flow is managed by GameTestBase and GameTester defines the implementation.
Instead of using functions, I used anonymous delegates. This allowed me to isolate the objects under test within each concreate GameTester without GameTestBase having to know about the inner workings of each test. Or have each concrete GameTester query the world from GameTestBase.
Program.cs provides entry into the application so the code to run a test is as follows.
A GameTester is supplied as a parameter to the GameTestBase constructor to plugin the implementation of the test. Once the GameTestBase object has been constructed we tell it to run the test. And that's it! Woot! Now let's take a look at the GameTester (GameObjectRenderTester).
A concrete GameTester object is made up of three public properties: LoadContentDelegate, UpdateDelegate, and DrawDelegate. Each delegate is responsible for implementing a particular section of the application flow. The LoadContentDelegate is responsible for loading any content before the application enters the application loop. The UpdateDelegate is responsible for performing any object animations or prerender operations. Finally, the DrawDelegate delegate is responsible for rendering.
The cool thing about this approach is how the tester can have its own state and it be used within each delegate without any interference from the GameTestBase class. This greatly simplified my tests from prior. I was in static hell!
Now let's have a look at the GameTestBase class to see how it uses the GameTester to run a test.
First, GameTestBase inherits from the Microsoft.Xna.Framework.Game class. It then overrides the LoadContent(), Update(), and Draw() methods. These are the three methods that the GameTester will implement. As demonstrated in the GameTestBase constructor, the GameTester delegates are stored off and used from within the GameTestBase overrides.
And that's all she wrote folks. It is that easy. It even gives me a nice way to organize my tests. This type of testing is a step up from unit testing because now I can test logic such as collision detection to verify it is calculating and rendering properly. This does not replace my unit testing though, but provides a way to perform tests that don't lend themselves well to unit testing.
So, can I get a hell yeah???
I've created a small hierarchy. There is the GameTestBase class and the GameTester interface. My approach is very simillar to the Template Method design pattern where the flow is managed by GameTestBase and GameTester defines the implementation.
Instead of using functions, I used anonymous delegates. This allowed me to isolate the objects under test within each concreate GameTester without GameTestBase having to know about the inner workings of each test. Or have each concrete GameTester query the world from GameTestBase.
Program.cs provides entry into the application so the code to run a test is as follows.
new GameTestBase(new GameObjectRenderTester()).Run();
A GameTester is supplied as a parameter to the GameTestBase constructor to plugin the implementation of the test. Once the GameTestBase object has been constructed we tell it to run the test. And that's it! Woot! Now let's take a look at the GameTester (GameObjectRenderTester).
public class GameObjectRenderTester : GameTester
{
private GameObject ball;
public
GameTestBase.LoadContentDelegate LoadContentDelegate
{
get
{
return new GameTestBase.LoadContentDelegate(
delegate(GameTestBase game)
{
ball = new GameObject(
game.Content.Load("ball"));
});
}
}
public GameTestBase.UpdateDelegate UpdateDelegate
{
get { return null; }
}
public GameTestBase.DrawDelegate DrawDelegate
{
get
{
return new GameTestBase.DrawDelegate(
delegate(GameTestBase game)
{
game.SpriteBatch.Begin();
ball.Render(game.SpriteBatch);
game.SpriteBatch.End();
});
}
}
}
A concrete GameTester object is made up of three public properties: LoadContentDelegate, UpdateDelegate, and DrawDelegate. Each delegate is responsible for implementing a particular section of the application flow. The LoadContentDelegate is responsible for loading any content before the application enters the application loop. The UpdateDelegate is responsible for performing any object animations or prerender operations. Finally, the DrawDelegate delegate is responsible for rendering.
The cool thing about this approach is how the tester can have its own state and it be used within each delegate without any interference from the GameTestBase class. This greatly simplified my tests from prior. I was in static hell!
Now let's have a look at the GameTestBase class to see how it uses the GameTester to run a test.
public GameTestBase(GameTester tester)
{
this.drawDelegate = tester.DrawDelegate;
this.loadContentDelegate =
tester.LoadContentDelegate;
this.updateDelegate = tester.UpdateDelegate;
...
}
protected override void LoadContent()
{
...
if (loadContentDelegate != null)
loadContentDelegate(this);
}
protected override void Update(GameTime gameTime)
{
...
if (updateDelegate != null)
updateDelegate(this, gameTime);
}
protected override void Draw(GameTime gameTime)
{
...
if (drawDelegate != null)
drawDelegate(this);
...
}
First, GameTestBase inherits from the Microsoft.Xna.Framework.Game class. It then overrides the LoadContent(), Update(), and Draw() methods. These are the three methods that the GameTester will implement. As demonstrated in the GameTestBase constructor, the GameTester delegates are stored off and used from within the GameTestBase overrides.
And that's all she wrote folks. It is that easy. It even gives me a nice way to organize my tests. This type of testing is a step up from unit testing because now I can test logic such as collision detection to verify it is calculating and rendering properly. This does not replace my unit testing though, but provides a way to perform tests that don't lend themselves well to unit testing.
So, can I get a hell yeah???
Sunday, March 02, 2008
Krav Maga Videos
Here is a listing of some cool Krav videos. Enjoy!
Krav video 1
Krav video 2
Krav video 3
Krav video 4
Krav video 5
OOH OOH EEH EEH
Krav video 1
Krav video 2
Krav video 3
Krav video 4
Krav video 5
OOH OOH EEH EEH
Saturday, February 16, 2008
SQuba Car??
Bond...James Bond.
It's awesome yet crazy. The new submarine car is out. A car that drives on land and underwater.
Just make sure you are wearing your freshly tailored scuba suit before you decide to take a nice midday dive. :)
WHERE'S MY TELEPORTER???
It's awesome yet crazy. The new submarine car is out. A car that drives on land and underwater.
Just make sure you are wearing your freshly tailored scuba suit before you decide to take a nice midday dive. :)
WHERE'S MY TELEPORTER???
Texture Cache
I created a texture caching system that separates the region definitions from the requesting a region. Below is a code snippet of it in action.
The TextureCache object takes in XML and a TextureBuilder to load the textures appropriate to the application. The XML defines the regions within a texture. The TextureBuilder is an application specific object that performs the conversion of the XML data into the right Texture format. For example, in my Pong remake I am using XNA so my TextureBuilder converts the XML data into a Texture2D object wrapper.
The XML file is pretty straight forward, see snippet below. Each texture node has a collection of region nodes that define a portion of the texture that can be used in rendering. Each region is given a name that is used as a key in the texture cache.
The power behind this interface is it's retrieval mechanism. Basically you ask for what you want.
You just ask the texture cache for a texture, then ask the texture for the region you would like to render. It's that simple. Another powerful piece is the system relies on Generics so each application can have the texture cache provide application specific textures.
In the future I am looking to build a UI to create the XML definition file to simplify that process. Will keep you posted on the results of that endeavor.
Stay easy.
XmlDocument xml = new XmlDocument();
xml .Load("textures.xml");
TextureCache tc = new TextureCache<Texture>(xml, new CustomTextureBuilder());
The TextureCache object takes in XML and a TextureBuilder to load the textures appropriate to the application. The XML defines the regions within a texture. The TextureBuilder is an application specific object that performs the conversion of the XML data into the right Texture format. For example, in my Pong remake I am using XNA so my TextureBuilder converts the XML data into a Texture2D object wrapper.
The XML file is pretty straight forward, see snippet below. Each texture node has a collection of region nodes that define a portion of the texture that can be used in rendering. Each region is given a name that is used as a key in the texture cache.
<textures>
<texture name="textureName">
<region name="regionName" x="0" y="0" width="64" height="64" />
</texture>
<texture ...>...</texture>
</textures>
The power behind this interface is it's retrieval mechanism. Basically you ask for what you want.
Texture t = textureCache["textureName"];
TextureRegion tr = t.GetTextureRegion("regionName");
You just ask the texture cache for a texture, then ask the texture for the region you would like to render. It's that simple. Another powerful piece is the system relies on Generics so each application can have the texture cache provide application specific textures.
In the future I am looking to build a UI to create the XML definition file to simplify that process. Will keep you posted on the results of that endeavor.
Stay easy.
Sunday, January 20, 2008
Announcing my XNA game dev library
So, I am at it again. To learn how to use XNA I've decided to create a little game dev library using XNA as the foundation. For more information on XNA visit this link.
My first project will be a variation of Pong. Here is a link to a screenshot of the main menu. Pong is simple and something I know how to make. My plan is to use it as proof of concept for the ideas I will be implementing in my library.
Currently, I have a basic rendering and input system. At the moment the rendering system wraps XNA, but my input system provides the ability to map input responses to any kind of input type (i.e. keyboard, mouse, gamepads, etc). The menu system currently utilizes this feature.
I will post code examples once I have more done. I am will be providing significant test coverage to ensure a clean and solid set of interfaces. Stay tuned.
My first project will be a variation of Pong. Here is a link to a screenshot of the main menu. Pong is simple and something I know how to make. My plan is to use it as proof of concept for the ideas I will be implementing in my library.
Currently, I have a basic rendering and input system. At the moment the rendering system wraps XNA, but my input system provides the ability to map input responses to any kind of input type (i.e. keyboard, mouse, gamepads, etc). The menu system currently utilizes this feature.
I will post code examples once I have more done. I am will be providing significant test coverage to ensure a clean and solid set of interfaces. Stay tuned.
Thursday, January 10, 2008
Fathering 2...piece of cake?
I had assumed it would be easier to be a father to my second child. Interestingly I have been awakened by reality. Deep down I know it will be fine, but that doesn't stop me from wondering if I will be good enough to father two children.
I guess only time will tell.
Seeing my unborn child move and interact with us in the ultrasound was so fascinating. She has so much energy. I'm filled with so much joy when I feel her react to me poking the walls of her current home. That justifies these ridiculous feelings. All I want is to be the best Dad I can for her, and that she is assured by that.
Awaiting the life lessons she has in store for me.
April 24, 2008 my walk with Simone begins...
I guess only time will tell.
Seeing my unborn child move and interact with us in the ultrasound was so fascinating. She has so much energy. I'm filled with so much joy when I feel her react to me poking the walls of her current home. That justifies these ridiculous feelings. All I want is to be the best Dad I can for her, and that she is assured by that.
Awaiting the life lessons she has in store for me.
April 24, 2008 my walk with Simone begins...
Good Programming Books
Just wanted to link a couple of books I think are must haves when coding.
Interface-Oriented Design
Refactoring
OOH OOH EEH EEH
Interface-Oriented Design
Refactoring
OOH OOH EEH EEH
Wednesday, February 14, 2007
Performancing
This a test post. I am creating this post from within Firefox. I am really loving this browser. It supports everything and is so extensible. I just found this extension ("Performancing") that allows you to post blogs from the brower. Sweet!
powered by performancing firefox
Sunday, March 26, 2006
Never fear, boost is here!
I don't think I provided the link before to the Boost library, but here it is: http://www.boost.org.
I successfully used the unit test framework to test the initial version of the config file system for Block Drop. It was a cinch to setup and get running. With the test framework working, I should have more confidence to get new features out. Although, I am curious about how I am going use the unit test framework to test some of the graphics related systems. I am also wondering if there is a decent mocking toolset for C++. This would definately be a big plus so I can test the communication between the system interfaces. Looks like it is time to do more research.
Anyways, the config system was a breeze to get going. It is built ontop of the boost::program_options library. Boost does all the hard work. It provides all of the parsing/storing functionality in just two step:
1.) Define the option-value type pairs
2.) Parse the values from the config file
Here is a simple example of using the boost::program_options library.
And that is all there is to it for loading the contents of a config file. Then whenever you need a specific value you just reference it through the map like this: map["myOption"].as(). The overloaded () operator makes it a breeze for organizing and adding options to the the list to be parsed.
The Monkeyboy Framework wraps this interface into its Configuration class which is meant to overriden by any system that uses the framework so that each new application can define its own configuration file and option-value pairs.
So Block Drop has a class called BlockDropConfiguration that inherits from the Monkeyboy Framework Configuration class. Here is how it defines its configuration file and option-value pairs:
Now the main Block Drop class owns an instance of the BlockDropConfiguration class and uses it to initialize its subsystems. Here is a sneek peek at it initializing the graphics subsystem.
I decided on this approach since the configuration class is specific to the application so it should know what the graphics system needs to be initialized. I figured at the time of creation this appeared the be the easiest approach. I am open to input on this as well if anyone has any thoughts on a different approach.
OOH OOH EEH EEH
I successfully used the unit test framework to test the initial version of the config file system for Block Drop. It was a cinch to setup and get running. With the test framework working, I should have more confidence to get new features out. Although, I am curious about how I am going use the unit test framework to test some of the graphics related systems. I am also wondering if there is a decent mocking toolset for C++. This would definately be a big plus so I can test the communication between the system interfaces. Looks like it is time to do more research.
Anyways, the config system was a breeze to get going. It is built ontop of the boost::program_options library. Boost does all the hard work. It provides all of the parsing/storing functionality in just two step:
1.) Define the option-value type pairs
2.) Parse the values from the config file
Here is a simple example of using the boost::program_options library.
...
#include
namespace po = boost::program_options;
po::options_description description("Config File Options");
description.add_options()
("myOption", po::value<int>()->default_value(5), "My type of option")
("mySecondOption", po::value<std::vector<std::string>>(), "My second type of option")
;
po::variables_map map;
po::store(po::parse_config_file("configFile.cfg", description), map);
po::notify(map);
And that is all there is to it for loading the contents of a config file. Then whenever you need a specific value you just reference it through the map like this: map["myOption"].as
The Monkeyboy Framework wraps this interface into its Configuration class which is meant to overriden by any system that uses the framework so that each new application can define its own configuration file and option-value pairs.
So Block Drop has a class called BlockDropConfiguration that inherits from the Monkeyboy Framework Configuration class. Here is how it defines its configuration file and option-value pairs:
BlockDropConfiguration::BlockDropConfiguration()
: Configuration(std::string("blockDrop.cfg"))
{
this->optionsDescription.add_options()
("title", po::value<std::string>(), "Title of the application")
("width", po::value<int>()->default_value(800), "Width of the application window")
("height", po::value<int>()->default_value(600), "Height of the application window")
;
}
Now the main Block Drop class owns an instance of the BlockDropConfiguration class and uses it to initialize its subsystems. Here is a sneek peek at it initializing the graphics subsystem.
...
class BlockDrop : GameDemoApplication
{
BlockDrop::BlockDrop() {
configuration.parse();
configuration.loadGraphicsProperties(graphicsSystem);
... //Add more subsystem initialization calls
}
...
private:
BlockDropConfiguration configuration;
Graphics graphicsSystem;
};
I decided on this approach since the configuration class is specific to the application so it should know what the graphics system needs to be initialized. I figured at the time of creation this appeared the be the easiest approach. I am open to input on this as well if anyone has any thoughts on a different approach.
OOH OOH EEH EEH
Saturday, March 25, 2006
Boost Library Unit Test Framework
Alright, I know I have been away for a long while, but I'm back. And once again, so is Block Drop. This has been a project of mine that has been in development for a long time. It has experienced numerous architecture and platform changes. Mostly because of my interests changing so frequently. But that's okay, because it gives me a reason to learn something new.
Since we employ XP practices at work, I wanted to encorporate some of those practices to my Block Drop project. The first I intend to use is Test Driven Development (TDD). My first task was to find a good unit testing framework for C++. I narrowed the search down to CPPUnit and the boost::unit_test_framework. Both appeared to lack the ease of use as some of the Java test frameworks, but they seemed the easiest to get going and work with from my perspective.
I am thinking I will choose the boost library version because I intend to use the other features the boost library offers (i.e. smart_pointers, program_options, and possibly others). This will also bring the number of included libraries down.
OOH OOH EEH EEH
Since we employ XP practices at work, I wanted to encorporate some of those practices to my Block Drop project. The first I intend to use is Test Driven Development (TDD). My first task was to find a good unit testing framework for C++. I narrowed the search down to CPPUnit and the boost::unit_test_framework. Both appeared to lack the ease of use as some of the Java test frameworks, but they seemed the easiest to get going and work with from my perspective.
I am thinking I will choose the boost library version because I intend to use the other features the boost library offers (i.e. smart_pointers, program_options, and possibly others). This will also bring the number of included libraries down.
OOH OOH EEH EEH
Friday, June 10, 2005
Updates
Lights! Camera! Action!
Okay, the camera system is almost complete. I am working out some of the jerkyness in the movement of the camera. There are two types of cameras: Basic and Player. The basic camera provides the basic orientation operations on a camera, such as, pitch, yaw, roll, and move. The Player camera is broken up into three different cameras: First Person, Third Person, and Spacecraft. All Player cameras are attached to a player object. I will elaborate on each camera once the system is complete...so stay tuned!!
Do you see what I see???
I simplified the interface of the graphics system so it is much easier to get DirectX up and running. The graphics system manages the DirectX interface and device as well as the MBLib graphics renderer. Each of these components are accessible through this system.
That is all for now. Once the camera system is complete, I plan to update the terrain demo adding a dynamic camera that switches between the different camera modes. So, I'll see you then.
OOH OOH EEH EEH
Okay, the camera system is almost complete. I am working out some of the jerkyness in the movement of the camera. There are two types of cameras: Basic and Player. The basic camera provides the basic orientation operations on a camera, such as, pitch, yaw, roll, and move. The Player camera is broken up into three different cameras: First Person, Third Person, and Spacecraft. All Player cameras are attached to a player object. I will elaborate on each camera once the system is complete...so stay tuned!!
Do you see what I see???
I simplified the interface of the graphics system so it is much easier to get DirectX up and running. The graphics system manages the DirectX interface and device as well as the MBLib graphics renderer. Each of these components are accessible through this system.
That is all for now. Once the camera system is complete, I plan to update the terrain demo adding a dynamic camera that switches between the different camera modes. So, I'll see you then.
OOH OOH EEH EEH
Thursday, May 26, 2005
Errors
Let me know if you come across any errors when running the demos. That way I can make sure the system is as stable as possible. It should be, I test the systems before uploading them, but you can never do enough tests... Thanks in advance.
OOH OOH EEH EEH
OOH OOH EEH EEH
Dynamic Vertex Buffers
Here is a screenshot of a demo application I created to show the new dynamic features of the vertex/index buffer interface. It displays a patch field the uses a sine wave to calculate the new positions of each vertex on each interation of the application loop. The effect is a rippling effect from the center of the patch to the end. Also, the red diffuse color is adjusted to become more intense at the high wave peak and less intense at the wave down peak. All of these effects are scaled by time to create a smooth animation. You can enjoy the demo by clicking here
I have modified the vertex/index buffers to support both static and dynamic propertics. The demo above show the nature of using dynamic vertex buffers. This allows the client to modify the vertices in the vertex buffer at any time. There are two conditions to be aware of, an overwrite vertex buffer and a nooverwrite vertex buffer.
The overwrite vertex buffer will discard the vertices in the vertex buffer and write the new vertices starting at the beginning of the buffer. Since the Graphics Processing Unit (GPU) will be expecting this to occur, it will return a new pointer into the buffer for the client to add vertices to and then discard the previous vertices.
The nooverwrite vertex buffer will only return a pointer to the available space remaining in the vertex buffer to add the new vertices to. The catch is, if there isn't enough space to add the new vertices, then the vertex buffer will move into overwrite mode and will function like an overwrite vertex buffer. The vertex buffer will return an error when this occurs to let the client know it is no longer protecting the original vertices. This will give the client an opportunity to either continue rendering without crashing or to recreate the vertex buffer to add more space to it. The best approach when using a nooverwrite vertex buffer is to check for enough space before adding the vertices.
Also, to run the demo your video card must support the use of dynamic vertex buffering. The demo doesn't use extensive error handling. I will update the code to be a bit more user-friendly, but its main purpose is to demonstate the use of the Dynamic Vertex Buffer interface. Enjoy!
That's all for now...I am coming with more updates, so stay tuned!
OOH OOH EEH EEH
Monday, May 23, 2005
Terrain Demo is here!!
Okay, it is here as promised. The screenshot is of the initial version of my terrain class (MBGraphics_Terrain). It creates the terrain based on values in a height map. The height map is broken up into sectors to provide optimal performance pushing vertices down the graphics pipeline.
The lighting in the screenshot is simulated. That will change once I get the DirectXGraphics lighting system operational. Also, the camera is locked at that angle. That will also change. I am currently working on the camera system to provide a player control camera under different perspectives. My next post will provide more information into the design of that system.
Enjoy this screenie for now...it's time to feed the monkey's belly!!! OOH OOH EEEEH!!!
OOH OOH EEH EEH
Saturday, May 21, 2005
Vertex/Index Buffer Demo
Okay, it is time for an update on the MBLib. I am currently working on the mesh interface of the MBGraphics component. I have created a simple mesh interface (MBGraphics_Mesh). Its purpose is to manage the locations in the vertex and index buffers of where an objects data is stored. This works well with batch loading and rendering of mesh objects. The idea is to be able to sort mesh objects by the vertex buffers they reference. This way when the renderer loads a vertex buffer all mesh objects that reference that vertex buffer and are visible by the camera will be rendered at that time. This will increase rendering performance because vertex buffers are not being switched out frequently causing the rendering pipeline to stall.

Above is a screenshot of a demo that shows the use of the mesh and the vertex/index buffer interfaces. It displays two mesh objects, a cube and a prism, and rotates them on unique axes. The vertices and indices of each mesh object share the same vertex/index buffers. Each mesh stores its location into these buffers so the render knows how to draw them to the display.
There is still some work that needs to be done with the mesh interface. There will be a high level manager that manages all mesh objects needed by an application. The idea behind this is to have one mesh be used by multiple objects. This is often referred to as "instancing". This cuts back on the memory usage because each object references a single mesh in memory.
Also to be added are some utility operations for loading mesh model formats such as 3DS, OBJ, and Milkshape3D models. I am still debating on coming up with a universal format that converts those formats into a proprietary one, or just relying on those. I am not totally sure of the pros/cons of either decision, but I will keep you posted after I do more research.
Also, the terrain interface is still being designed. I will post a description of the interface and a demo once that is completed.
Well, that's all I have for today...back to the lab
OOH OOH EEH EEH
Above is a screenshot of a demo that shows the use of the mesh and the vertex/index buffer interfaces. It displays two mesh objects, a cube and a prism, and rotates them on unique axes. The vertices and indices of each mesh object share the same vertex/index buffers. Each mesh stores its location into these buffers so the render knows how to draw them to the display.
There is still some work that needs to be done with the mesh interface. There will be a high level manager that manages all mesh objects needed by an application. The idea behind this is to have one mesh be used by multiple objects. This is often referred to as "instancing". This cuts back on the memory usage because each object references a single mesh in memory.
Also to be added are some utility operations for loading mesh model formats such as 3DS, OBJ, and Milkshape3D models. I am still debating on coming up with a universal format that converts those formats into a proprietary one, or just relying on those. I am not totally sure of the pros/cons of either decision, but I will keep you posted after I do more research.
Also, the terrain interface is still being designed. I will post a description of the interface and a demo once that is completed.
Well, that's all I have for today...back to the lab
OOH OOH EEH EEH
Tuesday, May 17, 2005
I added the vertex/index buffer interface to the MBGraphics component of the MBLib library. It is divided into two sections: pools and buffers. I wanted this interface to be very simple at getting up and running while maintaining high standards in performance.
Pools
There are two pools: MBGraphics_VertexBufferPool and MBGraphics_IndexBufferPool. The purpose of the pools is to have a central location for managing the existence of and access to the buffers needed by an application. The client is able to interface with a particular buffer through the buffer's id. All buffer ids are supplied to the client when they are allocated in the pool. From there it becomes the responsibility of the client to organize and manage them.
Buffers
There are two buffers: MBGraphics_VertexBuffer and MBGraphics_IndexBuffer. The vertex buffer is used to store vertex information about a mesh object. The index buffer is used to reference vertices loaded in a vertex buffer describing how those vertices are supposed to be connected. A vertex buffer can be used without an index buffer, but it is highly advantageous to use an index buffer to cutback on the memory usage. Index buffers must reference a vertex buffer (at this point in time) in order to be used by the renderer.
Another important advantage is all buffers take advantage of the Direct3D Managed Pool system. This take the responsibility of having to recover lost vertex data during lost device situations. The disadvantage is because Direct3D maintains a system copy of the data, the memory use is doubled. I chose this route because I wanted the use of this system to be simple, and one less thing the client has to worry about is a big plus to me.
Conclusion
This system is still a work in progress, but I am very pleased at its current state. It is fast and very simple and flexible to use. Once the MBGraphics component of the MBLib has been completed, i will provide a series of brief tutorials on how to use it. I speculate this component being the largest out of all the other planned components. Stay tuned! There is plenty more to come...
OOH OOH EEH EEH
Pools
There are two pools: MBGraphics_VertexBufferPool and MBGraphics_IndexBufferPool. The purpose of the pools is to have a central location for managing the existence of and access to the buffers needed by an application. The client is able to interface with a particular buffer through the buffer's id. All buffer ids are supplied to the client when they are allocated in the pool. From there it becomes the responsibility of the client to organize and manage them.
Buffers
There are two buffers: MBGraphics_VertexBuffer and MBGraphics_IndexBuffer. The vertex buffer is used to store vertex information about a mesh object. The index buffer is used to reference vertices loaded in a vertex buffer describing how those vertices are supposed to be connected. A vertex buffer can be used without an index buffer, but it is highly advantageous to use an index buffer to cutback on the memory usage. Index buffers must reference a vertex buffer (at this point in time) in order to be used by the renderer.
Another important advantage is all buffers take advantage of the Direct3D Managed Pool system. This take the responsibility of having to recover lost vertex data during lost device situations. The disadvantage is because Direct3D maintains a system copy of the data, the memory use is doubled. I chose this route because I wanted the use of this system to be simple, and one less thing the client has to worry about is a big plus to me.
Conclusion
This system is still a work in progress, but I am very pleased at its current state. It is fast and very simple and flexible to use. Once the MBGraphics component of the MBLib has been completed, i will provide a series of brief tutorials on how to use it. I speculate this component being the largest out of all the other planned components. Stay tuned! There is plenty more to come...
OOH OOH EEH EEH
Subscribe to:
Posts (Atom)