0

私はopenGLの経験を積もうとしていますが、今は「1.5」の問題に直面しています;)。最初の問題/質問は、「同時に」2方向に回転させるにはどうすればよいですか? 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;
}
4

2 に答える 2

2

同時に複数の方向に回転するには、行列の組み合わせが必要です (一般的に一般的な回転行列と呼ばれます) 。

さらに興味がある場合は、このマトリックスがどのように生成されるかを示すサイトがいくつかあります。

2 番目の問題に関しては、通常、シェーダーは init セクションで初期化されます。

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

于 2013-01-09T22:30:52.930 に答える
1

shaderProgram.bind(); を呼び出すだけです。シェーダーでオブジェクトを描画する前に毎回。ロードとリンクは、通常、プログラムの初期化で一度だけ行われます。mouseMoveEvent メソッドの shaderProgram.setAttributeValue のみを呼び出します。

編集 回転の問題を解決する簡単な方法は、両方の回転を交互に行うシェーダーを作成することです。変数に秒を追加し、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;
}

この方法では、行列の乗算を知る必要はありません。

于 2013-01-09T22:36:14.847 に答える