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

📄 ch3rendr.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
					/*
					 * create an egg frame within the scene
					 */
				    egg = CreateFrame(m_sceneFrame);

					/*
					 * add the loaded mesh into the frame
					 */
				    if(egg)
				    {	
				    	rval = egg->AddVisual(egg_mesh);
						egg->Release();
					}
					egg_mesh->Release();
				}
			}
			#endif

		}
		#endif
	}
	#endif


	SetTexture(0);

	m_ppDefaults = new QvNode* [QvState::NumStacks];
	for(int j=0; j<	QvState::NumStacks; j++) m_ppDefaults[j] = 0;

	// We don't set defaults for cameras, and lights
	m_ppDefaults[QvState::BaseColorIndex	       		] =   new QvBaseColor; 
	m_ppDefaults[QvState::Coordinate3Index       		] =   new QvCoordinate3; 
	m_ppDefaults[QvState::FontStyleIndex         		] =   new QvFontStyle;
	m_ppDefaults[QvState::InfoIndex         	 		] =   new QvInfo;
	m_ppDefaults[QvState::MaterialBindingIndex   		] =   new QvMaterialBinding; 
	m_ppDefaults[QvState::MaterialIndex          		] =   new QvMaterial;  
	m_ppDefaults[QvState::NormalBindingIndex     		] =   new QvNormalBinding;   
	m_ppDefaults[QvState::NormalIndex            		] =   new QvNormal;
	m_ppDefaults[QvState::ShapeHintsIndex        		] =   new QvShapeHints;
	m_ppDefaults[QvState::Texture2Index          		] =   new QvTexture2;  
	m_ppDefaults[QvState::Texture2TransformationIndex 	] =   new QvTexture2Transform;
	m_ppDefaults[QvState::TextureCoordinate2Index		] =   new QvTextureCoordinate2;
	//		 transforms are different, but we need one identity instance handy
	m_ppDefaults[QvState::TransformationIndex			] =   new QvScale;

	ChQvBuildState state((ChMazeWnd*)GetWnd());

	// traverse once to init; this guarantees renderdata is newed
	m_ppDefaults[QvState::BaseColorIndex	       		]->traverse(&state);
	m_ppDefaults[QvState::Coordinate3Index       		]->traverse(&state);
	m_ppDefaults[QvState::FontStyleIndex         		]->traverse(&state);
	m_ppDefaults[QvState::InfoIndex         	 		]->traverse(&state);
	m_ppDefaults[QvState::MaterialBindingIndex   		]->traverse(&state);
	m_ppDefaults[QvState::MaterialIndex          		]->traverse(&state);
	m_ppDefaults[QvState::NormalBindingIndex     		]->traverse(&state);
	m_ppDefaults[QvState::NormalIndex            		]->traverse(&state);
	m_ppDefaults[QvState::ShapeHintsIndex        		]->traverse(&state);
	m_ppDefaults[QvState::Texture2Index          		]->traverse(&state);
	m_ppDefaults[QvState::Texture2TransformationIndex 	]->traverse(&state);
	m_ppDefaults[QvState::TextureCoordinate2Index		]->traverse(&state);
	m_ppDefaults[QvState::TransformationIndex			]->traverse(&state);

}

void ChRenderContext::AbortConstruction()
{
	// Stop all construction threads currently
	// running for this instance
	#if (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
	if ( IsThreaded() )
	{
		// cancel all threads, currently running
		m_boolContinueConstruction = false;
		// Tell the reconstruction thread to abort all requests and clean up the queue

		// Abort all reconstruction requests
		::ResetEvent( GetEndConstructEvent() );
		::SetEvent( m_hReconstructEvents[abortReconstruct] );

		DWORD dwStatus;
	   	// Wait till reconstruction thread says we are OK to proceed
		dwStatus = ::WaitForSingleObject( GetEndConstructEvent(), INFINITE );
		ASSERT( dwStatus == WAIT_OBJECT_0 );
	
		TRACE1( "AbortConstruction : Threads running before abort : %d\n", NumPendingConstructionThreads() );

		while( NumPendingConstructionThreads() )
		{  // There is a thread curently running, block on the end thread event

			dwStatus = ::WaitForSingleObject( GetEndConstructEvent(), INFINITE );

			ASSERT( dwStatus == WAIT_OBJECT_0 );
		}

		// We can start construction of scenes again
		m_boolContinueConstruction = true;
		TRACE1( "AbortConstruction : Threads running after abort : %d\n", NumPendingConstructionThreads() ); 
		ASSERT( NumPendingConstructionThreads() == 0 );
	}
	#endif
}


