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

📄 tunnel.cpp

📁 国外游戏开发者杂志1997年第九期配套代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************

Mixed Rendering

 **************************************************************************/
/***************************************************************
*
*       This program has been developed by Intel Corporation.  
*		You have Intel's permission to incorporate this code 
*       into your product, royalty free.  Intel has various 
*	    intellectual property rights which it may assert under
*       certain circumstances, such as if another manufacturer's
*       processor mis-identifies itself as being "GenuineIntel"
*		when the CPUID instruction is executed.
*
*       Intel specifically disclaims all warranties, express or
*       implied, and all liability, including consequential and
*		other indirect damages, for the use of this code, 
*		including liability for infringement of any proprietary
*		rights, and including the warranties of merchantability
*		and fitness for a particular purpose.  Intel does not 
*		assume any responsibility for any errors which may 
*		appear in this code nor any responsibility to update it.
*
*  * Other brands and names are the property of their respective
*    owners.
*
*  Copyright (c) 1995, Intel Corporation.  All rights reserved.
***************************************************************/
/*==========================================================================
 *
 *  Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
 *
 *  File: tunnel.c
 *
 ***************************************************************************/

#include <math.h>
#include <malloc.h>

#define D3D_OVERLOADS

#include <d3d.h>
#include "d3ddemo.h"
#include "main.h" 
#include "ddutil.h"

/*
 * Globals to keep track of execute buffer
 */
static D3DEXECUTEDATA d3dExData;
static LPDIRECT3DEXECUTEBUFFER lpD3DExBuf;
static D3DEXECUTEBUFFERDESC debDesc;

 
//  This define tells us if for each frame the Spot will be transformed  
//   to camera coordinates and then to screen coordinates,
//   or will be setup once (!!!) at creation time to screen coordinated.
// #define SCREEN_COORDINATES

#define SW_SPOT

#ifdef SW_SPOT
    // execute buffer for the 
	static D3DEXECUTEDATA			    d3dExDataSpot;
    static LPDIRECT3DEXECUTEBUFFER	   lpD3DExBufSpot;
	
	// we have four vertices and two triangles for the spot
	// in th HW scene
    #define NUM_VERTICES_SPOT  4
	#define NUM_TRIANGLES_SPOT 2
    D3DTLVERTEX  src_v[NUM_VERTICES_SPOT];
	D3DTRIANGLE  src_tri[NUM_TRIANGLES_SPOT];
    
	// for each frame calcs new location for the spot
	void moveSWPolygon();
    // init the vertices
	void initSwSpot(); 
    
    // onCruve is the currnet location of the SPot in camera space 
	D3DVECTOR onCurve , viewVec , upVec ; 
	
	// create execute buffer for the spot and fill it
	BOOL
    InitViewSW(LPDIRECTDRAW lpDD, LPDIRECT3D lpD3D, 
			   LPDIRECT3DDEVICE lpDev,LPDIRECT3DVIEWPORT lpView, 
			   int NumTextures, LPD3DTEXTUREHANDLE TextureHandle);
#include "d3dmain.h"

#endif

/*
 * More globals
 */
LPDIRECT3DMATERIAL lpbmat;
LPDIRECT3DMATERIAL lpmat;   /* Material object */

/*
 * Global projection and view matrices
 */
D3DMATRIXHANDLE hProj;

D3DMATRIX proj, view;

static D3DMATRIX
IdentityMatrix()
{
    D3DMATRIX ret;
    for (int i = 0; i < 4; i += 1)
        for (int j = 0; j < 4; j += 1)
            ret(i, j) = (i==j) ? 1.0f : 0.0f;
    return ret;
}

static D3DMATRIX
ProjectionMatrix()
{
    D3DMATRIX ret = IdentityMatrix();
    ret(0, 0) = 2.0f;
    ret(1, 1) = 2.0f;
    ret(3, 3) = 0.0f;
    ret(3, 2) = -1.0f;
    ret(2, 3) = 1.0f;
    return ret;
}

D3DMATRIXHANDLE hView;

D3DMATRIX
ViewMatrix()
{
    D3DMATRIX ret = IdentityMatrix();
    ret(3, 2) = 10.0f;
    return ret;
}

D3DMATRIXHANDLE hWorld;

#define PI 3.14159265359f

