deargui-vpl/ref/virtools/Samples/VRSdk/SampleBlend/Sources/MyVRManager.cpp

369 lines
11 KiB
C++

/*************************************************************************/
/* 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;
}