简体   繁体   English

“2D”相机在OpenGL / C ++中的运动

[英]Movement of '2D' camera in OpenGL/C++

I've checked every other related question on this site but none of the solutions have worked for me. 我在这个网站上检查了所有其他相关问题,但没有一个解决方案对我有用。 I'm simply trying to follow my rectangle, which moves left and right with key presses in OpenGL. 我只是想跟随我的矩形,它在OpenGL中通过按键左右移动。 Here's my very simple program: 这是我非常简单的程序:

/*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*/

The keyboard movement works perfectly, however: 然而,键盘运动完​​美无缺:

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-playerSpeed,0,0);

inside my keyboard() function, does nothing. 在我的keyboard()函数里面,什么也没做。 And if I try it with GL_PROJECTION , it turns my screen black. 如果我用GL_PROJECTION尝试它,它会使我的屏幕变黑。

First of all note, that drawing by glBegin / glEnd sequences and the fixed function matrix stack is deprecated since decades. 首先要注意的是, glBegin / glEnd序列和固定函数矩阵栈的glEnd几十年来一直被弃用。 See Fixed Function Pipeline and Legacy OpenGL . 请参阅固定功能管道旧版OpenGL


Simplify things. 简化事情。

Add a the keyboard events for key up and down ( glutKeyboardFunc / glutKeyboardUpFunc ). 为键上下添加键盘事件( glutKeyboardFunc / glutKeyboardUpFunc )。 This functions only modifies the speed of the player. 此功能仅修改播放器的速度。 The speed is set when a button is pressed and is set 0, when a button is release: 按下按钮时设置速度,当按钮释放时设置为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;
}

The timer event just modifies the position of the player: 计时器事件只是修改了玩家的位置:

void update(int value)
{
    playerX += playerSpeed;

    glutTimerFunc(interval, update, 0);
    glutPostRedisplay();
}

In draw the model matrix is set and the rectangle is drawn: 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();
}

Set the callback functions in main : main设置回调函数:

int main(int argc, char** argv) 
{
    // ...

    glutDisplayFunc(draw);
    glutTimerFunc(interval, update, 0);
    glutKeyboardFunc( keyboardDown );
    glutKeyboardUpFunc( keyboardUp );

    // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM