How exactly are you calculating ry? I don't really see anything wrong with your math so I'm not quite sure what is causing the 45 degree discrepancy, so it may be that. I use this quick method to calculate the direction of my camera.

[source lang="cpp"] horizontalAngle += mouseSpeed * float(ScreenWidth / 2 - xpos ); verticalAngle += mouseSpeed * float(ScreenHeight / 2 - ypos ); [/source]

Where mouseSpeed is some small floating point number(something like .005f) and xpos and ypos is your mouses x and y coordinates (Note: In this example my X axis is right to left and my Y axis is up and down. Judging from your vel.x and vel.z calculations your Z axis appears to be up and down while your Y is right to left). Then to calculate direction just use your found angles to convert from spherical coordinates to Cartesian as you do.

[source lang="cpp"]vec3 direction( cos(verticalAngle) * sin(horizontalAngle), // X-Axis left to right sin(verticalAngle), // Y-Axis up and down cos(verticalAngle) * cos(horizontalAngle) // Z-Axis in and out of screen);[/source]

You can restrict any look directions as you see fit.

Then when moving the camera you can just use position += direction*deltatime*speed and position -= direction*deltatime*speed or something similar to move forward and backward. So when you make your view matrix you can just add your direction vector to your position vector to find your "look at" vector. I hope that helped!