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

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

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

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

C++

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

Q&A

1回答

1555閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

OpenGL

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

C++

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

0グッド

0クリップ

投稿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}

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

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

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

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

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

guest

回答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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問