Archive for the ‘C++’ Category

A Custom MFC Control to Display Guitar Chords

Thursday, May 1st, 2008

Recently, I’ve tasked myself with learning a bit more about custom MFC controls. For a hands on project, I chose to create a custom MFC control for displaying guitar chords. The basic steps of creating custom MFC controls are this:

1. Create a class for your control, and inherit from a control similar to what you want to make. If nothing is similar, inherit from CStatic.
2. Override the OnPaint function to do your custom drawing.

Everything else is just MFC, although you have to be careful about redrawing. If you’re constantly redrawing, you could get a bit of flicker.

To show your control in a dialog, you have do the following:

1. Add a Custom Control to the dialog.
2. Set the “Class” property of the custom control to the name of your custom class.
3. Make sure you register your custom class using the AfxRegisterClass() function. An example of this is in ChordDisplay.cpp.

In making this control, I learned something very important. If you can draw something with the CDC drawing functions, then do it that way. Bitmaps are easy enough to blit onto the Device Context, but if you need transparency or any fancy stuff, you’re gonna be spending a good bit of time figuring it out (or searching for code that does what you want). I used 100% CDC drawing functions for my guitar control.

Here’s a screenshot:


And, as always, my source code is here. The control can be told to draw a chord by filling a struct with some data. See ChordDatabase.cpp for more how to do that. An expansion of this would be to get a full database of chords that could be loaded from an xml file. I’ve only got a few chords here because it’s just a sample to show the control.

Playing with OpenGL – Mouse Interaction

Tuesday, April 8th, 2008

I haven’t worked with OpenGL in a long time. The last time I wrote anything using OpenGL was in college when I took a class on it. Well, I recently bought the OpenGL SuperBible, and from reading the first bit of it, it sounds like some interesting stuff has developed. There’s now this OpenGL shading language? I don’t remember anything about that, at least. There’s also a trimmed down version of OpenGL for mobile devices too, and that’s really cool.

Anyways, I remember in the class I never ended up with an OpenGL app that would allow for proper mouse rotation of a 3d object. Mouse interaction was never really assigned in that class, and I remember spending a lot of my time trying to figure out the math the teacher was having us do instead.

So I thought now that I’m jumping back into OpenGL related stuff, my first project should be revisiting that very simple, yet often overlooked bit of code that handles mouse interaction. I reviewed some of the code I had written in the class, and it had the basic idea right, but not enough thought put into it.

So I started fresh. I’ve learned some interesting things:

ROTATION
If you rotate the camera about your scene, then you won’t be able to spin a translated object in place (what you get is a big swing around the object, rather than watching the object spin). So it seems one wants to rotate the the whole scene before drawing it. This is, of course, to mimic what is seen in 3ds Max.

TRANSLATION
This is probably the easiest part of the math involved. Since translation from this projects point of view is moving about the screen plane, then we only have to move in two dimensions (The third dimension is zoom). All that needs be done is move our eyeball AND the point we’re looking at in parallel.

ZOOM
This one is a bit tricky. The effect we want is to move our eye closer to the point we’re looking at. This point is not necessarily the object. Imagine you have an eye location E and a focus point F. Moving our eye towards F involves a little bit of vector math. If we create a vector from E to F, we are half way there. To do that, subtract F from E in each dimension:

Vx = Fx – Ex;
Vy = Fy – Ey;
Vz = Fz – Ez;

Now we simple move our Eye point along this vector. Multiple the vector by some scaling factor and add

newEye = E + V*scale;

or

newEyex = Ex + Vx*scale;
newEyey = Ey + Vy*scale;
newEyez = Ez + Vz*scale;

When you think about the math, it makes sense. When you look at the math, it’s easy to get confused.

At any rate, here’s my program. I’ve tried to put it together so you don’t need to modify your paths to get it to build (the glut library is included).