Most recent commit: 2012/01/27 - Keyboard devices are created and data is read each frame. Devices activate/deactivate with... [view]

Prospect NPC interactions

A second character has appeared in my Prospect game, an NPC (non-player character) that stands around waiting for the player to talk to him. I wanted to have the NPC “talk” to you by having the game slowly draw his message in, one character at a time. (It may be hard to read the text unless you go into full screen mode.)

To get this to work, a chain of events is started once I walk the player within a certain distance of the NPC. First, the player is forced to walk towards a point in front of the character. I wanted the conversation viewed from the side, so next the camera slerps over the course of a few frames to the desired rotation and position. Player input is ignored during this transition. Once the speech is finished, only mouse input is checked so a left click can end the conversation. After that the player has full control once again.

If this was a real game, there would be a few additions. Typically you’d be able to go back and hear the message again, but you’d have to go near the character and hit a button instead of being forced into it. There would also probably be a button to display all the text at once if you don’t feel like sitting through his speech.

The capsule character may be going into retirement. If I make a better looking character, though, it’s going to look really silly if the legs don’t move as he walks. So I’ll need to get into adding bones to characters and animating them. This is a big topic so I’m not sure I want to jump into it yet.

Leave a comment
Camera collision

I added a building to the Prospect test game so I could test camera behavior when confined. Each frame, the camera shoots out a virtual ray from the point it’s looking at (just above the player’s head) back to the camera position. If anything is hit, then something is obstructing the view. To keep the player visible, the camera shortens up the distance it is following behind the player to put itself in front of the collision point.

As the video shows, it works nicely even in extreme cases like when the player is jammed all the way into the corner. Also, terrain is treated no differently than the building. If I rotate the camera so far that it would be on the wrong side of the terrain, I get the effect of it zooming in on the player.

Right now this camera behavior would occur no matter what is blocking the camera. If a box were lying on the ground and I rotated the camera low to put the camera behind it, the camera would jump to be in front of it. A better solution for small things getting in the way might be to make the obstructing objects slightly transparent. If you’ve been reading this blog long enough to remember my Barnyard game, that’s the method I used to maintain visibility even if the camera was in a big group of trees.

Leave a comment
Prospect begins

I’ve started working on a small test game that I’m calling “Prospect”. It exists solely to let me try out new ideas that the Jest game is going to need. The first thing I did was put together a new third person character and camera controller. My goal is to work on a variety of things like camera behavior when confined, non-player characters, fighting, climbing ladders, etc.

If you’ve been reading this blog long enough, you might remember my Barnyard game where the player ran around picking up barnyard animals and throwing them into the proper bin for their animal type. The game eventually became a testing ground for new Nightshade features. That’s essentially the purpose Prospect is serving this time.

Leave a comment
Font rendering

I posted yesterday that using FreeType2 for font rendering greatly improves the font system over my previous attempts, but I didn’t mention why. In the past, I rendered fonts in games by typing all the characters (usually just ASCII characters) of a font into a texture. There would be an associated data file that specified the location and size of each character in the texture. When it came time to render a string, I’d apply the appropriate portion of the texture to a rectangle. Leaving a one pixel gap between letters, I’d continue this process until the entire string of text had been rendered.

This worked OK, but had a few limitations or annoyances. The biggest one was simply creating the texture and measuring out the positions and sizes of characters. It took me (or at least felt like it took me) hours to make one font in one point size. I eventually got sick of it and wrote a tool to take a font and make the texture and data file for me. Another problem I actually just mentioned: this work resulted in only one size of text. Scaling down might have worked for smaller sizes, but magnifying them would have looked horrible.

Using FreeType2 frees me from these problems. Instead of making a big texture of characters, GooeyJam includes a TrueType font, no different than the fonts sitting in the fonts folder on your computer. When it comes time to render a character, FreeType2 doesn’t interact with your graphics system, it simply “renders” the character into a memory buffer. Below is a picture of Visual Studio’s debugger showing me the memory an ‘A’ has been rendered to:

The byte values are actually opacities. On the horizontal bar of the A, you can see a bunch of ‘FF’ bytes, which correspond to a decimal 255, the highest value to fit in one byte. These pixels will be completely opaque. If you look at some of the values on the slanted parts of the A, you’ll see many small values like 03 or 11. These parts are going to be very faint. The A will contribute a bit of color, but the background will be mainly what shows through at that point. When it comes time to render, I can render the character to a texture in any color I want. I just supply these opacity values as the alpha components of the color I’m rendering the characters in. This data was used to render the A in the string below:

I can also create font “faces” in just about any size that I want. The character in the debugger picture is in a small font size just so I could take a reasonably sized screenshot of the debugger. Any character in the font is fair game for rendering, too; no more limiting to ASCII. The font I’m using in testing has almost 1200 glyphs.

The biggest win for this system is yet to come. I’m not using it yet, but I’ll be able to do kerning on the characters. Instead of the old method of “place a character, put a one pixel gap, place another character”, FreeType2 will help out with placing more or less space between characters to make things look nice.

Leave a comment
GooeyJam

A name has been decided for the GUI system: GooeyJam. The code is up on BitBucket.org.

Most of the work lately has been on font rendering using the FreeType2 library. I’ve worked on GUI systems in the past, but using FreeType2 this time greatly improves the font system. Nightshade demos will soon have text in the GUI so there’s some indication of what the controls are.

Leave a comment
Started a GUI system

I mentioned a while back that the lack of a GUI system usually isn’t a problem, but there’s been a few cases where I wish I had one up and running. The most recent time was when I was working on the render to texture demo. It would have been nice to be able to map the rendered texture onto a GUI widget. I had to fake it by applying the texture to a “real” game entity that was just a plane that happened to be facing the viewer. (It helped that the camera doesn’t move in that demo.)

