So two major changes have happened to Gail in the last week, so thought i’d explain them. Lets start with the easy one.
Particle System (Rendering rewrite)
The particle system hasn’t been around that long, and was originally written to be quick to code instead of being fast. Internally, it used a single ImageGroup and a billion Images to handle all of the particles. Which means the 2k particles or whatever had to change its VBO every single frame. (as a side note, that hasn’t been fixed yet). However, every single particle was a quad, meaning you had 4 verts per particle, and each vert had position, color, texture information. Massive amount of information for a simple particle system.
So I added PointSprite support to Gail::RendererNG. PointSprite is an opengl feature that allows a point to be textured, specifically designed for things like particle systems. Spec can be found at : http://www.opengl.org/registry/specs/ARB/point_sprite.txt . Its been enabled by default since OpenGL3 and ES2, so enabling it for the rest wasn’t a big deal (so if your using Gail with antialiased points, drop it right now
). Biggest thing is the rest of Gail mostly expected triangles for everything (at least for filling up VBO nodes), so VerticesData now can take different formats and generates accordingly. Lastly, ParticleEmitterNode now generates a single list of points for all particles, and uses a new shader in Gail::RendererNG::ShaderLibrary to render the points.
So did this change help? Originally, the Particle module in Gail::Playground ran at 7-11FPS on a computer. Removing the ImageGroup brought it up to 24FPS, adding the point sprites brought it up to 50-60FPS. On device for RocketFrogz, it went from 5FPS to 20FPS so it was worth it.
There is still a lot more improvements to be done : streaming the VBO, working on the shader its using, but its finally not lagging stuff anymore.
Resource System Overhaul (or how I deprecated your last month of work)
Resource management in Gail has always been moving. Originally you handled it yourself, and used Gail::VFS to abstract some of it. Next you used Source.xml and Gail::Resource to automatically handle loading and caching resources (and then caching got removed due to it being stupid, but thats a different story). Currently, the issue is that their isn’t a clear seperation between the source resources, and the resources generated. Also resources are all installed as install steps (except for mobile platforms), which confuses IDE’s build and run feature. Lastly, you have to add rules for building resources in 3 or so places. Source.xml to tell Gail the resource will exist there. Catalyst so that it generates the file from the given source files. And in code to use it (though the Resource.h that GailResourceCompiler generates helps here). You also run into the issue that some platforms use certain files and not others.
So whats the solution? A new resource XML format! (yes that seems to be my solution for everything).
This file is Resources.xml. Its very very like Source.xml (which we’ll see later) but contains all the information to build resources. GailResourceCompiler has been altered accordingly to be able to build these resources, and return all sorts of information for cmake to use. Several catalyst rules have been added to Gail to allow it to use this directly.
So lets have some examples:
In RocketFrogz’s CMakeLists.txt, here is the important line.
gail_generate_resources (RocketFrogz_GENERATED_RESOURCES_NEW ${RocketFrogz_SOURCE_DIR}/ RocketFrogz/ RocketFrogz)
This line generates all the rules for the Resources.xml in the current source directory, will install the resources into the directory RocketFrogz/ for the target named RocketFrogz.
It automatically builds a lot of cmake rules to generate all the resources listed. These generated files are put into the variable GENERATED_RESOURCES_NEW (named accordingly so i didn’t stop on my old resource stuff) which yo uadd to your catalyst_add_executable like normal.
So whats this Resources.xml look like? A small piece follows
<?xml version=”1.0″ ?>
<gailresources>
<group name=”AvailableUnitsView”>
<resource alias=”availableUnitsViewUI” type=’Gail::UI::UIType’ command=’copy’
input=’Resources/AvailableUnitsView/AvailableUnitsView.gailui’
output=’AvailableUnitsView/AvailableUnitsView.gailui’/>
<resource alias=”availableUnitsViewSpriteSheet” type=’Gail::Sprite::SpriteSheetType’ command=’copy’
input=’Resources/AvailableUnitsView/AvailableUnitsView.spritesheet’
output=’AvailableUnitsView/AvailableUnitsView.spritesheet’ />
</group>
</gailreources>
Its very similar to Source.xml, except it has a few extra fields. Each resource has an input file (relative to your source directory), an output file (relative to your binary resource directory), and a command on how to create one from another. Both of these are just straight copies, but theirs various other commands. For example, ‘pngToPVR’ converts a png file to a PVR when it builds the resources. You can also mark what platforms the resource should be built on, via platform=” and not_platform=” attributes. This gives greater control over how resources are built. This also seperates the final resources from the source resources : right now, most of the resource rules build intermediate resources that you end up storing in your VCS anyways, not leading to a clear seperation. Lastly, since this copies it into the build dir, IDEs build and run should work properly now without having to install first.
~ thothonegan