This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| GL_Export For 3DS Max Users Submitted by

If you are a 3DS Max user and want your Max scene to appear in your OpenGL project, this smart utility does just that. Please read the provided readme.html.

Currently browsing [GL_Export1.zip] (104,965 bytes) - [BlankProject/Main.cpp] - (4,182 bytes)

    #pragma comment(lib, "opengl32.lib")
    #pragma comment(lib, "glu32.lib")
    #pragma comment(lib, "glaux.lib")

    #include "main.h"
    #include <math.h>
    #include "Camera.h"

    // Include Your Header File Here
    // Then Call Function CreateMaterialLib()
    //			Don't forget Create<YourObj/s>()
    //			in RenderScene() Call glCallList Function to Call your Objects ObjectID

    #define		INC	3.0
    #define		R_180	3.142857142
    #define		R_90	1.571428571

    bool  g_bFullScreen = 1;							// Set full screen as default
    HWND  g_hWnd;											// This is the handle for the window
    RECT  g_rRect;											// This holds the window dimensions
    HDC   g_hDC;											// General HDC - (handle to device context)
    HGLRC g_hRC;											// General OpenGL_DC - Our Rendering Context for OpenGL
    HINSTANCE g_hInstance;									// This holds the global hInstance for UnregisterClass() in DeInit()
    float rotationH,rotationV;
    Point3 CamPos, CamTar;
    float thetha,thethaV=0;
    float focullength=2;
    float step=5;

    GLfloat Vertex[] = {	-75.0000,	-50.0000,	0.0000,
    						75.0000,	-50.0000,	0.0000,
    						-75.0000,	50.0000,	0.0000,
    						75.0000,	50.0000,	0.0000
    					};

    GLfloat TVertex[] = {	0.0f, 0.0f,
    						1.0f, 0.0f,
    						0.0f, 1.0f,
    						1.0f, 1.0f,
    					};
    CCamera	g_Camera;

    UINT g_Texture[MAX_TEXTURES];

    void Init(HWND hWnd)
    {
    	g_hWnd = hWnd;										// Assign the window handle to a global window handle
    	GetClientRect(g_hWnd, &g_rRect);					// Assign the windows rectangle to a global RECT
    	InitializeOpenGL(g_rRect.right, g_rRect.bottom);	// Init OpenGL with the global rect

    	// CreateMaterialLib() here and
    	// Object's Create Functions

    	g_Camera.PositionCamera( 10,150,12, 9,150,12, 0,1,0 );
    	g_Camera.SetCameraRadius(1);

    }

    WPARAM MainLoop()
    {
    	MSG msg;
    	while(1)											// Do our infinate loop
    	{													// Check if there was a message
    		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
            {
    			if(msg.message == WM_QUIT)					// If the message wasnt to quit
    				break;
                TranslateMessage(&msg);						// Find out what the message does
                DispatchMessage(&msg);						// Execute the message
            }
    		else											// if there wasn't a message
    		{
    			g_Camera.Update();
    			RenderScene();								// Redraw the scene every frame
    		}
    	}

    	DeInit();											// Free all the app's memory allocated

    	return(msg.wParam);									// Return from the program
    }

    void RenderScene()
    {
    	CamTar.x = CamPos.x+focullength*cos( thetha );
    	CamTar.z = CamPos.z+focullength*sin( thetha );
    	CamPos.y = 100;
    	CamTar.y = 100;

    	glVertexPointer( 3, GL_FLOAT, 0, Vertex );
    	glTexCoordPointer(2, GL_FLOAT, 0, TVertex );

    	glEnableClientState(GL_VERTEX_ARRAY);
    	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    	glLoadIdentity();
    	g_Camera.Look();
    	glPushMatrix();

    			// Call Your Object Lists Here by
    			// glCallList()
    			// Like glCallList( BOX01 ) if BOX01 is defined.

    	glPopMatrix();

    	SwapBuffers(g_hDC);									// Swap the backbuffers to the foreground
    }

    LRESULT CALLBACK WinProc(HWND hWnd,UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        LONG    lRet = 0;
        PAINTSTRUCT    ps;
        static int lxPos,lyPos;
        static int xPos, yPos;

        POINT mpos;
        switch (uMsg)
    	{
        case WM_SIZE:										// If the window is resized
    		if(!g_bFullScreen)								// Do this only if we are NOT in full screen
    		{
    			SizeOpenGLScreen(LOWORD(lParam),HIWORD(lParam));// LoWord=Width, HiWord=Height
    			GetClientRect(hWnd, &g_rRect);

    		}
            break;

    	case WM_PAINT:										// If we need to repaint the scene
    		BeginPaint(hWnd, &ps);							// Init the paint struct
    		EndPaint(hWnd, &ps);							// EndPaint, Clean up
    		break;
        case WM_CLOSE:										// If the window is being closes
            PostQuitMessage(0);								// Send a QUIT Message to the window
            break;

        default:											// Return by default
            lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
            break;
        }

        return lRet;										// Return by default
    }

Currently browsing [GL_Export1.zip] (104,965 bytes) - [BlankProject/3DMath.h] - (4,395 bytes)

    #ifndef _3DMATH_H
    #define _3DMATH_H

    #define PI 3.1415926535897932					// This is our famous PI

    #define BEHIND		0
    #define INTERSECTS	1
    #define FRONT		2

    // This is our basic 3D point/vector class
    struct CVector3
    {
    public:

    	// A default constructor
    	CVector3() {}
    	CVector3( CVector3 *vPos )
    	{
    		x = vPos->x;
    		y = vPos->y;
    		z = vPos->z;
    	}
    	// This is our constructor that allows us to initialize our data upon creating an instance
    	CVector3(float X, float Y, float Z)
    	{
    		x = X; y = Y; z = Z;
    	}

    	// Here we overload the + operator so we can add vectors together
    	CVector3 operator+(CVector3 vVector)
    	{
    		// Return the added vectors result.
    		return CVector3(vVector.x + x, vVector.y + y, vVector.z + z);
    	}

    	// Here we overload the - operator so we can subtract vectors
    	CVector3 operator-(CVector3 vVector)
    	{
    		// Return the subtracted vectors result
    		return CVector3(x - vVector.x, y - vVector.y, z - vVector.z);
    	}

    	// Here we overload the * operator so we can multiply by scalars
    	CVector3 operator*(float num)
    	{
    		// Return the scaled vector
    		return CVector3(x * num, y * num, z * num);
    	}

    	// Here we overload the / operator so we can divide by a scalar
    	CVector3 operator/(float num)
    	{
    		// Return the scale vector
    		return CVector3(x / num, y / num, z / num);
    	}

    	float x, y, z;
    };

    // This returns the absolute value of "num"
    float Absolute(float num);

    //	This returns a perpendicular vector from 2 given vectors by taking the cross product.
    CVector3 Cross(CVector3 vVector1, CVector3 vVector2);

    //	This returns the magnitude of a normal (or any other vector)
    float Magnitude(CVector3 vNormal);

    //	This returns a normalize vector (A vector exactly of length 1)
    CVector3 Normalize(CVector3 vNormal);

    //	This returns the normal of a polygon (The direction the polygon is facing)
    CVector3 Normal(CVector3 vPolygon[]);

    // This returns the distance between 2 3D points
    float Distance(CVector3 vPoint1, CVector3 vPoint2);

    // This returns the point on the line segment vA_vB that is closest to point vPoint
    CVector3 ClosestPointOnLine(CVector3 vA, CVector3 vB, CVector3 vPoint);

    // This returns the distance the plane is from the origin (0, 0, 0)
    // It takes the normal to the plane, along with ANY point that lies on the plane (any corner)
    float PlaneDistance(CVector3 Normal, CVector3 Point);

    // This takes a triangle (plane) and line and returns true if they intersected
    bool IntersectedPlane(CVector3 vPoly[], CVector3 vLine[], CVector3 &vNormal, float &originDistance);

    // This returns the dot product between 2 vectors
    float Dot(CVector3 vVector1, CVector3 vVector2);

    // This returns the angle between 2 vectors
    double AngleBetweenVectors(CVector3 Vector1, CVector3 Vector2);

    // This returns an intersection point of a polygon and a line (assuming intersects the plane)
    CVector3 IntersectionPoint(CVector3 vNormal, CVector3 vLine[], double distance);

    // This returns true if the intersection point is inside of the polygon
    bool InsidePolygon(CVector3 vIntersection, CVector3 Poly[], long verticeCount);

    // Use this function to test collision between a line and polygon
    bool IntersectedPolygon(CVector3 vPoly[], CVector3 vLine[], int verticeCount);

    // This function classifies a sphere according to a plane. (BEHIND, in FRONT, or INTERSECTS)
    int ClassifySphere(CVector3 &vCenter,
    				   CVector3 &vNormal, CVector3 &vPoint, float radius, float &distance);

    // This takes in the sphere center, radius, polygon vertices and vertex count.
    // This function is only called if the intersection point failed.  The sphere
    // could still possibly be intersecting the polygon, but on it's edges.
    bool EdgeSphereCollision(CVector3 &vCenter,
    						 CVector3 vPolygon[], int vertexCount, float radius);

    // This returns true if the sphere is intersecting with the polygon.
    bool SpherePolygonCollision(CVector3 vPolygon[],
    							CVector3 &vCenter, int vertexCount, float radius);

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    // This returns the offset the sphere needs to move in order to not intersect the plane
    CVector3 GetCollisionOffset(CVector3 &vNormal, float radius, float distance);

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    #endif

Currently browsing [GL_Export1.zip] (104,965 bytes) - [BlankProject/Camera.cpp] - (13,155 bytes)

    //***********************************************************************//
    //																		 //
    //		- "Talk to me like I'm a 3 year old!" Programming Lessons -		 //
    //                                                                       //
    //		$Author:		DigiBen		DigiBen@GameTutorials.com			 //
    //																		 //
    //		$Program:		BSP Loader										 //
    //																		 //
    //		$Description:	Loads faces and textures from a Quake3 BSP file  //
    //																		 //
    //		$Date:			5/9/02											 //
    //																		 //
    //***********************************************************************//

    #include "main.h"
    #include "Camera.h"

    // We increased the speed a bit from the Camera Strafing Tutorial
    // This is how fast our camera moves
    #define kSpeed	190.0f

    // Our global float that stores the elapsed time between the current and last frame
    float g_FrameInterval = 0.0f;

    ///////////////////////////////// CALCULATE FRAME RATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This function calculates the frame rate and time intervals between frames
    /////
    ///////////////////////////////// CALCULATE FRAME RATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    void CalculateFrameRate()
    {
    	static float framesPerSecond    = 0.0f;		// This will store our fps
        static float lastTime			= 0.0f;		// This will hold the time from the last frame
    	static char strFrameRate[50] = {0};			// We will store the string here for the window title

    	static float frameTime = 0.0f;				// This stores the last frame's time

    	// Get the current time in seconds
        float currentTime = timeGetTime() * 0.001f;

    	// Here we store the elapsed time between the current and last frame,
    	// then keep the current frame in our static variable for the next frame.
     	g_FrameInterval = currentTime - frameTime;
    	frameTime = currentTime;

    	// Increase the frame counter
        ++framesPerSecond;

    	// Now we want to subtract the current time by the last time that was stored
    	// to see if the time elapsed has been over a second, which means we found our FPS.
        if( currentTime - lastTime > 1.0f )
        {
    		// Here we set the lastTime to the currentTime
    	    lastTime = currentTime;

    		// Copy the frames per second into a string to display in the window title bar
    		sprintf(strFrameRate, "Current Frames Per Second: %d", int(framesPerSecond));

    		// Set the window title bar to our string
    		SetWindowText(g_hWnd, strFrameRate);

    		// Reset the frames per second
            framesPerSecond = 0;
        }
    }

    ///////////////////////////////// CCAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This is the class constructor
    /////
    ///////////////////////////////// CCAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    CCamera::CCamera()
    {
    	CVector3 vZero = CVector3(0.0, 0.0, 0.0);		// Init a vVector to 0 0 0 for our position
    	CVector3 vView = CVector3(0.0, 1.0, 0.5);		// Init a starting view vVector (looking up and out the screen)
    	CVector3 vUp   = CVector3(0.0, 0.0, 1.0);		// Init a standard up vVector (Rarely ever changes)

    	m_vPosition	= vZero;					// Init the position to zero
    	m_vView		= vView;					// Init the view to a std starting view
    	m_vUpVector	= vUp;						// Init the UpVector

    	for( int i=0; i<10 ; i++ )
    	{
    		for( int j=0 ; j<10 ; j++ )
    		{
    			if( i==0 || j==0 || i==9 || j==9 )
    				Map[i][j] = 1;
    			else
    				Map[i][j] = 0;

    		}
    	}
    }

    ///////////////////////////////// POSITION CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This function sets the camera's position and view and up vVector.
    /////
    ///////////////////////////////// POSITION CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    void CCamera::PositionCamera(float positionX, float positionY, float positionZ,
    				  		     float viewX,     float viewY,     float viewZ,
    							 float upVectorX, float upVectorY, float upVectorZ)
    {
    	CVector3 vPosition	= CVector3(positionX, positionY, positionZ);
    	CVector3 vView		= CVector3(viewX, viewY, viewZ);
    	CVector3 vUpVector	= CVector3(upVectorX, upVectorY, upVectorZ);

    	// The code above just makes it cleaner to set the variables.
    	// Otherwise we would have to set each variable x y and z.

    	m_vPosition = vPosition;					// Assign the position
    	m_vView     = vView;						// Assign the view
    	m_vUpVector = vUpVector;					// Assign the up vector
    }

    ///////////////////////////////// SET VIEW BY MOUSE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This allows us to look around using the mouse, like in most first person games.
    /////
    ///////////////////////////////// SET VIEW BY MOUSE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    void CCamera::SetViewByMouse()
    {
    	POINT mousePos;									// This is a window structure that holds an X and Y
    	int middleX = SCREEN_WIDTH  >> 1;				// This is a binary shift to get half the width
    	int middleY = SCREEN_HEIGHT >> 1;				// This is a binary shift to get half the height
    	float angleY = 0.0f;							// This is the direction for looking up or down
    	float angleZ = 0.0f;							// This will be the value we need to rotate around the Y axis (Left and Right)
    	static float currentRotX = 0.0f;

    	// Get the mouse's current X,Y position
    	GetCursorPos(&mousePos);

    	// If our cursor is still in the middle, we never moved... so don't update the screen
    	if( (mousePos.x == middleX) && (mousePos.y == middleY) ) return;

    	// Set the mouse position to the middle of our window
    	SetCursorPos(middleX, middleY);

    	// Get the direction the mouse moved in, but bring the number down to a reasonable amount
    	angleY = (float)( (middleX - mousePos.x) ) / 500.0f;
    	angleZ = (float)( (middleY - mousePos.y) ) / 500.0f;

    	// Here we keep track of the current rotation (for up and down) so that
    	// we can restrict the camera from doing a full 360 loop.
    	currentRotX -= angleZ;

    	/* Kapil This is desable because it restricts the viewing angle
    	// If the current rotation (in radians) is greater than 1.0, we want to cap it.
    	if(currentRotX > 1.0f)
    		currentRotX = 1.0f;
    	// Check if the rotation is below -1.0, if so we want to make sure it doesn't continue
    	else if(currentRotX < -1.0f)
    		currentRotX = -1.0f;
    	// Otherwise, we can rotate the view around our position
    	else
    	{*/
    		// To find the axis we need to rotate around for up and down
    		// movements, we need to get a perpendicular vector from the
    		// camera's view vector and up vector.  This will be the axis.
    		CVector3 vAxis = Cross(m_vView - m_vPosition, m_vUpVector);
    		vAxis = Normalize(vAxis);

    		// Rotate around our perpendicular axis and along the y-axis
    		RotateView(angleZ, vAxis.x, vAxis.y, vAxis.z);
    		RotateView(angleY, 0, 1, 0);
    	//}
    }

    ///////////////////////////////// ROTATE VIEW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This rotates the view around the position using an axis-angle rotation
    /////
    ///////////////////////////////// ROTATE VIEW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    void CCamera::RotateView(float angle, float x, float y, float z)
    {
    	CVector3 vNewView;

    	// Get the view vector (The direction we are facing)
    	CVector3 vView = m_vView - m_vPosition;

    	// Calculate the sine and cosine of the angle once
    	float cosTheta = (float)cos(angle);
    	float sinTheta = (float)sin(angle);

    	// Find the new x position for the new rotated point
    	vNewView.x  = (cosTheta + (1 - cosTheta) * x * x)		* vView.x;
    	vNewView.x += ((1 - cosTheta) * x * y - z * sinTheta)	* vView.y;
    	vNewView.x += ((1 - cosTheta) * x * z + y * sinTheta)	* vView.z;

    	// Find the new y position for the new rotated point
    	vNewView.y  = ((1 - cosTheta) * x * y + z * sinTheta)	* vView.x;
    	vNewView.y += (cosTheta + (1 - cosTheta) * y * y)		* vView.y;
    	vNewView.y += ((1 - cosTheta) * y * z - x * sinTheta)	* vView.z;

    	// Find the new z position for the new rotated point
    	vNewView.z  = ((1 - cosTheta) * x * z - y * sinTheta)	* vView.x;
    	vNewView.z += ((1 - cosTheta) * y * z + x * sinTheta)	* vView.y;
    	vNewView.z += (cosTheta + (1 - cosTheta) * z * z)		* vView.z;

    	// Now we just add the newly rotated vector to our position to set
    	// our new rotated view of our camera.
    	m_vView = m_vPosition + vNewView;
    }

    ///////////////////////////////// STRAFE CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This strafes the camera left and right depending on the speed (-/+)
    /////
    ///////////////////////////////// STRAFE CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    void CCamera::StrafeCamera(float speed)
    {
    	// Add the strafe vector to our position
    	CVector3 m_vPosition1 ( &m_vPosition ),m_vView1( &m_vView );
    	m_vPosition1.x += m_vStrafe.x * speed;
    	m_vPosition1.z += m_vStrafe.z * speed;

    	// Add the strafe vector to our view
    	m_vView1.x += m_vStrafe.x * speed;
    	m_vView1.z += m_vStrafe.z * speed;
    	if( m_vPosition1.x > -800 && m_vPosition1.x < 230
    		&& m_vPosition1.z > -190 && m_vPosition1.z < 770 )
    	{
    		m_vPosition.x = m_vPosition1.x;
    		m_vPosition.z = m_vPosition1.z;

    		m_vView.x = m_vView1.x;
    		m_vView.z = m_vView1.z;
    	}
    }

    ///////////////////////////////// MOVE CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This will move the camera forward or backward depending on the speed
    /////
    ///////////////////////////////// MOVE CAMERA \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    void CCamera::MoveCamera(float speed)
    {
    	// Get the current view vector (the direction we are looking)
    	CVector3 m_vPosition1 ( &m_vPosition ),m_vView1( &m_vView );
    	CVector3 vVector = m_vView - m_vPosition;

    	vVector = Normalize(vVector);
    	m_vPosition1.x += vVector.x * speed;		// Add our acceleration to our position's X
    	m_vPosition1.y += vVector.y * speed;		// Add our acceleration to our position's Y
    	m_vPosition1.z += vVector.z * speed;		// Add our acceleration to our position's Z

    	m_vView1.x += vVector.x * speed;			// Add our acceleration to our view's X
    	m_vView1.y += vVector.y * speed;			// Add our acceleration to our view's Y
    	m_vView1.z += vVector.z * speed;			// Add our acceleration to our view's Z

    	// Here should be the collision testing condition.....
    	if( m_vPosition1.x > -800 && m_vPosition1.x < 230
    		&& m_vPosition1.z > -190 && m_vPosition1.z < 770 )
    	{
    		m_vPosition.x = m_vPosition1.x;
    		m_vPosition.y = m_vPosition1.y;
    		m_vPosition.z = m_vPosition1.z;

    		m_vView.x = m_vView1.x;
    		m_vView.y = m_vView1.y;
    		m_vView.z = m_vView1.z;
    	}
    }

    //////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

    ///////////////////////////////// CHECK CAMERA COLLISION \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This checks all the polygons in our list and offsets the camera if collided
    /////
    ///////////////////////////////// CHECK CAMERA COLLISION \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    void CCamera::CheckCameraCollision(CVector3 *pVertices, int numOfVerts)
    {
    	for(int i = 0; i < numOfVerts; i += 3)
    	{

    		CVector3 vTriangle[3] = { pVertices[i], pVertices[i+1], pVertices[i+2] };
    		CVector3 vNormal = Normal(vTriangle);
    		float distance = 0.0f;
    		int classification = ClassifySphere(m_vPosition, vNormal, vTriangle[0], m_radius, distance);
    		if(classification == INTERSECTS)
    		{

    			CVector3 vOffset = vNormal * distance;
    			CVector3 vIntersection = m_vPosition - vOffset;
    			if(InsidePolygon(vIntersection, vTriangle, 3) ||
    			   EdgeSphereCollision(m_vPosition, vTriangle, 3, m_radius / 2))
    			{
    				vOffset = GetCollisionOffset(vNormal, m_radius, distance);
    				m_vPosition = m_vPosition + vOffset;
    				m_vView = m_vView + vOffset;
    			}
    		}
    	}
    }

    void CCamera::CheckForMovement()
    {
    	float speed = kSpeed * g_FrameInterval;

    	x = (m_vView.x + 750 )/100;
    	y = (m_vView.z + 180 )/100;
    	if(GetKeyState(VK_UP) & 0x80 || GetKeyState('W') & 0x80)
    	{

    			MoveCamera(speed);
    	}

    	if(GetKeyState(VK_DOWN) & 0x80 || GetKeyState('S') & 0x80)
    	{
    		MoveCamera(-speed);
    	}

    	if(GetKeyState(VK_LEFT) & 0x80 || GetKeyState('A') & 0x80)
    	{
    		StrafeCamera(-speed);
    	}

    	// Check if we hit the Right arrow or the 'd' key
    	if(GetKeyState(VK_RIGHT) & 0x80 || GetKeyState('D') & 0x80) {

    		// Strafe the camera right
    		StrafeCamera(speed);
    	}
    }

    void CCamera::Update()
    {
    	// Initialize a variable for the cross product result
    	CVector3 vCross = Cross(m_vView - m_vPosition, m_vUpVector);

    	// Normalize the strafe vector
    	m_vStrafe = Normalize(vCross);

    	// Move the camera's view by the mouse
    	SetViewByMouse();

    	// This checks to see if the keyboard was pressed
    	CheckForMovement();

    	// Calculate our frame rate and set our frame interval for time based movement
    	CalculateFrameRate();
    }

    void CCamera::Look()
    {

    	gluLookAt(m_vPosition.x, m_vPosition.y, m_vPosition.z,
    			  m_vView.x,	 m_vView.y,     m_vView.z,
    			  m_vUpVector.x, m_vUpVector.y, m_vUpVector.z);
    }

    /////////////////////////////////////////////////////////////////////////////////
    //
    // * QUICK NOTES *
    //
    //
    //
    // Ben Humphrey (DigiBen)
    // Game Programmer
    // DigiBen@GameTutorials.com
    // Co-Web Host of www.GameTutorials.com
    //
    //

