第一个TV与HK同时执行无干扰

本文深入探讨了游戏开发领域的核心技术,包括游戏引擎、图形渲染、音视频处理等关键环节,为开发者提供全面的技术指导。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

西昌.何雨锋

#include "stdafx.h"
#include <windows.h>
#include <windowsx.h>

#include ".\TV.h"
#include ".\havok.h"

CTVEngine *engine1; 
CTVInputEngine *input1;         //输入引擎
CTVScene *scene1;               //场景
CTVGlobals *global1;            //全球变量
CTVAtmosphere *atmos1; 
CTVLandscape *land1; 
CTVTextureFactory *fac1;
CTVMesh *sphere1;
CTVCameraFactory *camfac1;
CTVCamera *cam1;
hkReal lastTime,nextTime;
double xrot=0;                 //
double yrot=0;
double zrot=0;
double xpos=0;                 //主角位置
double ypos=0;
double zpos=0;
double lookx=0;                //主角视点
double looky=0;
double lookz=0;
double xangle=0;
double yangle=0;
double arcc=0;
double timeleft;
float me_walk = 0.0;            //前后移动变量
float me_strafe = 0.0;          //左右移动变量
float me_updown=0.0;

void init_TV(HWND Handle);
void render();
void input();
void unload();

hkpWorld* physicsWorld=NULL;
hkJobQueue* jobQueue=NULL;
hkJobThreadPool* threadPool=NULL;
hkpPhysicsContext* context=NULL;
hkArray<hkProcessContext*> contexts;

hkVisualDebugger* vdb;

void setupPhysics();
void Init_Havok();
void Run_Havok();
void createBrickWall(int height, int length, const hkVector4& position, hkReal gapWidth, hkpConvexShape* box, hkVector4Parameter halfExtents );
hkpRigidBody* g_ball;

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);


void init(HWND Handle)
{
	init_TV(Handle);	
}

//Entry point.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//Firstly lets create a window.
    HWND hWnd;
    WNDCLASSEX wc;
    ZeroMemory(&wc, sizeof(WNDCLASSEX));

    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = (WNDPROC)WindowProc;
    wc.hInstance     = hInstance;
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
    wc.lpszClassName = (LPCWSTR) "WindowClass1";

    RegisterClassEx(&wc);

    int Cx = GetSystemMetrics(SM_CXSCREEN);
    int Cy = GetSystemMetrics(SM_CYSCREEN);

    hWnd = CreateWindowEx(NULL,(LPCWSTR) "WindowClass1",(LPCWSTR) "Blank Screen", WS_CAPTION, (Cx / 2) - (800 / 2), (Cy / 2) - (600 / 2), 800, 600, NULL, NULL, hInstance, NULL);    
    ShowWindow(hWnd, nCmdShow);

	init(hWnd);
    MSG msg;

    Init_Havok();       
    unload();
	/*	while(TRUE)
		{
		  if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		  {			
			if(msg.message == WM_QUIT) break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		   }
	     }*/
    

	return msg.wParam;
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch(message)
    {
        case WM_DESTROY:
            {
                PostQuitMessage(0);
                return 0;
            } break;
    }
    return DefWindowProc (hWnd, message, wParam, lParam);
}

void render()
{
    engine1->Clear(false);	 
	
	atmos1->Atmosphere_Render();
    land1->Render();
	scene1->RenderAllMeshes();
	

	//scene1->RenderAllActors();
	//scene1->RenderAllMeshes();			    	
	engine1->RenderToScreen ();
}

