/*************************************************************************/ /* File : MyVRManager.h */ /* */ /* Author : Virtools */ /* */ /*************************************************************************/ #include "CKAll.h" #include "VRAll.h" #include "MyVRManager.h" /////////////////////////////////////////////////////////////////////////// MyVRManager::MyVRManager(CKContext *Context, CKBOOL &oError) : VRBaseManager(Context,MyVRManagerGUID,"MyVRManager") { oError = FALSE; // Notes: // + m_VRContext will be in Virtools Dev that do not support the // VRSdk for now. In this case, we don't register our manager. // + Our manager is meaningfull only for the VRPlayer. // + If you intend to compile your dll in the manager directory : // * in the constructor, register your manager only in the CKContext. // * in OnCKInit, register it to the VRContext. if ( !m_VRContext || (m_VRContext->GetExecutionMode()!=VREXECUTION_VRPLAYER) ) { oError = TRUE; return; } // Register for Virtools events m_Context->RegisterNewManager(this); // Register for VR events m_VRContext->RegisterNewManager(this); // Initialization m_level = NULL; m_BlendMaterial = NULL; m_OriginalViewMaterial = NULL; m_BlendCamera = NULL; } /////////////////////////////////////////////////////////////////////////// MyVRManager::~MyVRManager() { // Nothing to clear } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::OnParse() { CKPathManager* pm = m_Context->GetPathManager(); // Here, we read our tokens. // Get Blending Size. This field are not required, they can use default values //m_VRContext->GetToken("BlendWidth", &m_BlendWidth, 512); //m_VRContext->GetToken("BlendWidth", &m_BlendHeight, 512); // Here, get Additionnal token if needed m_TokenOK = TRUE; return VR_OK; } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::OnViewCreate(VRView* iView) { // Get Sub Tokens CKBOOL SubTokenOK = TRUE; /////////////////////////////////////////////////////////////////////// // Activate Blend only when a "BlendingType" SubToken is specified XString Blending; if ( m_VRContext->GetSubToken(iView->UserTokens, "BlendingType", &Blending) != VR_OK ){ m_VRContext->OutputToLog(0, "Blending Warn - Blending will be disabled on view %d.\n", iView->ID); m_VRContext->DeActivateWarp(iView); return VR_OK; } if ( Blending != "TextureBlending" ){ m_VRContext->OutputToLog(0, "Blending Warn - Blending will be disabled on view %d.\n", iView->ID); m_VRContext->DeActivateWarp(iView); return VR_OK; } // General token must be set if ( !m_TokenOK ) { m_VRContext->OutputToLog(0, "Blending Warn - Blending will be disabled on view %d.\n", iView->ID); m_VRContext->DeActivateWarp(iView); return VR_OK; } /////////////////////////////////////////////////////////////////////// // Get Other Sub Tokens // Get Image file MyWarpData* ViewData = new MyWarpData(); SubTokenOK &= (m_VRContext->GetSubToken(iView->UserTokens, "BlendTexture", &ViewData->Texturename, "filter.tga")== VR_OK); // Test if Blending image is found CKPathManager* pm = m_Context->GetPathManager(); if ( pm->ResolveFileName(ViewData->Texturename, BITMAP_PATH_IDX) < 0 ) { m_VRContext->OutputToLog(0, "Blending Warn - File image load failed: %s - Blending will be disabled.\n", ViewData->Texturename); m_VRContext->DeActivateWarp(iView); return VR_OK; } /////////////////////////////////////////////////////////////////////// // Memorize TextureName on the view m_VRContext->SetViewData(iView, (void*) ViewData); /////////////////////////////////////////////////////////////////////// // Create the Blending environment if ( CreateBlendingEnvironment(iView) != VR_OK ) { m_VRContext->OutputToLog(0, "Blending Err - Could not create Blending environment: %s.\n"); delete (ViewData); return VR_OK; } /////////////////////////////////////////////////////////////////////// // Activate Warp WarpInfo WInfo; WInfo.UseWarpTexture = TRUE; WInfo.Width = iView->Width; WInfo.Height = iView->Height; if ( m_VRContext->ActivateWarp(iView, &WInfo) != VR_OK ) { m_VRContext->OutputToLog(0, "Blending Err - Could not activate Blending.\n"); delete (ViewData); return VR_OK; } return VR_OK; } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::OnViewDelete(VRView* iView) { // We clear the user data we created if ( iView->UserData ) { // Verify we are indeed in SampleWarp configuration XString Blending; if ( m_VRContext->GetSubToken(iView->UserTokens, "BlendingType", &Blending) != VR_OK ) return VR_OK; if ( Blending != "TextureBlending" ) return VR_OK; // It is our data, delete it. MyWarpData* ViewData = (MyWarpData*) m_VRContext->SetViewData(iView, NULL); delete (ViewData); m_VRContext->DeActivateWarp(iView); } return VR_OK; } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::OnViewWarp(CKRenderContext* rc, VRView* iView) { // We add objects to Level if(!m_level){ m_level = m_Context->GetCurrentLevel(); m_level->AddObject(m_BlendTexture); m_level->AddObject(m_BlendMaterial); m_level->AddObject(m_OriginalViewMaterial); m_level->AddObject(m_BlendEntity); m_level->AddObject(m_OriginalViewTargetSprite); m_level->AddObject(m_BlendCamera); } ////////////////////////////////////////////////////////////////////////// // This commented code shows you how to copy the backbuffer to a texture // when you are not using the warping texture to keep the antialiasing effect. /* if ( !iView->WarpTexture ) { VxRect SrcRect, DestRect; SrcRect.left = (float) iView->PositionX; SrcRect.top = (float) iView->PositionY; SrcRect.right = (float) iView->PositionX + iView->Width; SrcRect.bottom = (float) iView->PositionY + iView->Height; DestRect.left = 0; DestRect.top = 0; DestRect.right = (float) iView->Width; DestRect.bottom = (float) iView->Height; m_BlendTexture->CopyContext(rc, &SrcRect, &DestRect); m_BlendMaterial->SetTexture(m_BlendTexture); } */ ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // This commented code show you how to erase the background in black whatever // background color is set in Virtools. If you can avoid clearing the background, // it will be faster, but it is sometimes necessary when you require a non black // background material. /* CKMaterial *m = rc->GetBackgroundMaterial(); VxColor bgc = m->GetDiffuse(); CKTexture *bgt = m->GetTexture(); m->SetDiffuse(VxColor(0.0f, 0.0f, 0.0f, 1.0f)); m->SetTexture(NULL); // When using multiple view, you can't clear the entire rendering window, // you have to clear only the viewport. DWORD ro = CK_RENDER_CLEARZ|CK_RENDER_CLEARBACK|CK_RENDER_CLEARSTENCIL; if ( m_VRContext->GetViewCount() > 1 ) ro |= CK_RENDER_CLEARVIEWPORT; rc->Clear((CK_RENDER_FLAGS) ro); */ ////////////////////////////////////////////////////////////////////////// // Save the current transformation matrices. VxMatrix ov = rc->GetViewTransformationMatrix(); VxMatrix op = rc->GetProjectionTransformationMatrix(); // Set Camera Transformation VxMatrix mat; m_BlendCamera->ComputeProjectionMatrix(mat); rc->SetProjectionTransformationMatrix(mat); rc->SetViewTransformationMatrix(m_BlendCamera->GetInverseWorldMatrix()); //Set blend and original View size VxRect rect(0.0f,0.0f,(float)iView->Width,(float)iView->Height); m_BlendEntity->SetRect(rect); m_OriginalViewTargetSprite->SetRect(rect); //get the right texture if multiview if ( m_VRContext->GetViewCount() > 1 ){ MyWarpData* ViewData = (MyWarpData*) m_VRContext->GetViewData(iView); m_BlendTexture->LoadImage((ViewData->Texturename).Str()); } // Attach the warping texture to the warping object if(iView->ID == 0){ m_OriginalViewMaterial->SetTexture(iView->WarpTexture); } // Render the warping screen. m_OriginalViewTargetSprite->Render(rc); // Render the blending screen. m_BlendEntity->Show(); m_BlendEntity->Render(rc); m_BlendEntity->Show(CKHIDE); // Restore the original tranformation matrices. rc->SetViewTransformationMatrix(ov); rc->SetProjectionTransformationMatrix(op); return VR_OK; } /////////////////////////////////////////////////////////////////////////// CKERROR MyVRManager::CreateBlendingEnvironment(VRView* iView) { // Environment already loaded if ( m_BlendCamera ) return VR_OK; CKPathManager* pm = m_Context->GetPathManager(); //Create and load BlendTexture m_BlendTexture = (CKTexture*) m_Context->CreateObject(CKCID_TEXTURE ,"BlendTexture",CK_OBJECTCREATION_REPLACE); m_BlendTexture->ModifyObjectFlags(CK_OBJECT_NOTTOBEDELETED|CK_OBJECT_PRIVATE, 0); MyWarpData* ViewData = (MyWarpData*) m_VRContext->GetViewData(iView); pm->ResolveFileName(ViewData->Texturename, BITMAP_PATH_IDX); m_BlendTexture->LoadImage((ViewData->Texturename).Str()); //Create 2 materials m_BlendMaterial = (CKMaterial*) m_Context->CreateObject(CKCID_MATERIAL ,"BlendMaterial",CK_OBJECTCREATION_REPLACE); m_BlendMaterial->ModifyObjectFlags(CK_OBJECT_NOTTOBEDELETED|CK_OBJECT_PRIVATE, 0); if (m_BlendTexture) m_BlendMaterial->SetTexture(m_BlendTexture); else return VRERR_GENERICERROR; m_OriginalViewMaterial = (CKMaterial*) m_Context->CreateObject(CKCID_MATERIAL ,"m_OriginalViewMaterial",CK_OBJECTCREATION_REPLACE); m_OriginalViewMaterial->ModifyObjectFlags(CK_OBJECT_NOTTOBEDELETED|CK_OBJECT_PRIVATE, 0); // Set material texture option VxColor color(1.0f,1.0f,1.0f,1.0f); m_BlendMaterial->EnableAlphaTest(TRUE); m_BlendMaterial->EnableAlphaBlend(TRUE); m_BlendMaterial->SetTextureAddressMode(VXTEXTURE_ADDRESSWRAP); m_BlendMaterial->SetTextureMagMode(VXTEXTUREFILTER_LINEAR); m_BlendMaterial->SetTextureMinMode(VXTEXTUREFILTER_LINEAR); m_BlendMaterial->SetTextureBlendMode(VXTEXTUREBLEND_MODULATE); m_BlendMaterial->SetDestBlend(VXBLEND_INVSRCALPHA); m_BlendMaterial->SetSourceBlend(VXBLEND_SRCALPHA); m_BlendMaterial->SetDiffuse(color); m_OriginalViewMaterial->SetTextureAddressMode(VXTEXTURE_ADDRESSWRAP); m_OriginalViewMaterial->SetTextureMagMode(VXTEXTUREFILTER_LINEAR); m_OriginalViewMaterial->SetTextureMinMode(VXTEXTUREFILTER_LINEAR); m_OriginalViewMaterial->SetTextureBlendMode(VXTEXTUREBLEND_MODULATE); m_OriginalViewMaterial->SetDiffuse(color); //Create 2 2DEntity m_BlendEntity = (CK2dEntity*) m_Context->CreateObject(CKCID_2DENTITY,"BlendFrame",CK_OBJECTCREATION_REPLACE); m_BlendEntity->ModifyObjectFlags(CK_OBJECT_NOTTOBEDELETED|CK_OBJECT_PRIVATE, 0); m_BlendEntity->SetMaterial(m_BlendMaterial); m_OriginalViewTargetSprite = (CK2dEntity*) m_Context->CreateObject(CKCID_2DENTITY,"m_OriginalViewTargetSprite",CK_OBJECTCREATION_REPLACE); m_OriginalViewTargetSprite->ModifyObjectFlags(CK_OBJECT_NOTTOBEDELETED|CK_OBJECT_PRIVATE, 0); m_OriginalViewTargetSprite->SetBackground(true); m_OriginalViewTargetSprite->SetMaterial(m_OriginalViewMaterial); //Create Camera m_BlendCamera = (CKCamera*) m_Context->CreateObject(CKCID_CAMERA ,"BlendCamera",CK_OBJECTCREATION_REPLACE); m_BlendCamera->ModifyObjectFlags(CK_OBJECT_NOTTOBEDELETED|CK_OBJECT_PRIVATE, 0); // We must remove the camera aspect ratio for VRPlayer multiple views m_BlendCamera->SetFlags(m_BlendCamera->GetFlags()|CK_3DENTITY_CAMERAIGNOREASPECT); return VR_OK; }