I don't know much about OpenGL, so I can't comment on the method you're currently using. Direct3D9 doesn't support any sort of readback of a depthstencil buffer, but there are vendor-specific "extensions" that let you sample them directly. Nvidia has RAWZ for their 6 and 7-series, and INTZ for 8-series and above. You can read about those
here. ATI has their own extensions that are similar, which you can read about
here. I would imagine that these are also exposed in OpenGL as extensions.
D3D10/D3D11 natively support sampling a depthstencil buffer, if you create the buffer using a TYPELESS format and create an appropriate shader resource view.