Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I am currently drawing a rectangle to the screen and would like to move it by using the arrow keys. However, when I press an arrow key the vertex data changes but the display does refresh to reflect these changes, even though I am calling glutPostRedisplay(). Is there something else that I must do?

My code:

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/freeglut_ext.h>
#include <iostream>
#include "Shaders.h"
using namespace std;

const int NUM_VERTICES = 6;
const GLfloat POS_Y = -0.1;
const GLfloat NEG_Y = -0.01;

struct Vertex {
    GLfloat x;
    GLfloat y;
    Vertex() : x(0), y(0) {}
    Vertex(GLfloat givenX, GLfloat givenY) : x(givenX), y(givenY) {}
};

Vertex left_paddle[NUM_VERTICES];

void init() {
    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

    left_paddle[0] = Vertex(-0.95f, 0.95f);
    left_paddle[1] = Vertex(-0.95f,  0.0f);
    left_paddle[2] = Vertex(-0.85f,  0.95f);
    left_paddle[3] = Vertex(-0.85f,  0.95f);
    left_paddle[4] = Vertex(-0.95f,  0.0f);
    left_paddle[5] = Vertex(-0.85f,  0.0f);

    GLuint vao;
    glGenVertexArrays( 1, &vao );
    glBindVertexArray( vao );

    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(left_paddle), 
        NULL, GL_STATIC_DRAW);

    GLuint program = init_shaders( "vshader.glsl", "fshader.glsl" );
    glUseProgram( program );

    GLuint loc = glGetAttribLocation( program, "vPosition" );
    glEnableVertexAttribArray( loc );
    glVertexAttribPointer( loc, 2, GL_FLOAT, GL_FALSE, 0,
                           0);

    glBindVertexArray(vao);
}

void movePaddle(Vertex* array, GLfloat change) {
    for(int i = 0; i < NUM_VERTICES; i++) {
        array[i].y = array[i].y + change;
    }
    glutPostRedisplay();
}

void special( int key, int x, int y ) {
    switch ( key ) {
    case GLUT_KEY_DOWN:
        movePaddle(left_paddle, NEG_Y);
        break;
    }
}

void display() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glutSwapBuffers();
}

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

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(500,500);
    glutCreateWindow("Rectangle");

    glewInit();
    init();

    glutDisplayFunc(display);  
    glutSpecialFunc(special); 

    glutMainLoop();
    return 0;

}
share|improve this question

1 Answer 1

up vote 1 down vote accepted

You need to actually update the vPosition vertex attribute in your draw function. As is, you're always redrawing with the original value you used in the init function.

Do not be fooled by the fact that OpenGL takes pointer arguments. It does not store a reference to the memory of your position vector, but rather makes a copy of it (likely into the video memory).

share|improve this answer
    
Thank you! That worked perfectly :) –  A D Jul 7 '12 at 5:33

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.