How to move a rectangle properly?

Started by
4 comments, last by Paradigm Shifter 10 years, 6 months ago

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

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
}

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

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Suave? Like suave Ben from Blue Velvet?

ben.jpg

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

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

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

Savvy” means “understanding”.

L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

Shrewd and knowledgeable, too.

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

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

This topic is closed to new replies.

Advertisement