2010-12-04 16 views
1

J'implémente une arcball avec openGL (on cpp). Dites, j'ai un objet au centre du système d'axes et je veux tourner plusieurs fois en fonction des axes (du monde) d'origine. Mais, après la première rotation, les axes sont modifiés et toutes les autres rotations se passent mal. Des idées? Merci.Préserver le système d'axe d'origine tout en tournant avec openGL

+1

Qu'est-ce que c'est «openPG»? – genpfault

+0

Les quaternions sont une bonne solution pour 'Gimbal lock' – sje397

Répondre

1

Je devais faire la même chose moi-même dans une application OpenGL ES, que je décris dans un article à ce sujet here. L'approche brute d'origine lire la matrice actuelle de vue du modèle et manipulé pour produire l'effet désiré:

GLfloat currentModelViewMatrix[16]; 
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix); 
glRotatef(xRotation, currentModelViewMatrix[1], currentModelViewMatrix[5], currentModelViewMatrix[9]); 
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix); 
glRotatef(yRotation, currentModelViewMatrix[0], currentModelViewMatrix[4], currentModelViewMatrix[8]); 

Cela fonctionne, mais il faut savoir que les deux appels glGetFloatv() va ralentir le processus de rendu en arrêtant le pipeline. J'ai depuis remplacé ce code avec des calculs que j'effectue sur ma propre copie interne de la matrice de vue de modèle, puis j'écris simplement la matrice de vue de modèle manipulée en interne après chaque rotation. Cela supprime le besoin de faire les opérations de lecture de matrice coûteuses.

2

Fournissez l'objet avec ses propres axes d'orientation (matrice modelview), puis multipliez-le par les matrices de rotation. Consultez Wikipédia pour savoir comment construire des matrices de rotation.

+0

J'utilise la fonction glRotatef() pour les rotatins. Que voulez-vous dire "propres axes d'orientation"? – Sanich

+0

Vous n'utilisez pas de shaders alors, désolé j'aurais dû demander. Souhaitez-vous pousser/sauter la pile de matrice pour chaque appel de glRotate? – cmannett85

1

Ajouter xAngle et yAngle à la matrice actuelle.

Matrix.rotateM(matrix, 0, xAngleADD, matrix[1], matrix[5], matrix[9]); 
Matrix.rotateM(matrix, 0, yAngleADD, matrix[0], matrix[4], matrix[8]); 
gl.glMultMatrixf(matrix, 0);