質問編集履歴

1

提示文章を修正

2021/04/19 11:30

投稿

退会済みユーザー
test CHANGED
@@ -1 +1 @@
1
- glfwキー押された瞬間の1フレームだけ取得したい
1
+ [GLFW] glfwSetKeyCallback()関数を使ってキー押された瞬間を検出したい
test CHANGED
@@ -1,224 +1,152 @@
1
- 提示サイトですがキーが押された1フレームだけ一だけを取得する」関数はあるのでしょうか?自分は押しているずーっif文通るコードしか作れず困っています。モード切り替えの再に一回だけif文中を実行できよう関数がほしいのですがどうすればいいのでしょうか?
2
-
3
- 提示サイトをgoogle翻訳に通して見てみましたがわかりません、むしろあるのでしょうか?自分はあると思います。
4
-
5
-
6
-
7
- 参考サイト: https://www.glfw.org/docs/3.3.2/group__input.html
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
- ```CPP
26
-
27
- //アップデート
28
-
29
- void Game::Update()
30
-
31
- {
32
-
33
- if (glfwGetKey(Window, GLFW_KEY_ESCAPE) == GLFW_PRESS || glfwWindowShouldClose(Window) != GL_FALSE)
34
-
35
- {
36
-
37
- mIsRunLoop = false;
38
-
39
- }
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
- if (glfwGetKey(Window, GLFW_KEY_F1) == GLFW_PRESS)
52
-
53
- {
54
-
55
-
56
-
57
- key = 0;
58
-
59
- printf("MODE: 移動\n");
60
-
61
-
62
-
63
- }
64
-
65
-
66
-
67
-
68
-
69
- //モード切り替え
70
-
71
- switch ( key ) {
72
-
73
-
74
-
75
- case 0: {
76
-
77
- //左右上下移動
78
-
79
- if (glfwGetKey(Window, GLFW_KEY_LEFT) == GLFW_PRESS)
80
-
81
- {
82
-
83
- pos.x -= 0.03f;
84
-
85
- pos.y += 0.0f;
86
-
87
- pos.z += 0.0f;
88
-
89
-
90
-
91
- Set_move(pos.x, pos.y, pos.z);
92
-
93
- printf("LEFT\n");
94
-
95
- }
96
-
97
- else if (glfwGetKey(Window, GLFW_KEY_RIGHT) == GLFW_PRESS)
98
-
99
- {
100
-
101
-
102
-
103
- pos.x += 0.03f;
104
-
105
- pos.y -= 0.0f;
106
-
107
- pos.z -= 0.0f;
108
-
109
-
110
-
111
- Set_move(pos.x, pos.y, pos.z);
112
-
113
-
114
-
115
- printf("RIGHT\n");
116
-
117
- }
118
-
119
-
120
-
121
- if (glfwGetKey(Window, GLFW_KEY_UP) == GLFW_PRESS)
122
-
123
- {
124
-
125
-
126
-
127
- pos.x -= 0.0f;
128
-
129
- pos.y += 0.03f;
130
-
131
- pos.z -= 0.0f;
132
-
133
-
134
-
135
- Set_move(pos.x, pos.y, pos.z);
136
-
137
-
138
-
139
- printf("UP\n");
140
-
141
-
142
-
143
- }
144
-
145
- else if (glfwGetKey(Window, GLFW_KEY_DOWN) == GLFW_PRESS)
146
-
147
- {
148
-
149
- pos.x -= 0.0f;
150
-
151
- pos.y -= 0.03f;
152
-
153
- pos.z -= 0.0f;
154
-
155
-
156
-
157
- Set_move(pos.x, pos.y, pos.z);
158
-
159
- printf("DOWN\n");
160
-
161
- }
162
-
163
-
164
-
165
- //Z軸移動
166
-
167
- if (glfwGetKey(Window, GLFW_KEY_Z) == GLFW_PRESS)
168
-
169
- {
170
-
171
-
172
-
173
- pos.x -= 0.0f;
174
-
175
- pos.y -= 0.0f;
176
-
177
- pos.z -= 0.03f;
178
-
179
-
180
-
181
-
182
-
183
- Set_move(pos.x, pos.y, pos.z);
184
-
185
- printf("Z: %.2f\n", pos.z);
186
-
187
- }
188
-
189
- else if (glfwGetKey(Window, GLFW_KEY_X) == GLFW_PRESS)
190
-
191
- {
192
-
193
-
194
-
195
- pos.x += 0.0f;
196
-
197
- pos.y += 0.0f;
198
-
199
- pos.z += 0.03f;
200
-
201
-
202
-
203
- Set_move(pos.x, pos.y, pos.z);
204
-
205
- printf("X: %.2f\n", pos.z);
206
-
207
- }
208
-
209
- }
210
-
211
- break;
212
-
213
-
214
-
215
-
216
-
217
-
218
-
219
-
220
-
221
- }
1
+ 提示コードの///コメン部内の部のコードですがglfwSetKeyCallback();イベント処理関数を使ってキーが押された瞬間返す方法知りたいです。提示画像ですが提示コードのように実装たのですがなぜ1という値が数フレーム返って来てしまいます。本来押された瞬間であれば1は一回だけで後は2値が来はずなのですがログを見ると数フレーム来てしまっていま。こは何が原因なのでしょうか?
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+ 参考サイト: https://www.glfw.org/docs/latest/group__input.html#ga1caf18159767e761185e49a3be019f8d
10
+
11
+
12
+
13
+ ![イメージ説明](5ab6fd60b2faf850b37b3115bc174654.png)
14
+
15
+
16
+
17
+ ```cpp
18
+
19
+ //#define GLEW_STATIC //スタティックリンク
20
+
21
+ #include <iostream>
22
+
23
+ #include <fstream>
24
+
25
+ #include <cstdlib>
26
+
27
+ #include <vector>
28
+
29
+ #include <glew/include/GL/glew.h>
30
+
31
+ #include <glfw/include/GLFW/glfw3.h>
32
+
33
+
34
+
35
+
36
+
37
+
38
+
39
+ #include "Window.hpp"
40
+
41
+ #include "Shape.hpp"
42
+
43
+ #include "Shader.hpp"
44
+
45
+
46
+
47
+ Object::Vertex rectangleVertex[4] =
48
+
49
+ {
50
+
51
+ {-0.5f,-0.5f},
52
+
53
+ {0.5f,-0.5f},
54
+
55
+ {0.5f,0.5f},
56
+
57
+ {-0.5f,0.5f}
58
+
59
+ };
60
+
61
+
62
+
63
+
64
+
65
+ int main()
66
+
67
+ {
68
+
69
+ if (glfwInit() == GL_FALSE)
70
+
71
+ {
72
+
73
+ std::cerr << "glfw初期化失敗。" << std::endl;
74
+
75
+ return -1;
76
+
77
+ }
78
+
79
+
80
+
81
+
82
+
83
+ atexit(glfwTerminate); //プログラム終了時の処理を登録
84
+
85
+ Window window;
86
+
87
+
88
+
89
+ //OpenGL Verison 3.2 Core Profile を選択する
90
+
91
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
92
+
93
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,2);
94
+
95
+ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT,GL_TRUE);
96
+
97
+ glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
98
+
99
+
100
+
101
+ Shape* shape = new Shape(2, 4, rectangleVertex);
102
+
103
+
104
+
105
+ Shader shader("Test.vert","Test.frag");
106
+
107
+ shader.setBindAttribVertex(0, "Position");
108
+
109
+ shader.setBindAttribFragment(0, "fragment");
110
+
111
+
112
+
113
+
114
+
115
+ glClearColor(1.0, 0.0, 0.0, 1.0); //背景色
116
+
117
+ while (window)
118
+
119
+ {
120
+
121
+ glClear(GL_COLOR_BUFFER_BIT); //カラーバッファをクリア
122
+
123
+ shader.Active();
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+ printf(": %d\n", window.getKeyInput(GLFW_KEY_SPACE));
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+ window.SwapBuffers(); //ダブルバッファリング
148
+
149
+ }
222
150
 