Currently browsing [GL_Export1.zip] (104,965 bytes) - [BlankProject/Camera.h] - (2,740 bytes)

    #ifndef _CAMERA_H
    #define _CAMERA_H

    #include <mmsystem.h>

    class CCamera {

    public:
    	int x, y;
    	int Map[10][10];

    	// Our camera constructor
    	CCamera();

    	// These are are data access functions for our camera's private data
    	CVector3 Position()
    	{
    		return m_vPosition;
    	}
    	CVector3 View()		{	return m_vView;			}
    	CVector3 UpVector() {	return m_vUpVector;		}
    	CVector3 Strafe()	{	return m_vStrafe;		}

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    	// This intializes the camera's sphere radius
    	void SetCameraRadius(float radius) {	m_radius = radius;	};

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    	// This changes the position, view, and up vector of the camera.
    	// This is primarily used for initialization
    	void PositionCamera(float positionX, float positionY, float positionZ,
    			 		    float viewX,     float viewY,     float viewZ,
    						float upVectorX, float upVectorY, float upVectorZ);

    	// This rotates the camera's view around the position depending on the values passed in.
    	void RotateView(float angle, float X, float Y, float Z);

    	// This moves the camera's view by the mouse movements (First person view)
    	void SetViewByMouse();

    	// This rotates the camera around a point (I.E. your character).
    	void RotateAroundPoint(CVector3 vCenter, float X, float Y, float Z);

    	// This strafes the camera left or right depending on the speed (+/-)
    	void StrafeCamera(float speed);

    	// This will move the camera forward or backward depending on the speed
    	void MoveCamera(float speed);

    	// This checks for keyboard movement
    	void CheckForMovement();

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    	// This takes a list of vertices and the vertex count to determine if the camera's
    	// shere has collided with them.
    	void CheckCameraCollision(CVector3 *pVertices, int numOfVerts);

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    	// This updates the camera's view and other data (Should be called each frame)
    	void Update();

    	// This uses gluLookAt() to tell OpenGL where to look
    	void Look();

    private:

    	// The camera's position
    	CVector3 m_vPosition;

    	// The camera's view
    	CVector3 m_vView;

    	// The camera's up vector
    	CVector3 m_vUpVector;

    	// The camera's strafe vector
    	CVector3 m_vStrafe;

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    	// The camera's collision radius
    	float m_radius;

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    };

    #endif

