You need a glFinish() call to tell the driver to do the actual drawing. The glReadPixels() call is causing things to work because it forces the rendering to happen -- you've told the driver that you want to read the pixels back, so it pauses until rendering is complete.