What? More Language skins?Posted: January 30, 2012
I once wrote some code for distributing GDI calls to multiple desktops in a classroom environment. It was pretty nifty. Just capture everything the app was doing, and send it out via multicast. Recipients received, and rendered locally. Likewise with keyboard and mouse, in both directions.
So, GDI is a programming interface that I’m familiar with. It’s ancient, and slowly but surely fading into the sunset, but there it is. At its core, it has everything that every other 2D based graphics API, even today, has. Basic primitives such as point, line, rect, arc, etc, including the ability to render a bitmap, and even rectangle gradients.
Ah, those were the good ol’ days. Some people still feel comfortable with making GDI calls. So, wouldn’t it be nice if the HeadsUp system could deal with that? Just a little language wrapper that makes things look and feel like GDI, while under the covers, it’s actually going to OpenGL.
GDI is a representation of an “Immediate Mode” API. That is, there’s no scene graph. You draw something, and then you move on. Keeping track of what’s been drawn is the concern of the application. Similarly, managing redrawing is the domain of the application as well. That’s all well and good. What’s the modern equivalent? Well, these days, there’s this <canvas> tag in “HTML 5”. If you look at that API, it is the moral equivalent of the 2D GDI calls of old. I know this because I just went through the spec, and wrote the HeadsUp equivalent of the CanvasRenderingContext2D interface. Pretty much everything there mapps to what I had implemented in my own Renderer class.
This is great, because lots of people want to program using this modern API so they can see their stuff in a browser. So, why not in HeadsUp? I don’t need no stinkin browser! Furthermore, since I’m sitting on top of OpenGL, which is implemented on pretty much every new visual device on the planet, I can port my code fairly easily, without having to rely on the implementation of a Web Browser. That has some benefits.
As HeadsUp got its start mimicking the Processing environment, that gives me a few language skins. Processing, HTML 5 Canvas, GDI. The way things are arranged, these language skins are just that, skins. They don’t really add any significant functionality on their own. They pretty much just wrap the underlying graphics system with pretty function calls that will be familiar to users of those other APIs. That’s kind of cool because by simply choosing your language skin, you create an environment for yourself that is familiar. Much lower learning curve.
This skin just started, but it won’t take long before it’s up and running.
As I was fiddling about with the graphics sub-system over the weekend, I found more ways to eliminate code. I have this PImage object, which represents an image/bitmap. At first, I had it tied to the opengl texture object. It was kind of funky, although it worked. I simply removed the connection to the gl texture object, and eliminated about 50 lines of code. I could do this because I added the DrawImage() call to the renderer, which it should be. That way, the PImage object doesn’t have to render itself (what if I’m not rendering to a GL context?), and everything is fine. I still have a separate texture object, and that’s great because I can render into that object, and use it for 3D texture mapping in the 3D modeling side of the world.
Similarly, I was struggling with the “Graphic” object. This is an object that has a frame, and can draw itself. It’s a good base to start creating “controls”, you know, things that respond to mouse and keyboard.
At first, I was designing for sub-classing. That is, lots of core routines, with extension points. Then I got to thinking. Do I really need MouseDown, MouseUp, MouseMove, or can I just get away with MouseActivity()?
Furthermore, perhaps I can just have a MouseCatcher attribute, and instead of sub-classing, the user can just specify a function they want to handle their mouse events. Again, elimination of code, reduction of overall API, making life easier for the programmer.
Additionally, this sets up a very nice situation whereby all interaction simply goes through asynchronouse queues, whether they are located on the machine, or sending across the internet…