⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cpp

📁 Bezier Curve
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//***********************************************************************//
//																		 //
//		- "Talk to me like I'm a 3 year old!" Programming Lessons -		 //
//                                                                       //
//		$Author:		DigiBen		digiben@gametutorials.com			 //
//																		 //
//		$Program:		Bezier Curve									 //
//																		 //
//		$Description:	Moves a sphere along a bezier curve				 //
//																		 //
//		$Date:			10/8/01											 //
//																		 //
//***********************************************************************//

// This is a compiler directive that includes libraries (For Visual Studio)
// You can manually include the libraries in the "Project->settings" menu under
// the "Link" tab.
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")

#include "main.h"										// This includes our header file


bool  g_bFullScreen = true;								// 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()


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

// This tutorial shows you how to create a bezier curve.  This is a VERY handy
// bit of knowledge to have, especially as we see how popular curved surfaces
// in games are becoming (starting with Quake).  Some examples of when we would
// use a curve is for Tunnels, camera movements, etc... To demonstrate using a bezier
// curve, we will create a sphere that we can use the RIGHT and LEFT arrow keys
// to move a across a rendered curve.  Creating a bezier curve is simple, but
// the math at first can be intimidating.  Basically, a bezier curve has at least
// 3 points.  The first point is the starting point of the curve.  The second point
// is the control point of the curve.  A control point "controls" the arc of the curve.
// The third point is the end point of the curve.  In this tutorial we will use 4 control
// points (including the start and end point).  The first and last point will be where
// the curve starts and stops, and the middle 2 points will be used to shape the curve.
// 

#define BALL_SPEED	0.02f								// This is how fast our camera moves
#define MAX_STEPS   25.0f								// This is the amount of steps we want to draw the curve

// We create a class that has an X, Y and Z.  We will use this point class
// to store our XYZ points of the curve.

struct CVector3 										// Remember, we use a C in front to show it's a class
{
public:
	float x, y, z;										// We just want a float for a X Y and Z.
};

float g_CurrentTime = 0.0f;								// This is the current position of the sphere along the curve (0 to 1)

CVector3 g_vStartPoint    = {-4,  0,  0};				// This is the starting point of the curve
CVector3 g_vControlPoint1 = {-2,  3,  2};				// This is the first control point of the curve
CVector3 g_vControlPoint2 = { 2, -3, -2};				// This is the second control point of the curve
CVector3 g_vEndPoint	  = { 4,  0,  0};				// This is the end point of the curve

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


///////////////////////////////// INIT GAME WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function initializes the game window.
/////
///////////////////////////////// INIT GAME WINDOW \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

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
	
//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////

	// Just to give the sphere more realism, we enable the default
	// lights for shading.  First we turn on a light, turn lighting on,
	// then enable coloring.  We need to enable color functions like glColor3f()
	// since lighting is on.  If we don't all objects will be white.

	glEnable(GL_LIGHT0);								// Turn on this light
	glEnable(GL_LIGHTING);								// Turn lighting on
	glEnable(GL_COLOR_MATERIAL);						// Since lighting is on, allow glColor*() functions

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

}

///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function Handles the main game loop
/////
///////////////////////////////// MAIN GAME LOOP \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

WPARAM MainLoop()
{
	MSG msg;
	bool bRedraw = false;

	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
		{ 		
			RenderScene();								// Update the screen every frame
        } 
	}

	DeInit();											// Clean up and free all allocated memory

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


///////////////////////////////// POINT ON CURVE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function returns an XYZ point along the curve, depending on t (0 to 1)
/////
///////////////////////////////// POINT ON CURVE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

CVector3 PointOnCurve(CVector3 p1, CVector3 p2, CVector3 p3, CVector3 p4, float t)
{
	float var1, var2, var3;
    CVector3 vPoint = {0.0f, 0.0f, 0.0f};

	// Here is the juice of our tutorial.  Below is the equation for a 4 control point
	// bezier curve:
	// B(t) = P1 * ( 1 - t )^3 + P2 * 3 * t * ( 1 - t )^2 + P3 * 3 * t^2 * ( 1 - t ) + P4 * t^3 
	// Yes I agree, this isn't the most intuitive equation, but it is pretty straight forward.
	// If you got up to Trig, you will notice that this is a polynomial.  That is what a curve is.
	// "t" is the time from 0 to 1.  You could also think of it as the distance along the
	// curve, because that is really what it is.  P1 - P4 are the 4 control points.
	// They each have an (x, y, z) associated with them.  You notice that there is a lot of
	// (1 - t) 's?  Well, to clean up our code we will try to contain some of these
	// repetitions into variables.  This helps our repeated computations as well.

	// Store the (1 - t) in a variable because it is used frequently
    var1 = 1 - t;
	
	// Store the (1 - t)^3 into a variable to cut down computation and create clean code
    var2 = var1 * var1 * var1;

	// Store the t^3 in a variable to cut down computation and create clean code
    var3 = t * t * t;

	// Now that we have some computation cut down, we just follow the equation above.
	// If you multiply and simplify the equation, you come up with what we have below.
	// If you don't see how we came to here from the equation, multiply the equation
	// out and it will become more clear.  I don't intend to go into any more detail
	// on the math of a bezier curve, because there are far better places out there
	// with graphical displays and tons of examples.  Look in our * Quick Notes *
	// for an EXCELLENT web site that does just this.  It derives everything and has
	// excellent visuals.  It's the best I have seen so far.
    vPoint.x = var2*p1.x + 3*t*var1*var1*p2.x + 3*t*t*var1*p3.x + var3*p4.x;
    vPoint.y = var2*p1.y + 3*t*var1*var1*p2.y + 3*t*t*var1*p3.y + var3*p4.y;
    vPoint.z = var2*p1.z + 3*t*var1*var1*p2.z + 3*t*t*var1*p3.z + var3*p4.z;

	// Now we should have the point on the curve, so let's return it.
    return(vPoint);				
}


///////////////////////////////// DRAW SPHERE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function renders a sphere to a given XYZ and with a given radius
/////
///////////////////////////////// DRAW SPHERE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void DrawSphere(float x, float y, float z, float radius)
{
	// To use Quadrics, we need to create a new one first.  This is done below.
	// The GLUquadricObj type is defined with the GLU32 library and associated header file.

	GLUquadricObj *pSphere = gluNewQuadric();			// Get a Quadric off the stack

	// Let's put on a matrix so what ever we do it doesn't effect the rest of
	// the objects we will display.

	glPushMatrix();										// Push on a new matrix

		glTranslatef(x, y, z);							// Move the sphere to the desired (x, y, z)

		// Draw the a sphere with a given radius and a width and height detail 
		// of 15 (15 by 15 is a good level of detail.  The lower the detail the 
		// more jagged the sphere becomes, where the high the detail the more round it is.
		gluSphere(pSphere, radius, 15, 15);				// Draw the sphere with a radius of 0.2

	glPopMatrix();										// Pop the current matrix

	// Since we are done rendering the Quadric, we can free the object.
	// gluDeleteQuadric() takes the object to be released. If you have a lot 
	// of Quadrics, you might not want to allocate and free them every frame.

	gluDeleteQuadric(pSphere);							// Free the quadric object
}


///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*
/////
/////	This function renders the entire scene.
/////
///////////////////////////////// RENDER SCENE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*

void RenderScene() 
{

//////////// *** NEW *** ////////// *** NEW *** ///////////// *** NEW *** ////////////////////
	
	static float rotateY = 0.0f;						// Create a static variable for rotation

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
	glLoadIdentity();									// Reset The matrix

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -