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;
}
The author goes through the process of drawing 3D graphics step by step, fully explaining the maths and the graphics pipeline. Understanding them is the most crucial aspect, and modern, core OpenGL is much better suited for that purpose.
– Fault Dec 09 '13 at 23:47