2013-08-18 4 views
0

Я пытаюсь создать класс пользователя firendly transform (пример Unity), который только удерживает (или только видимый для пользователя) положение, вращение и перевод векторов.OpenGL Translate Поворот трансформации шкалы

Применение преобразования легко для OpenGL с помощью функций glTranslate, glRotate и glScale. Я вызываю метод Transform для каждого объекта, прежде чем он будет нарисован. Но у меня возникают проблемы с изменением позиции, связанной поворотом. Вот мой код.

// Пример метода визуализации для объекта

void Render() 
    { 
     glPushMatrix(); 
     glMatrixMode(GL_MODELVIEW); 

     transform->Transform(); 

     glEnable(GL_COLOR_MATERIAL); 
     glEnableClientState(GL_VERTEX_ARRAY); 
     glEnableClientState(GL_COLOR_ARRAY); 

     glColorPointer(3, GL_FLOAT, 0, m_colors->constData()); 
     glVertexPointer(3, GL_FLOAT, 0, m_positions->constData()); 
     glDrawArrays(GL_LINES, 0, 6); 

     glDisable(GL_COLOR_MATERIAL); 
     glDisableClientState(GL_VERTEX_ARRAY); 
     glDisableClientState(GL_COLOR_ARRAY); 

     glPopMatrix(); 
    } 

// Трансформация класса

class Transformation 
    { 

    public: 

     QVector3D Position; 
     QVector3D Rotation; 
     QVector3D Scale; 

     Transformation() 
     { 
      Position = QVector3D(0.0f, 0.0f, 0.0f); 
      Rotation = QVector3D(0.0f, 0.0f, 0.0f); 
      Scale = QVector3D(1.0f, 1.0f, 1.0f); 
     } 

     ~Transformation() 
     { 

     } 

     void Translate(const QVector3D& amount) 
     { 

     } 

     void Rotate(const QVector3D& amount) 
     { 
      Rotation += amount; 

      Rotation.setX(AdjustDegree(Rotation.x())); 
      Rotation.setY(AdjustDegree(Rotation.y())); 
      Rotation.setZ(AdjustDegree(Rotation.z())); 
     } 

     void Transform() 
     { 
      // Rotation 
      glRotatef(Rotation.x(), 1.0f, 0.0f, 0.0f); 
      glRotatef(Rotation.y(), 0.0f, 1.0f, 0.0f); 
      glRotatef(Rotation.z(), 0.0f, 0.0f, 1.0f); 

      // Translation 
      glTranslatef(Position.x(), Position.y(), Position.z()); 

      // Scale 
      glScalef(Scale.x(), Scale.y(), Scale.z()); 
     } 

    }; 

Как я могу Перевести?

+0

Мой совет: Не используйте встроенные матричные манипуляторы OpenGL. Для одних они громоздки для работы. И что еще более важно, они были полностью очищены от более поздних версий. Используйте настоящую матричную математическую библиотеку, такую ​​как GLM, Eigen или linmath.h. – datenwolf

+0

Спасибо за советы, но ни один из них не отвечает на мой вопрос. Я спрашиваю, как переводить по степеням вращения. –

+0

Вот почему я написал это как _comment_. – datenwolf

ответ

2

Преобразования в openGL хранятся в стеке, а затем они применяются к модели обратно. В вашем коде вы сначала применяете масштаб, затем переводите и, наконец, поворачиваете. Поскольку поворот производится из (0, 0, 0), если вы переместили (перевели) объект, вы измените его положение. Чтобы повернуть объект, его центр должен находиться в (0, 0, 0).

Правильный порядок преобразований: Масштаб/Поворот, а затем Перевести

Таким образом, в вашем коде, перевод должен быть первым преобразованием вы делаете.

+0

Хороший совет Я еще не использовал масштаб. Я только знаю, что ротация должна применяться перед переводом. Благодарю. –

+0

@ CahitBurakKüçüksütcü Но учтите, что преобразования хранятся в стеке, поэтому они применяются обратно. Сначала вам нужно применить поворот, так что вам нужно кодовое вращение последним – Stratford

+2

@Stratford: на самом деле преобразования OpenGL * не * хранятся в стеке. Матричный стек выполняет совершенно другую цель, а именно, иметь возможность создавать обратимую иерархию преобразований. Но когда вы вызываете функции преобразования OpenGL последовательно, они только на месте умножаются на одну единственную матрицу 4 × 4. – datenwolf