Flixel Forums

development => iOS => Topic started by: tokyotron on Thu, May 10, 2012

Title: Canabalt's HUD class
Post by: tokyotron on Thu, May 10, 2012
Hello. I am trying to find out how the HUD class works. The HUD class is what draws the always increasing distance in Canabalt game to the upper right corner.
It uses a small "font" (hud.png) and finds out the correct texture coords in order for opengl to draw, I guess this class is made because of optimization, otherwise you'd use the text features from the engine (?)

Specifically what I cannot understand is:

Code: [Select]
//then digits
for (int i = 0; i < DIGITS; ++i) {
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-4] = (GLshort)(width-runningWidth);
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-3] = (GLshort)(hudTexture.size.height);
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-8] = (GLshort)(width-runningWidth);
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-7] = 0;
runningWidth += digitWidths[DIGITS-1-i];
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-12] = (GLshort)(width-runningWidth);
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-11] = (GLshort)(hudTexture.size.height);
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-16] = (GLshort)(width-runningWidth);
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-15] = 0;
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-2] = [FlxGLView convertToShort:(hudOffsets[digits[i]+1]/hudTexture.paddedSize.width)];
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-1] = [FlxGLView convertToShort:(hudTexture.size.height/hudTexture.paddedSize.height)];
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-6] = [FlxGLView convertToShort:(hudOffsets[digits[i]+1]/hudTexture.paddedSize.width)];
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-5] = [FlxGLView convertToShort:(0)];
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-10] = [FlxGLView convertToShort:(hudOffsets[digits[i]]/hudTexture.paddedSize.width)];
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-9] = [FlxGLView convertToShort:(hudTexture.size.height/hudTexture.paddedSize.height)];
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-14] = [FlxGLView convertToShort:(hudOffsets[digits[i]]/hudTexture.paddedSize.width)];
hudVerticesUVs[VERTEX_COUNT*4-(i+1)*16-13] = [FlxGLView convertToShort:(0)];

I can understand the right hand size values - these would be the origins in pairs x, then y, then next x,y and so on...
However the left hand side VERTEX_COUNT*4-(i+1)*16-4 etc... anyone got a good explanation of that?
Title: Re: Canabalt's HUD class
Post by: initials on Thu, May 10, 2012
It's great to see someone new posting here in the forums.

I'm not 100% sure what each line does.

I understand what vertices and UVs are from 3D packages, but I'm not sure if it applies to OpenGLes.

You could achieve the same effect with FlxText, but as you said, it was done this way for optimisation.
Title: Re: Canabalt's HUD class
Post by: tokyotron on Fri, May 11, 2012
Yes the vertices apply in 2D as well. You can comment out the last area hiding the blanks (0):

Code: [Select]
BOOL blank = YES;
for (int i = DIGITS-1; i >= 0; --i) {
if (digits[i] != 0) {
blank = NO;
if (blank) {
hudVerticesUVs[(DIGITS-i-1)*16+5] = hudVerticesUVs[(DIGITS-i-1)*16+1];
hudVerticesUVs[(DIGITS-i-1)*16+13] = hudVerticesUVs[(DIGITS-i-1)*16+9];
Then 6 digits will always be visible. The leftmost zeroes should be visible.
I guess it takes some study of OpenGL to know what stuff like (DIGITS-i-1)*16+1 means. I was watching one of those OpenGL lessons in the iTunes U app a while back. It explained some of this although I never went through all of it. Back to classroom...

Oh anyway I'm successfully using a similar class for my own display of another subset font. The downside of this method is that you can only use integer numbers (at least without rewriting some parts), and no commas dots, alphabet etc.
My problem is once again I can't use retina graphics with this without finding out how to draw that with opengl...

What I've noticed about Flixel so far is that it's not straightforward to use retina graphics out of the box - or I've missed something. This would indeed hinder most devs use of this engine. With native iOS apps you only really add @2x versions of your image files and that's it. It doesn't seem that easy with Flixel...
Title: Re: Canabalt's HUD class
Post by: goshki on Fri, May 11, 2012
UV are typically texture coordinates in 3D rendering (iOS Canabalt uses OpenGL renderer underneath), so I presume hudVerticesUVs is a buffer holding UV texture coordinates for every quad that is rendered within the HUD. This loop specifically seems to fill the buffer with texture coordinates for each quad that holds a specific digit from the score. So if your score is 1234 then this loop will run 4 times sequentially filling the buffer with UV coordinates corresponding to the hud.png font texture. First the quad corresponding to digit '1' will get UV coordinates of digit '1' in hud.png, then the second quad corresponding to digit '2' will get UV coordinates of digit '2' in hud.png, and so on.
Title: Re: Canabalt's HUD class
Post by: tokyotron on Tue, May 22, 2012
goshki yes you're on the right track. I finally got around to deal with this. Sure there are texture coords (called UV) but also triangle vertices. They are packed into the same array which is fed to OpenGL in bottom of HUD.m. It's set to draw triangle strips but afaik there is no optimization done thag would make use of the triangle strip way of reducing vertices. I learned all of this from that iTunes U lecture on OpenGL ES and some Q&A on the net.

I was able to write up my own class with similar way of drawing, that also supports retina sized gfx. The big aha for me was that you're only supposed to scale the size of the UV coords, not the triangle sizes. Should make sense after all. I was scaling the wrong stuff first and if something goes wrong there's normally just garbled or no output at all.