2014-09-06 3 views
2

J'utilise Java et OpenGL (LWJGL) pour configurer certaines matrices, je ne voulais pas utiliser les méthodes intégrées car je veux aussi que cela fonctionne sur Android et donc en utilisant les classes Matrix de LWJGL ne serait pas Être approprié. Actuellement, je mets en place une vue en perspective, en utilisant un fov de 70, znear 0.1, zfar 1000. Rotation en utilisant la configuration actuelle seulement des résultats étranges, ne tourne pas correctement, et les objets sont étrangement échelonnés et souvent disparaissent.OpenGL 2.0 Matrices ne fonctionnant pas

Voici la classe Matrix4D:

public class Matrix4D { 

/* The values within this matrix */ 
public float[] values; 

/* The default constructor */ 
public Matrix4D() { 
    //Create the values 
    this.values = new float[16]; 
} 

/* The constructor with the values given */ 
public Matrix4D(float[] values) { 
    //Create the values 
    this.values = values; 
} 

/* The constructor with the values given */ 
public Matrix4D(float[][] values) { 
    //Load the values 
    load(values); 
} 

/* The method used to set the values given a 2 dimensional array */ 
public void load(float[][] values) { 
    this.values = new float[] { 
      values[0][0], values[0][1], values[0][2], values[0][3], 
      values[1][0], values[1][1], values[1][2], values[1][3], 
      values[2][0], values[2][1], values[2][2], values[2][3], 
      values[3][0], values[3][1], values[3][2], values[3][3] 
    }; 
} 

/* The method used to get a value using the coordinate within this matrix */ 
public float get(int x, int y) { 
    //Get the position 
    int position = x + (y * 4); 
    //Return the value 
    return this.values[position]; 
} 

/* The method used to return a string representation of this matrix */ 
public String toString() { 
    //Return the string 
    return "[ " + this.values[0] + " " + this.values[1] + " " + + this.values[2] + " " + + this.values[3] + " ]" + "\n" + 
      "[ " + this.values[4] + " " + this.values[5] + " " + + this.values[6] + " " + + this.values[7] + " ]" + "\n" + 
      "[ " + this.values[8] + " " + this.values[9] + " " + + this.values[10] + " " + + this.values[11] + " ]" + "\n" + 
      "[ " + this.values[12] + " " + this.values[13] + " " + + this.values[14] + " " + + this.values[15] + " ]"; 
} 

/* The method used to get the values */ 
public float[] getValues() { return this.values; } 

/* The method used to get the values in a 2D array */ 
public float[][] getValues2DArray() { 
    //The array 
    float[][] array = new float[4][4]; 
    //Go through each value 
    int column = 0; 
    int row = 0; 
    while (column * row < array.length) { 
     row ++; 
     if (row >= 4) { 
      column++; 
      row = 0; 
     } 
     array[column][row] = this.values[column * row]; 
    } 
    //Return the array 
    return array; 
} 

} 

Voici la classe Matrix (Utilisé pour la configuration et effectuer des calculs sur une matrice):

