您的位置:首页 > 其它

一个使用Directx渲染的Havok程序

2012-07-14 15:45 337 查看
作者: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<d3d9.h>

#include<d3dx9.h>

#define WINDOW_CLASS "UGPDX"

#define WINDOW_NAME "Blank D3D Window"



//包涵Havok相关的头文件

// 数学库和基本库

#include <Common/Base/hkBase.h>

#include <Common/Base/System/hkBaseSystem.h>

#include <Common/Base/System/Error/hkDefaultError.h>

#include <Common/Base/Memory/System/Util/hkMemoryInitUtil.h>

#include <Common/Base/Monitor/hkMonitorStream.h>

#include <Common/Base/Memory/System/hkMemorySystem.h>

#include <Common/Base/Memory/Allocator/Malloc/hkMallocAllocator.h>



// 动力学库

#include <Physics/Collide/hkpCollide.h>

#include <Physics/Collide/Agent/ConvexAgent/SphereBox/hkpSphereBoxAgent.h>

#include <Physics/Collide/Shape/Convex/Box/hkpBoxShape.h>

#include <Physics/Collide/Shape/Convex/Sphere/hkpSphereShape.h>

#include <Physics/Collide/Dispatch/hkpAgentRegisterUtil.h>

#include <Physics/Collide/Query/CastUtil/hkpWorldRayCastInput.h>

#include <Physics/Collide/Query/CastUtil/hkpWorldRayCastOutput.h>

#include <Physics/Dynamics/World/hkpWorld.h>

#include <Physics/Dynamics/Entity/hkpRigidBody.h>

#include <Physics/Utilities/Dynamics/Inertia/hkpInertiaTensorComputer.h>

#include <Common/Base/Thread/Job/ThreadPool/Cpu/hkCpuJobThreadPool.h>

#include <Common/Base/Thread/Job/ThreadPool/Spu/hkSpuJobThreadPool.h>

#include <Common/Base/Thread/JobQueue/hkJobQueue.h>

// Keycode

#include <Common/Base/keycode.cxx>

#define HK_FEATURE_REFLECTION_PHYSICS

#define HK_CLASSES_FILE <Common/Serialize/Classlist/hkClasses.h>

#define HK_EXCLUDE_FEATURE_MemoryTracker

#define HK_EXCLUDE_FEATURE_SerializeDeprecatedPre700

#define HK_EXCLUDE_FEATURE_RegisterVersionPatches

#define HK_EXCLUDE_LIBRARY_hkGeometryUtilities

#include <Common/Base/Config/hkProductFeatures.cxx>

#include <stdio.h>

// 函数原型

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();

}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