🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
OpenGL

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

C++

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

Q&A

解決済

3回答

1786閲覧

回転行列が上手く動作しない理由が知りたい。 中心を中心回転させたい。

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

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

C++

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

0グッド

0クリップ

投稿2021/02/14 03:22

編集2021/02/15 12:21

提示画像ですが移動して左キーを押すと座標はそのままで画像が上に移動してしまうのですがこれは何が原因なのでしょか?画像サイズはこの砲弾の画像の大きさが読み込んでいます。22,28
提示コードの/////コメント部の内部の回転行列の行列部が悪いと思うのですが何を間違えてのでしょうか?よく考えましたがどうしてもわかりません。
描画原点を中心に回転してしまうのですがどうすれば中心を中心に回転するのでしょうか?

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

cpp

1#include "../Header/Sprite.hpp" 2#include "../Header/Shader.hpp" 3#include "../Header/Entry.hpp" 4#include "../Header/LoadTexture.hpp" 5#include "../Header/VertexData.hpp" 6 7// 数学ライブラリ 8#include "glm/ext.hpp" 9#include "glm/glm.hpp" 10 11#include <vector> 12 13// OpenCV 14#include <opencv2/core.hpp> 15 16/*################################################################################################################ 17* 画像 描画クラス 18################################################################################################################*/ 19 20//コンストラクタ 21/* 22* Entry クラス 23* テクスチャ パス 24* 描画する画像の寸法 25*/ 26Sprite::Sprite(class Entry* g, std::shared_ptr<TextureData> sp ) : Transform_2D(g) 27{ 28 shader = std::make_shared<class Shader>(g,"Shader/2D/Sprite.vert", "Shader/2D/Sprite.frag"); 29 30 Owner = g;//Entryクラス 31 32 Transform_2D::setTransfrom(glm::vec2(1,1),0,glm::vec2(0,0)); //トランスフォームを初期化 33 34 //テクスチャを設定 35 glGenTextures(1, &TextureID); 36 glBindTexture(GL_TEXTURE_2D, TextureID); 37 38 //画像の大きさ 39 mPicSize.x = (float)sp->mSize.x; 40 mPicSize.y = (float)sp->mSize.y; 41 42 43// printf("%d\n",sp->mData->size()); 44 45 46 if (sp->mData->data() != NULL) 47 { 48 if (sp->channels == 3) 49 { 50 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, (GLsizei)sp->mSize.x, (GLsizei)sp->mSize.y, 0, GL_RGB, GL_UNSIGNED_BYTE, sp->mData->data()); 51 } 52 else if (sp->channels == 4) 53 { 54 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)sp->mSize.x, (GLsizei)sp->mSize.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, sp->mData->data()); 55 } 56 } 57 else { 58 std::cerr << "Unable to load texture: " <<std::endl; 59 } 60 61 62 //ミニマップを設定 63 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 64 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 65 glGenerateMipmap(GL_TEXTURE_2D); 66 67 //異方性フィルタリングを設定 68 GLfloat largest; 69 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &largest); 70 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, largest); 71 72 73 74 75 //VAO 76 glGenVertexArrays(1, &VAO); 77 glBindVertexArray(VAO); 78 79 //VBO 80 glGenBuffers(1, &VBO); 81 glBindBuffer(GL_ARRAY_BUFFER, VBO); 82 glBufferData(GL_ARRAY_BUFFER, (sizeof(vertex) / sizeof(vertex[0])) * sizeof(VertexAttribute_2D), vertex, GL_STATIC_DRAW); 83 84 85 86} 87 88//描画 89void Sprite::DrawGraph(glm::ivec2 pos, glm::vec2 start, glm::vec2 end) 90{ 91 92 glm::vec2 mSize; 93 94 mSize = end - start; //描画範囲を取得 95 96 if (mSize.x > mPicSize.x) 97 { 98 mSize.x = mPicSize.x; 99 } 100 101 if (mSize.y > mPicSize.y) 102 { 103 mSize.y = mPicSize.y; 104 } 105 106 //左上が原点になるように修正 107 //pos.x = (-SCREEN_WIDTH / 2) + (pos.x); 108 //pos.y = (SCREEN_HEIGHT / 2) + (pos.y); 109 110 111 shader->Enable(); //シェーダーを有効にする 112 shader->SetFloatUniform_3m("uViewMatrix", getViewMatrix()); 113 shader->SetFloatUniform_3m("uWorldMatrix", getWorldMatrix()); 114 115 Transform_2D::setTransform_Move(pos); //移動 116 117 /* // 描画座標の中心に画像を描画 118 vertex[0] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f, start.x / mPicSize.x ,start.y / mPicSize.y }; 119 vertex[1] = VertexAttribute_2D{ -mSize.x / 2.0f,-mSize.y / 2.0f, start.x / mPicSize.x ,end.y / mPicSize.y }; 120 vertex[2] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f, end.x / mPicSize.x ,end.y / mPicSize.y }; 121 vertex[3] = VertexAttribute_2D{ -mSize.x / 2.0f,mSize.y / 2.0f, start.x / mPicSize.x ,start.y / mPicSize.y }; 122 vertex[4] = VertexAttribute_2D{ mSize.x / 2.0f,-mSize.y / 2.0f, end.x / mPicSize.x ,end.y / mPicSize.y }; 123 vertex[5] = VertexAttribute_2D{ mSize.x / 2.0f,mSize.y / 2.0f, end.x / mPicSize.x ,start.y / mPicSize.y }; 124 */ 125 126 //左上が原点 127 vertex[0] = VertexAttribute_2D{ 0,0, start.x / mPicSize.x ,start.y / mPicSize.y }; 128 vertex[1] = VertexAttribute_2D{ 0,-mSize.y, start.x / mPicSize.x ,end.y / mPicSize.y }; 129 vertex[2] = VertexAttribute_2D{ mSize.x,-mSize.y, end.x / mPicSize.x ,end.y / mPicSize.y }; 130 131 132 vertex[3] = VertexAttribute_2D{ 0 ,0, start.x / mPicSize.x ,start.y / mPicSize.y }; 133 vertex[4] = VertexAttribute_2D{ mSize.x,-mSize.y, end.x / mPicSize.x ,end.y / mPicSize.y }; 134 vertex[5] = VertexAttribute_2D{ mSize.x, 0, end.x / mPicSize.x ,start.y / mPicSize.y }; 135 136 137 138 139 //VAO 140 glBindVertexArray(VAO); 141 142 //VBO 143 glBindBuffer(GL_ARRAY_BUFFER, VBO); 144 glBufferData(GL_ARRAY_BUFFER, (sizeof(vertex) / sizeof(vertex[0])) * sizeof(VertexAttribute_2D), vertex, GL_STATIC_DRAW); 145 146 //頂点座標 147 glEnableVertexAttribArray(0); 148 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexAttribute_2D), NULL); 149 150 //UV座標 151 glEnableVertexAttribArray(1); 152 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexAttribute_2D), (void*)(sizeof(float) * 2)); 153 154 glBindVertexArray(VAO); 155 glBindTexture(GL_TEXTURE_2D, TextureID); 156 glDrawArrays(GL_TRIANGLES, 0, (GLsizei)std::size(vertex)); 157 158} 159 160 161 162// 画像サイズを取得 163glm::vec2 Sprite::getSize() 164{ 165 return mPicSize; 166} 167 168 169//コンストラクタ 170Sprite::Sprite(const Sprite & sp) : Transform_2D(sp.Owner) 171{ 172 shader = std::make_shared<Shader>(sp.Owner, "Shader/2D/Sprite.vert", "Shader/2D/Sprite.frag"); 173 Owner = sp.Owner; //Entryクラス 174 mPicSize.x = sp.mPicSize.x; 175 mPicSize.y = sp.mPicSize.y; 176 177} 178 179 180// デストラクタ 181Sprite::~Sprite() 182{ 183 // バッファを解放 184 glDeleteBuffers(1, &VAO); 185 glDeleteVertexArrays(1, &VAO); 186 187 glBindVertexArray(0); 188 glBindTexture(GL_TEXTURE_2D, 0); 189 190 glDeleteTextures(1,&TextureID); 191 192} 193