/*
 * These defines describe the section of the tube in the execute buffer at
 * one time. (Note, tube and tunnel are used interchangeably).
 */
#define SEGMENTS 20   /* Number of segments in memory at one time.  Each
                       * segment is made up oftriangles spanning between
                       * two rings.
                       */ 
#define SIDES 8       /* Number of sides on each ring. */
#define TEX_RINGS 5   /* Number of rings to stretch the texture over. */
#define NUM_V (SIDES*(SEGMENTS+1)) // Number of vertices in memory at once
#define NUM_TRI (SIDES*SEGMENTS*2) // Number of triangles in memory
#define TUBE_R 1.0f      /* Radius of the tube. */
#define SPLINE_POINTS 50 /* Number of spline points to initially
                          * calculate.  The section in memory represents
                          * only a fraction of this.
                          */
/*
 * Movement and track scalars given in terms of position along the spline
 * curve.
 */
#define SEGMENT_LENGTH 0.05 /* Length of each segment along curve. */
#define SPEED 0.01   /*0.02    /* Amount to increment camera position along
                             * curve for each frame.
                             */
#define DEPTH 0.8           /* How close the camera can get to the end of
                             * track before new segments are added.
                             */
#define PATH_LENGTH (SPLINE_POINTS - 1) /*Total length of the tunnel.*/

/*
 * A global structure holding the tube data.
 */
static struct _tube {
    LPD3DVERTEX lpV;                /* Points to the vertices. */
    LPD3DTRIANGLE lpTri;          /* Points to the triangles which make up the segments.                 */
    int TriOffset;                            /* Offset into the execute buffer were the     triangle list is found. */
    LPD3DVECTOR lpPoints;        /* Points to the points defining the spline curve. */
	D3DMATERIALHANDLE hMat; /* Handle for the material on the tube. */
    D3DTEXTUREHANDLE hTex;  /* Handle for the texture on the material.*/
    D3DLIGHT light;                      /* Structure defining the light. */
    LPDIRECT3DLIGHT lpD3DLight;  /* Object pointer for the light. */
    D3DVECTOR cameraP, cameraD, cameraN; /* Vectors defining the camera position, direction and up. */
    float cameraPos;										      /* Camera position along the spline curve. */
    D3DVECTOR endP, endD, endN;    /* Vectors defining the position, direction and up 
						                                     * at the foremost end of  the section in memory. */
    float endPos;								   /* Position along the spline curve of the end. */
    int currentRing, currentSegment;   /* Numbers of the ring and tube at  the back end of the section. */
                                      
} tube;

extern LPD3DMATRIX D3DMATRIXInvert(LPD3DMATRIX d, LPD3DMATRIX a);
extern LPD3DMATRIX D3DMATRIXSetRotation(LPD3DMATRIX lpM, LPD3DVECTOR lpD,
                                        LPD3DVECTOR lpU);

/*
 * Calculates a point along a B-Spline curve defined by four points. p
 * n output, contain the point. t     Position
 * along the curve between p2 and p3.  This position is a float between 0
 * and 1. p1, p2, p3, p4    Points defining spline curve. p, at parameter
 * t along the spline curve
 */
D3DVECTOR 
spline(double t, const LPD3DVECTOR p[4])
{
    double t2 = t * t;
    double t3 = t2 * t;
    D3DVECTOR ret(0.0f);
    float m[4];

    m[0] = (float) (0.5f*((-1.0 * t3) + (2.0 * t2) + (-1.0 * t)));
    m[1] = (float) (0.5f*((3.0 * t3) + (-5.0 * t2) + (0.0 * t) + 2.0));
    m[2] = (float) (0.5f*((-3.0 * t3) + (4.0 * t2) + (1.0 * t)));
    m[3] = (float) (0.5f*((1.0 * t3) + (-1.0 * t2) + (0.0 * t)));

    for (int i = 0; i < 4; i += 1) {
        ret += *p[i]*m[i];
    }
    return ret;
}

/*
 * Creates a matrix which is equivalent to having the camera at a
 * specified position. This matrix can be used to convert vertices to
 * camera coordinates. lpP    Position of the camera. lpD    Direction of
 * view. lpN    Up vector. lpM    Matrix to update.
 */
