I’m writing a Linux program where I want to set the orientation of an object so it is mounted onto a surface (like a man standing on the ground) but the more I look at the problem it causes a headache.

I have the surface normal N (I verified it is correct by drawing a GL_LINE) and I use a function to create a quaternion Q from the three values of the normal, and store Q with the object that is to be mounted.

Later at render time I call glTranslatef to move the object and then call another function to extract axis and angle from Q and pass the result to glRotatef. However nothing seems to actually happen, the object is not rotated at all.

Is this actually the correct approach to calculate the quaternion from the surface normal? I’m pretty sure the quaternion functions itself work fine as they are from a certain online tutorial.

A quaternion is really just a rotation matrix. So think about what you’re rotating in this case.

I think you’re going to need to construct a basis using your surface normal and 2 other vectors. The other 2 vectors are totally arbitrary (so long as they’re mutually orthogonal) , so choose them to capture your object’s desired rotation around the normal.

Then once you have your basis and a position on the surface the OpenGL end if it is just plug’n’play.

“I use a function to create a quaternion Q from the three values of the normal”

I don’t think this is right.
You have the current orientation of the person, i.e. you know the vector pointing from their feet to head. You have the surface normal, which will be the new vector for the person (feet to head).

You need to build the quat from those 2 vectors:
i.e.
qaut axis = old_vector cross new_vector
quat ang = angle_between(old_vector, new_vector)

So, first translate the feet, then rotate the body using the quat.