GLESGAE

From Pandora Wiki
Revision as of 12:40, 2 February 2012 by Stuckie (talk | contribs) (Added Evaluation Chapters)
Jump to: navigation, search

GLESGAE - GL ES Game Application Engine

GLESGAE is a vehicle for a series of tutorials on building a game engine for the Pandora console from scratch.
These will be written when I have time.. the uncreated ones below being an indicator of what's to come.
Unwritten parts may be split up, moved, or otherwise manipulated before actually going live, so don't take the following as set in stone till the link turns blue!

Table of Contents

Part One - Setup Stuff!

Part Two - Show me Stuff!

Part Three - Manage my Stuff!

Part Four - The First Evaluation

Part Five - Make it do Stuff!

Part Six - Push Stuff around!

Part Seven - Make Stuff squeak!

Part Eight - The Second Evaluation

Part Nine - Poke Stuff from afar!

Part Ten - Advanced Stuff!

Part Eleven - Tool Stuff!

GLESGAE Overview

To try not spam the wiki to death, I'll include the first two parts here, but subsequent parts will be in their own pages as they're more to deal with actual development problems rather than general overview stuff.
Where possible, I'll also combine things if they're related to the last part that I did - IE: generating a window, and then adding ES contexts.

Originally, I was going to attempt to take part in the Platformer Homebrew Competition over on the OpenPandora boards. However, with free time being very limited, no engine to speak of, the need to do assets and that it's already been going a month so I'm a bit behind, I've decided to tackle a somewhat different challenge - build and document an engine, originally for Pandora and spawning out elsewhere later.

Yes, another engine.

I've been dragging my old SGZEngine around for quite a while now.. though it's never really got much further than it has, and it's full of weird quirks and bugs that with each project, I spend more time working around than writing actual logic.
I did start another engine - SGEngine ( dropped the Z ) - however this was highly experimental in fobbing off every subsystem to a dynamically runtime loadable DLL to facilitate mix and matching bits and pieces. Especially useful for testing OpenGL and D3D renderers and a neat hack, but not much use as it was becoming highly complicated to do anything.
This brings us to GLESGAE. The name being chosen due to me being Scottish, and it being an amusing mnemoic to begin with.

Recently, I've been doing a lot of Android programming.
This involved writing a custom renderer for GLES1 and then onto GLES2.
With my previous experience of writing such low level GL code being glBegin(); ... glEnd(); I effectively got thrown in at the deep end and had to fight a bit to stay afloat. However, I pulled through, and while furthering the work engine is always going to be appreciated by them; there's already a defined system of how things work, and I wanted to change a bit too much of that.. so a new personal engine it is; using the new found knowledge I've just gained.

So, with the introduction out of the way, this ( weekly, with any luck ) set of tutorials, guides and random gibberings on building an engine while I continue GLESGAE shall begin.

Engine Design Overview

Game Engines are somewhat of a necessary evil these days if you have any inclination of producing more than one game on a system, or one game on many systems. However, there is also a very real danger of writing a solution for a non-existing problem - an engine without a game. As such, I will be writing a game alongside this as well, to make sure that the engine does in fact have useful features.

The danger of writing an engine without a game in mind, is that you keep adding bits and pieces and end up not really getting anywhere. Which is exactly what happened with SGEngine. Lots of neat hacks, but it never really got anywhere, and it's a right pig to try and get working for anything serious now. It was still a useful educational experience, as I learned how to deal with dynamic runtime libraries across Windows and *nix systems, as well as a more saner route for platform independent modules - SGZEngine essentially had a platform folder where all the code went, and interfaces and objects everywhere else. It wasn't particularly clean, even though it sounds like it should've been.

So what is an Engine?
In the purest sense, it's a collection of generic functions that when wired up can help you create code much quicker. Generally, a Game Engine can pull in other Engines such as Rendering Engines, Audio Engines and Physics Engines - all tailor made for their own specific domains.
As programmers we do tend to have the habit of being a bit ego-centric with an "I can rewrite the wheel better!" attitude. This can get us in to trouble at times! While I specifically want to deal with GL ES rendering on my own, I'll be pulling in OpenAL for audio and bullet or perhaps box2d for Physics; while trying to leave things open to be able to switch these out for something else at a later date.

This is therefore going to be a set of tutorials on building a Game Engine with a custom Graphics Engine in particular.
However, a Game Engine isn't just Audio, Graphics and Physics - though these are by far the most interesting parts of a Game Engine. You'll also generally need a set of utility functions that range from file I/O, input handling, event handling, memory management, resource management, and much more.
You may also want to abstract logic out to a scripting engine; something I've a lot of experience with and quite fond of, so shall be pulling in Lua as well for this purpose.

While on PC development ( and by extension, Pandora ) you can generally get away with just new/malloc random things at any point and free/delete when necessary all over the place, certain consoles don't particularly like that and you're generally better off managing your own heap and memory pages so you know exactly where your memory is at any time, and can cache things yourself, rather than relying on anything that may or may not do what you expect.

File Management can also catch you unaware on other platforms. Android, for example, has a rather strict permission system whereby you only really have access to your own package, and the contents of the sdcard. Granted, Android 2.3 gives you more control, but if you're writing NDK apps for <2.3 you'll have to jump back and forth between Java and C where file management becomes a whole new game of fun.

And what about input? The Pandora has those nubs! those lovely lovely nubs, dpad, face buttons, shoulder buttons, touchscreen and a full keyboard! You've also got the possibility of godknows what connected via USB - game pads, mice, full-sized keyboards...

I won't even start about threading and the chaos that can bring... then there's networking, which is even worse!