void 
PositionCamera(LPD3DVECTOR lpP, LPD3DVECTOR lpD, LPD3DVECTOR lpN, 
               LPD3DMATRIX lpM)
{
    D3DMATRIX tmp;

    /*
     * Set the rotation part of the matrix and invert it. Vertices must be
     * inverse rotated to achieve the same result of a corresponding 
     * camera rotation.
     */
    tmp._14 = tmp._24 = tmp._34 = tmp._41 = tmp._42 = tmp._43 = (float)0.0;
    tmp._44 = (float)1.0;
    D3DMATRIXSetRotation(&tmp, lpD, lpN);
    D3DMATRIXInvert(lpM, &tmp);
    /*
     * Multiply the rotation matrix by a translation transform.  The
     * translation matrix must be applied first (left of rotation).
     */
    lpM->_41=-(lpM->_11 * lpP->x + lpM->_21 * lpP->y + lpM->_31 * lpP->z);
    lpM->_42=-(lpM->_12 * lpP->x + lpM->_22 * lpP->y + lpM->_32 * lpP->z);
    lpM->_43=-(lpM->_13 * lpP->x + lpM->_23 * lpP->y + lpM->_33 * lpP->z);
}

/*
 * Updates the given position, direction and normal vectors to a given
 * position on the spline curve.  The given up vector is used to determine
 * the new up vector.
 */

void 
MoveToPosition(float position, LPD3DVECTOR lpP, LPD3DVECTOR lpD, 
               LPD3DVECTOR lpN)
{
    LPD3DVECTOR lpSplinePoint[4];
    D3DVECTOR pp, x;
    int i, j;
    float t;

    /*
     * Find the four points along the curve which are around the position.
     */
    i = 0;
    t = position;
    while (t > 1.0) {
        i++;
        if (i == SPLINE_POINTS)
            i = 0;
        t -= 1.0f;
    }
    for (j = 0; j < 4; j++) {
        lpSplinePoint[j] = &tube.lpPoints[i];
        i++;
        if (i == SPLINE_POINTS)
            i = 0;
    }
    /*
     * Get the point at the given position and one just before it.
     */
    *lpP = spline(t, lpSplinePoint);
    pp = spline(t - (float)0.01, lpSplinePoint);
    /*
     * Calculate the direction.
     */
    *lpD = Normalize(*lpP - pp);
    /*
     * Find the new normal.  This method will work provided the change in
     * the normal is not very large.
     */
    *lpN = Normalize(*lpN);
    x = CrossProduct(*lpN, *lpD);
    *lpN = Normalize(CrossProduct(*lpD, x));
}


/*
 * Evaluate the Spline at the given position, 
 */

void 
SplineAtPosition(float position, LPD3DVECTOR lpP)
{
    LPD3DVECTOR lpSplinePoint[4];
    int i, j;
    float t;

    /*
     * Find the four points along the curve which are around the position.
     */
    i = 0;
    t = position;
    while (t > 1.0) {
        i++;
        if (i == SPLINE_POINTS)
            i = 0;
        t -= 1.0f;
    }
    for (j = 0; j < 4; j++) {
        lpSplinePoint[j] = &tube.lpPoints[i];
        i++;
        if (i == SPLINE_POINTS)
            i = 0;
    }
    /*
     * Get the point at the given position 
     */
    *lpP = spline(t, lpSplinePoint);
}

/*
 * Generates a ring of vertices in a plane defined by n and the cross
 * product of n and p.  On exit, joint contains the vertices.  Join must
 * be pre-allocated. Normals are generated pointing in.  Texture
 * coordinates are generated along tu axis and are given along tv.
 */
static void 
MakeRing(const D3DVECTOR& p, 
         const D3DVECTOR& d, 
         const D3DVECTOR& n, float tv,
         LPD3DVERTEX joint)
{
    D3DVECTOR nxd = CrossProduct(n, d);
    for (int spoke = 0; spoke < SIDES; spoke++) {
        float theta = (float)(2.0 * PI) * spoke / SIDES;
        /*
         * v, u defines a unit vector in the plane
         * defined by vectors nxd and n.
         */
        float v = (float)sin(theta);
        float u = (float)cos(theta);
        /*
         * x, y, z define a unit vector in standard coordiante space
         */
        D3DVECTOR pt = u*nxd + v*n;
        /*
         * Position, normals and texture coordiantes.
         */

⌨️ 快捷键说明

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