x
Yes
No
Do you want to visit DriveHQ English website?
首页
产品服务
价格
免费试用
下载客户端
关于我们
云文件服务
|
云备份服务
|
FTP服务
|
企业邮箱服务
|
网站托管
|
客户端软件
云文件服务
云备份服务
FTP服务
企业级邮箱服务
网站托管
客户端软件
GameLevel.cpp - Hosted on DriveHQ Cloud IT Platform
返回上层目录
上传
下载
共享
发布
新建文件夹
新建文件
复制
剪切
删除
粘贴
评论
升级服务
路径: \\game3dprogramming\materials\DarkPuzzle\GameEngine\GameLevel.cpp
旋转
特效
属性
历史版本
//#include "DXUT.h" #include "DarkPuzzle.h" #include "GameLevel.h" #include "GameEngine.h" #include "Game3DInstance.h" #include "Light.h" #include "Character.h" #include
using namespace std; using namespace DarkBattle; #define NEAR_PLANE 1.0f #define PROJECTION_WIDTH 1.0f #define PROJECTION_HEIGHT 1.0f //#include "GameEngine.h" namespace DarkBattle{ GameLevel* GameLevel::theGameLevel = NULL; const char* EffectParamNames[EFFECT_NUMPARAMS]={"matWorld","matView","matProjection", "matWorldView","matWorldViewProjection","bump_Tex","base_Tex", "litShadowPos","litShadowRange","litShadowColor","litFallOffPercent", "litShadowDirView","litShadowIsSpot","litShadowRadius","debugMode","lightDirectionalDir"}; D3DXHANDLE* GameLevel::effectParams = NULL; extern FILE* fdebug; } #define GAMELEVEL_NAME "GameLevel" #define GAMELEVEL_FRAMEMOVE "FrameMove" #define GAMELEVEL_MOUSE_LEFT_DOWN "MouseLeftDown" #define GAMELEVEL_MOUSE_RIGHT_DOWN "MouseRightDown" #define GAMELEVEL_MOUSE_MOVE "MouseMove" class myLine{ public: Vec3 from; Vec3 to; Vec3 color; myLine(Vec3 fromP,Vec3 toP){ this->from = Vec3(fromP.x,fromP.y,fromP.z); this->to = Vec3(toP.x,toP.y,toP.z); this->color = Vec3(1,0,0); }; myLine(Vec3 fromP,Vec3 toP,Vec3 Color){ this->from = Vec3(fromP.x,fromP.y,fromP.z); this->to = Vec3(toP.x,toP.y,toP.z); this->color = Color; }; }; list
debugLines; void GameLevel::DrawDebugLine(Vec3 fromP, Vec3 toP){ debugLines.push_back(myLine(fromP,toP)); } void GameLevel::DrawDebugLineDelta(Vec3 fromP, Vec3 delta){ debugLines.push_back(myLine(fromP,fromP+delta)); } void GameLevel::DrawDebugLine(Vec3 fromP, Vec3 toP, Vec3 color){ debugLines.push_back(myLine(fromP,toP,color)); } void GameLevel::DrawDebugLineDelta(Vec3 fromP, Vec3 delta,Vec3 color){ debugLines.push_back(myLine(fromP,fromP+delta,color)); } struct CUSTOME_VERTEX{ float x,y,z; float r,g,b; //float nx,ny,nz; //float tu,tv; }; const D3DVERTEXELEMENT9 streamDecl[3] = { { 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, { 0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0 }, //{ 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, D3DDECL_END() }; void GameLevel::renderDebugLines(){ if (debugLines.empty()) return; int primitiveCount = debugLines.size(); int bufSize = primitiveCount*2*sizeof(CUSTOME_VERTEX); CUSTOME_VERTEX* pBuf = new CUSTOME_VERTEX[primitiveCount*2]; int i=0; while (!debugLines.empty()){ myLine curLine = debugLines.back(); //D3DXVec3TransformNormal(&pos,&pos,view); pBuf[i].x = curLine.from.x; pBuf[i].y = curLine.from.y; pBuf[i].z = curLine.from.z; pBuf[i].r = curLine.color.x; pBuf[i].g = curLine.color.y; pBuf[i].b = curLine.color.z; i++; pBuf[i].x = curLine.to.x; pBuf[i].y = curLine.to.y; pBuf[i].z = curLine.to.z; pBuf[i].r = curLine.color.x; pBuf[i].g = curLine.color.y; pBuf[i].b = curLine.color.z; i++; debugLines.pop_back(); } assert(i==primitiveCount*2); GetD3DDevice()->SetFVF(D3DFVF_XYZ|D3DFVF_NORMAL); GetD3DDevice()->DrawPrimitiveUP(D3DPT_LINELIST,primitiveCount,pBuf,sizeof(CUSTOME_VERTEX)); SAFE_DELETE_ARRAY(pBuf); } bool GameLevel::RayCast(Vec3 fromP, Vec3 toP, Vec3* pHitPos, Vec3* pNormalVec){ //assert(&hitPos!=NULL); //assert(&normalVec!=NULL); btCollisionWorld::ClosestRayResultCallback rayCallback(fromP.ToBtVector3(), toP.ToBtVector3()); GameLevel::GetInstance()->m_dynamicsWorld->rayTest(fromP.ToBtVector3(), toP.ToBtVector3(), rayCallback,RAY_STATIC_FILTER); if (rayCallback.HasHit()){ if (pHitPos!=NULL) *pHitPos = Vec3(rayCallback.m_hitPointWorld); if (pNormalVec!=NULL) *pNormalVec = Vec3(rayCallback.m_hitNormalWorld); return true; }else return false; } bool GameLevel::RayCastTwoWay(Vec3 pos1, Vec3 pos2){ return RayCast(pos1,pos2,NULL,NULL) || RayCast(pos2,pos1,NULL,NULL); } void GameLevel::framemoveBullet(float elapseTime){ ///step the simulation if (m_dynamicsWorld) { //because Bullet use microsecond as the parameter, so mul it with 10^6 m_dynamicsWorld->stepSimulation(elapseTime * 1000000.0f,2,1.0f/FRAME_RATE); //optional but useful: debug drawing //m_dynamicsWorld->debugDrawWorld(); } } void GameLevel::destroyBullet(){ //cleanup in the reverse order of creation/initialization //remove the rigidbodies from the dynamics world and delete them int i; for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(obj); if (body && body->getMotionState()) { delete body->getMotionState(); } m_dynamicsWorld->removeCollisionObject( obj ); //delete obj->getUserPointer(); delete obj; } //delete collision shapes for (int j=0;j
setGravity(btVector3(0,0,GRAVITY_VALUE)); ///create a few basic rigid bodies // btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,0,1),50); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,0,-55)); //create the ground shape //{ // btScalar mass(0.); // //rigidbody is dynamic if and only if mass is non zero, otherwise static // bool isDynamic = (mass != 0.f); // btVector3 localInertia(0,0,0); // if (isDynamic) // groundShape->calculateLocalInertia(mass,localInertia); // //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects // btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); // btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); // btRigidBody* body = new btRigidBody(rbInfo); // //add the body to the dynamics world // m_dynamicsWorld->addRigidBody(body); //} //{ // //create a few dynamic rigidbodies // // Re-using the same collision is better for memory usage and performance // btCollisionShape* colShape = new btBoxShape(btVector3(1,1,1)); // //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); // m_collisionShapes.push_back(colShape); // /// Create Dynamic Objects // btTransform startTransform; // startTransform.setIdentity(); // btScalar mass(1.f); // //rigidbody is dynamic if and only if mass is non zero, otherwise static // bool isDynamic = (mass != 0.f); // btVector3 localInertia(0,0,0); // if (isDynamic) // colShape->calculateLocalInertia(mass,localInertia); // float start_x = -5 - ARRAY_SIZE_X/2; // float start_y = -5; // float start_z = -1; // //float* color = new float[ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z]; // //memchr(color,0,ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z); // for (int k=0;k
setCollisionFlags(body->getCollisionFlags()|btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); // //color[i*j*k]=0.0f; // float* color = new float(0.0f); // body->setUserPointer(color); // m_dynamicsWorld->addRigidBody(body); // } // } // } //} gContactAddedCallback = myContactCallback; } bool GameLevel::haveTimeLeft(){ //determine time left here, OR IT WILL LOOP FOREVER, OR IT WILL DO NOTHING //double test = DXUTGetTime(); //DEBUG_OUTPUT("%d\n",test); //double test2 = 1/GameEngine::PreferedFrameRate; //bool test3 = DXUTIsTimePaused(); //double test = DXUTGetGlobalTimer()->GetTime(); return GetCurrentTime()-previousTime<1/GameEngine::PreferedFrameRate; //return DXUTGetElapsedTime()<1/GameEngine::PreferedFrameRate; //return false; } GameLevel::GameLevel(IDirect3DDevice9* pd3dDevice):GameScreen(pd3dDevice),mapSizeX(-1),mapSizeY(-1){ GameLevel::theGameLevel = this; this->levelName = NULL; this->light = D3DLIGHT9(); this->m_collisionConfiguration = NULL; //this->m_collisionShapes = NULL; this->m_dispatcher = NULL; this->m_dynamicsWorld = NULL; this->m_overlappingPairCache = NULL; this->m_solver = NULL; this->controllableCharacter = NULL; this->angle = 0; this->mouseIsHit = false; initBullet(); //init shadow this->hasShadow = true; this->pEffect = NULL; if (hasShadow){ DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE; #ifdef DEBUG_VS dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT; #endif #ifdef DEBUG_PS dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT; #endif #ifdef _DEBUG //HRESULT hr; LPD3DXBUFFER pErrors; hr = D3DXCreateEffectFromFileA( pd3dDevice, "resources\\effects\\shadow.fx", NULL, NULL, dwShaderFlags, NULL, &pEffect, &pErrors); char* errStr = (pEffect==NULL)?(char*)pErrors->GetBufferPointer():NULL; assert(pEffect!=NULL);//check the name of the effect file #else D3DXCreateEffectFromFileA( pd3dDevice, "resources\\effects\\shadow.fx", NULL, NULL, dwShaderFlags, NULL, &pEffect, NULL); #endif // _DEBUG // Determine the rendering techniques to use based on device caps techniqueRenderScene = pEffect->GetTechniqueByName( "ShadowVolume" ); assert(techniqueRenderScene!=NULL);//check the name of the technique in the fx file SAFE_DELETE_ARRAY(effectParams); effectParams = new D3DXHANDLE[EFFECT_NUMPARAMS];//check the number of parameters in the effect for (int i=0;i
GetParameterByName(NULL,EffectParamNames[i]); assert(effectParams[i]!=NULL);//ensure the names are correct } {//check the passes names D3DXPASS_DESC passDesc; pEffect->GetPassDesc(pEffect->GetPass(techniqueRenderScene,EPASS_RenderAmbient),&passDesc); assert(strcmp(passDesc.Name,"RenderSceneDirectionalLight")==0); pEffect->GetPassDesc(pEffect->GetPass(techniqueRenderScene,EPASS_RenderShadowMesh),&passDesc); assert(strcmp(passDesc.Name,"RenderShadowVolume")==0); pEffect->GetPassDesc(pEffect->GetPass(techniqueRenderScene,EPASS_RenderLight),&passDesc); assert(strcmp(passDesc.Name,"RenderWithShadowLight")==0); } {//check two sided stencil D3DCAPS9 Caps; pd3dDevice->GetDeviceCaps( &Caps ); if( !(Caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) ){ //report an error here MessageBoxA(DXUTGetHWND(),"Two sided stencil is not available, application will now exit", "Unrecoverable error",MB_OK); exit(1); } if( !(Caps.RasterCaps & D3DPRASTERCAPS_SCISSORTEST) ){ //report an error here MessageBoxA(DXUTGetHWND(),"Scissor Test is not available, application will now exit", "Unrecoverable error",MB_OK); exit(1); } } } }; void GameLevel::SetMapSizeX(float size){ mapSizeX = size; if (mapSizeX!=-1 && mapSizeY!=-1) initPathFinding(); } void GameLevel::SetMapSizeY(float size){ mapSizeY = size; if (mapSizeX!=-1 && mapSizeY!=-1) initPathFinding(); } void GameLevel::initPathFinding(){ //make the grid //raycast //store the height field //a map to store which cell is accessible //an accessible cell has height lower than something //need raycast to static object, not dynamic obj //map = new Map(MapSizeX/Map::GridSize,MapSizeX/Map::GridSize); //Vec3 from,to,hit,norm; //for (int x=0;x
SizeX();x++){ // for (int y=0;y
SizeY();y++){ // to = Vec3(x*Map::GridSize,y*Map::GridSize,-10); // from = to + Vec3(0,0,40); // if (RayCast(from,to,hit,norm)){ // map->SetHeight(x,y,hit.z); // } // } //} map = new Map(mapSizeX,mapSizeY); } void GameLevel::renderPhysicsWorld(){ //return; assert(m_dynamicsWorld!=NULL);//Check LoadContent to see what happen IDirect3DDevice9* pd3dDevice = GetD3DDevice(); int numObjects = m_dynamicsWorld->getNumCollisionObjects(); for (int i=0;i
getCollisionObjectArray()[i]; /*btRigidBody* body = btRigidBody::upcast(colObj); if (body && body->getMotionState()) { btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); myMotionState->m_graphicsWorldTrans.getOpenGLMatrix((btScalar*)&world); } else { colObj->getWorldTransform().getOpenGLMatrix((btScalar*)&world); }*/ //D3DXMatrixIdentity(&world); //pd3dDevice->SetTransform(D3DTS_WORLD, &world); if (colObj->getUserPointer()){ //Game3DObject* obj = (Game3DObject*)colObj->getUserPointer(); Game3DInstance* pInstance = (Game3DInstance*)colObj->getUserPointer(); assert(pInstance!=NULL); world = pInstance->GetTransformMatrix(); Game3DObject* const obj = pInstance->Get3DObject(); if (obj){ //set effect parameter per-object hr = pEffect->SetMatrix(GetEffectParamConst(EffectParamConst::MatWorld),&world); assert(SUCCEEDED(hr)); worldView = world * view; hr = pEffect->SetMatrix(GetEffectParamConst(EffectParamConst::MatWorldView),&worldView); assert(SUCCEEDED(hr)); worldViewProjection = worldView * projection; hr = pEffect->SetMatrix(GetEffectParamConst(EffectParamConst::MatWorldViewProjection),&worldViewProjection); assert(SUCCEEDED(hr)); pEffect->CommitChanges(); obj->OnRender(pd3dDevice); } } } } GameLevel::~GameLevel(void){ GameLevel::theGameLevel = NULL; destroyBullet(); Game3DObject::DestroyAll3DObjects(); delete levelName; SAFE_RELEASE(pEffect); SAFE_DELETE_ARRAY(effectParams); SAFE_DELETE(map); } void GameLevel::LoadContent(IDirect3DDevice9* pd3dDevice,const char* fileName){ SAFE_DELETE_ARRAY(levelName); CLONE_STR(levelName,fileName); string str = "resources\\"; str.append(levelName); str.append(".dae"); {//load the level from a COLLADA file MyConverter* converter = new MyConverter(m_dynamicsWorld); converter->load(pd3dDevice,str.c_str(),this->hasShadow); //TODO: complete the loading here_ delete converter; } ScriptEngine::GetInstance()->Initialize();//common init for all levels string str2 = "resources\\"; str2.append(levelName); str2.append(".lua"); ScriptEngine::GetInstance()->DoFile(str2.c_str());//init for this level only //initPathFinding();//after the level has been initialized this->thinkingIter = Character::GetPool().Begin(); } void GameLevel::OnResetDevice(IDirect3DDevice9* pd3dDevice){ previousTime = GetCurrentTime(); //TODO: reset all 3d resources here Game3DObject::ResetAll3DObjects(pd3dDevice); //set up the projection D3DXMatrixPerspectiveLH(&projection, PROJECTION_WIDTH, PROJECTION_HEIGHT, NEAR_PLANE, 1000.0f); //pd3dDevice->SetTransform(D3DTS_PROJECTION, &projection); light.Type = D3DLIGHT_DIRECTIONAL; light.Ambient = D3DXCOLOR(1.0,1.0,1.0,1.0); light.Diffuse = D3DXCOLOR(1.0,1.0,1.0,1.0); light.Direction = D3DXVECTOR3(-0.2f,-0.5f,-0.8f); light.Range=500; light.Specular = D3DXCOLOR(1.0,1.0,1.0,1.0); pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE ); pd3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE); pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); //pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA(100,100,100,255)); pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);//should be the opposite pd3dDevice->SetLight(0, &light); pd3dDevice->LightEnable(0,TRUE); //reset the effect if (pEffect){ pEffect->OnResetDevice(); } } void GameLevel::OnLostDevice(){ //TODO: release 3d resources here Game3DObject::ReleaseAll3DObjects(); //pBox->Release(); //release effect if (pEffect){ pEffect->OnLostDevice(); } } btRigidBody* GameLevel::MyConverter::findRigidBodyBySID(const char* sid){ for (int i=0;i
getNumRigidBodies();i++){ domInstance_rigid_body* rigidBody = this->findRigid_body_instance(this->getRigidBody(i)); if (rigidBody){ if (strcmp(sid,rigidBody->getBody())==0){ return this->getRigidBody(i); //return this->m_dynamicsWorld->getCollisionObjectArray()[i]; } } } return NULL; } bool GameLevel::MyConverter::load(IDirect3DDevice9* pd3dDevice, const char* fileName, bool hasShadow){ if (!ColladaConverter::load(fileName)) return false; domLibrary_physics_models_Array* physicsModelArray = &(this->m_dom->getLibrary_physics_models_array()); for (int i=0;i
getCount();i++){ domPhysics_model_Array* modelArray = &(physicsModelArray->get(i).cast()->getPhysics_model_array()); for (int j=0;j
getCount();j++){ domRigid_body_Array* rigidArr = &(modelArray->get(j).cast()->getRigid_body_array()); for (int k=0;k
getCount();k++){ domRigid_body* ridBody = rigidArr->get(k).cast(); //ridBody->getSid(); ridBody->getName(); char* name; CLONE_STR(name,ridBody->getName()); Game3DObject* obj = Game3DObject::Create3DObject(pd3dDevice,name,hasShadow); assert(obj!=NULL); btRigidBody* rigidBody = this->findRigidBodyBySID(ridBody->getSid()); assert(rigidBody!=NULL); #ifdef _DEBUG //filterGroup is 2 when obj is static, 1 when obj is dynamic if (rigidBody->isStaticObject()) assert(rigidBody->getBroadphaseHandle()->m_collisionFilterGroup==RAY_STATIC_FILTER); else assert(rigidBody->getBroadphaseHandle()->m_collisionFilterGroup==RAY_DYNAMIC_FILTER); #endif // _DEBUG Game3DInstance* pInstance; if (Character::CheckNameBelongToThisClass(name)){ //pInstance = new Character(obj, rigidBody,name); //new method from here Game3DInstance::CreateReference(obj,rigidBody, name);//there is only 1 name, no need to trim //create a 3dinstance reference //Game3DInstance::CreateReference(obj,rigidBody,name); //Game3DInstance::InitAllReferences() //remove this rigid body, now or later? //Character(name) --> call Game3DInstance::GetFromReference(name,&obj,&rigidBody) }else{ pInstance = new Game3DInstance(obj, rigidBody); } //rigidBody->setUserPointer((void*)pInstance); if (Light::CheckNameBelongToThisClass(name)){ Light* light = new Light(pInstance,name); } SAFE_DELETE_ARRAY(name); } } } //init all references here Game3DInstance::InitAllReferences(); return true; } void GameLevel::OnFrameMove(float elapsedTime){ framemoveBullet(elapsedTime); //update all objects state here GameEngine::Mouse mouse = GameEngine::GetMouseState(); ScriptEngine::GetInstance()->ExecuteOneParamFunction(GAMELEVEL_MOUSE_MOVE,(void*)this,GAMELEVEL_NAME); if (mouse.leftButtonDown && (!mouse.leftOld)){ ScriptEngine::GetInstance()->ExecuteOneParamFunction(GAMELEVEL_MOUSE_LEFT_DOWN,(void*)this,GAMELEVEL_NAME); } if (mouse.rightButtonDown && (!mouse.rightOld)){ ScriptEngine::GetInstance()->ExecuteOneParamFunction(GAMELEVEL_MOUSE_RIGHT_DOWN,(void*)this,GAMELEVEL_NAME); } //call level per frame script ScriptEngine::GetInstance()->ExecuteOneParamFunction(GAMELEVEL_FRAMEMOVE,(void*)this,GAMELEVEL_NAME); //act all characters, one-frame action for (MyIterator
iter = Character::GetPool().Begin();!Character::GetPool().IsEnd(iter); iter.Next()){ Character* character = iter.GetCurrent(); character->FrameMove(elapsedTime); } while (true){ Character* curChar = thinkingIter.GetCurrent(); curChar->ThinkStep(); //next char thinkingIter.Next(); if (Character::GetPool().IsEnd(thinkingIter)) thinkingIter = Character::GetPool().Begin(); //check time left if (!haveTimeLeft()) break; } } void GameLevel::OnRender(IDirect3DDevice9* pd3dDevice){ previousTime = GetCurrentTime(); //TODO: render all 3d content here //HRESULT hr; //init camera and all relevant matrixes { //eye = D3DXVECTOR3(40,40,80); at = D3DXVECTOR3(50,50,00); up = D3DXVECTOR3(0,0,1); D3DXMATRIX matRot; //angle+=0.1; D3DXVECTOR3 toEye = D3DXVECTOR3(1,0,0); D3DXMatrixRotationZ(&matRot,angle/180*3.14); D3DXVec3TransformCoord(&toEye,&toEye,&matRot); eye = at + toEye*60; eye.z = 80; D3DXMatrixLookAtLH(&view, &eye, &at, &up); } //pd3dDevice->SetTransform(D3DTS_VIEW, &view); //hero position GameLevel::DrawDebugLineDelta(Character::GetHero()->GetCenter(),Vec3(0,0,25)); //rayCast from hero eye downward //btVector3 from,to; //from = Character::GetHero()->GetCenter()+btVector3(0,0,25); //to = Character::GetHero()->GetCenter()+btVector3(50,0,-20); //btCollisionWorld::ClosestRayResultCallback rayCallback(from,to); //m_dynamicsWorld->rayTest(from, to, rayCallback); //if (rayCallback.HasHit()){ // GameLevel::DrawDebugLineDelta(rayCallback.m_hitPointWorld,rayCallback.m_hitNormalWorld*15); // GameLevel::DrawDebugLine(Character::GetHero()->GetCenter(),rayCallback.m_hitPointWorld); //} //ray cast to mouse pos GameEngine::Mouse mouse = GameEngine::GetMouseState(); D3DXVECTOR3 vecFrom = eye; D3DXVECTOR3 vecTo = D3DXVECTOR3(mouse.x/2*PROJECTION_WIDTH,-mouse.y/2*PROJECTION_HEIGHT,NEAR_PLANE); D3DXMATRIX viewInv; D3DXMatrixInverse(&viewInv,NULL,&view); D3DXVec3TransformCoord(&vecTo,&vecTo,&viewInv); vecTo = vecFrom+(vecTo-vecFrom)*500.0f; if ( GameLevel::RayCast(vecFrom,vecTo,&mouseHitPos,&mouseHitNorm) ){ mouseIsHit = true; //GameLevel::DrawDebugLineDelta(mouseHitPos,mouseHitNorm*25); }else mouseIsHit = false; //btCollisionWorld::ClosestRayResultCallback rayCallback = btCollisionWorld::ClosestRayResultCallback(from,to); ///*for (int i=0;i<100;i++)*/ m_dynamicsWorld->rayTest(from, to, rayCallback); //if (rayCallback.HasHit()){ // GameLevel::DrawDebugLineDelta(rayCallback.m_hitPointWorld,rayCallback.m_hitNormalWorld*15); //} pEffect->SetTechnique(techniqueRenderScene); UINT cPass; pEffect->Begin(&cPass,0); assert(cPass==3);//check the number of passes in your shader //set all per-scene constant hr = pEffect->SetMatrix(GetEffectParamConst(EffectParamConst::MatView),&view); assert(SUCCEEDED(hr)); hr = pEffect->SetMatrix(GetEffectParamConst(EffectParamConst::MatProjection),&projection); assert(SUCCEEDED(hr)); viewProjection = view * projection; //float litDirectionalDir[3] = {0.6f,0.2f,0.2f}; hr = pEffect->SetFloatArray(GetEffectParamConst(EffectParamConst::LightDirectionalDir),GameEngine::lightDirectionalDir,3); assert(SUCCEEDED(hr)); {//pass 0: render debug infos currentPass=0; pEffect->SetBool(GetEffectParamConst(EffectParamConst::DebugMode),true); D3DXMATRIX matTemp; D3DXMatrixIdentity(&matTemp); pEffect->SetMatrix(GetEffectParamConst(EffectParamConst::MatWorld),&matTemp); pEffect->SetMatrix(GetEffectParamConst(EffectParamConst::MatWorldView),&view); matTemp = view*projection; pEffect->SetMatrix(GetEffectParamConst(EffectParamConst::MatWorldViewProjection),&matTemp); pEffect->BeginPass(currentPass); //isRenderingShadowMesh = false; #ifdef _DEBUG renderDebugLines(); #endif // _DEBUG //pEffect->EndPass(); } {//pass 0: render with ambient and directional light currentPass=0; //pEffect->BeginPass(currentPass); //isRenderingShadowMesh = false; pEffect->SetBool(GetEffectParamConst(EffectParamConst::DebugMode),false); pEffect->CommitChanges(); renderPhysicsWorld(); pEffect->EndPass(); } //iterate through each light, render the shadow for each V(pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE,TRUE)); RECT clipRect; //clipRect.left = 100; //clipRect.right = 400; //clipRect.top = 100; //clipRect.bottom = 400; D3DRECT d3dClipRect; d3dClipRect.x1 = clipRect.left;d3dClipRect.x2=clipRect.right;d3dClipRect.y1 = clipRect.top;d3dClipRect.y2=clipRect.bottom; for (Light* lit = Light::IterationBegin();!(Light::IterationEnd());lit = Light::IterationNextElement()){ //compute the scissor test region D3DXMATRIX mat = lit->GetTransform(); float litPos[3] = {mat._41,mat._42,mat._43}; if (lit->IsSpotLight()){ D3DXVECTOR3 litShadowDir = lit->GetLightDirection(); D3DXVec3Normalize(&litShadowDir,&litShadowDir); //compute the light shadow direction in view space D3DXVECTOR3 litShadowDirView = litShadowDir; D3DXVec3TransformNormal(&litShadowDirView,&litShadowDirView,&view); D3DXVec3Normalize(&litShadowDirView,&litShadowDirView); D3DXVECTOR3 litPosWord,litPosViewProjection,litRangePos,litRangePosProjection,litRadiusPos,litRadiusPosProjection; litPosWord.x = litPos[0]; litPosWord.y = litPos[1]; litPosWord.z = litPos[2]; D3DXVECTOR3 viewHorizontal; D3DXVec3Cross(&viewHorizontal,&up,&(eye-at)); D3DXVec3Normalize(&viewHorizontal,&viewHorizontal);//is the horizontal vector in view space //litFarPos is the position at the light range litRangePos = litPosWord + litShadowDir*lit->GetLightRange(); //litOuterCircle is the pos distant from litFarPos litRadiusPos = litRangePos + viewHorizontal*lit->GetLightRadius(); D3DXVec3TransformCoord(&litPosViewProjection,&litPosWord,&viewProjection); D3DXVec3TransformCoord(&litRangePosProjection,&litRangePos,&viewProjection); D3DXVec3TransformCoord(&litRadiusPosProjection,&litRadiusPos,&viewProjection); //transformedRadius is the lightRadius in view space float transformedRadius = D3DXVec3Length(&(litRangePosProjection-litRadiusPosProjection)); clipRect.left = (litRangePosProjection.x+1 - transformedRadius)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Width; clipRect.right = (litRangePosProjection.x+1 + transformedRadius)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Width; clipRect.top = (-litRangePosProjection.y+1 - transformedRadius)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Height; clipRect.bottom = (-litRangePosProjection.y+1 + transformedRadius)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Height; float litPosXProj,litPosYProj; litPosXProj = (litPosViewProjection.x+1)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Width; litPosYProj = (-litPosViewProjection.y+1)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Height; //check to extend the clip rect to contain the light pos if (clipRect.left>litPosXProj) clipRect.left = litPosXProj; if (clipRect.right
litPosYProj) clipRect.top = litPosYProj; if (clipRect.bottom
SetFloat(GetEffectParamConst(EffectParamConst::LightShadowRadius),lit->GetLightRadius()); pEffect->SetFloatArray(GetEffectParamConst(EffectParamConst::LightShadowDirView),litShadowDirViewArray,3); }else{//point light D3DXVECTOR3 litPosWord,litPosViewProjection,litRangePos,litRangePosProjection; litPosWord.x = litPos[0]; litPosWord.y = litPos[1]; litPosWord.z = litPos[2]; D3DXVECTOR3 viewHorizontal; D3DXVec3Cross(&viewHorizontal,&up,&(eye-at)); D3DXVec3Normalize(&viewHorizontal,&viewHorizontal);//is the horizontal vector in view space //litRangePos is the pos place at a distance lightRange from litPosWorld litRangePos = litPosWord + viewHorizontal*lit->GetLightRange(); D3DXVec3TransformCoord(&litPosViewProjection,&litPosWord,&viewProjection); D3DXVec3TransformCoord(&litRangePosProjection,&litRangePos,&viewProjection); float transformedRange = D3DXVec3Length(&(litRangePosProjection-litPosViewProjection)); clipRect.left = (litPosViewProjection.x+1 - transformedRange)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Width; clipRect.right = (litPosViewProjection.x+1 + transformedRange)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Width; clipRect.top = (-litPosViewProjection.y+1 - transformedRange)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Height; clipRect.bottom = (-litPosViewProjection.y+1 + transformedRange)/2*DXUTGetD3D9BackBufferSurfaceDesc()->Height; } //check the clip rect with the screen size if (clipRect.left<0) clipRect.left=0; if (clipRect.right>DXUTGetD3D9BackBufferSurfaceDesc()->Width) clipRect.right=DXUTGetD3D9BackBufferSurfaceDesc()->Width; if (clipRect.top<0) clipRect.top=0; if (clipRect.bottom>DXUTGetD3D9BackBufferSurfaceDesc()->Height) clipRect.bottom=DXUTGetD3D9BackBufferSurfaceDesc()->Height; //copy the clip rect to d3d clip rect d3dClipRect.x1 = clipRect.left;d3dClipRect.x2=clipRect.right; d3dClipRect.y1 = clipRect.top;d3dClipRect.y2=clipRect.bottom; //must be placed before clearing stencil pd3dDevice->SetScissorRect(&clipRect); //clear the stencil only on scissor test rect V( pd3dDevice->Clear(1, &d3dClipRect, D3DCLEAR_STENCIL, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0) ); //V( pd3dDevice->Clear(0, NULL, D3DCLEAR_STENCIL, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0) ); //TODO: set the light parameters here pEffect->SetBool(GetEffectParamConst(EffectParamConst::LightIsSpotLight),lit->IsSpotLight()); pEffect->SetFloatArray(GetEffectParamConst(EffectParamConst::LightShadowPos),litPos,3); pEffect->SetFloat(GetEffectParamConst(EffectParamConst::LightShadowRange),lit->GetLightRange()); pEffect->SetFloat(GetEffectParamConst(EffectParamConst::LightFallOff),lit->GetLightFallOff()); pEffect->SetFloatArray(GetEffectParamConst(EffectParamConst::LightShadowColor),lit->GetLightColor(),3); {//pass 1: render the shadow volume currentPass=1; pEffect->BeginPass(currentPass); //isRenderingShadowMesh = true; renderPhysicsWorld(); pEffect->EndPass(); } {//pass 2: render the final light currentPass=2; hr = pEffect->BeginPass(currentPass); assert(SUCCEEDED(hr)); //isRenderingShadowMesh = false; renderPhysicsWorld(); pEffect->EndPass(); } } pEffect->End(); V(pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE,FALSE)); }
GameLevel.cpp
网页地址
文件地址
上一页
37/65
下一页
下载
( 31 KB )
Comments
Total ratings:
0
Average rating:
无评论
of 10
Would you like to comment?
Join now
, or
Logon
if you are already a member.