Currently browsing [GL_Export1.zip] (104,965 bytes) - [BlankProject/Init.cpp] - (7,758 bytes)

    #include "main.h"

    void CreateTexture(UINT textureArray[], LPSTR strFileName, int textureID)
    {
    	AUX_RGBImageRec *pBitmap = NULL;

    	if(!strFileName)
    		return;

    	pBitmap = auxDIBImageLoad( strFileName );

    	if(pBitmap == NULL)
    		exit(0);

    	glGenTextures(1, &textureArray[textureID]);
    	glBindTexture(GL_TEXTURE_2D, textureArray[textureID]);

    	gluBuild2DMipmaps(GL_TEXTURE_2D, 3,
    		pBitmap->sizeX, pBitmap->sizeY,
    		GL_RGB, GL_UNSIGNED_BYTE, pBitmap->data);
    	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);//GL_NEAREST);
    	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR);//GL_NEAREST);
    	//GL_NEAREST
    	if (pBitmap)										// If we loaded the bitmap
    	{
    		if (pBitmap->data)								// If there is texture data
    		{
    			free(pBitmap->data);						// Free the texture data, we don't need it anymore
    		}

    		free(pBitmap);									// Free the bitmap structure
    	}
    }

    void ChangeToFullScreen()
    {
    	DEVMODE dmSettings;									// Device Mode variable

    	memset(&dmSettings,0,sizeof(dmSettings));			// Makes Sure Memory's Cleared

    	if(!EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dmSettings))
    	{
    		MessageBox(NULL, "Could No t Enum Display Settings", "Error", MB_OK);
    		return;
    	}

    	dmSettings.dmPelsWidth	= SCREEN_WIDTH;				// Selected Screen Width
    	dmSettings.dmPelsHeight	= SCREEN_HEIGHT;			// Selected Screen Height

    	int result = ChangeDisplaySettings(&dmSettings,CDS_FULLSCREEN);

    	if(result != DISP_CHANGE_SUCCESSFUL)
    	{
    		MessageBox(NULL, "Display Mode Not Compatible", "Error", MB_OK);
    		PostQuitMessage(0);
    	}
    }

    HWND CreateMyWindow(LPSTR strWindowName, int width, int height, DWORD dwStyle, bool bFullScreen, HINSTANCE hInstance)
    {
    	HWND hWnd;
    	WNDCLASS wndclass;

    	memset(&wndclass, 0, sizeof(WNDCLASS));				// Init the size of the class
    	wndclass.style = CS_HREDRAW | CS_VREDRAW;			// Regular drawing capabilities
    	wndclass.lpfnWndProc = WinProc;						// Pass our function pointer as the window procedure
    	wndclass.hInstance = hInstance;						// Assign our hInstance
    	wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);	// General icon
    	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);		// An arrow for the cursor
    	wndclass.hbrBackground = (HBRUSH) (COLOR_WINDOW+1);	// A white window
    	wndclass.lpszClassName = "GameTutorials";			// Assign the class name

    	RegisterClass(&wndclass);							// Register the class

    	if(bFullScreen && !dwStyle) 						// Check if we wanted full screen mode
    	{													// Set the window properties for full screen mode
    		dwStyle = WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    		ChangeToFullScreen();							// Go to full screen
    		ShowCursor(FALSE);								// Hide the cursor
    	}
    	else if(!dwStyle)									// Assign styles to the window depending on the choice
    		dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

    	g_hInstance = hInstance;							// Assign our global hInstance to the window's hInstance

    	RECT rWindow;
    	rWindow.left	= 0;								// Set Left Value To 0
    	rWindow.right	= width;							// Set Right Value To Requested Width
    	rWindow.top	    = 0;								// Set Top Value To 0
    	rWindow.bottom	= height;							// Set Bottom Value To Requested Height

    	AdjustWindowRect( &rWindow, dwStyle, false);		// Adjust Window To True Requested Size

    														// Create the window
    	hWnd = CreateWindow("GameTutorials", strWindowName, dwStyle, 0, 0,
    						rWindow.right  - rWindow.left, rWindow.bottom - rWindow.top,
    						NULL, NULL, hInstance, NULL);

    	if(!hWnd) return NULL;								// If we could get a handle, return NULL

    	ShowWindow(hWnd, SW_SHOWNORMAL);					// Show the window
    	UpdateWindow(hWnd);									// Draw the window

    	SetFocus(hWnd);										// Sets Keyboard Focus To The Window

    	return hWnd;
    }

    bool bSetupPixelFormat(HDC hdc)
    {
        PIXELFORMATDESCRIPTOR pfd;
        int pixelformat;

        pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);			// Set the size of the structure
        pfd.nVersion = 1;									// Always set this to 1
    														// Pass in the appropriate OpenGL flags
        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
        pfd.dwLayerMask = PFD_MAIN_PLANE;					// We want the standard mask (this is ignored anyway)
        pfd.iPixelType = PFD_TYPE_RGBA;						// We want RGB and Alpha pixel type
        pfd.cColorBits = SCREEN_DEPTH;						// Here we use our #define for the color bits
        pfd.cDepthBits = SCREEN_DEPTH;						// Depthbits is ignored for RGBA, but we do it anyway
        pfd.cAccumBits = 0;									// No special bitplanes needed
        pfd.cStencilBits = 0;								// We desire no stencil bits

        if ( (pixelformat = ChoosePixelFormat(hdc, &pfd)) == FALSE )
        {
            MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
            return FALSE;
        }

        if (SetPixelFormat(hdc, pixelformat, &pfd) == FALSE)
        {
            MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
            return FALSE;
        }

        return TRUE;										// Return a success!
    }

    void SizeOpenGLScreen(int width, int height)			// Initialize The GL Window
    {
    	if (height==0)										// Prevent A Divide By Zero error
    	{
    		height=1;										// Make the Height Equal One
    	}

    	glClearIndex( 0.0f );
    	glClearDepth( 1.0f );
    	glEnable( GL_DEPTH_TEST );

    	glViewport(0,0,width,height);						// Make our viewport the whole window
    	glMatrixMode(GL_PROJECTION);						// Select The Projection Matrix

    	glLoadIdentity();									// Reset The Projection Matrix

    	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height, 10.0f ,2000.0f);

    	glMatrixMode(GL_MODELVIEW);							// Select The Modelview Matrix
    	glLoadIdentity();									// Reset The Modelview Matrix
    	glEnable( GL_LIGHTING );
    	glEnable( GL_LIGHT0 );

    }

    void InitializeOpenGL(int width, int height)
    {
        g_hDC = GetDC(g_hWnd);								// This sets our global HDC
    														// We don't free this hdc until the end of our program
        if (!bSetupPixelFormat(g_hDC))						// This sets our pixel format/information
            PostQuitMessage (0);							// If there's an error, quit

        g_hRC = wglCreateContext(g_hDC);					// This creates a rendering context from our hdc
        wglMakeCurrent(g_hDC, g_hRC);						// This makes the rendering context we just created the one we want to use

    	glEnable(GL_TEXTURE_2D);
    	glCullFace( GL_FRONT );
    	glEnable( GL_CULL_FACE );
    	GLfloat Amb[] ={ 2,2,2,1 };
    	glLightModelfv( GL_LIGHT_MODEL_AMBIENT, Amb );

    	SizeOpenGLScreen(width, height);					// Setup the screen translations and viewport
    }

    void DeInit()
    {
    	if (g_hRC)
    	{
    		wglMakeCurrent(NULL, NULL);						// This frees our rendering memory and sets everything back to normal
    		wglDeleteContext(g_hRC);						// Delete our OpenGL Rendering Context
    	}

    	if (g_hDC)
    		ReleaseDC(g_hWnd, g_hDC);						// Release our HDC from memory

    	if(g_bFullScreen)									// If we were in full screen
    	{
    		ChangeDisplaySettings(NULL,0);					// If So Switch Back To The Desktop
    		ShowCursor(TRUE);								// Show Mouse Pointer
    	}

    	UnregisterClass("GameTutorials", g_hInstance);		// Free the window class

    	PostQuitMessage (0);								// Post a QUIT message to the window
    }

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hprev, PSTR cmdline, int ishow)
    {
    	HWND hWnd;

    	hWnd = CreateMyWindow("Hotel", SCREEN_WIDTH, SCREEN_HEIGHT, 0, g_bFullScreen, hInstance);

    	// If we never got a valid window handle, quit the program
    	if(hWnd == NULL) return TRUE;

    	// INIT OpenGL
    	Init(hWnd);

    	// Run our message loop and after it's done, return the result
    	return MainLoop();
    }