void input()
{
	if(input1->IsKeyPressed(cTV_KEY_ESCAPE))		//Check if ESCAPE has been pressed.
	{	
		PostQuitMessage(0);
	}    		

	if(input1->IsKeyPressed(cTV_KEY_UP))
	    me_walk=0.2;
	if(input1->IsKeyPressed(cTV_KEY_DOWN))
	    me_walk=-0.2;
    if(input1->IsKeyPressed(cTV_KEY_LEFT))
	    me_strafe =0.2;
	if(input1->IsKeyPressed(cTV_KEY_RIGHT))
	    me_strafe = -0.2;

	if(input1->IsKeyPressed(cTV_KEY_W))
        me_walk = 1;

    if(input1->IsKeyPressed(cTV_KEY_S))
        me_walk = -1;

    if(input1->IsKeyPressed(cTV_KEY_A))
        me_strafe =1;

    if(input1->IsKeyPressed(cTV_KEY_D))
        me_strafe = -1;
    if(input1->IsKeyPressed(cTV_KEY_C))
        me_updown=-1;
	if(input1->IsKeyPressed(cTV_KEY_SPACE))
        me_updown=1;

	 long mousex=0; long mousey=0;
     int mouse_b1=0; int mouse_b2=0; int mouse_b3=0;   
     long mouse_old=0; long mouse_new=0;
     mouse_old = mouse_new;

  
     input1->GetMouseState((int *) &mousex,(int *) &mousey,(bool *)&mouse_b1,(bool *)&mouse_b2,(bool *)&mouse_b3,(bool *) &mouse_old); 

     xangle = xangle - ((float)mousey / 100.0f);
     yangle = yangle - ((float)mousex / 100.0f);
     if(xangle > 1.3f) xangle = 1.3f;
     if(xangle < -1.3f) xangle = -1.3f;

	if(me_walk > 0)
	{
        me_walk = me_walk - 0.05f;
        if(me_walk < 0) me_walk = 0;
	}
    if(me_walk < 0)
	{
        me_walk = me_walk + 0.05f;
        if(me_walk > 0) me_walk = 0;
	}

    if(me_strafe > 0)
	{
        me_strafe = me_strafe - 0.05f;
        if(me_strafe < 0) me_strafe = 0;
	}
    if(me_strafe < 0)
	{
        me_strafe = me_strafe + 0.05f;
        if(me_strafe > 0) me_strafe = 0;
	}
	timeleft=engine1->TimeElapsed();
    //不知道hl中是否也这样写的呢?上下移动是否与鼠标无关?
    xpos = xpos + (cosf(yangle) * me_walk * timeleft) + (cosf(yangle + 3.141596f / 2.0f) * me_strafe * timeleft);
    zpos = zpos + (sinf(yangle) * me_walk * timeleft) + (sinf(yangle + 3.141596f / 2.0f) * me_strafe * timeleft);
	ypos=ypos+me_updown;
	me_updown=0;
	lookx = xpos + cosf(yangle);
    looky = ypos + tanf(xangle);
    lookz = zpos + sinf(yangle);  

	cam1->SetCamera(xpos,ypos,zpos,lookx,looky,lookz);	

}

void unload()
{
    engine1->ReleaseAll();
    delete(engine1);

}

void init_TV(HWND Handle)
{
    engine1 = new CTVEngine;	
	engine1->SetDebugFile("debug.txt");      //We want TV to dump a debug file, this is very useful, Sylvain is good at catching common mistakes and informing you that you've made them in this files log.
	engine1->Init3DWindowed(Handle, true);   //We want to initialize on our windows handle and we have hardware transform and lighting.
	//engine1->Init3DFullscreen(800, 600, 32, true, false, cTV_DEPTHBUFFER_BESTBUFFER, 1, Handle);
    global1=new CTVGlobals;

	  input1=new CTVInputEngine;
	input1->Initialize(true, true);

	
    scene1=new CTVScene;               //场景
    global1=new CTVGlobals;            //全球变量
    atmos1=new CTVAtmosphere; 
    land1=new CTVLandscape; 
    fac1=new CTVTextureFactory;
    sphere1=new CTVMesh;
	camfac1=new CTVCameraFactory;
	cam1=new CTVCamera;
    
    fac1->LoadTexture("map\\skybox\\up.jpg","up",-1,-1,cTV_COLORKEY_NO);
	fac1->LoadTexture("map\\skybox\\dn.jpg","down",-1,-1,cTV_COLORKEY_NO);
	fac1->LoadTexture("map\\skybox\\lf.jpg","left",-1,-1,cTV_COLORKEY_NO);
	fac1->LoadTexture("map\\skybox\\rt.jpg","right",-1,-1,cTV_COLORKEY_NO);
	fac1->LoadTexture("map\\skybox\\ft.jpg","front",-1,-1,cTV_COLORKEY_NO);
	fac1->LoadTexture("map\\skybox\\bk.jpg","back",-1,-1,cTV_COLORKEY_NO);	  

	atmos1->SkyBox_SetTexture(global1->GetTex("front"),global1->GetTex("back"),global1->GetTex("left"),global1->GetTex("right"),global1->GetTex("up"),global1->GetTex("down"));
    atmos1->SkyBox_Enable(true);
	    
	fac1->LoadTexture("map\\heightmap\\texture2.jpg","map_tex",-1,-1,cTV_COLORKEY_NO);    
	land1=scene1->CreateLandscape("land1");
	land1->LoadTerrainData("map\\heightmap\\3.map");
	//land1->GenerateTerrain("map\\heightmap\\height1.jpg",cTV_PRECISION_LOW,32,32,1000,1000,true);
	//land1->SetScale(2,16,2);
    land1->ExpandTexture(global1->GetTex("map_tex"),0,0,32,32,false);

    camfac1->CreateCamera("cam1");	
	cam1=camfac1->GetCameraByName("cam1");
	cam1->SetPosition(500,land1->GetHeight(500,500)+20,500);
	cam1->SetLookAt(100,100,100);
	cam1->SetViewFrustum(60,5000,1);
	engine1->SetCamera(cam1);
}

