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

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

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

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

C++

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

受付中

[OpenGL] 画面サイズを変えると描画位置がおかしくなる原因が知りたい

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

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

C++

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

1回答

0グッド

0クリップ

767閲覧

投稿2022/04/23 10:28

編集2022/04/29 07:30

提示画像ですが一枚目は実行時で二枚目は画面を横伸ばしした時の画像ですが画面サイズが変わっても同じように画面の中央に表示させるにはどうすればいいのでしょうか?画面サイズがリサイズされた際に ビューポートのサイズを変更して透視投影行列の行列を画面サイズのアスペクト比に毎フレーム変更を適用しているのですがこれはなぜでしょうか?カスタムフレームバッファを利用しています。

ソースファイル全文:https://29.gigafile.nu/0501-d7dcf96b048a4eb8c01e1935fd44736de

現状

1,リサイズイベントを実装しています。
2,ビューポートで画面サイズを変更した際に再設定しています。
3,画面サイズがリサイズされた際に ビューポートのサイズを変更して透視投影行列の行列を画面サイズのアスペクト比に毎フレーム変更を適用
4,カスタムフレームバッファを利用しています。

参考サイト

https://tatsy.github.io/OpenGLCourseJP/window_resize/

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

Window.cpp

cpp

1 2 glfwSetWindowSizeCallback(window, Resize_Event); //ウインドウサイズ 3// ##################################### イベント処理 画面サイズ変更 ##################################### 4void FrameWork::Window::Resize_Event(GLFWwindow* const win, int width, int height) 5{ 6 int fbWidth, fbHeight; 7 glfwGetFramebufferSize(win, &fbWidth, &fbHeight); 8 glViewport(0, 0, fbWidth, fbHeight); 9 10 Window* const instance = (Window*)glfwGetWindowUserPointer(win); 11 12 if (instance != NULL) 13 { 14 instance->size.x = (GLfloat)fbWidth; 15 instance->size.y = (GLfloat)fbHeight; 16 } 17} 18
Camera.cpp

cpp

1//一部抜粋 2// ##################################### 透視投影行列 ##################################### 3glm::mat4 FrameWork::Camera::getViewPerspective() 4{ 5 return glm::perspective(glm::radians(90.0f), ((float)currentWindow->getSize().x / (float)currentWindow->getSize().y), 0.1f, 1000.0f) * view; 6}
Sprite.cpp

cpp

