This manual is a project for documenting AgateLib, and demonstrating some of the features and techniques. If you are unfamiliar with AgateLib, you may want to read the first few sections on getting started with it.
AgateLib is a platform-independent .NET library intended for cross-platform development of games and game development tools. It is CLS-compliant, so it is accessible to any .NET language. AgateLib is built on a driver-based model so that new platforms and rendering pipelines can be implemented easily. The design and interfaces in AgateLib were inspired by the powerful ClanLib C++ library. AgateLib is developed entirely in C#, and builds and runs under .NET 3.5 and Mono on Windows, Linux and Mac OS X.
How does AgateLib work on different platforms? The answer is simple really, thanks to powerful reflection capabilities in the .NET standard library.
AgateLib has several abstract classes located in AgateLib.ImplementationBase which must be inherited from by a driver. The three main subsystems (Display, Audio and JoystickInput) have abstract classes which behave as a class factory to create their own concrete implementations of these abstract base classes.
When the Agate library is initialized, it searches the directory of the executing file for other DLL's. Each DLL it finds, it checks for a class extending AgateDriverReporter. When it finds one, AgateLib instantiates it and asks it what classes in the library provide implementations for the AgateLib subsystems. The best one of these is chosen and used for running the graphical engine (or audio or input). New drivers can be added to an existing program without recompiling it. Thanks to Mono's ability to load and execute MSIL, one can compile a game into a binary executable with Microsoft Visual Studio, for example, and copy it to a Mac OS X machine, drop in appropriate Mac OS X drivers and run the application. All of this happens behind the scenes.
If multiple drivers are present, Agate will choose the best available one. Agate can also show a dialog to the user asking them which drivers to choose. This is useful for debugging purposes. This also allows a single distribution to be constructed for all platforms just by including the drivers for each platform.
AgateLib operates through a driver or plug-in model where drivers are loaded at startup automatically based on what is available. Your application only needs a reference to AgateLib.dll. Upon initializing AgateLib, it will instantiate drivers to operate through OpenGL or Direct3D, depending on which drivers are present.
Considerable work and testing has gone into ensuring that AgateLib runs as consistently as possible across multiple platforms. Currently supported platforms are Windows, Mac OS X, and Linux. AgateLib is regularly tested on several versions of these platforms in order to ensure that the behavior is consistent.
An application built with AgateLib is easy to deploy. The AgateLib.dll itself has no external dependencies. The recommended drivers AgateOTK (for graphics) and AgateSDL (for audio and joysticks) operate on all platforms, provided native libraries are present. OpenGL is generally already installed on every computer, so this usually amounts to making sure that SDL and SDL_mixer are present. If SDL is not a desirable dependency, then AgateSDL can be swapped out for AgateFMOD or AgateMDX to use FMOD or DirectSound for audio.
Eighty percent of users will use twenty percent of the code. AgateLib is designed to make that twenty percent of code that you will use as accessible as possibly, giving you code ends up being very readable and easy to maintain.
From day one, being able to use AgateLib to render to a control on a Form has been a goal, and that will never go away. This makes AgateLib ideal for writing game authoring tools or applications which require a complex set controls for user experience as well as smooth animations in the rendering region.
With AgateLib, you have complete control over your rendering. You don't have to give up control of your render loop, where it is called, with what frequency, or even how many render loops you have. Of course, you can give up control over the render loop if you prefer, as this eases the coding effort on you and enforces some structure. With AgateLib, you have the choice.
Many OOP libraries abstract away the details to the point where two lines of code which look identical can have very different performance characteristics. With AgateLib, expensive operations like copying pixel data from application memory to video memory require explicit method calls which make the intent clear. You never have to hunt for weird performance bugs where, say, you have some surfaces stored in video memory and others not.
AgateLib has been thoroughly tested and optimized. Surfaces are packed into video memory to minimize graphics accelerator state changes, and drawing calls are queued up in order to batch them. These optimizations occur behind the scenes, so all you notice is that your AgateLib game is blazing fast, even on old hardware.
In this chapter, details on how to install AgateLib and create projects which use AgateLib are described.
First, for Windows, we recommend that you have a copy of Visual Studio. The express editions can be downloaded for free from Microsoft. This tutorial is specific to Visual C# 2005 Express, but instructions should be very similar for the 2008 version.
Visual C# 2005(8) Express
Start a new project using the "Windows Application" template and save it. AgateLib provides all the functionality necessary for creating windows and drawing to the screen. So you do not need references to many of the default libraries visual studio has.
Take a close look at the solution explorer, expanding any collapsed items (the properties folder can be ignored). Under the reference folder Visual Studio will have automatically added references to System, System.Data, System.Deployment, System.Drawing, System.Windows.Forms, and System.Xml. Delete all of these except System and System.Core (if running on Visual Studio 2008). You may also want to keep System.Xml and System.Xml.Linq if you plan to read/write any XML files. Also delete Form1.cs.
Now you need to add a reference to the AgateLib library. Right click on the References folder in the Solution Explorer and click "Add Reference...", make sure the selected tab is ".NET", and then click the Browse tab. Locate the folder you extracted AgateLib to. If you just want to get on with it, add a reference to AgateLib.dll and AgateOTK.dll, and skip the next section. At some point you should read the page on drivers to get familiar with their requirements.
Visual Studio 2005 contains some nifty features which help you debug applications. Unfortunately, one of these is incompatible with Managed DirectX 1.1, so if you are using AgateMDX instead of AgateOTK we need to disable it. If you are using AgateOTK, skip this step. In the menu bar, go to Debug -> Exceptions. Expand Managed Debugging Assistants. Scroll down to the LoaderLock exception, and uncheck it. Click OK to accept changes. If you skip this step while using AgateMDX, you will notice that the application will get an exception when it starts up. It is important to point out, this is only an issue if you are running your code in the Visual Studio debugger. This is not an issue if you double-click the .exe file outside the debugger, or use CTRL-F5 to run without debugging. It is also not an issue when your game is complete and you wish to send it to other people to play it. Visual Studio is designed so that this is a per-solution setting. So LoaderLock exceptions have to be disabled for every solution with a project using AgateLib and the MDX driver.
Now we are ready to write some code. We will be working with the program.cs file. You may rename it if you wish, by single clicking on it and pressing F2. Double-click program.cs in the Solution Explorer. Visual Studio generated some code which creates a Form from Form1 and shows it. Delete the text in program.cs, and replace it with the following code:
To develop with AgateLib on Linux, first you must have Mono installed. You can download Mono from the Mono-Project web site. This includes MonoDevelop, the C# IDE for Linux. Many Linux distributions include a version of mono in their repositories. Check with your distribution to see what package you need to install to get Mono and MonoDevelop. You also need Mono's WinForms implementation.
OpenSUSE 11.1: zypper install mono-complete
Download
Once you have a working copy of Mono, you should download AgateLib version 0.2.5 from the SourceForge site. Extract it to a folder, say ~/Agate.
Creating a Project
Note: These instructions were written for an older version of MonoDevelop. They should still be valid but there may be minor differences.
In MonoDevelop, create a new project (Shift+Ctrl+N) and name it TestAgate. You should be able to pick any language you like, but be sure to pick an Empty Project underneath it. Picking a language other than C# may make the instructions that follow a little different, so you may want to start with C# until you get familiar with how to setup a new project.
Setting the runtime
In order to use AgateLib effectively, you need to be using the .NET 2.0 stack. To make this change, look in the Solution window on the left hand side. There will be a tree there with Solution TestAgate and TestAgate under it. Expand them both. Right click the project (titled TestAgate) and choose Options. In the new window that comes up, underneath General there will be Runtime Options. Click that, and on the right hand side, make sure the runtime version to 2.0 and click Ok.
Adding AgateLib references
Once you have a new project created, look in the Solution window on the left hand side. so that you see the references folder. Right click that folder, and choose Edit References. Pick the tab that is titled .Net Assembly. At the top you will see a file browser. Pick the folder that you extracted AgateLib to, and select all DLL files there. Click Add and then OK to add the references to your project.
Adding Source Code
Now back in the Solution window, we need to add a source code file. Right click on your project (named TestAgate), go down to Add and choose New File.... MonoDevelop will give you several choices on what to add here. You want to click the General category on the left hand side, and then choose Empty File on the right hand side. Name this file TestAgate.cs and click New.
Copy and paste the following code into the TestAgate.cs file.
Now build and run the application by pressing the F5 key. If you did everything right, then the application should crash with an unhandled exception! Unfortunately, there's one more important step, which should be handled by MonoDevelop but isn't.
== Copying DLL config files ==
If you look inside the directory where you extracted AgateLib (ie. ~/Agate), you should see a file OpenTK.OpenGL.dll.config and a Linux folder. The config file must be manually copied to the same directory as the executable that is produced by the Mono compiler. The Linux folder contains other files that components of AgateLib depend on that are specific to Linux. At the moment, this is only the FMOD library. To use FMOD, these files must also be copied to the same directory as your executable. So open up a terminal window and execute the following two commands:
cp ~/Agate/*.config ~/Projects/TestAgate/TestAgate/bin/Debug
cp ~/Agate/Linux/* ~/Projects/TestAgate/TestAgate/bin/Debug
Note: You may have to change the above lines depending on choices you made previously. If you changed the name of your project from TestAgate, you will have to use your project name. If you didn't choose to make a separate directory for the solution, the target directory structure will be something like ~/Projects/ProjectName/bin/Debug. Also, if you extracted AgateLib to a different directory than ~/Agate, you will need to change that.
Now if you go back to MonoDevelop and push F5 to build and run your project, you should have a window with a "Hello World" title with a green background. Congratulations, you have just written your first application using AgateLib!
AgateLib is built with a driver architecture. A project developed with AgateLib needs only to link to AgateLib.dll. When Agate is initialized, it will search for available drivers in the working directory. These drivers are placed in other .NET assemblies and are loaded dynamically at run-time. This allows an application to switch from using, say, DirectX to OpenGL just by placing the correct file in the folder with the executable, without recompiling the program.
There are three types of drivers currently. Display drivers are used to render graphics, audio drivers are used to play sound and music, and input drivers are used to interface with a joystick.
AgateDrawing.dll is a driver which does all rendering through the classes in the System.Drawing namespace. This is a platform independent implementation of the 2D graphical features supported by AgateLib. It actually performs reasonably well if there's not a whole lot going on. Rotations, coloring and alpha blend probably cause a large performance hit for this driver. Lighting is completely unsupported. This driver is mostly for testing purposes and should not be used in production builds.
To use AgateDrawing.dll, you only need to include it with your application. If any other display driver is present, AgateDrawing will not be chosen to do rendering.
The AgateFMOD driver uses FMOD for cross-platform audio support on Windows and Linux. FMOD also supports playing MIDI files using provided soundbanks. The use of FMOD carries license restrictions, so be sure to pay attention to the FMOD license if you distribute AgateFMOD.dll.
In order to use AgateFMOD.dll in Windows, the fmodex.dll file from the deps directory must be copied to the application directory or the c:\windows\system32 directory. It is recommended to copy it to the application directory, as this simplifies distribution.
In order to use AgateFMOD.dll in Linux, the libfmodex.so.4.04.43 and AgateFMOD.dll.config files must be placed in the same directory as AgateFMOD.dll. Separate distributions for Linux and Windows do not need to be created; you can include the Linux and Windows dependencies in the same directory with no problems, other than a startup warning message on Linux, but this is only seen when running the application through a terminal window.
AgateMDX.dll contains a complete set of drivers, video, audio and input using Managed DirectX. Obviously, this is a Windows specific implementation. All drawing calls are done through Direct3D, so hardware acceleration is available for rotations, coloring, alpha blending and lighting. Performance with this driver is quite good, especially compared to AgateDrawing.dll.
Audio support is provided through Managed DirectSound and the DirectX.AudioVideoPlayback class. These to not provide very fine-grained control over how sounds play, so the AgateFMOD.dll driver is preferred.
Managed DirectInput provides Joystick support. There is currently no support for force feedback, either through the driver or the AgateLib interface, mainly because I do not have a force feedback joystick to test it with.
AgateMDX requires an up-to-date installation of DirectX on whatever target machines an Agate application is being run on, as well as an installation of the appropriate Managed DirectX assemblies. These are not included with a typical DirectX install that most end-users would have performed when they installed their video drivers. An installation for the DirectX runtime files is included in the Agate download. So, if you use AgateMDX.dll then you will require an extra installation step for most anyone who uses your program.
AgateMDX may perform slightly better than AgateOTK.dll as it's more mature. In what tests I have done, I have not seen a significant difference in performance between the two except under specific circumstances.
AgateOTK.dll is display driver using OpenGL through the OpenTK interop library. OpenTK provides some nifty features such as automatic context creation for Windows, Linux and Mac OS X, so AgateOTK provides hardware-accelerated OpenGL support for these operating systems. The framerate in both Windows and Linux is comparable to the framerate obtained using AgateMDX on Windows.
In order to use AgateOTK.dll, the OpenTK.dll and OpenTK.Utilities.dll files must be included. In order to support running on Mono on non-Windows platforms, the OpenTK.dll.config file must be manually copied into the same directory as the OpenTK.dll file. This config file provides mapping from the dll names used in Windows to the dynamic libraries (.so or .dylib) used in Linux and Mac OS.
The AgateSDL driver uses Simple DirectMedia Layer for sound and joystick input. SDL is LGPL licensed, operates on Windows, Linux and MacOS X, and (in most cases) should support playing Ogg Vorbis and midi files.
In this chapter there are tutorials on the basic use of the various parts of AgateLib.
Audio tutorial goes here.
Basic drawing primitive shapes goes here.
Of course in any game you want to be able to write text to the display. Agate provides a painless way of loading fonts:
The above line of code creates a font object using 12-point Arial.
Drawing text to the screen is simple, using the DrawText function
FontSurfaces also have the same Alpha, Color, ScaleWidth, and ScaleHeight properties that Surfaces and Sprites have.
Mouse Input
Input from the mouse can be obtained in an easy manner, through the use of the static Mouse class. The following three methods get the position of the mouse cursor.
The above properties have set methods also, so the mouse position can be changed. You can check them every frame, or if you prefer you can attach to the Mouse.MouseMove event, as in the next example.
The Mouse also has a MouseDown and a MouseUp event that you can attach to in order to deal with mouse clicks.
Keyboard Input
Input from the keyboard is obtained in a similar manner to mouse input, through the static Keyboard class. You can check the state of any key with the Keys member, as in the following example.
You can also attach to the Keyboard.KeyDown and Keyboard.KeyUp events.
Tutorials on creating / loading / using resources go here.
AgateLib contains two serializers.
AgateLib has a sprite class which can be used to create animated sprites. In order to use sprites, you need to add the following using directive to the top of any file you wish to use sprites:
Loading images into a sprite
Managing animations where you have several frames of animation can be tedious. Luckily, AgateLib has a fairly robust Sprite class which will do all of it for you. There are several ways to load up a sprite and add frames to it. The simplest follows:
The above two function calls are equivalent. You specify a file, and the sprite automatically cuts out frames of the size passed (32x32 in the above example). It will automatically ignore frames which are blank.
If you have frames of animation in more than one file, you can add them after creating a sprite in this manner:
Drawing with a sprite
Sprites have all the same drawing functions that Surfaces do. They also have a number of the same properties.
Animating sprites
Loading images
Loading an image to display on the screen is easy. Simply create a surface object and tell it what file to load.
Png files are recommended, because they are small and they support per-pixel transparency, at 256 different levels for each pixel. Png transparencies are supported by AgateLib.
Drawing with surfaces
Surfaces have many properties that affect how they are drawn. The simplest way to draw on the screen is
to call one of the surface's Draw methods. The line of code below will draw the surface at the point x = 20 and y = 30.
By default, the above line tells Agate to draw with the point (20, 30) as the upper-left point of the surface. However, this can be changed easily. If you wanted to issue the above command and have (20, 30) be for example, the center of the surface, then you would need to first set the surface's DisplayAlignment property.
Scaling Surfaces
This is very convenient if you have surfaces which you want to stretch as part of an animation. The above line will cause draw points to be interpreted as the center of the image, taking into account scaling. Speaking of scaling, it is very simple to scale a surface. The following code lists several methods to scale a surface.
Color and Transparency
You can make a surface partially or completely transparent by using its alpha property. An alpha value of 1.0 is fully opaque, 0.0 is fully transparent.
Surfaces can also be colored, with their Color property. Following are several examples showing how to set the color of a surface.
Notice that the Color structure has an alpha channel. Setting the Color property of a surface will overwrite its Alpha value. Surface colors are multiplicitive in effect, so the effect is much greater on images which are lighter in color than images which are darker in color.
Rotations
Surfaces can also be rotated. Rotations can be specified in either radians or degrees, and positive numbers indicate rotating in the counter-clockwise (CCW) direction.
Just like you can change the display alignment of a surface, you can also change its center of rotation. By default it is in the center of the surface.
An arbitrary rotation center cannot be specified in this way. If you want to make a rotation around an arbitrary point, there is a Draw overload which takes a rotation center point. The following line of code draws the surface at the point (20, 30) rotated around the point (40, 50).
This chapter contains general tips about improving performance of your games written with AgateLib.
This page should be read with the thought in mind, premature optimization is the root of all evil. Don't bother optimizing your code until you know it's too slow, or it's done. And don't optimize code before running through a profiler. Programmers are usually not very good at predicting which parts of their code will actually be performance bottlenecks. Compilers can be quite surprising in the things they will and won't be able to optimize efficiently.
NProf is an excellent free open-source .NET profiler. NProf will give you an indication of what parts of your application take the most CPU time.
The CLR Profiler will profile the memory usage of your application. It will tell you when, where, and how much of each type is allocated, how often the garbage collector runs, how much is collected and much more.
MSDN Blogs
Here's some interesting .NET related blogs from people at Microsoft I've found. Many of these contain some very useful performance tips.
Garbage Collection
Garbage collection can be a serious enemy of writing smoothly performing games. A collection which lasts 50 milliseconds is virtually unnoticable in a desktop application, but in a game running 60 frames per second, this results in 3 dropped frames. The implications go beyond that; it means the amount of time between the frame before the GC and the next frame is four times what it usually is, which causes objects to appear to jump across the screen in a very jerky manner and is quite unattractive to the user.
On the other hand, there are a number of performance advantages that garbage collection grants. It automatically compacts memory, so memory does not become fragmented over time, and a small enough application can maintain a large amount of its data in cache memory, avoiding costly cache misses.
The old adage goes, ''the fastest code is code that never runs.'' To make an analogous statement, we could say from that ''the fastest memory to garbage collect is that which was never allocated.'' Some performance strategies I've had success with are:
Loading levels
Contrary to the usual wisdom, if you are loading a new level or map in your game, it's often a good idea to throw in a GC.Collect(); at the end of your load routine. If the user spends a fair amount of time on your level, then most of the objects specific to the level will probably have made it to generation 2, which is a garbage collection that takes a fair amount of time to execute. When loading a new level, many of those objects are unreferenced, and subject to collection. But you don't want to see a Gen 2 collection a few seconds after the user starts the next level, this will be really annoying to them, because it will cause a sudden freezing of your application for a brief moment. Throwing a GC.Collect() after loading a new level and making sure to dereference all the old data forces the garbage collection to occur at a time when the user expects to be waiting anyway.
You should not throw in GC.Collect anywhere until you are certain that you have a garbage collection problem. You can see if you have garbage collection issues by using the CLR profiler.
Installation
Should you run ngen on your application when installing it?
To ngen or not to ngen.
Here will be a list of information relevant to the different versions of AgateLib released on sourceforge.net.
AgateLib 0.1.8 Release Notes
======================================
Requires .NET 2.0 or Mono.
Deployment procedure, with respect to DirectX runtime files is unknown at the moment. I
have included what I think is the minimum required files for the DirectX runtime distributable
to work with the AgateMDX library in the dxredist directory of the archives.
Known Issues:
* VSync is not properly supported in the Direct3D driver.
* There's a problem with Display.PackAllSurfaces where it does not copy surfaces correctly.
* Direct3D driver does not work with Mono. If you are running in Mono, delete AgateMDX.dll from your application directory.
AgateLib 0.2.1 Release Notes
======================================
AgateLib applications should run under Linux now. I have successfully tested them using the Mono VMWare SuSE image on my computer. Unfortunately, this is the limit to my ability to test on Linux at the moment. The serious development of an OpenGL driver is postponed until the next version of Tao, so hardware support under Linux will not be available until then. Windows platform-specific P/Invoke methods have been moved to the AgateWindows.dll assembly. This was required for Linux support. Using AgateWindows.dll should provide a speed-up and greater memory efficiency by providing access to PeekMessage and high-resolution timers. This benefit may be negligible; more testing needs to be done. The source code has been restructured a bit.
In the version 0.2.2 the System.Drawing replacement structures Color, Point, PointF, Rectangle, RectangleF, Size, SizeF will be moved to the ERY.AgateLib.Geometry namespace. You can prepare for this by adding a using statement for this namespace now. This change will help prevent naming conflicts which occur when mixing Windows.Forms components with AgateLib. This should not be an issue for game applications, but it is an issue for tools. The resource classes ResourceManager and Resource have been moved to the ERY.AgateLib.Resources namespace. Display.DeltaTime will now never return zero, so it's safe to divide by it. However, due to the nature of this hack, if a high resolution platform-dependent timer is unavailable (such as the one in AgateWindows), this will cap your framerate at whatever the resolution of System.Environment.GetTickCount() is. On my test machine, this is 64 fps.
Known Issues:
* No hardware acceleration support in Mono.
* Playing .mid files as music won't play more than one. In the future, the implementation will probably switch to FMOD instead of DirectX.AudioVideoPlayback.
Changes:
* Restructured storage for registered drivers in Registrar class to allow easier addition of new types of drivers.
* Added platform specific drivers to provide P/Invoke methods to increase speed and memory efficiency.
* Agate applications should run under Linux with a proper Mono installation now.
* Added debug messages when non-cross-platform paths are used, in particular when the backslash (\) is used as a path separator.
* Organized some of the source code in different directories.
* Registrar.Initialize is now internal instead of public. If you are calling it, use Core.Initialize instead.
* Added a hack to make sure the Display.DeltaTime never returns zero.
* Fixed a Sprite bug where if a Clone'd sprite was Dispose'd, the shared surface data would also be disposed. Now SpriteFrames are reference counted to resolve this.
* Fixed a bug in Sound and Music objects where they might not respond to StopAllSounds/Music.
AgateLib 0.2.5 Release Notes
======================================
AgateLib is much more compatible with Linux now. An OpenGL driver has been written which should get
similar performance to the Direct3D driver. This driver should work on Windows and Linux with
Mono version 1.1.16 or newer. Unfortunately, Mono version 1.1.13.8 seems to be what's available
in the package managers in a lot of Linux distributions. So if your version of Mono is older than
that, you must download a newer version. I've had best luck with installing Mono as a regular user,
_not_ as root.
Some issues may not be resolved in running full-screen apps on Linux. In particular, going full-screen
depends on the presence of the XFree86 video mode extension. This doesn't appear to be installed on
all machines, or worse, it may have different names (libXxf86vm.so or libXxf86vm.so.1 so far) on
different machines. I am searching for a full-screen solution which does not rely on this extension,
as there are other minor issues as well.
Cross-platform audio is supported through the use of the FMOD library. If you wish to distribute FMOD with
your application, you must be aware that FMOD has license restrictions on distribution. A license to distribute
FMOD can be obtained from http://www.fmod.org/ . At the time of this writing, there are several license options
available for FMOD, including a special license for distributing software which is free (as in beer).
AgateLib now uses bitmap fonts. Bitmap fonts are generated from a System.Drawing.Font object. At the moment the
way these fonts look is platform dependent, and it seems that either Mono or X11 does not generate fonts which
look quite as nice as they do on Windows. However, this is still an improvement over the previous method of
creating fonts. In the future, there will be a code model for generating a bitmap font on one platform and
saving it to disk to distribute to other platforms.
Support for reading and writing surface data is included now in the PixelBuffer class. The PixelBuffer
class provides basically an array of bytes to work with. There are also several wrapper methods to help read/write
pixels as well as conversion routines to convert from one pixel format to another.
To increase compatibility for authoring-tool type applications, the System.Drawing replacement classes are
now moved to a different namespace. For updating an existing Agate application which does not use any
System.Drawing calls, you only need to insert a using statement (Imports in VB) for the ERY.AgateLib.Geometry
namespace at the top of each source file. This still doesn't have the level of compatibility I want, because
AgateLib.dll still has a reference to System.Drawing. In a future version of AgateLib, conversion routines
for working with System.Drawing classes will be moved into a separate class, in a separate assembly.
The ability to create lighting effects is now available. This is not supported by the System.Drawing driver.
You create Light objects, add them to a LightManager object, and call its DoLighting method. It can create
some neat effects.
Known Issues:
* 16-bit display formats are not supported.
* Joysticks are not supported in Linux.
* Using a surface as a render target in OpenGL is slow, because rendering occurs in the framebuffer and then
the pixels are copied to the surface.
* Mono on Windows is not supported. It hasn't been tested, so I have no idea if it works or not.
Thanks to:
* Apviper, for his diligent testing efforts when I was trying to figure out how to get this to work on other machines
* Skel1 for writing Ball: Buster in C++ in the first place and introducing me to ClanLib.
* Ravuya for help with making Agate work on Mac OS X.
ChangeLog
======================
AgateOTK has been added for OpenGL support, and AgateFMOD has been added to use the FMOD ex library to play audio.
Both are being tested on Windows with .NET and Linux with Mono.
Important Breaking Changes:
* Moved System.Drawing replacement classes (Color, Rectangle, Point, Size and floating-point versions) to ERY.AgateLib.Geometry namespace.
* Removed ERY.AgateLib.Geometry.Color.FromArgb(System.Drawing.Color) static method. To convert colors from System.Drawing structures, use the ToArgb method.
Obsolete API's:
* Display.EndFrame(bool waitVSync) - Set the Display.VSync flag to indicate whether or not the vertical blank should be waited for.
* DisplayWindow.Closed - Read the DisplayWindow.IsClosed property instead.
* DisplayWindow.ToggleFullScreen - Use SetWindowed and SetFullScreen instead (old version did not allow for changing resolutions when full screen.)
Additions:
* Created OpenGL driver using the OpenTK library to add hardware accelerated support when running under Linux.
* Created FMOD driver for audio support.
* Added PixelBuffer class for direct modification of Surface data.
* Added Licensing information to some files where it was missing.
* Added code to create bitmap fonts from fonts provided by the operating system. These are default for creating fonts in DX and OGL, because they look better than other options.
* Added the ability to introduce lighting effects. Also Surfaces now have a TesselateFactor property which automatically divides them up into smaller rectangles for better lighting effects (per-pixel lighting not supported yet).
Fixes:
* Various minor bugs fixed.
* Various issues associated with running under Mono on Linux have been fixed.
* Reorganized source tree for AgateLib, and moved stuff which is not critical for use by external programs to namespaces under ERY.AgateLib.
* Reabsorbed the platform-specific drivers back into AgateLib.dll. AgateWindows.dll will not be missed.
* Fixed Display.PackAllSurfaces bug.
Changes:
* Packing surfaces is now done entirely in managed memory spaces, so it should be much more robust than the render-to-texture method used previously.
* Is*Blank methods of the Surface class are obsolete now; instead use ReadPixels and then methods on the resulting PixelBuffer.
AgateLib 0.3.0 Release Notes
======================================
There are several major additions to this version of AgateLib, the most notable
is support for MacOS X without running through X11. To have support for MacOS
and Linux use the AgateOTK driver, which uses OpenGL as a backend. This driver
also works on Windows, so there really is little reason to use AgateMDX any
more.
Support for using SDL for audio and joystick input has been implemented. This
is the recommended means of getting audio and joystick support under Linux and
MacOS. In fact, for creating a cross-platform distribution using AgateOTK and
AgateSDL probably creates the least amount of headache.
Several parts of the API have been reorganized into separate namespaces. For
the most part this means adding statements like "using AgateLib.DisplayLib" to
your source files. A lot of things have been deprecated in this release, and
shortly following the release of 0.3.0 there will be a release of 0.3.1 which
removes all deprecated features.
Most of the testing on Linux and Mac OS X for this release has been done under
Mono 2.0 and 2.2. Everything should probably work on older versions of Mono,
down to 1.2.6 maybe. Ubuntu includes Mono 1.9.1 which seems to work well but
has not been thoroughly tested.
In this chapter we will describe the things that need to be done to deploy an AgateLib project on the different platforms that are supported.
Useful links:
http://www.mono-project.com/Guidelines:Application_Deployment
Listed here are my future plans for the next version of AgateLib. Most of these are partially implemented.
AgateFMOD driver
Fonts
Sprites
GUI
A link to the current revision of the TODO.txt file in the subversion repository is here:
http://agate.svn.sourceforge.net/viewvc/agate/trunk/TODO.txt?view=markup