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

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

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

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

解決済

[opengl] ライブラリ制作 ウインドウコンテキストの適切な持たせ方が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

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

2回答

0グッド

0クリップ

471閲覧

投稿2022/10/31 06:33

編集2022/10/31 07:29

提示コードですがRender.cppのgetScale_Sprite()関数で利用側でウインドウコンテキストを指定しているのですがこれはあまりよくないと思うのですが実際はどうするのが正解なのでしょうか?

1,現在ライブラリ側と利用側でプログラムを分けているのですがライブラリ側で公開するものとしてウインドウコンテキストはあまり正解ではないと思っていますなぜなら変更されると困るからです。

2,関数にウインドウコンテキストを設定すること自体がおかしいと思っています

Player のコンストラクタはどうやって呼んでいるのか(ライブラリ内? ライブラリ利用者?)

ライブラリ利用者のMain.cppで読んでいます。

Player::transform のコンストラクタ

transformのコンストラクタでは値を初期化しているだけです。継承等はしていません。

現状

windowsクラスで静的変数を用意してそれを利用側のMain.cppで確保して利用側の各所で使っています。

また複数のウインドウを用意したいと思っているのですがその場合、上記を踏まえた上でどういった実装が適切なのでしょうか?

Main.cpp

cpp

1 2int main() 3{ 4 if (glfwInit() != GLFW_TRUE) 5 { 6 assert(0 && "glfw 初期化失敗"); 7 } 8 9  //ウインドウコンテキスト確保 10 FrameWork::Window::windowContext = std::make_shared<FrameWork::Window>(glm::ivec2(800, 800), "Hello World"); 11 FrameWork::Window::windowContext->setCurrentContext(); 12 13 14 15 // OpenGL Verison 4.5 Core Profile 16 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 17 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5); 18 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 19 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 20 21 if (glewInit() != GLEW_OK) 22 { 23 assert(0 && "glew 初期化失敗"); 24 } 25
Windows.hpp

cpp

1class Window 2 { 3 4 public: 5 6 Window(const glm::ivec2 s,const char* t); //コンストラクタ 7 ~Window(); //デストラクタ 8 9 operator bool(); //bool 演算子 10 void SwapBuffers()const; //ダブルバッファリング 11 const glm::ivec2 getSize() const; //サイズ 12 void setCurrentContext(); //クライアントコンテキスト 13 14 //イベント処理 15 static void Resize_Event(GLFWwindow* win, const int width, const int height); //画面サイズ 16 static void DragAndDrop_Event(GLFWwindow* win, const int num, const char* str[]); //ドラック&ドロップ 17 static void MouseScroll_Event(GLFWwindow* win, const double x, const double y); //マウススクロール 18 static void KeyInputChar_Event(GLFWwindow* win, const unsigned int n); //テキスト入力 19 static void KeyInput_Event(GLFWwindow* win, const int key, const int scanCode, const int action, const int mods); //キー入力 20 static void MouseMove_Event(GLFWwindow* win, const double xpos, const double ypos); //マウス 21 22 23 bool getKeyInput(int keyCode); 24 25 static std::shared_ptr<FrameWork::Window> windowContext; 26 27 private: 28 29 std::string title; //ウインドウタイトル 30 glm::ivec2 size; //画面サイズ 31 32 GLFWwindow* window; //ウインドウコンテキスト 33 34 std::array<short int,GLFW_KEY_MENU> keyBoard; //キー入力 35 unsigned int inputKey; //テキスト入力 36 37 double mouseWheel; //マウスホイール 38 glm::dvec2 mousePosition; //マウス座標 39 std::vector<std::string> drop; //ドラック&ドロップ 40 }; 41 42
getMatScale_Sprite

cpp

1/*############################################################################################ 2# サイズケール 取得 3############################################################################################*/ 4glm::mat4 FrameWork::Transform::getMatScale_Sprite(const std::shared_ptr<FrameWork::Window> window)const 5{ 6 glm::vec2 size; 7 //UV座標 8 float sizeX = 1.0f / (float)window->getSize().x; 9 float sizeY = 1.0f / (float)window->getSize().y; 10 11 size.x = sizeX * 128; 12 size.y = sizeY * 128; 13 14 15 return glm::scale(glm::mat4(1), glm::vec3(size, 1.0f)); 16}
Render

cpp

1 2void Player::Render(const glm::mat4 view) 3{ 4 sprite.shader->setEnable(); 5 6 7 sprite.shader->setUniform4f("uFragment",glm::vec4(0.0,0.0,1.0,1.0)); 8 sprite.shader->setUniformMatrix4x4fv("uViewProjection", view); 9 sprite.shader->setUniformMatrix4x4fv("uScale", transform.getMatScale_Sprite(FrameWork::Window::windowContext)); 10 sprite.shader->setUniformMatrix4x4fv("uTranslate", transform.getMatPosition()); 11 sprite.shader->setUniformMatrix4x4fv("uRotate", transform.getMatRotate()); 12 13 sprite.Render(view); 14 15 sprite.shader->setDisable(); 16 17} 18 19void Player::Update() 20{ 21 //sprite.setTexture(0, texture.at(0)); 22} 23 24 25

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

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

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

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

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

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

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

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

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

int32_t

2022/10/31 07:18

「複数のウインドウを用意したい」==「複数の FrameWork::Window を同時に扱える必要がある」ということで間違いないですか? Player のコンストラクタはどうやって呼んでいるのか(ライブラリ内? ライブラリ利用者?)とか、Player::transform のコンストラクタはどうやって呼んでいるのかとかの情報があると答えやすいです。
退会済みユーザー

退会済みユーザー

2022/10/31 07:30

> 「複数のウインドウを用意したい」==「複数の FrameWork::Window を同時に扱える必要がある」 そうです。 FrameWork::Window::windowContextをライブラリ利用側で引数として記述するのを辞めたいそれでいて複数のウインドウを扱う場合の処理の書き方が知りたいです。
fana

2022/10/31 08:38

glfwWindowHint() のタイミング遅すぎたりしないんですかね,コレ.
退会済みユーザー

退会済みユーザー

2022/10/31 08:46

そうなのでしょうか?ではどの順番なのでしょうか?自分はこれで問題なのですが
fana

2022/10/31 08:55

glfwWindowHint() は,以降の glfwCreateWindow() に効いてくる物だから,大丈夫なん?って思っただけ. (実際にあなたがいつ glfwCreateWindow() を用いているか次第だけど,例えば Window 型のコンストラクタ内でやってるとしたら,その Main.cpp のコードだと順序が逆順になるんじゃね?,と.)

回答2

1

ベストアンサー

FrameWork::Window::windowContextをライブラリ利用側で引数として記述するのを辞めたいそれでいて複数のウインドウを扱う場合の処理の書き方が知りたいです。

複数の FrameWork::Window を扱いたいなら、それは基本的に辞められません。クラスのメソッドで必要になるなら、そのクラスのコンストラクタに渡すこともできます。

  • Window::setCurrentContext() は廃止
  • Window::windowContext は廃止
  • Player のコンストラクタに FrameWork::Window を渡して、Player のデータメンバとして保持しておく
  • Player::Render() では そのデータメンバを transform.getMatScale_Sprite() に渡す

投稿2022/10/31 07:49

int32_t

総合スコア17087

退会済みユーザー👍を押しています

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

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

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

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

回答へのコメント

退会済みユーザー

退会済みユーザー

2022/10/31 07:58

なるほどわかりました。現状の状態はどうなのでしょうか?
int32_t

2022/10/31 08:01

現状では複数のウィンドウのサポートはできませんよ。どうすればいいかは回答に書いてあります。
退会済みユーザー

退会済みユーザー

2022/10/31 08:14 編集

そうですかわかりました。 仮にウインドウが一つの場合だとGetWindowContext()的な関数を用意すれば問題はないのでしょうか?
int32_t

2022/10/31 15:31

> 仮にウインドウが一つの場合だとGetWindowContext()的な関数を用意すれば問題はないのでしょうか? そうですね。
退会済みユーザー

退会済みユーザー

2022/11/01 03:06

なるほど。質問ですが これまでのやり取り通り複数のウインドウがある場合は関数の引数にWindowsコンテキストを渡すしか方法はないということでしょうか?
int32_t

2022/11/01 11:10

既に何度も書いているとおり、関数の引数やクラスのデータメンバでWindowを渡しましょう。 それ以外の方法が皆無ではないですが、マトモな方法ではないので実用にはなりません。

0

getScale_Sprite()関数で利用側でウインドウコンテキストを指定しているのですがこれはあまりよくないと思うのですが

っていう話だけど,じゃあ getMatScale_Sprite() が何やってるのか?っていうと,単に getSize() なるメソッドの結果が欲しいだけである様子.

「だったら,getMatScale_Sprite() の引数を glm::ivec2 型にすればいいんじゃね?」と思うのですが.


Window 型自体を公開すること自体どうなのか? とお思いなのであれば,「公開しない」形を検討してみればよいのでは.
そういう方向のやり方に関しては,他の質問で回答もらってますよね
(そもそも GLFW の GLFWwindow 型ってのがまさにそんな感じですよね.)

投稿2022/10/31 09:05

編集2022/10/31 09:14
fana

総合スコア10641

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

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

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

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

回答へのコメント

退会済みユーザー

退会済みユーザー

2022/10/31 12:15

> 単に getSize() なるメソッドの結果が欲しいだけである様子. その引数にウインドウコンテキストを引数として渡す必要があるあら悩んでいるのですw戻り値は問題なのですが
fana

2022/11/01 01:11

Window::getSize() が返してくる glm::ivec2 型データにしか用が無いのであれば,引数としてWindowを要求する必要性はない.用があるデータだけを引数として受け取れば十分なんじゃないの? つまり,Window::getSize() を呼ぶことは getMatScale_Sprite() の外側でやればいいよね. っていう話なんだけど.

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

ただいまの回答率
86.12%

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

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

質問する

関連した質問

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

C++

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