⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chrenderdata.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	if(m_texture) return this;		// Something already there, do nothing for now
	bool boolLimit = false;			// Should we allow reduction for RLAB??

	m_pImage = new ChRLImage(pDibIn, boolLimit, uOption, luChromaClr);

	pContext->LockScene();

	m_texture = RLCreateTexture(pRLImage(*m_pImage));

	// Now propagate to all dependents 
	MyTextureDataIterator iterator(*this);
	iterator.IterateDependents();

	pContext->UnlockScene();
			#endif

		  
#endif
	return this;
}

#if defined(CH_USE_3DR)
ChQvBackgroundData* ChQvBackgroundData::LoadTexture( ChRenderContext *pContext, ChTextureHandle texHandle )
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
ChQvBackgroundData* ChQvBackgroundData::LoadTexture( ChRenderContext *pContext, ChRLImage* pRLImg )
#endif
{

	#if NOT_YET
#if defined(CH_USE_3DR)

	SetTextureHandle( texHandle );

#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))

	if(m_texture) 
	{
		// Delete the old texture we have
		delete pRLImg;
		return this;	  // Something already there, do nothing for now
	}		
	// We are saving RLImage because RL makes us keep it around.
	m_pImage = pRLImg;

	pContext->LockScene();
	m_texture = RLCreateTexture(pRLImage(*m_pImage));

	// Now propagate to all dependents 
	MyTextureDataIterator iterator(*this);
	iterator.IterateDependents();
	pContext->UnlockScene();
#endif
		  
#endif
	return this;
}

// Return whether it will -never- have a texture
bool ChQvBackgroundData::IsEmpty()
{
	bool boolEmpty = true;
	QvBackground *pNode = (QvBackground *)GetNode();
	string strURL = string(pNode->panorama.values[0].getString());
	if(!strURL.IsEmpty()) boolEmpty = false;
	return boolEmpty;
}

// ChQvBackgroundInfoData
		
ChQvBackgroundInfoData::ChQvBackgroundInfoData(QvNode *pNode) :	 ChQvTextureRenderData(pNode),
	m_height(0),
	m_width(0), 
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	m_pTiledImage(0),
	m_backgroundFrame(0),
	#endif
	m_boolDirty(false)
{ }

void BackgroundTextureDestroyCallback(ChNrObject obj, void * arg)
{
	((ChQvBackgroundInfoData*)arg)->OnDestroyTexture();
}

ChQvBackgroundInfoData::~ChQvBackgroundInfoData()
{
	#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	if(GetTextureHandle())
	{
		ChNrObjectRemoveDestroyCallback(GetTextureHandle(), BackgroundTextureDestroyCallback, this);
	}
	//delete m_pTiledImage;
	if ( m_pTiledImage )
	{
		m_pTiledImage->Release();
	}
	m_pTiledImage = 0;
	m_backgroundFrame = 0;
	#endif
}

int ChQvBackgroundInfoData::GetURL(QvState *qvstate)
{
	// return true if this is a spawn request, else false
	if( ((ChQvState*)qvstate)->GetType() != ChQvState::spawnRequests)
	{
		return false;
	}

	// Spawn a new http request and add it to the info's list of requests
	if(m_strURL.IsEmpty())
	{
		ChQvSpawnState *state = (ChQvSpawnState *)qvstate;
		QvInfo *pNode = (QvInfo *)GetNode();
		string strURL = string(pNode->string.value.getString());
		m_strURL = pNode->string.value.getString();

		// check if we need to fetch a texture from a WWW site
		if(!m_strURL.IsEmpty())	
		{
			// TODO: Ask that the texture not be changed in size TODO!!!!!!!!!
			ChMazeTextureHTTPReq *pHTTPReq = new ChMazeTextureHTTPReq ( 
									state->GetView(), m_strURL, pNode , ChMazeTextureHTTPReq::textureKeepSize );
			pHTTPReq->SetPage(state->GetView()->GetCurrentPage());

		   	string defURL = state->GetDefaultURL();
			state->GetView()->GetURL( m_strURL, (chparam)pHTTPReq, LPCTSTR(defURL) );
		}

	}
	return true;
}


