0
\$\begingroup\$

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;

}
\$\endgroup\$
0

2 Answers 2

1
\$\begingroup\$

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).

\$\endgroup\$
0
-1
\$\begingroup\$

Add glutIdleFunc(display); to main().

\$\endgroup\$
1
  • 2
    \$\begingroup\$ This answer could be improved by elaborating on why/how the proposed solution fixes the problem. \$\endgroup\$
    – bornander
    Commented Oct 26, 2015 at 8:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .