Exemplo n.º 1
0
CRenderingContext::CRenderingContext(CRenderer* pRenderer, bool bInherit)
{
	m_pRenderer = pRenderer;

	m_clrRender = ::Color(255, 255, 255, 255);

	s_aContexts.push_back();

	if (bInherit && s_aContexts.size() > 1)
	{
		CRenderContext& oLastContext = s_aContexts[s_aContexts.size()-2];
		CRenderContext& oThisContext = GetContext();

		oThisContext.m_mProjection = oLastContext.m_mProjection;
		oThisContext.m_mView = oLastContext.m_mView;
		oThisContext.m_mTransformations = oLastContext.m_mTransformations;

		oThisContext.m_hMaterial = oLastContext.m_hMaterial;
		oThisContext.m_pFrameBuffer = oLastContext.m_pFrameBuffer;
		tstrncpy(oThisContext.m_szProgram, PROGRAM_LEN, oLastContext.m_szProgram, PROGRAM_LEN);
		oThisContext.m_pShader = oLastContext.m_pShader;

		oThisContext.m_rViewport = oLastContext.m_rViewport;
		oThisContext.m_eBlend = oLastContext.m_eBlend;
		oThisContext.m_flAlpha = oLastContext.m_flAlpha;
		oThisContext.m_bDepthMask = oLastContext.m_bDepthMask;
		oThisContext.m_bDepthTest = oLastContext.m_bDepthTest;
		oThisContext.m_eDepthFunction = oLastContext.m_eDepthFunction;
		oThisContext.m_bCull = oLastContext.m_bCull;
		oThisContext.m_bWinding = oLastContext.m_bWinding;

		m_pShader = oThisContext.m_pShader;

		if (m_pShader)
			m_iProgram = m_pShader->m_iProgram;
		else
			m_iProgram = 0;
	}
	else
	{
		m_pShader = NULL;

		BindTexture(0);
		UseMaterial(CMaterialHandle());
		UseFrameBuffer(NULL);
		UseProgram("");

		SetViewport(Rect(0, 0, Application()->GetWindowWidth(), Application()->GetWindowHeight()));
		SetBlend(BLEND_NONE);
		SetAlpha(1);
		SetDepthMask(true);
		SetDepthTest(true);
		SetDepthFunction(DF_LESS);
		SetBackCulling(true);
		SetWinding(true);
	}
}
Exemplo n.º 2
0
void CRenderingContext::UseProgram(const tchar* pszProgram)
{
	tstrncpy(GetContext().m_szProgram, PROGRAM_LEN, pszProgram, PROGRAM_LEN);

	GetContext().m_pShader = m_pShader = CShaderLibrary::GetShader(pszProgram);

	if (*pszProgram)
		TAssert(m_pShader);

	UseProgram(m_pShader);
}
Exemplo n.º 3
0
void CTrayIcon::Add(const CWnd& oWnd, uint nTrayID, uint nMsgID, uint nRscID, const tchar* pszToolTip)
{
	ASSERT(m_hWnd        == NULL);
	ASSERT(m_nTrayID     == 0);
	ASSERT(m_nMsgID      == 0);
	ASSERT(oWnd.Handle() != NULL);
	ASSERT(nTrayID       != 0);
	ASSERT((pszToolTip == nullptr) || (tstrlen(pszToolTip) < MAX_TIP_LEN));

	// Save parameters.
	m_hWnd    = oWnd.Handle();
	m_nTrayID = nTrayID;
	m_nMsgID  = nMsgID;

	// Load the icon resource.
	CIcon oIcon(nRscID, ICON_WIDTH, ICON_HEIGHT);

	uint nFlags = NIF_ICON;

	// Work out which other fields to set.
	if (m_nMsgID != 0)
		nFlags |= NIF_MESSAGE;

	if (pszToolTip != nullptr)
		nFlags |= NIF_TIP;

	NOTIFYICONDATA oData = { 0 };

	// Fill in the message structure.
	oData.cbSize           = sizeof(oData);
	oData.hWnd             = m_hWnd;
	oData.uID              = m_nTrayID;
	oData.uFlags           = nFlags;
	oData.uCallbackMessage = m_nMsgID;
	oData.hIcon            = oIcon.Handle();

	if (pszToolTip != nullptr)
		tstrncpy(oData.szTip, pszToolTip, MAX_TIP_LEN-1);

	// Send message.
	::Shell_NotifyIcon(NIM_ADD, &oData);
}
Exemplo n.º 4
0
void CRenderingContext::UseProgram(class CShader* pShader)
{
	GetContext().m_pShader = m_pShader = pShader;

	if (!m_pShader)
	{
		GetContext().m_szProgram[0] = '\0';
		m_iProgram = 0;
		glUseProgram(0);
		return;
	}

	tstrncpy(GetContext().m_szProgram, PROGRAM_LEN, pShader->m_sName.c_str(), PROGRAM_LEN);

	m_iProgram = m_pShader->m_iProgram;
	glUseProgram((GLuint)m_pShader->m_iProgram);

	SetUniform("mProjection", GetContext().m_mProjection);
	SetUniform("mView", GetContext().m_mView);
}
Exemplo n.º 5
0
void CRenderingContext::UseProgram(class CShader* pShader)
{
	CRenderContext& oContext = GetContext();

	oContext.m_pShader = m_pShader = pShader;

	if (!m_pShader)
	{
		oContext.m_szProgram[0] = '\0';
		m_iProgram = 0;
		glUseProgram(0);
		return;
	}

	tstrncpy(oContext.m_szProgram, PROGRAM_LEN, pShader->m_sName.c_str(), PROGRAM_LEN);

	m_iProgram = m_pShader->m_iProgram;
	glUseProgram((GLuint)m_pShader->m_iProgram);

	oContext.m_bProjectionUpdated = false;
	oContext.m_bViewUpdated = false;
}
Exemplo n.º 6
0
void CTrayIcon::Modify(uint nRscID, const tchar* pszToolTip)
{
	ASSERT(m_hWnd    != NULL);
	ASSERT(m_nTrayID != 0);
	ASSERT(nRscID != 0 || pszToolTip != nullptr);
	ASSERT((pszToolTip == nullptr) || (tstrlen(pszToolTip) < MAX_TIP_LEN));

	uint nFlags = 0;

	// Work out which fields we're setting.
	if (nRscID != 0)
		nFlags |= NIF_ICON;

	if (pszToolTip != nullptr)
		nFlags |= NIF_TIP;

	NOTIFYICONDATA oData = { 0 };

	// Fill in the message structure.
	oData.cbSize           = sizeof(oData);
	oData.hWnd             = m_hWnd;
	oData.uID              = m_nTrayID;
	oData.uFlags           = nFlags;
	oData.uCallbackMessage = m_nMsgID;

	if (nRscID != 0)
	{
		CIcon oIcon(nRscID, ICON_WIDTH, ICON_HEIGHT);

		oData.hIcon = oIcon.Handle();
	}

	if (pszToolTip != nullptr)
		tstrncpy(oData.szTip, pszToolTip, MAX_TIP_LEN-1);

	// Send message.
	::Shell_NotifyIcon(NIM_MODIFY, &oData);
}
Exemplo n.º 7
0
// Silo ascii
void CModelConverter::ReadSIA(const tstring& sFilename)
{
	if (m_pWorkListener)
		m_pWorkListener->BeginProgress();

	CConversionSceneNode* pScene = m_pScene->GetScene(m_pScene->AddScene(GetFilename(sFilename).append(_T(".sia"))));

	if (m_pWorkListener)
		m_pWorkListener->SetAction(_T("Reading file into memory..."), 0);

	FILE* fp = tfopen(sFilename, _T("r"));

	if (!fp)
	{
		printf("No input file. Sorry!\n");
		return;
	}

	fseek(fp, 0L, SEEK_END);
	long iOBJSize = ftell(fp);
	fseek(fp, 0L, SEEK_SET);

	// Make sure we allocate more than we need just in case.
	size_t iFileSize = (iOBJSize+1) * (sizeof(tchar)+1);
	tchar* pszEntireFile = (tchar*)malloc(iFileSize);
	tchar* pszCurrent = pszEntireFile;

	// Read the entire file into an array first for faster processing.
	tstring sLine;
	while (fgetts(sLine, fp))
	{
		tstrncpy(pszCurrent, iFileSize-(pszCurrent-pszEntireFile), sLine.c_str(), sLine.length());
		size_t iLength = sLine.length();

		if (pszCurrent[iLength-1] == _T('\n'))
		{
			pszCurrent[iLength-1] = _T('\0');
			iLength--;
		}

		pszCurrent += iLength;
		pszCurrent++;

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(0);
	}

	pszCurrent[0] = _T('\0');

	fclose(fp);

	const tchar* pszLine = pszEntireFile;
	const tchar* pszNextLine = NULL;
	while (pszLine < pszCurrent)
	{
		if (pszNextLine)
			pszLine = pszNextLine;

		pszNextLine = pszLine + tstrlen(pszLine) + 1;

		// This code used to call StripWhitespace() but that's too slow for very large files w/ millions of lines.
		// Instead we'll just cut the whitespace off the front and deal with whitespace on the end when we come to it.
		while (*pszLine && IsWhitespace(*pszLine))
			pszLine++;

		if (tstrlen(pszLine) == 0)
			continue;

		eastl::vector<tstring> aTokens;
		tstrtok(pszLine, aTokens, _T(" "));
		const tchar* pszToken = aTokens[0].c_str();

		if (tstrncmp(pszToken, _T("-Version"), 8) == 0)
		{
			// Warning if version is later than 1.0, we may not support it
			int iMajor, iMinor;
			eastl::vector<tstring> asTokens;
			tstrtok(pszLine, asTokens, _T(" ."));

			if (asTokens.size() >= 3)
			{
				iMajor = stoi(asTokens[1]);
				iMinor = stoi(asTokens[2]);
				if (iMajor != 1 && iMinor != 0)
					printf("WARNING: I was programmed for version 1.0, this file is version %d.%d, so this might not work exactly right!\n", iMajor, iMinor);
			}
		}
		else if (tstrncmp(pszToken, _T("-Mat"), 4) == 0)
		{
			pszNextLine = ReadSIAMat(pszNextLine, pszCurrent, pScene, sFilename);
		}
		else if (tstrncmp(pszToken, _T("-Shape"), 6) == 0)
		{
			pszNextLine = ReadSIAShape(pszNextLine, pszCurrent, pScene);
		}
		else if (tstrncmp(pszToken, _T("-Texshape"), 9) == 0)
		{
			// This is the 3d UV space of the object, but we only care about its 2d UV space which is contained in rhw -Shape section, so meh.
			pszNextLine = ReadSIAShape(pszNextLine, pszCurrent, pScene, false);
		}
	}

	free(pszEntireFile);

	m_pScene->SetWorkListener(m_pWorkListener);

	for (size_t i = 0; i < m_pScene->GetNumMeshes(); i++)
	{
		m_pScene->GetMesh(i)->CalculateEdgeData();
		m_pScene->GetMesh(i)->CalculateVertexNormals();
		m_pScene->GetMesh(i)->CalculateVertexTangents();
	}

	m_pScene->CalculateExtends();

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();
}
Exemplo n.º 8
0
void CModelConverter::ReadOBJ(const tstring& sFilename)
{
	if (m_pWorkListener)
		m_pWorkListener->BeginProgress();

	FILE* fp = tfopen(sFilename, _T("r"));

	if (!fp)
	{
		printf("No input file. Sorry!\n");
		return;
	}

	CConversionSceneNode* pScene = m_pScene->GetScene(m_pScene->AddScene(GetFilename(sFilename).append(_T(".obj"))));

	CConversionMesh* pMesh = m_pScene->GetMesh(m_pScene->AddMesh(GetFilename(sFilename)));
	// Make sure it exists.
	CConversionSceneNode* pMeshNode = m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh);

	size_t iCurrentMaterial = ~0;
	size_t iSmoothingGroup = ~0;

	bool bSmoothingGroups = false;

	tstring sLastTask;

	int iTotalVertices = 0;
	int iTotalFaces = 0;
	int iVerticesComplete = 0;
	int iFacesComplete = 0;

	if (m_pWorkListener)
		m_pWorkListener->SetAction(_T("Reading file into memory..."), 0);

	fseek(fp, 0L, SEEK_END);
	long iOBJSize = ftell(fp);
	fseek(fp, 0L, SEEK_SET);

	// Make sure we allocate more than we need just in case.
	size_t iFileSize = (iOBJSize+1) * (sizeof(tchar)+1);
	tchar* pszEntireFile = (tchar*)malloc(iFileSize);
	tchar* pszCurrent = pszEntireFile;
	pszCurrent[0] = _T('\0');

	// Read the entire file into an array first for faster processing.
	tstring sLine;
	while (fgetts(sLine, fp))
	{
		tstrncpy(pszCurrent, iFileSize-(pszCurrent-pszEntireFile), sLine.c_str(), sLine.length());
		size_t iLength = sLine.length();

		tchar cLastChar = pszCurrent[iLength-1];
		while (cLastChar == _T('\n') || cLastChar == _T('\r'))
		{
			pszCurrent[iLength-1] = _T('\0');
			iLength--;
			cLastChar = pszCurrent[iLength-1];
		}

		pszCurrent += iLength;
		pszCurrent++;

		if (m_pWorkListener)
			m_pWorkListener->WorkProgress(0);
	}

	pszCurrent[0] = _T('\0');

	fclose(fp);

	const tchar* pszLine = pszEntireFile;
	const tchar* pszNextLine = NULL;
	while (pszLine < pszCurrent)
	{
		if (pszNextLine)
			pszLine = pszNextLine;

		pszNextLine = pszLine + tstrlen(pszLine) + 1;

		// This code used to call StripWhitespace() but that's too slow for very large files w/ millions of lines.
		// Instead we'll just cut the whitespace off the front and deal with whitespace on the end when we come to it.
		while (*pszLine && IsWhitespace(*pszLine))
			pszLine++;

		if (tstrlen(pszLine) == 0)
			continue;

		if (pszLine[0] == '#')
		{
			// ZBrush is kind enough to notate exactly how many vertices and faces we have in the comments at the top of the file.
			if (tstrncmp(pszLine, _T("#Vertex Count"), 13) == 0)
			{
				iTotalVertices = stoi(pszLine+13);
				pMesh->SetTotalVertices(iTotalVertices);
			}

			if (tstrncmp(pszLine, _T("#Face Count"), 11) == 0)
			{
				iTotalFaces = stoi(pszLine+11);
				pMesh->SetTotalFaces(iTotalFaces);

				// Don't kill the video card while we're loading the faces.
				if (iTotalFaces > 10000)
					pMeshNode->GetMeshInstance(0)->SetVisible(false);
			}

			continue;
		}

		tchar szToken[1024];
		tstrncpy(szToken, 1024, pszLine, 1024);
		tchar* pszState = NULL;
		tchar* pszToken = strtok<tchar>(szToken, " ", &pszState);

		if (tstrncmp(pszToken, _T("mtllib"), 6) == 0)
		{
			tstring sDirectory = GetDirectory(sFilename);
			tstring sMaterial = sprintf(tstring("%s/%s"), sDirectory.c_str(), pszLine + 7);
			ReadMTL(sMaterial);
		}
		else if (tstrncmp(pszToken, _T("o"), 1) == 0)
		{
			// Dunno what this does.
		}
		else if (tstrncmp(pszToken, _T("v"), 2) == 0)
		{
			if (m_pWorkListener)
			{
				if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0)
					m_pWorkListener->WorkProgress(iVerticesComplete++);
				else
				{
					m_pWorkListener->SetAction(_T("Reading vertex data"), iTotalVertices);
					sLastTask = tstring(pszToken);
				}
			}

			// A vertex.
			float v[3];
			// scanf is pretty slow even for such a short string due to lots of mallocs.
			const tchar* pszToken = pszLine+1;
			int iDimension = 0;
			while (*pszToken)
			{
				while (pszToken[0] == _T(' '))
					pszToken++;

				v[iDimension++] = (float)stof(pszToken);
				if (iDimension >= 3)
					break;

				while (pszToken[0] != _T(' '))
					pszToken++;
			}
			pMesh->AddVertex(v[0], v[1], v[2]);
		}
		else if (tstrncmp(pszToken, _T("vn"), 3) == 0)
		{
			if (m_pWorkListener)
			{
				if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0)
					m_pWorkListener->WorkProgress(0);
				else
					m_pWorkListener->SetAction(_T("Reading vertex normal data"), 0);
			}
			sLastTask = tstring(pszToken);

			// A vertex normal.
			float x, y, z;
			eastl::vector<tstring> asTokens;
			tstrtok(pszLine, asTokens, _T(" "));
			if (asTokens.size() == 4)
			{
				x = stof(asTokens[1]);
				y = stof(asTokens[2]);
				z = stof(asTokens[3]);
				pMesh->AddNormal(x, y, z);
			}
		}
		else if (tstrncmp(pszToken, _T("vt"), 3) == 0)
		{
			if (m_pWorkListener)
			{
				if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0)
					m_pWorkListener->WorkProgress(0);
				else
					m_pWorkListener->SetAction(_T("Reading texture coordinate data"), 0);
			}
			sLastTask = tstring(pszToken);

			// A UV coordinate for a vertex.
			float u, v;
			eastl::vector<tstring> asTokens;
			tstrtok(pszLine, asTokens, _T(" "));
			if (asTokens.size() == 3)
			{
				u = stof(asTokens[1]);
				v = stof(asTokens[2]);
				pMesh->AddUV(u, v);
			}
		}
		else if (tstrncmp(pszToken, _T("g"), 1) == 0)
		{
			// A group of faces.
			pMesh->AddBone(pszLine+2);
		}
		else if (tstrncmp(pszToken, _T("usemtl"), 6) == 0)
		{
			// All following faces should use this material.
			tstring sMaterial = tstring(pszLine+7);
			size_t iMaterial = pMesh->FindMaterialStub(sMaterial);
			if (iMaterial == ((size_t)~0))
			{
				size_t iSceneMaterial = m_pScene->FindMaterial(sMaterial);
				if (iSceneMaterial == ((size_t)~0))
					iCurrentMaterial = m_pScene->AddDefaultSceneMaterial(pScene, pMesh, sMaterial);
				else
				{
					size_t iMaterialStub = pMesh->AddMaterialStub(sMaterial);
					m_pScene->GetDefaultSceneMeshInstance(pScene, pMesh)->GetMeshInstance(0)->AddMappedMaterial(iMaterialStub, iSceneMaterial);
					iCurrentMaterial = iMaterialStub;
				}
			}
			else
				iCurrentMaterial = iMaterial;
		}
		else if (tstrncmp(pszToken, _T("s"), 1) == 0)
		{
			if (tstrncmp(pszLine, _T("s off"), 5) == 0)
			{
				iSmoothingGroup = ~0;
			}
			else
			{
				bSmoothingGroups = true;
				eastl::vector<tstring> asTokens;
				tstrtok(pszLine, asTokens, _T(" "));
				if (asTokens.size() == 2)
					iSmoothingGroup = stoi(asTokens[1]);
			}
		}
		else if (tstrncmp(pszToken, _T("f"), 1) == 0)
		{
			if (m_pWorkListener)
			{
				if (tstrncmp(sLastTask.c_str(), pszToken, sLastTask.length()) == 0)
					m_pWorkListener->WorkProgress(iFacesComplete++);
				else
				{
					m_pWorkListener->SetAction(_T("Reading polygon data"), iTotalFaces);
					sLastTask = tstring(pszToken);
				}
			}

			if (iCurrentMaterial == ~0)
				iCurrentMaterial = m_pScene->AddDefaultSceneMaterial(pScene, pMesh, pMesh->GetName());

			// A face.
			size_t iFace = pMesh->AddFace(iCurrentMaterial);

			// If we get to 10k faces force the mesh off so it doesn't kill the video card.
			if (iFace == 10000)
				pMeshNode->GetMeshInstance(0)->SetVisible(false);

			pMesh->GetFace(iFace)->m_iSmoothingGroup = iSmoothingGroup;

			while (pszToken = strtok<tchar>(NULL, _T(" "), &pszState))
			{
				if (tstrlen(pszToken) == 0)
					continue;

				// We don't use size_t because SOME EXPORTS put out negative numbers.
				long f[3];
				bool bValues[3];
				bValues[0] = false;
				bValues[1] = false;
				bValues[2] = false;

				// scanf is pretty slow even for such a short string due to lots of mallocs.
				const tchar* pszValues = pszToken;
				int iValue = 0;
				do
				{
					if (!pszValues)
						break;

					if (!bValues[0] || pszValues[0] == _T('/'))
					{
						if (pszValues[0] == _T('/'))
							pszValues++;

						bValues[iValue] = true;
						f[iValue++] = (long)stoi(pszValues);
						if (iValue >= 3)
							break;
					}

					// Don't advance if we're on a slash, because that means empty slashes. ie, 11//12 <-- the 12 would get skipped.
					if (pszValues[0] != _T('/'))
						pszValues++;
				}
				while (*pszValues);

				if (bValues[0])
				{
					if (f[0] < 0)
						f[0] = (long)pMesh->GetNumVertices()+f[0]+1;
					TAssert ( f[0] >= 1 && f[0] < (long)pMesh->GetNumVertices()+1 );
				}

				if (bValues[1] && pMesh->GetNumUVs())
				{
					if (f[1] < 0)
						f[1] = (long)pMesh->GetNumUVs()+f[1]+1;
					TAssert ( f[1] >= 1 && f[1] < (long)pMesh->GetNumUVs()+1 );
				}

				if (bValues[2] && pMesh->GetNumNormals())
				{
					if (f[2] < 0)
						f[2] = (long)pMesh->GetNumNormals()+f[2]+1;
					TAssert ( f[2] >= 1 && f[2] < (long)pMesh->GetNumNormals()+1 );
				}

				// OBJ uses 1-based indexing.
				// Convert to 0-based indexing.
				f[0]--;
				f[1]--;
				f[2]--;

				if (!pMesh->GetNumUVs())
					f[1] = ~0;
				if (bValues[2] == false || !pMesh->GetNumNormals())
					f[2] = ~0;

				pMesh->AddVertexToFace(iFace, f[0], f[1], f[2]);
			}
		}
	}

	free(pszEntireFile);

	m_pScene->SetWorkListener(m_pWorkListener);

	m_pScene->CalculateExtends();

	for (size_t i = 0; i < m_pScene->GetNumMeshes(); i++)
	{
		m_pScene->GetMesh(i)->CalculateEdgeData();

		if (bSmoothingGroups || m_pScene->GetMesh(i)->GetNumNormals() == 0)
			m_pScene->GetMesh(i)->CalculateVertexNormals();

		m_pScene->GetMesh(i)->CalculateVertexTangents();
	}

	if (m_pWorkListener)
		m_pWorkListener->EndProgress();
}