Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: Help with collision

  1. #1
    Newbie Newbie
    Join Date
    Jan 2014
    Posts
    1

    Help with collision

    The idea of the game is to have ball move and hit a target on a wall. I have no idea how to do the collision with the wall and the ball.

    Here is the code:

    //Windows - uncomment the includes below

    #include "shared/gltools.h" //OpenGL toolkit - in the local shared folder
    #include <math.h> //These were included in glm.cpp so I kept them here
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include "shared/glm.h"
    #include <iostream> //Needed for console output (debugging)


    //
    // texture.cpp
    //
    //
    //Windows uncomment the includes below


    //Mac includes + frameworks OpenGL and GLUT - comment out for Windows
    //#include <iostream>
    //#include <stdio.h>
    //#include <OpenGL/glu.h>
    //#include <GLUT/glut.h>
    //#include "gltools.h"
    //#include <OpenGL/gl.h>
    //#include <OpenGL/glext.h>
    //#include <OpenGL/gl3ext.h>

    //note that this needs gltools.h and gltools.cpp to be included in the shared directory

    //can define any number of textures here - we just have 2 images
    //these are just integers so you can use them as such
    #define IMAGE1 0
    #define IMAGE2 1
    #define IMAGE3 2
    #define IMAGE4 3


    bool ballGoingUp = false;
    bool ballGoingDown;
    bool ballGoingLeft;
    bool ballGoingRight;
    bool boolMoving = false;

    float ballUDMovement = 0.0;
    float ballLRMovement = 0.0;
    float length = 1.0;
    float rotationTimer = 0;
    float scoreNumber;

    float ballMoving1;
    float ballMoving2;

    int frame=0,time2 = 0,timebase=0;
    char frameRate [6];

    #define TEXTURE_COUNT 4
    GLuint textures[TEXTURE_COUNT];
    char score [6];

    //below is simply a character array to hold the file names
    //note that you may need to replace the below with the full directory root depending on where you put your image files
    //if you put them where the exe is then you just need the name as below
    const char *textureFiles[TEXTURE_COUNT] = {"padhamsBG.tga", "brick_texture.tga","grass_diff.tga","FootballComp leteMap.tga"};


    //for lighting if you want to experiment with these

    GLfloat mKa[4] = {0.11f,0.06f,0.11f,1.0f}; //ambient
    GLfloat mKd[4] = {0.43f,0.47f,0.54f,1.0f}; //diffuse
    GLfloat mKs[4] = {1.0f,1.0f,1.0f,1.0f}; //specular
    GLfloat mKe[4] = {0.5f,0.5f,0.0f,1.0f}; //emission




    // Useful lighting colour values
    GLfloat greenLight[] = { 0.0f, 0.6f, 0.0f, 1.0f };
    GLfloat redLight[] = { 0.6f, 0.0f, 0.0f, 1.0f };
    GLfloat blueLight[] = { 0.0f, 0.0f, 0.6f, 1.0f };
    GLfloat whiteLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    GLfloat noLight[] = { 0.1f, 0.1f, 0.1f, 1.0f };//well, very little light intensity
    GLfloat lightPos[] = { 100.0f, 100.0f, 50.0f, 1.0f };
    GLfloat lightPos1[] = { ballLRMovement, ballUDMovement, 0.0f, 0.0f };


    //we need these for the texture loader
    //they are to do with the image format and size
    GLint iWidth, iHeight, iComponents;
    GLenum eFormat;
    // this is a pointer to memory where the image bytes will be held
    GLbyte *pBytes0;

    //end of intialisation

    //------------------------------------//

    void renderBitmapString(
    float x,
    float y,
    float z,
    void *font,
    char *string) {
    char *c;
    glRasterPos3f(x, y,z);
    for (c=string; *c != '\0'; c++) {
    glutBitmapCharacter(font, *c);
    }
    }


    void SpecialKeys(int key, int x, int y)
    {

    if(key == GLUT_KEY_UP){

    ballUDMovement = ballUDMovement + length;

    }

    if(key == GLUT_KEY_DOWN){


    ballUDMovement = ballUDMovement - length;
    }

    if(key == GLUT_KEY_LEFT){


    ballLRMovement = ballLRMovement - length;
    ballMoving2 = ballLRMovement;
    }

    if(key == GLUT_KEY_RIGHT){


    ballLRMovement = ballLRMovement + length;
    ballMoving2 = ballLRMovement;
    }

    if(key == GLUT_KEY_F1){

    ballGoingUp = true;
    ballMoving1 += ballUDMovement/5;

    }
    }

    void drawTexturedQuad(int image)
    {
    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable( GL_TEXTURE_2D );
    //bind the texture
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0,0.0);
    glVertex3f(-50.0, 0.0,100.0);
    glTexCoord3f(1.0,0.0,0.0);
    glVertex3f(50.0, 0.0,100.0);
    glTexCoord2f(1.0,1.0);
    glVertex3f(50.0, 100.0,100.0);
    glTexCoord2f(0.0,1.0);
    glVertex3f(-50.0, 100.0,100.0);
    glEnd();
    glDisable( GL_TEXTURE_2D );

    }


    void drawGrass(int image)
    {
    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable( GL_TEXTURE_2D );
    //bind the texture
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0,0.0);
    glVertex3f(-800.0, 0.0,100.0);
    glTexCoord3f(1.0,0.0,0.0);
    glVertex3f(800.0, 0.0,100.0);
    glTexCoord2f(1.0,1.0);
    glVertex3f(800.0, 300.0,100.0);
    glTexCoord2f(0.0,1.0);
    glVertex3f(-800.0, 300.0,100.0);
    glEnd();
    glDisable( GL_TEXTURE_2D );

    }

    void drawMiddleWall(int image)
    {
    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable( GL_TEXTURE_2D );
    //bind the texture
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0,0.0);
    glVertex3f(-100.0, 0.0,100.0);
    glTexCoord3f(1.0,0.0,0.0);
    glVertex3f(100.0, 0.0,100.0);
    glTexCoord2f(1.0,1.0);
    glVertex3f(100.0, 100.0,100.0);
    glTexCoord2f(0.0,1.0);
    glVertex3f(-100.0, 100.0,100.0);
    glEnd();
    glDisable( GL_TEXTURE_2D );

    }

    void drawSideWall(int image)
    {
    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable( GL_TEXTURE_2D );
    //bind the texture
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0,0.0);
    glVertex3f(-100.0, 0.0,100.0);
    glTexCoord3f(1.0,0.0,0.0);
    glVertex3f(100.0, 0.0,100.0);
    glTexCoord2f(1.0,1.0);
    glVertex3f(100.0, 100.0,100.0);
    glTexCoord2f(0.0,1.0);
    glVertex3f(-100.0, 100.0,100.0);
    glEnd();
    glDisable( GL_TEXTURE_2D );

    }

    void drawSky(int image)
    {
    //add some lighting normals for each vertex
    //draw the texture on the front
    glEnable(GL_TEXTURE_2D);
    glFrontFace(GL_CW); //use glFrontFace(GL_CW) to texture the other side - not needed here as we set this elsewhere
    glColor3f(0.8, 0.8, 0.8);
    glEnable( GL_TEXTURE_2D );
    //bind the texture
    glBindTexture(GL_TEXTURE_2D, textures[image]);
    glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0,0.0);
    glVertex3f(-300.0, 0.0,100.0);
    glTexCoord3f(1.0,0.0,0.0);
    glVertex3f(300.0, 0.0,100.0);
    glTexCoord2f(1.0,1.0);
    glVertex3f(300.0, 110.0,100.0);
    glTexCoord2f(0.0,1.0);
    glVertex3f(-300.0, 110.0,99.0);
    glEnd();
    glDisable( GL_TEXTURE_2D );

    }

    void disk( float x, float y, float r)
    {
    glBegin( GL_TRIANGLE_FAN );
    glVertex2f( x, y );
    for( float i = 0; i <= 2 * 3.14 + 0.1; i += 0.1 )
    {
    glVertex2f( x + sin( i ) * r, y + cos( i ) * r );
    }
    glEnd();
    }

    void drawBall()
    {
    GLUquadricObj *qObj = gluNewQuadric();

    gluQuadricNormals(qObj, GLU_SMOOTH);

    gluQuadricTexture(qObj, GL_TRUE);

    glEnable(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, 5);

    glPushMatrix();
    glTranslatef(0.0, -101, 100.0);
    gluSphere(qObj, 20.0f, 24, 24);
    glPopMatrix();

    }

    void direction1()
    {
    glBegin(GL_QUADS);
    glColor3f(1.0,0.0,0.0);
    glVertex2f(ballLRMovement,-70);
    glVertex2f(ballLRMovement,-60);
    glVertex2f(-5,-60);
    glVertex2f(-5,-70);
    glEnd();
    }

    void direction2()
    {

    glBegin(GL_QUADS);
    glColor3f(0.0, 0.0, 1.0);
    glVertex2f(10,0);
    glVertex2f(10,ballUDMovement);
    glVertex2f(20,ballUDMovement);
    glVertex2f(20,0);
    glEnd();

    }


    // Called to draw scene


    void RenderScene(void)
    {


    // Clear the window with current clearing colour
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);



    glMatrixMode(GL_MODELVIEW);

    // a test point
    //use for locating points in your view
    /* glEnable(GL_POINT_SMOOTH);
    glPointSize(10.0);
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_POINTS);
    glVertex3f(0.0f, 0.0f, 100.0f);
    glEnd();
    */

    sprintf(score, "5");
    glColor3f(1.0, 0.0, 0.0);
    renderBitmapString(-6,30,101,GLUT_BITMAP_HELVETICA_18,score);

    sprintf(score, "10");
    glColor3f(1.0, 0.0, 0.0);
    renderBitmapString(-45,-12,101,GLUT_BITMAP_HELVETICA_18,score);

    sprintf(score, "4");
    glColor3f(1.0, 0.0, 0.0);
    renderBitmapString(45,5,101,GLUT_BITMAP_HELVETICA_ 18,score);

    sprintf(score,"Score: ");
    glColor3f(1.0, 1.0, 1.0);
    renderBitmapString(-160,130,101,GLUT_BITMAP_TIMES_ROMAN_24,score);


    frame++;
    time2=glutGet(GLUT_ELAPSED_TIME);
    if (time2 - timebase > 1000) {

    sprintf(frameRate,"FPS: %4.2f",
    frame*1000.0/(time2-timebase));

    timebase = time2;
    frame = 0;
    }
    renderBitmapString(30,130,101,GLUT_BITMAP_TIMES_RO MAN_24,frameRate);


    glPushMatrix();
    glTranslatef(ballMoving2,0,0);
    if (ballGoingUp = true)
    {
    glTranslatef(0,ballMoving1,-ballMoving1);
    }
    drawBall();
    glPopMatrix();


    glPushMatrix();
    glTranslatef(0,-250,0);
    glRotatef(-50,1,0,0);
    drawGrass(IMAGE3);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0,-20,-80);
    drawMiddleWall(IMAGE2);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(200,-20,100);
    glRotatef(-70,0.0,1.0,0.0);
    drawSideWall(IMAGE2);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-200,-20,100);
    glRotatef(70,0.0,1.0,0.0);
    drawSideWall(IMAGE2);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-20,80,-100);
    drawSky(IMAGE1);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-20,20,25);
    disk(15,15,15);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-60,-18,25);
    disk(10,10,10);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(35,-10,25);
    disk(20,20,20);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(-80,-40,100);
    direction1();
    glPopMatrix();

    glPushMatrix();
    glTranslatef(70,-100,100);
    direction2();
    glPopMatrix();

    }


    // This function does any needed initialization on the rendering
    // context.
    void SetupRC()
    {
    //textures

    GLuint texture;
    // allocate a texture name
    glGenTextures( 1, &texture );
    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
    //make sure any TGA has no alpha channel - photoshop is a good converter to targa (TGA)
    //the gltLoadTGA method is found in gltools.cpp and is from the OpenGL SuperBible book
    //there are quite a few ways of loading images
    // Load textures in a for loop
    glGenTextures(TEXTURE_COUNT, textures);
    //this puts the texture into OpenGL texture memory
    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    for(int iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++)
    {
    // Bind to next texture object
    glBindTexture(GL_TEXTURE_2D, textures[iLoop]);

    // Load texture data, set filter and wrap modes
    //note that gltLoadTGA is in the glm.cpp file and not a built-in openGL function
    pBytes0 = gltLoadTGA(textureFiles[iLoop],&iWidth, &iHeight,
    &iComponents, &eFormat);

    glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes0);

    //set up texture parameters

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    //try these too
    // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
    // glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
    free(pBytes0);
    }

    //enable textures
    glEnable(GL_TEXTURE_2D);


    glEnable(GL_DEPTH_TEST); // Hidden surface removal
    //glFrontFace(GL_CCW);// Counter clock-wise polygons face out
    //glEnable(GL_CULL_FACE); // Do not calculate inside

    glCullFace(GL_FRONT_AND_BACK);

    // Enable lighting
    glEnable(GL_LIGHTING);
    glEnable(GL_POINT_SMOOTH);
    // Setup and enable light 0
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
    glLightfv(GL_LIGHT0,GL_DIFFUSE,whiteLight);
    glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
    glEnable(GL_LIGHT0);


    // Enable colour tracking
    glEnable(GL_COLOR_MATERIAL);

    // Set Material properties to follow glColor values
    glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);

    // Black blue background
    glClearColor(0.0f, 0.0f, 0.03f, 1.0f );
    }


    void TimerFunc(int value)
    {
    rotationTimer = rotationTimer +1;
    glutSwapBuffers();
    glutPostRedisplay();
    glutTimerFunc(25, TimerFunc, 1);
    }

    void ChangeSize(int w, int h)
    {
    GLfloat fAspect;

    // Prevent a divide by zero
    if(h == 0)
    h = 1;

    // Set Viewport to window dimensions
    glViewport(0, 0, w, h);

    // Calculate aspect ratio of the window
    fAspect = (GLfloat)w/(GLfloat)h;

    // Set the perspective coordinate system
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // field of view of 45 degrees, near and far planes 1.0 and 1000
    //that znear and zfar should typically have a ratio of 1000:1 to make sorting out z depth easier for the GPU
    gluPerspective(55.0f, fAspect, 1.0, 1000.0);
    // Modelview matrix reset
    glMatrixMode(GL_MODELVIEW);
    //pull the eye position back to view the scene
    gluLookAt(0.00,0,400.0,//eye
    0.00,0.00,0.00,//centre
    0.00,1.00,0.00);//up
    }




    int main(int argc, char* argv[])
    {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    glutInitWindowSize(800, 600);// a 4:3 ratio
    glutCreateWindow("Football Game");
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);
    glutTimerFunc(25, TimerFunc, 1);
    glutSpecialFunc(SpecialKeys);
    SetupRC();
    glutMainLoop();
    return 0;
    }

  2. #2
    Senior Member OpenGL Pro
    Join Date
    Jan 2012
    Location
    Australia
    Posts
    1,106
    I have no idea how to do the collision...

    This is a very big topic but there is plenty of examples on the web.

  3. #3
    Junior Member Newbie
    Join Date
    Sep 2012
    Posts
    7
    OpenGL doesn't handle collision detection. You could try with box-collision detection and spherical-collision detection. It's something like this:

    Code :
    // Box collision:
    Vector3 Box1,  Box2
    If Box1 is inside Box2
        // Collision
    Else
        // No collision

    Code :
    // Spherical collision:
    Vector3 Obj1Position; Float Obj1Size;
    Vector3 Obj2Position; Float Obj2Size;
     
    If (Distance between Obj1Position and Obj2Position) < (Obj1Size + Obj2Size)
        // Collision
    Else
        // No collision

  4. #4
    Newbie Newbie
    Join Date
    Jan 2014
    Posts
    3
    "I have no idea how to do the collision with the wall and the ball."

    The "ball hits the wall" test is probably one of the simplest: my math background is a bit dusty, but I think it boils down to determine whether a point is in a plane (your "wall*) or not. Now your point is not infinitely small, but has a radius instead (your "ball"), so you probably want to know: "What is the distance of a point (centre of your ball) to a given plane?" - When that distance is smaller than the radius of your ball, you have a hit!

    For everything else(tm) you could also incorporate a "physics engine" which does all the math for you. "Bullet Physics" is such an engine, and it is open source!

    Here is a tutorial how to incorporate it into a "the ball hits the wall" game (aka Breakout): it seems I cannot add URLs (yet?) to my posts, so google for "Bullet Physics Tutorial: Getting Started ray wenderlich" (should be the first hit)

    It is for iOS and OpenGL ES 2.0 and XCode, but you'll figure it out

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •