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

📄 ch3rendr.cpp

📁 Windows上的MUD客户端程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*----------------------------------------------------------------------------
                        _                              _ _       
        /\             | |                            | (_)      
       /  \   _ __   __| |_ __ ___  _ __ ___   ___  __| |_  __ _ 
      / /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` |
     / ____ \| | | | (_| | | | (_) | | | | | |  __/ (_| | | (_| |
    /_/    \_\_| |_|\__,_|_|  \___/|_| |_| |_|\___|\__,_|_|\__,_|

    The contents of this file are subject to the Andromedia Public
	License Version 1.0 (the "License"); you may not use this file
	except in compliance with the License. You may obtain a copy of
	the License at http://www.andromedia.com/APL/

    Software distributed under the License is distributed on an
	"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
	implied. See the License for the specific language governing
	rights and limitations under the License.

    The Original Code is Pueblo client code, released November 4, 1998.

    The Initial Developer of the Original Code is Andromedia Incorporated.
	Portions created by Andromedia are Copyright (C) 1998 Andromedia
	Incorporated.  All Rights Reserved.

	Andromedia Incorporated                         415.365.6700
	818 Mission Street - 2nd Floor                  415.365.6701 fax
	San Francisco, CA 94103

    Contributor(s):
	--------------------------------------------------------------------------
	   Chaco team:  Dan Greening, Glenn Crocker, Jim Doubek,
	                Coyote Lussier, Pritham Shetty.

					Wrote and designed original codebase.

------------------------------------------------------------------------------

	Implementation for the ChRenderContext class for  Intel 3DR.

----------------------------------------------------------------------------*/

// $Header: /home/cvs/chaco/modules/client/msw/ChGraphx/Ch3Rendr.cpp,v 2.109 1996/09/26 02:06:59 pritham Exp $

#include "grheader.h"

#include <QvInfo.h>
#include <QvState.h>
#include "ChMaze.h"
#include "ChRenderData.h"
#include "ChMazDep.h"
#include "CvConvrt.h"
#include "CvTrnsfm.h"
#include "CvNormal.h"
#include "CvInstnc.h"
#include "CvTextur.h"
#include "CvType.h"
#include "CvHitTst.h"
#include "CvMaterl.h"
#include "ChSphere.h"
#include "ChRLImg.h"
#include <ChSFImage.h>
#include "ChCollision.h"

#if defined(CH_USE_D3D)
#include <d3d.h>
#endif

#include <malloc.h>
#if defined(WIN32)
#include <sys/timeb.h>
#endif

#include <ChCore.h>
#include <ChUtil.h>

// Even if we render purely retained, we need this if we use RL
#if (defined(CH_USE_RLAB))
#include "imode.h"
#endif

// Use our debugging allocator - caution do not use for production
// it's too slow and probably won't work for 2 dlls
//#define USE_OUR_RL_ALLOC	1
#define new DEBUG_NEW


#if (defined(CH_USE_RLAB))

const ChNrRenderQuality stdQuality = RenderGouraud ; // 	 // 	RLRenderPhong  
//const ChNrColorModel stdColorModel = RLColourRGB; //   RLColourRamp		
const ChNrColorModel stdColorModel = RLColourRamp; //   RLColourRGB	
	
#if defined(_DEBUG) && defined(USE_OUR_RL_ALLOC)
void* ChRLAlloc(size_t);           
void* ChRLRealloc(void*, size_t);   
void ChRLFree(void*);               

#endif // defined(_DEBUG) && defined(USE_OUR_RL_ALLOC)

#elif defined(CH_USE_D3D)

const ChNrRenderQuality stdQuality = RenderGouraud | D3DRMLIGHT_ON |  D3DRMFILL_SOLID; // 	 // 	RLRenderPhong  
//const ChNrColorModel stdColorModel = RLColourRGB; //   RLColourRamp		
//const ChNrColorModel stdColorModel = RLColourRamp; //   RLColourRGB		
#endif



class ChCameraEntry
{
	protected:
		string m_name;
		QvNode *m_pCamera;
		ChGraphicPageID m_page;

	public:
		ChCameraEntry(string name, QvNode *pCamera, ChGraphicPageID page) :
			m_name(name), m_pCamera(pCamera), m_page(page) {};

		string &GetName() {return m_name;};
		QvNode *GetCamera(){ return m_pCamera;};
};


ChRenderContext::ChRenderContext() : 
				#if defined(CH_USE_3DR)
				m_hGC(0), 
				m_numLightsOn(0),
				#else
				m_pStack(0),
				m_sceneFrame(0),
				m_cameraFrame(0),
				m_headlightFrame(0),
				m_viewport(0), 
				m_boolContinueConstruction( true ),
				m_pCollisionSensor(0),
				m_maxTransparency(false),
				m_pBackgroundTexture(0),
				m_pBackGroundNode(0),
				m_backgroundFrame(0),
				#endif
				#if defined(CH_USE_D3D)
				m_DD(0),
				m_D3D(0),
				m_D3DRM(0),
				m_DDClipper(0),
				#endif
				m_hRC(0), 
				m_hDC(0), 
				m_pWnd(0),
				m_userShading( defaultShading ), 
				m_pRootInstance(0),
				m_cameraCount(0),
				m_pCamera(0),
				m_pDefaultCamera(0),
				m_boolDirty(false),
				m_boolSettingsDirty(false),
				m_boolAnimating(false),
				m_ppDefaults(0),
				m_iShapeCount( 0 ),
				m_iFrameCount( 0 ),
				m_iTotalWork( 0 )

{
	for(int j=0; j<CH_MAX_SPHERE_LEVEL+1; j++)
	{
		m_pSpheres[j] = 0;
	}
	
	#if (defined(CH_USE_RLAB))

	#if defined(_DEBUG) && defined(USE_OUR_RL_ALLOC)
	RLSetAllocator(ChRLAlloc, ChRLRealloc, ChRLFree );
	#endif // defined(_DEBUG) && defined(USE_OUR_RL_ALLOC)
	#else
	m_boolThreaded = false;
	#endif

	m_boolThreaded = !!(ChUtil::GetSystemProperties() & CH_PROP_MULTITHREADED);
 
 	if(IsThreaded())
	{
		::InitializeCriticalSection(&m_sceneCriticalSection);
		::InitializeCriticalSection(&m_qvCriticalSection);
		::InitializeCriticalSection(&m_constructionCriticalSection);
		::InitializeCriticalSection(&m_reconstructionCriticalSection);
	
		// Reconstruction thread events	
		m_hReconstructEvents[reconstructInstance] = ::CreateEvent( 0, false, false, 0 );
		ASSERT( m_hReconstructEvents[reconstructInstance]  );

		m_hReconstructEvents[abortReconstruct] = ::CreateEvent( 0, false, false, 0 );
		ASSERT( m_hReconstructEvents[abortReconstruct] );

		m_hReconstructEvents[endThread] 		  = ::CreateEvent( 0, false, false, 0 );
		ASSERT( m_hReconstructEvents[endThread] );

		// Start the reconstruction thread
		CWinThread *pThread = ::AfxBeginThread(ReConstructInstanceThread, 
										(void*)this, THREAD_PRIORITY_BELOW_NORMAL ); 
		ASSERT( pThread );


		// end of construction event
		m_hConstructDoneEvent  = ::CreateEvent( 0, false, false, 0 );
		ASSERT( m_hConstructDoneEvent );
	}

}

#if defined(_DEBUG) && defined(USE_OUR_RL_ALLOC)
static int numRLAllocs = 0;
static int numRLBytes = 0;

void* ChRLAlloc(size_t size)
{

	numRLAllocs++;
	numRLBytes+=size;
	if(!(numRLAllocs % 100))
	{
		TRACE2("Number RL allocs: %d, bytes %d\n", numRLAllocs, numRLBytes);
	}
	char *bytes = new char[size+8];
	int *pSize = (int*)bytes;
	*pSize++ = 0xcacacaca;
	*pSize = size;
	return (bytes+8);
}
           
void* ChRLRealloc(void* ptr, size_t size)
{
	// Not optimal - just for debugging
	char *bytes = new char[size+8];
	int *pSize = (int*)bytes;
	*pSize++ = 0xcacacaca;
	*pSize = size;
	char *oldPtr = ((char*)ptr)-8;

	int *pTag = (int*)oldPtr;
	if(*pTag == 0xcacacaca)
	{
		if(bytes)
		{
			int oldSize = *(((int*)oldPtr)+1);
			memcpy(bytes + 8, oldPtr + 8, min(size_t(oldSize), size));
			numRLBytes+=size;
			numRLBytes-=oldSize;
		}
		delete [] oldPtr;
	}
	else
	{
		TRACE("Attempt to resize block that's not ours!\n");
	}
	return (bytes+8);
}

void ChRLFree(void* ptr)
{
	numRLAllocs--;

	char *oldPtr = ((char*)ptr)-8;
	int *pSize = (int*)oldPtr;
	int oldSize = pSize[1];
	if(*pSize == 0xcacacaca)
	{
		delete [] oldPtr;
		numRLBytes-=oldSize;
	}
}               

#endif // defined(_DEBUG) && defined(USE_OUR_RL_ALLOC)

ChRenderContext::~ChRenderContext()
{

	RemoveCameras();
	#if (defined(CH_USE_D3D) || defined(CH_USE_RLAB))
	// cleanup the synchronization objects
	if(IsThreaded())
	{
		::CloseHandle( m_hReconstructEvents[reconstructInstance] );
		::CloseHandle( m_hReconstructEvents[abortReconstruct] );
		::CloseHandle( m_hReconstructEvents[endThread] );

		::CloseHandle( m_hConstructDoneEvent);

		::DeleteCriticalSection(&m_sceneCriticalSection);
		::DeleteCriticalSection(&m_qvCriticalSection);
		::DeleteCriticalSection(&m_constructionCriticalSection);
		::DeleteCriticalSection(&m_reconstructionCriticalSection);
	}
	delete m_pCollisionSensor;	// delete the collision sensor viewport
	m_pCollisionSensor = 0;
	#endif

	if ( ChMazeWnd::GetNumMazeObjects() == 0 )
	{ // This is the last object, cleanup all static renderdata objects
		ChQvRenderBaseData::Term();
	}

	#if (defined(CH_USE_D3D))
	// Clean up interfaces
	RELEASE_INTERFACE(m_DDClipper);
	RELEASE_INTERFACE(m_D3DRM);
	RELEASE_INTERFACE(m_D3D);
	RELEASE_INTERFACE(m_DD);
	#endif
}

ChRenderContext*  ChRenderContext::SetRoot(ChQvInstance *pRootInstance)
{
	if(m_pRootInstance != pRootInstance && m_pRootInstance) m_pRootInstance->Release();
	m_pRootInstance = pRootInstance; 
	return this;
};

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

#if (defined(CH_USE_RLAB))
void CameraCallback(ChNrFrame frame, void * arg)
#else
void CameraCallback(ChNrFrame frame, void * arg, float delta)
#endif
{
#if 1
	//ASSERT(arg);
	if(arg)
	{
		QvNode *pCamera = ((ChRenderContext*)arg)->GetCurrentCamera();
		if(pCamera)
		{
			ChQvPCameraRenderData *pRenderData = (ChQvPCameraRenderData *)(pCamera->GetRenderData());

			pRenderData->OnTick();
		}
	}
#endif
}
#endif


#if 0 && defined(_DEBUG)
int GetHeapDetails(HANDLE heap, int &numBlocks, int &numBytes)
{
	numBlocks = 0;
	numBytes = 0;
	PROCESS_HEAP_ENTRY entry;
	entry.lpData = 0;

	HeapLock(heap);
	while(HeapWalk(heap, &entry))
	{
		numBlocks ++;
		numBytes += entry.cbData;
		
	}
	HeapUnlock(heap);
	return numBlocks;
}
void CheckMemory()
{
	#if 0 && defined(_DEBUG)
	HANDLE heaps[200];
	int numHeaps = 	GetProcessHeaps( sizeof(heaps) / sizeof(heaps[0]), heaps);
	TRACE1("Number of heaps = %d\n", numHeaps);
	HANDLE sysHeap = GetProcessHeap();
	int numBytes, numBlocks;

	for(int j=0; j < numHeaps; j++)
	{
		GetHeapDetails(heaps[j], numBlocks, numBytes);
		TRACE2("Heap blocks = %d, bytes = %d", numBlocks, numBytes);
		if(heaps[j] == sysHeap) TRACE(" (process heap)");
		if(!HeapValidate(heaps[j], 0, 0)) TRACE(" INVALID HEAP!");
		TRACE("\n");
	}

	_HEAPINFO heapInfo;
	int heapRet;
	numBlocks = numBytes = 0;
	int numInUseBlocks = 0, numInUseBytes = 0;

	memset(&heapInfo, 0, sizeof(heapInfo));
	while((heapRet = _heapwalk( &heapInfo)) == _HEAPOK)
	{
		numBlocks ++;
		numBytes += heapInfo._size;
		if(heapInfo._useflag)
		{
			numInUseBlocks ++;
			numInUseBytes += heapInfo._size;
		}
	}				
	TRACE2("CRT Heap total blocks = %d, bytes = %d", numBlocks, numBytes);
	TRACE("\n");
	TRACE2("CRT Heap in use blocks = %d, bytes = %d", numInUseBlocks, numInUseBytes);
	TRACE("\n");
	if(heapRet != _HEAPEND) TRACE("CRT Heap invalid!\n");

	char *p = (char*)malloc(2);
	free(p);

	static int passCount = 0;
	static CMemoryState msLast;

	passCount++;
	if (passCount >= 3)
	{
	//AfxDumpMemoryLeaks();
		CMemoryState msNow;
		msNow.Checkpoint();

	if (msNow.m_lCounts[CMemoryState::objectBlock] != 0 ||
		msNow.m_lCounts[CMemoryState::bitBlock] != 0)
	{
		// dump objects since since difference detected.
		TRACE0("Detected memory growth!\n");
		afxDump.SetDepth(1);    // just 1 line each
		//CMemoryState msEmpty;   // construct empty memory state object
		msLast.DumpAllObjectsSince();
	}
	msLast.Checkpoint();


	}
	#endif
}
#else
#define CheckMemory()
#endif

#if (defined(CH_USE_RLAB) || defined(CH_USE_D3D))
void SceneDestroyCallback(ChNrObject obj, void * arg)
{
	//TRACE("Scene Destroyed\n");
}
void ViewportDestroyCallback(ChNrObject obj, void * arg)
{
	//TRACE("Viewport Destroyed\n");
}
void CameraDestroyCallback(ChNrObject obj, void * arg)
{
	//TRACE("Camera frame Destroyed\n");
}
#endif

ChRenderContext*  ChRenderContext::ResetScene()
{

	// Before we reset the scene we need to terminate all threads currently
	// running for this instance
	#if (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
	// Stop all currently active construction threads because we have a new scene
	AbortConstruction();
	
	// at this point there should be only one
	// thread running

	#endif
	
	CheckMemory();

	// remove all textures in our queue for this scene
	if ( !m_textureQueue.IsEmpty() ) 
	{
		ChPosition pos  = m_textureQueue.GetHeadPosition();

		while( pos )
		{
			ChMazeTextureHTTPReq* pReq  = m_textureQueue.GetNext( pos );
			#if defined(CH_USE_3DR)	
				#pragma message("3DR textures leak")
			#elif (defined(CH_USE_RLAB)) || defined(CH_USE_D3D)
				//delete ((ChRLImage *)pReq->GetTextureHandle())->Release();
				if ( pReq->GetTextureHandle() )
				{
					((ChRLImage *)pReq->GetTextureHandle())->Release();
				}
			#endif
			delete pReq;
		
		}
		m_textureQueue.Empty();
	}

	
	SetRoot(0); 
	m_iShapeCount = 0; // This will be incremented by the construction thread

⌨️ 快捷键说明

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