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

309 lines
9.8 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_WarpFile = "";
m_WarpCamera = NULL;
m_WarpMaterial = NULL;
}
///////////////////////////////////////////////////////////////////////////
MyVRManager::~MyVRManager()
{
// Nothing to clear
}
///////////////////////////////////////////////////////////////////////////
CKERROR MyVRManager::OnParse()
{
CKPathManager* pm = m_Context->GetPathManager();
// Here, we read our tokens. Note that we could also do it when the
// first "TestWarping" view is found to avoid reading unneeded tokens.
// But as a sample, we do it here.
m_TokenOK = TRUE;
// Get Warping File. We can use the path manager as all configuration
// file search directories have been added to it.
m_TokenOK &= (m_VRContext->GetToken("WarpingFile", &m_WarpFile) == VR_OK);
pm->ResolveFileName(m_WarpFile, DATA_PATH_IDX);
// Get Warping Size. This field are not required, they can use default values
m_VRContext->GetToken("WarpingWidth", &m_WarpWidth, 512);
m_VRContext->GetToken("WarpingHeight", &m_WarpHeight, 512);
// Here, get Additionnal token if needed
return VR_OK;
}
///////////////////////////////////////////////////////////////////////////
CKERROR
MyVRManager::OnViewCreate(VRView* iView)
{
// Get Sub Tokens
CKBOOL SubTokenOK = TRUE;
///////////////////////////////////////////////////////////////////////
// Activate Warp only when a "Warping" SubToken is specified
// Activate mew warp only when warping "Mew" option is set or if ViewMode is ViewWarping
XString Warping;
if ( m_VRContext->GetSubToken(iView->UserTokens, "Warping", &Warping) != VR_OK ){
m_VRContext->OutputToLog(0, "Warping Warn - Warping will be disabled on view %d.\n", iView->ID);
m_VRContext->DeActivateWarp(iView);
return VR_OK;
}
if ( Warping != "SampleWarp" ){
m_VRContext->OutputToLog(0, "Warping Warn - Warping 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, "Test Warping Err - Tokens 'WarpingFile' must be set for test warping.");
m_VRContext->OutputToLog(0, "Test Warping Err - Warping will be disabled on view %d.", iView->ID);
m_VRContext->DeActivateWarp(iView);
return VR_OK;
}
///////////////////////////////////////////////////////////////////////
// Get Other Sub Tokens
// Get Camera Distance
MyWarpData* ViewData = new MyWarpData();
SubTokenOK &= (m_VRContext->GetSubToken(iView->UserTokens, "WarpDistance", &ViewData->Distance, 18.0f)==VR_OK);
// We don't force the user to specify this additionnal token, but we could
/* if ( !SubTokenOK ) {
m_VRContext->OutputToLog(0, "Test Warping Err - View subtokens 'WarpDistance' must be set for test warping.");
m_VRContext->OutputToLog(0, "Test Warping Err - Disable mew warping on view %d.", iView->ID);
delete (ViewData);
return VR_OK;
}
*/
///////////////////////////////////////////////////////////////////////
// Load the warping environment
if ( LoadWarpEnvironment() != VR_OK ) {
m_VRContext->OutputToLog(0, "Test Warping Err - Could not load the warping environment: %s.", m_WarpFile);
delete (ViewData);
return VR_OK;
}
///////////////////////////////////////////////////////////////////////
// Activate Warp
WarpInfo WInfo;
WInfo.UseWarpTexture = TRUE;
WInfo.Width = m_WarpWidth;
WInfo.Height = m_WarpHeight;
if ( m_VRContext->ActivateWarp(iView, &WInfo) != VR_OK ) {
m_VRContext->OutputToLog(0, "Test Warping Err - Could not activate warping.");
delete (ViewData);
return VR_OK;
}
///////////////////////////////////////////////////////////////////////
// Memorize distance on the view
m_VRContext->SetViewData(iView, (void*) ViewData);
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 Warping;
if ( m_VRContext->GetSubToken(iView->UserTokens, "Warping", &Warping) != VR_OK )
return VR_OK;
if ( Warping != "SampleWarp" )
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)
{
//////////////////////////////////////////////////////////////////////////
// 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 ( !view->WarpTexture )
{
VxRect SrcRect, DestRect;
SrcRect.left = (float) view->PositionX;
SrcRect.top = (float) view->PositionY;
SrcRect.right = (float) view->PositionX + view->Width;
SrcRect.bottom = (float) view->PositionY + view->Height;
DestRect.left = 0;
DestRect.top = 0;
DestRect.right = (float) view->Width;
DestRect.bottom = (float) view->Height;
m_MyTexture->CopyContext(rc, &SrcRect, &DestRect);
}
*/
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
// 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 necessery 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();
// We should set the warping distance here using the view data
MyWarpData* ViewData = (MyWarpData*) m_VRContext->GetViewData(iView);
// Set Camera Transformation
VxMatrix mat;
m_WarpCamera->ComputeProjectionMatrix(mat);
rc->SetProjectionTransformationMatrix(mat);
rc->SetViewTransformationMatrix(m_WarpCamera->GetInverseWorldMatrix());
// Attach the warping texture to the warping object
m_WarpMaterial->SetTexture(iView->WarpTexture);
// Render the warping screen.
m_WarpEntity->Render(rc);
// Restore the original tranformation matrices.
rc->SetViewTransformationMatrix(ov);
rc->SetProjectionTransformationMatrix(op);
return VR_OK;
}
///////////////////////////////////////////////////////////////////////////
CKERROR
MyVRManager::LoadWarpEnvironment()
{
// Environment already loaded
if ( m_WarpCamera )
return VR_OK;
// Load the file
CKObjectArray *array = CreateCKObjectArray();
if ( m_Context->Load(m_WarpFile.Str(), array) != CK_OK )
return VRERR_GENERICERROR;
// Mark all the objects as internal and locate the warping objects.
CKObject* obj;
for(array->Reset() ;!array->EndOfList(); array->Next())
{
obj = array->GetData(m_Context);
obj->ModifyObjectFlags(CK_OBJECT_NOTTOBEDELETED|CK_OBJECT_PRIVATE, 0);
switch ( obj->GetClassID() )
{
case CKCID_CAMERA:
case CKCID_TARGETCAMERA:
m_WarpCamera = (CKCamera*) obj;
break;
case CKCID_3DOBJECT:
m_WarpEntity = (CK3dEntity*) obj;
break;
case CKCID_MESH:
m_WarpMesh = (CKMesh*) obj;
break;
case CKCID_MATERIAL:
m_WarpMaterial = (CKMaterial*) obj;
break;
}
}
// Verify that the object were succesfully loaded
if ( !m_WarpEntity || !m_WarpMesh || !m_WarpMaterial || !m_WarpCamera ) {
for(array->Reset() ;!array->EndOfList(); array->Next())
CKDestroyObject( array->GetData(m_Context) );
DeleteCKObjectArray(array);
return VRERR_GENERICERROR;
}
// We must remove the camera aspect ratio for VRPlayer multiple views
m_WarpCamera->SetFlags(m_WarpCamera->GetFlags()|CK_3DENTITY_CAMERAIGNOREASPECT);
// Force some mesh options : object must be prelited, not light computation is done.
m_WarpMesh->SetLitMode(VX_PRELITMESH);
// Set material texture option
m_WarpMaterial->SetTextureAddressMode(VXTEXTURE_ADDRESSWRAP);
m_WarpMaterial->SetTextureMagMode(VXTEXTUREFILTER_LINEAR);
m_WarpMaterial->SetTextureMinMode(VXTEXTUREFILTER_LINEAR);
m_WarpMaterial->SetTextureBlendMode(VXTEXTUREBLEND_MODULATE);
// Delete Array
DeleteCKObjectArray(array);
return VR_OK;
}