示例#1
0
/*!****************************************************************************
 @Function		ReleaseView
 @Return		bool		true if no error occurred
 @Description	Code in ReleaseView() will be called by PVRShell when the
				application quits or before a change in the rendering context.
******************************************************************************/
bool OGLES3MagicLantern::ReleaseView()
{
	// Delete all effects.
	for (unsigned int i=0; i<m_ppEffectParser->GetNumberEffects(); i++)
	{
		delete m_pFX[i];
	}

	// Delete the PFX container.
	delete m_ppEffectParser;

	// Delete buffer objects.
	glDeleteBuffers(m_Scene.nNumMesh, m_puiVbo);
	glDeleteBuffers(m_Scene.nNumMesh, m_puiIndexVbo);

	// Release loaded textures
	for(unsigned int uiIndex = 0; uiIndex < m_TextureCache.GetSize(); ++uiIndex)
	{
		GLuint uiHandle = m_TextureCache.GetDataAtIndex(uiIndex)->uiHandle;
		glDeleteTextures(1, &uiHandle);
	}

	m_TextureCache.Clear();

	// Release Print3D Textures
	m_Print3D.ReleaseTextures();

	return true;
}
示例#2
0
/*!***************************************************************************
@Function		PVRTPFXOnLoadTexture
@Input			TextureName
@Output			uiHandle
@Output			uiFlags
@Return			EPVRTError	PVR_SUCCESS on success.
@Description	Callback function on texture load.
*****************************************************************************/
EPVRTError OGLES3MagicLantern::PVRTPFXOnLoadTexture(const CPVRTStringHash& TextureName, GLuint& uiHandle, unsigned int& uiFlags)
{
	/*
		Because we have multiple effects being loaded yet the textures remain the same we can
		efficiently cache texture IDs and only load a texture once but assign it to
		multiple effects.
	*/

	// Check if the texture already exists in the map
	if(m_TextureCache.Exists(TextureName))
	{
		const STextureData& TexData = m_TextureCache[TextureName];
		uiHandle = TexData.uiHandle;
		uiFlags  = TexData.uiFlags;
		return PVR_SUCCESS;
	}

	// Texture is not loaded. Load and add to the map.
	PVRTextureHeaderV3 sHeader;
	if(PVRTTextureLoadFromPVR(TextureName.c_str(), &uiHandle, &sHeader) != PVR_SUCCESS)
		return PVR_FAIL;

	uiFlags = 0;
	if(sHeader.u32NumFaces == 6)
		uiFlags |= PVRTEX_CUBEMAP;

	STextureData& TexData = m_TextureCache[TextureName];
	TexData.uiFlags  = uiFlags;
	TexData.uiHandle = uiHandle;

	return PVR_SUCCESS;
}
示例#3
0
/*!****************************************************************************
 @Function		LoadTextures
 @Output		pErrorStr		A CPVRTString describing the error on failure
 @Return		bool			true if no error occured
 @Description	Loads the textures required for this training course
******************************************************************************/
bool OGLES3ShadowMapping::LoadTextures(CPVRTString* const pszErrorStr)
{
	for (unsigned int i=0; i < c_uiNumTextureNames; i++)
	{		
		// Check if the texture already exists in the map
		if(m_TextureCache.Exists(c_sTextureNames[i]))
			continue;

		CPVRTString filename = c_sTextureNames[i].String() + CPVRTString(".pvr");
		
		// Texture is not loaded. Load and add to the map.
		GLuint uiHandle;
		PVRTextureHeaderV3 sHeader;
		if(PVRTTextureLoadFromPVR(filename.c_str(), &uiHandle, &sHeader) != PVR_SUCCESS)
		{
			*pszErrorStr = CPVRTString("Failed to load texture: ") + filename;
			return false;		
		}

		m_TextureCache[c_sTextureNames[i]] = uiHandle;		
	}	
	
	return true;
}
示例#4
0
/*!****************************************************************************
 @Function		RenderSceneWithEffect
 @Return		bool		true if no error occured
 @Description	Renders the whole scene with a single effect.
******************************************************************************/
bool OGLES3ShadowMapping::RenderSceneWithEffect(const int uiEffectId, const PVRTMat4 &mProjection, const PVRTMat4 &mView)
{
	CPVRTPFXEffect *pEffect = m_ppPFXEffects[uiEffectId];

	// Activate the passed effect
	pEffect->Activate();
	
	for (unsigned int i=0; i < m_Scene.nNumMeshNode; i++)
	{
		SPODNode* pNode = &m_Scene.pNode[i];
		SPODMesh* pMesh = &m_Scene.pMesh[pNode->nIdx];
		SPODMaterial *pMaterial = 0;

		if (pNode->nIdxMaterial != -1)
		{
			pMaterial = &m_Scene.pMaterial[pNode->nIdxMaterial];	

			// Bind the texture if there is one bound to this object
			if (pMaterial->nIdxTexDiffuse != -1)
			{	
				CPVRTString texname = CPVRTString(m_Scene.pTexture[pMaterial->nIdxTexDiffuse].pszName).substitute(".png", "");
				CPVRTStringHash hashedName(texname);
				if (m_TextureCache.Exists(hashedName))
					glBindTexture(GL_TEXTURE_2D, m_TextureCache[hashedName]);
			}
		}
		
		glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i]);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]);

		// Pre-calculate commonly used matrices
		PVRTMat4 mWorld;
		m_Scene.GetWorldMatrix(mWorld, *pNode);
		PVRTMat4 mWorldView = mView * mWorld;

		// Bind semantics
		const CPVRTArray<SPVRTPFXUniform>& Uniforms = pEffect->GetUniformArray();
		for(unsigned int j = 0; j < Uniforms.GetSize(); ++j)
		{
			switch(Uniforms[j].nSemantic)
			{
			case ePVRTPFX_UsPOSITION:
				{
					glVertexAttribPointer(Uniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
					glEnableVertexAttribArray(Uniforms[j].nLocation);
				}
				break;
			case ePVRTPFX_UsNORMAL:
				{
					glVertexAttribPointer(Uniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
					glEnableVertexAttribArray(Uniforms[j].nLocation);
				}
				break;
			case ePVRTPFX_UsUV:
				{
					glVertexAttribPointer(Uniforms[j].nLocation, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);
					glEnableVertexAttribArray(Uniforms[j].nLocation);
				}
				break;
			case ePVRTPFX_UsMATERIALCOLORDIFFUSE:
				{										
					if (pMaterial)
						glUniform4f(Uniforms[j].nLocation, pMaterial->pfMatDiffuse[0], pMaterial->pfMatDiffuse[1], pMaterial->pfMatDiffuse[2], 1.0f);
				}
				break;			
			case ePVRTPFX_UsWORLDVIEWPROJECTION:
				{
					PVRTMat4 mWorldViewProj = mProjection * mWorldView;					
					glUniformMatrix4fv(Uniforms[j].nLocation, 1, GL_FALSE, mWorldViewProj.f);
				}
				break;
			case ePVRTPFX_UsWORLDI:
				{
					PVRTMat3 mWorldI3x3(mWorld.inverse());
					glUniformMatrix3fv(Uniforms[j].nLocation, 1, GL_FALSE, mWorldI3x3.f);
				}
				break;
			case ePVRTPFX_UsWORLDVIEWIT:
				{
					PVRTMat3 mWorldViewIT3x3(mWorldView.inverse().transpose());
					glUniformMatrix3fv(Uniforms[j].nLocation, 1, GL_FALSE, mWorldViewIT3x3.f);
				}
				break;
			case ePVRTPFX_UsTEXTURE:
				{
					// Set the sampler variable to the texture unit
					glUniform1i(Uniforms[j].nLocation, Uniforms[j].nIdx);
				}		
				break;			
			case ePVRTPFX_UsLIGHTPOSWORLD:
				{					
					glUniform3fv(Uniforms[j].nLocation, 1, m_vLightPosition.ptr());
				}
				break;			
			case eCUSTOMSEMANTIC_SHADOWTRANSMATRIX:
				{					
					// We need to calculate the texture projection matrix. This matrix takes the pixels from world space to previously rendered light projection space
					//where we can look up values from our saved depth buffer. The matrix is constructed from the light view and projection matrices as used for the previous render and 
					//then multiplied by the inverse of the current view matrix.
					//PVRTMat4 mTextureMatrix = m_mBiasMatrix * m_mLightProjection *  m_mLightView * mView.inverse();
					PVRTMat4 mTextureMatrix = m_mBiasMatrix * m_mLightProjection *  m_mLightView * mWorld;
					glUniformMatrix4fv(Uniforms[j].nLocation, 1, GL_FALSE, mTextureMatrix.f);
				}
				break;
			case ePVRTPFX_UsRANDOM:
				{					
					glUniform1f(Uniforms[j].nLocation, m_fBias);
				}
				break;			
			default:
				{
					PVRShellOutputDebug("Error: Unhandled semantic in RenderSceneWithEffect()\n");
					return false;
				}
			}
		}

		//	Now that all uniforms are set and the materials ready, draw the mesh.		
		glDrawElements(GL_TRIANGLES, pMesh->nNumFaces*3, GL_UNSIGNED_SHORT, 0);

		// Disable all vertex attributes
		for(unsigned int j = 0; j < Uniforms.GetSize(); ++j)
		{
			switch(Uniforms[j].nSemantic)
			{
			case ePVRTPFX_UsPOSITION:
			case ePVRTPFX_UsNORMAL:
			case ePVRTPFX_UsUV:
				glDisableVertexAttribArray(Uniforms[j].nLocation);
				break;
			}
		}
	}

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	return true;
}