Currently browsing [GL_Export1.zip] (104,965 bytes) - [BlankProject/3DMath.cpp] - (24,351 bytes)

    //***********************************************************************//
    //																		 //
    //		- "Talk to me like I'm a 3 year old!" Programming Lessons -		 //
    //                                                                       //
    //		$Author:		DigiBen		digiben@gametutorials.com			 //
    //																		 //
    //		$Program:		CameraWorldCollision							 //
    //																		 //
    //		$Description:	Shows how to check if camera and world collide	 //
    //																		 //
    //		$Date:			1/23/02											 //
    //																		 //
    //***********************************************************************//

    #include "main.h"
    #include <math.h>	// We include math.h so we can use the sqrt() function
    #include <float.h>	// This is so we can use _isnan() for acos()

    /////////////////////////////////////// ABSOLUTE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns the absolute value of the number passed in
    /////
    /////////////////////////////////////// ABSOLUTE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    float Absolute(float num)
    {
    	// If num is less than zero, we want to return the absolute value of num.
    	// This is simple, either we times num by -1 or subtract it from 0.
    	if(num < 0)
    		return (0 - num);

    	// Return the original number because it was already positive
    	return num;
    }

    /////////////////////////////////////// CROSS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns a perpendicular vector from 2 given vectors by taking the cross product.
    /////
    /////////////////////////////////////// CROSS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    CVector3 Cross(CVector3 vVector1, CVector3 vVector2)
    {
    	CVector3 vNormal;									// The vector to hold the cross product

    	// The X value for the vector is:  (V1.y * V2.z) - (V1.z * V2.y)													// Get the X value
    	vNormal.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));

    	// The Y value for the vector is:  (V1.z * V2.x) - (V1.x * V2.z)
    	vNormal.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));

    	// The Z value for the vector is:  (V1.x * V2.y) - (V1.y * V2.x)
    	vNormal.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));

    	return vNormal;										// Return the cross product (Direction the polygon is facing - Normal)
    }

    /////////////////////////////////////// MAGNITUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns the magnitude of a normal (or any other vector)
    /////
    /////////////////////////////////////// MAGNITUDE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    float Magnitude(CVector3 vNormal)
    {
    	// This will give us the magnitude or "Norm" as some say, of our normal.
    	// Here is the equation:  magnitude = sqrt(V.x^2 + V.y^2 + V.z^2)  Where V is the vector

    	return (float)sqrt( (vNormal.x * vNormal.x) + (vNormal.y * vNormal.y) + (vNormal.z * vNormal.z) );
    }

    /////////////////////////////////////// NORMALIZE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns a normalize vector (A vector exactly of length 1)
    /////
    /////////////////////////////////////// NORMALIZE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    CVector3 Normalize(CVector3 vNormal)
    {
    	float magnitude = Magnitude(vNormal);				// Get the magnitude of our normal

    	// Now that we have the magnitude, we can divide our normal by that magnitude.
    	// That will make our normal a total length of 1.  This makes it easier to work with too.

    	vNormal.x /= magnitude;								// Divide the X value of our normal by it's magnitude
    	vNormal.y /= magnitude;								// Divide the Y value of our normal by it's magnitude
    	vNormal.z /= magnitude;								// Divide the Z value of our normal by it's magnitude

    	// Finally, return our normalized normal.

    	return vNormal;										// Return the new normal of length 1.
    }

    /////////////////////////////////////// NORMAL \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns the normal of a polygon (The direction the polygon is facing)
    /////
    /////////////////////////////////////// NORMAL \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    CVector3 Normal(CVector3 vPolygon[])
    {														// Get 2 vectors from the polygon (2 sides), Remember the order!
    	CVector3 vVector1 = vPolygon[2] - vPolygon[0];
    	CVector3 vVector2 = vPolygon[1] - vPolygon[0];

    	CVector3 vNormal = Cross(vVector1, vVector2);		// Take the cross product of our 2 vectors to get a perpendicular vector

    	// Now we have a normal, but it's at a strange length, so let's make it length 1.

    	vNormal = Normalize(vNormal);						// Use our function we created to normalize the normal (Makes it a length of one)

    	return vNormal;										// Return our normal at our desired length
    }

    /////////////////////////////////// DISTANCE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns the distance between 2 3D points
    /////
    /////////////////////////////////// DISTANCE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    float Distance(CVector3 vPoint1, CVector3 vPoint2)
    {
    	// This is the classic formula used in beginning algebra to return the
    	// distance between 2 points.  Since it's 3D, we just add the z dimension:
    	//
    	// Distance = sqrt(  (P2.x - P1.x)^2 + (P2.y - P1.y)^2 + (P2.z - P1.z)^2 )
    	//
    	double distance = sqrt( (vPoint2.x - vPoint1.x) * (vPoint2.x - vPoint1.x) +
    						    (vPoint2.y - vPoint1.y) * (vPoint2.y - vPoint1.y) +
    						    (vPoint2.z - vPoint1.z) * (vPoint2.z - vPoint1.z) );

    	// Return the distance between the 2 points
    	return (float)distance;
    }

    ////////////////////////////// CLOSEST POINT ON LINE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns the point on the line vA_vB that is closest to the point vPoint
    /////
    ////////////////////////////// CLOSEST POINT ON LINE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    CVector3 ClosestPointOnLine(CVector3 vA, CVector3 vB, CVector3 vPoint)
    {
    	// Create the vector from end point vA to our point vPoint.
    	CVector3 vVector1 = vPoint - vA;

    	// Create a normalized direction vector from end point vA to end point vB
        CVector3 vVector2 = Normalize(vB - vA);

    	// Use the distance formula to find the distance of the line segment (or magnitude)
        float d = Distance(vA, vB);

    	// Using the dot product, we project the vVector1 onto the vector vVector2.
    	// This essentially gives us the distance from our projected vector from vA.
        float t = Dot(vVector2, vVector1);

    	// If our projected distance from vA, "t", is less than or equal to 0, it must
    	// be closest to the end point vA.  We want to return this end point.
        if (t <= 0)
    		return vA;

    	// If our projected distance from vA, "t", is greater than or equal to the magnitude
    	// or distance of the line segment, it must be closest to the end point vB.  So, return vB.
        if (t >= d)
    		return vB;

    	// Here we create a vector that is of length t and in the direction of vVector2
        CVector3 vVector3 = vVector2 * t;

    	// To find the closest point on the line segment, we just add vVector3 to the original
    	// end point vA.
        CVector3 vClosestPoint = vA + vVector3;

    	// Return the closest point on the line segment
    	return vClosestPoint;
    }

    /////////////////////////////////// PLANE DISTANCE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns the distance between a plane and the origin
    /////
    /////////////////////////////////// PLANE DISTANCE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    float PlaneDistance(CVector3 Normal, CVector3 Point)
    {
    	float distance = 0;									// This variable holds the distance from the plane tot he origin

    	// Use the plane equation to find the distance (Ax + By + Cz + D = 0)  We want to find D.
    	// So, we come up with D = -(Ax + By + Cz)
    														// Basically, the negated dot product of the normal of the plane and the point. (More about the dot product in another tutorial)
    	distance = - ((Normal.x * Point.x) + (Normal.y * Point.y) + (Normal.z * Point.z));

    	return distance;									// Return the distance
    }

    /////////////////////////////////// INTERSECTED PLANE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This checks to see if a line intersects a plane
    /////
    /////////////////////////////////// INTERSECTED PLANE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    bool IntersectedPlane(CVector3 vPoly[], CVector3 vLine[], CVector3 &vNormal, float &originDistance)
    {
    	float distance1=0, distance2=0;						// The distances from the 2 points of the line from the plane

    	vNormal = Normal(vPoly);							// We need to get the normal of our plane to go any further

    	// Let's find the distance our plane is from the origin.  We can find this value
    	// from the normal to the plane (polygon) and any point that lies on that plane (Any vertex)
    	originDistance = PlaneDistance(vNormal, vPoly[0]);

    	// Get the distance from point1 from the plane using: Ax + By + Cz + D = (The distance from the plane)

    	distance1 = ((vNormal.x * vLine[0].x)  +					// Ax +
    		         (vNormal.y * vLine[0].y)  +					// Bx +
    				 (vNormal.z * vLine[0].z)) + originDistance;	// Cz + D

    	// Get the distance from point2 from the plane using Ax + By + Cz + D = (The distance from the plane)

    	distance2 = ((vNormal.x * vLine[1].x)  +					// Ax +
    		         (vNormal.y * vLine[1].y)  +					// Bx +
    				 (vNormal.z * vLine[1].z)) + originDistance;	// Cz + D

    	// Now that we have 2 distances from the plane, if we times them together we either
    	// get a positive or negative number.  If it's a negative number, that means we collided!
    	// This is because the 2 points must be on either side of the plane (IE. -1 * 1 = -1).

    	if(distance1 * distance2 >= 0)			// Check to see if both point's distances are both negative or both positive
    	   return false;						// Return false if each point has the same sign.  -1 and 1 would mean each point is on either side of the plane.  -1 -2 or 3 4 wouldn't...

    	return true;							// The line intersected the plane, Return TRUE
    }

    /////////////////////////////////// DOT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This computers the dot product of 2 vectors
    /////
    /////////////////////////////////// DOT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    float Dot(CVector3 vVector1, CVector3 vVector2)
    {
    	// The dot product is this equation: V1.V2 = (V1.x * V2.x  +  V1.y * V2.y  +  V1.z * V2.z)
    	// In math terms, it looks like this:  V1.V2 = ||V1|| ||V2|| cos(theta)

    			 //    (V1.x * V2.x        +        V1.y * V2.y        +        V1.z * V2.z)
    	return ( (vVector1.x * vVector2.x) + (vVector1.y * vVector2.y) + (vVector1.z * vVector2.z) );
    }

    /////////////////////////////////// ANGLE BETWEEN VECTORS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This checks to see if a point is inside the ranges of a polygon
    /////
    /////////////////////////////////// ANGLE BETWEEN VECTORS \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    double AngleBetweenVectors(CVector3 Vector1, CVector3 Vector2)
    {
    	// Get the dot product of the vectors
    	float dotProduct = Dot(Vector1, Vector2);

    	// Get the product of both of the vectors magnitudes
    	float vectorsMagnitude = Magnitude(Vector1) * Magnitude(Vector2) ;

    	// Get the angle in radians between the 2 vectors
    	double angle = acos( dotProduct / vectorsMagnitude );

    	// Here we make sure that the angle is not a -1.#IND0000000 number, which means indefinate
    	if(_isnan(angle))
    		return 0;

    	// Return the angle in radians
    	return( angle );
    }

    /////////////////////////////////// INTERSECTION POINT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns the intersection point of the line that intersects the plane
    /////
    /////////////////////////////////// INTERSECTION POINT \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    CVector3 IntersectionPoint(CVector3 vNormal, CVector3 vLine[], double distance)
    {
    	CVector3 vPoint, vLineDir;					// Variables to hold the point and the line's direction
    	double Numerator = 0.0, Denominator = 0.0, dist = 0.0;

    	// 1)  First we need to get the vector of our line, Then normalize it so it's a length of 1
    	vLineDir = vLine[1] - vLine[0];		// Get the Vector of the line
    	vLineDir = Normalize(vLineDir);				// Normalize the lines vector

    	// 2) Use the plane equation (distance = Ax + By + Cz + D) to find the
    	// distance from one of our points to the plane.
    	Numerator = - (vNormal.x * vLine[0].x +		// Use the plane equation with the normal and the line
    				   vNormal.y * vLine[0].y +
    				   vNormal.z * vLine[0].z + distance);

    	// 3) If we take the dot product between our line vector and the normal of the polygon,
    	Denominator = Dot(vNormal, vLineDir);		// Get the dot product of the line's vector and the normal of the plane

    	// Since we are using division, we need to make sure we don't get a divide by zero error
    	// If we do get a 0, that means that there are INFINATE points because the the line is
    	// on the plane (the normal is perpendicular to the line - (Normal.Vector = 0)).
    	// In this case, we should just return any point on the line.

    	if( Denominator == 0.0)						// Check so we don't divide by zero
    		return vLine[0];						// Return an arbitrary point on the line

    	dist = Numerator / Denominator;				// Divide to get the multiplying (percentage) factor

    	// Now, like we said above, we times the dist by the vector, then add our arbitrary point.
    	vPoint.x = (float)(vLine[0].x + (vLineDir.x * dist));
    	vPoint.y = (float)(vLine[0].y + (vLineDir.y * dist));
    	vPoint.z = (float)(vLine[0].z + (vLineDir.z * dist));

    	return vPoint;								// Return the intersection point
    }

    /////////////////////////////////// INSIDE POLYGON \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This checks to see if a point is inside the ranges of a polygon
    /////
    /////////////////////////////////// INSIDE POLYGON \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    bool InsidePolygon(CVector3 vIntersection, CVector3 Poly[], long verticeCount)
    {
    	const double MATCH_FACTOR = 0.99;		// Used to cover up the error in floating point
    	double Angle = 0.0;						// Initialize the angle
    	CVector3 vA, vB;						// Create temp vectors

    	for (int i = 0; i < verticeCount; i++)		// Go in a circle to each vertex and get the angle between
    	{
    		vA = Poly[i] - vIntersection;			// Subtract the intersection point from the current vertex
    												// Subtract the point from the next vertex
    		vB = Poly[(i + 1) % verticeCount] - vIntersection;

    		Angle += AngleBetweenVectors(vA, vB);	// Find the angle between the 2 vectors and add them all up as we go along
    	}

    	if(Angle >= (MATCH_FACTOR * (2.0 * PI)) )	// If the angle is greater than 2 PI, (360 degrees)
    		return true;							// The point is inside of the polygon

    	return false;								// If you get here, it obviously wasn't inside the polygon, so Return FALSE
    }

    /////////////////////////////////// INTERSECTED POLYGON \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This checks if a line is intersecting a polygon
    /////
    /////////////////////////////////// INTERSECTED POLYGON \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    bool IntersectedPolygon(CVector3 vPoly[], CVector3 vLine[], int verticeCount)
    {
    	CVector3 vNormal;
    	float originDistance = 0;

    	// First, make sure our line intersects the plane
    									 // Reference   // Reference
    	if(!IntersectedPlane(vPoly, vLine,   vNormal,   originDistance))
    		return false;

    	// Now that we have our normal and distance passed back from IntersectedPlane(),
    	// we can use it to calculate the intersection point.
    	CVector3 vIntersection = IntersectionPoint(vNormal, vLine, originDistance);

    	// Now that we have the intersection point, we need to test if it's inside the polygon.
    	if(InsidePolygon(vIntersection, vPoly, verticeCount))
    		return true;							// We collided!	  Return success

    	return false;								// There was no collision, so return false
    }

    ///////////////////////////////// CLASSIFY SPHERE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This tells if a sphere is BEHIND, in FRONT, or INTERSECTS a plane, also it's distance
    /////
    ///////////////////////////////// CLASSIFY SPHERE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    int ClassifySphere(CVector3 &vCenter,
    				   CVector3 &vNormal, CVector3 &vPoint, float radius, float &distance)
    {
    	// First we need to find the distance our polygon plane is from the origin.
    	float d = (float)PlaneDistance(vNormal, vPoint);

    	// Here we use the famous distance formula to find the distance the center point
    	// of the sphere is from the polygon's plane.
    	distance = (vNormal.x * vCenter.x + vNormal.y * vCenter.y + vNormal.z * vCenter.z + d);

    	// If the absolute value of the distance we just found is less than the radius,
    	// the sphere intersected the plane.
    	if(Absolute(distance) < radius)
    		return INTERSECTS;
    	// Else, if the distance is greater than or equal to the radius, the sphere is
    	// completely in FRONT of the plane.
    	else if(distance >= radius)
    		return FRONT;

    	// If the sphere isn't intersecting or in FRONT of the plane, it must be BEHIND
    	return BEHIND;
    }

    ///////////////////////////////// EDGE SPHERE COLLSIION \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns true if the sphere is intersecting any of the edges of the polygon
    /////
    ///////////////////////////////// EDGE SPHERE COLLSIION \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    bool EdgeSphereCollision(CVector3 &vCenter,
    						 CVector3 vPolygon[], int vertexCount, float radius)
    {
    	CVector3 vPoint;

    	// This function takes in the sphere's center, the polygon's vertices, the vertex count
    	// and the radius of the sphere.  We will return true from this function if the sphere
    	// is intersecting any of the edges of the polygon.

    	// Go through all of the vertices in the polygon
    	for(int i = 0; i < vertexCount; i++)
    	{
    		// This returns the closest point on the current edge to the center of the sphere.
    		vPoint = ClosestPointOnLine(vPolygon[i], vPolygon[(i + 1) % vertexCount], vCenter);

    		// Now, we want to calculate the distance between the closest point and the center
    		float distance = Distance(vPoint, vCenter);

    		// If the distance is less than the radius, there must be a collision so return true
    		if(distance < radius)
    			return true;
    	}

    	// The was no intersection of the sphere and the edges of the polygon
    	return false;
    }

    ////////////////////////////// SPHERE POLYGON COLLISION \\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns true if our sphere collides with the polygon passed in
    /////
    ////////////////////////////// SPHERE POLYGON COLLISION \\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    bool SpherePolygonCollision(CVector3 vPolygon[],
    							CVector3 &vCenter, int vertexCount, float radius)
    {
    	// 1) STEP ONE - Finding the sphere's classification

    	// Let's use our Normal() function to return us the normal to this polygon
    	CVector3 vNormal = Normal(vPolygon);

    	// This will store the distance our sphere is from the plane
    	float distance = 0.0f;

    	// This is where we determine if the sphere is in FRONT, BEHIND, or INTERSECTS the plane
    	int classification = ClassifySphere(vCenter, vNormal, vPolygon[0], radius, distance);

    	// If the sphere intersects the polygon's plane, then we need to check further
    	if(classification == INTERSECTS)
    	{
    		// 2) STEP TWO - Finding the psuedo intersection point on the plane

    		// Now we want to project the sphere's center onto the polygon's plane
    		CVector3 vOffset = vNormal * distance;

    		// Once we have the offset to the plane, we just subtract it from the center
    		// of the sphere.  "vPosition" now a point that lies on the plane of the polygon.
    		CVector3 vPosition = vCenter - vOffset;

    		// 3) STEP THREE - Check if the intersection point is inside the polygons perimeter

    		// If the intersection point is inside the perimeter of the polygon, it returns true.
    		// We pass in the intersection point, the list of vertices and vertex count of the poly.
    		if(InsidePolygon(vPosition, vPolygon, 3))
    			return true;	// We collided!
    		else
    		{
    			// 4) STEP FOUR - Check the sphere intersects any of the polygon's edges

    			// If we get here, we didn't find an intersection point in the perimeter.
    			// We now need to check collision against the edges of the polygon.
    			if(EdgeSphereCollision(vCenter, vPolygon, vertexCount, radius))
    			{
    				return true;	// We collided!
    			}
    		}
    	}

    	// If we get here, there is obviously no collision
    	return false;
    }

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    ///////////////////////////////// GET COLLISION OFFSET \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
    /////
    /////	This returns the offset to move the center of the sphere off the collided polygon
    /////
    ///////////////////////////////// GET COLLISION OFFSET \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

    CVector3 GetCollisionOffset(CVector3 &vNormal, float radius, float distance)
    {
    	CVector3 vOffset = CVector3(0, 0, 0);

    	// Once we find if a collision has taken place, we need make sure the sphere
    	// doesn't move into the wall.  In our app, the position will actually move into
    	// the wall, but we check our collision detection before we render the scene, which
    	// eliminates the bounce back effect it would cause.  The question is, how do we
    	// know which direction to move the sphere back?  In our collision detection, we
    	// account for collisions on both sides of the polygon.  Usually, you just need
    	// to worry about the side with the normal vector and positive distance.  If
    	// you don't want to back face cull and have 2 sided planes, I check for both sides.
    	//
    	// Let me explain the math that is going on here.  First, we have the normal to
    	// the plane, the radius of the sphere, as well as the distance the center of the
    	// sphere is from the plane.  In the case of the sphere colliding in the front of
    	// the polygon, we can just subtract the distance from the radius, then multiply
    	// that new distance by the normal of the plane.  This projects that leftover
    	// distance along the normal vector.  For instance, say we have these values:
    	//
    	//	vNormal = (1, 0, 0)		radius = 5		distance = 3
    	//
    	// If we subtract the distance from the radius we get: (5 - 3 = 2)
    	// The number 2 tells us that our sphere is over the plane by a distance of 2.
    	// So basically, we need to move the sphere back 2 units.  How do we know which
    	// direction though?  This part is easy, we have a normal vector that tells us the
    	// direction of the plane.
    	// If we multiply the normal by the left over distance we get:  (2, 0, 0)
    	// This new offset vectors tells us which direction and how much to move back.
    	// We then subtract this offset from the sphere's position, giving is the new
    	// position that is lying right on top of the plane.  Ba da bing!
    	// If we are colliding from behind the polygon (not usual), we do the opposite
    	// signs as seen below:

    	// If our distance is greater than zero, we are in front of the polygon
    	if(distance > 0)
    	{
    		// Find the distance that our sphere is overlapping the plane, then
    		// find the direction vector to move our sphere.
    		float distanceOver = radius - distance;
    		vOffset = vNormal * distanceOver;
    	}
    	else // Else colliding from behind the polygon
    	{
    		// Find the distance that our sphere is overlapping the plane, then
    		// find the direction vector to move our sphere.
    		float distanceOver = radius + distance;
    		vOffset = vNormal * -distanceOver;
    	}

    	// There is one problem with check for collisions behind the polygon, and that
    	// is if you are moving really fast and your center goes past the front of the
    	// polygon, it will then assume you were colliding from behind and not let
    	// you back in.  Most likely you will take out the if / else check, but I
    	// figured I would show both ways in case someone didn't want to back face cull.

    	// Return the offset we need to move back to not be intersecting the polygon.
    	return vOffset;
    }

