kyle
kyle

Reputation: 1

Why isn't glTranslate doing anything in a double buffered GLUT window?

I'm trying to make it so that when I press W, A, S, or D, it moves a bunch of lines around on the screen. I read in all the lines from a file and display them, and that works fine.

So I have a keyboard function that has a switch statement that increments an X and Y variable which I use in glTranslate inside of my display function, but my lines don't move. Could anyone help me out with this?

#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. */
}

Upvotes: 0

Views: 818

Answers (2)

datenwolf
datenwolf

Reputation: 162164

You were missing a glutPostRedisplay in your keyboard handler. Without that no redraw of the window would have been initiated. Settings display as idle func does the trick as well, but works differently: The window is constantly redrawn, almost all CPU time used up for drawing. Your code also had some other fallacies. I fixed that.

#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;
}

Upvotes: 0

Carlos Scheidegger
Carlos Scheidegger

Reputation: 1966

I haven't read too carefully, but you're most likely missing a

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

before the call to glTranslate. glTranslate composes a translation. From your code it seems like you're expecting it to set a translation.

You'll probably also want to avoid reading from disk at every frame. Load your model into a data structure at startup and render from that instead.

Upvotes: 1

Related Questions