cpp

1#include "../Header/Transform_2D.hpp" 2#include "../Header/Entry.hpp" 3 4//コンストラクタ 5Transform_2D::Transform_2D(class Entry* g) 6{ 7 Owner = g; //Entryクラス 8 9 //回転行列を初期化 10 mRotate_matrix = glm::mat3(0); 11 mRadian = 0; 12 13 //拡大縮小行列を初期化 14 mScale_matrix = glm::mat3(0); 15 16 //平行移動行列を初期化 17 mMove_matrix = glm::mat3(0); 18 19 20 mScale = glm::vec2(1,1); //スケール 21 mRadian = 0; //回転 22 mMove = glm::vec2(0, 0); //平行移動 23 24 //初期化 25 setTransform_Scale(mScale); 26 setTransform_Rotate(mRadian); 27 setTransform_Move(mMove); 28} 29 30void Transform_2D::UpdateTransform() 31{ 32 setTransform_Scale(mScale); 33 setTransform_Rotate(mRadian); 34 setTransform_Move(mMove); 35} 36 37// 同時に初期化 38void Transform_2D::setTransfrom(glm::vec2 s, float r, glm::vec2 m) 39{ 40 setTransform_Scale(s); 41 setTransform_Rotate(r); 42 setTransform_Move(m); 43} 44 45///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 46//回転行列 47void Transform_2D::setTransform_Rotate(float r) 48{ 49 float sc[9]; 50 sc[0] = cos(r); 51 sc[1] = -sin(r); 52 sc[2] = 0; 53 54 sc[3] = sin(r); 55 sc[4] = cos(r); 56 sc[5] = 0; 57 58 sc[6] = 0; 59 sc[7] = 0; 60 sc[8] = 1; 61 62 glm::mat3 t = glm::make_mat3(sc); 63 mRotate_matrix = t; 64 65 mRadian = r; 66} 67/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 68//拡大縮小 69void Transform_2D::setTransform_Scale(glm::vec2 p) 70{ 71 float sc[9]; 72 sc[0] = p.x; 73 sc[1] = 0; 74 sc[2] = 0; 75 76 sc[3] = 0; 77 sc[4] = p.y; 78 sc[5] = 0; 79 80 sc[6] = 0; 81 sc[7] = 0; 82 sc[8] = 1; 83 84 glm::mat3 t = glm::make_mat3(sc); 85 mScale_matrix = t; 86} 87 88//平行移動 89void Transform_2D::setTransform_Move(glm::vec2 p) 90{ 91 float m[9]; 92 93 m[0] = 1; 94 m[1] = 0; 95 m[2] = p.x; 96 97 m[3] = 0; 98 m[4] = 1; 99 m[5] = p.y; 100 101 m[6] = 0; 102 m[7] = 0; 103 m[8] = 1; 104 105 106 glm::mat3 tt = glm::make_mat3(m); 107 mMove_matrix = tt; 108 109 mMove = p; 110 111} 112 113//回転 114glm::mat3 Transform_2D::getRotate() 115{ 116 return mRotate_matrix; 117} 118 119//平行移動 120glm::mat3 Transform_2D::getMove() 121{ 122 return mMove_matrix; 123} 124//拡大縮小 125glm::mat3 Transform_2D::getScale() 126{ 127 return mScale_matrix; 128} 129 130 131float Transform_2D::getTransform_getRotate() 132{ 133 return mRadian; 134} 135 136glm::vec2 Transform_2D::getTransform_Scale() 137{ 138 return mScale; 139} 140 141glm::vec2 Transform_2D::getTransform_Move() 142{ 143 return mMove; 144} 145 146 147 148//ワールド行列 149glm::mat3 Transform_2D::getWorldMatrix() 150{ 151 glm::mat3 r = mScale_matrix * mRotate_matrix * mMove_matrix; 152 153 return r; 154} 155 156//ビュー行列 157glm::mat3 Transform_2D::getViewMatrix() 158{ 159 //ビュー行列 160 float sv[9]; 161 sv[0] = (2.0f / SCREEN_WIDTH); 162 sv[1] = 0.0f; 163 sv[2] = 0.0f; 164 165 sv[3] = 0.0f; 166 sv[4] = (2.0f / SCREEN_HEIGHT); 167 sv[5] = 0.0f; 168 169 sv[6] = 0.0f; 170 sv[7] = 0.0f; 171 sv[8] = 1.0f; 172 173 ViewMatrix = glm::make_mat3(sv); 174 175 return ViewMatrix; 176} 177 178 179

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

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

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

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

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

