2014-11-04 7 views
0

Я пытаюсь закодировать камеру с glTranslate/glRotate. Для реализации функций look-up/look-down мне нужно, чтобы все объекты в моем пространстве рендеринга вращались вокруг точки (то есть, где находится «камера»), точка, которая обычно отличается от начала координат. Тем не менее, вещи продолжают вращаться вокруг источника. Есть ли способ указать другую точку?Вращение вокруг точки, отличной от исходной


EDIT: Добавлен код

Спасибо за ваш быстрый ответ. Кажется, что я не могу заставить его работать правильно, несмотря ни на что, поэтому я решил добавить свой код; Я был бы очень признателен, если бы кто-нибудь мог взглянуть на него и рассказать мне, какие изменения необходимы для перевода/поворота/перевода назад.

#include <iostream> 
#include <cmath> 
#include <GLUT/GLUT.h> 

const double roaming_step = .13; 
double z_offset = .0; 
double y_offset = .0; 
double x_offset = .0; 

const double angle_step = 1.5; 
double angle_xz = .0; 
double angle_yz = .0; 

bool keyStates[256] = { false }; 

void drawFloor() 
{ 
    glColor3f(1.0, 1.0, 1.0); 

    glBegin(GL_QUADS); 
     glVertex3f(-3.0, -1.0, 3.0); 
     glVertex3f(-3.0, -1.0, -3.0); 
     glVertex3f(3.0, -1.0, -3.0); 
     glVertex3f(3.0, -1.0, 3.0); 
    glEnd(); 
} 

void drawBalls() 
{   
    glTranslatef(-3.0, -.5, -3.0); 
    glColor3f(.8, .1, .1); 

    for(int i = 0; i < 3; i++) 
    { 
     glPushMatrix(); 

     glTranslatef(.0, -.5, i * 3); 

     for(int j = 0; j < 3; j++) 
     { 
      glPushMatrix(); 

      glTranslatef(j * 3, .0, .0); 
      glutSolidSphere(.5, 20, 20); 

      glPopMatrix(); 
     } 

     glPopMatrix(); 
    } 
} 

void keyPressed(unsigned char key, int x, int y) 
{ 
    keyStates[key] = true; 
} 

void keyReleased(unsigned char key, int x, int y) 
{ 
    keyStates[key] = false; 
} 

void keyboardOperations() 
{ 
    if(keyStates['w']) 
     z_offset += roaming_step; 

    if(keyStates['s']) 
     z_offset -= roaming_step; 

    if(keyStates['a']) 
     x_offset += roaming_step; 

    if(keyStates['d']) 
     x_offset -= roaming_step; 

    if(keyStates['i']) 
    { 
     angle_xz -= angle_step; 

     if(angle_xz < .0) 
      angle_xz += 360.0; 
    } 

    if(keyStates['o']) 
    { 
     angle_xz += angle_step; 

     if(angle_xz >= 360.0) 
      angle_xz -= 360.0; 
    } 

    if(keyStates['u']) 
    { 
     angle_yz -= angle_step; 

     if(angle_yz < .0) 
      angle_yz += 360.0; 
    } 

    if(keyStates['j']) 
    { 
     angle_yz += angle_step; 

     if(angle_yz >= 360.0) 
      angle_yz -= 360.0; 
    } 

    if(keyStates['q']) 
     exit(0); 
} 

// I guess it has to be done in this function 
// but didn't get how 
void camera() 
{ 
    glLoadIdentity(); 

    // Forward/Backward 
    glTranslated(.0, .0, z_offset); 

    // Left/Right 
    glTranslated(x_offset, .0, .0); 

    // XZ Rotation 
    glRotated(angle_xz, .0, 1.0, .0); 

    // YZ Rotation 
    glRotated(angle_yz, 1.0, .0, .0); 
} 

void display(void) 
{ 
    keyboardOperations(); 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    camera(); 

    drawFloor(); 
    drawBalls(); 

    glutSwapBuffers(); 
} 

void reshape(int width, int height) 
{ 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    glViewport(0, 0, width, height); 

    GLdouble aspect = (GLdouble) width/(GLdouble) height; 
    gluPerspective(60, aspect, 1, 100); 

    glMatrixMode(GL_MODELVIEW); 
} 

int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); 

    glutInitWindowSize(500, 500); 
    glutInitWindowPosition(0, 0); 
    glutCreateWindow("openGLtest3"); 
    glClearColor(.0, .0, .0, .0); 

    glEnable(GL_DEPTH_TEST); 
    glShadeModel(GL_FLAT); 

    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 
    glutIdleFunc(display); 

    glutIgnoreKeyRepeat(true); 
    glutKeyboardFunc(keyPressed); 
    glutKeyboardUpFunc(keyReleased); 

    glutMainLoop(); 

    return 0; 
} 

ответ

2

В openGL, glRotation fuction берет начало в качестве ссылки. Чтобы повернуть вокруг точки (координата вашей камеры в этом случае), вы должны перевести позицию вашей камеры в начало координат (переведите все ваши объекты соответственно), а затем примените функцию поворота. Затем вы можете перевести камеру назад (со всеми вашими объектами)

позволяет сказать, что ваша позиция камеры (а, б, в), так что должно быть ваш код что-то вроде:

foreach object 
{ 
    glPushMatrix(); 
    glTranslate(a,b,c); 
    glRotate(...); 
    glTranslate(-a,-b,-c); 
    //render 
    glPopMatrix(); 
} 
+0

Я добавил код, не могли бы вы, пожалуйста, посмотрите на это? – pr0gma

+0

Это неправильный порядок преобразований. См. Это для правильного порядка: http://stackoverflow.com/questions/23442499/rotating-an-object-around-a-fixed-point-using-glmultmatrix/23448400#23448400. –

+0

@RetoKoradi thx для предупреждения. Я отредактировал решение –

Смежные вопросы