为什么glTranslate在双缓冲GLUT窗口中没有做任何事情?

时间:2011-02-01 00:04:49

标签: opengl

我试图这样做,当我按下W,A,S或D时,它会在屏幕上移动一堆线条。我从文件中读取所有行并显示它们,并且工作正常。

所以我有一个键盘函数,它有一个switch语句,它增加了我在显示函数里面的glTranslate中使用的X和Y变量,但是我的行不会移动。任何人都可以帮我解决这个问题吗?

#include <GL/glut.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>

int height = 640, width = 640;

int X = 0, Y = 0;

void drawPolyLineFile(char * fileName) {
    std::fstream inStream;
    inStream.open(fileName, std::ios::in);
    if (inStream.fail()) {
        std::cerr<< "Error opening file";
        return;
    }

    glClear(GL_COLOR_BUFFER_BIT);

    GLint numpolys, numLines, x, y;
    inStream >> numpolys;
    for ( int j =0; j < numpolys; j++) {
        inStream >> numLines;
        glBegin(GL_LINE_STRIP);
        for (int i = 0; i < numLines; i++) {
            inStream >> x >> y;
            glVertex2i(x, y);
        }
        glEnd();
    }

    //glutSwapBuffers();

    inStream.close();
}

void display(void)
{
/* clear all pixels  */
   glClear (GL_COLOR_BUFFER_BIT);

   glTranslatef(X, Y, 0);
   drawPolyLineFile("dino.dat");

/* don't wait!
 * start processing buffered OpenGL routines
 */
   glutSwapBuffers();
}

void init (void)
{
/* select clearing color        */
   glClearColor (0.0, 0.0, 0.0, 0.0);

/* initialize viewing values  */
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.0, 640.0, 0.0, 640.0, -1.0, 1.0);
}


void keyboard(unsigned char key, int x, int y) {
    float speed = 5.0f;
    switch ( key ) {
        case 'a':
            X -= speed;
            std::cerr<< X << std::endl;
            break;
        case 'd':
            X += speed;
            std::cerr<< X << std::endl;
            break;
        case 's':
            Y -= speed;
            std::cerr<< Y << std::endl;
            break;
        case 'w':
            Y += speed;
            std::cerr<< Y << std::endl;
            break;
        default:
            break;
    }

}


/*
 * Declare initial window size, position, and display mode
 * (single buffer and RGBA).  Open window with "hello"
 * in its title bar.  Call initialization routines.
 * Register callback function to display graphics.
 * Enter main loop and process events.
 */
int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
   glutInitWindowSize (640, 640);
   glutInitWindowPosition (100, 100);
   glutCreateWindow ("hello");
   init ();
   glutKeyboardFunc(keyboard);
   glutDisplayFunc(display);
   glutMainLoop();
   return 0;   /* ANSI C requires main to return int. */
}

2 个答案:

答案 0 :(得分:1)

我没有仔细阅读,但你很可能错过了

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
在致电glTranslate之前

。 glTranslate撰写翻译。从你的代码看,你似乎期望它设置一个翻译。

您可能还希望避免在每一帧都从磁盘读取。在启动时将模型加载到数据结构中,然后从中进行渲染。

答案 1 :(得分:0)

您的键盘处理程序中缺少glutPostRedisplay。没有它,就不会重新开始重新绘制窗口。设置显示为空闲功能也可以做到这一点,但工作方式不同:窗口不断重绘,几乎所有CPU时间都用于绘图。您的代码也有其他一些谬误。我解决了这个问题。

#include <GL/glut.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <stdexcept>

int X = 0, Y = 0;

void drawPolyLineFile(char * fileName) throw(std::runtime_error)
{
    std::fstream inStream;
    inStream.open(fileName, std::ios::in);
    if (inStream.fail()) {
        throw std::runtime_error("Error opening file")
    }

    GLint numpolys, numLines, x, y;
    inStream >> numpolys;
    for ( int j =0; j < numpolys; j++) {
        inStream >> numLines;
        glBegin(GL_LINE_STRIP);
        for (int i = 0; i < numLines; i++) {
            inStream >> x >> y;
            glVertex2i(x, y);
        }
        glEnd();
    }

    inStream.close();
}

void display(void)
{
   int window_width, window_height;

   window_width  = glutGet(WINDOW_WIDTH);
   window_height = glutGet(WINDOW_HEIGHT);

   glViewport(0, 0, window_width, window_height);

   /* clear all pixels  */
   glClearColor (0.0, 0.0, 0.0, 0.0);
   glClear (GL_COLOR_BUFFER_BIT);

   /* always set all projection parameters a new
    * each rendering pass
    */    
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0.0, window_width, 0.0, window_height, -1.0, 1.0);

   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();

   glTranslatef(X, Y, 0);
   drawPolyLineFile("dino.dat");

   /* 
    * SwapBuffers will flush the OpenGL queue indeed,
    * but more importantly it brings the content from
    * the back buffer to the front
    */
   glutSwapBuffers();
}

void keyboard(unsigned char key, int x, int y) {
    float speed = 5.0f;
    switch ( key ) {
        case 'a':
            X -= speed;
            std::cerr<< X << std::endl;
            break;
        case 'd':
            X += speed;
            std::cerr<< X << std::endl;
            break;
        case 's':
            Y -= speed;
            std::cerr<< Y << std::endl;
            break;
        case 'w':
            Y += speed;
            std::cerr<< Y << std::endl;
            break;
        default:
            break;
    }
    glutPostRedisplay();    
}


/*
 * Declare initial window size, position, and display mode
 * (single buffer and RGBA).  Open window with "hello"
 * in its title bar.  Call initialization routines.
 * Register callback function to display graphics.
 * Enter main loop and process events.
 */
int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);

   glutInitWindowSize (640, 640);
   glutInitWindowPosition (100, 100);
   glutCreateWindow ("hello");
   glutKeyboardFunc(keyboard);
   glutDisplayFunc(display);

   try {
       glutMainLoop();
   } catch (std::runtime_error &err) {
     std::cerr << err.what();
   }

   return 0;
}