OpenGL Pong

Seems that a lot of foreign people had been redirected to the OpenGL Pong post that was in greek and left the page because they couldn’t understand it so I’m reposting it in english.

This is an OpenGL 2D pong as simple as it can be. There are a lot of mistakes of course but the code is working and that’s what I wanted. The rest is simple to fix if need. I wanted to make it as simple as I could for reference reasons. You can download it here with lots of comments. In case it helped you please remember to thank me. It would help motivate me!

Pong screenshot

Pong in OpenGL

// Pong by Konstantinos Egarhos (aka konsnos)

#include <GL/freeglut.h>	// OpenGL toolkit
#include <stdio.h>

// Function Initialising
void drawRect(GLfloat, GLfloat, int, int, float, float, float);
void update();

// Window dimensions
const int Width = 500;
const int Height = 500;

// Dimensions
#define paddleHeight 80
#define paddleWidth 10
#define zAxis 0

float p1 = 220;
float p2 = 220;
// GLfloat player1[4][2] = { 10, p1, 10, p1+paddleHeight, 10+paddleWidth, p1+paddleHeight, 10+paddleWidth, p1 };
// GLfloat player2[4][2] = { 480, p2, 480, p2+paddleHeight, 480+paddleWidth, p2+paddleHeight, 480+paddleWidth, p2 };
const float pspeed = 10;

int score[2];// = {0, 0}; // Score for players 1 and 2

#define bsize 10
GLdouble bpos[2] = {235,235};
GLfloat bvx = 1; // ball vector in left-right axis
GLfloat bvy = 1; // ball vector in top-bottom axis
// GLfloat ball[4][2] = { pos[0], pos[1], pos[0], pos[1]+bsize, pos[0]+bsize, pos[1]+bsize, pos[0]+bsize, pos[1] };
float bspeed = 2;

// Time variables for the speed calculation of the objects
GLdouble time;
GLdouble prtime;
GLdouble timeDiff;
GLdouble runtime;

// Text variable
static char str[200];
void * font = GLUT_BITMAP_9_BY_15;

/*********************************************
    Drawing
*********************************************/
void renderScene(void)
{
     // Elapsed time from the initiation of the game.
     time = glutGet(GLUT_ELAPSED_TIME);
     timeDiff = time - prtime; // Elapsed time from the previous frame.
     prtime = time;
     runtime = timeDiff / 10.0;

     update(); // Update the game.
     // Clear the screen.
     glClear(GL_COLOR_BUFFER_BIT);

     sprintf(str, "Player 1 Score: %d, Player 2 Score: %d", score[0], score[1] );
     glRasterPos2f(10, 10);
     glutBitmapString(font,(unsigned char*)str);

     // Draws the 1st paddle and the 2nd.
     drawRect(10.0, p1, paddleHeight, paddleWidth, 0, 0, 1); // Left blue paddle.
     drawRect(480.0, p2, paddleHeight, paddleWidth, 1, 0, 0); // Right red paddle.

	 drawRect(bpos[0], bpos[1], bsize, bsize, 1, 1, 0); // Yellow ball.

     glutSwapBuffers(); // Draw the new frame of the game.
}

/*********************************************
    Update
*********************************************/
void update()
{
     // Ball collision with the border of the window.
     if(bpos[0] + bspeed > 500-bsize)
     {
          bvx = -1;
          score[0]++;
     }
     else if (bpos[0] - bspeed < 0)
     {
          bvx = 1;
          score[1]++;
     }
     if(bpos[1] + bspeed > 500-bsize)
          bvy = -1;
     else if (bpos[1] - bspeed < 0)
          bvy = 1;

     /******** Collision with the paddles ********/
     // Collision with left paddle.
     if(bpos[0] <= 10 + paddleWidth && bpos[1] >= p1 && bpos[1] + bsize <= p1 + paddleHeight)
     {
          bvx *= -1;
          // bspeed *= 1.01;
     }
     // Collision with right paddle.
     if(bpos[0] + bsize >= 480 && bpos[1] >= p2 && bpos[1] + bsize <= p2 + paddleHeight)
     {
          bvx *= -1;
          // bspeed *= 1.01;
     }

     // New position of the ball dependent to the speed ***************
     // Because frame rate isn't always the same that might affect objects speed.
     // That's why we multiply the frame speed and multiply it with the object speed.
     // In that way the object speed is always the same.
     bpos[0] += bspeed * bvx * runtime;
     bpos[1] += bspeed * bvy * runtime;
}

/*********************************************
    Create and draw a rectangle.
    Generally, we are only interested in the height(y) of the paddle.
*********************************************/
void drawRect(GLfloat x, GLfloat y, int height, int width, float R, float G, float B)
{
     glColor3f(R,G,B);

     glBegin(GL_QUADS);
          glVertex2f( x, y);				        // Top Left
          glVertex2f( x, y + height);				// Bottom Left
          glVertex2f( x + width, y + height);		// Bottom Right
          glVertex2f( x + width, y);				// Top Right
	 glEnd();
}

/*********************************************
    User Input (keyboard)

    I don't calculate frame speed, since it doesn't affect much.
*********************************************/
void keyPress(unsigned char key, int x, int y)
{
    switch (key)
    {
        case 'w':
        case 'W':
             if(420>=p1+pspeed)
                      {p1 += pspeed;}
             break;
        case 's':
        case 'S':
             if(0<=p1-pspeed)
                      {p1 -= pspeed;}
             break;
        case 27 :
             exit(0);
    }
}

/*********************************************
    Special Keys Input (keyboard arrows)

    I don't calculate frame speed, since it doesn't affect much.
*********************************************/
void specialKeyPress(int key, int x, int y)
{
     switch (key)
     {
            case GLUT_KEY_UP:
                 if(420>=p2+pspeed)
                      {p2 += pspeed;}
                 break;
            case GLUT_KEY_DOWN:
                 if(0<=p2-pspeed)
                      {p2 -= pspeed;}
                 break;
     }
}

/*********************************************
    Let there be initial variables.
*********************************************/
void init(void)
{
     // The color the windows will redraw. Its done to erase the previous frame.
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Black, no opacity(alpha).

     // Orthographic projection matrix (initiating 2D window).
     gluOrtho2D(0,500,0,500);

     // Initialize time.
     prtime = time = glutGet(GLUT_ELAPSED_TIME);

     // Initialize score.
     score[0] = score[1] = 0;
}

/* Main function */
int main(int argc, char *argv[])
{
    // Initialize openGL with Double buffer and RGB color without transparency.
    // Its interesting to try GLUT_SINGLE instead of GLUT_DOUBLE.
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

    // Create the window.
    glutInitWindowSize(Width, Height);
    glutInitWindowPosition(150,50);
    glutCreateWindow("Pong by kon_nos");

    // Define the draw function.
    glutDisplayFunc(renderScene);

    // Define the keyboard input function.
    glutKeyboardFunc(keyPress);
    // Define the keyboards' special keys input function.
    glutSpecialFunc(specialKeyPress);

    // Define which function to execute when nothing except the gameplay is updating.
    glutIdleFunc(renderScene);

    init();

    glutMainLoop();

    return 0;
}

Posted on 4 October, 2011, in Game Engines, OpenGL, Programming and tagged , , , , , . Bookmark the permalink. 3 Comments.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: