openGL(Qt)正确绑定+两次同时旋转

时间:2013-01-09 22:15:40

标签: qt opengl rotation glsl shader

我正在尝试获得一些openGL的经验,但现在我面临“1.5”问题;)。 第一个问题/问题是如何“同时”在两个方向上进行旋转? 我想绘制一个可在x轴和y轴上移动的坐标系。但我只能在x轴或y轴上移动。我无法弄清楚如何同时做两件事。

我的另一半问题并不是一个真正的问题,但正如你所看到的那样,当我移动我的鼠标时,我一直在绑定我的着色器。有没有更好的方法可以做到?

void GLWidget::mouseMoveEvent(QMouseEvent *event)
{
    differencePostition.setX(event->x() - lastPosition.x());
    differencePostition.setY(event->y() - lastPosition.y());

    shaderProgram.removeAllShaders();
    shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, "../Vector/yRotation.vert");
    shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, "../Vector/CoordinateSystemLines.frag");
    shaderProgram.link();
    shaderProgram.bind();
    shaderProgram.setAttributeValue("angle", differencePostition.x());

    //shaderProgram.release();
    //shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, "../Vector/xRotation.vert");
    //shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, "../Vector/CoordinateSystemLines.frag");
    //shaderProgram.link();
    //shaderProgram.bind();
    //shaderProgram.setAttributeValue("angle", differencePostition.y());

    updateGL();
}

void GLWidget::mousePressEvent(QMouseEvent *event)
{
    lastPosition = event->posF();
}

xRotation.vert

#version 330
in float angle;
const float PI = 3.14159265358979323846264;
void main(void)
{
    float rad_angle = angle * PI / 180.0;
    vec4 oldPosition = gl_Vertex;
    vec4 newPosition = oldPosition;
    newPosition.y = oldPosition.y * cos(rad_angle) - oldPosition.z * sin(rad_angle);
    newPosition.z = oldPosition.y * sin(rad_angle) + oldPosition.z * cos(rad_angle);
    gl_Position = gl_ModelViewProjectionMatrix * newPosition;
}

yRotation.vert

#version 330
in float angle;
const float PI = 3.14159265358979323846264;
void main(void)
{
    float rad_angle = angle * PI / 180.0;
    vec4 oldPosition = gl_Vertex;
    vec4 newPosition = oldPosition;
    newPosition.x = oldPosition.x * cos(rad_angle) + oldPosition.z * sin(rad_angle);
    newPosition.z = oldPosition.z * cos(rad_angle) - oldPosition.x * sin(rad_angle);
    gl_Position = gl_ModelViewProjectionMatrix * newPosition;
}

2 个答案:

答案 0 :(得分:2)

同时在多个方向上旋转需要矩阵组合(通常称为general rotation matrix

如果您对此感兴趣,有几个网站会显示如何生成此矩阵。

关于第二个问题,着色器通常在init部分初始化。

示例:http://doc-snapshot.qt-project.org/5.0/qtopengl/cube-mainwidget-cpp.html

答案 1 :(得分:1)

你只需要调用shaderProgram.bind();每次在您想要使用着色器绘制对象之前。加载和链接通常只在程序初始化时完成一次。只调用shaderProgram.setAttributeValue你的mouseMoveEvent方法。

修改 解决旋转问题的一种快速方法是编写一个一个接一个旋转的着色器。在变量中添加第二个,并使用setAttributeValue方法设置它们。

#version 330
in float angleX;
in float angleY;
const float PI = 3.14159265358979323846264;
void main(void)
{
    float rad_angle_x = angleX * PI / 180.0;
    vec4 oldPosition = gl_Vertex;
    vec4 newPositionX = oldPosition;
    newPositionX.y = oldPosition.y * cos(rad_angle_x) - oldPosition.z * sin(rad_angle_x);
    newPositionX.z = oldPosition.y * sin(rad_angle_x) + oldPosition.z * cos(rad_angle_x);

    float rad_angle_y = angleY * PI / 180.0;
    vec4 newPositionXY = newPositionX;
    newPositionXY.x = newPositionX.x * cos(rad_angle_y) + newPositionX.z * sin(rad_angle_y);
    newPositionXY.z = newPositionX.z * cos(rad_angle_y) - newPositionX.x * sin(rad_angle_y);
    gl_Position = gl_ModelViewProjectionMatrix * newPositionXY;
}

这样您就不需要知道矩阵乘法了。