#include "dxstdafx.h" #include "resource.h" #include "RaytraceRenderer.h" #include "Scene.h" #include "GameManager.h" #include "NodeFilter.h" #include RaytraceRenderer::RaytraceRenderer(void) : Renderer() { srand( (unsigned)time( NULL ) ); this->nextUpdate = -1000.0f; g_fFresnelFactor = 1.0f; g_fFresnelFactor = 0.05f; g_fRefractionIndex = 0.95f; g_iNumberOfIteration = 10; g_bUseDistanceImpostors = true; this->counter = 0; this->setRenderPriority(30);//40); this->rendererType |= Renderer::RENDERER_RAYTRACE; g_pEffect = NULL; // D3DX effect interface g_pRenderTargetSurfaceOld = NULL; // Store the original Screen's surface g_pDepthStencilSurfaceOld = NULL; // Store the original Screen's DSS // Cube map textures g_pRoomColorDistCubeMapTexture = NULL; // CubeMap for store: Color + Distance //g_pRoomUVCubeMapTexture = NULL; // CubeMap for store: UV + ObjectID g_pCubeMapDepthStencilSurface = NULL; // Depth-stencil buffer for rendering to cube texture g_pDepthStencilSurface = NULL; // Depth-stencil buffer for Room Texture g_bInitialization = true; // Initialization is in progress g_bUseDistanceImpostors = true; // Use distance impostor method D3DXMatrixPerspectiveFovLH( &this->cubeMapProjectionMat, D3DX_PI * 0.5f, 1.0f, 0.001f, 10000.0f ); } RaytraceRenderer::~RaytraceRenderer(void) { SAFE_RELEASE( g_pRoomColorDistCubeMapTexture ); //SAFE_RELEASE( g_pRoomUVCubeMapTexture ); SAFE_RELEASE( g_pDepthStencilSurface ); SAFE_RELEASE( g_pCubeMapDepthStencilSurface ); } void RaytraceRenderer::setFresnelFactor(float _fresnel) { g_fFresnelFactor = _fresnel; } void RaytraceRenderer::setRefractionIndex(float _refraction) { g_fRefractionIndex = _refraction; } HRESULT CALLBACK RaytraceRenderer::OnCreateDevice( IDirect3DDevice9* asdf, const D3DSURFACE_DESC* pBackBufferSurfaceDesc ) { return S_OK; } IDirect3DTexture9* RaytraceRenderer::CreateTexture( int size, D3DFORMAT Format ) { HRESULT hr; IDirect3DTexture9* pTexture; V( this->device->CreateTexture( size, size, 1, D3DUSAGE_RENDERTARGET, Format, D3DPOOL_DEFAULT, &pTexture, NULL ) ); return pTexture; } IDirect3DCubeTexture9* RaytraceRenderer::CreateCubeTexture( int size, D3DFORMAT Format ) { HRESULT hr; IDirect3DCubeTexture9* pCubeTexture; V( this->device->CreateCubeTexture( size, 1, D3DUSAGE_RENDERTARGET, Format, D3DPOOL_DEFAULT, &pCubeTexture, NULL ) ); return pCubeTexture; } IDirect3DSurface9* RaytraceRenderer::CreateDepthStencilSurface( int size ) { HRESULT hr; IDirect3DSurface9* pDSSurface; V( this->device->CreateDepthStencilSurface( size, size, DXUTGetDeviceSettings().pp.AutoDepthStencilFormat, D3DMULTISAMPLE_NONE, 0, TRUE, &pDSSurface, NULL ) ); return pDSSurface; } HRESULT RaytraceRenderer::OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) { this->myScene->manager->printToConsole("on resetdevice in RaytraceRenderer called!"); HRESULT hr; if( g_pEffect ) V_RETURN( g_pEffect->OnResetDevice() ); // Create textures g_pRoomColorDistCubeMapTexture = CreateCubeTexture( CUBEMAP_SIZE, D3DFMT_A16B16G16R16F ); // Because 32 can not use linear filtering. g_pCubeMapDepthStencilSurface = CreateDepthStencilSurface( CUBEMAP_SIZE ); g_bInitialization = true; RenderSceneInitialization(); return S_OK; } void RaytraceRenderer::render() { HRESULT hr; UINT cPass; D3DXMATRIXA16 mScaleLightObjSize, mWorldViewLight, mWorldViewCausticGenerator; switch(this->myScene->getActivePassId()) { case Scene::PASS_NORMAL: case Scene::PASS_RAYTRACE: this->myScene->specialRenderer = this; if ( g_bInitialization ) { RenderSceneInitialization(); g_bInitialization = false; } this->counter++; if( SUCCEEDED( this->device->BeginScene() ) ) { D3DXMATRIX rotMat; D3DXMATRIX invTrans; D3DXMATRIX worldMat; D3DXMATRIX worldViewMat; D3DXMATRIX worldViewProjMat; Vector camPos; Vector nodePos; Node* node = this->myNode.lock().get(); //Build world, worldView and worldViewProjection Matrices worldMat = *node->getWorldMatrix(); D3DXMatrixMultiply(&worldViewMat, &worldMat, &this->myScene->getViewMatrix()); D3DXMatrixMultiply(&worldViewProjMat, &worldViewMat, &this->myScene->getProjectionMatrix()); //Build rot and translation Matrix nodePos = node->getAbsolutePosition(); D3DXMatrixTranslation(&invTrans, -nodePos.x, -nodePos.y, -nodePos.z); D3DXMatrixMultiply(&rotMat, &worldMat, &invTrans); //Get Camera Postition camPos = this->myScene->getActiveCamera()->getAbsolutePosition(); float camPosF[3]; camPosF[0] = camPos.x; camPosF[1] = camPos.y; camPosF[2] = camPos.z; //Transfer parameter V( this->device->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ) ); V( g_pEffect->SetTexture( "g_txRoomColorDistanceCubeMap", g_pRoomColorDistCubeMapTexture ) ); if(this->myScene->useRaytracer) { V( g_pEffect->SetTechnique( "RefractObject" ) ); } else { V( g_pEffect->SetTechnique( "RefractObjectClassic" ) ); } V( g_pEffect->SetMatrix( "g_mWorldViewProjection", &worldViewProjMat ) ); V( g_pEffect->SetMatrix( "g_mWorldView", &worldViewMat ) ); V( g_pEffect->SetMatrix( "g_mWorldCenterObject", &worldMat ) ); V( g_pEffect->SetMatrix( "g_mCenterObjectRot", &rotMat) ); V( g_pEffect->SetFloatArray( "g_vCameraPos3f", camPosF, 3 ) ); V( g_pEffect->SetInt( "g_iNumberOfIteration", g_iNumberOfIteration)); V( g_pEffect->SetFloat( "g_fFresnelFactor", g_fFresnelFactor)); V( g_pEffect->SetFloat( "g_fRefractionIndex", g_fRefractionIndex )); V( g_pEffect->Begin( &cPass, 0 ) ); V( g_pEffect->BeginPass( 0 ) ); V( g_pEffect->CommitChanges() ); Object3d* obj = (Object3d*) node; for(UINT i = 0; i < obj->Materials.size(); i++) { (*obj->getMesh())->DrawSubset(i); } V( g_pEffect->EndPass() ); V( g_pEffect->End() ); this->device->EndScene(); } this->myScene->specialRenderer = NULL; break; case Scene::PASS_DEPTH: this->renderDepth(); break; } } void RaytraceRenderer::RenderSceneInitialization() { HRESULT hr; // Bind textures V( g_pEffect->SetTexture( "g_txRoomColorDistanceCubeMap", g_pRoomColorDistCubeMapTexture ) ); } void RaytraceRenderer::OnLostDevice(void* pUserContext ) { this->myScene->manager->printToConsole("OnLostDevice called from RaytraceRenderer"); if( g_pEffect ) g_pEffect->OnLostDevice(); SAFE_RELEASE( g_pRoomColorDistCubeMapTexture ); SAFE_RELEASE( g_pDepthStencilSurface ); SAFE_RELEASE( g_pCubeMapDepthStencilSurface ); } void RaytraceRenderer::OnDestroyDevice(void* pUserContext ) { this->myScene->manager->printToConsole("OnDestroyDevice called from RaytraceRenderer"); SAFE_RELEASE( g_pEffect ); } void RaytraceRenderer::init() { SPTR sn = this->myNode.lock(); g_pEffect = this->myScene->manager->getEffect(GameManager::EFFECT_RAYTRACE); if(!g_pEffect) { g_pEffect = this->myScene->manager->loadEffect(GameManager::EFFECT_RAYTRACE, L"shaders/RayTraceEffects.obj"); } // Create textures g_pRoomColorDistCubeMapTexture = CreateCubeTexture( CUBEMAP_SIZE, D3DFMT_A16B16G16R16F ); // Because 32 can not use linear filtering. g_pCubeMapDepthStencilSurface = CreateDepthStencilSurface( CUBEMAP_SIZE ); g_bInitialization = true; RenderSceneInitialization(); } void RaytraceRenderer::setCurrentTexture(IDirect3DTexture9* texture) { HRESULT hr; V( g_pEffect->SetTexture( "g_txCurrentTexture", texture) ); V( g_pEffect->CommitChanges() ); } bool RaytraceRenderer::isLowerThan(Renderer* renderer) { if(this->getRenderPriority() == renderer->getRenderPriority()) { SPTR node1 = this->myNode.lock(); Object3d *myObj = (Object3d *) (node1.get()); SPTR node2 = renderer->myNode.lock(); Object3d *otherObj = (Object3d *) (node2.get()); return myObj->camDistance>otherObj->camDistance; } return this->getRenderPriority() < renderer->getRenderPriority(); } D3DXMATRIX* RaytraceRenderer::getCubeMapProjectionMatrix() { return &this->cubeMapProjectionMat; } D3DXMATRIX RaytraceRenderer::getCubeMapView(int nbView) { D3DXMATRIXA16 invWorldPos; Vector vec = this->myNode.lock()->getAbsolutePosition(); D3DXMatrixTranslation(&invWorldPos, -vec.x, -vec.y, -vec.z); return invWorldPos*DXUTGetCubeMapViewMatrix(nbView); } IDirect3DSurface9* RaytraceRenderer::getCubeMapSurface(int nbView) { HRESULT hr; V( g_pRoomColorDistCubeMapTexture->GetCubeMapSurface( (D3DCUBEMAP_FACES)nbView, 0, &this->pCubeMapDistSurf ) ); return this->pCubeMapDistSurf; } void RaytraceRenderer::setNumberOfIterations(int _nbIteration) { this->g_iNumberOfIteration = _nbIteration; } bool RaytraceRenderer::needsUpdate() { if(this->nextUpdate==-1000.0f) { //First Time - Render RefractionMap this->renderRefractionMap(); this->nextUpdate = 4 + ((((float) rand())/RAND_MAX)-0.5f)*2*2; return true; //First Update } else { this->nextUpdate-= this->myScene->getDeltaTime(); if(this->nextUpdate<=0) { this->nextUpdate = 4 + ((((float) rand())/RAND_MAX)-0.5f)*2*2; return true; } return false; } } void RaytraceRenderer::blurDepthPass(int face) { //In CubeMap steht tiefe /*HRESULT hr; UINT cPass; IDirect3DSurface9* depthMap = this->getCubeMapSurface(face); IDirect3DSurface9* tempDepthMap; V( g_pTempRoomColorDistCubeMapTexture->GetCubeMapSurface( (D3DCUBEMAP_FACES)face, 0, &tempDepthMap ) ); //tempTextur mit horizontalem Pass this->device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); this->device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); V( this->g_pEffect->SetTexture("g_txTempRoomColorDistanceCubeMap", this->g_pTempRoomColorDistCubeMapTexture) ); //V( this->g_pEffect->SetTexture("g_txCurrentTexture", depthMap) ); //V( this->g_pEffect->SetInt("face", face) ); V( this->g_pEffect->CommitChanges()); V( this->device->SetRenderTarget(0, tempDepthMap) ); V( this->g_pEffect->SetTechnique("gaussHorizontal") ); V( g_pEffect->Begin( &cPass, 0 ) ); V( g_pEffect->BeginPass( 0 ) ); V( g_pEffect->CommitChanges() ); this->myScene->getQuadMesh()->DrawSubset(0); V( g_pEffect->EndPass() ); V( g_pEffect->End() ); //V( this->g_pEffect->SetTexture("g_txCurrentTexture", tempDepthMap) ); V( this->g_pEffect->CommitChanges()); V( this->device->SetRenderTarget(0, depthMap) ); V( this->g_pEffect->SetTechnique("gaussVertikal") ); V( g_pEffect->Begin( &cPass, 0 ) ); V( g_pEffect->BeginPass( 0 ) ); V( g_pEffect->CommitChanges() ); this->myScene->getQuadMesh()->DrawSubset(0); V( g_pEffect->EndPass() ); V( g_pEffect->End() ); this->device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); this->device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); SAFE_RELEASE(depthMap); SAFE_RELEASE(tempDepthMap);*/ //alte Textur mit vertical pass } void RaytraceRenderer::renderRefractionMap() { //Todo RefractionMap } void RaytraceRenderer::renderDepth() { SPTR node = this->myNode.lock(); Object3d *obj = (Object3d *) (node.get()); UINT cPass; HRESULT hr; ID3DXEffect* effect; effect = this->myScene->manager->getEffect(GameManager::EFFECT_DEPTHIMP); if(obj!=NULL && obj->isModelLoaded()) { V( effect->SetMatrix("g_mWorldViewProjection", &this->myScene->activeRenderPass->getWorldViewProjectionMatrix(obj->getWorldMatrix())) ); V( effect->SetTechnique("DepthPass") ); V( effect->CommitChanges() ); this->device->BeginScene(); V( effect->Begin( &cPass, 0 ) ); V( effect->BeginPass( 0 ) ); if (obj->Materials.size() == 0) { this->device->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); this->device->SetRenderState( D3DRS_LIGHTING, FALSE ); this->device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); if(obj->isPMesh()) { (*obj->getProgressiveMesh())->DrawSubset(0); } else { (*obj->getMesh())->DrawSubset(0); } this->device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); } else { this->device->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); this->device->SetRenderState( D3DRS_LIGHTING, TRUE ); this->device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); // bilinear texture filtering: this->device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); this->device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); this->device->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); for(UINT i = 0; i < obj->Materials.size(); i++) { this->device->SetMaterial( &obj->Materials[i] ); this->device->SetTexture(0, obj->Textures[i]); if(obj->isPMesh()) { (*obj->getProgressiveMesh())->DrawSubset(i); } else { (*obj->getMesh())->DrawSubset(i); } } //deactivate textures this->device->SetTexture(0, 0); } V( effect->EndPass() ); V( effect->End() ); this->device->EndScene(); } }