void ChRenderContext::Term()
{

	#if defined(CH_USE_3DR)
	if(m_hGC) G3dDeleteGC(m_hGC);
	if(m_hRC) R3dDeleteRC(m_hRC);
	m_hGC = 0;
	m_hRC = 0;
	#else

	// Terminate the reconstruction thread
	if ( IsThreaded() )
	{
		// Abort all reconstruction requests
		::SetEvent( m_hReconstructEvents[endThread] );

		DWORD dwStatus;
	   	// Wait till reconstruction thread says we are OK to proceed
		dwStatus = ::WaitForSingleObject( GetEndConstructEvent(), INFINITE );
		ASSERT( dwStatus == WAIT_OBJECT_0 );
		
	}

	delete m_pDefaultCamera;

	ChNrObjectDestroy(m_hRC);
	ChNrObjectDestroy(m_sceneFrame);
	m_hRC 			= 0;
	m_sceneFrame 	= 0;
	m_cameraFrame 	= 0;
	m_viewport 		= 0;
	#endif

	// Moved from destructor to Term by VSP : This was required to
	// Plug leaks in QV.
	if(m_ppDefaults)
	{
		for(int j=0; j<	QvState::NumStacks; j++)
		{
			delete m_ppDefaults[j];
			m_ppDefaults[j] = 0;
		}
	}
	delete m_ppDefaults;
	m_ppDefaults = 0;
	if(m_pRootInstance) m_pRootInstance->Release();
	//delete m_pRootInstance;
	m_pRootInstance = 0;
	for(int j=0; j<CH_MAX_SPHERE_LEVEL+1; j++)
	{
		delete m_pSpheres[j];
		m_pSpheres[j] = 0;
	}
	#if defined(CH_USE_3DR)
	#else
	delete m_pStack;
	m_pStack = 0;
	#endif

}

#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
void ChRenderContext::Resize( int width, int height, bool boolForceNew )
{
	if(m_hRC)
	{
		LockScene();
		if(width == 0 || width == 0)
		{
		    RECT r;
		    GetWnd()->GetClientRect(&r);
			if(!width) width = r.right;
			if(!height) height = r.bottom;
		}

	    int dev_width = ChNrDeviceGetWidth(m_hRC);
	    int dev_height = ChNrDeviceGetHeight(m_hRC);
	    ChNrValue front = ChNrViewportGetFront(m_viewport);
	    ChNrValue back = ChNrViewportGetBack(m_viewport);
	    ChNrValue field = ChNrViewportGetField(m_viewport);

	    ChNrObjectDestroy(m_viewport);

	    /*
	     * if requesting a device of zero dimensions, actually make the device
	     * slightly larger, as a device of width or height zero is no device at
	     * all, and it causes many problems
	     */

	    if (!width) {
			width = 10;
	    }
	    if (!height) {
			height = 10;
	    }

	    if (boolForceNew || (width > dev_width || height > dev_height))
	    {	
		    int old_dither = ChNrDeviceGetDither(m_hRC);
			ChNrRenderQuality old_quality = ChNrDeviceGetQuality(m_hRC);
			ChNrColorModel old_model = ChNrDeviceGetColorModel(m_hRC);
			int old_shades = ChNrDeviceGetShades(m_hRC);

			#if 0
			// We don't use any right now
			RLDestroyCallback* fns;
			void** args;
			int c, count;

			RLObjectGetDestroyCallbacks(m_hRC, &count, &fns, &args);

			for (c = 0; c < count; c++) {
			    RLObjectRemoveDestroyCallback(m_hRC, fns[c], args[c]);
			}
			#endif

			ChNrObjectDestroy(m_hRC);
			m_hRC = CreateDevice(width, height);

			#if 0
			for (c = 0; c < count; c++) {
			    ChNrObjectAddDestroyCallback(m_hRC, fns[c], args[c]);
			}

			RLFree(fns);
			RLFree(args);
			#endif

			ChNrDeviceSetDither(m_hRC, old_dither);
			ChNrDeviceSetQuality(m_hRC, old_quality);
			#if (defined(CH_USE_RLAB))
			// Just for RL, implicit in device in d3d
			ChNrDeviceSetColorModel(m_hRC, old_model);
			#endif
			ChNrDeviceSetShades(m_hRC, old_shades);
	    }
	    m_viewport = CreateViewport(m_hRC, m_cameraFrame, 0, 0, width, height);
		ChNrObjectAddDestroyCallback(m_viewport, ViewportDestroyCallback, this);
		//TRACE("Viewport Created\n");

	    ChNrViewportSetBack(m_viewport, back);
	    ChNrViewportSetFront(m_viewport, front);
	    ChNrViewportSetField(m_viewport, field);

		if(m_pBackGroundNode)
		{
			ChQvBackgroundInfoData *pData = (ChQvBackgroundInfoData *)(m_pBackGroundNode->GetRenderData());
			pData->OnResize(this);
		}

		if(GetCurrentCamera())((ChQvPCameraRenderData*)(GetCurrentCamera()->GetRenderData()))->SynchCamera();

		SetDirty();

		UnlockScene();
	}
}
#endif

