📄 ch3rendr.cpp
字号:
// when a shape is done
m_iFrameCount = 0; // frames displayed so far for this scene
RemoveCameras();
RemoveLights();
RemoveTimeSensors();
Reset();
#if (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
m_dotsCache.Erase(); // We don't need to clear items, they
// are freed when RLab deletes texture objects
delete m_pCollisionSensor; // delete the collision sensor viewport
m_pCollisionSensor = 0;
if(m_sceneFrame)
{
#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
RECT r;
int bpp;
ChNrObjectDestroy(m_viewport); // viewport too
ChNrObjectDestroy(m_sceneFrame); // whole scene and camera
m_sceneFrame = 0;
ChNrObjectDestroy(m_hRC); // whole device
GetWnd()->GetClientRect(&r);
m_hRC = CreateDevice(r.right, r.bottom);
{
CDC *pdc = GetWnd()->GetDC();
bpp = pdc->GetDeviceCaps(BITSPIXEL);
GetWnd()->ReleaseDC(pdc);
}
if (bpp == 1)
{
ChNrDeviceSetShades(m_hRC, 4);
ChNrSetDefaultTextureShades(4);
} else if (bpp == 16)
{
ChNrDeviceSetShades(m_hRC, 32);
ChNrSetDefaultTextureColors(64);
ChNrSetDefaultTextureShades(32);
ChNrDeviceSetDither(m_hRC, FALSE);
} else if (bpp == 24)
{
ChNrDeviceSetShades(m_hRC, 256);
ChNrSetDefaultTextureColors(64);
ChNrSetDefaultTextureShades(256);
ChNrDeviceSetDither(m_hRC, FALSE);
} else
{
ChNrSetDefaultTextureColors(16); //32
ChNrSetDefaultTextureShades(8);
ChNrDeviceSetDither(m_hRC, TRUE);
}
UpdateOptimization();
m_sceneFrame = CreateFrame(0);
ChNrObjectAddDestroyCallback(m_sceneFrame, SceneDestroyCallback, this);
//TRACE("Scene Created\n");
m_cameraFrame = CreateFrame(m_sceneFrame);
ChNrFrameAddCallback(m_cameraFrame, CameraCallback, this);
ChNrObjectAddDestroyCallback(m_cameraFrame, CameraDestroyCallback, this);
//TRACE("Camera frame Created\n");
D3DRelease(m_cameraFrame);
m_viewport = CreateViewport( m_hRC, m_cameraFrame, 0, 0,
ChNrDeviceGetWidth(m_hRC),
ChNrDeviceGetHeight(m_hRC)
);
ChNrObjectAddDestroyCallback(m_viewport, ViewportDestroyCallback, this);
//TRACE("Viewport Created\n");
ChNrViewportSetBack(m_viewport, ChNrVal(5000.0));
ChNrFrameAddScale(m_sceneFrame, CombineReplace, 1., 1., -1.);
#if (defined(CH_USE_RLAB))
RLSceneSetBackground(m_sceneFrame, ((ChMazeWnd*)GetWnd())->GetBackgroundColorL());
#elif (defined(CH_USE_D3D))
unsigned long color = ((ChMazeWnd*)GetWnd())->GetBackgroundColorL();
SetBackgroundColor(color);
#endif
ClearTransformStack();
#if 0 && defined(CH_USE_D3D)
ChNrLight light1 = CreateLightRGB(ChNrLightAmbient, ChNrVal(0.5), ChNrVal(0.5), ChNrVal(0.5));
ChNrFrameAddLight(m_sceneFrame, light1);
D3DRelease(light1);
light1 = CreateLightRGB(ChNrLightDirectional, ChNrVal(0.5), ChNrVal(0.5), ChNrVal(0.5));
ChNrFrameAddLight(m_sceneFrame, light1);
D3DRelease(light1);
#endif
ChNrViewportForceUpdate(m_viewport, 0, 0,
ChNrDeviceGetWidth(m_hRC),
ChNrDeviceGetHeight(m_hRC));
#else
#pragma message(" resetscene not done!!")
#endif
}
#endif
Animate();
return this;
};
QvNode *ChRenderContext::GetCurrentProperty(ChQvState *pState, QvState::StackIndex index)
{
QvNode *pNode = (QvNode *)(pState->GetTopNode(index));
ASSERT(m_ppDefaults);
if(!pNode) pNode = m_ppDefaults[index];
return pNode;
}
ChQvSphereCacheData *ChRenderContext::GetSphere(int level)
{
level = min(level, CH_MAX_SPHERE_LEVEL);
level = max(level, CH_MIN_SPHERE_LEVEL);
if(!m_pSpheres[level]) m_pSpheres[level] = new ChQvSphereCacheData(level);
return m_pSpheres[level];
}
float ChRenderContext::GetQuality()
{
float quality;
if(((ChMazeWnd*)m_pWnd)->IsMoving())
{
quality =m_moveQuality;
}
else
{
quality =m_standingQuality;
}
return quality;
}
ChRenderContext *ChRenderContext::Reset()
{ // predraw reset rc
#if defined(CH_USE_3DR)
m_numLightsOn = 0;
// Turn off all light
for (int j = 0; j < G3D_MAX_LIGHTS; j++)
{
G3dResetLight( GetGC(), j );
}
G3dSetActiveStack(GetGC(), G3DT_MODEL);
G3dClearStack ( GetGC() );
G3dSetActiveStack(GetGC(), G3DT_CAM_CLIP);
G3dClearStack ( GetGC() );
G3dSetActiveStack(GetGC(), G3DT_MODEL);
#else
// TODO figure out if this is needed; probably not
//#pragma message("ChRenderContext::Reset() Not done!")
#endif
return this;
}
//ChRenderContext *ChRenderContext::Draw()
bool ChRenderContext::Draw()
{
Reset();
#if defined(CH_USE_3DR)
if(!IsDirty())
{
if ( m_textureQueue.GetCount() )
{
ProcessTextureQueue();
}
return false;
}
// Set up camera
ChQvState state((ChMazeWnd*)GetWnd());
m_pCamera->traverse(&state);
// Turn on lights
TraverseLights();
// Traverse the instance tree, drawing the shapes
ChDrawIterator drawIt(this);
drawIt.Attach(m_pRootInstance);
drawIt.Iterate();
m_iFrameCount++;
SetDirty(false);
#elif (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
// Do a tick of the simulation; this might dirty us
TickSensors();
if(!IsDirty())
{
if ( m_textureQueue.GetCount() )
{
ProcessTextureQueue();
}
return false;
}
((ChMazeWnd*)GetWnd())->StartFrameTime();
// Set the total work done to zero so that we can do reconstruction before the
// next draw
m_iTotalWork = 0;
// Lock the scene and don't be nice
LockScene();
//TRACE("Drawing the tree - it's dirty.\n");
{
#if defined(CH_VRML_PLUGIN )
AdjustHeadlight( );
if ( NumPendingConstructionThreads() && !((ChMazeWnd*)GetWnd())->IsMoving() )
{ // if the construction is still in progress, update the whole view
ForceUpdate();
}
#endif
#if 0
if(((ChMazeWnd*)GetWnd())->IsMoving())
{
//ChNrDeviceSetQuality(m_hRC, RLRenderFlat);
}
else
{
ChNrDeviceSetQuality(m_hRC, stdQuality);
}
//ChNrDeviceSetQuality(m_hRC, RLRenderGouraud);
#endif
SetDirty(false);
UpdateOptimization();
#if 1 && defined(CH_IMMED_MODE)
// This is a hack because it seems the dither setting gets messed up
// in immediate mode - maybe the viewport keeps its own?
// who knows? This makes it works anyways.
int old_dither = ChNrDeviceGetDither(m_hRC);
ChNrDeviceSetDither(m_hRC, old_dither);
// end hacked bug work-around
ChNrViewportForceUpdate
( m_viewport,
ChNrViewportGetX(m_viewport),
ChNrViewportGetY(m_viewport),
ChNrViewportGetWidth(m_viewport),
ChNrViewportGetHeight(m_viewport)
);
#endif
ChNrFrameMove(m_sceneFrame, 1);
//DoBackground();
ChNrViewportClear(m_viewport);
ChNrViewportRender(m_viewport, m_sceneFrame);
#if defined(CH_IMMED_MODE)
// Traverse the instance tree, drawing the shapes
// in immmediate mode
ChDrawIterator drawIt(this);
drawIt.Attach(m_pRootInstance);
drawIt.Iterate();
#endif
ChNrDeviceUpdate(m_hRC);
m_iFrameCount++;
}
UnlockScene();
#else
#endif
if ( m_textureQueue.GetCount() )
{
ProcessTextureQueue();
}
return true;
}
void ChRenderContext::ProcessTextureQueue()
{ // process only one request at a time
ChMazeTextureHTTPReq* pReq = m_textureQueue.RemoveHead();
if( pReq->GetPage() == ((ChMazeWnd*)GetWnd())->GetCurrentPage() )
{
TRACE( "ProcessTextureQueue :: Using texture %s\n", LPCSTR(pReq->GetURL()));
ChQvTextureRenderData* pRenderData =
(ChQvTextureRenderData*)(pReq->GetTextureNode()->GetRenderData());
if( pReq->GetTextureNode()->GetUsage() > 1
&& !pRenderData->GetTextureHandle() )
{
#if defined(CH_USE_3DR)
ChTextureHandle hTexture = (ChTextureHandle)pReq->GetTextureHandle();
#elif (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
ChRLImage *hTexture = (ChRLImage *)pReq->GetTextureHandle();
#endif
pRenderData->LoadTexture( this, hTexture );
SetDirty( true );
}
else
{
#if defined(CH_USE_3DR)
#pragma message("3DR textures leak")
#elif (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
//delete ((ChRLImage *)pReq->GetTextureHandle());
TRACE( "ProcessTextureQueue ::Texture not used\n" );
((ChRLImage *)pReq->GetTextureHandle())->Release();
#endif
}
}
else if( pReq->GetTextureHandle() )
{
#if defined(CH_USE_3DR)
#pragma message("3DR textures leak")
#elif defined(CH_USE_RLAB)
//delete ((ChRLImage *)pReq->GetTextureHandle());
((ChRLImage *)pReq->GetTextureHandle())->Release();
#endif
}
delete pReq;
}
#if (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
bool ChRenderContext::DoBackground()
{
#if 0 // dead code??
if(m_sceneFrame)
{
if(!m_pBackgroundTexture)
{
// make it
DWORD width = 1;
#if defined(CH_USE_D3D)
while(width <= (m_hRC->GetWidth())) width *= 2;
#else
while(width <= ChNrDeviceGetWidth(m_hRC)) width *= 2;
#endif
width /= 4;
DWORD height = 1;
while(height <= ChNrDeviceGetHeight(m_hRC)) height *= 2;
height /= 4;
m_pBackgroundTexture = new ChTexture(width, height, ChColor(200,0,0), true);
RLSceneSetBackgroundImage(m_sceneFrame, m_pBackgroundTexture->GetHandle());
}
else
{
// say it changed
ChNrTextureChanged( m_pBackgroundTexture->GetHandle(), 1, 0);
}
}
#endif
return true;
}
#endif
#if (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
ChRenderContext *ChRenderContext::ForceUpdate()
{
if(m_sceneFrame && m_viewport)
{
ChNrViewportForceUpdate(m_viewport, 0, 0,
ChNrDeviceGetWidth(m_hRC),
ChNrDeviceGetHeight(m_hRC));
}
return this;
}
#endif
void ChRenderContext::TraverseLights()
{
#if defined(CH_USE_3DR)
ChQvLightInstance *pInstance;
ChPosition pos = m_lights.GetHeadPosition();
while (pos) {
pInstance = m_lights.GetNext(pos);
pInstance->traverse(this);
}
#else
// unnecessary
#endif
}
ChRenderContext *ChRenderContext::SetTexture(ChTextureHandle hTex)
{
#if defined(CH_USE_3DR)
Fixed32_t On = 1;
Fixed32_t Off = 0;
if(hTex)
{
R3dSetState( m_hRC, R3D_STA_ENABLES, R3D_SE_TEXTURING);
R3dSetState( m_hRC, R3D_STA_TEX_ID, (Dword_t)(hTex));
// Modulation depends on material; we either multply or don't modulate at all
// We will turn on/off later face-by-face based on emissiveity
R3dSetState( m_hRC, R3D_STA_ENABLES, R3D_SE_MODULATION);
G3dSetState( m_hGC, G3DL_TEXTURE_MOD, &On);
// Note: Alternative functions are to R3D_TF_MULTIPLY, R3D_TF_REDUCE or R3D_TF_SHADE;
R3dSetState( m_hRC, R3D_STA_TEX_FUNCTION, R3D_TF_MULTIPLY);
//R3dSetState( m_hRC, R3D_STA_TEX_FUNCTION, R3D_TF_SHADE);
}
else
{
R3dSetState( m_hRC, R3D_STA_DISABLES, R3D_SE_TEXTURING);
R3dSetState( m_hRC, R3D_STA_TEX_ID, (Dword_t)(0));
R3dSetState( m_hRC, R3D_STA_DISABLES, R3D_SE_MODULATION);
G3dSetState( m_hGC, G3DL_TEXTURE_MOD, &Off);
R3dSetState( m_hRC, R3D_STA_TEX_FUNCTION, R3D_TF_MULTIPLY);
//R3dSetState( m_hRC, R3D_STA_TEX_FUNCTION, R3D_TF_SHADE);
}
#elif (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
// not needed
#else
#pragma message("SetTexture not done!")
#endif
return this;
}
ChTextureHandle ChRenderContext::GetTexture()
{
#if defined(CH_USE_3DR)
if(m_hRC)
return R3dGetState( m_hRC, R3D_STA_TEX_ID);
else
#elif (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
// not needed
#else
#pragma message("SetTexture not done!")
#endif
return (0);
}
#if defined(CH_USE_3DR)
ChTextureHandle ChRenderContext::LoadDIBTexture( /*ChMazeMainInfo* pInfo,*/ ChDib *pDibIn,
chuint32 luChromaClr, chuint uOption )
{
R3dHandle_t hRC = GetRC();
int iWidth = 1;
int iHeight = 1;
// power of 2
while( (iWidth * 2) <= pDibIn->GetWidth() )
{
iWidth *= 2;
}
while( (iHeight * 2) <= pDibIn->GetHeight() )
{
iHeight *= 2;
}
if ( ((ChMazeWnd*)GetWnd())->GetSettings()->GetScaleTextures() )
{ // Limit to 128
if ( iWidth > 128 )
{
iWidth = 128;
}
if ( iHeight > 128 )
{
iHeight = 128;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -