質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

Q&A

解決済

1回答

2616閲覧

画像の真ん中を中心に回転させる方法 行列計算

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

0グッド

0クリップ

投稿2021/04/27 08:56

編集2021/04/27 10:15

提示コードの///コメント内部のコードですが原点を中心ではなく画像の中心を中心に回転させたいのですがなぜ画像自体が動いてしまうのでしょか?本来であれば画面の左上に描画されるはずのですが?これはなぜなのでしょうか?

画像は提示コードのangle 変数部の数値0の場合とそうじゃない場合の画像です。

イメージ説明
イメージ説明
イメージ説明

このコードで原点を真ん中にずらしたものを変数mに入れてその行列をvecRotate分回転させて値がrorate変数格納という処理なのでがこの処理で
図形の場所がずれる原因がわかりません。

cpp

1 glm::mat4 m = glm::translate(translate, glm::vec3(size.x * 0.5f, size.y * 0.5f,0)); //平行移動 2 rotate = glm::rotate(m,angle, vecRotate);
#include "DrawTest_2D.hpp" #include <iostream> #include "Shader.hpp" #include <glm/glm.hpp> #include <glm/gtx/transform.hpp> #include <glm/gtc/matrix_transform.hpp> //コンストラクタ DrawTest_2D::DrawTest_2D() { shader = std::make_shared<Shader>("BasicMono_2D.vert", "BasicMono_2D.frag"); //シェーダー //頂点配列 struct Vertex { GLfloat position[2]; }; //頂点情報 Vertex rectangleVertex[6] = { //頂点 {0.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 1.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, }; //vao glGenVertexArrays(1, &vao); glBindVertexArray(vao); //vbo glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); //頂点 GLint attrib = shader->getAttribLocation("vertexPosition"); glEnableVertexAttribArray(attrib); glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(Vertex), rectangleVertex, GL_STATIC_DRAW); glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), (GLvoid*)0); //モデル行列のパラメータを初期化 size = glm::vec2(100.0f,100.0f); vecScale = glm::vec3(size.x, size.y, 1.0f); //拡大縮小 vecRotate = glm::vec3(0.0f, 0.0f, -1.0f); //回転 angle = 20.0f; //回転量 vecTranslate = glm::vec3(0.0f, 0.0f, 0.0f); //平行移動 //モデル行列 translate = glm::translate(glm::mat4(1), vecTranslate); //平行移動 glm::mat4 m = glm::translate(translate, glm::vec3(size.x * 0.5f, size.y * 0.5f,0)); //平行移動 std::cout << "m 行列" << std::endl; std::cout << m[0].x << " , " << m[0].y << " , " << m[0].z << " , " << m[0].w << std::endl; std::cout << m[1].x << " , " << m[1].y << " , " << m[1].z << " , " << m[1].w << std::endl; std::cout << m[2].x << " , " << m[2].y << " , " << m[2].z << " , " << m[2].w << std::endl; std::cout << m[3].x << " , " << m[3].y << " , " << m[3].z << " , " << m[3].w << std::endl; std::cout << std::endl; std::cout << std::endl; rotate = glm::rotate(m,angle, vecRotate); //回転 std::cout << "rotate 行列" << std::endl; std::cout << rotate[0].x << " , " << rotate[0].y << " , " << rotate[0].z << " , " << rotate[0].w << std::endl; std::cout << rotate[1].x << " , " << rotate[1].y << " , " << rotate[1].z << " , " << rotate[1].w << std::endl; std::cout << rotate[2].x << " , " << rotate[2].y << " , " << rotate[2].z << " , " << rotate[2].w << std::endl; std::cout << rotate[3].x << " , " << rotate[3].y << " , " << rotate[3].z << " , " << rotate[3].w << std::endl; std::cout << std::endl; std::cout << std::endl; //translate = glm::translate(translate, vecTranslate); //平行移動 scale = glm::scale(glm::mat4(1), vecScale); //拡大縮小 //ビュー /* glm::vec3 pos = glm::vec3(0, 0, 1); //座標 glm::vec3 center = glm::vec3(0, 0, -1); //向き glm::vec3 up = glm::vec3(0, 1, 0); //上方向 view = glm::lookAt(pos, center, up); */ //projection = glm::perspective(glm::radians(90.0f), 4.0f / 3.0f, 0.1f, 100.0f); //透視射形 projection = glm::ortho(0.0f, 640.0f, 480.0f, 0.0f, -1.0f, 1.0f); //透視射形 } //更新 void DrawTest_2D::Update() { } //描画 void DrawTest_2D::Draw() { shader->setEnable(); shader->setBindAttribVertex("vertexPosition"); /*########## Unifrom ##########*/ shader->setUniform4f("uFragment", glm::vec4(0.0, 0.0, 1.0, 1.0)); shader->setUniformMatrix4fv("uTranslate", translate); shader->setUniformMatrix4fv("uRotate", rotate); shader->setUniformMatrix4fv("uScale", scale); shader->setUniformMatrix4fv("uProjection", projection); shader->setUniformMatrix4fv("uView", view); glDrawArrays(GL_TRIANGLES, 0, 6); shader->setDisable(); } //デストラクタ DrawTest_2D::~DrawTest_2D() { glDeleteVertexArrays(1, &vao); glDeleteBuffers(1, &vbo); }

