sure … if you do not trust gluPerspective …
i use rowmajor matrices, unlike opengl default.
the matrix class i use is basically just a double[4][4], double[row][column].
this is how i setup orthogonal projections :
public static void setOrtho(double left, double right,
double top, double bottom,
double near, double far,
Matrix m)
{
m.set(2.0 / (right - left), 0, 0, (left + right) / (right - left), // row 0
0, 2.0 / (top - bottom), 0, (top + bottom) / (top - bottom), // row 1
0, 0, -2.0 / (far - near), (far + near) / (far - near), // row 2
0, 0, 0, 1); // row 3
}
i feed the same values i use with glViewport but in this order : 0.0, width, 0.0, height, -1.0 (near), 1.0 (far).
for perspective projections i use :
// fovr = y-fov in radians, vertical.
// aspect = viewport (float)width/height
// znear should be > 0.0
public static void setPerspective(double fovr, double aspect, double near, double far, Matrix m)
{
final double y = near*StrictMath.tan(fovr*0.5);
final double x = aspect*y;
setFrustum(-x,x,y,-y,near,far,m);
}
setting the frustum :
public static void setFrustum(double left, double right,
double top, double bottom,
double near,double far,
Matrix m)
{
m.set(( 2.0*near )/( right - left ),0,( left + right )/( right - left ),0, // row 0
0,( 2.0*near )/( top - bottom ),( top + bottom )/( top - bottom ),0, // row 1
0,0,-( near + far )/( far - near ),( -2*near*far )/( far - near ), // row 2
0,0,-1,0); // row 3
}
now, to move this to opengl i transpose the matrices and copy them … in one go :
public static void copy(Matrix m, FloatBuffer buffer)
{
buffer.put((float)m.matrix[0][0]);
buffer.put((float)m.matrix[1][0]);
buffer.put((float)m.matrix[2][0]);
buffer.put((float)m.matrix[3][0]);
buffer.put((float)m.matrix[0][1]);
buffer.put((float)m.matrix[1][1]);
buffer.put((float)m.matrix[2][1]);
buffer.put((float)m.matrix[3][1]);
buffer.put((float)m.matrix[0][2]);
buffer.put((float)m.matrix[1][2]);
buffer.put((float)m.matrix[2][2]);
buffer.put((float)m.matrix[3][2]);
buffer.put((float)m.matrix[0][3]);
buffer.put((float)m.matrix[1][3]);
buffer.put((float)m.matrix[2][3]);
buffer.put((float)m.matrix[3][3]);
buffer.rewind();
}
that buffer was a FloatBuffer of size 16 (one could use a DoubleBuffer too but i do not) and is going to opengl by :
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadMatrix(projection);
//GL11.glMatrixMode(GL11.GL_MODELVIEW);
//GL11.glLoadMatrix(modelview)
or if you use direct state :
EXTDirectStateAccess.glMatrixLoadEXT(GL11.GL_PROJECTION,projection);
//EXTDirectStateAccess.glMatrixLoadEXT(GL11.GL_MODELVIEW,modelview);
edit the modern way is write all values into a UBO-mapped-buffer, not use loadMatrix() and have all shaders source matrices from that UBO’s, this on the other hand should work with fixed-pipeline opengl 1.1.
next would be … look-at matrix into modelview 
o/