Since Ambrose3D is meant to be a learning platform, here's a few ideas for experimentation and extension projects:
A usable (but not perfect) implementation might be to change the render loop to go through all objects twice. On first pass, render all solid objects, and on the second render all transparent objects.
Render a "skybox"
Basically, load two different scenes, and instead of clearing the framebuffer, render the 'sky scene'. Use the camera from the 'real scene', with translation set to zero. Remember to clear the depth buffer before rendering the real scene.
Control stuff interactively
Instead of just using canned animations, find an object by name using code and change its transformation matrix.
Render custom stuff
For example lens flares and particle systems. Place a dummy object in the scene, and find it by name in code. Don't render the dummy object, but use its transformation to know where to place your custom things.
Currently Ambrose3D doesn't include hierarchy data. This causes some limitations in its use; for example moving a animated walking figure from code may be difficult.
Optimize animation export format
The animation data, as it is now, is huge. A 4x4 matrix is stored per frame per object, regardless of whether the object is moving or not. Easiest way to shrink the scene sizes is to detect static objects and not export the animation for them. Further work would be to split the transformation to translation, scale and rotation and only saving what's needed.
Bring in the shaders
Instead of using the fixed pipeline, implement rendering using shaders.
Add shadow maps
Shadow maps can be (relatively) easily implemented. The basic idea is to render the whole scene from the light's viewpoint and use the resulting z-buffer as a projective texture. Needed changes include support for spot lights, a new render style that doesn't bother with textures, possibly the use of FBOs (framebuffer objects)..
Render to texture fun
Create a TV set in 3d, and then use render to texture trickery to place an image on it. This doesn't actually require any changes in Ambrose3D proper; you can find a texture by name and replace its contents easily.
As it is, Ambrose3d always renders all objects, whether they're seen or not. This limits the scene complexity. Consider different visibility optimizations.
Blender supports skinning. Export the related data and apply it.
Add collision detection, ray picking, ODE - all of the above, or something else completely.
With a little creativity, Ambrose3d can be used as is to make 3d games. With a few extensions it can be used to make even better games. =)