# OpenGL How to move a rectangle properly?

This topic is 2110 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

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.

1. 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?
2. 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:
3. 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;
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};

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

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


##### Share on other sites

If you want to move the actual vertices, you could just set some delta:

float dx = 0, dy = 0;

if (left)  dx = -speed;
if (right) dx += speed;
// etc.

// iterate all vertices (not every float)
for (int i = 0; i < vertexCount * 3; i += 3)
{
vertex[i]     += dx; // all X'es
vertex[i + 1] += dy; // all Y's
// not increasing any Z's which would be vertex[i + 2]
// vertex[i + 3] belongs to any next vertex
}

Edited by Kaptein

##### Share on other sites

It is not performance-suave to update the vertices directly.

You should not touch the vertices and instead supply a transform matrix of some kind and transform them in the vertex shader.

L. Spiro

##### Share on other sites

Suave? Like suave Ben from Blue Velvet?

Clip: (obvs NSFW or at any time)

Another warning: it's not safe for work or at any other time, that clip.

I  think you mean "savvy"? ;)

##### Share on other sites

Suave” means “elegant”, “sophisticated”, “refined”, “polished”, etc.  In reference to performance in this case.

Savvy” means “understanding”.

L. Spiro

Edited by L. Spiro

##### Share on other sites

Shrewd and knowledgeable, too.

Suave tends to mean greasy and a bit pervy (think Bryan Ferry from Roxy Music).

• 18
• 29
• 11
• 21
• 16