teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

提示文章を修正

2021/04/19 11:30

投稿

退会済みユーザー
title CHANGED
@@ -1,1 +1,1 @@
1
- glfwでキー押された瞬間の1フレームだけ取得したい
1
+ [GLFW] glfwSetKeyCallback()関数を使ってキー押された瞬間を検出したい
body CHANGED
@@ -1,115 +1,203 @@
1
- 提示サイトですがキーが押された1フレームだけ一だけを取得する」関数はあるのでしょうか?自分は押しているずーっif文通るコードしか作れず困っています。モード切り替えの再に一回だけif文の中を実行よう関数がほしいのですがどうすればいいのでしょうか?
2
- 提示サイトをgoogle翻訳に通して見てみましたがわかりません、むしろあるのでしょうか?自分はあると思います。
1
+ 提示コードの///コメン部内の部のコードですがglfwSetKeyCallback();イベント処理関数を使ってキーが押された瞬間返す方法知りたいです。提示画像ですが提示コードのように実装たのですがなぜ1という値が数フレーム返って来てしまいます。本来押された瞬間であれば1は一回だけで後は2の値が来はずなのですがログを見ると数フレーム来てしまっていま。こは何が原因なのでしょうか?
3
2
 
4
- 参考サイト: https://www.glfw.org/docs/3.3.2/group__input.html
5
3
 
6
4
 
5
+ 参考サイト: https://www.glfw.org/docs/latest/group__input.html#ga1caf18159767e761185e49a3be019f8d
7
6
 
7
+ ![イメージ説明](5ab6fd60b2faf850b37b3115bc174654.png)
8
8
 
9
+ ```cpp
10
+ //#define GLEW_STATIC //スタティックリンク
11
+ #include <iostream>
12
+ #include <fstream>
13
+ #include <cstdlib>
14
+ #include <vector>
15
+ #include <glew/include/GL/glew.h>
16
+ #include <glfw/include/GLFW/glfw3.h>
9
17
 
10
18
 
11
19
 
20
+ #include "Window.hpp"
21
+ #include "Shape.hpp"
22
+ #include "Shader.hpp"
12
23
 
13
- ```CPP
14
- //アップデート
15
- void Game::Update()
24
+ Object::Vertex rectangleVertex[4] =
16
25
  {
17
- if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(Window) != GL_FALSE)
18
- {
19
- mIsRunLoop = false;
26
+ {-0.5f,-0.5f},
27
+ {0.5f,-0.5f},
28
+ {0.5f,0.5f},
29
+ {-0.5f,0.5f}
20
- }
30
+ };
21
31
 
22
32
 
33
+ int main()
34
+ {
35
+ if (glfwInit() == GL_FALSE)
36
+ {
37
+ std::cerr << "glfw初期化失敗。" << std::endl;
38
+ return -1;
39
+ }
23
40
 
24
41
 
25
-
26
- if (glfwGetKey(Window, GLFW_KEY_F1) == GLFW_PRESS)
42
+ atexit(glfwTerminate); //プログラム終了時の処理を登録
27
- {
43
+ Window window;
28
44
 
29
- key = 0;
45
+ //OpenGL Verison 3.2 Core Profile を選択する
30
- printf("MODE: 移動\n");
46
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
47
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,2);
48
+ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE);
49
+ glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
31
50
 
32
- }
51
+ Shape* shape = new Shape(2, 4, rectangleVertex);
52
+
33
-
53
+ Shader shader("Test.vert","Test.frag");
54
+ shader.setBindAttribVertex(0, "Position");
55
+ shader.setBindAttribFragment(0, "fragment");
34
56
 
35
- //モード切り替え
36
- switch ( key ) {
37
57
 
38
- case 0: {
39
- //左右上下移動
40
- if (glfwGetKey(Window, GLFW_KEY_LEFT) == GLFW_PRESS)
58
+ glClearColor(1.0, 0.0, 0.0, 1.0); //背景色
59
+ while (window)
41
- {
60
+ {
61
+ glClear(GL_COLOR_BUFFER_BIT); //カラーバッファをクリア
42
- pos.x -= 0.03f;
62
+ shader.Active();
43
- pos.y += 0.0f;
63
+
44
- pos.z += 0.0f;
45
64
 
46
- Set_move(pos.x, pos.y, pos.z);
65
+
47
- printf("LEFT\n");
48
- }
49
- else if (glfwGetKey(Window, GLFW_KEY_RIGHT) == GLFW_PRESS)
66
+ printf(": %d\n", window.getKeyInput(GLFW_KEY_SPACE));
50
- {
51
67
 
52
- pos.x += 0.03f;
68
+
53
- pos.y -= 0.0f;
54
- pos.z -= 0.0f;
55
69
 
56
- Set_move(pos.x, pos.y, pos.z);
57
70
 
58
- printf("RIGHT\n");
59
- }
60
71
 
61
- if (glfwGetKey(Window, GLFW_KEY_UP) == GLFW_PRESS)
62
- {
63
72
 
64
- pos.x -= 0.0f;
65
- pos.y += 0.03f;
66
- pos.z -= 0.0f;
67
73
 
68
- Set_move(pos.x, pos.y, pos.z);
74
+ window.SwapBuffers(); //ダブルバッファリング
75
+ }
69
76
 
70
- printf("UP\n");
77
+ }
71
78
 
72
- }
79
+ ```
73
- else if (glfwGetKey(Window, GLFW_KEY_DOWN) == GLFW_PRESS)
74
- {
75
- pos.x -= 0.0f;
76
- pos.y -= 0.03f;
77
- pos.z -= 0.0f;
78
80
 
79
- Set_move(pos.x, pos.y, pos.z);
81
+ ```cpp
80
- printf("DOWN\n");
82
+ #include "Window.hpp"
81
- }
82
83
 