glsl

1/*######################################################################### 2# 単色の2D描画 3###########################################################################*/ 4#extension GL_ARB_explicit_attrib_location: enable 5 6/*########## 頂点情報 ##########*/ 7layout(location = 0) in vec2 vertexPosition; //頂点座標 8 9/*########## フラグメント ##########*/ 10layout(location = 1) out vec4 vFragment; //頂点カラー 11 12/*########## Uniform ##########*/ 13uniform mat4 uScale; //スケール 14uniform mat4 uRotate; //回転 15uniform mat4 uTranslate; //平行移動 16uniform mat4 uProjection; //正射形行列 17uniform mat4 uView; //ビュー行列 18uniform vec4 uFragment; //描画色 19 20void main() 21{ 22 23 24 25 26 27 vec4 vertex = vec4(vertexPosition,0.0,1.0); //頂点座標 28 mat4 model = uTranslate * uRotate * uScale; //モデル行列 29 //gl_Position = (uProjection * uView * model) * vertex; 30 gl_Position = uProjection * model * vertex; 31 32 33 34 35 vFragment = uFragment; //カラー 36}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2021/04/27 09:27 編集

(回転中心の話,これで何回目だろうか…?) うまくいかんならば,まずは,何はともあれ,マトリクスの要素値を自分でチェックすべき. 「理屈の上で要素値がいくつになるのか」を把握しているなら,その値と比較すれば良いだけだ. 理屈の値と異なっているマトリクスが戦犯だから,それを突き止める. 「質問する前に,そのくらいはやろうよ」という意味.それがしばらく成されない場合には「丸投げ」に投票させていただく予定. 今さらあり得ないと思うが,仮に,理屈上の値がわからないという状態だとすれば,実装作業に入る前にやるべきことがあると思う.
fluid_love

2021/04/27 10:01 編集

「画像」というのは青の正方形を指していますか? 「原点を中心ではなく画像の中心を中心に回転させたい」とありますが,現状のコードで変数「angle」の値を増加させたら画面の原点を中心に回転したのですか?
fana

2021/04/27 10:30 編集

> 画面の原点を中心に回転したのですか? マトリクスは頂点の座標に乗じているのだから,現状の回転中心は,大元の座標が (0.0f, 0.0f) な頂点の位置であるハズ. 現状,そのことはそのままであり,加えて,全体が (50,50) だけ並進している. 何故ならば,そのような行列を作って乗じているからだ.
fana

2021/04/27 10:37

> そのような行列 が,どこから来たのか? というと,それは当然,これ↓だ. > glm::mat4 m = glm::translate(translate, glm::vec3(size.x * 0.5f, size.y * 0.5f,0)); //平行移動 回転量が0のときを考えてみれば rotate とはこのmそのものであり,このmとは,座標を(+50,+50)だけオフセットさせるもの. だから,結果として(50,50)の位置に四角形の角が来ている.
fana

2021/04/27 10:48

どうでもいいけど,行列の operator[] は列ベクトルを返すっぽいから, > std::cout << m[0].x << " , " << m[0].y << " , " << m[0].z << " , " << m[0].w << std::endl; これだと,行列を転置した形で見ていることになると思う.
退会済みユーザー

退会済みユーザー

2021/04/27 10:51

なるほど。ではこうでしょか? std::cout << m[1].x << " , " << m[1].x << " , " << m[2].x << " , " << m[3].x << std::endl;
fana

2021/04/27 11:00 編集

ベクトル自体も operator[] を持ってるから,2重ループとかで書けば楽かもね.
退会済みユーザー

退会済みユーザー

2021/04/27 11:00

なるほどありがとうざいます。
guest

回答1

0

ベストアンサー

glm::rorate();関数による回転後位置をその分ずらすことで解決しました。

cpp

1translate = glm::translate(translate, glm::vec3(-size.x * 0.5f, -size.y * 0.5f, 0)); //平行移動

投稿2021/04/27 10:48

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問