I recently started to learn OpenGL. Right now I finished the first chapter of the "OpenGL SuperBible". There were two examples. The first had the complete code and showed how to draw a simple triangle. The second example is supposed to show how to move a rectangle using SpecialKeys. The only code provided for this example was the SpecialKeys method. I still tried to implement it but I had two problems.
In the previous example I declared and instaciated vVerts in the SetupRC() method. Now as it is also used in the SpecialKeys() method, I moved the declaration and instantiation to the top of the code. Is this proper c++ practice?
I copied the part where vertex positions are recalculated from the book, but I had to pick the vertices for the rectangle on my own. So now every time I press a key for the first time the rectangle's upper left vertex is moved to (-0,5:-0.5). This ok because of
GLfloat blockX = vVerts[0]; //Upper left X
GLfloat blockY = vVerts[7]; // Upper left Y
But I also think that this is the reason why my rectangle is shifted in the beginning. After the first time a key was pressed everything works just fine. Here is my complete code I hope you can help me on those two points.
GLBatch squareBatch;
GLShaderManager shaderManager;
//Load up a triangle    
GLfloat vVerts[] = {-0.5f,0.5f,0.0f,
                    0.5f,0.5f,0.0f,
                    0.5f,-0.5f,0.0f,
                    -0.5f,-0.5f,0.0f};
//Window has changed size, or has just been created.
//We need to use the window dimensions to set the viewport and the projection matrix.
void ChangeSize(int w, int h)
{
    glViewport(0,0,w,h);
}
//Called to draw the scene.
void RenderScene(void)
{
    //Clear the window with the current clearing color
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
    GLfloat vRed[] = {1.0f,0.0f,0.0f,1.0f};
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY,vRed);
    squareBatch.Draw();
    //perform the buffer swap to display the back buffer
    glutSwapBuffers();
}
//This function does any needed initialization on the rendering context.
//This is the first opportunity to do any OpenGL related Tasks.
void SetupRC()
{
    //Blue Background
    glClearColor(0.0f,0.0f,1.0f,1.0f);
    shaderManager.InitializeStockShaders();
    squareBatch.Begin(GL_QUADS,4);
    squareBatch.CopyVertexData3f(vVerts);
    squareBatch.End();
}
//Respond to arrow keys by moving the camera frame of reference
void SpecialKeys(int key,int x,int y)
{
    GLfloat stepSize = 0.025f;
    GLfloat blockSize = 0.5f;
    GLfloat blockX = vVerts[0]; //Upper left X
    GLfloat blockY = vVerts[7]; // Upper left Y
    if(key == GLUT_KEY_UP)
    {
        blockY += stepSize;
    }
    if(key == GLUT_KEY_DOWN){blockY -= stepSize;}
    if(key == GLUT_KEY_LEFT){blockX -= stepSize;}
    if(key == GLUT_KEY_RIGHT){blockX += stepSize;}
    //Recalculate vertex positions
    vVerts[0] = blockX;
    vVerts[1] = blockY - blockSize*2;
    vVerts[3] = blockX + blockSize * 2;
    vVerts[4] = blockY - blockSize *2;
    vVerts[6] = blockX+blockSize*2;
    vVerts[7] = blockY;
    vVerts[9] = blockX;
    vVerts[10] = blockY;
    squareBatch.CopyVertexData3f(vVerts);
    glutPostRedisplay();
}
//Main entry point for GLUT based programs
int main(int argc, char** argv)
{
    //Sets the working directory. Not really needed
    gltSetWorkingDirectory(argv[0]);
    //Passes along the command-line parameters and initializes the GLUT library.
    glutInit(&argc,argv);
    //Tells the GLUT library what type of display mode to use, when creating the window.
    //Double buffered window, RGBA-Color mode,depth-buffer as part of our display, stencil buffer also available
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH|GLUT_STENCIL);
    //Window size
    glutInitWindowSize(800,600);
    glutCreateWindow("MoveRect");
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    glutSpecialFunc(SpecialKeys);
    //initialize GLEW library
    GLenum err = glewInit();
    //Check that nothing goes wrong with the driver initialization before we try and do any rendering.
    if(GLEW_OK != err)
    {
        fprintf(stderr,"Glew Error: %s\n",glewGetErrorString);
        return 1;
    }
    SetupRC();
    glutMainLoop();
    return 0;
}