1 2// ##################################### テクスチャ描画 公開 ##################################### 3void FrameWork::RenderGraph(const glm::mat4 view,const glm::vec3 position,const FrameWork::Texture texture) 4{ 5 FrameWork::sprite->Render(view,position,texture); 6} 7 8// ##################################### コンストラクタ ##################################### 9FrameWork::Sprite::Sprite() : FrameWork::Transform() 10{ 11 vao = 0; 12 vbo = 0; 13 14 glGenVertexArrays(1, &vao); 15 glGenBuffers(1, &vbo); 16 17 glBindVertexArray(vao); 18 glBindBuffer(GL_ARRAY_BUFFER, vbo); 19 20 21 shader = std::make_unique<Shader>(); 22 shader->Load("Asset/shader/2D/BasicTexture_2D.vert","Asset/shader/2D/BasicTexture_2D.frag"); 23 24 shader->setEnable(); 25 26 glBufferData(GL_ARRAY_BUFFER, vertex.size() * sizeof(VertexAttribute), (float*)vertex.data(), GL_DYNAMIC_DRAW); 27 28 GLuint attrib = shader->getAttribLocation("vertexPosition"); 29 glEnableVertexAttribArray(attrib); 30 glVertexAttribPointer(attrib, 3, GL_FLOAT, GL_FALSE, (sizeof(VertexAttribute) / sizeof(float)) * sizeof(float), (GLvoid*)(sizeof(GLfloat) * 0)); 31 shader->setBindAttribLocation("vertexPosition"); 32 33 attrib = shader->getAttribLocation("vertexUV"); 34 glEnableVertexAttribArray(attrib); 35 glVertexAttribPointer(attrib, 2, GL_FLOAT, GL_FALSE, (sizeof(VertexAttribute) / sizeof(float)) * sizeof(float), (GLvoid*)(sizeof(GLfloat) * 3)); 36 shader->setBindAttribLocation("vertexUV"); 37 38 shader->setDisable(); 39 glBindVertexArray(0); 40 glBindBuffer(GL_ARRAY_BUFFER, 0); 41 42 43} 44 45// ##################################### テクスチャ描画 ##################################### 46void FrameWork::Sprite::Render(const glm::mat4 view,const glm::vec3 position,const FrameWork::Texture texture) 47{ 48 shader->setEnable(); 49 glm::vec2 screenSize = glm::vec2(1.0f / FrameWork::currentWindow->getSize().x,1.0f / FrameWork::currentWindow->getSize().y); 50 glBindVertexArray(vao); 51 glBindBuffer(GL_ARRAY_BUFFER, vbo); 52 53 setSize(glm::ivec2(0,0),texture.size); 54 setUV(glm::ivec2(0,0),texture.size,texture.size); 55 56 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(VertexAttribute) * vertex.size(), vertex.data()); 57 58 Transform::setPosition(glm::vec3(screenSize.x * position.x,screenSize.y * position.y,0)); 59 Transform::setPosition(glm::vec3(position.x,position.y,0)); 60 Transform::setRotate(glm::vec3(0, 0, 1), 0); 61 Transform::setScale(glm::vec3(texture.size,1)); 62 63 shader->setUniformSampler2D("uImage",0,texture.ID); 64 shader->setUniformMatrix4fv("uTranslate", Transform::getMatTranslation()); 65 shader->setUniformMatrix4fv("uRotate", Transform::getMatRotate()); 66 shader->setUniformMatrix4fv("uScale", Transform::getMatScale()); 67 shader->setUniformMatrix4fv("uViewProjection", view); 68 69 glDrawArrays(GL_TRIANGLES,0,vertex.size()); 70 71 glBindVertexArray(0); 72 glBindBuffer(GL_ARRAY_BUFFER, 0); 73 shader->setDisable(); 74 75} 76 77// ##################################### 頂点 ##################################### 78void FrameWork::Sprite::setSize(const glm::vec2 startSize,const glm::vec2 endSize) 79{ 80 81 glm::vec2 scr = glm::ivec2(1,1); 82 scr.x = 1.0f/ 2.0f; 83 scr.y = 1.0f/ 2.0f; 84 85 // 頂点座標 86 vertex[0].position.x = -scr.x; 87 vertex[0].position.y = scr.y; 88 vertex[0].position.z = 0; 89 90 vertex[1].position.x = -scr.x; 91 vertex[1].position.y = -scr.y; 92 vertex[1].position.z = 0; 93 94 vertex[2].position.x = scr.x; 95 vertex[2].position.y = scr.y; 96 vertex[2].position.z = 0; 97 98 vertex[3].position.x = scr.x; 99 vertex[3].position.y = scr.y; 100 vertex[3].position.z = 0; 101 102 vertex[4].position.x = -scr.x; 103 vertex[4].position.y = -scr.y; 104 vertex[4].position.z = 0; 105 106 vertex[5].position.x = scr.x; 107 vertex[5].position.y = -scr.y; 108 vertex[5].position.z = 0; 109 110 111} 112 113 114 115 116// ##################################### 頂点 ##################################### 117void FrameWork::Sprite::setUV(const glm::vec2 startSize, const glm::vec2 endSize,const glm::ivec2 textureSize) 118{ 119 glm::vec2 size = endSize - startSize; 120 121 122 //UV座標 123 float sizeX = 1.0f / (float)textureSize.x; 124 float sizeY = 1.0f / (float)textureSize.y; 125 126 FrameWork::Sprite::vertex[0].uv.x = sizeX * startSize.x; 127 FrameWork::Sprite::vertex[0].uv.y = sizeY * startSize.y; 128 129 FrameWork::Sprite::vertex[1].uv.x = sizeX * startSize.x; 130 FrameWork::Sprite::vertex[1].uv.y = sizeY * endSize.y; 131 132 FrameWork::Sprite::vertex[2].uv.x = sizeX * endSize.x; 133 FrameWork::Sprite::vertex[2].uv.y = sizeY * startSize.y; 134 135 FrameWork::Sprite::vertex[3].uv.x = sizeX * endSize.x; 136 FrameWork::Sprite::vertex[3].uv.y = sizeY * startSize.y; 137 138 FrameWork::Sprite::vertex[4].uv.x = sizeX * startSize.x; 139 FrameWork::Sprite::vertex[4].uv.y = sizeY * endSize.y; 140 141 FrameWork::Sprite::vertex[5].uv.x = sizeX * endSize.x; 142 FrameWork::Sprite::vertex[5].uv.y = sizeY * endSize.y; 143} 144 145 146FrameWork::Sprite::~Sprite() 147{ 148 149}

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

2022/04/23 14:23依頼された後にこの質問は修正されています

こちらの質問が複数のユーザーから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました。

回答1

0

ビューポート変換は投影された映像をスクリーン座標に変換する処理なのでビューポートを変更するだけでは投影された内容を画面のサイズにリサイズして表示しているような結果になると思います。
提示された画像でもテクスチャの表示サイズも変わっているように見えます。
描画部分のコードを見ていないので正確ではないかもしれませんが
リサイズイベントで射影行列を再生成するなどする必要があるのではないでしょうか?

cpp

1mat4 projectionMatrix; 2void FrameWork::Window::Resize_Event(GLFWwindow* const win, int width, int height) 3{ 4 int fbWidth, fbHeight; 5 glfwGetFramebufferSize(win, &fbWidth, &fbHeight); 6 glViewport(0, 0, fbWidth, fbHeight); 7 projectionMatrix = mat4.ortho( -fbWidth / 2, fbWidth / 2, -fbHeight / 2, fbHeight / 2, -1, 1 ); //射影行列を再生成 8 9 Window* const instance = (Window*)glfwGetWindowUserPointer(win); 10 11 if (instance != NULL) 12 { 13 instance->size.x = (GLfloat)width; 14 instance->size.y = (GLfloat)height; 15 } 16}

投稿2022/04/23 11:35

Rei_312

総合スコア24

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

回答へのコメント

退会済みユーザー

退会済みユーザー

2022/04/24 02:30

なるほどありがとうざいます。以下のようにアスペクト比を取得画面サイズごとに設定しているのですがこれはなぜでしょうか? // ##################################### 透視投影行列 ##################################### glm::mat4 FrameWork::Camera::getViewPerspective() { return glm::perspective(glm::radians(90.0f), ((float)currentWindow->getSize().x / (float)currentWindow->getSize().y), 0.1f, 1000.0f) * view; }
Rei_312

2022/04/24 06:24

描画部分のコードを載せていただけますか? もしかするとそちらに原因があるかもしれません。
退会済みユーザー

退会済みユーザー

2022/04/24 08:55

はい。スプライト描画部を公開しました。またソースファイル全文も公開しました。

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

同じタグがついた質問を見る

OpenGL

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

C++

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