Finally, there's the thought of how you organize data and feed it to your engine.
These days, most engines follow a very data-driven design - and for good reason! You don't want to have to recompile half your codebase just for changing some NPC text, repositioning a graphic, loading a new model, etc.. GLESGAE is going to be data driven - and that also means tools that will be able to create the data to feed it, in the format that works best for the target platform.
We shall be building these tools along the way too, and where possible, also having them run on the Pandora itself.

I'll cover more bits as we get to them.. for now, we'll get the Environment Setup.

Environment Setup

I'm Lazy, Give Me A Pre-Configured Thing!

Here you go: http://www.stuckiegamez.co.uk/apps/pandora/SimpleDev/zaxxon-premade-dev.tar.bz2 ~250mb

Extract to an ext2/3 formatted SD card, and boot. Simple!

NOTE: This is a bit old, now.. and may have somewhat dodgy WiFi, but I'll get round to fixing this soon ( hopefully by 13th May. )

Tell Me What You Did

This weekend is essentially the overview and setup phase, so it's a bit boring I'm afraid.
To keep everyone on the same page, I'm going to assume you're using Angstrom from an SD card, that you've installed GCC et al on it, and you'll be booting from it for development purposes.

This gives us a few benefits;

  • We are developing on the target hardware and can test things immediately.
  • We can keep the NAND in a near enough vanilla state to ensure we don't accidentally pull in and use random libraries that not everyone will have.
  • If we do something really bad, we've only messed up an SD card and can just re-extract the tarball and start again, rather than reflash the NAND!

If you've already got an SD card setup with dev tools, then you can leave class early and I'll see you next week.
Same for if you have a preferred development environment already.. if it works for you, there's no point changing it.
The rest of you, pay attention!

We'll do everything on the Pandora, to save having to deal with Linux, Windows, Mac, BSD, BeOS, whatever... madness.
I advise at least grabbing yourself a 2Gig SD card.. go for a bigger card if you like, but 2Gig is probably a good minimum and are reasonably cheap these days.

Grab your SD card and ensure everything you want from it has been removed - we're about to sacrifice it to the Pandora Dev Gods.
Stick it in your left slot.
Open up a terminal.
You'll need to manually unmount it before going near it with cfdisk to repartition.
sudo umount /dev/mmcblk0p1 -- and possibly p2, p3, p# depending on how many partitions it has. Generally, it'll only have the one.
sudo cfdisk /dev/mmcblk0 -- this'll launch cfdisk on your card.. if you see more than one partition and you've only unmounted one partition, then quit and unmount them!

We want to delete all partitions on this card, so press right and then return to delete the current partition.
Press up and down to move the selector if need be to remove the rest of them if you've more than one.
Now we want to create a new partition, so with the Free Space selected, press right to highlight [ New ] and hit return, select [ Primary ], and let it use the full card ( just hit return. )
Press Left to highlight [ Write ] and press return. Type "yes" and hit return to confirm the changes, then [ Quit ]
You could have added swap if you wanted.. it's up to you really.

Now we have to format it.
sudo mkfs.ext2 /dev/mmcblk0p1

Remove the card and reinsert so that the system re-reads the partition table correctly and gives you access to your newly formatted partition.

Now, we download the latest rootfs from OpenPandora.org and extract it to the card. We shall be lazy and stay in the terminal for this so...
cd /media/mmcblk0p1
sudo su -- we'll need to be root for this, as we'll have no permission by default to touch this card.
wget -c http://openpandora.org/firmware/pandora-rootfs.tar.bz2 - this grabs us the latest rootfs - though lately, these appear to be very out of sync between Pandora OE and Angstrom OE so be careful!
tar -xjpf pandora-rootfs.tar.bz2' -- you could add v to the arguments if you like.. it'll let you see what it's extracting and is slightly more exciting than just waiting for it to finish! The p is for preserving permissions, x to extract, j for bz2 support and f for file.
rm pandora-rootfs.tar.bz2

We want the system to autoboot this when the card is inserted, so let's create autoboot.txt
nano autoboot.txt
Fill it with the following:

setenv bootargs debug root=/dev/mmcblk0p1 rw rootdelay=2 console=ttyS0,115200n8 vram=6272K omapfb.vram=0:3000K
ext2load mmc 0 0x80300000 /boot/uImage-2.6.27.46-omap1
bootm 0x80300000

That's us.. reboot and run through the First Time Configuration stuff, being sure to choose XFCE over MiniMenu, and then feel free to configure the look as you see fit.

Now the fun bit.

Warning - This is potentially dangerous as Angstrom and Pandora libraries may have gone off at tangents at this point... this is why we're doing this on an SD card rather than the NAND so if we stuff it up, we only need to reformat an SD card and not reflash the NAND!

Make sure your Pandora is connected to the net by whatever means you have.
Open up a terminal
sudo opkg update
sudo opkg install gcc g++ make binutils-dev cpp cpp-symlinks g++-symlinks gcc-symlinks libstdc++-dev libgles-omap3-dev subversion - You could install sdl etc.. too if you want, but that's all we'll be using for now; and you'll be needing subversion later to keep up with the project.

Now the ever popular Hello World.
mkdir Projects
cd Projects
nano main.cpp

#include <cstdio>

int main(void)
{
	printf("Hello World!\n");
	
	return 0;
}

g++ -o main main.cpp
./main

Interesting Gotcha - In the rootfs I downloaded (HF5 RC1), ncurses hadn't been installed... sudo opkg install libncurses5 if you get "cannot open shared object file libncurses.so.5" when invoking nano.

That's all for this week.. course you could go and install Geany, or whatever code editor you prefer.
Next time, we shall be opening up a window via badgering X11 directly, and getting a GL ES context up and running.