Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8700211
  • 博文数量: 1413
  • 博客积分: 11128
  • 博客等级: 上将
  • 技术积分: 14685
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-13 10:03
个人简介

follow my heart...

文章分类

全部博文(1413)

文章存档

2013年(1)

2012年(5)

2011年(45)

2010年(176)

2009年(148)

2008年(190)

2007年(293)

2006年(555)

分类:

2006-11-26 19:16:37

一个非常完美而且简单的3d图像引擎.在win32环境下,可以用visual c++ 及dev cpp进行编译.强烈推荐,试用之后,发现他的简易程度和tv3d不相上下,下面是一个该引擎的源程序示例,分享一下.
 //3D引擎示例
//在winxpsp2+devcpp4.9中通过
//引擎可在海上软件园中下载到
//This simple example implements a keyboard controlled ball.
//Arrow keys apply forces to the ball.
//[Ctrl] key reverses gravity force direction.

//After compilation, this source code is turned into a file named 3impactd.dll and
//saved to the 3impactWork folder on your hard disk.
//When 3impactd.exe file (the engine) is launched, it will load this .dll file and
//will execute the five functions below, also known as 'callbacks'.
//They are: PreInit(), Init(), Run(), Exit(), PostExit().

//You can fully control the engine by calling creation functions, setting functions
//and transformation functions inside the callbacks. It is that easy! See below.

//Include some external code giving access to commonly used Windows methods
#i nclude
#i nclude
#i nclude
//Include also some engine specific functions and definitions.
#i nclude "..\common\3impactDLL_defs.h"

//In the Init() callback you'll see that we create virtual world objects by calling
//creation functions.
//Newly created objects should always be stored to proper 'containers', named
//'object variables', to allow for subsequent handling.
//Object variables are typically declared at the beginning of the code. Typically, one
//single line of code declares one single variable. A declaration is made of two parts.
//The first part declares the type of the variable (for example 'CAMERA*') and the
//second part declares its custom (user defined) name (for example 'Camera').
//For simplicity, an object variable is usually called 'object' (e.g., 'camera object').
//The following are the object variables we need for this example.
CAMERA* Camera;//摄像机
SPRITE* LoadingMessage;//加载信息
SKYBOX* SkyBox;//天空

BODY* Terrain;//地形
MESH* TerrainMesh;//地形模型

BODY* Ball;//球
MESH* BallMesh;//球模型
MESH* BallMeshShadow;//球阴影

BODYBODY* BallTerrain;//球与地形之间

