📄 chrenderdata.cpp
字号:
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 + -