Почему glTranslate ничего не делает в окне GLUT с двойной буферизацией? - PullRequest
0 голосов
/ 01 февраля 2011

Я пытаюсь сделать так, чтобы, когда я нажимал W, A, S или D, он перемещал кучу строк на экране.Я читаю все строки из файла и отображаю их, и это прекрасно работает.

Итак, у меня есть функция клавиатуры, которая имеет оператор switch, который увеличивает переменные X и Y, которые я использую в glTranslate внутри моегофункция отображения, но мои строки не двигаются.Может ли кто-нибудь помочь мне с этим?

#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 ]

1 голос
/ 01 февраля 2011

Я не слишком внимательно читал, но вы, скорее всего, пропускаете

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

до вызова glTranslate.glTranslate составляет перевод.Из вашего кода кажется, что вы ожидаете, что он установит перевод.

Возможно, вы также захотите избегать чтения с диска в каждом кадре.Загрузите вашу модель в структуру данных при запуске и выполните рендеринг из нее.

0 голосов
/ 01 февраля 2011

Вам не хватает glutPostRedisplay в обработчике клавиатуры. Без этого перерисовка окна не была бы инициирована. Настройки, отображаемые как бездействующая функция, тоже делают свое дело, но работают по-другому: окно постоянно перерисовывается, почти все процессорное время используется для рисования. В вашем коде также были некоторые другие ошибки. Я исправил это.

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...