void PreInit(DWORD* settings)//预初始化,产生在显示对话框之前
{
   //This callback is executed once, at startup, before opening the Display Options panel.
   //Note that 3Impact functions are not available here yet. You cannot call, for
   //example, iCameraCreate(). This callback is intended for special initializations.
   //We don't need any special initialization now, so we are leaving this callback empty.
}
void Init()//初始化
{
   //This callback is executed once, right after opening the rendering window or the
   //rendering fullscreen display.
   //This callback is typically used to create objects, to set their initial status,
   //physics properties, rendering mode, etc.

   //We always need to create a camera (point of view). Without a camera, nothing can
   //be rendered to the screen. The following line calls the iCameraCreate() function
   //and stores the camera object which it creates to the object variable named Camera.
   Camera=iCameraCreate(0,0,100,100);//创建摄像机
   //Now that the newly created camera is in the 'Camera' variable, we can handle it.
   //For example, we can set its location, inside the virtual space. The next line of code
   //calls the iCameraLocationSet() function, passing the Camera as first parameter and
   //a constant 3d vector as second parameter (the location).
   iCameraLocationSet(Camera,&D3DXVECTOR3(0.0f,3.0f,-10.0f));//设置摄像机位置

   //We also want to specify sun light direction and color.
 //设置光线方向与色彩
   iLightDirectionalSet(&D3DXVECTOR3(1.0f,-1.0f,1.0f),&D3DXVECTOR4(1.0f,1.0f,1.0f,0.35f));

   //Creating objects can be a lengthy operation. We want to display something while
   //loading is in progress. So we create a 2d object (also known as 'sprite') to
   //display a 'Loading...' message.
   //Note that object creation will typically require a resource file, as source.
   //For example, for sprites, we need an image file and a .x file.
   //Custom resources can be created. Refer to the quick start tutorial for details.
   //The next line of code will create a sprite from the loading.x resource, and will
   //store it to the variable named 'LoadingMessage'.
   //创建加载精灵
   LoadingMessage=iSpriteCreate("default_res\\sprites\\loading.x",NULL);
   //We want the message displayed now, before we start creating (loading) all other objects.
   //渲染精灵,以便显示
   iSpriteRender(LoadingMessage,NULL);

   //We now create a 3d background for the virtual space.
   //为虚拟空间创建一个3d背景
   SkyBox=iSkyBoxCreate("default_res\\skyboxes\\skybox01.sky");

   //The first 3d 'solid' object we create is a piece of terrain. Solid objects
   //are called 'bodies'. A body is considered 'solid' because it is collision-response
   //capable. In this case, the body is a polygonal object (polyhedron).
   //创建地形实体 ,但是实体是无法显示的 ,注意地形实体是基于多面体的 ,所以扩展名是ply
   Terrain=iBodyCreate("default_res\\terrain_5.00.ply");
   //Bodies are invisible. They are processed by the engine as invisible-solid objects.
   //It means that they cannot be rendered (displayed) by the engine. However, we can
   //attach a visible mesh to them, to show where they are and what their shape is.
   //Mesh objects are non-solid 3d models. Unlike bodies, they are rendered by the engine.
   //With the next line of code, we create a 3d visible object from a .x
   //resource file. As parameters, we pass the file name for the resource to load and
   //the body object we want attach the mesh to (Terrain).
   //创建地形模型,依附于地形实体
   TerrainMesh=iBodyMeshCreate("default_res\\terrain.x",Terrain);

   //The second body we create is a ball. Unlike the terrain, which is made of polygons,
   //this object is sphere-group based. It is as simple as a ball, so it is a one-ball
   //group. See quick start tutorial for details on polyhedron and sphere-group based bodies.
   //基于球体创建,注意扩展名是spg(sphere-group)
   Ball=iBodySGCreate("default_res\\ball_.spg",0.13f);
   //As a body, the newly created ball is invisible. Let's attach a ball-shaped mesh to it.
   //依附于球体创建球模型
   BallMesh=iBodyMeshCreate("default_res\\ball.x",Ball);
   //We want the ball at about 5 meters above the ground, at startup.
   //设置球体位置处于离地面5m
   iBodyLocationSet(Ball,&D3DXVECTOR3(0.0f,5.0f,0.0f),TRUE);
   //By default, there is no air friction for bodies. We can simulate it by setting
   //some damping for the ball.
   //See reference.txt for details on iBodyDampingSet() instruction and damping.
   //设置实体阻碍
   iBodyDampingSet(Ball,0.0f,0.999f,0.0f,0.995f);

   //We want our ball to cast a shadow onto other objects in the scenery.
   //The next line of code creates a shadow volume mesh from a source .x file
   //and attaches it to the Ball body. See reference.txt for details on
   //iMeshBodyShadowCasterCreate() instruction and shadows.
   //创建球的阴影
   BallMeshShadow=iMeshBodyShadowCasterCreate("default_res\\ball_shadow.x",Ball,500.0f);

   //By default, no collision checking is performed for the bodies we have created.
   //We have to tell the engine what body couples should be checked for collision.
   //The next line of code creates a so called body-body object.
   //Basically, the body-body object is a data block specifying a body couple and
   //a few parameters required by the engine to compute collision-response.
   //创建球与地面一对物体
   BallTerrain=iBodyBodyCreate(Ball,Terrain);
   //We have stored the body-body object for the ball-terrain couple, so that we can
   //set collision-response parameters for it. See reference.txt for details on them.
   //物体之间摩擦力设置
   iBodyBodyFrictionSet(BallTerrain,10.0f);

   //Newly created bodies are disabled (no physics, no collision-response computation).
   //The next two lines of code enable Ball and Terrain bodies.
   //使地形可用
   iBodyEnable(Terrain);
   //使球体可用
   iBodyEnable(Ball);

   //We don't want to show the loading message any longer, now that object creation is complete.
   //到此为止,加载工作完成,隐藏loading信息
   iSpriteHide(LoadingMessage);
   //Newly created meshes are hide. Let's show all of them.
   //显示天空,地形模型,球模型及球阴影模型
   iSkyBoxShow(SkyBox);
   iMeshShow(TerrainMesh);
   iMeshShow(BallMesh);
   iMeshShow(BallMeshShadow);
}
//运行的循环过程
void Run()
{
   //This callback is executed 75 times per second. The first execution happens
   //after the Init() callback above is completed.

   //It means that the engine will repeatedly scan the lines of code from the '{'
   //right below the 'void Run()' line to the '}' right above the 'void Exit()' line.

   //Each scan from '{' to '}' is called 'dll loop'. It is basically the heartbeat
   //of the simulation.

   //The rendering phase, in which the virtual world is displayed in its current status,
   //as seen from the current camera location, happens after each dll loop is complete.

   //The dll loops continue until the [Esc] key is pressed or the iExit() function
   //is called. Terminating the dll loops basically stops the simulation.

   //So, we have a piece of terrain and a ball. We want the camera to constantly
   //take the ball, wherever it goes. First of all, let's define a vector variable
   //to save the current ball position, that is the target to point the camera to.
   //定义一个矢量变量保存球的位置,同样这位位置也是摄像机的点
   D3DXVECTOR3 cameratarget;
   //We put the current ball location into the vector by calling iBodyLocationCM().
   //
   iBodyLocationCM(Ball,&cameratarget);
   //Finally, we call a special function that will point the camera to the target.
   //指定摄像机到目标上面
   iCameraLookAt(Camera,&cameratarget,0.1f);

   //We finally want the ball to be controlled by key presses. The idea is applying
   //forces to it according to what arrow keys are pressed by the user.
   //First of all, let's define proper variables to store some temporary information
   //we need to achieve our goal.
   //加速点
   D3DXVECTOR3 acceleration;
   //四元组- 摄像机方向
   D3DXQUATERNION cameraorientation;

   //Linear accelerations (*) are defined by 3d vectors. We have provided a variable
   //named 'acceleration' to store the acceleration generated by key presses.
   //This vector variable will work as an accumulator. The first step is resetting it.
   //给加速点赋值
   acceleration=D3DXVECTOR3(0.0f,0.0f,0.0f);
   //Depending on what keys are pressed, we will add a constant vector to the
   //acceleration variable. The length of the vector defines the intensity of
   //the acceleration. The direction of the vector defines the direction of it.
   //For example, if up-arrow is pressed, we add a 10 meter long vector
   //to the accumulator. Its direction is towards Z-positive world axis.
   //It basically means that the ball will be pushed with an acceleration of 10
   //meters per second^2 in that direction, when up-arrow is pressed (**).
   //通过箭头键来控制加速方式
   if (iKeyDown(DIK_LEFT)) acceleration += D3DXVECTOR3(-10.0f,0.0f,0.0f);
   if (iKeyDown(DIK_RIGHT)) acceleration += D3DXVECTOR3(10.0f,0.0f,0.0f);
   if (iKeyDown(DIK_UP)) acceleration += D3DXVECTOR3(0.0f,0.0f,10.0f);
   if (iKeyDown(DIK_DOWN)) acceleration += D3DXVECTOR3(0.0f,0.0f,-10.0f);

   //(**) The code above basically tends to push the ball along world's X and Z
   //axes only, no matter where the camera is taking the scene from. It makes a bit
   //difficult for the user to effectively direct the ball.
   //We want to re-orientate the resulting acceleration vectors so that they
   //are camera relative. For example, we want an acceleration towards X+ axis to be
   //re-orientated so that it becomes an acceleration towards the right of the screen.
   //To achieve this, we first store the camera orientation to a quaternion variable.
   //Note: most physics engine quantities (locations, forces, torques, etc) can be stored
   //to vector variables. To store orientations and rotations we use special variables
   //called 'quaternions'.
   //设置摄像机方向
   iCameraOrientation(Camera,&cameraorientation);
   //The next function takes a vector (acceleration) and rotates it by using a
   //quaternion as a reference. Basically, 'cameraorientation' quaternion is
   //the rotation required to change the camera from its natural status (that
   //is, looking at Z+ horizon) to its current orientation. We can
   //say that it is the current camera orientation, but it is a rotation actually.
   //So, we basically apply that orientation to the given vector. The result
   //is that the vector is transformed from world coordinates (absolute) to
   //camera coordinates (relative). And it is exactly what we need here.
   //矢量旋转
   iVectorRotate(&acceleration,&acceleration,&cameraorientation);

   //Controls are easier now that applied acceleration has been made camera-relative.
   //Still we aren't done yet. Controlling the ball when the camera is pitched (for
   //example facing downward) isn't very easy. For some reason, it would be easier
   //if acceleration vector direction was always parallel to the XZ (ground) plane.
   //To constrain the vector to the XZ plane we just have to force its Y
   //coordinate to zero. Note that this may reduce vector length (intensity) on
   //extreme camera pitching, but it is ok for this simple example.
   acceleration.y = 0.0f;//设置y轴,也就是高度为0
   //在坐标系中,X是水平移动,Y是高度,Z是纵深

   //Now that the acceleration vector is set (or still reset to null if no
   //key was pressed), we can finally apply it to the Ball body.
   //(*) We are applying an acceleration and not a force. Applying a force
   //means transferring to a body a defined quantity of energy. So, the resulting
   //speed depends on the body mass: a force applied to an heavy body will generate
   //a lower speed respect to the same force applied to a lighter body.
   //Applying an acceleration, instead, means transferring to a body the energy required
   //to obtain, over time, a defined velocity or spin, regardless of the body mass.
  //应用加速-球
  iBodyAccelerationApply(Ball,&acceleration);

   //Finally, we apply a constant acceleration to simulate gravity.
   //We also implement an additional control, with the next lines of code.
   //We want to reverse the gravity force (but we should actually name it
   //'gravity acceleration'...) while the [Ctrl] key is pressed.
   //当按下ctrl键时,球在Y轴上升,相反如果没有按的话,球下降.
   if (!iKeyDown(DIK_LCONTROL)) iBodyAccelerationApply(Ball,&D3DXVECTOR3(0.0f,-9.80665f,0.0f));
  
   else iBodyAccelerationApply(Ball,&D3DXVECTOR3(0.0f,9.80665f,0.0f));
}
//退出
void Exit()
{
   //This callback is executed after the Run() callback is stopped by pressing [Esc],
   //before the rendering window is closed.
   //You typically free any memory resource you have allocated elsewhere, here.
}
//发送退出
void PostExit(HWND hWnd)
{
   //This callback is executed after the Exit() callback, after closing the
   //rendering window, before closing the application.
   //It is intended for special purposes like, for example, running an external
   //application, an Internet browser, etc.
}


阅读(2123) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~