Creating a Custom Orthographic Projection With Pyglet
When you create a pyglet window, pyglet sets up an OpenGL orthographic projection for the window. The size of the projection matches the size of the window. If the window is 640 pixels wide and 480 pixels wide, the orthographic projection is 640 units wide and 480 units high. Pyglet’s default behavior works well in many cases, but there are situations where you may want to create an orthographic projection with different dimensions. If you’re writing a tile-based game, it is convenient to size the projection in tiles instead of pixels. How do you create a custom orthographic projection?
Override pyglet’s on_resize() method for the window and make a call to glOrtho(). The following code provides an example of creating a custom-sized orthographic projection:
@window.event
def on_resize(width, height):
glViewport(0, 0, width, height)
glMatrixMode(gl.GL_PROJECTION)
glLoadIdentity()
projectionWidth = 24
projectionHeight = 16
glOrtho(0, projectionWidth, 0, projectionHeight, -1, 1)
glMatrixMode(gl.GL_MODELVIEW)
glLoadIdentity()
return pyglet.event.EVENT_HANDLED
My example copies what the default on_resize() method does, but I supply a custom width and height to glOrtho().
Installing Pyglet on 64-bit Macs
Pyglet is a technology to write cross-platform OpenGL games and applications in Python. If you go to the pyglet site, you will find installers for Mac OS X and Windows. The current Mac version of the installer, 1.1.4, uses Carbon, which means it doesn’t work with 64-bit applications. Not working with 64-bit applications is a problem if you’re running Mac OS X 10.6 and later. Version 1.2 uses Cocoa and works with 64-bit applications, but an installer is not currently available because 1.2 is still in development. Until an installer for 1.2 becomes available, you will have to install pyglet from source code to use version 1.2.
Install Mercurial
The source code for pyglet is in a Mercurial repository. If you do not have Mercurial installed on your computer, you must install it to be able to install pyglet 1.2. Installers for Mac OS X and Windows are available at the Mercurial site.
Clone the Repository
Cloning the pyglet repository gives you a copy of the source code so you can install pyglet. Launch the Terminal application, navigate to where you want the source code to reside, and run the following command:
hg clone https://pyglet.googlecode.com/hg/ pyglet
There is a space before pyglet in the last part of the URL. You should see a pyglet folder after cloning the repository.
Install Pyglet
After cloning the repository, it’s time to install pyglet. In the Terminal application go to the pyglet folder and run the following command:
python setup.py install
Now pyglet should be installed and you can start coding.
Install AVbin
Installing pyglet alone has one limitation. It can play only uncompressed audio files. To play compressed audio files, such as MP3 and Ogg Vorbis files, with pyglet, you must install the AVbin library, which is what pyglet uses to play compressed audio. There are multiple versions available for Mac OS X, Windows, and Linux on the AVbin download page. Those of you running Mac OS X 10.6 and later should download a version that supports 64-bit Intel.
After downloading AVbin, you must install it from the Terminal application. Navigate to the avbin folder (the latest name of the folder on Mac OS X is avbin-darwin-x86-64-v8) and enter the following command:
sudo bash install.sh
Running the installation script installs AVbin and lets you play compressed audio files with pyglet.
SDL OpenGL Typedef Redefinition Error on Mac OS X 10.7
If you build a SDL OpenGL application for Mac OS X using SDL 1.2.14 (using the binary installer at the SDL site) and the Mac OS X 10.7 SDK, you can get the following error:
typedef redefinition with different types ('unsigned int' vs 'void *')
The SDL header file SDL_opengl.h and the OpenGL header file glext.h both define a data type GLhandleARB. SDL_opengl.h defines it as an unsigned integer. The Mac OS X 10.7 version of glext.h defines it as a void pointer. Defining GLhandleARB as different data types in different header files causes problems.
The SDL team fixed the problem in their Mercurial repository. The fix is not too difficult to apply. In your SDL_opengl.h file, change the following line of code:
typedef unsigned int GLhandleARB;
To the following:
#if defined(__APPLE__)
typedef void *GLhandleARB;
#else
typedef unsigned int GLhandleARB;
#endif
The fix defines GLhandleARB as a void pointer on Mac OS X and an unsigned integer on other operating systems.
Mac Game Programming Roadmap Update for 2010
I’ve seen several questions on Mac programming forums recently looking for Mac game programming tutorials, which made me look at my Mac Game Programming Roadmap article. The article is three years old, and some things have changed in the past three years.
Avoid Carbon
Unless you have an existing Carbon codebase, avoid Carbon. If you don’t want to learn Objective-C, use a cross-platform game framework like SDL, Allegro, or SFML. Another advantage of using one of these frameworks is you can support Windows and Linux without having to rewrite much of your code.
SFML
SFML is a cross-platform game framework that has grown in popularity in the past three years. I have not used SFML, but go the SFML website and see if it meets your needs.
Unity
Unity existed in 2007, but its Indie version cost $199. The Indie version is now free and lets you write games that run on Mac OS X, Windows, and the Web. If you’re interested in creating 3D games, I recommend Unity. You’ll finish your game much faster with Unity than you will by programming your game from scratch.
Troubleshooting PNG Loading with SDL_image
SDL_image is a library that simplifies loading image files for SDL games. One of the more popular image file formats for games is PNG, and SDL_image has support for PNG. On game development message boards, you’ll find many questions from people having trouble loading PNG files with SDL_image. This trouble has two common causes.
Cause 1: PNG Files Not Found
The most common cause of trouble of PNG file loading is the operating system being unable to find the file. Suppose you have the following SDL_image function call in your code to load an image:
SDL_Surface* image;
image = IMG_Load_RW("background.png", 1);
That code works only if the file background.png is in the current working directory. If the file isn’t in the current working directory, SDL_image won’t load it, and you have problems.
On Linux and Windows, the current working directory is the directory where the executable file is. Make sure your image files are in the same directory as the executable file.
On Mac OS X, SDL sets the working directory to the directory containing the application bundle. But your image files are in the Resources folder inside the application bundle. This means the code example to load background.png will not work on Mac OS X. The best solution is to change the working directory. My SDL Tips for Mac OS X post has instructions on changing the working directory.
Cause 2: DLLs Not Found
The second common cause of PNG loading problems affects only Windows programmers. For SDL code to run on Windows, Windows must be able to find the SDL DLLs. To find the DLLs, they must reside either in the same directory as the executable file or in the windows\system32 directory.
To use SDL_image on Windows, you must add the SDL_image DLL to the same location as the SDL DLL. Most people remember to add the SDL_image DLL, but they discover PNG files will not load.
The reason the PNG files will not load is that loading PNG files with SDL_image on Windows requires the zlib and libpng DLLs as well as the SDL_image DLL. It’s an easy mistake to make, and the error message SDL_image returns isn’t very clear. The solution is to move the zlib and libpng DLLs to the same location as the SDL and SDL_image DLLs.
SDL Tips for Mac OS X
SDL’s most compelling feature is its cross-platform compatibility. You can use the same source code to write a game for Linux, Mac OS X, Windows, and any other system SDL supports. When people write a game with SDL on Linux or Windows and try to build a Mac version of your game, they learn that Mac OS X has some subtle differences from Linux and Windows. The three tips in this post should help people create Mac versions of their SDL games.
Use the Xcode Project Templates
If you haven’t done so already, go to the SDL website and download it. At the SDL download site, you will see both runtime and development libraries for Mac OS X. Download both libraries. The runtime libraries contain the SDL framework. The development libraries contain documentation and Xcode project templates.
The Xcode project templates do two nice things for you when you build the project. First, the templates create a proper Mac application bundle for you. Second, the templates copy the SDL framework to the application bundle. Including the SDL framework with your game lets people play your game without having to install SDL.
Adding Files to the Game
Games contain many external files, such as graphics, sound, and data files. Mac games store these files in the Resources folder inside the game’s application bundle. If you add graphics, sound, and data files to your project’s Resources folder, they will be copied to the application bundle’s Resources folder when you build your project.
Go to the Groups and Files list on the left side of Xcode’s project window. The top entry should be the name of your project. Click the disclosure triangle next to the project name to see a series of folders. Right-click the Resources folder and choose Add > Existing Files. Select the files you want to add and click the Add button.
A second sheet will open. If you are adding individual files, click the Add button. If you’re adding a folder of files, click the Create Folder References for any added folders radio button before clicking the Add button. Creating a folder reference copies the folder to the Resources folder inside the application bundle when Xcode builds your project.
Changing the Working Directory
The Mac OS X version of SDL sets the working directory to the directory containing the application bundle. This default behavior makes loading images and sounds more difficult because the images and sounds usually reside in the application bundle’s Resources folder. You can make file loading simpler by changing the working directory to the Resources folder.
Open the file SDLMain.m and modify the setupWorkingDirectory: method. The following code changes the working directory to the application bundle’s Resources folder:
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
[[NSFileManager defaultManager] changeCurrentDirectoryPath:resourcePath];
By changing the working directory to the application’s Resources folder, you should be able to use the same code to load files on Linux, Mac OS X, and Windows.
SDL File Loading When Running from Visual C++’s Debugger
I was testing some texture loading code on Visual C++ 2005 and 2008. The code compiled fine, but when I ran it from Visual C++’s debugger, it crashed every time. The code crashed because the program could not find my image file so it could not read the file and load the image. But the code ran file when I ran it from Windows Explorer. Why could my image file be found when I ran my program from Windows Explorer, but not from Visual C++’s debugger?
The reason was that Visual C++’s debugger uses a different working directory. Windows normally sets the working directory to the same directory as the executable file, which is where I had my image file. But Visual C++’s debugger sets the working directory to the directory containing the project file. Where is the project file? When you create a Visual C++ project, Visual C++ creates a folder that has the same name as the project name. Inside this folder is a second folder that has the same name as the project name. The project file resides in the second folder. The second folder is where the image file needed to be to debug my program. Moving my image file to the second folder fixed the crashing problem inside the Visual C++ debugger.
If you’re using Visual C++ to write a game and you want to run the game inside the debugger, make sure your game’s files are in the same directory as the project file.
Setting Up SDL with Visual C++ 2008 Express
Microsoft recently released Visual Studio Express. I wanted to see if my SDL setup instructions for Visual C++ 2005 Express (PDF) worked with Visual C++ 2008 Express so I installed Visual C++ 2008 Express and went through my instructions. The good news is Microsoft did not make a lot of changes in Visual C++ 2008 Express so most of the instructions still apply. There are two differences.
Unlike Visual C++ 2005 Express, Visual C++ 2008 Express ships with the Windows Platform SDK, also known as the Win32 SDK. Visual C++ 2008 Express’s Win32 SDK support means you don’t have to install the SDK separately, and you don’t have to modify any files to get Win32 support.
If you’re running Visual C++ 2008 Express, you can skip over the Installing the Windows Platform SDK, Updating the Visual C++ Properties File, and Updating the Application Wizard’s Settings File sections in my instructions.
In the section Telling Visual C++ Where to Find Your SDL Headers and Libraries, I said the path to the Win32 SDK was the following path:
If you install Visual C++ 2008 Express, you’ll find the Win32 SDK at the following path:
The v6.0A is the Win32 SDK version. If you’re reading this in the future, the version number may change.
Changing SDL’s Working Directory on Mac OS X
The Mac OS X version of SDL sets the working directory to the directory containing the application bundle. This default behavior makes loading images and sounds more difficult because the images and sounds most likely reside in the application bundle’s Resources folder. What would be nice would be to set the working directory to the Resources folder. How do you do this?
You change the working directory by modifying the method -setupWorkingDirectory: in the file SDLMain.m. You’ll want to change the code in SDLMain.m in SDL’s Xcode templates so your changes take effect for any new SDL projects you create. Just to be safe, you should comment out the original code or save a copy of it so you can go back to the original if things go wrong. Enter the following code in the -setupWorkingDirectory: method:
NSString *resourcePath = [[NSBundle mainBundle] resourcePath];[[NSFileManager defaultManager] changeCurrentDirectoryPath:resourcePath];
Thanks to Keith Bauer, aka OneSadCookie, for the source code to change the working directory.
New Article: Mac Game Programming Roadmap
I have a new article available that provides an overview of the technologies to learn to write Mac games. The article was motivated by a discussion that has been brewing on Apple’s game development mailing list for several list. The discussion revolved around Apple’s lack of support for games, and one complaint was that Apple did not have a game library like DirectX. Without a game library getting started with Mac game development can be difficult because he or she may not know where to begin. My article helps them know where to begin. If you’re new to Mac game development, check out the article.