Qt GUIで3Dグラフィックスをレベルアップ!QMatrix4x4::scale()関数でオブジェクトを拡大・縮小

2024-04-02

Qt GUIにおけるQMatrix4x4::scale()関数

QMatrix4x4::scale()関数は、3D空間におけるオブジェクトのスケーリング(拡大・縮小)を制御します。Qt GUIフレームワークで3Dグラフィックスを扱う際に、オブジェクトのサイズ変更やアニメーションなどに使用されます。

詳細

QMatrix4x4クラスは、4x4行列を表すクラスです。この行列は、3D空間におけるオブジェクトの変換を定義します。scale()関数は、この行列にスケーリング変換を適用します。

引数

scale()関数は、以下の3つの引数を受け取ります。

  • sx: X軸方向のスケーリング係数

これらの係数は、それぞれオブジェクトのX軸、Y軸、Z軸方向にどれだけの倍率で拡大・縮小するかを指定します。

コード例

// オブジェクトをX軸方向に2倍、Y軸方向に3倍、Z軸方向に4倍に拡大する
QMatrix4x4 matrix;
matrix.scale(2.0f, 3.0f, 4.0f);

// オブジェクトを原点を中心に拡大する
QMatrix4x4 matrix;
matrix.translate(0.0f, 0.0f, 0.0f);
matrix.scale(2.0f, 2.0f, 2.0f);

// オブジェクトを指定された点を中心に拡大する
QMatrix4x4 matrix;
matrix.translate(1.0f, 2.0f, 3.0f);
matrix.scale(2.0f, 2.0f, 2.0f);
matrix.translate(-1.0f, -2.0f, -3.0f);

注意事項

  • scale()関数は、オブジェクトの回転や移動などの他の変換とは順番に適用されます。
  • スケーリングは、オブジェクトの形状を変えずにサイズを変更します。
  • スケーリング係数は、0.0fより大きい値を指定する必要があります。

補足

  • QMatrix4x4クラスには、rotate()translate()などの他の変換関数も用意されています。
  • Qt GUIフレームワークには、3Dグラフィックスを扱うためのQOpenGLWidgetクラスなどのクラスも用意されています。


Qt GUIにおけるQMatrix4x4::scale()関数のサンプルコード

オブジェクトを原点を中心に拡大・縮小する

#include <QtWidgets/QApplication>
#include <QtOpenGL/QOpenGLWidget>
#include <QtOpenGL/QGLShaderProgram>

class MyWidget : public QOpenGLWidget {
public:
  MyWidget() {
    // 初期化
    setGeometry(0, 0, 640, 480);
  }

  void paintGL() override {
    // OpenGLの設定
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);

    // シェーダープログラムの設定
    QGLShaderProgram program;
    program.addShaderFromSourceFile(QGLShader::Vertex, ":/shader.vert");
    program.addShaderFromSourceFile(QGLShader::Fragment, ":/shader.frag");
    program.link();
    program.bind();

    // 頂点データの設定
    static const float vertices[] = {
      -1.0f, -1.0f, 0.0f,
      1.0f, -1.0f, 0.0f,
      1.0f,  1.0f, 0.0f,
      -1.0f,  1.0f, 0.0f,
    };

    // 頂点バッファーオブジェクトの設定
    QOpenGLBuffer vertexBuffer(QOpenGLBuffer::VertexBuffer);
    vertexBuffer.create();
    vertexBuffer.bind();
    vertexBuffer.allocate(vertices, sizeof(vertices));

    // 頂点属性の設定
    program.setAttributeBuffer("vertexPosition", GL_FLOAT, 0, 3, 0);

    // モデルビュー行列の設定
    QMatrix4x4 modelViewMatrix;
    modelViewMatrix.translate(0.0f, 0.0f, -5.0f);
    modelViewMatrix.scale(2.0f, 2.0f, 2.0f);

    // 投影行列の設定
    QMatrix4x4 projectionMatrix;
    projectionMatrix.perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);

    // ユニフォーム変数の設定
    program.setUniformValue("modelViewMatrix", modelViewMatrix);
    program.setUniformValue("projectionMatrix", projectionMatrix);

    // 図形の描画
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  }
};

int main(int argc, char** argv) {
  QApplication app(argc, argv);

  MyWidget widget;
  widget.show();

  return app.exec();
}