txty

2021/02/14 04:19 編集

positionの単位はpxでいいんですかでも,pxなら1画素ですよね。何をもってその数値なんでしょうか なんか間違えてますか。
退会済みユーザー

退会済みユーザー

2021/02/14 04:35 編集

2Dの行列を使っているのですがどういうことなのでしょうか?
txty

2021/02/14 04:38

500 -370 の単位が知りたいだけです 質問の解答じゃないです
退会済みユーザー

退会済みユーザー

2021/02/15 12:17

文章を修正しました。
int32_t

2021/02/16 01:05

コードは精読していませんが、座標の原点は画面中央で、キャラクターに180度の回転行列を適用すると、原点を中心に回転してしまうが、キャラクターの中心を中心に回転させたい、という理解で合ってますか?
退会済みユーザー

退会済みユーザー

2021/02/16 01:07

そうですね。この画像と状態を見るにおそらくそいうことが起きてほしいのでだと思います。
guest

回答3

0

ベストアンサー

(※強引な「エスパー回答」的なものになるかと思うので,間違いだと判断できた方はその旨をコメントとして示しつつ低評価していただきたく)

glm::mat3 Transform_2D::getWorldMatrix()の返す行列の内容が
glm::mat3 r = mScale_matrix * mRotate_matrix * mMove_matrix;であること
と,
その行列の用いられ方との間に齟齬があることが(左を押すと上に行くみたいな)問題現象の原因ではないかと想像します.