public class Matrix { 

/* The different matrices */ 
public static Matrix4D modelMatrix = new Matrix4D(); 
public static Matrix4D viewMatrix = new Matrix4D(); 
public static Matrix4D projectionMatrix = new Matrix4D(); 
public static Matrix4D modelViewProjectionMatrix = new Matrix4D(); 

/* The static method used to load an identity matrix */ 
public static void loadIdentity(Matrix4D matrix) { 
    //Load the identity matrix 
    matrix.load(new float[][] { 
      new float[] { 1, 0, 0, 0 }, 
      new float[] { 0, 1, 0, 0 }, 
      new float[] { 0, 0, 1, 0 }, 
      new float[] { 0, 0, 0, 1 }, 
    }); 
} 

/* The static method used to add two matrices together */ 
public static Matrix4D add(Matrix4D matrixA, Matrix4D matrixB) { 
    //Create a new matrix 
    Matrix4D matrix = new Matrix4D(); 
    //Go through each value 
    for (int a = 0; a < matrix.values.length; a++) 
     //Assign the current value 
     matrix.values[a] = matrixA.values[a] + matrixB.values[a]; 
    //Return the matrix 
    return matrix; 
} 

/* The static method used to subtract a matrix (B) from another (A) */ 
public static Matrix4D subtract(Matrix4D matrixA, Matrix4D matrixB) { 
    //Create a new matrix 
    Matrix4D matrix = new Matrix4D(); 
    //Go through each value 
    for (int a = 0; a < matrix.values.length; a++) 
     //Assign the current value 
     matrix.values[a] = matrixB.values[a] - matrixA.values[a]; 
    //Return the matrix 
    return matrix; 
} 

/* The static method used to multiply two matrices together */ 
public static Matrix4D multiply(Matrix4D matrixA, Matrix4D matrixB) { 
    //Create a new matrix 
    Matrix4D matrix = new Matrix4D(new float[][] { 
      new float[] { 
        (matrixA.values[0] * matrixB.values[0]) + (matrixA.values[1] * matrixB.values[4]) + (matrixA.values[2] * matrixB.values[8]) + (matrixA.values[3] * matrixB.values[12]), 
        (matrixA.values[0] * matrixB.values[1]) + (matrixA.values[1] * matrixB.values[5]) + (matrixA.values[2] * matrixB.values[9]) + (matrixA.values[3] * matrixB.values[13]), 
        (matrixA.values[0] * matrixB.values[2]) + (matrixA.values[1] * matrixB.values[6]) + (matrixA.values[2] * matrixB.values[10]) + (matrixA.values[3] * matrixB.values[14]), 
        (matrixA.values[0] * matrixB.values[3]) + (matrixA.values[1] * matrixB.values[7]) + (matrixA.values[2] * matrixB.values[11]) + (matrixA.values[3] * matrixB.values[15]) 
      }, 
      new float[] { 
        (matrixA.values[4] * matrixB.values[0]) + (matrixA.values[5] * matrixB.values[4]) + (matrixA.values[6] * matrixB.values[8]) + (matrixA.values[7] * matrixB.values[12]), 
        (matrixA.values[4] * matrixB.values[1]) + (matrixA.values[5] * matrixB.values[5]) + (matrixA.values[6] * matrixB.values[9]) + (matrixA.values[7] * matrixB.values[13]), 
        (matrixA.values[4] * matrixB.values[2]) + (matrixA.values[5] * matrixB.values[6]) + (matrixA.values[6] * matrixB.values[10]) + (matrixA.values[7] * matrixB.values[14]), 
        (matrixA.values[4] * matrixB.values[3]) + (matrixA.values[5] * matrixB.values[7]) + (matrixA.values[6] * matrixB.values[11]) + (matrixA.values[7] * matrixB.values[15]) 
      }, 
      new float[] { 
        (matrixA.values[8] * matrixB.values[0]) + (matrixA.values[9] * matrixB.values[4]) + (matrixA.values[10] * matrixB.values[8]) + (matrixA.values[11] * matrixB.values[12]), 
        (matrixA.values[8] * matrixB.values[1]) + (matrixA.values[9] * matrixB.values[5]) + (matrixA.values[10] * matrixB.values[9]) + (matrixA.values[11] * matrixB.values[13]), 
        (matrixA.values[8] * matrixB.values[2]) + (matrixA.values[9] * matrixB.values[6]) + (matrixA.values[10] * matrixB.values[10]) + (matrixA.values[11] * matrixB.values[14]), 
        (matrixA.values[8] * matrixB.values[3]) + (matrixA.values[9] * matrixB.values[7]) + (matrixA.values[10] * matrixB.values[11]) + (matrixA.values[11] * matrixB.values[15]) 
      }, 
      new float[] { 
        (matrixA.values[12] * matrixB.values[0]) + (matrixA.values[13] * matrixB.values[4]) + (matrixA.values[14] * matrixB.values[8]) + (matrixA.values[15] * matrixB.values[12]), 
        (matrixA.values[12] * matrixB.values[1]) + (matrixA.values[13] * matrixB.values[5]) + (matrixA.values[14] * matrixB.values[9]) + (matrixA.values[15] * matrixB.values[13]), 
        (matrixA.values[12] * matrixB.values[2]) + (matrixA.values[13] * matrixB.values[6]) + (matrixA.values[14] * matrixB.values[10]) + (matrixA.values[15] * matrixB.values[14]), 
        (matrixA.values[12] * matrixB.values[3]) + (matrixA.values[13] * matrixB.values[7]) + (matrixA.values[14] * matrixB.values[11]) + (matrixA.values[15] * matrixB.values[15]) 
      } 
    }); 
    //Return the matrix 
    return matrix; 
} 

/* The static method used to transpose a matrix */ 
public static Matrix4D transpose(Matrix4D matrix) { 
    //Get the values from the matrix 
    float[][] values = matrix.getValues2DArray(); 
    //The new values 
    float[][] newValues = new float[4][4]; 
    //Go through the array 
    for (int y = 0; y < values.length; y++) { 
     for (int x = 0; x < values[y].length; x++) { 
      //Assign the new value 
      newValues[x][y] = values[y][x]; 
     } 
    } 
    //Return the matrix 
    return new Matrix4D(newValues); 
} 

/* The static method used to translate a matrix */ 
public static Matrix4D translate(Matrix4D matrix, Vector3D vector) { 
    //The transform matrix 
    Matrix4D transform = new Matrix4D(new float[][] { 
      new float[] { 0, 0, 0, vector.x }, 
      new float[] { 0, 0, 0, vector.y }, 
      new float[] { 0, 0, 0, vector.z }, 
      new float[] { 0, 0, 0, 0 }, 
    }); 
    //Add onto the matrix and return the result 
    return add(matrix, transform); 
} 

/* The static method used to rotate a matrix */ 
public static Matrix4D rotate(Matrix4D matrix, float angle, int x, int y, int z) { 
    //The transform matrix 
    Matrix4D transform = new Matrix4D(); 
    //Calculate the values needed 
    float cos = (float) Math.cos(angle); 
    float sin = (float) Math.sin(angle); 
    //Check the x y and z values 
    if (x == 1) { 
     transform.load(new float[][] { 
       new float[] { 0, 0, 0, 0 }, 
       new float[] { 0, cos, -sin, 0 }, 
       new float[] { 0, sin, cos, 0 }, 
       new float[] { 0, 0, 0, 0 }, 
     }); 
    } else if (y == 1) { 
     transform.load(new float[][] { 
       new float[] { cos, 0, sin, 0 }, 
       new float[] { 0, 0, 0, 0 }, 
       new float[] { -sin, 0, cos, 0 }, 
       new float[] { 0, 0, 0, 0 }, 
     }); 
    } else if (z == 1) { 
     transform.load(new float[][] { 
       new float[] { cos, -sin, 0, 0 }, 
       new float[] { sin, cos, 0, 0 }, 
       new float[] { 0, 0, 0, 0 }, 
       new float[] { 0, 0, 0, 0 }, 
     }); 
    } 
    //Add onto the matrix and return the result 
    return add(matrix, transform); 
} 

/* The static method used to scale a matrix */ 
public static Matrix4D scale(Matrix4D matrix, Vector3D vector) { 
    //The transform matrix 
    Matrix4D transform = new Matrix4D(new float[][] { 
      new float[] { vector.x, 0, 0, 0 }, 
      new float[] { 0, vector.y, 0, 0 }, 
      new float[] { 0, 0, vector.z, 0 }, 
      new float[] { 0, 0, 0, 0 }, 
    }); 
    //Add onto the matrix and return the result 
    return add(matrix, transform); 
} 

/* The static method used to return an orthographic projection matrix */ 
public static Matrix4D ortho(float left, float right, float top, float bottom, float zfar, float znear) { 
    return new Matrix4D(new float[][] { 
      new float[] { 2/(right - left), 0, 0, -((right + left)/(right - left)) }, 
      new float[] { 0, 2/(top - bottom), 0, -((top + bottom)/(top - bottom)) }, 
      new float[] { 0, 0, -2/(zfar - znear), -((zfar + znear)/(zfar - znear)) }, 
      new float[] { 0, 0, 0, 1 }, 
    }); 
} 

/* The static method used to return a perspective projection matrix */ 
public static Matrix4D perspective(float fov, float aspect, float zNear, float zFar) { 
    float f = (float) (1f/Math.tan(fov/2f)); 
    return new Matrix4D(new float[][] { 
      new float[] { f/aspect, 0, 0, 0 }, 
      new float[] { 0, f, 0, 0 }, 
      new float[] { 0, 0, (zFar + zNear)/(zFar - zNear), (2 * zFar * zNear)/(zNear - zFar) }, 
      new float[] { 0, 0, -1, 0 }, 
    }); 
} 

} 