void setupPhysics()
{
	{
		hkVector4 groundRadii( 70.0f, 2.0f, 140.0f );
		hkpConvexShape* shape = new hkpBoxShape( groundRadii , 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;

		physicsWorld->addEntity(new hkpRigidBody( ci ) )->removeReference();
		shape->removeReference();
	}

	hkVector4 groundPos( 0.0f, 0.0f, 0.0f );
	hkVector4 posy = groundPos;	

	int wallHeight = 8;
	int wallWidth  = 8;
	int numWalls = 6;
	hkVector4 boxSize( 1.0f, 0.5f, 0.5f);
	hkpBoxShape* box = new hkpBoxShape( boxSize , 0 );
	box->setRadius( 0.0f );

	hkReal deltaZ = 25.0f;
	posy(2) = -deltaZ * numWalls * 0.5f;

	for ( int y = 0; y < numWalls; y ++ )			// first wall
	{
		createBrickWall(wallHeight, wallWidth, posy, 0.2f, box, boxSize );
		posy(2) += deltaZ;
	}
	box->removeReference();

	const hkReal radius = 1.5f;
	const hkReal sphereMass = 150.0f;

	hkVector4 relPos( 0.0f,radius + 0.0f, 50.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(posy, relPos );
	info.m_motionType  = hkpMotion::MOTION_BOX_INERTIA;

	info.m_qualityType = HK_COLLIDABLE_QUALITY_BULLET;


	hkpRigidBody* sphereRigidBody = new hkpRigidBody( info );
	g_ball = sphereRigidBody;

	physicsWorld->addEntity( sphereRigidBody );
	sphereRigidBody->removeReference();
	info.m_shape->removeReference();

	hkVector4 vel(  0.0f,4.9f, -100.0f );
	sphereRigidBody->setLinearVelocity( vel );
}


void Init_Havok()
{
	PlatformInit();
	hkMemoryRouter* memoryRouter = hkMemoryInitUtil::initDefault( hkMallocAllocator::m_defaultMallocAllocator, hkMemorySystem::FrameInfo( 500* 1024 ) );
	hkBaseSystem::init( memoryRouter, errorReport );	
	{
		
		//hkJobThreadPool* threadPool;
		int totalNumThreadsUsed;

		hkHardwareInfo hwInfo;
		hkGetHardwareInfo(hwInfo);
		totalNumThreadsUsed = hwInfo.m_numThreads;

		hkCpuJobThreadPoolCinfo threadPoolCinfo;
		threadPoolCinfo.m_numThreads = totalNumThreadsUsed - 1;

		threadPoolCinfo.m_timerBufferPerThreadAllocation = 200000;
		threadPool = new hkCpuJobThreadPool( threadPoolCinfo );

		
		hkJobQueueCinfo info;
		info.m_jobQueueHwSetup.m_numCpuThreads = totalNumThreadsUsed;
		hkJobQueue* jobQueue = new hkJobQueue(info);

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


		//hkpWorld* world;		
		{
			
			hkpWorldCinfo worldInfo;
			worldInfo.m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED;
			worldInfo.m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_REMOVE_ENTITY;
			physicsWorld = new hkpWorld(worldInfo);

			physicsWorld->m_wantDeactivation = false;

			physicsWorld->markForWrite();

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

			physicsWorld->registerWithJobQueue( jobQueue );
			
			setupPhysics();
		}


		//hkArray<hkProcessContext*> contexts;


		//hkpPhysicsContext* context;
		{
			
			context = new hkpPhysicsContext();
			hkpPhysicsContext::registerAllPhysicsProcesses();
			context->addWorld(physicsWorld); 
			contexts.pushBack(context);

			physicsWorld->unmarkForWrite();
		}

		hkVisualDebugger* vdb = new hkVisualDebugger(contexts);
		vdb->serve();
		
		hkStopwatch stopWatch;
	    stopWatch.start();
		hkReal lastTime = stopWatch.getElapsedSeconds();

		hkReal timestep = 1.f / 60.f;
		int numSteps = int(60.f / timestep);

		while(TRUE)
		{            			
		  Run_Havok();
          physicsWorld->stepMultithreaded( jobQueue, threadPool, 1.f / 60.f );

		  context->syncTimers( threadPool );
		  vdb->step();
			
		  hkMonitorStream::getInstance().reset();
		  threadPool->clearTimerData();

		  while (stopWatch.getElapsedSeconds() < lastTime + timestep);
		  lastTime += timestep;
			
          
	      render();
          input();
			
		}

		{
			physicsWorld->markForWrite();
			physicsWorld->removeReference();
		}

		vdb->removeReference();

	
		context->removeReference();

		delete jobQueue;		

		threadPool->removeReference();	
	}
	
	hkBaseSystem::quit();
    hkMemoryInitUtil::quit();
	

	PlatformQuit();
}

void Run_Havok()
{   
		  
}



void createBrickWall( int height, int length, const hkVector4& position, hkReal gapWidth, hkpConvexShape* box, hkVector4Parameter halfExtents )
{
	hkVector4 posx = position;
	
	{
		hkpWorldRayCastInput ray;
		ray.m_from = posx;
		ray.m_to = posx;

		ray.m_from(1) += 20.0f;
		ray.m_to(1)   -= 20.0f;

		hkpWorldRayCastOutput result;
		physicsWorld->castRay( ray, result );
		posx.setInterpolate4( ray.m_from, ray.m_to, result.m_hitFraction );
	}
	
	posx(0) -= ( gapWidth + 2.0f * halfExtents(0) ) * length * 0.5f;
	posx(1) -= halfExtents(1) + box->getRadius();

	hkArray<hkpEntity*> entitiesToAdd;

	for ( int x = 0; x < length; x ++ )		
	{
		hkVector4 pos = posx;
		for( int ii = 0; ii < height; ii++ )
		{
			pos(1) += (halfExtents(1) + box->getRadius())* 2.0f;

			hkpRigidBodyCinfo boxInfo;
			boxInfo.m_mass = 10.0f;
			hkpMassProperties massProperties;
			hkpInertiaTensorComputer::computeBoxVolumeMassProperties(halfExtents, boxInfo.m_mass, massProperties);

			boxInfo.m_mass = massProperties.m_mass;
			boxInfo.m_centerOfMass = massProperties.m_centerOfMass;
			boxInfo.m_inertiaTensor = massProperties.m_inertiaTensor;
			boxInfo.m_solverDeactivation = boxInfo.SOLVER_DEACTIVATION_MEDIUM;
			boxInfo.m_shape = box;
			
			boxInfo.m_restitution = 0.0f;

			boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;

			{
				boxInfo.m_position = pos;
				hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
				physicsWorld->addEntity( boxRigidBody );
				boxRigidBody->removeReference();
			}

			pos(1) += (halfExtents(1) + box->getRadius())* 2.0f;
			pos(0) += halfExtents(0) * 0.6f;
			{
				boxInfo.m_position = pos;
				hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
				entitiesToAdd.pushBack(boxRigidBody);
			}
			pos(0) -= halfExtents(0) * 0.6f;
		}
		posx(0) += halfExtents(0)* 2.0f + gapWidth;
	}
	physicsWorld->addEntityBatch( entitiesToAdd.begin(), entitiesToAdd.getSize());

	for (int i=0; i < entitiesToAdd.getSize(); i++){ entitiesToAdd[i]->removeReference(); }
}
 
 
总结:
 physicsWorld->stepMultithreaded( jobQueue, threadPool, 1.f / 60.f );语句非常奇怪,不能放到任何函数里执行,甚至不能放到WinMain的while循环里去执行,查看HVK的范例,全都是基于控制台而非windows平台编写的,而TV似乎又只能在win32程序中执行,坑爹啊.....


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值