problem porting GLU

I’m having a problem porting gluPerspective to java where the screen turns up at half the size ???..
I’m obviously doing something wrong, could someone please take a look?

C code from Mesa:


static void
frustum(GLdouble left, GLdouble right,
        GLdouble bottom, GLdouble top, 
        GLdouble nearval, GLdouble farval)
{
   GLdouble x, y, a, b, c, d;
   GLdouble m[16];

   x = (2.0 * nearval) / (right - left);
   y = (2.0 * nearval) / (top - bottom);
   a = (right + left) / (right - left);
   b = (top + bottom) / (top - bottom);
   c = -(farval + nearval) / ( farval - nearval);
   d = -(2.0 * farval * nearval) / (farval - nearval);

#define M(row,col)  m[col*4+row]
   M(0,0) = x;     M(0,1) = 0.0F;  M(0,2) = a;      M(0,3) = 0.0F;
   M(1,0) = 0.0F;  M(1,1) = y;     M(1,2) = b;      M(1,3) = 0.0F;
   M(2,0) = 0.0F;  M(2,1) = 0.0F;  M(2,2) = c;      M(2,3) = d;
   M(3,0) = 0.0F;  M(3,1) = 0.0F;  M(3,2) = -1.0F;  M(3,3) = 0.0F;
#undef M

   glMultMatrixd(m);
}


void GLAPIENTRY
gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
{
   GLdouble xmin, xmax, ymin, ymax;

   ymax = zNear * tan(fovy * M_PI / 360.0);
   ymin = -ymax;
   xmin = ymin * aspect;
   xmax = ymax * aspect;

   /* don't call glFrustum() because of error semantics (covglu) */
   frustum(xmin, xmax, ymin, ymax, zNear, zFar);
}

… and the ported java code:


      public static void gluPerspective(
            float fovy,
            float aspect,
            float zNear,
            float zFar) {
                  
            float xmin, xmax, ymin, ymax;

            ymax = zNear * (float) Math.tan(fovy * PI / 360.0f);
            ymin = -ymax;
            xmin = ymin * aspect;
            xmax = ymax * aspect;

            /* don't call glFrustum() because of error semantics (covglu) */
            frustum(xmin, xmax, ymin, ymax, zNear, zFar);
      }
      
      /**
       * Method frustum.
       * @param xmin
       * @param xmax
       * @param ymin
       * @param ymax
       * @param zNear
       * @param zFar
       */
      private static void frustum(
            float left,
            float right,
            float bottom,
            float top,
            float nearval,
            float farval) {

            float x, y, a, b, c, d;
            FloatBuffer m = tmpFloatBuffer16;
            m.rewind();

            x = (2.0f * nearval) / (right - left);
            y = (2.0f * nearval) / (top - bottom);
            a = (right + left) / (right - left);
            b = (top + bottom) / (top - bottom);
            c = - (farval + nearval) / (farval - nearval);
            d = - (2.0f * farval * nearval) / (farval - nearval);
            
            m.put(x);
            m.put(0.0f);
            m.put(a);
            m.put(0.0f);
            m.put(0.0f);
            m.put(y);
            m.put(b);
            m.put(0.0f);
            m.put(0.0f);
            m.put(0.0f);
            m.put(c);
            m.put(d);
            m.put(0.0f);
            m.put(0.0f);
            m.put(-1.0f);
            m.put(0.0f);
            m.flip();
            GL.glMultMatrixf(m);

      }

basically I’m suspecting 2 things:

  1. I’m doing something wrong with the FloatBuffer

  2. I replaced GL.glMultMatrixd(m) with GL.glMultMatrixf(m) (is there a difference I should know here except that the latter takes floats instead of doubles?)

  3. I made some other stupid mistake (okay, so that’s 3 things ;D)

oh, another thing, when I call glFrustum() (of which the comment says I shouldn’t) instead of the ported frustum(), it seems to work okay… :-/

Just a guess, but maybe FloatBuffer is row major?

m.put(x);
m.put(0.0f);
m.put(a);
m.put(0.0f);
m.put(0.0f);
m.put(y);
m.put(b);
m.put(0.0f);
m.put(0.0f);
m.put(0.0f);
m.put©;
m.put(d);
m.put(0.0f);
m.put(0.0f);
m.put(-1.0f);
m.put(0.0f);
m.flip();

would then be:

m.put(x);
m.put(0);
m.put(0);
m.put(0);
m.put(0);
m.put(y);

etc.

Worth trying I guess.

Hey I think that was it!

(although

… I think was not quite right ::slight_smile:

Thanks!