So a few days ago I started on a GUI system. I’ve decided to make it a separate project from Nightshade. Non-game apps might get some mileage out of it, too, without the need to have an entire 3D engine come along with it. One thing I haven’t figured out yet is a name for it. For now it is called GooeyGUI.

It’s pretty far along considering that it has only been a few days. I’ve modified the render to texture demo to use it, and next up is making overlays for the demos so there’s some indication of what the controls are.

Leave a comment
Transparency

Continuing my minor graphics improvements, I’ve done some work with transparency. This required a few changes to how my render system works. To demonstrate it, I modeled a simple window frame containing colored “glass” and placed it in my physics demo. One side of the window is green and one side is red.

When you can see one window through the other, the green (or red) color appears brighter as both of the windows are being blended with whatever is behind them. The reason transparent objects required some changes is because I can’t just render them in an arbitrary order like everything else. In most cases, DirectX or OpenGL handles overlapping objects through the “depth buffer”. This data is for keeping track of the distance from the camera for each rendered pixel. If something being drawn at a pixel is further away than something already drawn there, then the pixel need not be drawn again.

This process won’t work for transparent objects, though. Since they blend with the objects behind them, when it comes time to draw my window panes, what’s behind them must already have been rendered. This means transparent items need to be drawn last. Additionally, there are times when a transparent object might be blending with another transparent object, as you can see in the video when one window is visible from another window. The solution is to also sort transparent items by distance from the camera so the ones further away render first.

Transparency will also be used by the GUI system. Rounded buttons, for example, won’t actually be round meshes. They’ll just be a rectangular mesh with a texture applied that happens to be transparent where nothing should be rendered.

Leave a comment
Reflections

With so many major pieces of the puzzle left to work on, I’ve been hesitant to work on anything that’s just a graphical enhancement. Reflections are an exception that I justified with the fact that they’ll be needed to do water rendering at some point (and I figured I could get them done before I leave for vacation). I put together a reflection demo with a few shapes reflected in a ground plane.

How it works is interesting. The reflection of an object is generated by taking the camera’s eye position and view direction of the scene and reflecting over the reflection plane (the ground). In the image below, you can see that in the reflected view the bottom and right of the cube would be visible, which is how you’d expect the final reflection to look. This reflected view is rendered to a texture.

Reflected view

The texture is then applied to the ground and blended with the ground’s tile texture. Unlike regular texture mapping where each vertex specifies where on its texture the color should come from, this projected texturing works differently. In addition to transforming the ground vertices for the normal view, the vertex shader must also transform the same vertices for the reflected view. This is because the pixel shader comes along afterwards and must determine where on the reflected texture each ground pixel is. After sampling both textures the colors are blended together. In the video, I’ve set the reflected texture weight to 0.25 with the other 0.75 coming from the blue tile texture.

There’s no reason the reflection plane must be the ground or have the reflection plane be the y=0 plane. For testing, I had the “ground” rotated to many different orientations and the reflections looked as you’d expect.

There’s one small problem with the system. If you rotate the view so that the cube is not visible, it won’t be rendered. That’s normally how it should work, but with reflections, it will still need to be drawn if its reflection is visible. I have to think about the best way to handle that.

Leave a comment
Render to texture

I’ll be away for a few days at the end of the month, so I’ve decided to put off starting the game until sometime after I get back. Before I leave, I think I can get reflection rendering working. To use reflections, I need the ability to render the scene to a texture instead of the back buffer. Reflections will appear by taking the rendered texture and applying it to another object.

This video demonstrates just the rendering to a texture part. I made a small demo with a bunch of shapes moving around in a circle and rotating. The purple texture to the right is the scene as it is rendered into the texture. It is cleared to purple first just so it stands out from the black background.

The render to texture functionality was pretty easy to get working. What was a bit of a pain is the fact that I have no GUI system in place yet. The object the purple texture is on is actually a “real” entity in the scene. It’s hidden when the scene is rendered to the texture and then made visible when the scene is rendered to the screen. I may start on a GUI system at the beginning of the month since there have been a number of times lately where I could have used one. I plan on making it a separate free software project.

Leave a comment
Camera slerps

This is another post about improvements made to similar functionality in Barnyard. As the user rotated the Barnyard player, the camera would spin to always be behind the player. This worked well enough, but it was very stiff. It felt like the camera was actually attached to the player. I’ve made a big improvement: the camera no longer immediately “snaps” to the same rotation as the player. Each frame, the camera checks the rotation it is at and the rotation the player is at, and interpolates between the two.

The method I’m using is known as Spherical Linear Interpolation, or “slerp”. There’s a starting and ending rotation, and a floating point value (t) in the range [0 .. 1]. Output from the slerp function is a rotation as if we rotated the starting rotation “t” amount of the way towards the ending rotation.

In the video, each frame the camera will rotate 5% of the way from where it is at and where it should be at. The 5% is arbitrary; I set it low to make it more apparent in a video. One nice effect is that as the camera gets nearer to its goal position, it slows down more and more. This is because 5% gets to be a smaller and smaller rotation change as the current and goal rotations become closer together.

In theory, moving 5% of the way towards something each frame means we’ll never actually get there. But once the rotations become extremely close after a number of frames, they’re going to actually be the same rotation since we don’t have infinite precision.

This works great for something I spent just a few hours on. Having so much in place already is starting to make it easier to add functionality like this. I’d like to say what is coming next, but I’m not sure. It is time to make a list of what Jest still needs in order to get a first level up and running.

Leave a comment