Gail Updates : Playing with Scissors

So this weekend I’ve been playing with a really fancy UI animation. This post is not about that. Instead, its about a problem i’ve been wondering about for a while : how to render something partially. You need to clip your rendering to a piece of the screen for some reason, like a scrolling list where you might see half an item. This involves the scissor test (glScissor() in opengl).

Scissoring and the Scissor Test

What is scissoring? It is restricting the output of draw commands to a specific area of the screen (similar to clipping). Say your rendering a list of items in a box. When you scroll, the list of items scrolls : at some point, half an item is displayed. Even with only half the item displayed though, you only want to render what’s in the box. You do this by scissoring the list box before you do your draw, so when you render the extra line only half is displayed.
So how would we represent this in Gail? Everything in Gail renderering wise is part of the Scene Graph. Lets take the 2D Gui one for an example, since it’s simpler to understand.
- Gail::GuiNG::Gui : the entire gui
  - Gail::GuiNG::Layer : layer of images
    - Gail::GuiNG::Image : image to display
So where does scissoring come into play? Scissoring affects rendering, so it makes sense its a node. Anything a child of that node is affected by the scissor. The only issues that comes up is the scissor node should be relative to its parents, but the scissor function is in absolute coordinates. Luckily, its not hard to get the absolute coordinates since its all a translation anyways.
So in our example, if we want to scissor the image, our graph changes to be like this:
- Gail::GuiNG::Gui : the entire gui
  - Gail::GuiNG::Layer : layer of images
    - Gail::GuiNG::ScissorNode : Anything under this is clipped to the bounding box of the ScissorNode
      - Gail::GuiNG::Image : image to display. Clipped.
So implementation details
First, had to add CapabilityScissor as a capability that Gail can turn on and off as needed. Two lines of code, and its in business. Next was the new node. Most of the hard work here was figuring out glScissor() (freaking straight forward) and defining the Gail::RendererNG interface for it (beginRestrictingDrawingToRect(Gail::Core::Rect), endRestrictingDrawing()). Now since scissoring is a node, you could have multiple scissor nodes in a tree that are children of each other. Therefore, it needs to be handle multiple scissoring so a stack was added similar to the matrix stack. After I added this, it was first testing time. I took Playground (since it was still setup with the particle demo) and changed a few lines. The rendering became:
void Application::render (void)
{
    m_renderer->beginRestrictingDrawingToRect(Gail::Core::Rect (200, 200, 400, 400));
    m_gui->render();
    m_renderer->endRestrictingDrawing();
}
This way, anything rendered would be restricted within that box. Very easy to tell if it works or not. And I got this.
Perfect. Now we need that node.
Gail::GuiNG::ScissorNode is going to be a standard GuiNG::Node with an overridden render. It really doesn’t need its own functions, since both position and size it inherits (which can give us the rectangle to scissor). So should be really straightforward. For future work, might even have a ‘restrict drawing to node boundary’ option kindof like UIKit, but for now its fine to maintain it manually for the few places that actually need it.
Wrote that class, tested via Playground again. And now can use it where I actually need it.

Gail updates : Particle System and GailResourceCompiler

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 :P ). 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