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

📄 ch3rendr.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					  // 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 + -