void ChRenderContext::SetModulation(bool boolUseTexture /*= true*/, bool boolPureEmissive)
{
	#if defined(CH_USE_3DR)
	Fixed32_t On = 1;
	Fixed32_t Off = 0;
	if(boolUseTexture && boolPureEmissive)
	{	
		// turn off texture modulation - it paints black
		R3dSetState( m_hRC, R3D_STA_DISABLES, R3D_SE_MODULATION);	
		G3dSetState( m_hGC, G3DL_TEXTURE_MOD, &Off);
	}
	else if(boolUseTexture && (R3dGetState( m_hRC, R3D_STA_ENABLES) & R3D_SE_SHADING))
	{
		// Normal case for diffuse or specular faces - must be smooth shaded to work
		// in 3dr. 
		R3dSetState( m_hRC, R3D_STA_ENABLES, R3D_SE_MODULATION);	
		G3dSetState( m_hGC, G3DL_TEXTURE_MOD, &On);
	}
	else if(boolUseTexture)
 	{	
		// turn off texture modulation -  no smoothing 
		R3dSetState( m_hRC, R3D_STA_DISABLES, R3D_SE_MODULATION);	
		G3dSetState( m_hGC, G3DL_TEXTURE_MOD, &Off);
	}
	// else texturing is off, so don't care
	#elif (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
	// not needed
	#else
	#pragma message("ChRenderContext::SetModulation() Not done!")
	#endif
}


// Set shading according to user preferences and traversal state

ChRenderContext* ChRenderContext::SetShading( ChQvShapeInstance *pInstance )
{
	#if defined(CH_USE_3DR)
	ChShadingLevel	stateShading = defaultShading;
	ChShadingLevel	resultShading;
	int permute[5];

	permute[int(smoothShading)] = 0;
	permute[int(flatShading)] = 1;
	permute[int(noShading)] = 2;
	permute[int(defaultShading)] = 3;
	permute[int(wireFrame)] = 4;
											// Indexing is [user][state]
	static ChShadingLevel aShadingTbl[5][5] =
	{
		// user == smoothShading
		{ smoothShading, flatShading, noShading, smoothShading, noShading },
		// user == flatShading
		{ flatShading, flatShading, noShading, flatShading, noShading },
		// user == none
		{ noShading, noShading, noShading, noShading, noShading },
		// user == defaultShading
		{ smoothShading, flatShading, noShading, defaultShading, noShading },
		// user == wireframe
		{ noShading, noShading, noShading, noShading, noShading }
	};

	// Get Stack top and get the shading value, if any
	// Right now the node only pushes shading nodes, so we don't have to walk down
	QvInfo *pInfoNode = 0;
	if(pInstance) pInfoNode = pInstance->GetInfo();
	if(pInfoNode && pInfoNode->GetRenderData())
	{
		stateShading = ((ChQvInfoRenderData	*)(pInfoNode->GetRenderData()))->GetShading();
	}

	// Make sure values are in range - Help stamp out wild pointers
	int i = int(m_userShading);	if(i>sizeof(permute)/sizeof(permute[0]) || i<0) i = defaultShading;
	int j = int(stateShading);	if(j>sizeof(permute)/sizeof(permute[0]) || j<0) j = defaultShading;
	
	// Lookup in table
	resultShading = aShadingTbl[permute[i]][permute[j]];

	// Set it into the renderer's context
	Fixed32_t On = 1;
	Fixed32_t Off = 0;

    if (resultShading == flatShading)
    {
        R3dSetState( GetRC(), R3D_STA_DISABLES, R3D_SE_SHADING);
        //G3dSetState( GetGC(), G3DL_FLAT_SHADING, &On);
	}
	else if (resultShading == noShading)
	{
        R3dSetState( GetRC(), R3D_STA_DISABLES, R3D_SE_SHADING);
        //G3dSetState( GetGC(), G3DL_FLAT_SHADING, &On);
	}
	else if (resultShading == smoothShading)
	{
    	R3dSetState( GetRC(), R3D_STA_ENABLES, R3D_SE_SHADING); 
        //G3dSetState( GetGC(), G3DL_FLAT_SHADING, &Off);
	}
	else   // default to smoothShading
	{
    	R3dSetState( GetRC(), R3D_STA_ENABLES, R3D_SE_SHADING );
        //G3dSetState( GetGC(), G3DL_FLAT_SHADING, &Off);
	}
	#elif (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
	// not needed
	#else
	#pragma message("ChRenderContext::SetShading() Not done!")
	#endif
	return this;
}