Enfin, la méthode utilisée pour la configuration du point de vue/projection orthographique est:

/* The static method to setup an orthographic view given the width, height 
* znear and zfar values */ 
public static void setupOrtho(float width, float height, float znear , float zfar) { 
    Matrix.loadIdentity(Matrix.modelMatrix); 
    Matrix.loadIdentity(Matrix.viewMatrix); 
    Matrix.projectionMatrix = Matrix.ortho(0, width, 0, height, znear, zfar); 
} 

/* The static method used to setup a perspective view given the 
* fov, z near and z far value */ 
public static void setupPerspective(float fov, float zNear, float zFar) { 
    setupPerspective(fov, (float) (Settings.Window.Width/Settings.Window.Height), zNear, zFar); 
} 

/* The static method used to setup a perspective view given the 
* fov, aspect ratio, z near and z far values */ 
public static void setupPerspective(float fov, float aspect, float zNear, float zFar) { 
    Matrix.loadIdentity(Matrix.modelMatrix); 
    Matrix.loadIdentity(Matrix.viewMatrix); 
    Matrix.projectionMatrix = Matrix.perspective(fov, aspect, zNear, zFar); 
} 

Pour rendre tout cela et passer les matrices à le shader que j'utilise

//Multiply the matrices together 
    Matrix4D modelViewMatrix = Matrix.multiply(Matrix.modelMatrix, Matrix.viewMatrix); 
    Matrix.modelViewProjectionMatrix = (Matrix.multiply(modelViewMatrix, Matrix.projectionMatrix)); 
    System.out.println(Matrix.modelViewProjectionMatrix.toString() + "\n"); 

