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

Posted

技术标签:

【中文标题】openGL(Qt)正确绑定+同时两个旋转【英文标题】:openGL (Qt) bind properly + Two rotation at the same time 【发布时间】:2013-01-09 22:15:40 【问题描述】:

我正在尝试获得一些 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;

【问题讨论】:

【参考方案1】:

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

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

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

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

【讨论】:

【参考方案2】:

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

编辑 解决旋转问题的一种快速方法是编写一个着色器,它一个接一个地进行两个旋转。添加第二个 in 变量并使用 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;

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

【讨论】:

哦,好的。我永远不会想出那个着色器;)谢谢。但我另当别论。我已经在我的 initializeGL() 方法中绑定了着色器,因为我想在开始旋转之前先绘制我的坐标系线。 也许我想的太远了,但后来我想加载新的着色器来绘制东西,然后我就不能再使用我的初始化方法了。 您可以在 initializeGL 中加载和链接 所有 着色器,但在绘制对象之前绑定()它们。对于您的坐标系,您可能无论如何都想使用不同的着色器,因为它从未旋转过。为您的坐标系线创建一个着色器,然后为您的不同外观对象创建另一个着色器。

以上是关于openGL(Qt)正确绑定+同时两个旋转的主要内容,如果未能解决你的问题,请参考以下文章

使用 GLM 正确旋转 Open GL 相机

QT和OpenGL如何正确集成并显示纹理

将绑定到 FBO 的纹理复制到另一个 OpenGL 上下文

OpenGL 平移和旋转同时进行

opengl glrotatef 无法正确旋转

如何使用 GLM 在 OpenGL 中正确计算旋转