Есть проект, на C++ с OpenGL - просто камера, которой можно управлять с помощью клавиатуры. Но когда включена русская раскладка, то камера не перемещается, а при отпускании клавиши приложение завершается с ошибкой. (Выводится сообщение от Windows что прекращена работа программы). проект включает в себя ещё 4 файла (Camera.h, Camera.cpp, Vector3.h, Vector3.cpp), если надо, то могу скинуть их содержимое. Заранее спасибо.
#include "Camera.h"
#include "Vector3.h"
#include <GL/glut.h>
#include <math.h>
#include <vector>
#include <algorithm>
using namespace std;
int HWND;
float WIN_WIDTH = 640, WIN_HEIGHT = 480;
float CAM_MOVE_SPEED = 2, CAM_ROT_SPEED = 2;
Camera cam = Camera();
vector<char> keys;
static long double d2r(long double d) {return (d / 180.0) * ((long double) M_PI);}
void drawMap()
{
int m[] = {
1, 0, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
1, 0, 0, 0, 1,
0, 1, 1, 1, 0,
};
for (int y=0; y<5; y++)
{
for (int x=0; x<5; x++)
{
if (m[x*5+y] == 1)
{
glutWireCube(20);
}
glTranslatef(-20, 0, 0);
}
glTranslatef(100, 0, 20);
}
}
void draw()
{
glClear(GL_COLOR_BUFFER_BIT);
drawMap();
cam.updateMatrix();
glutSwapBuffers();
}
void timer(int)
{
glutPostRedisplay();
glutTimerFunc(50, timer, 0);
}
void keyTimer(int)
{
if (find(keys.begin(), keys.end(), 'w') != keys.end()) cam.move(-sin(d2r(cam.rot.y)*CAM_MOVE_SPEED), 0, cos(d2r(cam.rot.y))*CAM_MOVE_SPEED);
if (find(keys.begin(), keys.end(), 's') != keys.end()) cam.move(sin(d2r(cam.rot.y)*CAM_MOVE_SPEED), 0, -cos(d2r(cam.rot.y))*CAM_MOVE_SPEED);
if (find(keys.begin(), keys.end(), 'a') != keys.end()) cam.move(cos(d2r(cam.rot.y)*CAM_MOVE_SPEED), 0, sin(d2r(cam.rot.y))*CAM_MOVE_SPEED);
if (find(keys.begin(), keys.end(), 'd') != keys.end()) cam.move(-cos(d2r(cam.rot.y)*CAM_MOVE_SPEED), 0, -sin(d2r(cam.rot.y))*CAM_MOVE_SPEED);
if (find(keys.begin(), keys.end(), 'q') != keys.end()) cam.move(0, -CAM_ROT_SPEED, 0);
if (find(keys.begin(), keys.end(), 'z') != keys.end()) cam.move(0, CAM_ROT_SPEED, 0);
if (find(keys.begin(), keys.end(), 'u') != keys.end()) cam.rotate(-CAM_ROT_SPEED, 0, 0);
if (find(keys.begin(), keys.end(), 'j') != keys.end()) cam.rotate(CAM_ROT_SPEED, 0, 0);
if (find(keys.begin(), keys.end(), 'h') != keys.end()) cam.rotate(0, -CAM_ROT_SPEED, 0);
if (find(keys.begin(), keys.end(), 'k') != keys.end()) cam.rotate(0, CAM_ROT_SPEED, 0);
glutTimerFunc(50, keyTimer, 0);
}
void reshape(int w, int h)
{
WIN_WIDTH = w; WIN_HEIGHT = h;
glMatrixMode(GL_PROJECTION);
glViewport(0, 0, w, h);
glLoadIdentity();
gluPerspective(60, WIN_WIDTH/WIN_HEIGHT, 0.1, 400.0);
glMatrixMode(GL_MODELVIEW);
}
/// x cos(x)*cos(y)
/// z sin(x)*cos(y)
/// y sin(y)
void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
glutDestroyWindow(HWND);
exit(0);
break;
case 'w': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
case 's': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
case 'a': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
case 'd': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
case 'q': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
case 'z': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
case 'u': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
case 'j': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
case 'h': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
case 'k': if (find(keys.begin(), keys.end(), (char)key) != keys.end()) keys.push_back((char)key); break;
}
}
void keyboardUp(unsigned char key, int x, int y)
{
switch (key)
{
case 'w': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
case 's': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
case 'a': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
case 'd': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
case 'q': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
case 'z': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
case 'u': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
case 'j': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
case 'h': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
case 'k': keys.erase(std::find(keys.begin(), keys.end(), (char)key)); break;
}
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, WIN_WIDTH/WIN_HEIGHT, 0.1, 400.0);
glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(WIN_WIDTH, WIN_HEIGHT);
glutInitWindowPosition(100, 200);
HWND = glutCreateWindow("Game");
glutDisplayFunc(draw);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutKeyboardUpFunc(keyboardUp);
glutTimerFunc(50, timer, 0);
glutTimerFunc(50, keyTimer, 0);
glutFullScreen();
init();
glutMainLoop();
return 0;
}
Видимо тут проблема в реализации keyboardUp
, если отпускается неизвестная клавиша, то поиск вернет итератор конца вектора, что будет нарушением инварианта для vector::erase
, который требует валидный и разименуемый итератор. Кроме того, вся эта копипаста в свиче явно ни к чему. Можно сократить до:
void keyboardUp(unsigned char key, int x, int y)
{
keys.erase(std::remove(keys.begin(), keys.end(), (char)key), keys.end());
}
Как меняется крипторынок и к чему готовиться владельцам криптообменников
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Есть вот такая вот программа которая входящие данные забивает в бинарное дерево, а потом считает количество обращений к элементамНужно после...
Есть в котором встречаются <i> и </i>Заменить каждое вхождение <i> на <курсив>, а каждое вхождение </i> на <конец курсив>
Программа запрашивает у пользователя шестизначное числоВывести на экран, соблюдал ли он правила