Et dans le shader je multiplie la position actuelle des sommets par la projection de la vue du modèle marix.

Voici une image de ce à quoi il ressemble actuellement.

What the output currently looks like

Répondre

1

Vous semblez être multiplier vos matrices dans le mauvais ordre. Lors de la combinaison des transformations matricielles, celle à droite de l'équation sera la première transformation effectuée.

Vous calculez votre matrice en tant que modèle × Affichage × Projection. En multipliant cela par un vecteur, la projection serait effectuée en premier, suivie par la transformation de la vue, et enfin la transformation du modèle. Évidemment, ce n'est pas ce que vous voulez.

Votre matrice finale doit être calculée comme Projection × Afficher × Modèle pour effectuer les transformations dans le bon ordre.

+0

Je viens d'essayer, mais pas tout à fait raison. J'ai ajouté quelques photos de ce qui se passe. Cela aurait-il quelque chose à voir avec l'ordre des transformations, je pense que je suis en train de mettre à l'échelle, de tourner puis de traduire. – 2851999

+0

Vous ne calculez pas correctement vos matrices de translation, de rotation et d'échelle correctement. Pour appliquer correctement la transformation à la matrice que vous passez à la fonction, vous devez multiplier la nouvelle plutôt que d'ajouter. Vous devez également avoir 1s dans la diagonale principale pour que cela fonctionne. –