Currently browsing [GL_Export1.zip] (104,965 bytes) - [BlankProject/MAIN.H] - (3,151 bytes)

    #ifndef _MAIN_H
    #define _MAIN_H

    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <gl\gl.h>										// Header File For The OpenGL32 Library
    #include <gl\glu.h>										// Header File For The GLu32 Library
    #include <gl\glaux.h>

    #include <float.h>
    #include <math.h>
    #include "3DMath.h"
    #include "Camera.h"

    #define SCREEN_WIDTH  640								// We want our screen width 800 pixels
    #define SCREEN_HEIGHT 480							// We want our screen height 600 pixels
    #define SCREEN_DEPTH 8							// We want 16 bits per pixel

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    #define MAX_TEXTURES 1									// This says how many texture we will be using

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    extern bool  g_bFullScreen;									// Set full screen as default
    extern HWND  g_hWnd;										// This is the handle for the window
    extern RECT  g_rRect;										// This holds the window dimensions
    extern HDC   g_hDC;											// General HDC - (handle to device context)
    extern HGLRC g_hRC;											// General OpenGL_DC - Our Rendering Context for OpenGL
    extern HINSTANCE g_hInstance;

    struct Point3
    {
    	float x;
    	float y;
    	float z;
    };

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    extern UINT g_Texture[MAX_TEXTURES];					// This is our texture data array

    /////// * /////////// * /////////// * NEW * /////// * /////////// * /////////// *

    // This is our MAIN() for windows
    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hprev, PSTR cmdline, int ishow);

    // The window proc which handles all of window's messages.
    LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

    // This controls our main program loop
    WPARAM MainLoop();

    // This loads a texture into openGL from a file (IE, "bitmap.bmp")
    void CreateTexture(UINT textureArray[], LPSTR strFileName, int textureID);

    // This changes the screen to full screen mode
    void ChangeToFullScreen();

    // This is our own function that makes creating a window modular and easy
    HWND CreateMyWindow(LPSTR strWindowName, int width, int height, DWORD dwStyle, bool bFullScreen, HINSTANCE hInstance);

    // This allows us to configure our window for OpenGL and backbuffered
    bool bSetupPixelFormat(HDC hdc);

    // This inits our screen translations and projections
    void SizeOpenGLScreen(int width, int height);

    // This sets up OpenGL
    void InitializeOpenGL(int width, int height);

    // This initializes the whole program
    void Init(HWND hWnd);

    // This draws everything to the screen
    void RenderScene();

    // This frees all our memory in our program
    void DeInit();

    #endif

    /////////////////////////////////////////////////////////////////////////////////
    //
    // * QUICK NOTES *
    //
    // We added MAX_TEXTURES to this header file.  This define is the size of the g_Texture[]
    // array, which we also extern here so init.cpp can free it's data.
    //
    //
    // Ben Humphrey (DigiBen)
    // Game Programmer
    // DigiBen@GameTutorials.com
    // Co-Web Host of www.GameTutorials.com
    //
    //

Currently browsing [GL_Export1.zip] (104,965 bytes) - [BlankProject/resource.h] - (456 bytes)

    //{{NO_DEPENDENCIES}}
    // Microsoft Developer Studio generated include file.
    // Used by Script1.rc
    //
    #define IDB_BITMAP1                     101

    // Next default values for new objects
    //
    #ifdef APSTUDIO_INVOKED
    #ifndef APSTUDIO_READONLY_SYMBOLS
    #define _APS_NEXT_RESOURCE_VALUE        102
    #define _APS_NEXT_COMMAND_VALUE         40001
    #define _APS_NEXT_CONTROL_VALUE         1000
    #define _APS_NEXT_SYMED_VALUE           101
    #endif
    #endif

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.