この行列が
shader->SetFloatUniform_3m("uWorldMatrix", getWorldMatrix());
としてシェーダに渡された後で実際にどのように使用されているのかは示されていませんが,頂点座標ベクトルに左からかける:

(mScale_matrix * mRotate_matrix * mMove_matrix) * 頂点座標

という形で用いるのだとすれば,この演算は

mScale_matrix * ( mRotate_matrix * ( mMove_matrix * 頂点座標 ) )

ということであり,
真っ先に mMove_matrix が適用される形となります.
その結果座標に対して mRotate_matrix を適用した結果の座標というのはどこに行くのか? ということを再確認されると良いのではないでしょうか.

投稿2021/02/17 05:33

編集2021/02/17 05:34
fana

総合スコア11985

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

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

退会済みユーザー

退会済みユーザー

2021/02/17 09:42

自分の能力では不可能と判断しました。
guest

0

(微塵もコードを読まずに回答します。OpenGLの知識はないのでコードでの回答はできません。)

キャラクターの中心点を中心として回転をさせたい場合は、

  1. キャラクターの座標から、キャラクターの中心点を引いて、原点に移動させる
  2. 結果の座標に回転行列を適用する
  3. 結果の座標に、手順1で引いたキャラクター中心点を足す

という計算をすればよいはずです。
(これを一つの行列計算でやることが可能だった気がしますが、それは無くても動くし、必要ならご自分で調べてください)

投稿2021/02/16 01:19

int32_t

総合スコア21679

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

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

0

おそらくmSpriteの内部実装と思われます。なんとなくですが setTransform_Rotate の回転の機能が移動と描画に対して整理されておらず、うまく作用していないような気がします。

投稿2021/02/14 03:55

Serbonis

総合スコア586

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

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

退会済みユーザー

退会済みユーザー

2021/02/14 04:26

提示コードを修正しました。 またそのコードを確認しましたがないもおかしな点は見つかりせん 他の原因では何が考えられるのでしょうか?
Serbonis

2021/02/14 08:54

DrawGraphのvertexの値を確認してみてはいかがでしょうか?あと最初に掲示していたコードを消してしまうと、わかりにくくなるかと思います。
退会済みユーザー

退会済みユーザー

2021/02/15 08:27

確認しましたが不審点は見つかりません、どこが悪いのでしょうか?
Serbonis

2021/02/15 09:52

WorldMatrixとViewMatrixが想定している値になっているか確認されてまではいかがでしょうか?ここまでの流れからすると、とりあえずWorldMatrixには回転成分は入ってないものかと思います。
退会済みユーザー

退会済みユーザー

2021/02/15 10:23

確認しましたが入ってますwwwどうしたらいいのでしょうか? //ワールド行列を生成 glm::mat4 Transform::getWorldMatrix() { glm::mat4 m = getMove() * getScale() * getRotate(); return m; }
Serbonis

2021/02/15 10:36

言い方が間違っていました回転成分自体は必ず入っています。ただ今回のこの状況では回転角度0の成分になっているのではないでしょうか?という意味です。回転角度0ではない回転行列になってしまっている場合はそうなった箇所を自身で特定・修正するしかありません。
退会済みユーザー

退会済みユーザー

2021/02/15 10:39

わからないので4方向分のスプライトを用意することにしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問