2014-07-05 6 views
-1

Edit: ok, j'ai écrit le code tout à fait intuitive maintenant et voici le résultat:axe X semble inversé dans OpenTK

http://i.imgur.com/x5arJE9.jpg

Le Cube est à 0,0,0

Comme vous pouvez le voir, la position de la caméra est négative sur l'axe z, ce qui suggère que je regarde le long de l'axe z positif, qui ne correspond pas. (fw est négatif)

Les couleurs des cubes suggèrent également que je suis sur l'axe z positif, en regardant dans la direction négative. De plus, le positif de l'axe x est vers la droite (en ModelSpace)

Les angles sont calculés comme suit:

public virtual Vector3 Right 
    { 
     get 
     { 

      return Vector3.Transform(Vector3.UnitX, Rotation); 
     } 
    } 
    public virtual Vector3 Forward 
    { 
     get 
     { 
      return Vector3.Transform(-Vector3.UnitZ, Rotation); 
     } 
    } 
    public virtual Vector3 Up 
    { 
     get 
     { 
      return Vector3.Transform(Vector3.UnitY, Rotation); 
     } 
    } 

rotation est un quaternion.

Voici comment la vue et les matrices modèle sont crée:

public virtual Matrix4 GetMatrix() 
    { 
     Matrix4 translation = Matrix4.CreateTranslation(Position); 
     Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation); 
     return translation * rotation; 
    } 

Projection:

private void SetupProjection() 
    { 
     if(GameObject != null) 
     { 
      AspectRatio = GameObject.App.Window.Width/(float)GameObject.App.Window.Height; 
      projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)((Math.PI * Fov)/180), AspectRatio, ZNear, ZFar); 

     } 
    } 

La multiplication de matrices:

public Matrix4 GetModelViewProjectionMatrix(Transform model) 
    { 
     return model.GetMatrix()* Transform.GetMatrix() * projectionMatrix; 
    } 

Shader:

[Shader vertex] 
#version 150 core 

in vec3 pos; 
in vec4 color; 
uniform float _time; 
uniform mat4 _modelViewProjection; 

out vec4 vColor; 

void main() { 
    gl_Position = _modelViewProjection * vec4(pos, 1); 
    vColor = color; 
} 

Les matrices OpenTK sont transposées, donc l'ordre de multiplication.

Avez-vous une idée de la raison pour laquelle l'axe/les emplacements sont tous endommagés?

Fin de l'édition. Original Post:

Jetez un oeil à cette image: http://i.imgur.com/Cjjr8jz.jpg

Comme vous pouvez le voir, tandis que le vecteur avant (de l'appareil) est positif dans l'axe z et le cube rouge est sur le x négatif axe,

float[] points = { 
// position (3) Color (3) 
-s, s, z, 1.0f, 0.0f, 0.0f, // Red point 
s, s, z, 0.0f, 1.0f, 0.0f, // Green point 
s, -s, z, 0.0f, 0.0f, 1.0f, // Blue point 
-s, -s, z, 1.0f, 1.0f, 0.0f, // Yellow point 
}; 

(cubes sont créés dans le nuanceur géométrique autour de ces points)

la caméra position x semble être inversé. En d'autres termes, si j'augmente la position de la caméra le long de son axe local x, elle se déplacera vers la gauche, et vice versa.

Je passe la matrice de transformation comme ceci:

 if (DefaultAttributeLocations.TryGetValue("modelViewProjectionMatrix", out loc)) 
     { 
      if (loc >= 0) 
      { 
       Matrix4 mvMatrix = Camera.GetMatrix() * projectionMatrix; 
       GL.UniformMatrix4(loc, false, ref mvMatrix); 
      } 

     } 

Procédé GetMatrix() se présente comme suit:

public virtual Matrix4 GetMatrix() 
    { 
     Matrix4 translation = Matrix4.CreateTranslation(Position); 
     Matrix4 rotation = Matrix4.CreateFromQuaternion(Rotation); 

     return translation * rotation; 
    } 

et la matrice de projection:

private void SetupProjection() 
    { 
     AspectRatio = Window.Width/(float)Window.Height; 
     projectionMatrix = Matrix4.CreatePerspectiveFieldOfView((float)((Math.PI * Fov)/180), AspectRatio, ZNear, ZFar); 
    } 

J » t vois ce que je fais mal:/

Répondre

1

C'est un peu difficile à dire du code, mais je crois que c'est parce que dans OpenGL, le vecteur avant par défaut de la caméra est négatif le long de l'axe Z - le vôtre est positif, ce qui signifie que vous regardez le modèle arrière. Ce serait pourquoi la coordonnée X semble inversée.

+0

Eh bien, peu importe ce que j'essaie, certains axes semblent toujours être inversés. Je pense qu'il y a quelque chose de bizarre dans l'implémentation de openTK Matrix4. Je vais le mettre à jour bientôt. – pixartist

+0

Hmm ... eh bien, je pense seulement que OpenTK Matrix4 est stocké différemment d'OpenGL (OpenTK est row-major, OpenGL est column-major). Mais vos transformations semblent bonnes. Peut-être essayer de les mélanger un peu, voir ce que ça fait ... – vesan

+0

Si vous utilisez des matrices majeures, vous devez dire à OpenGL que les matrices que vous lui transmettez sont majeures. Regardez le troisième paramètre de glUniformMatrix4fv par exemple. Aussi, comme l'a dit Vesan, le vecteur avant par défaut pour la caméra est (0, 0, -1). Cela signifie que vous ne pouvez pas utiliser la même fonction lookAt pour la caméra et vos objets normaux si vos objets habituels utilisent (0, 0, 1) leur direction avant. Vous pouvez créer votre matrice de projection de sorte que la caméra regarde vers le bas de l'axe z positif. Cela vous permettra d'utiliser la même fonction lookAt pour tout. – Homar

0

Bien que cette question date de quelques années, j'aimerais quand même donner ma contribution.

La raison pour laquelle vous rencontrez ce bogue est que les matrices d'OpenTK sont en ligne majeure. Tout cela signifie vraiment que vous devez faire toutes les mathématiques de la matrice est inverse. Par exemple, la matrice de transformation sera multipliée comme ceci:

public static Matrix4 CreateTransformationMatrix(Vector3 position, Quaternion rotation, Vector3 scale) 
{ 
    return Matrix4.CreateScale(scale) * 
      Matrix4.CreateFromQuaternion(rotation) * 
      Matrix4.CreateTranslation(position); 
} 

Cela vaut pour toute matrice, donc si vous utilisez Vector3 de la place de Quaternion est pour votre rotation, il ressemblerait à ceci:

public static Matrix4 CreateTransformationMatrix(Vector3 position, Vector3 rotation, Vector3 scale) 
{ 
    return Matrix4.CreateScale(scale) * 
      Matrix4.CreateRotationZ(rotation.Z) * 
      Matrix4.CreateRotationY(rotation.Y) * 
      Matrix4.CreateRotationX(rotation.X) * 
      Matrix4.CreateTranslation(position); 
} 

Notez que votre vertex shader sera toujours multiplié comme ceci:

void main() 
{ 
    gl_Position = projection * view * transform * vec4(position, 1.0f); 
} 

J'espère que cela aide!