223
151
 
224
152
 
@@ -227,3 +155,251 @@
227
155
 
228
156
 
229
157
  ```
158
+
159
+
160
+
161
+ ```cpp
162
+
163
+ #include "Window.hpp"
164
+
165
+
166
+
167
+ //コンストラクタ
168
+
169
+ Window::Window(int width, int height, const char* title)
170
+
171
+ :window(glfwCreateWindow(width, height, title, NULL, NULL)),
172
+
173
+ wheel(0)
174
+
175
+ {
176
+
177
+ std::fill(std::begin(keyStatus),std::end(keyStatus),0);
178
+
179
+
180
+
181
+ if (window == NULL)
182
+
183
+ {
184
+
185
+ std::cerr << "ウインドウ生成失敗" << std::endl;
186
+
187
+ exit(1);
188
+
189
+ }
190
+
191
+
192
+
193
+ glfwMakeContextCurrent(window); //コンテキストを作成
194
+
195
+
196
+
197
+ glewExperimental = GL_TRUE;
198
+
199
+ if (glewInit() != GLEW_OK)
200
+
201
+ {
202
+
203
+ std::cerr << "GLFW 初期化失敗" << std::endl;
204
+
205
+ exit(1);
206
+
207
+ }
208
+
209
+
210
+
211
+ atexit(glfwTerminate); //プログラム終了時の処理を登録
212
+
213
+ glfwSwapInterval(1); //垂直同期
214
+
215
+
216
+
217
+
218
+
219
+ //イベント処理
220
+
221
+ glfwSetWindowUserPointer(window, this); //このインスタンスのthis
222
+
223
+ glfwSetWindowSizeCallback(window, Resize); //ウインドウサイズを変更する時に呼び出す処理
224
+
225
+ glfwSetScrollCallback(window,Wheel); //マウスホイール操作時に呼び出す処理
226
+
227
+ //////////////////////////////////////////////////////////////////////////////////////////////
228
+
229
+ glfwSetKeyCallback(window, KeyBoard); //キー入力時に呼び出す処理
230
+
231
+ //////////////////////////////////////////////////////////////////////////////////////////////
232
+
233
+
234
+
235
+
236
+
237
+ Resize(window, width, height);
238
+
239
+
240
+
241
+ }
242
+
243
+
244
+
245
+ //サイズ変更
246
+
247
+ void Window::Resize(GLFWwindow* const win, int width, int height)
248
+
249
+ {
250
+
251
+ int fbWidth, fbHeight;
252
+
253
+ glfwGetFramebufferSize(win, &fbWidth, &fbHeight);
254
+
255
+ glViewport(0, 0, fbWidth, fbHeight);
256
+
257
+
258
+
259
+ Window* const instance = (Window*)glfwGetWindowUserPointer(win);
260
+
261
+
262
+
263
+ if (instance != NULL)
264
+
265
+ {
266
+
267
+ instance->size.x = (GLfloat)width;
268
+
269
+ instance->size.y = (GLfloat)height;
270
+
271
+ }
272
+
273
+ }
274
+
275
+
276
+
277
+ //ウインドウサイズを取得
278
+
279
+ const glm::vec2 Window::getSize() const
280
+
281
+ {
282
+
283
+ return size;
284
+
285
+ }
286
+
287
+
288
+
289
+
290
+
291
+ //キー入力を取得
292
+
293
+ const int Window::getKeyInput(int key)const
294
+
295
+ {
296
+
297
+ return keyStatus[key];
298
+
299
+ }
300
+
301
+
302
+
303
+ //マウスホイール
304
+
305
+ void Window::Wheel(GLFWwindow* win, double x, double y)
306
+
307
+ {
308
+
309
+ Window* const instance = (Window*)glfwGetWindowUserPointer(win);
310
+
311
+
312
+
313
+ if (instance != NULL)
314
+
315
+ {
316
+
317
+ instance->wheel += (GLfloat)y;
318
+
319
+ }
320
+
321
+ }
322
+
323
+
324
+
325
+ /////////////////////////////////////////////////////////////////////////////////////////////////
326
+
327
+ //キー入力
328
+
329
+ void Window::KeyBoard(GLFWwindow* win, int key, int scancode, int action, int mods)
330
+
331
+ {
332
+
333
+ Window* const instance = (Window*)glfwGetWindowUserPointer(win);
334
+
335
+
336
+
337
+ if (instance != NULL)
338
+
339
+ {
340
+
341
+ instance->keyStatus[key] = action;
342
+
343
+ }
344
+
345
+ }
346
+
347
+ ////////////////////////////////////////////////////////////////////////////////////////////////
348
+
349
+
350
+
351
+ //bool 演算子
352
+
353
+ Window::operator bool()
354
+
355
+ {
356
+
357
+ glfwPollEvents(); //イベントを取り出す
358
+
359
+
360
+
361
+ //ウインドウを閉じる必要があれば false
362
+
363
+ if (glfwWindowShouldClose(window) != 0)
364
+
365
+ {
366
+
367
+ return false;
368
+
369
+ }
370
+
371
+ else {
372
+
373
+ return true;
374
+
375
+ }
376
+
377
+ }
378
+
379
+
380
+
381
+ //ダブルバッファリング
382
+
383
+ void Window::SwapBuffers()const
384
+
385
+ {
386
+
387
+ glfwSwapBuffers(window);
388
+
389
+ }
390
+
391
+
392
+
393
+ //デストラクタ
394
+
395
+ Window::~Window()
396
+
397
+ {
398
+
399
+ glfwDestroyWindow(window);
400
+
401
+ }
402
+
403
+
404
+
405
+ ```