【问题标题】:openGL 2D moving and object by 1 unitopenGL 2D 移动和对象 1 个单位
【发布时间】:2012-10-31 02:23:51
【问题描述】:

我有一些关于如何通过按键移动对象的问题。我要做的就是按下键盘上的向上按钮,让对象移动一个单位。

void display(){

    //Clear Window
    glClear(GL_COLOR_BUFFER_BIT);

    glPushMatrix();
    glBegin(GL_POLYGON);
    glColor3f(1.0, 0.0, 0.0);
    glVertex2f(-0.1, -0.2);
    glVertex2f(-0.1, 0.2);
    glVertex2f(0.1, 0.2);
    glVertex2f(0.1, -0.2);
    glEnd();
    glPopMatrix();
    glFlush();
}


void keyboardListener(int key)
{  
    if( key == GLUT_KEY_UP) 
    {
        glTranslatef(1.0, 0.0, 0.0);
        glutPostRedisplay(); 
    }
}

缺少什么或我不理解什么概念?

【问题讨论】:

  • 你收到key up事件了吗?会发生什么?
  • 第一个:您需要告诉我们您的解决方案中什么不起作用。第二:尝试将您的问题改写为一般问题,而不是“调试我的代码”。
  • 翻译使对象在 x 轴上向上移动 1 个单位,不是吗?所以“x”中的所有值该多边形将上升一个单位而不是-0.1,图像中的一个将是0.0,0.1将是0.2。我还发现奇怪的是,如果我按下右键,正方形将保持指向 90 度。在这种情况下,哪个功能可以让我向右转 90 度,使其指向 0 度?所有这一切都没有改变场景,因为我认为 rotatef 改变了视图,而不是真正的对象的物理位置

标签: c++ opengl 2d glut


【解决方案1】:

使用这个:

#include <stdio.h>
#include <gl/glut.h>

GLfloat rotation = 90.0;
float posX = 0, posY = 0, posZ = 0;

void reshape(int width, int heigth){
    /* window ro reshape when made it bigger or smaller*/

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    //clip the windows so its shortest side is 2.0
    if (width < heigth) {
        glOrtho(-2.0, 2.0, -2.0 * (GLfloat)heigth / (GLfloat)width, 2.0 * (GLfloat)heigth / (GLfloat)width, 2.0, 2.0);
    }
    else{
        glOrtho(-2.0, 2.0, -2.0 * (GLfloat)width / (GLfloat)heigth, 2.0 * (GLfloat)width / (GLfloat)heigth,2.0 , 2.0);
    }
    // set viewport to use the entire new window
    glViewport(0, 0, width, heigth);
}

void rect(){
    glBegin(GL_POLYGON);
    glColor3f(1.0, 0.0, 0.0);
    glVertex2f(-0.1, -0.2);
    glVertex2f(-0.1, 0.2);
    glVertex2f(0.1, 0.2);
    glVertex2f(0.1, -0.2);
    glEnd();

}

void display(){
    //Clear Window
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glPushMatrix();
    glTranslatef(posX,posY,posZ);
    rect();
    glPopMatrix();
    glFlush();
}


void init(){
    // set clear color to black
    glClearColor(0.0, 0.0, 0.0, 0.0);

    // set fill color to white
    glColor3f(1.0, 1.0, 1.0);

    //set up standard orthogonal view with clipping
    //box as cube of side 2 centered at origin
    //This is the default view and these statements could be removed
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(-1.0, 1.0, -1.0, 1.0);

}
float move_unit = 0.1f;
void keyboardown(int key, int x, int y)
{
    switch (key){
        case GLUT_KEY_RIGHT:
            posX+=move_unit;;
            break;

        case GLUT_KEY_LEFT:
            posX-=move_unit;;
        break;

        case GLUT_KEY_UP:
            posY+=move_unit;;
            break;

        case GLUT_KEY_DOWN:
            posY-=move_unit;;
        break;

        default:
         break;
    }
    glutPostRedisplay();
}


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

    //initialize mode and open a windows in upper left corner of screen
    //Windows tittle is name of program

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(0, 0);
    glutCreateWindow("Practice 1");
    glutDisplayFunc(display);
    init();
    glutSpecialFunc(keyboardown);
    glutMainLoop();

}

【讨论】:

    【解决方案2】:

    最简单的方法就是这样做

    float posX = 0, posY = 0, posZ = 0;
    
    void display(){
      glClear(GL_COLOR_BUFFER_BIT);
      glTranslate(posX,posY,posZ);
      drawPolygon();
      //...
    }
    
    
    void keyboardListener(int key){
      if(key == GLUT_KEY_RIGHT){ posX++; }
      else if(key == GLUT_KEY_LEFT){ posX--; }
      //..similar for up/down
      glutPostRedisplay();
    }
    

    【讨论】:

    • 感谢您的回复,看起来比较容易理解,所以我不需要使用push和pop吗?
    • 在这种情况下不是,只要确保 drawPolygon() 以原点为中心绘制,然后从那里继续
    • 在哪些情况下我使用推送和弹出?很抱歉打扰了。当我尝试应用它时,图像不会重绘,对象也不会移动。
    • 您可能需要在显示函数中添加 glutPostRedisplay,如果代码足够小,请将代码发布到 codepad.org 以便我查看
    • 感谢您的帮助!!基本上我的想法是像一个迷宫一样,一个物体需要完成它只是简单的东西,用一些正方形作为墙壁。去年用c++做了一个关于迷宫的项目,刚想到实现图形的想法codepad.org/ERyTZyYy
    【解决方案3】:

    此代码绘制一个圆圈,并在按下左、右、上或下键时移动。

    #include <cmath>
    #include <stdio.h>
    float posX = 0.01, posY = -0.1, posZ = 0;
    
    void circ() {
        glColor3f(0.0, 0.0, 1.0);
        glBegin(GL_TRIANGLE_FAN);
        for (int i = 0; i <= 300; i++) {
            angle = 2 * PI * i / 300;
            x = cos(angle) / 20;
            y = sin(angle) / 20;
            glVertex2d(x, y);
        }
        glEnd();
    }
    
    
    void display() {
        glClearColor(1.0, 1.0, 1.0, 0.0);
        glClear(GL_COLOR_BUFFER_BIT);
    
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        gluOrtho2D(-1.0, 1.0, -1.0, 1.0);
    
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();
    
        glPushMatrix();
        glTranslatef(posX, posY, posZ);
        circ();
        glPopMatrix();
    
        glutSwapBuffers();
    }
    
    **float move_unit = 0.02f;
    void keyboardown(int key, int x, int y) {
        switch (key) {
        case GLUT_KEY_RIGHT:
            posX += move_unit;
            break;
        case GLUT_KEY_LEFT:
            posX -= move_unit;
            break;
        case GLUT_KEY_UP:
            posY += move_unit;
            break;
        case GLUT_KEY_DOWN:
            posY -= move_unit;
            break;
        default:
            break;
        }
    glutPostRedisplay();
    }**
    
    
    
    int main(int argc, char** argv) {
        glutInit(&argc, argv);
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
        glutInitWindowSize(600, 500);
        glutInitWindowPosition(0, 0);
        glutCreateWindow("Example");
        glutDisplayFunc(display);
        glutSpecialFunc(keyboardown);
        glutMainLoop();
    }
    

    【讨论】:

    • 每次按下箭头键时都会更新圆的坐标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多