Движение "2D" камеры в OpenGL/C++
Я проверил все другие связанные вопросы на этом сайте, но ни одно из решений не помогло мне. Я просто пытаюсь следовать моему прямоугольнику, который перемещается влево и вправо при нажатии клавиш в OpenGL. Вот моя очень простая программа:
/*Begin useful backend functions/vars*/
/*************************************/
//Window size and refresh rate (60 fps)
int width = 500;
int height = 500;
int interval = 1000 / 60;
//Used to draw rectangles
void drawRect(float x, float y, float width, float height) {
glBegin(GL_QUADS);
glVertex2f(x, y);
glVertex2f(x + width, y);
glVertex2f(x + width, y + height);
glVertex2f(x, y + height);
glEnd();
}
/***********************************/
/*End useful backend functions/vars*/
/*Game vars*/
/***********/
//keycodes
#define keyA 0x41
#define keyD 0x44
//player
int playerWidth = 30;
int playerHeight = 50;
int playerSpeed = 3;
//player starting position
float playerX = width / 2;
float playerY = 25.0f;
/***************/
/*End game vars*/
/*Game specific functions*/
/*************************/
void keyboard() {
//Move player (and camera) on key presses
if (GetAsyncKeyState(keyA)) {
playerX -= playerSpeed;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-playerSpeed,0,0);
}
if (GetAsyncKeyState(keyD)) {
playerX += playerSpeed;
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(playerSpeed, 0, 0);
}
}
/********************/
/*End game functions*/
/*Draw and update for window*/
/****************************/
void draw() {
//Initialliy clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//Draw player
drawRect(playerX, playerY, playerWidth, playerHeight);
//Swap buffers to end
glutSwapBuffers();
}
void update(int value) {
// input handling
keyboard();
// Call update() again in 'interval' milliseconds
glutTimerFunc(interval, update, 0);
// Redisplay frame
glutPostRedisplay();
}
/*****************/
/*End draw/update*/
/*Main function*/
/***************/
int main(int argc, char** argv) {
// initialize opengl (via glut)
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutCreateWindow("My Game");
// Register callback functions
glutDisplayFunc(draw);
glutTimerFunc(interval, update, 0);
// setup scene to be 2d
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//set draw color to white
glColor3f(1.0f, 1.0f, 1.0f);
//start the whole thing
glutMainLoop();
return 0;
}
/*************/
/*End of main*/
Движение клавиатуры работает отлично, однако:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-playerSpeed,0,0);
внутри моего keyboard()
функция, ничего не делает. И если я попробую это с GL_PROJECTION
Оказывается мой экран черный.
1 ответ
Прежде всего обратите внимание, что рисунок glBegin
/ glEnd
Последовательности и стек матрицы с фиксированными функциями устарели с десятилетий. См. Фиксированный конвейер функций и устаревший OpenGL.
Упростите вещи.
Добавить клавиатуру событий для клавиши вверх и вниз (glutKeyboardFunc
/ glutKeyboardUpFunc
). Эта функция только изменяет скорость игрока. Скорость устанавливается при нажатии кнопки и устанавливается на 0, когда кнопка отпущена:
int playerSpeed = 0;
void keyboardDown(unsigned char key, int x, int y)
{
if (key == 'a')
playerSpeed -= 3;
else if (key == 'd')
playerSpeed = 3;
}
void keyboardUp( unsigned char key, int x, int y )
{
playerSpeed = 0;
}
Событие таймера просто изменяет положение игрока:
void update(int value)
{
playerX += playerSpeed;
glutTimerFunc(interval, update, 0);
glutPostRedisplay();
}
В draw
матрица модели установлена и прямоугольник нарисован:
void draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(playerX, playerY, 0);
//Draw player
drawRect(0, 0, playerWidth, playerHeight);
//Swap buffers to end
glutSwapBuffers();
}
Установите функции обратного вызова в main
:
int main(int argc, char** argv)
{
// ...
glutDisplayFunc(draw);
glutTimerFunc(interval, update, 0);
glutKeyboardFunc( keyboardDown );
glutKeyboardUpFunc( keyboardUp );
// ...
}