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

📄 scenegraph.cpp

📁 Torus 3D Engine is an open-source OpenGL ES 3D Engine for creating your own games in BREW environmen
💻 CPP
📖 第 1 页 / 共 2 页
字号:
int* CSceneItem::OBBMin()
{
	return m_OBBMin;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
int* CSceneItem::OBBMax()
{
	return m_OBBMax;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CSceneItem::SetEnvMapMode(byte jEnvMapMode)
{
	m_jEnvMapMode = jEnvMapMode;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
byte CSceneItem::EnvMapMode()
{
	return m_jEnvMapMode;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CSceneGraph::CSceneGraph(CEngine* pEngine)
{
	m_pEngine = pEngine;
	m_pRoot = new CSceneItem();
	m_pRoot->SetNode(TRUE);
	m_wModelCount = 0;
	m_pModelLibrary = NULL;
	m_wTextureCount = 0;
	m_pTextureLibrary = NULL;
	for (byte x=0; x<6; x++) m_pSkyBox[x] = NULL;
	m_bSkyBoxLoaded = FALSE;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CSceneGraph::~CSceneGraph()
{
	WORD x;

	if (m_pModelLibrary)
	{
		for (x=0; x<m_wModelCount; x++)
			delete m_pModelLibrary[x];

		FREE(m_pModelLibrary);
	}

	if (m_pTextureLibrary)
	{
		for (x=0; x<m_wTextureCount; x++)
			delete m_pTextureLibrary[x];

		FREE(m_pTextureLibrary);
	}

	for (x=0; x<6; x++)
		if (m_pSkyBox[x]) delete m_pSkyBox[x];

	delete m_pRoot;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CSceneGraph::AddItem(CSceneItem* pNode, CSceneItem* pItem)
{
	// start from specified node
	CSceneItem* pLeaf = pNode;

	// find last item
	while (pLeaf->Next()) pLeaf = pLeaf->Next();

	// add new item
	pLeaf->SetNext(pItem);

	// setup new item
	pItem->SetNode(FALSE);
	pItem->SetPrevious(pLeaf);
	pItem->SetNext(NULL);
	pItem->SetParent(NULL);
	pItem->SetChild(NULL);
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CSceneGraph::RemoveItem(CSceneItem* pItem)
{
	if (pItem->IsNode())
	{
		// remove node
		pItem->Parent()->SetChild(pItem->Child());
		pItem->SetParent(NULL);
	}
	else
	{
		// remove item
		if (pItem->Next()) pItem->Next()->SetPrevious(pItem->Previous());
		pItem->Previous()->SetNext(pItem->Next());
		pItem->SetPrevious(NULL);
	}
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CSceneGraph::AddChild(CSceneItem* pNode, CSceneItem* pItem)
{
	// start from specified node
	CSceneItem* pLeaf = pNode;

	// find last child node
	while (pLeaf->Child()) pLeaf = pLeaf->Child();

	// add new item
	pLeaf->SetChild(pItem);

	// setup new item
	pItem->SetNode(TRUE);
	pItem->SetParent(pLeaf);
	pItem->SetChild(NULL);
	pItem->SetPrevious(NULL);
	pItem->SetNext(NULL);
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CSceneGraph::RemoveNode(CSceneItem* pItem)
{
	RemoveItem(pItem);
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CSceneItem* CSceneGraph::Root()
{
	return m_pRoot;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CSceneGraph::Render(CSceneItem* pItem, CCamera* pCam, boolean bFrustum)
{
	// load camera projection view matrix
	glMatrixMode(GL_PROJECTION);
	glLoadMatrixx(pCam->ProjectionMatrix().m);

	// switch back to model view matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	// rotate world in camera space
	vec3_t r; VectorCopy(pCam->Rotation(), r);
	glRotatex(-r[0], 1,0,0);
	glRotatex(-r[1], 0,1,0);
	glRotatex(-r[2], 0,0,1);

	vec3_t p; VectorCopy(pCam->Position(), p);

	// render skybox before translation
	// (skybox always at 0,0,0)
	if (m_bSkyBoxLoaded)
	{
		glDisable(GL_DEPTH_TEST);
		for (byte x=0; x<6; x++)
		{
			VectorCopy(p, m_pSkyBox[x]->Position());
			m_pSkyBox[x]->Render(this);
		}
		glEnable(GL_DEPTH_TEST);
	}

	// translate world in camera space
	glTranslatex(-p[0], -p[1], -p[2]);

	// render recursively
	RecursiveRender(pItem, pCam, bFrustum);
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CSceneGraph::RecursiveRender(CSceneItem* pItem, CCamera* pCam, boolean bFrustum)
{
	//
	// render the hierarchical scenegraph
	//
	while (pItem)
	{
		glPushMatrix();

			// translate and rotate item
			vec3_t v; VectorCopy(pItem->Position(), v);
			vec3_t r; VectorCopy(pItem->Rotation(), r);
			glTranslatex(v[0], v[1], v[2]);
			glRotatex(r[0], 1, 0, 0);
			glRotatex(r[1], 0, 1, 0);
			glRotatex(r[2], 0, 0, 1);

			// render item
			if (pItem->ModelIndex() > -1)
			{
				vec3_t BBMin;
				VectorAdd(pItem->OBBMin(), pItem->Position(), BBMin);

				vec3_t BBMax;
				VectorAdd(pItem->OBBMax(), pItem->Position(), BBMax);

				if (!bFrustum || pCam->IsBoxVisible(BBMin, BBMax))
					pItem->Render(this);
			}

			// recursively render item's childrens
			if (pItem->Child())
				RecursiveRender(pItem->Child(), pCam);

		glPopMatrix();

		// jump to next item on the current level
		pItem = pItem->Next();
	}
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CMobModel* CSceneGraph::AddEmptyModel()
{
	if (!m_wModelCount)
		m_pModelLibrary = (CMobModel**)MALLOC(sizeof(CMobModel*));
	else
		m_pModelLibrary = (CMobModel**)REALLOC(m_pModelLibrary, sizeof(CMobModel*) * (m_wModelCount+1));

	if (!m_pModelLibrary) return NULL;

	m_pModelLibrary[m_wModelCount] = new CMobModel();
	CMobModel* pModel = m_pModelLibrary[m_wModelCount];
	m_wModelCount++;
	return pModel;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
boolean CSceneGraph::LoadModel(char *szFile, float fXScale, float fYScale, float fZScale)
{
	CMobModel* pModel = AddEmptyModel();
	if (!pModel) return FALSE;
	boolean ok = pModel->Load(m_pEngine->Applet(), "game.dat", szFile, fXScale, fYScale, fZScale);
	return ok;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
unsigned short CSceneGraph::ModelCount()
{
	return m_wModelCount;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CMobModel* CSceneGraph::Model(unsigned short wModel)
{
	return m_pModelLibrary[wModel];
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CTexture* CSceneGraph::CreateTexture(void)
{
	if (!m_wTextureCount)
		m_pTextureLibrary = (CTexture**)MALLOC(sizeof(CTexture*));
	else
		m_pTextureLibrary = (CTexture**)REALLOC(m_pTextureLibrary, sizeof(CTexture*) * (m_wTextureCount+1));

	if (!m_pTextureLibrary) return NULL;

	m_pTextureLibrary[m_wTextureCount] = new CTexture();
	CTexture* pTex = m_pTextureLibrary[m_wTextureCount];
	m_wTextureCount++;
	return pTex;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
boolean CSceneGraph::LoadTexture(char *szFile, boolean bGenMipMap)
{
	CTexture* pTex = CreateTexture();
	boolean ok = pTex->Load(m_pEngine->Applet(), "game.dat", szFile, bGenMipMap);
	return ok;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
unsigned short CSceneGraph::TextureCount()
{
	return m_wTextureCount;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CTexture* CSceneGraph::Texture(unsigned short wTexture)
{
	return m_pTextureLibrary[wTexture];
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
boolean CSceneGraph::GenSkyBox(char *szFile, int32 iSize)
{
	word wmod = m_wModelCount;
	word wtex = m_wTextureCount;

	// make a copy of the file name
	char szName[64];
	STRCPY(szName, szFile);

	// get a pointer to the extension
	char* szExt = &szName[STRLEN(szName)-3];

	// cut the filename upto the dot.
	szName[STRLEN(szName)-4] = '\0';

	// define suffixes for the textures
	const char szSuffixes[6][3] = { "ft", "up", "lf", "rt", "bk", "dn"};
	char szTex[64];

	// define sky box coordinates and uv mapping
	int32 iBoxData[6][12] =
	{
		// front plane
		-iSize,iSize,-iSize, -iSize,-iSize,-iSize, iSize,-iSize,-iSize, iSize,iSize,-iSize,

		// up plane
		iSize,iSize,iSize, -iSize,iSize,iSize, -iSize,iSize,-iSize, iSize,iSize,-iSize,

		// left plane (engine's right)
		iSize,iSize,-iSize, iSize,-iSize,-iSize, iSize,-iSize,iSize, iSize,iSize,iSize,

		// right plane (engine's left)
		-iSize,iSize,iSize, -iSize,-iSize,iSize, -iSize,-iSize,-iSize, -iSize,iSize,-iSize,

		// back plane
		iSize,iSize,iSize, iSize,-iSize,iSize, -iSize,-iSize,iSize, -iSize,iSize,iSize,

		// down plane
		-iSize,-iSize,iSize, iSize,-iSize,iSize, iSize,-iSize,-iSize, -iSize,-iSize,-iSize
	};

	int iuv[8] = { ITOX(0),ITOX(0), ITOX(0),ITOX(1), ITOX(1),ITOX(1), ITOX(1),ITOX(0) };

	byte x;

	// batch load box textures and procedurally create sky box planes as individual models
	for (x=0; x<6; x++)
	{
		STRCPY(szTex, szName);
		STRCAT(szTex, szSuffixes[x]);
		STRCAT(szTex, ".");
		STRCAT(szTex, szExt);
		if (!LoadTexture(szTex)) return FALSE;

		// generate a new mob model for the sky box plane
		CMobModel* pModel = AddEmptyModel();
		if (!pModel) return FALSE;

		pModel->SetZWrite(FALSE);
		pModel->SetBackCull(FALSE);
		pModel->AllocSpace(4, 2);

		byte y;
		for (y=0; y<12; y++) pModel->Vertices()[y] = iBoxData[x][y];
		for (y=0; y<8; y++) pModel->TexCoords()[y] = iuv[y];
		pModel->Faces()[0] = 0;
		pModel->Faces()[1] = 1;
		pModel->Faces()[2] = 2;
		pModel->Faces()[3] = 0;
		pModel->Faces()[4] = 2;
		pModel->Faces()[5] = 3;

		#if INC_NORMALS
			pModel->RecalculateNormals();
		#endif
	}

	for (x=0; x<6; x++)
	{
		// create the item but do not add the sky box plane to the scenegraph
		// (it is a special entity)
		m_pSkyBox[x] = new CSceneItem(this, wmod+x, wtex+x);
	}

	m_bSkyBoxLoaded = TRUE;

	return TRUE;
}

⌨️ 快捷键说明

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