2011-02-01 18 views
0

我試圖讓它當我按下W,A,S或D時,它會在屏幕上移動一堆線。我從文件中讀取所有行並顯示它們,並且工作正常。爲什麼glTranslate在雙緩衝GLUT窗口中做任何事情?

所以我有一個鍵盤函數,它具有一個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. */ 
} 

回答

1

我還沒有看太仔細,但你調用glTranslate之前最有可能缺少

glMatrixMode(GL_MODELVIEW); 
glLoadIdentity(); 

。 glTranslate組成翻譯。從你的代碼看,你似乎期待它設置一個翻譯。

您可能還想避免在每一幀讀取磁盤。相反,在啓動時將模型加載到數據結構中並進行渲染。

+0

我試過了,但它也沒有工作。不過,我在我的主要方法中添加了glutIdleFunc(display),現在一切正常。謝謝你的幫助! – kyle 2011-02-01 00:18:08

0

您在鍵盤處理程序中丟失了glutPostRedisplay。沒有這個窗口的重繪就不會被啓動。設置顯示爲空閒func也會執行該操作,但工作方式不同:窗口不斷重繪,幾乎所有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; 
} 
相關問題