オブジェクトを指定された点を中心に拡大・縮小する

#include <QtWidgets/QApplication>
#include <QtOpenGL/QOpenGLWidget>
#include <QtOpenGL/QGLShaderProgram>

class MyWidget : public QOpenGLWidget {
public:
  MyWidget() {
    // 初期化
    setGeometry(0, 0, 640, 480);
  }

  void paintGL() override {
    // OpenGLの設定
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);

    // シェーダープログラムの設定
    QGLShaderProgram program;
    program.addShaderFromSourceFile(QGLShader::Vertex, ":/shader.vert");
    program.addShaderFromSourceFile(QGLShader::Fragment, ":/shader.frag");
    program.link();
    program.bind();

    // 頂点データの設定
    static const float vertices[] = {
      -1.0f, -1.0f, 0.0f,
      1.0f, -1.0f, 0.0f,
      1.0f,  1.0f, 0.0f,
      -1.0f,  1.0f, 0.0f,
    };

    // 頂点バッファーオブジェクトの設定
    QOpenGLBuffer vertexBuffer(QOpenGLBuffer::VertexBuffer);
    vertexBuffer.create();
    vertexBuffer.


Qt GUIにおけるQMatrix4x4::scale()関数を使用する以外の方法

QTransformクラスは、2Dおよび3D空間におけるオブジェクトの変換を制御するクラスです。scale()関数を使用して、オブジェクトのスケーリング(拡大・縮小)を制御できます。

#include <QtWidgets/QApplication>
#include <QtOpenGL/QOpenGLWidget>
#include <QtOpenGL/QGLShaderProgram>

class MyWidget : public QOpenGLWidget {
public:
  MyWidget() {
    // 初期化
    setGeometry(0, 0, 640, 480);
  }

  void paintGL() override {
    // OpenGLの設定
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);

    // シェーダープログラムの設定
    QGLShaderProgram program;
    program.addShaderFromSourceFile(QGLShader::Vertex, ":/shader.vert");
    program.addShaderFromSourceFile(QGLShader::Fragment, ":/shader.frag");
    program.link();
    program.bind();

    // 頂点データの設定
    static const float vertices[] = {
      -1.0f, -1.0f, 0.0f,
      1.0f, -1.0f, 0.0f,
      1.0f,  1.0f, 0.0f,
      -1.0f,  1.0f, 0.0f,
    };

    // 頂点バッファーオブジェクトの設定
    QOpenGLBuffer vertexBuffer(QOpenGLBuffer::VertexBuffer);
    vertexBuffer.create();
    vertexBuffer.bind();
    vertexBuffer.allocate(vertices, sizeof(vertices));

    // 頂点属性の設定
    program.setAttributeBuffer("vertexPosition", GL_FLOAT, 0, 3, 0);

    // モデルビュー行列の設定
    QMatrix4x4 modelViewMatrix;
    modelViewMatrix.translate(0.0f, 0.0f, -5.0f);

    // QTransformクラスを使用してオブジェクトを拡大
    QTransform transform;
    transform.scale(2.0f, 2.0f);
    modelViewMatrix *= transform.toMatrix();

    // 投影行列の設定
    QMatrix4x4 projectionMatrix;
    projectionMatrix.perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);

    // ユニフォーム変数の設定
    program.setUniformValue("modelViewMatrix", modelViewMatrix);
    program.setUniformValue("projectionMatrix", projectionMatrix);

    // 図形の描画
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  }
};

int main(int argc, char** argv) {
  QApplication app(argc, argv);

  MyWidget widget;
  widget.show();

  return app.exec();
}

このコードは、QTransformクラスを使用して、原点を中心に2倍に拡大された正方形を描画します。

頂点シェーダーでスケーリング行列を定義することで、オブジェクトのスケーリングを行うことができます。

#include <QtWidgets/QApplication>
#include <QtOpenGL/QOpenGLWidget>
#include <QtOpenGL/QGLShaderProgram>

class MyWidget : public QOpenGLWidget {
public:
  MyWidget() {
    // 初期化
    setGeometry(0, 0, 640, 480);
  }