ChQvTextureRenderData* ChQvBackgroundInfoData::LoadTexture(ChRenderContext *pContext, ChDib *pDibIn, chuint32 luChromaClr, chuint uOption)
{
#if defined(CH_USE_3DR)
	SetTextureHandle( pContext->LoadDIBTexture( pDibIn, luChromaClr, uOption ));
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	if(m_texture) return this;		// Something already there, do nothing for now
	bool boolLimit = false;			// Don't allow reduction for RLAB

	m_pImage = new ChRLImage(pDibIn, boolLimit, uOption | ChMazeTextureHTTPReq::textureKeepSize, luChromaClr);

	pContext->LockScene();

	//m_texture = RLCreateTexture(pRLImage(*m_pImage));


	pContext->UnlockScene();

		  
#endif
	return this;
}

#if defined(CH_USE_3DR)
ChQvTextureRenderData* ChQvBackgroundInfoData::LoadTexture( ChRenderContext *pContext, ChTextureHandle texHandle )
#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
ChQvTextureRenderData* ChQvBackgroundInfoData::LoadTexture( ChRenderContext *pContext, ChRLImage* pRLImg )
#endif
{

#if defined(CH_USE_3DR)

	SetTextureHandle( texHandle );

#elif (defined(CH_USE_RLAB) || defined(CH_USE_D3D))

	if(m_texture) 
	{
		// Delete the old texture we have
		//delete pRLImg;
		pRLImg->Release();
		return this;	  // Something already there, do nothing for now
	}		
	// Save RLImage - we'll need it to rebuild the texture if size changes.
	m_pImage = pRLImg;

	pContext->LockScene();

	// Tile the image onto a sufficiently large texture
	CreateTexture(pContext);
	if(GetTextureHandle())
	{
		// Now propagate to the scene background frame
		m_backgroundFrame = pContext->SetBackgroundImage(this);


		// Now set up the background frame visual
		InitDecal(pContext);
	}
	pContext->UnlockScene();
		  
#endif
	return this;
}

// Return whether it will -never- have a texture
bool ChQvBackgroundInfoData::IsEmpty()
{
	bool boolEmpty = true;
	QvBackground *pNode = (QvBackground *)GetNode();
	string strURL = string(pNode->panorama.values[0].getString());
	if(!strURL.IsEmpty()) boolEmpty = false;
	return boolEmpty;
}		

#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))

int ChQvBackgroundInfoData::ComputeTiledWidth(ChRenderContext *pContext)
{
	int devWidth = ChNrDeviceGetWidth(pContext->GetRC());
	int imWidth = pRLImage(*m_pImage)->width;
	int width = 1;
	//while(width < devWidth + imWidth) width *= 2;
	width = max(4, devWidth + imWidth);
	width = ((width - 1) / 4 + 1) * 4;	
	return width;
}

int ChQvBackgroundInfoData::ComputeTiledHeight(ChRenderContext *pContext)
{
	int devHeight = ChNrDeviceGetHeight(pContext->GetRC());
	int imHeight = pRLImage(*m_pImage)->height;
	int height = 1;
	//while(height < devHeight + imHeight) height *= 2;
	height = max(4, devHeight + imHeight);
	height = ((height - 1) / 4 + 1) * 4; // make sure it's 4n pixels wide, guaranteeing 32bit alignment	
	return height;
}

bool ChQvBackgroundInfoData::CreateTexture(ChRenderContext *pContext)
{
	m_width = ComputeTiledWidth(pContext);
	m_height = ComputeTiledHeight(pContext);
	m_width += 8;	// slop factor to prevent too many resizings
	m_height += 8;	// slop factor to prevent too many resizings
	#if (defined(CH_USE_D3D))
	m_width = pRLImage(*m_pImage)->width;
	m_height = pRLImage(*m_pImage)->height;
	m_pTiledImage = 0;
	#else
	m_pTiledImage = new ChRLImage(*m_pImage, m_width, m_height);
	m_texture = pContext->CreateTexture(pRLImage(*m_pTiledImage));
	ChNrObjectAddDestroyCallback(m_texture, BackgroundTextureDestroyCallback, this);
	ChNrTextureSetColors(m_texture, 128);
	ChNrTextureSetShades(m_texture, 1);
	#endif
	return true;
}

void ChQvBackgroundInfoData::OnDestroyTexture()
{
	//delete m_pTiledImage;
	if ( m_pTiledImage )
	{
		m_pTiledImage->Release();
	}
	m_pTiledImage = 0;
	m_texture = 0;
}

