Grave of Creativity. A tip on how a 3D game coder can get by on a shoe string budget.

I am working on my latest game called “Dragons High“.

The game is a 3D Dragon flight combat simulation. It’s meant for the mobile platforms and will also have a desktop build.

I am a programmer and I can do a little bit of art but my art is not really that good.

I have recently learned that in order for me to make games quicker and look better I should buy stock art and models.

The reasons are that finding a dedicated good 3D artist can be hard and expensive and doing the art yourself is cheap but takes a lot of time and is often of poor quality.

However, you can’t always find what you want on the few royalty free art assets websites.

I was working on the GUI of Dragons High and I was in need of a next button.

I modeled a button in Lightwave and rendered it into a 2D sprite.

This was the result:

My Next Button

This is how it looked inside the game:

GUI Screenshot

At first I thought “Who cares, it’s good enough” but then I realized how bad it looks and how a simple button like this can make your game look unprofessional.

I then began looking for some assets to buy but I couldn’t find anything that was an arrow button or a sign that looked suitable for the game.

Then I found this:

Grave DemonstrationIt’s not really a sign or an arrow and it has writings on it. But what if I would rotate it by 90 degrees and render it from the back?

After a few rendering tweaks and making it look more suitable for the game(less cartoony) I got this:

Next WoodThis looks like an arrow and is way better looking than what I did myself.

So this is how you can get along on a budget and not give up on quality.

Just try to make the most of limited resources by editing existing assets into things with a different purpose than what was originally intended.

For the sake of completion here is the GUI with the new next button:

New GUI Screenshot

OpenGL Texture Size and performance? Texture Cache? (Android\iOS GLES 2)

I am working on my dragon simulation mobile game and I am at the stage of adding a terrain to the game.

I optimized the terrain render for my iOS devices but on my Android device I was getting bad performance.

Understanding texture size and performance is kind of elusive. I was being told many times that big textures are bad but I was never able to find the correlation between texture size and performance.

I am still not sure what is the correlation between texture size, bandwidth and performance on mobile devices and I am sure it’s a complex one.

However, I did find out something else.

As I mentioned, my first attempt to copy the OpenGLES shaders from my iOS code to my Android code gave me poor results. The same scene that ran at 60 FPS on my iPod was running on 25 FPS on my Android phone.

This is how the scene looked like on my Android phone:

Slow Terrain Render

Scene rendered at 25 FPS(40 ms per frame)

For the terrain I am using two 2048×2048 ETC1 compressed textures. One for the grass and one for the rocky mountain.

Maybe my phone’s performance is really not as good as my iPod? But then, something was missing.

On my iPod I was already using mipmapped textures while on the first attempt of the Android version I didn’t use mipmapped textures.

Mipmapped textures are texture which not only contain the texture itself but also all (or some) of the smaller versions of the same texture image.

If you have a texture of size 16×16 pixels then a mipmapped texture will contain both the 16×16 image but also the 8×8, 4×4, 2×2 and 1×1 resolutions of the same image.

This is useful because it’s hard to scale down a texture on the GPU without losing details. The mipmapped images are precalculated offline and may use the best algorithms to reduce the image.

When rendering with mipmapped textures the GPU selects the mipmapped image that is the most suitable for the current scaling in the scene.

But apart from looking better, there is another advantage. Performance.

The same scene using mipmapped version of the 2048×2048 textures runs a lot faster than before. I could get a scene render at about 50 to 60 FPS.

The reason for that is that textures have a 2D spatial cache.

In this scene the mountain and grass textures are scaled down considerabley. This in turn makes the GPU sample the textures in texel(texture pixels) that are far from each other making no use of the cache.

In order to make use of the cache the sampling of the texture must have spatial proximity.

When using the mipmapped version of the texture a much smaller layer of the 2048×2048 texture was sampled and thus it was possible to make use of the cache for this specific image.

For the sake of completion, here is the scene with the mipmapped textures:

Runs at about 50-60 FPS(17-20 ms)

Runs at about 50-60 FPS(17-20 ms)

Location 0? location -1? glGetUniformLocation, C++ and bugs. (Android\iOS GLES 2)

In OpenGLES 2 glGetUniformLocation receives the program id and a string as parameters. It then attempts to return a location int that can be used to set uniform GLSL shader variables.

If the variable is found it will return a 0 or positive value. If it fails to find the uniform variable it will return -1.

In C++ we should initialize the location ints in the ctr. If we don’t initialize the locations we might have garbage values when in Release mode.

Using the locations with garbage values might overwrite uniform variables with values we did not intend them to have.

So what we should initialize the locations with? One might think that 0 is a good value to initialize but it is not.

Remember! 0 is a valid shader uniform variable location. If we set all the locations to 0 we might overwrite the uniform variable at location 0.

We should initialize the location ints with -1.

We should do this because -1  is the value that is returned in case the uniform variable was not found and setting a value at location -1 will be ignored.