  void paintGL() override {
    // OpenGLの設定
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glEnable(GL_DEPTH_TEST);

    // シェーダープログラムの設定
    QGLShaderProgram program;
    program.addShaderFromSourceFile(QGLShader::Vertex, ":/shader.vert");
    program.addShaderFromSourceFile(QGLShader::Fragment, ":/shader.frag");
    program.link();
    program.bind();

    // 頂点データの設定
    static const float vertices[] = {
      -1.0f, -1.0f, 0.0f,
      1.0f, -1



QWindow::minimumWidthとQMainWindow:ウィンドウサイズ設定のベストプラクティス

QWindow::minimumWidthを設定するには、以下の方法があります。コンストラクタで設定するsetMinimumWidth() メソッドを使用するQt Designerを使用するQt Designerでウィンドウを選択し、「プロパティ」パネルで「minimumWidth」プロパティを設定します。



QWindow::setMouseGrabEnabled() の代替方法:QRubberBand と QGraphicsItem::setFlags() を活用

QWindow::setMouseGrabEnabled() は、マウスイベントを特定のウィンドウに独占的に送信させるための関数です。有効にすると、そのウィンドウがフォーカスを持っていなくても、すべてのマウスイベントを受け取ります。他のウィンドウは、マウスイベントを受け取らなくなります。


Qt GUI プログラミングのワンランク上を目指す!QScreen::handle() メソッドでカスタムスクリーンデバイスを作成する

QScreen::handle() メソッドは、Qt GUIアプリケーションにおいて、現在処理しているスクリーンに関連するプラットフォーム固有のハンドルを取得するために使用されます。このハンドルは、低レベルのプラットフォームAPIへのアクセスを可能にし、より高度なスクリーン制御や情報取得を実現します。


Qt GUIにおけるQStandardItem::type()とは?

QStandardItem クラスは、モデル/ビューアーフレームワークで使用されるアイテムを表すクラスです。モデル/ビューアーフレームワークは、ツリービューやテーブルビューなどの複雑なユーザーインターフェースを構築するための強力なツールです。


Qt GUI でネイティブジェスチャーを理解する: QNativeGestureEvent::gestureType() の詳細解説

QNativeGestureEvent::gestureType() は、Qt GUI でネイティブジェスチャーイベントのタイプを返します。ネイティブジェスチャーイベントは、オペレーティングシステムによって生成され、通常はタッチイベントを解釈することで発生します。ズームや回転などのジェスチャーを表す高レベルイベントです。



スライダーの動きを思い通りに!Qt Widgets QScrollBar::sliderChange()の使い方

QScrollBar::sliderChange() は、Qt Widgets モジュールの QScrollBar クラスで提供される重要な仮想関数です。スクロールバーのスライダー位置が変化した際に呼び出され、さまざまなイベントに対応した処理を実行できます。


Qt GUIにおける数値範囲設定のベストプラクティス

Range::to は、Qt の QSlider や QSpinBox などのウィジェットで数値範囲を設定するために使用されます。この関数は、範囲の開始値と終了値を指定することで、ウィジェットの最小値と最大値を設定します。例:Range::to を使用することで、以下の利点があります。


QSyntaxHighlighter::document() を使用してカスタムハイライトルールを実装する方法

QSyntaxHighlighter::document() は、Qt GUI アプリケーションにおけるシンタックスハイライト機能を提供するクラス QSyntaxHighlighter のメンバー関数です。この関数は、ハイライト対象となるテキストドキュメントへのポインタを取得するために使用されます。


Qt GUIでユーザーインターフェースの使いやすさを向上させる

主な用途意図しないドラッグ操作を防ぐドラッグ操作開始までの猶予時間を調整することで、ユーザーインターフェースの使いやすさを向上させる設定方法QStyleHints::startDragTime は、QApplication::setStartDragTime() 関数を使用して設定できます。この関数は、ドラッグ操作開始までの猶予時間をミリ秒単位で指定します。


Qt WidgetsにおけるQAbstractSpinBox::readOnlyプロパティの徹底解説

readOnlyプロパティを true に設定すると、ユーザーはスピンボックス内の値を変更できなくなります。矢印ボタンをクリックしたり、値を手動で入力したりしても、値は変化しません。一方、readOnlyプロパティを false に設定すると、ユーザーはスピンボックス内の値を自由に編集できます。