void ChQvBackgroundInfoData::Move( ChRenderContext *pContext)
{
	if(m_boolDirty) Resize(pContext);
	QvNode *pCamera = pContext->GetCurrentCamera();
	ChQvPCameraRenderData *pData = 0;
	if(GetTextureHandle() && pCamera)
	{
		pData = (ChQvPCameraRenderData*)(pCamera->GetRenderData());
		GxTransform3Wf	camLook;
		pData->GetOrientationTransform(camLook);
		GxVec3f newCenter = camLook * m_backCenter;
		float extent = max(ChNrDeviceGetWidth(pContext->GetRC()), ChNrDeviceGetHeight(pContext->GetRC()));
		newCenter.x() *= extent / 2;
		newCenter.x() += extent / 2;
		newCenter.y() *= -extent / 2;
		newCenter.y() += extent / 2;

		ChTextureHandle tex = GetTextureHandle();
		Justify(newCenter, pContext);
		ChNrTextureSetDecalOrigin(tex, newCenter.x(),	 newCenter.y());
	}
}
void ChQvBackgroundInfoData::OnResize( ChRenderContext *pContext )
{
	m_boolDirty = true;	
}

void ChQvBackgroundInfoData::Resize( ChRenderContext *pContext)
{
	int height = ComputeTiledHeight(pContext);
	int width = ComputeTiledWidth(pContext);
	ChTextureHandle tex = GetTextureHandle();
	if(m_texture || m_pTiledImage)
	{
		// 16 is a slop factor to prevent excessive resizing computations
		if(m_height < height || m_width < width || m_height - 16 > height || m_width - 16 > width )
		{
			if(tex) ChNrFrameRemoveVisual(m_backgroundFrame, tex);
			//delete m_pTiledImage;
			if ( m_pTiledImage )
			{
				m_pTiledImage->Release();
			}
			m_pTiledImage = 0;
			m_texture = 0;
		}
		else
		{
			m_boolDirty = false;	
			return;		// texture is ok as is
		}
	}

	CreateTexture(pContext);
	if(GetTextureHandle())
	{
		ChNrFrameAddVisual(m_backgroundFrame, GetTextureHandle());
		InitDecal(pContext);
	}
	m_boolDirty = false;	
}

void ChQvBackgroundInfoData::InitDecal( ChRenderContext *pContext)
{
	ChTextureHandle tex = GetTextureHandle();
	ChNrTextureSetDecalScale(tex, false);

	//RLTextureSetDecalDepth(tex, RLDecalFront);
	ChNrTextureSetDecalOrigin(tex, ChNrDeviceGetWidth(pContext->GetRC()) / 2, ChNrDeviceGetHeight(pContext->GetRC()) / 2);

	QvNode *pCamera = pContext->GetCurrentCamera();
	ChQvPCameraRenderData *pCamData = 0;
	if(pCamera)
	{
		pCamData = (ChQvPCameraRenderData*)(pCamera->GetRenderData());
		GxTransform3Wf	camLook;
		pCamData->GetOrientationTransform(camLook);
		camLook.Invert();
		m_backCenter = camLook * GxVec3f(0, 0, 1.);
		//m_backCenter = camLook * GxVec3f(ChNrDeviceGetWidth(GetRC()) / 2,	 ChNrDeviceGetHeight(GetRC())	/ 2, 1.);
		//float w;
		//m_backCenter = camLook.TransformW(GxVec3f(ChNrDeviceGetWidth(GetRC()) / 2, ChNrDeviceGetHeight(GetRC())	/ 2, 1.), w);
	}

}

void ChQvBackgroundInfoData::Justify(GxVec3f &pt, ChRenderContext *pContext)
{
	int devWidth = ChNrDeviceGetWidth(pContext->GetRC());
	int devHeight = ChNrDeviceGetHeight(pContext->GetRC());
	int imWidth = pRLImage(*m_pImage)->width;
	int imHeight = pRLImage(*m_pImage)->height;
	int imBackWidth = pRLImage(*m_pTiledImage)->width;
	int imBackHeight = pRLImage(*m_pTiledImage)->height;

	while(pt.x() < devWidth / 2) pt.x() += imWidth;
	while(pt.y() < devHeight / 2) pt.y() += imHeight;
	while(pt.x() >= imBackWidth - devWidth / 2) pt.x() -= imWidth;
	while(pt.y() >= imBackHeight - devHeight / 2) pt.y() -= imHeight;
}

