2013-03-11 133 views
0

我無法弄清楚如何將鼠標拖動轉換爲圍繞圖像平面的Ox和Oy旋轉。
我遵循here的第一個答案,我將modelView矩陣存儲在一個數組中,並在每次鼠標移動時更新它。 alphabeta與先前位置的鼠標增量成比例。圍繞絕對軸旋轉3d模型

此代碼更新旋轉當鼠標移動:

glLoadMatrixf(currentModelViewMatrix); 
glRotatef(beta,0,1,0); 
glRotatef(alpha,1,0,0); 
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix); 

我試圖從this解釋到底解決方案,但並沒有任何區別。

只有beta給出的旋轉是絕對的,alpha給出的旋轉圍繞模型中圍繞第一軸旋轉時的軸旋轉。我不知道如何讓第二次旋轉是絕對的。現在的方式對用戶來說似乎並不直觀。


編輯: 增量代碼:

GLfloat currentModelViewMatrix[16]; 
GLfloat whole[16]; 
void glob() 
{ 
    glLoadIdentity(); 
    glRotatef(beta,0,1,0); 
    glRotatef(alpha,1,0,0); 
    glMultMatrixf(currentModelViewMatrix); 
    glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix); 

    glLoadIdentity(); 
    glTranslatef(0,0,-20); 
    glMultMatrixf(currentModelViewMatrix); 
    glGetFloatv(GL_MODELVIEW_MATRIX,whole); 

    alpha=beta=0; 
} 

而且每個模型前,基質被載入:

glLoadMatrixf(whole); 

的完整代碼:

#include "math.h" 
#include "string.h" 
#include "stdio.h" 
#include "GL/freeglut.h" 
#include "GL/gl.h" 
#include "GL/glu.h" 
float alpha,beta; 

void key(int key, int x, int y) 
{ printf("%d",key); 
    switch(key) 
    { case GLUT_KEY_RIGHT: 
      printf("right\n"); 
      break; 
     case GLUT_KEY_LEFT: 
      printf("left\n"); 
      break; 
     case GLUT_KEY_UP: 
      printf("top\n"); 
      break; 
     case GLUT_KEY_DOWN: 
      printf("bottom\n"); 
      break; 
    } 
    glutPostRedisplay(); 
    fflush(stdout); 
} 

void otherkeys(unsigned char key,int x,int y) 
{ printf("%c\n",key); 
    fflush(stdout); 
    switch(key) 
    { case '+': 
      printf("plus\n"); 
      break; 
     case '-': 
      printf("minus\n"); 
      break; 
     case 'w': 
       alpha+=10; 
      break; 
     case 's': 
       alpha-=10; 
      break; 
     case 'd': 
       beta+=10; 
      break; 
     case 'a': 
       beta-=10; 
      break; 
    } 
    glutPostRedisplay(); 
} 
void drawCube() 
{ int i,j,d; 
    glBegin(GL_LINES); 
     for(i=0;i<8;i++) 
     { for(j=i+1;j<8;j++) 
      { d=j^i; 
       if(d==1||d==2||d==4) 
       { glVertex3i(i%2,i/2%2,i/4%2); 
        glVertex3i(j%2,j/2%2,j/4%2); 
       }     
      } 
     } 
    glEnd(); 
} 

GLfloat currentModelViewMatrix[16]; 
GLfloat whole[16]; 
void glob() 
{ 
    glLoadIdentity(); 
    glRotatef(beta,0,1,0); 
    glRotatef(alpha,1,0,0); 
    glMultMatrixf(currentModelViewMatrix); 
    glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix); 

    glLoadIdentity(); 
    glTranslatef(0,0,-20); 
    glMultMatrixf(currentModelViewMatrix); 
    glGetFloatv(GL_MODELVIEW_MATRIX,whole); 

    alpha=beta=0; 
} 
void renderFunction() 
{ int i; 
    glClearColor(0.0,0.0,0.0,0.0); 
    glClear(GL_COLOR_BUFFER_BIT); 
    glColor3f(1.0,1.0,1.0); 
    glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
//    glRotatef(angle2,0.0,0.0,1.0); 
     gluPerspective(60, 1.333, 0.1, 100); 

    glMatrixMode(GL_MODELVIEW); 

    glColor3f(1.0,0.0,0.0); 
    for(i=1;i<8;i++) 
    { 
     glLoadMatrixf(whole); 
     glTranslatef(i*2.0,0,0); 
     drawCube(); 
    } 

    glColor3f(0.0,1.0,0.0); 
    for(i=1;i<6;i++) 
    { 
     glLoadMatrixf(whole); 
     glTranslatef(0,i*2.0,0); 
     drawCube(); 
    } 

    glColor3f(0.0,0.0,1.0); 
    for(i=0;i<5;i++) 
    { 
     glLoadMatrixf(whole); 
     glTranslatef(0,0,i*2.0); 
     drawCube(); 
    } 

    glFlush(); 
} 

/*mouse*/ 
int prevx,prevy,dx,dy; 
void rotate(int dx,int dy) 
{ printf("%f %f\n",dy/10.0,dy/10.0); 
    alpha=dy/2.0; 
    beta=dx/2.0; 
    glob(); 
} 

void passive(int x,int y) 
{ prevx=x;prevy=y;} 

void active(int x,int y) 
{ dx=x-prevx; 
    prevx=x; 
    dy=y-prevy; 
    prevy=y; 
    rotate(dx,dy); 
} 

void globinit() 
{ 
    glLoadIdentity(); 
    glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix); 

    glLoadIdentity(); 
    glTranslatef(0,0,-20); 
    glGetFloatv(GL_MODELVIEW_MATRIX, whole);  
} 
int main (int argc, char* argv[]) 
{  
    glutInit(&argc,argv); 

    glutInitDisplayMode(GLUT_SINGLE); 
    glutInitWindowSize(800,600); 
    glutInitWindowPosition(100,100); 
    glutCreateWindow("Open GL bla bla"); 
    glutDisplayFunc(renderFunction); 
    glutIdleFunc(renderFunction); 
    glutSpecialFunc(key); 
    glutKeyboardFunc(otherkeys); 
    glutMotionFunc(active); 
    glutPassiveMotionFunc(passive); 
    globinit(); 
    glutMainLoop(); 
    return 0; 
} 

回答

1

嘗試以下操作:

glLoadIdentity(); 
glRotatef(beta,0,1,0); 
glRotatef(alpha,1,0,0); 
glMultMatrixf(currentModelViewMatrix); 
glGetFloatv(GL_MODELVIEW_MATRIX, currentModelViewMatrix); 

由於改變了順序旋轉的全局座標系統,而不是一個地方之一執行。

+0

謝謝你,它與翻譯效果很好,所以它不會圍繞原點旋轉 – titus 2013-03-11 10:35:44