📄 tunnel.cpp
字号:
/**************************************************************************
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 + -