一个使用Directx渲染的Havok程序

作者:CYM

摸索了半天终于完成了这个简单的Havok程序,她使用directX渲染.转载请说明出处,尊他人重劳动成果.

和DirectX一样,在使用Havok物理引擎库之前要先要配置好环境,我用的是Visual Studio2010.

第一步:首先要修改工程配置的 公共语言运行时库 ,默认情况下VS的这个选项是 公共语言运行时库支持(旧语法),在这里我们要把它改为

 无公共语言支持.如图

:

第二部:也是修改公共语言支持的选项,只是改的位置不同,这回要在C++常规属性上修改,如下图



第三部:接下来就是设置包涵文件和库文件路径了:在这里设置程序需要的包涵文件和库文件,如下图

第四部:s设置Havok的预处理器选项:选择工程属性->C++->预处理器->预处理器定义

将以下内容加进去

WIN32

NDEBUG

_WINDOWS

_WIN32

_DEBUG

HK_DEBUG

_CONSOLE

HK_CONFIG_SIMD=2

如图


第五步:
z在工程属性->连接器->输入 中的 附加依赖选项 加入以下内容:

d3d9.lib

d3dx9.lib

hkBase.lib

hkCompat.lib

hkSceneData.lib

hkSerialize.lib

hkInternal.lib

hkGeometryUtilities.lib

hkVisualize.lib

hkcdInternal.lib

hkcdCollide.lib

hkpCollide.lib

hkpConstraintSolver.lib

hkpDynamics.lib

hkpInternal.lib

hkpUtilities.lib

hkpVehicle.lib

如图;



这样配好后程序就可以保证运行了:但是还会出现一个 库文件冲突的提示,很多时候这对程序并无大碍,但是也有几个别时候会使程序崩溃,要解决这个问题只要在 工程属性->连接器->输入 中的 忽略特定默认库选项中添加 libcmtd.lib 就可以了


-------------------------以下是代码部分,已经做了详细的注解,想了解更多关于Havok可以查看我以前写的教程----------------------------------

点击以下链接地址(源码)

http://hi.baidu.com/ae8506/blog/item/ed2147ca70ceaf04bf09e6f4.html

 

作者:CYM

关于Havok环境配置部分教程可以点击以下链接地址

http://hi.baidu.com/ae8506/blog/item/7529e9633bb3b8c6e6113aea.html?timeStamp=1315916689964

一个模拟炮弹轨迹打出去的小球,以下是代码

---------------------------------------------------华丽分割线------------------------------------------------

//包涵directX相关的头文件

#include

#include

#define WINDOW_CLASS "UGPDX"

#define WINDOW_NAME  "Blank D3D Window"

 

//包涵Havok相关的头文件

// 数学库和基本库

#include

#include

#include

#include

#include

#include

#include

 

// 动力学库

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

// Keycode

#include

#define HK_FEATURE_REFLECTION_PHYSICS

#define HK_CLASSES_FILE

#define HK_EXCLUDE_FEATURE_MemoryTracker

#define HK_EXCLUDE_FEATURE_SerializeDeprecatedPre700

#define HK_EXCLUDE_FEATURE_RegisterVersionPatches 

#define HK_EXCLUDE_LIBRARY_hkGeometryUtilities

#include

#include

// 函数原型

bool InitializeD3D(HWND hWnd, bool fullscreen);

void RenderScene();

void Shutdown();

 

//关于Havok的函数原型

bool InitializeHavok(void);

void UpdateHavok(void);

void ShutdownHavok(void);

 

//错误信息打印函数

static void HK_CALL errorReport(const char* msg, void* userArgGivenToInit)

{

printf("%s", msg);

}

 

// D3D对象和D3D设备对象

LPDIRECT3D9 g_D3D = NULL;

LPDIRECT3DDEVICE9 g_D3DDevice = NULL;

 

//D3D全局灯光和材质

D3DLIGHT9g_d3dLight;

D3DMATERIAL9g_d3dMaterial;

 

//D3D网格对象

ID3DXMesh*g_d3dBall=NULL;//球体网格

ID3DXMesh*g_d3dGround=NULL;//陆地网格

//D3D图形变化矩阵

D3DXMATRIXg_d3dMatBall;//球体网格的变化矩阵