83
- //Z軸移動
84
+ //コンストラクタ
85
+ Window::Window(int width, int height, const char* title)
84
- if (glfwGetKey(Window, GLFW_KEY_Z) == GLFW_PRESS)
86
+ :window(glfwCreateWindow(width, height, title, NULL, NULL)),
87
+ wheel(0)
85
- {
88
+ {
89
+ std::fill(std::begin(keyStatus),std::end(keyStatus),0);
86
90
 
87
- pos.x -= 0.0f;
91
+ if (window == NULL)
92
+ {
93
+ std::cerr << "ウインドウ生成失敗" << std::endl;
88
- pos.y -= 0.0f;
94
+ exit(1);
89
- pos.z -= 0.03f;
95
+ }
90
96
 
97
+ glfwMakeContextCurrent(window); //コンテキストを作成
91
98
 
99
+ glewExperimental = GL_TRUE;
92
- Set_move(pos.x, pos.y, pos.z);
100
+ if (glewInit() != GLEW_OK)
101
+ {
93
- printf("Z: %.2f\n", pos.z);
102
+ std::cerr << "GLFW 初期化失敗" << std::endl;
103
+ exit(1);
94
- }
104
+ }
95
- else if (glfwGetKey(Window, GLFW_KEY_X) == GLFW_PRESS)
96
- {
97
105
 
106
+ atexit(glfwTerminate); //プログラム終了時の処理を登録
98
- pos.x += 0.0f;
107
+ glfwSwapInterval(1); //垂直同期
99
- pos.y += 0.0f;
100
- pos.z += 0.03f;
101
108
 
102
- Set_move(pos.x, pos.y, pos.z);
103
- printf("X: %.2f\n", pos.z);
104
- }
105
- }
106
- break;
107
109
 
110
+ //イベント処理
111
+ glfwSetWindowUserPointer(window, this); //このインスタンスのthis
112
+ glfwSetWindowSizeCallback(window, Resize); //ウインドウサイズを変更する時に呼び出す処理
113
+ glfwSetScrollCallback(window,Wheel); //マウスホイール操作時に呼び出す処理
114
+ //////////////////////////////////////////////////////////////////////////////////////////////
115
+ glfwSetKeyCallback(window, KeyBoard); //キー入力時に呼び出す処理
116
+ //////////////////////////////////////////////////////////////////////////////////////////////
108
117
 
109
118
 
119
+ Resize(window, width, height);
110
120
 
111
- }
121
+ }
112
122
 
123
+ //サイズ変更
124
+ void Window::Resize(GLFWwindow* const win, int width, int height)
125
+ {
126
+ int fbWidth, fbHeight;
127
+ glfwGetFramebufferSize(win, &fbWidth, &fbHeight);
128
+ glViewport(0, 0, fbWidth, fbHeight);
129
+
130
+ Window* const instance = (Window*)glfwGetWindowUserPointer(win);
131
+
132
+ if (instance != NULL)
133
+ {
134
+ instance->size.x = (GLfloat)width;
135
+ instance->size.y = (GLfloat)height;
136
+ }
113
137
  }
114
138
 
139
+ //ウインドウサイズを取得
140
+ const glm::vec2 Window::getSize() const
141
+ {
142
+ return size;
143
+ }
144
+
145
+
146
+ //キー入力を取得
147
+ const int Window::getKeyInput(int key)const
148
+ {
149
+ return keyStatus[key];
150
+ }
151
+
152
+ //マウスホイール
153
+ void Window::Wheel(GLFWwindow* win, double x, double y)
154
+ {
155
+ Window* const instance = (Window*)glfwGetWindowUserPointer(win);
156
+
157
+ if (instance != NULL)
158
+ {
159
+ instance->wheel += (GLfloat)y;
160
+ }
161
+ }
162
+
163
+ /////////////////////////////////////////////////////////////////////////////////////////////////
164
+ //キー入力
165
+ void Window::KeyBoard(GLFWwindow* win, int key, int scancode, int action, int mods)
166
+ {
167
+ Window* const instance = (Window*)glfwGetWindowUserPointer(win);
168
+
169
+ if (instance != NULL)
170
+ {
171
+ instance->keyStatus[key] = action;
172
+ }
173
+ }
174
+ ////////////////////////////////////////////////////////////////////////////////////////////////
175
+
176
+ //bool 演算子
177
+ Window::operator bool()
178
+ {
179
+ glfwPollEvents(); //イベントを取り出す
180
+
181
+ //ウインドウを閉じる必要があれば false
182
+ if (glfwWindowShouldClose(window) != 0)
183
+ {
184
+ return false;
185
+ }
186
+ else {
187
+ return true;
188
+ }
189
+ }
190
+
191
+ //ダブルバッファリング
192
+ void Window::SwapBuffers()const
193
+ {
194
+ glfwSwapBuffers(window);
195
+ }
196
+
197
+ //デストラクタ
198
+ Window::~Window()
199
+ {
200
+ glfwDestroyWindow(window);
201
+ }
202
+
115
203
  ```