#endif

/////////////////////////////////////////////////////////////////////////////////
ChQvSpinGroupRenderData::ChQvSpinGroupRenderData(QvNode* pNode) : 
	ChQvGroupRenderData(pNode), m_step(0)
{
#if defined(CH_VRML_EVENTS)
	if(!m_pDispatcher)
	{
		m_pDispatcher = new	ChVrmlDispatcher;
		Init();
	}
#endif
};


void ChQvSpinGroupRenderData::Init()
{
	ChQvGroupRenderData::Init();
	#if defined(CH_VRML_EVENTS)
	AddVrmlDispatcher("set_rotation", SFRotation, OnSetRotation);
	#endif
};

ChQvSpinGroupRenderData::~ChQvSpinGroupRenderData()
{
}

void ChQvSpinGroupRenderData::Term()
{
#if defined(CH_VRML_EVENTS)
	delete m_pDispatcher;
	m_pDispatcher = 0;
#endif
}

bool ChQvSpinGroupRenderData::OnSetRotation(ChRenderContext *pRC, ChApplet * pApplet, ChIVrmlEvent *pEventList)
{
	bool boolSuccess = true;
#if defined(CH_VRML_EVENTS)
	// Change the rotation value, and dirty the context so it takes effect
	float axis[3];
	float angle;
	ChRotationEvent *pEvent = (ChRotationEvent *)pEventList;
	pEvent->GetValue(axis, angle);
	QvSFRotation *pRotation = 0;
 	QvSpinGroup *pNode = (QvSpinGroup *)m_pNode;
	pRotation = &(pNode->rotation);

	pRotation->axis[0] = axis[0];
	pRotation->axis[1] = axis[1];
	pRotation->axis[2] = axis[2];
	pRotation->angle = angle;

	pRC->SetDirty();
#endif

	return boolSuccess;
}

void ChQvSpinGroupRenderData::Spin(ChQvSpinGroupInstance *pTarget)
{
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
	if(!pTarget->GetContext()->IsAnimating()) return;

	QvSpinGroup *pSpin = (QvSpinGroup*)GetNode();
	const float almostZero = 1.e-14;
	if(pSpin->rotation.angle > -almostZero && pSpin->rotation.angle < almostZero) return;


	GxTransform3Wf instTransform = pTarget->GetTransform();

	float newStep =  pTarget->GetContext()->GetFrameCount();
	double step = newStep - m_step;	// Based on frame count, interpreting the angle as "per frame increment"
	m_step  = newStep;

	// Integrate the incremental spin by applying this rotation to the current spinTransform

	if(step)
	{
		// Integrate the incremental spin by applying this rotation to the current spinTransform
		double twopi = atan(1.0) * 8.;	// good to about 17 places

		float angle = float(fmod(double(pSpin->rotation.angle) * step, twopi));
		GxVec3f axis(pSpin->rotation.axis[0], pSpin->rotation.axis[1], pSpin->rotation.axis[2]);
		m_spinTransform *= GxTransform3Wf(axis,  angle);
	}


	ChNrFrame frame = pTarget->GetFrame();

	if(frame)
	{
		if(pSpin->local.value == FALSE)
		{
			pTarget->GetTransformInstance()->SetSelfTransform(instTransform * m_spinTransform * instTransform.Inverse());
		}
		else
		{
			pTarget->GetTransformInstance()->SetSelfTransform(m_spinTransform);
		}
		pTarget->GetTransformInstance()->SetTransformDirty();
	}
	pTarget->GetContext()->SetDirty();	// force another frame
#endif

}

ChQvTimeSensorRenderData::~ChQvTimeSensorRenderData()
{
	if(m_pRC)
	{
		m_pRC->Remove(this);
	}
}

bool ChQvTimeSensorRenderData::OnTick(double t)
{
	((QvTimeSensor*)(GetNode()))->Tick(t);
	return true;
}

bool ChQvTimeSensorRenderData::Install(ChRenderContext *pRC)
{
	if(m_pRC == pRC) return true;	// already there
	if(m_pRC)
	{
		m_pRC->Remove(this);
	}
	m_pRC = pRC;
	if(pRC)
	{
		pRC->Add(this);
	}
	return true;
}

// end of file

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -