Hey, im new here, just like to say hello to you all before I begin my post about code
below is some basic openGl code which creates 2 circles on the screen, has them following a circluar path, im trying to get the circle - circle collision detection working (whict is almost does) and when the circles collide, i try and reverse the direction of the circles, only problem is the circles overlap each other and get stuck…ive tried everything here to get it working and the only reason i can see for it not working is the actual frame which the collision occurs…as I think both circles are trying to change directions but because they are overlapping, they cannot break free of each other, any help pls? thanks
#include<windows.h>
#include<gl/gl.h>
#include<gl/glu.h>
#include<math.h>
bool exiting = false;
long windowWidth = 800;
long windowHeight = 600;
long windowBits = 32;
bool fullscreen = false;
HDC hDC;
#define PI 3.14159
//-------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------//
float x_1 = 2.0; // x position of circle 1
float x_2 = -2.0; // x position of circle 2
float y_1 = 2.0; // y position of circle 1
float y_2 = -2.0; // y position of circle 2
float length = 4; // used to set the length of the arc the looping circles create
float angle1 = 0.0; // angle of first circle
float angle2 = 180.0; // angle of second circle
float r1 = 0.5; // radius of circle 1
float r2 = 0.5; // radius of circle 2
float D = 0.0; // to hold value of distance between the 2 circles centers
bool r = false; // boolean to see if circles have collided
void DrawCircle(float radius, float R, float G, float B)
{
glBegin(GL_POLYGON);
glColor3f(R,G,B); // colour
// calculate each vertex on the circle
for (int vertex = 0; vertex < 50; vertex++)
{
// calculate the angle of the current vertex
float angle = (float)vertex * (2.0f * (float)PI)/50;
// draw the current vertex at the correct radius
glVertex3d(cosf(angle)*radius, 0.0, sinf(angle)*radius);
} // end for
glEnd();
} // end DrawCircle()
//-------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------//
//-------------------------------------------------------------------------------------------------//
void SetupPixelFormat(HDC hDC)
{
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size
1, // version
PFD_SUPPORT_OPENGL | // OpenGL window
PFD_DRAW_TO_WINDOW | // render to window
PFD_DOUBLEBUFFER, // support double-buffering
PFD_TYPE_RGBA, // color type
32, // prefered color depth
0, 0, 0, 0, 0, 0, // color bits (ignored)
0, // no alpha buffer
0, // alpha bits (ignored)
0, // no accumulation buffer
0, 0, 0, 0, // accum bits (ignored)
16, // depth buffer
0, // no stencil buffer
0, // no auxiliary buffers
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0, // no layer, visible, damage masks
};
pixelFormat = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, pixelFormat, &pfd);
}
LRESULT CALLBACK MainWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HDC hDC;
static HGLRC hRC;
int height, width;
// dispatch messages
switch (uMsg)
{
case WM_CREATE: // window creation
hDC = GetDC(hWnd);
SetupPixelFormat(hDC);
//SetupPalette();
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
break;
case WM_DESTROY: // window destroy
case WM_QUIT:
case WM_CLOSE: // windows is closing
// deselect rendering context and delete it
wglMakeCurrent(hDC, NULL);
wglDeleteContext(hRC);
// send WM_QUIT to message queue
PostQuitMessage(0);
break;
case WM_SIZE:
height = HIWORD(lParam); // retrieve width and height
width = LOWORD(lParam);
break;
case WM_ACTIVATEAPP: // activate app
break;
case WM_PAINT: // paint
PAINTSTRUCT ps;
BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_LBUTTONDOWN: // left mouse button
break;
case WM_RBUTTONDOWN: // right mouse button
break;
case WM_MOUSEMOVE: // mouse movement
break;
case WM_LBUTTONUP: // left button release
break;
case WM_RBUTTONUP: // right button release
break;
case WM_KEYUP:
break;
case WM_KEYDOWN:
int fwKeys;
LPARAM keyData;
fwKeys = (int)wParam; // virtual-key code
keyData = lParam; // key data
switch(fwKeys)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
default:
break;
}
break;
default:
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX windowClass; // window class
HWND hwnd; // window handle
MSG msg; // message
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT windowRect;
windowRect.left=(long)0; // Set Left Value To 0
windowRect.right=(long)windowWidth; // Set Right Value To Requested Width
windowRect.top=(long)0; // Set Top Value To 0
windowRect.bottom=(long)windowHeight; // Set Bottom Value To Requested Height
// fill out the window class structure
windowClass.cbSize = sizeof(WNDCLASSEX);
windowClass.style = CS_HREDRAW | CS_VREDRAW;
windowClass.lpfnWndProc = MainWindowProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); // default icon
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); // default arrow
windowClass.hbrBackground = NULL; // don't need background
windowClass.lpszMenuName = NULL; // no menu
windowClass.lpszClassName = "GLClass";
windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // windows logo small icon
// register the windows class
if (!RegisterClassEx(&windowClass))
return 0;
if (fullscreen) // fullscreen?
{
DEVMODE dmScreenSettings; // device mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize = sizeof(dmScreenSettings);
dmScreenSettings.dmPelsWidth = windowWidth; // screen width
dmScreenSettings.dmPelsHeight = windowHeight; // screen height
dmScreenSettings.dmBitsPerPel = windowBits; // bits per pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
//
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
// setting display mode failed, switch to windowed
MessageBox(NULL, "Display mode failed", NULL, MB_OK);
fullscreen = FALSE;
}
}
if (fullscreen) // Are We Still In Fullscreen Mode?
{
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle=WS_POPUP; // Windows Style
ShowCursor(FALSE); // Hide Mouse Pointer
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_OVERLAPPEDWINDOW; // Windows Style
}
AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
// class registered, so now create our window
hwnd = CreateWindowEx(NULL, // extended style
"GLClass", // class name
"Circle - Circle Collision", // app name
dwStyle | WS_CLIPCHILDREN |
WS_CLIPSIBLINGS,
0, 0, // x,y coordinate
windowRect.right - windowRect.left,
windowRect.bottom - windowRect.top, // width, height
NULL, // handle to parent
NULL, // handle to menu
hInstance, // application instance
NULL); // no extra params
hDC = GetDC(hwnd);
// check if window creation failed (hwnd would equal NULL)
if (!hwnd)
return 0;
ShowWindow(hwnd, SW_SHOW); // display the window
UpdateWindow(hwnd); // update the window
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
glViewport(0, 0, 800, 600); // reset the viewport to new dimensions
glMatrixMode(GL_PROJECTION); // set projection matrix current matrix
glLoadIdentity(); // reset projection matrix
// calculate aspect ratio of window
gluPerspective(52.0f,(GLfloat)800/(GLfloat)600,1.0f,1000.0f);
glMatrixMode(GL_MODELVIEW); // set modelview matrix
glLoadIdentity(); // reset modelview matrix
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
while (!exiting)
{
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear screen and depth buffer
glLoadIdentity();
gluLookAt(0.0, 10.0, 0.1, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
x_1 = cosf(angle1)*length; // assign new value to circle 1 x position
y_1 = sinf(angle1)*length; // assign new value to circle 1 y position
x_2 = cosf(angle2)*length; // assign new value to circle 2 x position
y_2 = sinf(angle2)*length; // assign new value to circle 2 y position
// calculate the distance between the two centers of the circles
D = sqrt((((x_2+r2)-(x_1+r1))*((x_2+r2)-(x_1+r1))) + (((y_2+r2)-(y_1+r1))*((y_2+r2)-(y_1+r1))));
// if the distance between the centers is less than the two circles
// radii summed up - we have a collision!!
if( D <= r1+r2 )
{
r = true;
}
if( D >= r1+r2)
{
r = false;
}
if( r )
{
angle1 -= 0.05; // increment angle for circle 1 in clockwise direction
angle2 += 0.05; // decrement angle for circle 2 in anti - clockwise direction
}
if( !r )
{
angle1 += 0.05; // increment angle for circle 1 in clockwise direction
angle2 -= 0.05; // decrement angle for circle 2 in anti - clockwise direction
}
//--------------------------------------------------------------------------------
//-------------------------------- CIRCLE 1---------------------------------------
// push matrix onto the stack
glPushMatrix();
// create new x and y position for circle 1
glTranslatef(x_1, 0, y_1);
// call circle function to draw it
DrawCircle(r1, 255, 0, 0);
// pop matrix off the stack
glPopMatrix();
//--------------------------------------------------------------------------------
//--------------------------------- CIRCLE 2--------------------------------------
// push matrix onto the stack
glPushMatrix();
// create new x and y position for circle 2
glTranslatef(x_2, 0, y_2);
// call circle function to draw it
DrawCircle(r2, 0, 0, 255);
// pop matrix off the stack
glPopMatrix();
//--------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
SwapBuffers(hDC);
while (PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE))
{
if (!GetMessage (&msg, NULL, 0, 0))
{
exiting = true;
break;
}
TranslateMessage (&msg);
DispatchMessage (&msg);
}
}
if (fullscreen)
{
ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
return (int)msg.wParam;
}