D3DXMATRIXg_d3dMatGround;//陆地网格的变化矩阵

 

//Havok相关的定义

hkMemoryRouter* g_hkMemoryRouter;//内存路由器

hkJobThreadPool* g_hkThreadPool=NULL;//线程池

hkJobQueue* g_hkJobQueue=NULL;//工作队列

hkpRigidBody* g_hkBall=NULL;//物理球体

hkpRigidBody* g_hkGround=NULL;//物理陆地

hkpWorld* g_hkPhysicsWorld=NULL;//物理世界

hkStopwatch g_hkStopWatch;

 

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

   switch(msg)

      {

         case WM_DESTROY:

            PostQuitMessage(0);

            return 0;

            break;

 

         case WM_KEYUP:

            if(wParam == VK_ESCAPE) PostQuitMessage(0);

            break;

      }

 

   return DefWindowProc(hWnd, msg, wParam, lParam);

}

 

 

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE prevhInst, LPSTR cmdLine, int show)

{

   // 注册应用程序窗口类

   WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,

                     GetModuleHandle(NULL), NULL, NULL, NULL, NULL,

                     WINDOW_CLASS, NULL };

   RegisterClassEx(&wc);

 

   // 创建应用程序

   HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,

                            100, 100, 640, 480, GetDesktopWindow(), NULL,

                            wc.hInstance, NULL);

 

   //初始化D3D

   if(InitializeD3D(hWnd, false)&&InitializeHavok())

      {

         // 显示窗口

         ShowWindow(hWnd, SW_SHOWDEFAULT);

         UpdateWindow(hWnd);

 

         // 进入消息循环

         MSG msg;

         ZeroMemory(&msg, sizeof(msg));

 

         while(msg.message != WM_QUIT)

            {

               if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))

                  {

                     TranslateMessage(&msg);

                     DispatchMessage(&msg);

                  }

               else

 UpdateHavok();

                  RenderScene();

            }

      }

 

   // 释放所有资源

   ShutdownHavok();

   Shutdown();

 

   // 注销应程序窗口

   UnregisterClass(WINDOW_CLASS, wc.hInstance);

   return 0;

}

 

 

bool InitializeD3D(HWND hWnd, bool fullscreen)

{

   D3DDISPLAYMODE displayMode;

 

   // 创建D3D对象

   g_D3D = Direct3DCreate9(D3D_SDK_VERSION);

   if(g_D3D == NULL) return false;

 

   // 获取桌面显示模式

   if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))

      return false;

 

   // 填充用于创建D3D设备对象的结构体

   D3DPRESENT_PARAMETERS d3dpp;

   ZeroMemory(&d3dpp, sizeof(d3dpp));

 

   if(fullscreen)

      {

         d3dpp.Windowed = FALSE;

         d3dpp.BackBufferWidth = 640;

         d3dpp.BackBufferHeight = 480;

      }

   else

      d3dpp.Windowed = TRUE;

   d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

   d3dpp.BackBufferFormat = displayMode.Format;

 

   // 创建D3D设备对象

   if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,

             D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_D3DDevice)))

      {

         return false;

      }

 

   //初始化D3D灯光和材质

::ZeroMemory(&g_d3dLight, sizeof(D3DLIGHT9));

g_d3dLight.Type      = D3DLIGHT_DIRECTIONAL;

g_d3dLight.Ambient   = D3DXCOLOR(0.8f, 0.8f, 0.8f, 1.0f);

g_d3dLight.Diffuse   = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);

g_d3dLight.Specular  = D3DXCOLOR(0.2f, 0.2f, 0.2f, 1.0f);

g_d3dLight.Direction = D3DXVECTOR3(1.0f, -1.0f, 0.0f);

g_D3DDevice->SetLight(0, &g_d3dLight);//设置灯光

g_D3DDevice->LightEnable(0, true);//激活灯光

 

//初始化全局材质

::ZeroMemory(&g_d3dMaterial,sizeof(D3DMATERIAL9));

g_d3dMaterial.Diffuse.r = 0.4f;

g_d3dMaterial.Diffuse.g =0.4f;

g_d3dMaterial.Diffuse.b = 0.4f;

g_d3dMaterial.Ambient.r = 0.6f;

g_d3dMaterial.Ambient.g = 0.6f;

