#include "dxstdafx.h" #include ".\scene.h" #include "GameManager.h" #include "Object3d.h" #include "Box.h" #include "Sprite.h" #include "ParticleGroup.h" #include "ParticleEmitter.h" #include "SoundNode.h" #include "SharedResourceTexture.h" #include "fmod.h" Scene::Scene(void) { this->sceneAlpha = 1; this->root.setScene(*this); this->sceneLifeTime = 0; this->usePhysXDebugger = true; //Fade Stuff this->visible = true; this->fadeState = NOFADE; //Gravity this->pDefaultGravity.x = 0; this->pDefaultGravity.y = -9.8f; this->pDefaultGravity.z = 0; //Frustum Stuff this->enableFrustumCulling = true; this->drawBBoxes = true; this->boundingBox = NULL; this->quadTreeBuilt = false; //RenderChain Timing usw QueryPerformanceFrequency(&this->frequency); this->firstFrame = true; //PhysicStuff this->pScene = NULL; D3DXMatrixIdentity(&this->worldMatrix); D3DXMatrixIdentity(&this->identMatrix); this->root.myScene = this; this->contactReport = NULL; this->triggerReport = NULL; this->notifyReport = NULL; //Get the Device this->device = DXUTGetD3DDevice(); this->physxRenderer.setDevice(*this->device); //Sun Stuff this->sunDirection.setXYZ(-1.0f, -2.0f, 1.0f); this->specialRenderer = NULL; //DefaultRenderPass konfigurieren this->activeRenderPass = NULL; //Particle Group Stuff this->particleGroupCounter = 0; this->finalImage = NULL; this->preDistortionFinal = NULL; this->distortionMap1 = NULL; this->distortionMap2 = NULL; this->screenDistortionMap = NULL; this->quadMesh = NULL; this->meshCreated = false; this->depthTextureResource = NULL; this->useDepthImposter = true; this->useRaytracer = true; this->muteMusic = false; } Scene::~Scene(void) { SAFE_RELEASE(this->finalImage); SAFE_RELEASE(this->finalImageSurface); SAFE_RELEASE(this->quadMesh); SAFE_RELEASE(this->depthSurface); SAFE_RELEASE(this->preDistortionFinal); SAFE_RELEASE(this->preDistortionFinalSurface); SAFE_RELEASE(this->screenDistortionMapSurface); } void Scene::initScene(GameManager &_manager) { HRESULT hr; this->manager = &_manager; //Textur für endgültiges Bild erzeugen if(!this->finalImage) { //Create Texture V( DXUTGetD3DDevice()->CreateTexture(this->manager->screenWidth, this->manager->screenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &this->finalImage, NULL ) ); //Get Surface for RenderTarget this->finalImage->GetSurfaceLevel(0, &this->finalImageSurface); } this->sceneLifeTime = 0; this->firstFrame = true; this->defaultParticleGroup = (ParticleGroup*) this->createNode(Scene::NODE_PARTICLEGROUP, false); this->initPhysic(); this->boundingBox = (Box*) this->createNode(Scene::NODE_BOX); this->boundingBox->setVisible(false); this->boundingBox->setStandBy(true); //Camera Stuff this->defaultCamera = (Camera *) this->createNode(this->NODE_CAMERA); this->activeCamera = this->defaultCamera; //Default RenderPass this->defaultRenderPass.setSafeAndRestoreRenderTarget(false); this->defaultRenderPass.setScene(*this); this->defaultRenderPass.setRenderPassId(Scene::PASS_NORMAL); this->defaultRenderPass.setRenderTarget(this->finalImageSurface); this->defaultRenderPass.execute(RenderPass::CMD_CLEARRENDERTARGETANDZBUFFER); this->defaultRenderPass.execute(RenderPass::CMD_RENDERNODES); //Depth RenderPass this->depthTextureResource = (SharedResourceTexture*) this->getSharedResource(Scene::SR_TEXTURE_VIEWDEPTH); if(!this->depthTextureResource) { if(this->depthSurface){ SAFE_RELEASE (this->depthSurface); } this->depthTextureResource = (SharedResourceTexture*) this->createSharedResource(Scene::SR_TEXTURE_VIEWDEPTH); this->depthTextureResource->getTexture()->GetSurfaceLevel(0, &this->depthSurface); } //Load DistortionMaps if(!this->distortionMap1) this->distortionMap1 = this->manager->resManager.loadTexture("./media/textures/heatnoise.tga"); if(!this->distortionMap2) this->distortionMap2 = this->manager->resManager.loadTexture("./media/textures/heatnoise2.tga"); if(!this->screenDistortionMap) { SharedResourceTexture* distMap = (SharedResourceTexture*) this->createSharedResource(Scene::SR_TEXTURE_DISTORTION); this->screenDistortionMap = distMap->getTexture(); this->screenDistortionMap->GetSurfaceLevel(0, &this->screenDistortionMapSurface); } if(!this->preDistortionFinal) { //Create Texture V( DXUTGetD3DDevice()->CreateTexture(this->manager->screenWidth, this->manager->screenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &this->preDistortionFinal, NULL ) ); //Get Surface for RenderTarget this->preDistortionFinal->GetSurfaceLevel(0, &this->preDistortionFinalSurface); } this->depthRenderPass.setSafeAndRestoreRenderTarget(false); this->depthRenderPass.setScene(*this); this->depthRenderPass.setRenderPassId(Scene::PASS_DEPTH); this->depthRenderPass.setRenderTarget(this->depthSurface); this->depthRenderPass.execute(RenderPass::CMD_CLEARRENDERTARGETANDZBUFFER); this->depthRenderPass.execute(RenderPass::CMD_RENDERNODES); this->depthRenderPass.useThisRendererList(this->defaultRenderPass.usedRendererList); //Raytrace RenderPass this->raytraceRenderPass.setSafeAndRestoreRenderTarget(false); this->raytraceRenderPass.setScene(*this); this->raytraceRenderPass.setRenderPassId(Scene::PASS_RAYTRACE); this->raytraceRenderPass.execute(RenderPass::CMD_CLEARRENDERTARGETANDZBUFFER); this->raytraceRenderPass.execute(RenderPass::CMD_DOFRUSTUMCULLING); this->raytraceRenderPass.execute(RenderPass::CMD_RENDERNODES); } float Scene::getSceneLiveTime() { return this->sceneLifeTime; } void Scene::setVisible(bool _visible) { this->visible = _visible; } bool Scene::isVisible() { return this->visible; } void Scene::fadeIn(float _duration) { this->fadeDuration = _duration; this->fadeTimer = 0; this->fadeState = FADEIN; this->setVisible(true); } void Scene::fadeOut(float _duration) { this->fadeDuration = _duration; this->fadeTimer = 0; this->fadeState = FADEOUT; } void Scene::setSceneAlpha(float _alpha) { if(_alpha>1) _alpha = 1; if(_alpha<0) _alpha = 0; this->sceneAlpha = _alpha; } Node* Scene::getRoot() { return &this->root; } void Scene::clearScene() { this->root.removeAllChildren(); this->cleanUpScene(); this->nodeList.clear(); this->particleList.clear(); this->rendererList.clear(); this->refObject3dList.clear(); this->refCameraList.clear(); this->refSoundList.clear(); this->triggerList.clear(); this->particleGroupVector.clear(); this->clearSharedResources(); this->sharedResourceVector.clear(); this->visibleNodeList.clear(); this->soundNodeList.clear(); //this->usedRendererList.clear(); this->zombieNodeList.clear(); if(this->manager && this->manager->pPhysicsSDK) { this->manager->pPhysicsSDK->releaseScene(*this->pScene); this->pScene = NULL; } } void Scene::setWidth(float _w) { this->width = _w; } void Scene::setHeight(float _h) { this->height = _h; } void Scene::setDepth(float _d) { this->depth = _d; } float Scene::getWidth() { return this->width; } float Scene::getHeight() { return this->height; } float Scene::getDepth() { return this->depth; } Camera* Scene::getActiveCamera() { return this->activeCamera; } NxSceneDesc* Scene::getPhysicSceneDescriptor() { return &this->sceneDesc; } bool Scene::initPhysic() { // Create the scene this->manager->pPhysicsSDK->setParameter(NX_SKIN_WIDTH, (NxReal)0.01); if(this->usePhysXDebugger) { this->manager->pPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 5.0f); this->manager->pPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1); this->manager->pPhysicsSDK->setParameter(NX_VISUALIZE_ACTOR_AXES, 1); this->manager->pPhysicsSDK->setParameter(NX_VISUALIZE_JOINT_LOCAL_AXES, 1.0f); this->manager->pPhysicsSDK->setParameter(NX_VISUALIZE_JOINT_WORLD_AXES, 1); this->manager->pPhysicsSDK->setParameter(NX_VISUALIZE_JOINT_ERROR, 1); this->manager->pPhysicsSDK->setParameter(NX_VISUALIZE_JOINT_LIMITS, 1); this->manager->pPhysicsSDK->setParameter(NX_VISUALIZE_JOINT_FORCE, 1); } this->sceneDesc.gravity = pDefaultGravity; this->sceneDesc.collisionDetection = true; if(this->pScene!=NULL) { this->manager->pPhysicsSDK->releaseScene(*this->pScene); } this->pScene = this->manager->pPhysicsSDK->createScene(this->sceneDesc); if(this->contactReport) this->pScene->setUserContactReport(this->contactReport); if(this->triggerReport) this->pScene->setUserTriggerReport(this->triggerReport); if(this->notifyReport) this->pScene->setUserNotify(this->notifyReport); this->pScene->setTiming(1.0f/60.0f, 8, NX_TIMESTEP_FIXED); // Create the default material NxMaterial* defaultMaterial = this->pScene->getMaterialFromIndex(0); defaultMaterial->setRestitution(0.5); defaultMaterial->setStaticFriction(0.5); defaultMaterial->setDynamicFriction(0.5); return true; } float Scene::getDeltaTime() { return this->dt; } void Scene::buildQuadTree() { this->fcQuad.setDimension(this->getWidth(), this->getWidth()); this->fcQuad.setPosition(this->getWidth()/2, this->getWidth()/2); this->fcQuad.buildQuadTree(QUADLEVEL); this->quadTreeBuilt = true; } RenderPass* Scene::getActiveRenderPass() { return this->activeRenderPass; } void Scene::renderScene(float fElapsedTime) { if(this->isVisible()) { if(this->device==0) { this->device = DXUTGetD3DDevice(); this->physxRenderer.setDevice(*this->device); } this->device->SetRenderTarget(0, this->finalImageSurface); this->takeTime(); //ClearScreen //this->clearRenderTargetAndZBuffer(); //Clear SharedResources this->clearSharedResources(); //Fetch Physic Results this->fetchPhysicResults(); //Fading Stuff this->doFade(); //Trigger updates this->updateTrigger(); //Update Nodes this->updateNodes(); //Calculate Transformations this->calculateTransformations(); //startRenderPasses this->startRenderPasses(); //Cleanup Memory this->cleanUpScene(); //Start Physic this->startPhysic(); this->firstFrame = false; } } void Scene::takeTime() { //Take time if(this->firstFrame) { QueryPerformanceCounter(&this->currentFrame); this->lastFrame = this->currentFrame; return; } else { this->lastFrame = this->currentFrame; QueryPerformanceCounter(&this->currentFrame); } double tempdt; tempdt = (double)(this->currentFrame.QuadPart-this->lastFrame.QuadPart)/(double)this->frequency.QuadPart; this->dt = (float) tempdt; this->dt = min(0.033f, this->dt); } void Scene::fetchPhysicResults() { if(!this->firstFrame) { this->pScene->fetchResults(NX_RIGID_BODY_FINISHED, true); } } void Scene::doFade() { switch(this->fadeState) { case FADEOUT: this->fadeTimer+=this->dt; this->sceneAlpha -= this->dt/this->fadeDuration; if(this->sceneAlpha<=0) { this->setVisible(false); this->fadeState = NOFADE; this->sceneAlpha = 0; } this->updateSoundNodeVolume(); break; case FADEIN: if(!this->visible) this->setVisible(true); this->fadeTimer+=this->dt; this->sceneAlpha+=this->dt/this->fadeDuration; if(this->sceneAlpha>=1) { this->fadeState = NOFADE; this->sceneAlpha = 1; } this->updateSoundNodeVolume(); break; default: break; } } void Scene::updateTrigger() { this->sceneLifeTime+=this->getDeltaTime(); std::vector >::iterator it; for(it=this->triggerList.begin();it!=this->triggerList.end();it++) { if(this->sceneLifeTime>(*it)->getTime()) { this->executeTrigger(*it); this->triggerList.erase(it); it--; } else { return; } } for(UINT i=0;itriggerList.size();i++) { if(this->sceneLifeTime>this->triggerList.at(i)->getTime()) { this->executeTrigger(this->triggerList.at(i)); i--; } else { return; } } } void Scene::updateNodes() { this->root.update(this->dt); } void Scene::calculateTransformations() { //Object transformation this->root.calcWorldMatrix(this->worldMatrix); this->root.updateBBox(); } void Scene::doFrustumCulling() { Camera cam; cam.setViewMatrix(*this->activeRenderPass->getViewMatrix()); cam.setProjectionMatrix(*this->activeRenderPass->getProjectionMatrix()); std::vector* usedRendererList; usedRendererList = this->activeRenderPass->usedRendererList; std::list >::iterator nodeIt; Node* node; if(!this->quadTreeBuilt) this->buildQuadTree(); usedRendererList->clear(); Renderer *renderer; if(this->enableFrustumCulling) { Plane view[4]; view[0] = cam.getNearPlane(); view[1] = cam.getFarPlane(); view[2] = cam.getLeftPlane(); view[3] = cam.getRightPlane(); this->fcQuad.clipQuadAgainstCamera(&view[0]); for(nodeIt = this->nodeList.begin(); nodeIt!=this->nodeList.end();nodeIt++) { node = (*nodeIt).get(); if(!node->onStandBy() && node->visible && node->hasRenderer() && node->testAgainstFrustum && this->fcQuad.nodeInside(node)) { renderer = node->getRenderer().get(); if(this->activeRenderPass == &this->defaultRenderPass) { if(renderer->isA(Renderer::RENDERER_PARTICLE)) { this->needDepthPass |= renderer->needsExtraPass(); if(((ParticleRenderer*) renderer)->needHeatHazePass()) { this->needDistortionPass = true; this->heatHazeParticleRendererList.push_back((ParticleRenderer*) renderer); } } else if(renderer->isA(Renderer::RENDERER_RAYTRACE)) { this->needRaytracePass = true; this->raytraceRendererList.push_back((RaytraceRenderer*) renderer); } } usedRendererList->push_back(renderer); } else if(!node->onStandBy() && node->visible && node->hasRenderer() && !node->testAgainstFrustum) { renderer = node->getRenderer().get(); if(this->activeRenderPass == &this->defaultRenderPass) { if(renderer->isA(Renderer::RENDERER_PARTICLE)) { this->needDepthPass |= renderer->needsExtraPass(); if(((ParticleRenderer*) renderer)->needHeatHazePass()) { this->needDistortionPass = true; this->heatHazeParticleRendererList.push_back((ParticleRenderer*) renderer); } } else if(renderer->isA(Renderer::RENDERER_RAYTRACE)) { this->needRaytracePass = true; this->raytraceRendererList.push_back((RaytraceRenderer*) renderer); } } usedRendererList->push_back(renderer); } } } else { for(nodeIt = this->nodeList.begin(); nodeIt!=this->nodeList.end();nodeIt++) { node = (*nodeIt).get(); if(!node->onStandBy() && node->visible && node->hasRenderer()) { renderer = node->getRenderer().get(); if(this->activeRenderPass == &this->defaultRenderPass) { if(renderer->isA(Renderer::RENDERER_PARTICLE)) { this->needDepthPass |= renderer->needsExtraPass(); if(((ParticleRenderer*) renderer)->needHeatHazePass()) { this->needDistortionPass = true; this->heatHazeParticleRendererList.push_back((ParticleRenderer*) renderer); } } else if(renderer->isA(Renderer::RENDERER_RAYTRACE)) { this->needRaytracePass = true; this->raytraceRendererList.push_back((RaytraceRenderer*) renderer); } } usedRendererList->push_back(renderer); } } } } void Scene::doViewingTransformation() { this->device->SetTransform(D3DTS_VIEW, this->activeCamera->getViewMatrix() ); } void Scene::renderNodes() { std::vector* usedRendererList; usedRendererList = this->activeRenderPass->usedRendererList; //Sorts the rendering processes by its priority! std::sort(usedRendererList->begin(), usedRendererList->end(), renderSortFunction()); std::vector::iterator it; for(it=usedRendererList->begin();it!=usedRendererList->end();it++) { if((*it) == 0) { this->manager->printToConsole("Renderer in usedRenderList is NULL!!!!"); } if((*it)->nodeAdded) { SPTR n = (*it)->myNode.lock(); if(!n->onStandBy() && n->visible) { this->worldMatrix = *n->getWorldMatrix(); (*it)->render(); } } } if(this->usePhysXDebugger && this->activeRenderPass==&this->defaultRenderPass) { D3DXMATRIX worldMat; D3DXMatrixIdentity(&worldMat); this->device->SetTransform( D3DTS_WORLD, &worldMat); this->device->SetTransform( D3DTS_PROJECTION, this->activeCamera->getProjectionMatrix()); this->device->SetTransform( D3DTS_VIEW, this->activeCamera->getViewMatrix()); const NxDebugRenderable *dbgRenderable = pScene->getDebugRenderable(); this->physxRenderer.render(*dbgRenderable); this->device->SetTransform( D3DTS_PROJECTION, &worldMat); this->device->SetTransform( D3DTS_VIEW, &worldMat); } /*D3DXMatrixIdentity(&this->worldMatrix); if(this->drawBBoxes && this->boundingBox!=NULL) { for(it=this->usedRendererList.begin();it!=this->usedRendererList.end();it++) { SPTR n = (*it)->myNode.lock(); D3DXMATRIX tMat; Vector dim = *n->getAbsMaxBBox() - *n->getAbsMinBBox(); Vector absPos; absPos = *n->getAbsMinBBox()+dim/2; D3DXMatrixTranslation(&tMat, absPos.x, absPos.y, absPos.z); this->device->SetTransform( D3DTS_WORLD, &tMat); this->boundingBox->setDimension(dim.x, dim.y, dim.z); this->boundingBox->getRenderer()->render(); } }*/ } void Scene::cleanUpScene() { std::list >::iterator it; std::list >::iterator nit; std::vector >::iterator rit; Node* node; for(it=this->zombieNodeList.begin();it!=this->zombieNodeList.end();it++) { node = (*it).get(); node->getFather()->removeChild(*it); //Delete Renderer if(node->hasRenderer()) { Renderer *r = node->getRenderer().get(); for(rit=this->rendererList.begin();rit!=this->rendererList.end();rit++) { if((*rit).get() == r) { this->rendererList.erase(rit); break; } } } //Delete Physic Actor if(node->getActor()!=NULL) { this->pScene->releaseActor(*node->getActor()); } //Delete from NodeList this->deleteNodeInList(node, this->nodeList); this->deleteNodeInList(node, this->particleList); this->deleteNodeInList(node, this->soundNodeList); } this->zombieNodeList.clear(); } void Scene::deleteNodeInList(Node* node, std::list > &list) { std::list >::iterator it; for(it=list.begin();it!=list.end();it++) { if((*it).get() == node) { list.erase(it); break; } } } void Scene::deleteRendererInList(Renderer* renderer) { // remove particle renderer std::vector >::iterator it; for(it=rendererList.begin();it!=rendererList.end();it++) { if((*it).get() == renderer) { rendererList.erase(it); break; } } } void Scene::startPhysic() { this->pScene->simulate(this->dt); this->pScene->flushStream(); } void Scene::clearRenderTargetAndZBuffer() { DXUTGetD3DDevice()->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 0, 0, 0), 1.0f, 0); } //Clear SharedResources void Scene::clearSharedResources() { for(UINT i=0;isharedResourceVector.size();i++) { this->sharedResourceVector.at(i)->setResourceAvailable(false); } } void Scene::setKeyPressed(UINT key, bool bKeyPressed) { this->keyDown[key] = bKeyPressed; } void Scene::setMouseStatus(bool bLeftButtonDown, bool bRightButtonDown,bool bMiddleButtonDown, bool bSideButton1Down, bool bSideButton2Down, int nMouseWheelDelta, int xPos, int yPos) { this->mouseButton[MOUSE_LEFT] = bLeftButtonDown; this->mouseButton[MOUSE_RIGHT] = bRightButtonDown; this->mouseButton[MOUSE_MIDDLE] = bMiddleButtonDown; this->mouseButton[MOUSE_SIDE1] = bSideButton1Down; this->mouseButton[MOUSE_SIDE2] = bSideButton2Down; this->mousePos[0] = xPos; this->mousePos[1] = yPos; this->mouseWheel = nMouseWheelDelta; } Node* Scene::createNode(int type) { return this->createNode(type, this->root, true, false); } Node* Scene::createNode(int type, Node &father) { return this->createNode(type, father, true, false); } Node* Scene::createNode(int type, bool addDefaultRenderer) { return this->createNode(type, this->root, addDefaultRenderer, false); } Node* Scene::createNode(int type, Node &father, bool addDefaultRenderer) { return this->createNode(type, father, addDefaultRenderer, false); } Node* Scene::createReferenceNode(int type, bool addDefaultRenderer) { Node* n=0; Node* newNode = this->createNode(type, *n, addDefaultRenderer, true); newNode->setStandBy(true); return newNode; } Node* Scene::createNode(int type, Node &father, bool addDefaultRenderer, bool isReference) { switch(type) { case NODE_OBJECT3D: { SPTR node(new Object3d); node->setScene(*this); if(!isReference) { father.addChild(node); this->nodeList.push_back(node); } else { this->refObject3dList.push_back(node); } if(addDefaultRenderer) { SPTR renderer(new SimpleMeshRenderer); renderer->setScene(*this); WPTR wn(node); renderer->setNode(wn); node->setRenderer(renderer); renderer->init(); this->rendererList.push_back(renderer); } return node.get(); } break; case NODE_CAMERA: { SPTR node(new Camera); if(!isReference) { father.addChild(node); this->nodeList.push_back(node); } else { this->refCameraList.push_back(node); } node->setScene(*this); return node.get(); } break; case NODE_SOUND: { SPTR node(new SoundNode); if(!isReference) { father.addChild(node); this->nodeList.push_back(node); this->soundNodeList.push_back(node); } else { this->refSoundList.push_back(node); } node->setScene(*this); return node.get(); } case NODE_BOX: { SPTR node(new Box); node->setScene(*this); if(!isReference) { father.addChild(node); this->nodeList.push_back(node); } if(addDefaultRenderer) { SPTR renderer(new SimpleMeshRenderer); renderer->setScene(*this); WPTR wn(node); renderer->setNode(wn); node->setRenderer(renderer); renderer->init(); this->rendererList.push_back(renderer); } return node.get(); } break; case NODE_SPRITE: { SPTR node(new Sprite); node->setScene(*this); if(!isReference) { father.addChild(node); this->nodeList.push_back(node); } else { this->refObject3dList.push_back(node); } if(addDefaultRenderer) { SPTR renderer(new ParticleRenderer); renderer->setScene(*this); WPTR wn(node); renderer->setNode(wn); ((ParticleRenderer*) renderer.get())->setRenderSingleParticle(true); node->setRenderer(renderer); renderer->init(); this->rendererList.push_back(renderer); } return node.get(); } break; case NODE_PARTICLEGROUP: { SPTR node(new ParticleGroup); node->setScene(*this); if(!isReference) { if(&father != this->getRoot()) { this->manager->printToConsole("ERROR: Call of createNode for ParticleGroup only allows rootNode as father!!"); } father.addChild(node); this->nodeList.push_back(node); } if(addDefaultRenderer) { //TODO add ParticleRenderer SPTR renderer(new ParticleRenderer); renderer->setScene(*this); WPTR wn(node); renderer->setNode(wn); node->setRenderer(renderer); renderer->init(); this->rendererList.push_back(renderer); } ((ParticleGroup*) node.get())->setParticleGroup(this->particleGroupCounter); this->particleGroupVector.push_back(node); this->particleGroupCounter++; return node.get(); } break; case NODE_PARTICLEEMITTER: { SPTR node(new ParticleEmitter); node->setScene(*this); if(!isReference) { father.addChild(node); this->nodeList.push_back(node); } return node.get(); } break; } return 0; } void Scene::connectNodeAndRenderer(Node &node, SPTR &renderer) { std::list >::iterator it; SPTR sN; for(it = this->nodeList.begin(); it!=this->nodeList.end();it++) { if((*it).get() == &node) { WPTR wn(*it); renderer->setScene(*this); renderer->setNode(wn); (*it)->setRenderer(renderer); renderer->init(); this->rendererList.push_back(renderer); break; } } } void Scene::OnLostDevice( void* pUserContext ) { SAFE_RELEASE(this->finalImage); SAFE_RELEASE(this->finalImageSurface); SAFE_RELEASE(this->quadMesh); SAFE_RELEASE(this->depthSurface); SAFE_RELEASE(this->preDistortionFinal); SAFE_RELEASE(this->preDistortionFinalSurface); SAFE_RELEASE(this->screenDistortionMapSurface); this->finalImage = NULL; this->finalImageSurface = NULL; this->meshCreated = false; this->quadMesh = NULL; this->preDistortionFinal = NULL; this->preDistortionFinalSurface = NULL; this->screenDistortionMapSurface = NULL; std::list >::iterator nit; for(nit=this->nodeList.begin();nit!=this->nodeList.end();nit++) { (*nit)->OnLostDevice(pUserContext); } for(UINT i=0;isharedResourceVector.size();i++) { this->sharedResourceVector.at(i)->OnLostDevice(); } std::vector >::iterator it; for(it=this->rendererList.begin();it!=this->rendererList.end();it++) { (*it)->OnLostDevice(pUserContext); } } void Scene::OnDestroyDevice( void* pUserContext ) { std::list >::iterator nit; for(nit=this->nodeList.begin();nit!=this->nodeList.end();nit++) { (*nit)->OnDestroyDevice(pUserContext); } std::vector >::iterator it; for(it=this->rendererList.begin();it!=this->rendererList.end();it++) { (*it)->OnDestroyDevice(pUserContext); } this->depthTextureResource = NULL; this->sharedResourceVector.clear(); this->distortionMap1 = NULL; this->distortionMap2 = NULL; this->screenDistortionMap = NULL; this->preDistortionFinal = NULL; } HRESULT Scene::OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { HRESULT hr; //Restore that stuff this->device = pd3dDevice; SAFE_RELEASE(this->quadMesh); SAFE_RELEASE(this->depthSurface); SAFE_RELEASE(this->preDistortionFinal); SAFE_RELEASE(this->preDistortionFinalSurface); SAFE_RELEASE(this->screenDistortionMapSurface); //Textur für endgültiges Bild erzeugen if(!this->finalImage) { //Create Texture V( DXUTGetD3DDevice()->CreateTexture(this->manager->screenWidth, this->manager->screenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &this->finalImage, NULL ) ); //Get Surface for RenderTarget this->finalImage->GetSurfaceLevel(0, &this->finalImageSurface); } //Depth RenderPass this->depthTextureResource = (SharedResourceTexture*) this->getSharedResource(Scene::SR_TEXTURE_VIEWDEPTH); if(!this->depthTextureResource) { this->depthTextureResource = (SharedResourceTexture*) this->createSharedResource(Scene::SR_TEXTURE_VIEWDEPTH); } this->depthTextureResource->getTexture()->GetSurfaceLevel(0, &this->depthSurface); //Load DistortionMaps if(!this->distortionMap1) this->distortionMap1 = this->manager->resManager.loadTexture("./media/textures/heatnoise.tga"); if(!this->distortionMap2) this->distortionMap2 = this->manager->resManager.loadTexture("./media/textures/heatnoise2.tga"); if(!this->screenDistortionMap) { SharedResourceTexture* distMap = (SharedResourceTexture*) this->createSharedResource(Scene::SR_TEXTURE_DISTORTION); this->screenDistortionMap = distMap->getTexture(); this->screenDistortionMap->GetSurfaceLevel(0, &this->screenDistortionMapSurface); } if(!this->preDistortionFinal) { //Create Texture V( DXUTGetD3DDevice()->CreateTexture(this->manager->screenWidth, this->manager->screenHeight, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &this->preDistortionFinal, NULL ) ); //Get Surface for RenderTarget this->preDistortionFinal->GetSurfaceLevel(0, &this->preDistortionFinalSurface); } this->defaultRenderPass.setRenderTarget(this->finalImageSurface); this->depthRenderPass.setRenderTarget(this->depthSurface); std::list >::iterator nit; for(nit=this->nodeList.begin();nit!=this->nodeList.end();nit++) { (*nit)->OnResetDevice(pd3dDevice, pBackBufferSurfaceDesc, pUserContext); } std::vector >::iterator it; for(it=this->rendererList.begin();it!=this->rendererList.end();it++) { (*it)->OnResetDevice(pd3dDevice, pBackBufferSurfaceDesc, pUserContext); } return S_OK; } Vector Scene::getSunDirection() { return this->sunDirection; } void Scene::setSunDirection(Vector &v) { this->sunDirection.x = v.x; this->sunDirection.y = v.y; this->sunDirection.z = v.z; this->sunDirection.normalize(); } D3DXMATRIX Scene::getIdentityMatrix() { return this->identMatrix; } D3DXMATRIX Scene::getWorldMatrix() { return this->worldMatrix; } D3DXMATRIX Scene::getViewMatrix() { return *this->activeRenderPass->getViewMatrix(); } D3DXMATRIX Scene::getProjectionMatrix() { return *this->activeRenderPass->getProjectionMatrix(); } void Scene::setTrigger(int type, float time) { SPTR t(new Trigger(type, time)); this->triggerList.push_back(t); std::sort(this->triggerList.begin(), this->triggerList.end(), triggerSortFunction()); } void Scene::setTrigger(int type, Node *node, float time) { SPTR sN = this->getSmartPointer(node); SPTR t(new Trigger(type, sN, time)); this->triggerList.push_back(t); std::sort(this->triggerList.begin(), this->triggerList.end(), triggerSortFunction()); } void Scene::setTrigger(int type, Node *node, Node* secondNode, float time) { SPTR sN = this->getSmartPointer(node); SPTR secondSN = this->getSmartPointer(secondNode); SPTR t(new Trigger(type, sN, secondSN, time)); this->triggerList.push_back(t); std::sort(this->triggerList.begin(), this->triggerList.end(), triggerSortFunction()); } void Scene::setTrigger(int type, Node *node, Node* secondNode, Vector normal, float time) { SPTR sN = this->getSmartPointer(node); SPTR secondSN = this->getSmartPointer(secondNode); SPTR t(new Trigger(type, sN, secondSN, normal, time)); this->triggerList.push_back(t); std::sort(this->triggerList.begin(), this->triggerList.end(), triggerSortFunction()); } SPTR Scene::getSmartPointer(Node *node) { std::list >::iterator it; for(it = this->nodeList.begin(); it!=this->nodeList.end();it++) { if((*it).get() == node) { break; } } if(it==this->nodeList.end()) { this->manager->printToConsole("NODE NOT FOUND IN LIST!!!"); } return (*it); } void Scene::executeTrigger(SPTR trigger) { Trigger *t = trigger.get(); switch(t->getType()) { case this->TRIGGER_UNSETSTANDBY: if(!t->getNode()->isA(Scene::NODE_SOUND)) { t->getNode()->setStandBy(false); } else { t->getNode()->setStandBy(false); ((SoundNode*) t->getNode().get())->play(); } break; case this->TRIGGER_KILLNODE: t->getNode()->killMe(); break; case this->TRIGGER_SETDETAIL: break; } } void Scene::deleteNode(Node* node) { std::list >::iterator it; for(it=this->zombieNodeList.begin();it!=this->zombieNodeList.end();it++) { if((*it).get() == node) { return; } } SPTR sn = this->getSmartPointer(node); this->zombieNodeList.push_back(sn); } void Scene::setContactReport(NxUserContactReport *_contactReport) { this->contactReport = _contactReport; ((UserContactReport*) this->contactReport)->setScene(this); } void Scene::setTriggerReport(NxUserTriggerReport *_triggerReport) { this->triggerReport = _triggerReport; ((UserTriggerReport*) this->triggerReport)->setScene(this); } void Scene::setNotifyReport(NxUserNotify* _notifyReport) { this->notifyReport = _notifyReport; ((UserNotify*) this->notifyReport)->setScene(this); } void Scene::setLight(Vector direction) { //set ambient light: DXUTGetD3DDevice()->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB(120,120,120) ); // Fill in a light structure defining our light D3DLIGHT9 light; ZeroMemory( &light, sizeof(D3DLIGHT9) ); light.Type = D3DLIGHT_DIRECTIONAL; light.Diffuse.r = 1.0f; light.Diffuse.g = 1.0f; light.Diffuse.b = 1.0f; light.Diffuse.a = 1.0f; light.Range = 1000.0f; // Create a direction for our light - it must be normalized D3DXVECTOR3 vecDir; vecDir = D3DXVECTOR3(direction.x,direction.y,direction.z); D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir ); // Tell the device about the light and turn it on DXUTGetD3DDevice()->SetLight( 0, &light ); DXUTGetD3DDevice()->LightEnable( 0, TRUE ); } std::list >* Scene::getParticleList() { return &this->particleList; } void Scene::addToParticleList(Node *node) { SPTR sn = this->getSmartPointer(node); this->particleList.push_back(sn); } ParticleGroup* Scene::getParticleGroup(int id) { ParticleGroup* pg; for(UINT i=0;iparticleGroupVector.size();i++) { pg = (ParticleGroup*) this->particleGroupVector.at(i).get(); if(pg->getParticleGroup()==id) { return pg; } } return NULL; } SharedResource* Scene::createSharedResource(int id) { switch(id) { case this->SR_TEXTURE_VIEWDEPTH: { SPTR srt(new SharedResourceTexture); SharedResourceTexture* t = (SharedResourceTexture*) srt.get(); t->setResourceIdentifier(id); t->createTexture(this->manager->screenWidth, this->manager->screenHeight, D3DFMT_A16B16G16R16F, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT); this->sharedResourceVector.push_back(srt); return t; } break; case this->SR_TEXTURE_DISTORTION: { SPTR srt(new SharedResourceTexture); SharedResourceTexture* t = (SharedResourceTexture*) srt.get(); t->setResourceIdentifier(id); t->createTexture(this->manager->screenWidth, this->manager->screenHeight, D3DFMT_A16B16G16R16F, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT); this->sharedResourceVector.push_back(srt); return t; } break; } return NULL; } SharedResource* Scene::getSharedResource(int id) { for(UINT i=0;isharedResourceVector.size();i++) { if(this->sharedResourceVector.at(i)->getResourceIdentifier()==id) { SharedResource* sr = this->sharedResourceVector.at(i).get(); return sr; } } return NULL; } int* Scene::getMousePos() { return this->mousePos; } void Scene::OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext ) { } void Scene::createQuadMesh() { HRESULT hr; //Create a quad for rendering to screen if(SUCCEEDED( D3DXCreateMeshFVF(2, 4, D3DXMESH_MANAGED, this->FVF_Flags, this->device, &this->quadMesh)) ) { //lock vertex buffer Vector ecken[4]; Vertex* pVertices; V( this->quadMesh->LockVertexBuffer( 0, (void**)&pVertices ) ); ecken[0] = Vector(-1.0f, 1.0f, 0.0f); ecken[1] = Vector(-1.0f, -1.0f, 0.0f); ecken[2] = Vector(1.0f, -1.0f, 0.0f); ecken[3] = Vector(1.0f, 1.0f, 0.0f); pVertices[0] = Vertex(ecken[0], 0.0f, 0.0f); pVertices[1] = Vertex(ecken[1], 0.0f, 1.0f); pVertices[2] = Vertex(ecken[2], 1.0f, 1.0f); pVertices[3] = Vertex(ecken[3], 1.0f, 0.0f); //unlock vertex buffer V( this->quadMesh->UnlockVertexBuffer() ); // fill the indices: WORD* pIndices = NULL; this->quadMesh->LockIndexBuffer( 0, (void**)&pIndices ); pIndices[0] = (WORD) 0; pIndices[1] = (WORD) 2; pIndices[2] = (WORD) 1; pIndices[3] = (WORD) 0; pIndices[4] = (WORD) 3; pIndices[5] = (WORD) 2; this->quadMesh->UnlockIndexBuffer(); this->meshCreated=true; } else { this->manager->printToConsole("ERROR creating mesh!"); } } void Scene::renderFinalImage(ID3DXEffect* fadeEffect) { HRESULT hr = 0; if(!this->meshCreated) { this->createQuadMesh(); } UINT cPass; V( fadeEffect->SetFloat("alpha", this->sceneAlpha) ); V( fadeEffect->SetTexture("sceneRendering", this->finalImage) ); V( fadeEffect->CommitChanges() ); V( fadeEffect->SetTechnique("fade") ); V( fadeEffect->Begin( &cPass, 0 ) ); V( fadeEffect->BeginPass( 0 ) ); V( this->device->BeginScene() ); V( this->device->SetTexture(0, this->finalImage) ); V( this->quadMesh->DrawSubset(0) ); V( this->device->SetTexture(0, 0) ); V( this->device->EndScene() ); V( fadeEffect->EndPass() ); V( fadeEffect->End() ); } int Scene::getActivePassId() { if(this->activeRenderPass==NULL) { return this->PASS_NORMAL; } else { return this->activeRenderPass->getRenderPassId(); } } void Scene::setActiveRenderPass(RenderPass &_activePass) { this->activeRenderPass = &_activePass; this->activeRenderPass->calculateMatrices(); } void Scene::startRenderPasses() { //char temp[100]; HRESULT hr; bool tempDistortionPass = false; //Reset values this->needDepthPass = false; this->needRaytracePass = false; this->needDistortionPass = false; this->heatHazeParticleRendererList.clear(); //DefaultRenderPass aktivieren this->defaultRenderPass.setViewMatrix(*this->activeCamera->getViewMatrix()); this->defaultRenderPass.setProjectionMatrix(*this->activeCamera->getProjectionMatrix()); this->setActiveRenderPass(this->defaultRenderPass); //Gegen Frustum Cullen this->doFrustumCulling(); //Ueberprufen ob heatHaze benötigt wird, defaultRenderPass...renderTarget umstellen! if(this->needDistortionPass) { tempDistortionPass = true; this->defaultRenderPass.setRenderTarget(this->preDistortionFinalSurface); } //Ueberpruefen welche Passes gerendert werden if(this->needDepthPass && this->useDepthImposter) { //this->depthRenderPass.setRenderTarget(this->finalImageSurface); //this->manager->printToConsole("DepthPass Needed"); this->depthRenderPass.setViewMatrix(*this->activeCamera->getViewMatrix()); this->depthRenderPass.setProjectionMatrix(*this->activeCamera->getProjectionMatrix()); this->setActiveRenderPass(this->depthRenderPass); this->activeRenderPass->executePass(); this->depthTextureResource->setResourceAvailable(true); } if(this->needRaytracePass) { //Nächster Raytracerenderer finden Vector objPos; Vector camPos; Vector dist; float minDistance=9999999; float distance=0; RaytraceRenderer* nearestRenderer = NULL; camPos = this->activeCamera->getAbsolutePosition(); for(UINT i=0;iraytraceRendererList.size();i++) { objPos = this->raytraceRendererList.at(i)->myNode.lock().get()->getAbsolutePosition(); distance = (camPos-objPos).length(); if(minDistance>distance) { minDistance = distance; nearestRenderer = this->raytraceRendererList.at(i); } } //RaytracePass aktivieren bool oldFrustum = this->enableFrustumCulling; this->raytraceRenderPass.setProjectionMatrix(*nearestRenderer->getCubeMapProjectionMatrix()); for(int i=0;i<6;i++) { this->raytraceRenderPass.setViewMatrix(nearestRenderer->getCubeMapView(i)); this->raytraceRenderPass.setRenderTarget(nearestRenderer->getCubeMapSurface(i)); this->setActiveRenderPass(this->raytraceRenderPass); if(i==2) this->enableFrustumCulling = false ; this->activeRenderPass->executePass(); if(i==2) this->enableFrustumCulling = oldFrustum; SAFE_RELEASE(this->raytraceRenderPass.renderTarget); //BlurThatStuff //nearestRenderer->blurDepthPass(i); } RaytraceRenderer* tempRenderer; for(UINT i=0;iraytraceRendererList.size();i++) { tempRenderer = this->raytraceRendererList.at(i); if(tempRenderer!=nearestRenderer && tempRenderer->needsUpdate()) { //this->manager->printToConsole("UPDATING OTHER RAYTRACER!"); this->raytraceRenderPass.setProjectionMatrix(*tempRenderer->getCubeMapProjectionMatrix()); for(int i=0;i<6;i++) { this->raytraceRenderPass.setViewMatrix(tempRenderer->getCubeMapView(i)); this->raytraceRenderPass.setRenderTarget(tempRenderer->getCubeMapSurface(i)); this->setActiveRenderPass(this->raytraceRenderPass); if(i==2) this->enableFrustumCulling = false ; this->activeRenderPass->executePass(); if(i==2) this->enableFrustumCulling = oldFrustum; SAFE_RELEASE(this->raytraceRenderPass.renderTarget); } } } //Cullen, Nodes rendern...gegen die 6 flächen.... //Clear Raytracerlist this->raytraceRendererList.clear(); } FSOUND_Update(); //Update sount because of jittering //DefaultRenderPass aktivieren this->setActiveRenderPass(this->defaultRenderPass); this->activeRenderPass->executePass(); //if(this->needDistortionPass) { if(tempDistortionPass) { //Distortion if(!this->meshCreated) { this->createQuadMesh(); } ID3DXEffect* particleEffect; particleEffect = this->manager->getEffect(GameManager::EFFECT_DEPTHIMP); //Distortion Map rendern this->device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); this->device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); this->device->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); this->device->SetRenderState( D3DRS_LIGHTING, FALSE ); this->device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); this->device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); this->device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); this->device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); this->device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); this->device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); this->device->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); this->device->SetRenderTarget(0, this->screenDistortionMapSurface); this->device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 128, 128, 128), 1.0f, 0); V( particleEffect->SetTexture("distortionMap1", this->distortionMap1) ); V( particleEffect->SetTexture("distortionMap2", this->distortionMap2) ); V( particleEffect->SetTexture("screenDistortionMap", this->screenDistortionMap) ); V( particleEffect->CommitChanges() ); for(UINT i=0;iheatHazeParticleRendererList.size();i++) { this->heatHazeParticleRendererList.at(i)->renderHeatHaze(); } this->device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); //Bild auf finalRenderPass rendern this->device->SetRenderTarget(0, this->finalImageSurface); this->device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(0, 0, 0, 0), 1.0f, 0); //Bild in finalImageSurface kopieren UINT cPass; V( particleEffect->SetTexture("preDistortion", this->preDistortionFinal) ); V( particleEffect->CommitChanges() ); V( particleEffect->SetTechnique("HeatHazeCopy") ); V( particleEffect->Begin( &cPass, 0 ) ); V( particleEffect->BeginPass( 0 ) ); V( this->device->BeginScene() ); V( this->quadMesh->DrawSubset(0) ); V( this->device->SetTexture(0, 0) ); V( this->device->EndScene() ); V( particleEffect->EndPass() ); V( particleEffect->End() ); this->device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); this->device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); //Reset default RenderTarget this->defaultRenderPass.setRenderTarget(this->finalImageSurface); } } void Scene::updateSoundNodeVolume() { std::list >::iterator it; for(it = this->soundNodeList.begin();it!=this->soundNodeList.end();it++) { ((SoundNode*) it->get())->setSceneAlpha(this->sceneAlpha); } if(this->bgSoundChannel!=-1 && !this->muteMusic) { FSOUND_SetVolume(this->bgSoundChannel, (int)(255*this->bgSoundVolume*this->sceneAlpha)); } } LPD3DXMESH Scene::getQuadMesh() { if(!this->meshCreated) { this->createQuadMesh(); } return this->quadMesh; } void Scene::setBackgroundSoundMute(bool _muteMusic) { this->muteMusic = _muteMusic; if(!this->muteMusic) { if(this->bgSoundChannel!=-1) { FSOUND_SetVolume(this->bgSoundChannel, (int)(255*this->bgSoundVolume*this->sceneAlpha)); } } else { if(this->bgSoundChannel!=-1) { FSOUND_SetVolume(this->bgSoundChannel, 0); } } } bool Scene::getBackgroundSoundMute() { return this->muteMusic; } void Scene::setBackgroundSound(std::string filename) { this->bgMusicStream = FSOUND_Stream_Open(filename.c_str(), FSOUND_LOOP_NORMAL, 0, 0); } void Scene::setBackgroundSoundVolume(float vol) { this->bgSoundVolume = vol; if(this->bgSoundChannel!=-1) { if(!this->muteMusic) { FSOUND_SetVolume(this->bgSoundChannel, (int)(255*this->bgSoundVolume)); } else { FSOUND_SetVolume(this->bgSoundChannel, 0); } } } void Scene::playBackgroundSound() { if(this->bgMusicStream!=NULL) { this->bgSoundChannel = FSOUND_Stream_Play(FSOUND_FREE, this->bgMusicStream); if(!this->muteMusic) { FSOUND_SetVolume(this->bgSoundChannel, (int)(255*this->bgSoundVolume)); } else { FSOUND_SetVolume(this->bgSoundChannel, 0); } } }