Esempio n. 1
0
/*!***************************************************************************
@Function		LoadEffect
@Output			ppEffect
@Input			pszEffectName
@Input			pszFileName
@Return			bool	
@Description	Loads a PFX Effect.
*****************************************************************************/
bool OGLES3Skybox2::LoadEffect( CPVRTPFXEffect **ppEffect, const char * pszEffectName, const char *pszFileName )
{
	if(!ppEffect)
		return false;

	unsigned int	nUnknownUniformCount;
	CPVRTString		error;
	CPVRTPFXEffect* pEffect = *ppEffect;

	// Load an effect from the file
	if(!pEffect)
	{
		*ppEffect = new CPVRTPFXEffect();
		pEffect   = *ppEffect;

		if(!pEffect)
		{
			delete m_pEffectParser;
			PVRShellSet(prefExitMessage, "Failed to create effect.\n");
			return false;
		}
	}

	if(pEffect->Load(*m_pEffectParser, pszEffectName, pszFileName, NULL, nUnknownUniformCount, &error) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, error.c_str());
		return false;
	}

	if(nUnknownUniformCount)
	{
		PVRShellOutputDebug(error.c_str());
		PVRShellOutputDebug("Unknown uniform semantic count: %d\n", nUnknownUniformCount);
	}

	/* Set the textures for each effect */
	unsigned int			i,j ;
	const CPVRTArray<SPVRTPFXTexture>& sTex = pEffect->GetTextureArray();

	for(i = 0; i < sTex.GetSize(); ++i)
	{
		for(j = 0; j < g_ui32TexNo; ++j)
		{
			int iTexIdx = m_pEffectParser->FindTextureByName(sTex[i].Name);
			const CPVRTStringHash& FileName = m_pEffectParser->GetTexture(iTexIdx)->FileName;
			if(FileName == g_aszTextureNames[j])
			{
				if(j == 3 || j == 4)
					pEffect->SetTexture(i, m_ui32TextureIDs[j], PVRTEX_CUBEMAP);
				else
					pEffect->SetTexture(i, m_ui32TextureIDs[j]);
				break;
			}
		}
	}

	return true;
}
Esempio n. 2
0
/*!***************************************************************************
@Function		ChangeSkyboxTo
@Output			pEffect
@Input			ui32NewSkybox
@Description	Changes the skybox to use the selected effect.
*****************************************************************************/
void OGLES3Skybox2::ChangeSkyboxTo(CPVRTPFXEffect *pEffect, GLuint ui32NewSkybox)
{
	const CPVRTArray<SPVRTPFXTexture>& sTex = pEffect->GetTextureArray();

	for(unsigned int i = 0; i < sTex.GetSize(); ++i)
	{
		int iTexIdx = m_pEffectParser->FindTextureByName(sTex[i].Name);
		const CPVRTStringHash& FileName = m_pEffectParser->GetTexture(iTexIdx)->FileName;

		if(FileName == g_aszTextureNames[3])
		{
			pEffect->SetTexture(i, ui32NewSkybox, PVRTEX_CUBEMAP);
			return;
		}
	}
}
Esempio n. 3
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;
}
Esempio n. 4
0
/*!****************************************************************************
 @Function		ReleaseView
 @Return		bool		true if no error occured
 @Description	Code in ReleaseView() will be called by PVRShell when the
				application quits or before a change in the rendering context.
******************************************************************************/
bool OGLES3ShadowMapping::ReleaseView()
{
	// Release textures
	{
		const CPVRTArray<SPVRTPFXTexture>&	sTex = m_ppPFXEffects[0]->GetTextureArray();
		for(unsigned int i = 0; i < sTex.GetSize(); ++i)
			glDeleteTextures(1, &sTex[i].ui);
	}

	// Release Print3D Textures
	m_Print3D.ReleaseTextures();

	glDeleteBuffers(m_Scene.nNumMeshNode, m_puiVbo);
	glDeleteBuffers(m_Scene.nNumMeshNode, m_puiIndexVbo);

	// Release the effect[s] then the parser
	if (m_pPFXEffectParser)
		for (unsigned int i=0; i < m_pPFXEffectParser->GetNumberEffects(); i++)
			if (m_ppPFXEffects[i])
				delete m_ppPFXEffects[i];
	delete [] m_ppPFXEffects;
	delete m_pPFXEffectParser;
	
	return true;
}
Esempio n. 5
0
/*!****************************************************************************
 @Function		LoadPFX
 @Return		bool			true if no error occurred
 @Description	Loads and compiles the shaders and links the shader programs
				required for this training course
******************************************************************************/
bool OGLES3ShadowMapping::LoadPFX(CPVRTString* pErrorStr)
{
	// Parse the whole PFX and store all data.
	m_pPFXEffectParser = new CPVRTPFXParser();
	if(m_pPFXEffectParser->ParseFromFile(c_szPFXFile, pErrorStr) != PVR_SUCCESS)
	{
		*pErrorStr = "Parse failed:\n" + *pErrorStr;
		return false;
	}

	// Setup all effects in the PFX file so we initialize the shaders and
	// store uniforms and attributes locations.
	unsigned int uiNumEffects = m_pPFXEffectParser->GetNumberEffects();
	m_ppPFXEffects = new CPVRTPFXEffect*[uiNumEffects];
	for (unsigned int i=0; i < uiNumEffects; i++)
		m_ppPFXEffects[i] = 0;

	// Load one by one the effects. This will also compile the shaders.
	for (unsigned int i=0; i < uiNumEffects; i++)
	{
		m_ppPFXEffects[i] = new CPVRTPFXEffect(m_sContext);
				
		if(m_ppPFXEffects[i]->RegisterUniformSemantic(c_CustomSemantics, c_uiNumCustomSemantics, pErrorStr))
		{
			*pErrorStr = "Failed to set custom semantics:\n" + *pErrorStr;
			return false;
		}

		unsigned int nUnknownUniformCount = 0;
		if(m_ppPFXEffects[i]->Load(*m_pPFXEffectParser, m_pPFXEffectParser->GetEffect(i).Name.c_str(), NULL, NULL, nUnknownUniformCount, pErrorStr)  != PVR_SUCCESS)
		{
			*pErrorStr = "Failed to load effect " + m_pPFXEffectParser->GetEffect(i).Name.String() + CPVRTString(":\n") + *pErrorStr;
			return false;
		}

		// .. upps, some uniforms are not in our table. Better to quit because something is not quite right.
		if(nUnknownUniformCount)
		{
			*pErrorStr = "Unknown uniform semantic.\n";
			return false;
		}		
	}
	
	return true;
}
Esempio n. 6
0
/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no error occurred
 @Description	Code in InitView() will be called by PVRShell upon
				initialization or after a change in the rendering context.
				Used to initialize variables that are dependent on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLES3Skybox2::InitView()
{
	// Sets the clear colour
	glClearColor(0.6f, 0.8f, 1.0f, 1.0f);

	// Enables depth test using the z-buffer
	glEnable(GL_DEPTH_TEST);

	CPVRTString ErrorStr;

	/*
		Load textures
	*/
	if(!LoadTextures(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	/*********************/
	/* Create the Skybox */
	/*********************/
	float* skyboxVertices;
	float* skyboxUVs;

	PVRTCreateSkybox( 500.0f, true, 512, &skyboxVertices, &skyboxUVs );

	glGenBuffers(1, &m_iSkyVboID);
	glBindBuffer(GL_ARRAY_BUFFER, m_iSkyVboID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 24, &skyboxVertices[0], GL_STATIC_DRAW);
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	PVRTDestroySkybox(skyboxVertices, skyboxUVs);

	/**********************/
	/* Create the Effects */
	/**********************/

	{
		// Parse the file
		m_pEffectParser = new CPVRTPFXParser();

		if(m_pEffectParser->ParseFromFile(g_pszEffectFileName, &ErrorStr) != PVR_SUCCESS)
		{
			delete m_pEffectParser;
			PVRShellSet(prefExitMessage, ErrorStr.c_str());
			return false;
		}

		m_ppEffects = new CPVRTPFXEffect*[g_ui32NoOfEffects];
		memset(m_ppEffects, 0, sizeof(CPVRTPFXEffect*) * g_ui32NoOfEffects);

		// Skybox shader
		if(!LoadEffect(&m_ppEffects[0], "skybox_effect", g_pszEffectFileName))
		{
			delete m_pEffectParser;
			delete[] m_ppEffects;
			return false;
		}

		// The Balloon Shaders
		if(!LoadEffect(&m_ppEffects[1], "balloon_effect1", g_pszEffectFileName) ||
			!LoadEffect(&m_ppEffects[2], "balloon_effect2", g_pszEffectFileName) ||
			!LoadEffect(&m_ppEffects[3], "balloon_effect3", g_pszEffectFileName) ||
			!LoadEffect(&m_ppEffects[4], "balloon_effect4", g_pszEffectFileName) ||
			!LoadEffect(&m_ppEffects[5], "balloon_effect5", g_pszEffectFileName) ||
			!LoadEffect(&m_ppEffects[6], "balloon_effect6", g_pszEffectFileName) ||
			!LoadEffect(&m_ppEffects[7], "balloon_effect7", g_pszEffectFileName))
		{
			delete m_pEffectParser;
			delete[] m_ppEffects;
			return false;
		}
	}

	// Create Geometry Buffer Objects.
	m_aiVboID = new GLuint[m_Scene.nNumMeshNode];
	glGenBuffers(m_Scene.nNumMeshNode, m_aiVboID);

	for(unsigned int i = 0; i < m_Scene.nNumMeshNode ; ++i)
	{
		SPODNode* pNode = &m_Scene.pNode[i];

		// Gets pMesh referenced by the pNode
		SPODMesh* pMesh = &m_Scene.pMesh[pNode->nIdx];

		// Genereta a vertex buffer and set the interleaved vertex datas.
		glBindBuffer(GL_ARRAY_BUFFER, m_aiVboID[i]);
		glBufferData(GL_ARRAY_BUFFER, pMesh->sVertex.nStride*pMesh->nNumVertex, pMesh->pInterleaved, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

	}

	/**********************
	** Projection Matrix **
	**********************/
	/* Projection */
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	m_mProjection = PVRTMat4::PerspectiveFovRH(PVRT_PI / 6, (float) PVRShellGet(prefWidth) / (float) PVRShellGet(prefHeight), 4.0f, 1000.0f, PVRTMat4::OGL, bRotate);

	// Calculate the model view matrix turning around the balloon
	ComputeViewMatrix();

	/* Init Values */
	bPause = false;
	fDemoFrame = 0.0;
	fBurnAnim = 0.0f;

	m_i32Effect = 1;

	// Initialise Print3D
	if(m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n");
		return false;
	}

	// Initialise variables used for the animation
	m_iTimePrev = PVRShellGetTime();

	return true;
}
/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no error occured
 @Description	Code in InitView() will be called by PVRShell upon
				initialization or after a change in the rendering context.
				Used to initialize variables that are dependant on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLESIntroducingPFX::InitView()
{
	/*
		Initialize Print3D
	*/
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

	if(m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n");
		return false;
	}

	// Sets the clear color
	glClearColor(0.6f, 0.8f, 1.0f, 1.0f);

	// Enables depth test using the z-buffer
	glEnable(GL_DEPTH_TEST);

	/*
		Loads the light direction from the scene.
	*/
	// We check the scene contains at least one
	if (m_Scene.nNumLight == 0)
	{
		PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a light\n");
		return false;
	}

	/*
		Load the effect file
	*/
	{
		unsigned int	nUnknownUniformCount;
		CPVRTString	error;

		// Parse the file
		m_pEffectParser = new CPVRTPFXParser;
		if(m_pEffectParser->ParseFromFile(c_szPfxFile, &error) != PVR_SUCCESS)
		{
			PVRShellSet(prefExitMessage, error.c_str());
			return false;
		}

		// Load an effect from the file
		m_pEffect = new CPVRTPFXEffect();
		if(m_pEffect->Load(*m_pEffectParser, "Effect", c_szPfxFile, &error) != PVR_SUCCESS)
		{
			PVRShellSet(prefExitMessage, error.c_str());
			return false;
		}

		// Generate uniform array
		if(m_pEffect->BuildUniformTable(
			&m_psUniforms, &m_nUniformCnt, &nUnknownUniformCount,
			c_psUniformSemantics, sizeof(c_psUniformSemantics) / sizeof(*c_psUniformSemantics),
			&error) != PVR_SUCCESS)
		{
			PVRShellOutputDebug(error.c_str());
			return false;
		}
		if(nUnknownUniformCount)
		{
			PVRShellOutputDebug(error.c_str());
			PVRShellOutputDebug("Unknown uniform semantic count: %d\n", nUnknownUniformCount);
		}
	}

	/*
		Loads the textures.
		For a more detailed explanation, see Texturing and IntroducingPVRTools
	*/
	{
		const SPVRTPFXTexture	*psTex;
		unsigned int			nCnt, i;
		GLuint					ui;

		psTex = m_pEffect->GetTextureArray(nCnt);

		for(i = 0; i < nCnt; ++i)
		{
			if(strcmp(psTex[i].p, "Reflection.pvr") == 0)
			{
				if(PVRTTextureLoadFromPVR(c_szReflectTexFile, &ui) != PVR_SUCCESS)
				{
					PVRShellSet(prefExitMessage, "ERROR: Cannot load the texture\n");
					return false;
				}
			
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

				m_pEffect->SetTexture(i, ui);
			}
			else if (strcmp(psTex[i].p, "Basetex.pvr") == 0)
			{
				if(PVRTTextureLoadFromPVR(c_szBaseTexFile, &ui) != PVR_SUCCESS)
				{
					PVRShellSet(prefExitMessage, "ERROR: Cannot load the texture\n");
					return false;
				}
			
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
				
				m_pEffect->SetTexture(i, ui);
			}
			else
			{
				PVRShellOutputDebug("Warning: effect file requested unrecognised texture: \"%s\"\n", psTex[i].p);
				m_pEffect->SetTexture(i, 0);
			}
		}
	}

	// Create buffer objects.
	m_aiVboID = new GLuint[m_Scene.nNumMeshNode];
	glGenBuffers(m_Scene.nNumMeshNode, m_aiVboID);
	for(int i = 0; i < (int)m_Scene.nNumMeshNode ; i++)
	{
		SPODNode* pNode = &m_Scene.pNode[i];

		// Gets pMesh referenced by the pNode
		SPODMesh* pMesh = &m_Scene.pMesh[pNode->nIdx];

		// Generate a vertex buffer and set the interleaved vertex data.
		glBindBuffer(GL_ARRAY_BUFFER, m_aiVboID[i]);
		glBufferData(GL_ARRAY_BUFFER, pMesh->sVertex.nStride*pMesh->nNumVertex, pMesh->pInterleaved, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
	}

	return true;
}
/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no error occured
 @Description	Code in InitView() will be called by PVRShell upon
				initialization or after a change in the rendering context.
				Used to initialize variables that are dependant on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLES3IntroducingPFX::InitView()
{
	/*
		Initialize Print3D
	*/
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

	if(m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n");
		return false;
	}

	// Sets the clear color
	glClearColor(0.6f, 0.8f, 1.0f, 1.0f);

	// Enables depth test using the z-buffer
	glEnable(GL_DEPTH_TEST);

	/*
		Loads the light direction from the scene.
	*/
	// We check the scene contains at least one
	if (m_Scene.nNumLight == 0)
	{
		PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a light\n");
		return false;
	}

	// Load the VBOs
	LoadVBOs();

	/*
		Load the effect file
	*/
	CPVRTString	error;
	unsigned int uiUnknownUniforms;

	// Parse the file
	m_pEffectParser = new CPVRTPFXParser;
	if(m_pEffectParser->ParseFromFile(c_szPfxFile, &error) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, error.c_str());
		return false;
	}

	// --- Load an effect from the file
	m_pEffect = new CPVRTPFXEffect();

	// Register a custom uniform
	if(m_pEffect->RegisterUniformSemantic(c_sCustomSemantics, sizeof(c_sCustomSemantics) / sizeof(c_sCustomSemantics[0]), &error) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, error.c_str());
		return false;
	}

	/* 
		Load the effect.
		We pass 'this' as an argument as we wish to receive callbacks as the PFX is loaded.
		This is optional and supplying NULL implies that the developer will take care
		of all texture loading and binding to to the Effect instead.
	*/
	if(m_pEffect->Load(*m_pEffectParser, "Effect", c_szPfxFile, this, uiUnknownUniforms, &error) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, error.c_str());
		return false;
	}

	/*
		'Unknown uniforms' are uniform semantics that have been detected in the PFX file
		but are unknown to PVRTools. If you wish to utilise this semantic, register
		the semantic by calling RegisterUniformSemantic(). This is performed above.
	*/
	if(uiUnknownUniforms)
	{
		PVRShellOutputDebug(error.c_str());
		PVRShellOutputDebug("Unknown uniform semantic count: %u\n", uiUnknownUniforms);
	}

	// Enable culling
	glEnable(GL_CULL_FACE);
	return true;
}
Esempio n. 9
0
/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no error occured
 @Description	Code in InitView() will be called by PVRShell upon
				initialization or after a change in the rendering context.
				Used to initialize variables that are dependant on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLES3ShadowMapping::InitView()
{
	CPVRTString ErrorStr;	    
    
	m_bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

	// Initialize VBO data
	if(!LoadVbos(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	//	Load textures
	if (!LoadTextures(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	//	Load and compile the shaders & link programs
	if (!LoadPFX(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	// Map the individual effects to make it easier to address them
	for (unsigned int i=0; i < m_pPFXEffectParser->GetNumberEffects(); i++)
	{
		// Store the indices for the individual effects
		if (m_pPFXEffectParser->GetEffect(i).Name == c_RenderShadowMapEffectName)
			m_iEffectIndex[INDEX_RENDERSHADOW] = i;
		else if (m_pPFXEffectParser->GetEffect(i).Name == c_RenderSceneEffectName)
			m_iEffectIndex[INDEX_RENDERSCENE] = i;		
	}	

	if (!CreateFBO(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	//	Initialize Print3D
	if (m_Print3D.SetTextures(0, PVRShellGet(prefWidth), PVRShellGet(prefHeight),m_bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialize Print3D\n");
		return false;
	}

	// Use a nice bright blue as clear colour
	glClearColor(0.6f, 0.8f, 1.0f, 1.0f);

	// Enable culling
	glEnable(GL_CULL_FACE);	

	// and depth testing
	glEnable(GL_DEPTH_TEST);

	return true;
}
Esempio n. 10
0
/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no error occured
 @Description	Code in InitView() will be called by PVRShell upon
                initialization or after a change in the rendering context.
                Used to initialize variables that are dependant on the rendering
                context (e.g. textures, vertex buffers, etc.)
 ******************************************************************************/
bool OGLES2MaximumIntensityBlend::InitView()
{
	/*
	 Check that EXT_blend_minmax is supported
	 */
	if(!CPVRTgles2Ext::IsGLExtensionSupported("GL_EXT_blend_minmax"))
	{
		PVRShellSet(prefExitMessage, "ERROR: GL_EXT_blend_minmax extension is required to run this example.");
		return false;
	}
	
	/*
	 Initialize Print3D
	 */
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	
	if(m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n");
		return false;
	}
	
	// Sets the clear color
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	
	glEnable(GL_CULL_FACE);
	glFrontFace(GL_CW);
	
	// Load the VBOs
	LoadVBOs();
	
	/*
	 Load the effect file
	 */
	CPVRTString	error;
	unsigned int uiUnknownUniforms;
	
	// Parse the file
	m_pEffectParser = new CPVRTPFXParser;
	if(m_pEffectParser->ParseFromFile(c_szPfxFile, &error) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, error.c_str());
		return false;
	}
	
	// --- Load an effect from the file
	m_pEffect = new CPVRTPFXEffect();
	m_pEffect->RegisterUniformSemantic(c_sCustomSemantics, sizeof(c_sCustomSemantics) / sizeof(c_sCustomSemantics[0]), &error);
	
	/*
	 Load the effect.
	 */
	if(m_pEffect->Load(*m_pEffectParser, "Effect", c_szPfxFile, NULL, uiUnknownUniforms, &error) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, error.c_str());
		return false;
	}
	
	// --- Load the textured effect
	m_pEffectTextured = new CPVRTPFXEffect();
	m_pEffectTextured->RegisterUniformSemantic(c_sCustomSemantics, sizeof(c_sCustomSemantics) / sizeof(c_sCustomSemantics[0]), &error);
	
	/*
	 Load the effect.
	 */
	if(m_pEffectTextured->Load(*m_pEffectParser, "TexturedEffect", c_szPfxFile, this, uiUnknownUniforms, &error) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, error.c_str());
		return false;
	}
	
	return true;
}
Esempio n. 11
0
/*!****************************************************************************
 @Function		LoadPFX
 @Output		pErrorStr		A string describing the error on failure
 @Return		bool			true if no error occurred
 @Description	Loads and compiles the shaders and links the shader programs
				required for this training course
******************************************************************************/
bool OGLES3MagicLantern::LoadPFX(void)
{
	CPVRTString error = "";
	
	// Parse the whole PFX and store all data.
	m_ppEffectParser = new CPVRTPFXParser();
	if(m_ppEffectParser->ParseFromFile(c_szPFXSrcFile, &error) != PVR_SUCCESS)
	{
		error = "Parse failed:\n\n" + error;
		PVRShellSet(prefExitMessage, error.c_str());
		return false;
	}

	// Setup all effects in the PFX file so we initialise the shaders and
	// store uniforms and attributes locations.
	unsigned int uNumEffects = m_ppEffectParser->GetNumberEffects();
	for (unsigned int i=0; i<uNumEffects; i++)
	{
		// Load one by one the effects. This will also compile the shaders.
		m_pFX[i] = new CPVRTPFXEffect();
		unsigned int nUnknownUniformCount = 0;
		if(m_pFX[i]->Load(*m_ppEffectParser, m_ppEffectParser->GetEffect(i).Name.c_str(), NULL, this, nUnknownUniformCount, &error)  != PVR_SUCCESS)
		{
			error = "Effect load failed:\n\n" + error;
			PVRShellSet(prefExitMessage, error.c_str());
			return false;
		}

		// .. upps, some uniforms are not in our table. Better to quit because something is not quite right.
		if(nUnknownUniformCount)
		{
			PVRShellOutputDebug(error.c_str());
			PVRShellOutputDebug("Unknown uniform semantic count: %d\n", nUnknownUniformCount);
			return false;
		}
	}

	// Allocate an array of integers to hold an effect ID per material.
	m_puiMaterialEffectID = new GLuint[m_Scene.nNumMaterial];
	
	// Assign an effect to each material based on its name.
	// If there is a material with an effect name which is not in the PFX 
	// file, the application will quit and report an error.
	for(int i = 0; i < (int) m_Scene.nNumMaterial; ++i)
	{
		SPODMaterial* pMaterial = &m_Scene.pMaterial[i];

		m_puiMaterialEffectID[i] = 0xbad;

		for (unsigned int j=0; j<uNumEffects; j++)
		{
			// Compare the effect string in the material to each effect in our file so we can
			// match effects to meshes.
			// All effects are contained in the same PFX file so we do not have to worry about
			// effects spread across several files.
			// Note: Each material can only contain a single effect but the same effect
			// might be applied to several materials.
			if (m_ppEffectParser->GetEffect(j).Name == pMaterial->pszEffectName)
			{
				m_puiMaterialEffectID[i] = j;
			}
		}

		if(m_puiMaterialEffectID[i] == 0xbad)
		{
			PVRShellOutputDebug("ERROR: %s effect not found in PFX\n", pMaterial->pszEffectName);
			return false;
		}
	}

	return true;
}
Esempio n. 12
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occurred
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevant OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES3MagicLantern::RenderScene()
{
	PVRTMat4 mLightWorld;

	// Clear the color and depth buffer.
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Time based animation and locks the app to 60 FPS.
	// Uses the shell function PVRShellGetTime() to get the time in milliseconds.
	unsigned long ulTime = PVRShellGetTime();
	unsigned long ulDeltaTime = ulTime - m_ulTimePrev;
	m_ulTimePrev = ulTime;
	m_fFrame += (float)ulDeltaTime * (60.0f/1000.0f);

	// Create an animation for the the position and rotation of the light-ball.
	m_LightPosition.x = cos(m_fFrame/140.0f)*60.0f;
	m_LightPosition.z = sin(m_fFrame/70.0f)*60.0f - 40.0f;
	m_LightPosition.y = sin(m_fFrame/100.0f)*20.0f;

	mLightWorld  = PVRTMat4::Translation(m_LightPosition.x, m_LightPosition.y-10, m_LightPosition.z);
	mLightWorld *= PVRTMat4::RotationX(m_fFrame/540.0f);
	mLightWorld *= PVRTMat4::RotationZ(m_fFrame/370.0f);
	
	// To draw a scene, you must go through all the MeshNodes and draw the referenced meshes.
	for (unsigned int i = 0; i < m_Scene.nNumMeshNode; ++i)
	{
		SPODNode& Node = m_Scene.pNode[i]; 

		// Get the current effect from the material ID. The list of IDs was built in LoadPFX()
		GLuint uiFXID = m_puiMaterialEffectID[Node.nIdxMaterial];

		// Use the loaded effect (Vertex and Fragment shader)
		// And also bind all textures in the effect.
		m_pFX[uiFXID]->Activate();
		
		// Set the blend mode
		// Based in the info stored in the material by PVRShaman.
		// We check whether the blend mode is 'opaque' (ONE,ZERO).
		// Otherwise we enable blending and set the corresponding operations.
		if (m_Scene.pMaterial[Node.nIdxMaterial].eBlendSrcRGB == ePODBlendFunc_ONE && m_Scene.pMaterial[Node.nIdxMaterial].eBlendDstRGB == ePODBlendFunc_ZERO)
		{
			glDisable(GL_BLEND);
		}
		else
		{
			glEnable(GL_BLEND);
			glBlendFunc(m_Scene.pMaterial[Node.nIdxMaterial].eBlendSrcRGB, m_Scene.pMaterial[Node.nIdxMaterial].eBlendDstRGB);
		}

		// Now process PVRShaman semantics and set-up the associated uniforms.
		const CPVRTArray<SPVRTPFXUniform>& Uniforms = m_pFX[uiFXID]->GetUniformArray();
		for(unsigned int j = 0; j < Uniforms.GetSize() ; ++j)
		{
			switch(Uniforms[j].nSemantic)
			{
			case ePVRTPFX_UsWORLDVIEWPROJECTION:
				{
					PVRTMat4 mWVP;

					// The whole scene (except the ball) is static.
					// The POD file was saved with 'word space' coordinates so there is no need to apply the
					// transformation matrices for the meshes, just the identity.
					// If you are exporting animation you will need to set the corresponding mesh
					// transformation matrix here (see IntroducingPOD training course).
					PVRTMat4 mWorld = PVRTMat4::Identity();

					// Check whether the current effect is the sphere and set up the word matrix with the sphere animation.
					if (m_ppEffectParser->GetEffect(uiFXID).Name == c_SphereEffectName)
					{
						mWorld = mLightWorld;
					}

					// Pass the model-view-projection matrix (MVP) to the shader to transform the vertices.
					PVRTMat4 mModelView;
					mModelView = m_mView * mWorld;
					mWVP = m_mProjection * mModelView;

					glUniformMatrix4fv(Uniforms[j].nLocation, 1, GL_FALSE, mWVP.f);
				} 
				break;
			case ePVRTPFX_UsWORLDIT:
				{
					// Passes the inverse transpose of the light rotation matrix.
					// This is needed to transform the light direction (from the light to each vertex) 
					// and it will give us a three component texture vector to map the cubemap texture.
					PVRTMat3 mLightModelIT = PVRTMat3(mLightWorld).inverse().transpose();
					glUniformMatrix3fv(Uniforms[j].nLocation, 1, GL_FALSE, mLightModelIT.f);
				}
				break;
			case ePVRTPFX_UsLIGHTPOSWORLD:
				{
					glUniform3f(Uniforms[j].nLocation, m_LightPosition.x, m_LightPosition.y, m_LightPosition.z);
				}
				break;
			case ePVRTPFX_UsLIGHTCOLOR:
				{
					// Some color variation here to make it more interesting.
					float afLightColor[] = { 1.0f, sin(m_fFrame/300.0f)*0.3f+0.7f, cos(m_fFrame/400.0f)*0.3f+0.7f};
					glUniform3fv(Uniforms[j].nLocation, 1, afLightColor ); 
				}
				break;
			}
		}

		// Now that all transformation matrices and the materials are ready,
		// call a function to actually draw the mesh.
		// We need to pass the current effect to process 'attributes' properly.
		DrawMesh(i, m_pFX[uiFXID]);
	}

	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools.
	m_Print3D.DisplayDefaultTitle("Magic Lantern", "", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();

	return true;
}