g_d3dMaterial.Ambient.b = 0.7f;

g_d3dMaterial.Specular.r = 0.4f;

g_d3dMaterial.Specular.g = 0.4f;

g_d3dMaterial.Specular.b = 0.4f;

g_d3dMaterial.Power = 8.0f;

g_D3DDevice->SetMaterial(&g_d3dMaterial);

   

//设置摄像机和投影矩阵

D3DXMATRIX matView; 

D3DXVECTOR3 pEye(45.0f, 25.0f, 60.0f); 

D3DXVECTOR3 pAt(0.0f, 0.0f, 0.0f); 

D3DXVECTOR3 pUp(0.0f, 1.0f, 0.0f);

D3DXMatrixLookAtLH(&matView, &pEye,&pAt,&pUp);

g_D3DDevice->SetTransform(D3DTS_VIEW, &matView); 

 

//设置投影矩阵

D3DXMATRIX matProjection; 

D3DXMatrixPerspectiveFovLH(&matProjection, 

D3DXToRadian(75),

(FLOAT)640 / (FLOAT)480,

1.0f,

180.0f);

g_D3DDevice->SetTransform(D3DTS_PROJECTION, &matProjection); 

 

//创建d3d网格图形

// 创建陆地

D3DXCreateBox(g_D3DDevice,40.0f,2.0f,80.0f, &g_d3dGround,0); 

// 创建球体 

D3DXCreateSphere(g_D3DDevice, 1.5f, 20, 20, &g_d3dBall, 0); 

 

//设置渲染状态

g_D3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);

g_D3DDevice->SetRenderState(D3DRS_AMBIENT,D3DCOLOR_COLORVALUE(0.3f, 0.3f, 0.3f, 1.0f));

 

   return true;

}

 

 

//初始化Havok物理引擎

bool InitializeHavok(void)

{

//

// 初始化基本的系统和我们的内存系统

//

// 分配0.5MB的物理解决缓存

g_hkMemoryRouter = hkMemoryInitUtil::initDefault( hkMallocAllocator::m_defaultMallocAllocator, hkMemorySystem::FrameInfo( 500* 1024 ) );

hkBaseSystem::init(g_hkMemoryRouter,errorReport );

 

{

//

// 初始化多线程类, hkJobQueue, 和 hkJobThreadPool

//

int totalNumThreadsUsed;

 

hkHardwareInfo hwInfo;

hkGetHardwareInfo(hwInfo);

totalNumThreadsUsed = hwInfo.m_numThreads;

 

// We use one less than this for our thread pool, because we must also use this thread for our simulation

hkCpuJobThreadPoolCinfo threadPoolCinfo;

threadPoolCinfo.m_numThreads = totalNumThreadsUsed - 1;

 

//创建线程池

threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;

g_hkThreadPool = new hkCpuJobThreadPool( threadPoolCinfo );

 

//创建工作队列

hkJobQueueCinfo info;

info.m_jobQueueHwSetup.m_numCpuThreads = totalNumThreadsUsed;

g_hkJobQueue= new hkJobQueue(info);

 

//为这个线程池激活

hkMonitorStream::getInstance().resize(200000);

 

 

 

//创建Havok物理世界

{

//用于创建物理世界的信息

hkpWorldCinfo worldInfo;

//设置多线程来模拟我们的物理世界

worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;

// 将掉落在物理世界规定大小以外的实体移除

worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_REMOVE_ENTITY;

//创建物理世界

g_hkPhysicsWorld = new hkpWorld(worldInfo);

//设置去活化

g_hkPhysicsWorld->m_wantDeactivation = false;

 

//向我们已尽创建好的物理世界中写入数据

g_hkPhysicsWorld->markForWrite();

//注册碰撞代理

hkpAgentRegisterUtil::registerAllAgents( g_hkPhysicsWorld->getCollisionDispatcher() );

//注册工作队列

g_hkPhysicsWorld->registerWithJobQueue(g_hkJobQueue );

 

//-----------------------

//创建物理世界中的刚体

//-----------------------

//创建陆地

hkVector4 vec4Ground( 20.0f, 2.0f, 40.0f );

hkpConvexShape* shape = new hkpBoxShape(vec4Ground, 0 );

//填充陆地物理信息

hkpRigidBodyCinfo ci;

ci.m_shape = shape; 

ci.m_motionType = hkpMotion::MOTION_FIXED; 

ci.m_position = hkVector4( 0.0f, -2.0f, 0.0f ); 

ci.m_qualityType = HK_COLLIDABLE_QUALITY_FIXED;

//创建刚体,并添加到物理世界

g_hkGround=new hkpRigidBody(ci);

g_hkPhysicsWorld->addEntity(g_hkGround);

g_hkGround->removeReference();//移除引用

shape->removeReference();//移除引用

 

//创建球体

const hkReal radius = 1.5f;//球的直径

const hkReal sphereMass = 30.0f;//球的重量

hkVector4 relPos( 0.0f,radius + 0.0f, 0.0f );

//填充球体的刚体信息

hkpRigidBodyCinfo info; 

hkpMassProperties massProperties; 

hkpInertiaTensorComputer::computeSphereVolumeMassProperties(radius, sphereMass, massProperties);

info.m_mass = massProperties.m_mass; 

info.m_centerOfMass = massProperties.m_centerOfMass; 

info.m_inertiaTensor = massProperties.m_inertiaTensor; 

info.m_shape = new hkpSphereShape(radius); 

info.m_position.setAdd4(hkVector4(0.0f,0.0f,0.0f,20.0f),relPos ); 

info.m_motionType = hkpMotion::MOTION_BOX_INERTIA;

info.m_qualityType = HK_COLLIDABLE_QUALITY_BULLET;

//创建刚体

g_hkBall=new hkpRigidBody(info);

//添加到物理世界

g_hkPhysicsWorld->addEntity(g_hkBall); 

g_hkBall->removeReference();//移除引用

info.m_shape->removeReference();//移除引用

//设置球的方向和速度

hkVector4 vel( 0.0f,19.6f, 8.0f ); 

g_hkBall->setLinearVelocity(vel); 

 

//结束向物理世界写入数据

g_hkPhysicsWorld->unmarkForWrite();

}

}

return true;

}

 

//更新物理世界

void UpdateHavok(void)

{

//使用多线程进行一次模拟

g_hkPhysicsWorld->stepMultithreaded(g_hkJobQueue, g_hkThreadPool,1.0f/30.0f);

hkMonitorStream::getInstance().reset();

g_hkThreadPool->clearTimerData();

}

 

//释放资源

void ShutdownHavok(void)

{

//移除物理世界

g_hkPhysicsWorld->markForWrite();

g_hkPhysicsWorld->removeReference();

 

//清除工作队列和线程池

delete g_hkJobQueue;

g_hkThreadPool->removeReference();

 

//退出Havok内存系统

hkBaseSystem::quit();

    hkMemoryInitUtil::quit();

}

 

void RenderScene()

{

   // 清空后台缓存.

   g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);

 

   // 开始渲染

   g_D3DDevice->BeginScene();

 

//绘制陆地

D3DXMatrixTranslation(&g_d3dMatGround, 0.0f, -2.0f, 0.0f); 

// 设置世界矩阵 

g_D3DDevice->SetTransform(D3DTS_WORLD, &g_d3dMatGround); 

g_d3dGround->DrawSubset(0);

 

//绘制球体

hkVector4 pos = g_hkBall->getPosition(); 

D3DXMatrixTranslation(&g_d3dMatBall, pos(0), pos(1), pos(2)); 

//D3DXMatrixTranslation(&g_d3dMatBall, 0.0f, 5.0f,0.0f); 

g_D3DDevice->SetTransform(D3DTS_WORLD, &g_d3dMatBall); 

g_d3dBall->DrawSubset(0);

 

   // 结束渲染

   g_D3DDevice->EndScene();

 

   // 输出图像

   g_D3DDevice->Present(NULL, NULL, NULL, NULL);

}

 

 

void Shutdown()

{

if(g_d3dBall!=NULL) g_d3dBall->Release();

if(g_d3dGround!=NULL) g_d3dGround->Release();

   if(g_D3DDevice != NULL) g_D3DDevice->Release();

   if(g_D3D != NULL) g_D3D->Release();

}




 

 

你可能感兴趣的:(物理引擎,引擎开发,其它文章,游戏开发,游戏引擎,Direct3D)