#if defined(CH_USE_3DR)
// Private helper function for RebuildTransformStack
int ChRenderContext::ApplyQvTail( QvElement *elt)
{
	int tailDepth = 0;
	TransformF_t eltMat;
	G3dSetActiveStack(m_hGC, G3DT_MODEL);

	if(elt->next)
	{
		tailDepth = ApplyQvTail( elt->next );
	}
	if( tailDepth < elt->depth || elt->type == QvElement::NoOpTransform)
	{
		G3dPushTransform(m_hGC);
	}
	if(GetTransform( elt, eltMat))
	{
		G3dPostMultTransform(m_hGC, eltMat);
	}
	return elt->depth;
}

void ChRenderContext::RebuildTransformStack(ChQvState *pState)
{
	// recurse down the qv stack, applying each matrix, and pushing the geometry engine stack
	// each time the element depth changes, or a nooptransform is encountered. (Noop transforms are
	// used by TransformSeparator::traverse as markers)
	QvElement *	top = pState->getTopElement(QvState::TransformationIndex);
	
	G3dSetActiveStack(GetGC(), G3DT_MODEL);
	if(top) ApplyQvTail( top );
 
}
#else
	// not used by other renderer's implementations
#endif

Ch3DViewerMode ChRenderContext::GetViewerMode()
{
	Ch3DViewerMode	mode = ((ChMazeWnd*)GetWnd())->GetSceneViewerMode();
	Ch3DViewerMode	prefMode = ((ChMazeWnd*)GetWnd())->GetSettings()->GetViewerMode();

	#if 0
	if(mode == none || ((ChMazeWnd*)GetWnd())->GetSettings()->GetOverrideSceneMode())
	{
		mode = prefMode;
	}
	#endif
	return prefMode;
}

ChQvTransformationInstance *ChRenderContext::GetDefaultTransform()
{
	ChQvRenderBaseData *pData = (ChQvRenderBaseData *)(m_ppDefaults[QvState::TransformationIndex]->GetRenderData());
	return (ChQvTransformationInstance *)(pData->m_instances.GetHead());
}

ChRenderContext* ChRenderContext::AddCamera(QvNode *pCamera, string &strName)
{
	if(!strName.IsEmpty())
	{
		ChCameraEntry *pEntry = new ChCameraEntry(strName, pCamera, 
			((ChMazeWnd*)GetWnd())-> GetCurrentPage());
		m_cameras.AddTail(pEntry);
		m_cameraCount++;
	}
	return this;
}

ChRenderContext* ChRenderContext::RemoveCamera(string &strName)
{
	if(!strName.IsEmpty() && !m_cameras.IsEmpty())
	{
		ChPosition pos = m_cameras.GetHeadPosition();
		while(pos)
		{
			ChPosition thisPos = pos;
			ChCameraEntry *pEntry = m_cameras.GetNext(pos);
			if(pEntry && strName == pEntry->GetName())
			{
				m_cameras.Remove(thisPos);
				delete pEntry;
				break;
			}
		}
		//m_cameras.Delete(strName);
		m_cameraCount--;
	}
	return this;
}

ChRenderContext* ChRenderContext::RemoveCameras()
{
	while(!m_cameras.IsEmpty())
	{
		ChCameraEntry *pEntry = m_cameras.RemoveHead();
		delete pEntry;
	}
	m_cameraCount = 0;
	return this;
}

//////////////// ChCameraIterator - only non-trivial method ////////////
// We put it here because of similarity to RC camera stuff

bool ChCameraIterator::Iterate()
{
	if(!m_pRC) return false;

	bool boolContinue = true;
	if(!m_pRC->m_cameras.IsEmpty())
	{
		ChPosition pos = m_pRC->m_cameras.GetHeadPosition();
		while(pos && boolContinue)
		{
			ChCameraEntry *pEntry = m_pRC->m_cameras.GetNext(pos);

⌨️ 快捷键说明

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