Thursday 2 December 2010

A meandering thought, like a molecule displaying Brownian motion.

So yeah, nice nerdy title for today, displaying a rambling non-coherent, but nonetheless logical thought pattern.

I've been pretty stressed out this week, organising lighting for my schools Christmas production thing. In reality, doing lighting is a lot less fun that it sounds, and this week week I've mostly been doing is emailing people to either get stuff of them, or to make sure they'll be there on the night.

Thanks to this, I've had relatively little time to relax, and work on stuff than I would have liked. However, I have made some progress on my game: "whatever-it-is-I'm-calling-it-this-week". Now, I've got the sensors working properly, so lights will now sense which objects they should cast shadows from.

Unfortunately, because of the disconnect between b2world coordinates and screen coordinates, the sensor for the mouse light doesn't work properly.

However, this should be simple to fix, and beyond that, everything else works fine, so its not really important.

Adios!

Sunday 14 November 2010

Linked lists, Managers and actors

Yesterday evening, after writing the erudite blog post about textures, lighting and what I'd been working on, I went and watched a show about the goodies with my dad. I took with me a pad, and sketched out a rough diagram of the relationships between actors, lights, physics bodies, and managers (for the lights and actors) in my game.

Today, I sat down and implemented it.

Instead of the mess I had yesterday, I now have a beautifully organised, manageable,  expandable system for controlling actors and lights. Writing the system also introduced me to the beauty of linked lists.

I used linked lists in each of the manager classes, for both actors, and for lights. The linked list was formed of either Actor or Light objects, with pointers to the next and previous objects in the list. This isn't an especially new idea, but I had a couple of main reasons for wanting to structure the managers like this:

1) Eaisily implementable, expandable storage.
I can hear you now screaming "adam, if you wanted expandable storage, why didnt you use the std::vector???", or, I would if anyone read this blog. Of course, I could have used the std::vector class, but I had one massive reason against it. Pointers. Each of the bodies in the physics engine stores a pointer to its Actor, each Actor stores a pointer to its Light and each Light stores a pointer to its actor. If I was to implement the managers storage as a vector then it would have meant a lot more work for me in the long run figuring out how to manage pointers to members of vectors, and I couldn't be bothered.  As is, the linked list system works very well, as well as being very easy to iterate through.

2) As a learning exercise in pointers.
Despite having programmed quite a lot in c++, I am a bit of a novice with pointers. Implementing the data as a linked list forced me to really get to grips with pointers, manipulating them, and initialising them with new.

Having finished the core of the Actor, Actor_manager, Light and Light_manager classes, I can now begin to expand on them, and to implement further functionality, like shadows.

I still have two main hurdles to jump before properly getting shadows working:
1) Sensor shapes for the lights.
Ideally I would like to have a Box2d shape associated with the light, so that I can test intersection with bodies in the world, and thus whether I need to draw shadows for them.
2) Contact callbacks.
Instead of testing intersections manually, Box2d allows the programmer to define a contact callback class, which will call functions when two fixtures (wrappers for shapes) intersect. Once I have this up and running, I can configure it so that shadows will be drawn for fixtures when they intersect with shapes.

So, onwards and upwards!

Saturday 13 November 2010

Coding, Coding, Coding...

Yay! Coding!

I've been getting back into coding this week, after a bit of a hiatus. I've thrown myself into a new project, a kind of spiritual successor to kreis, and so far its going well.

I've got some lighting sorted out, which so far is much prettier looking, and more realistic than what kreis had.
Basically, this time, instead of assuming everything is "lit" from the off, then drawing in shadows to darken bits, I'm simply drawing a black (unlit) texture over everything and "cutting out" bits of it which are lit.
The process is slightly more complicated than that however, and goes a bit like this:

1) Render the white light to a texture:
This is relatively simple, you simply get a gradiated circle, with 100% alpha at the centre, and 0% at the edges:
void draw_light(float x, float y, float rad, float intensity)
{
float nx,ny;
glBegin(GL_TRIANGLE_FAN);
glColor4f(1,1,1,intensity);
glVertex2f(x,y);
glColor4f(1,1,1,0);
for (float ang = (2*pi)+(pi/24);ang>=0;ang-=pi/24)
{
nx = (rad*sin(ang))+x;
ny = (rad*cos(ang))+y;
glVertex2f(nx,ny);
}
glEnd();
}

2) Composite the lights onto one render texture.
Again, this is pretty simple. You simply draw the light texture of each of the lights in turn onto one master texture:
void predraw_light(GLuint tex, int x_l, int y_t, int x_r, int y_b)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glColor4f(1,1,1,1);
glBegin( GL_QUADS );
glTexCoord2d(0.0,0.0); glVertex2d(x_l,y_t);
glTexCoord2d(1.0,0.0); glVertex2d(x_r,y_t);
glTexCoord2d(1.0,1.0); glVertex2d(x_r,y_b);
glTexCoord2d(0.0,1.0); glVertex2d(x_l,y_b);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}
Where "tex" is the lights texture, and "x_l, x_r, y_t, y_b" are the right, left, top and bottom positions of the texture.

3) Render the master texture onto the scene, inverting the alpha values.
This is when it starts to get trickier. We need to render all the lights to the scene, but at the moment, we just have a collection of white blobs on a transparent black texture. What we do is draw the texture, whilst REVERSING the alpha. This means that the alpha of every pixel becomes 1-its alpha. So, during reversing, all the transparent black becomes opaque (unlit) and our lights become transparent, and therefore lit.
void draw_light_tex(GLuint tex, int x_l, int y_t, int x_r, int y_b)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glColor4f(1,1,1,1);
glBlendFunc( GL_SRC_ALPHA, GL_SRC_ALPHA );
glBegin( GL_QUADS );
glTexCoord2d(0.0,0.0); glVertex2d(x_l,y_t);
glTexCoord2d(1.0,0.0); glVertex2d(x_r,y_t);
glTexCoord2d(1.0,1.0); glVertex2d(x_r,y_b);
glTexCoord2d(0.0,1.0); glVertex2d(x_l,y_b);
glEnd();
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
}
Tex, x_l, x_r... all stand for the same things. Note the opengl blend functions:
glBlendFunc( GL_SRC_ALPHA, GL_SRC_ALPHA );
...
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
The first is the magic of this system. It reverses how the alpha is normally drawn (ie, the second function) and thus allows all our lights to work nicely.

Once you combine this with some nice physics (another thing I've been working on, getting Box2d integrated) you get lovely effects like this:

This is still VERY much wip, and I'm planning to tidy up the code a bit this weekend and package up some of the lighting stuff into its own class.

After that, I've got a couple of major targets which I want to meet:
1) Get shadows working.
So far, I've got some nice lights going, and darkness where there isn't light. However, what I dont have is objects casting shadows. I've done most of the legwork for this before (with kreis) so this time I just need to get it sitting nicely with the texture based lights.

2) Get some actor classes working.
I'll need an actor class eventually, so I may as well get one going now to tie together Box2d bodies, and the lights.

Apart from that, things are going pretty well! Box2d was a bit of an effort to get going, but only because of working out which projects to compile, and integrating it nicely.

Also, if anybody wants the full code, or the code for the texture generation and drawing, just email me at the address given on my website (harries {dot} adam {at} googlemail {dot} com), and I'll get back to you asap with it...

Sunday 17 October 2010

In praise of Internet Explorer

I never thought I'd say this.

I like Internet Explorer.

Help me.

Well, I say I like Internet Explorer. In truth, I like the beta version of Internet Explorer 9, and for (in my mind) one reason: Its not Internet Explorer. Internet Explorer 9 is a fresh, invigorated, fast browser, with a usable UI and is more or less standards compliant. For usability alone it far outpaces Firefox and Safari, although it still lags a little behind Chrome for me.

IE now passes the first 2 Acid tests, as well as performing better than Chrome on the third. For me this is a major milestone, as it shows that Microsoft, or at least the team behind IE are actually trying to pay attention to standards.

IE 9 is just the latest in a range of what seems to be departures from the norm for Microsoft. This change in culture; from bloat, non-compliance and ugliness to the status quo, looks like the future path for Microsoft. Gone are the failures of Windows Mobile 6, Vista and IE 7, and coming are the Triumphs of Windows 7, IE 9 and Windows Phone 7.

I wonder if this is a complete turn around for Microsoft, I for one hope it is.

Tuesday 12 October 2010

ASCII Tower Defence

I've mocked up a little something I might start working on at some point:


I'm calling it ASCII Tower Defence, and It seems like quite a nice little project I could work on on the side of all the school-work and revision I'm going to be doing over the next few months.

Although it doesn't really look like much in the mock-up, it should be a lot more appealing when moving, and when the design is a bit more final.

As a little aside about the mock-up: I designed it in the wonderful ASCII graphics programme ASCII Paint written by TIGSource forum member Melly. Try it sometime, Its great!

Monday 11 October 2010

Windows Phone 7

Wow. Windows phone doesnt look half bad!



I mean, that looks pretty good. It has a pretty nice interface, and it all seems pretty smooth. Everything seems easily accessible, and all the features seem really well integrated. The only worry I have is that the "bloatware" that comes with it (xbox live, netflix and all that) wont be uninstallable. I, and most people really don't need all that stuff, and I suspect that this will be the main problem with the os.

So yeah, I'm looking foward to it, but unless its VERY customisable, then I don't think I'm going to for it.

Saturday 9 October 2010

Well now

I'm close to finishing a redesign of my website now. The old design, frankly, was a bit 90's; black background, white text. The only things that really redeemed it was the lack of green, and the html5 header...

In any case, the whole things undergone a complete redesign, from the ground up. The background is now white/very light grey, with dark grey text, and the whole thing is centred. I've also used a couple of new technologies whilst redesigning it and they both proved pretty simple to use.

First up is JQuery. This is a relatively small/big (depending upon what you judge it against) Javascript library with a LOT of functionality. It provides animation effects for the DOM of the page, as well as easy wrappers for AJAX calls, which have proved to be especially useful. I've redesigned the way content is displayed as well; instead of each link going to its own page, an JQuery now loads each content page into the main one using AJAX, then provides a nice animation to slide it in.

The second technology isint really a technology as such; more a way of simplifying columns in a webpage. Its called "The Square Grid" and it provides an easy interface for creating columns on a page, in multiples of 14 pixels.

Together theese two toolkits have saved me a LOT of work. The homepage has gone from 349 lines of HTML and javascript to just 75.

As for the rest of the site, I plan to slowly migrate the rest of the content across over the coming weeks, and hopefully get some new stuff up as well...