/*!****************************************************************************
 @Function		HandleInput
 @Description	Handles user input and updates live variables accordingly.
******************************************************************************/
bool OGLES2ProceduralTextures::HandleInput()
{
	static unsigned long prevTime = PVRShellGetTime();
	unsigned long curTime = PVRShellGetTime();
	unsigned long deltaTime = curTime - prevTime;

	if (m_bDemoMode && deltaTime > 2500)
	{
		prevTime = curTime;
		m_uiVisualisation++;
		if (m_uiVisualisation == NUM_VISUALISATIONS)
		{
			m_uiVisualisation = 0;
			m_uiGenerator = (m_uiGenerator + 1) % NUM_GENERATORS;
		}

		return GenerateFnTexture();
	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT) || (m_bDemoMode && deltaTime > 5000))
	{
		m_uiGenerator = (m_uiGenerator + 1) % NUM_GENERATORS;
		return GenerateFnTexture();

	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		if (m_uiGenerator > 0)
		{ m_uiGenerator = (m_uiGenerator - 1) % NUM_GENERATORS; }
		else
		{ m_uiGenerator = NUM_GENERATORS - 1; }
		return GenerateFnTexture();
	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameUP))
	{
		m_uiVisualisation = (m_uiVisualisation + 1) % NUM_VISUALISATIONS;
	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
	{
		if (m_uiVisualisation > 0)
		{ m_uiVisualisation--; }
		else
		{ m_uiVisualisation = NUM_VISUALISATIONS - 1; }
	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameACTION1))
	{
		m_Scalars[m_uiGenerator] *= 0.95f;
		GenerateFnTexture();
	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameACTION2))
	{
		m_Scalars[m_uiGenerator] *= 1.05f;
		GenerateFnTexture();
	}

	return true;
}
/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occurred
 @Description	Code in InitApplication() will be called by PVRShell once per
				run, before the rendering context is created.
				Used to initialize variables that are not dependent on it
				(e.g. external modules, loading meshes, etc.)
				If the rendering context is lost, InitApplication() will
				not be called again.
******************************************************************************/
bool OGLES2ProceduralTextures::InitApplication()
{
	PVRShellSet(prefApiMajorVersion, 3);
	PVRShellSet(prefApiMinorVersion, 1);

	m_FnTexture = 0;
	// Get and set the read path for content files
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));

	// Get and set the load/release functions for loading external files.
	// In the majority of cases the PVRShell will return NULL function pointers implying that
	// nothing special is required to load external files.
	CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc));

	m_Width = TEXTURE_SIZE;
	m_Height = TEXTURE_SIZE;

	m_uiGenerator = EUCLID;
	m_uiVisualisation = FN1_MINUS_FN0;
	m_bDemoMode = true;

	m_Scalars[EUCLID] = 0.26448223f;
	m_Scalars[CHESSBOARD] = 0.284799f;
	m_Scalars[MANHATTAN] = 0.134101f;

	m_pProceduralTextures = new ProceduralTextures();

	srand(PVRShellGetTime());

	return true;
}
Example #3
0
/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occured
 @Description	Code in InitApplication() will be called by PVRShell once per
				run, before the rendering context is created.
				Used to initialize variables that are not dependant on it
				(e.g. external modules, loading meshes, etc.)
				If the rendering context is lost, InitApplication() will
				not be called again.
******************************************************************************/
bool OGLES2ParticleSystem::InitApplication()
{
	m_pParticleSystem = 0;

	// Get and set the read path for content files
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));

	// Get and set the load/release functions for loading external files.
	// In the majority of cases the PVRShell will return NULL function pointers implying that
	// nothing special is required to load external files.
	CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc));

	// Load the scene
	if(m_Scene.ReadFromFile(c_szSphereModelFile) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Couldn't load the sphere.pod file\n");
		return false;
	}
	
	srand((unsigned int) PVRShellGetTime());

	PVRShellSet(prefSwapInterval, 0);

	return true;
}
Example #4
0
/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occurred
 @Description	Code in InitApplication() will be called by PVRShell once per
				run, before the rendering context is created.
				Used to initialize variables that are not dependent on it
				(e.g. external modules, loading meshes, etc.)
				If the rendering context is lost, InitApplication() will
				not be called again.
******************************************************************************/
bool OGLES3PhantomMask::InitApplication()
{
    // Get and set the read path for content files
    CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));

    // Get and set the load/release functions for loading external files.
    // In the majority of cases the PVRShell will return NULL function pointers implying that
    // nothing special is required to load external files.
    CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc));

    // Load the scene
    if(m_Scene.ReadFromFile(c_szSceneFile) != PVR_SUCCESS)
    {
        PVRShellSet(prefExitMessage, "ERROR: Couldn't load the .pod file\n");
        return false;
    }

    // The cameras are stored in the file. We check it contains at least one.
    if(m_Scene.nNumCamera == 0)
    {
        PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a camera. Please add one and re-export.\n");
        return false;
    }

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

    return true;
}
Example #5
0
/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occured
 @Description	Code in InitApplication() will be called by PVRShell once per
				run, before the rendering context is created.
				Used to initialize variables that are not dependant on it
				(e.g. external modules, loading meshes, etc.)
				If the rendering context is lost, InitApplication() will
				not be called again.
******************************************************************************/
bool OGLES2EdgeDetection::InitApplication()
{
#ifdef SHOW_MAX_FPS
	// Disable v-sync
	PVRShellSet(prefSwapInterval,0);
#endif

	// Get and set the read path for content files
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));

	// Get and set the load/release functions for loading external files.
	// In the majority of cases the PVRShell will return NULL function pointers implying that
	// nothing special is required to load external files.
	CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc));

	/*	Loads the scene from the .pod file into a CPVRTModelPOD object.
		We could also export the scene as a header file and
		load it with ReadFromMemory().	*/
	if(m_Scene.ReadFromFile(c_szSceneFile) != PVR_SUCCESS)
	{
		CPVRTString ErrorStr = "ERROR: Couldn't load '" + CPVRTString(c_szSceneFile) + "'.";
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	//Initialises the time variables.
	m_ulCurrentTime = PVRShellGetTime();
	m_ulPreviousTimeAngle = m_ulCurrentTime;
	m_ulPreviousTimeFPS = m_ulCurrentTime;

	return true;
}
Example #6
0
/*******************************************************************************
 * Function Name  : InitView
 * Inputs		  : uWidth, uHeight
 * Returns        : true if no error occured
 * Description    : Code in InitView() will be called by the Shell upon a change
 *					in the rendering context.
 *					Used to initialise variables that are dependent on the rendering
 *					context (e.g. textures, vertex buffers, etc.)
 *******************************************************************************/
bool CTransforms::InitView()
{
	// Create paths
	CreatePaths();

	// Create paint
	m_vgPaint = vgCreatePaint();
	vgSetParameteri(m_vgPaint, VG_PAINT_TYPE, VG_PAINT_TYPE_COLOR);
	vgSetColor(m_vgPaint, PVRTRGBA(255, 255, 170, 255));

	vgSeti(VG_STROKE_JOIN_STYLE, VG_JOIN_ROUND);
	vgSetf(VG_STROKE_LINE_WIDTH, 2.5f / PVRShellGet(prefHeight));

	/*
	The clear colour will be used whenever calling vgClear(). The colour is given
	as non-premultiplied sRGBA.
	*/
	VGfloat afClearColour[] = { 0.6f, 0.8f, 1.0f, 1.0f };
	vgSetfv(VG_CLEAR_COLOR, 4, afClearColour);

	// Initialise custom text drawing
	m_PrintVG.Initialize(PVRShellGet(prefWidth), PVRShellGet(prefHeight));

	m_ui32StartTime = PVRShellGetTime();

	return true;
}
Example #7
0
/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occured
 @Description	Code in InitApplication() will be called by PVRShell once per
				run, before the rendering context is created.
				Used to initialize variables that are not dependant on it
				(e.g. external modules, loading meshes, etc.)
				If the rendering context is lost, InitApplication() will
				not be called again.
******************************************************************************/
bool OGLESIntroducingPFX::InitApplication()
{
	// Get and set the read path for content files
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));

	// Load the scene
	if (m_Scene.ReadFromFile(c_szSceneFile) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Couldn't load the .pod file\n");
		return false;
	}

	// The cameras are stored in the file. We check it contains at least one.
	if(m_Scene.nNumCamera == 0)
	{
		PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a camera\n");
		return false;
	}

	// Ensure that all meshes use an indexed triangle list
	for(unsigned int i = 0; i < m_Scene.nNumMesh; ++i)
	{
		if(m_Scene.pMesh[i].nNumStrips || !m_Scene.pMesh[i].sFaces.pData)
		{
			PVRShellSet(prefExitMessage, "ERROR: The meshes in the scene should use an indexed triangle list\n");
			return false;
		}
	}

	// Initialize variables used for the animation
	m_fFrame = 0;
	m_iTimePrev = PVRShellGetTime();

	return true;
}
/*!****************************************************************************
 @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 OGLESPVRScopeRemote::InitView()
{
	CPPLProcessingScoped PPLProcessingScoped(m_psSPSCommsData,
		__FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter);

	CPVRTString ErrorStr;
	/*
		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 texturing
	glEnable(GL_TEXTURE_2D);

	//	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;
	}

	/*
		Calculate the projection and view matrices
	*/

	m_mProjection = PVRTMat4::PerspectiveFovRH(PVRT_PIf/6, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate);

	m_mView = PVRTMat4::LookAtRH(PVRTVec3(0, 0, 75.0f), PVRTVec3(0, 0, 0), PVRTVec3(0, 1, 0));

	// Enable the depth test
	glEnable(GL_DEPTH_TEST);

	// Enable culling
	glEnable(GL_CULL_FACE);

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

	return true;
}
Example #9
0
/*!****************************************************************************
 @Function		UpdateFramerateCounter
 @Description	Updates and keeps track of the frames rendered per second.
******************************************************************************/
float OGLES2ParticleSystem::UpdateFramerateCounter()
{
	static long lOldPerf = PVRShellGetTime();
	static int i32Frame = 0;
	static float fFPS = 60.0f;
	long m_lPerf = PVRShellGetTime();
	++i32Frame;

	if((m_lPerf - lOldPerf) >= 1000l)
	{
		fFPS = i32Frame * 1000.0f / (float)(m_lPerf - lOldPerf);
		i32Frame = 0;
		lOldPerf = m_lPerf;
	}

	return fFPS;
}
/*!****************************************************************************
 @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 OGLES2ChameleonMan::InitView()
{
	CPVRTString ErrorStr;

	/*
		Initialize VBO data
	*/
	LoadVbos();

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

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

	/*
		Initialize Print3D
	*/

	// Is the screen rotated?
	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;
	}

	/*
		Set OpenGL ES render states needed for this training course
	*/
	// Enable backface culling and depth test
	glCullFace(GL_BACK);
	glEnable(GL_CULL_FACE);

	glEnable(GL_DEPTH_TEST);

	// Use black as our clear colour
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

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

	return true;
}
/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occured
 @Description	Code in InitApplication() will be called by PVRShell once per
				run, before the rendering context is created.
				Used to initialize variables that are not dependant on it
				(e.g. external modules, loading meshes, etc.)
				If the rendering context is lost, InitApplication() will
				not be called again.
******************************************************************************/
bool OGLES3TextureStreaming::InitApplication()
{
	m_i32Frame       = 0;
	m_puiVbo         = 0;
	m_puiIndexVbo    = 0;
	m_ulGlowTime     = 0;
	m_iNoiseCoordIdx = 0;
	m_uiTVScreen     = -1;
	m_bGlowState     = false;

	/*
		CPVRTResourceFile is a resource file helper class. Resource files can
		be placed on disk next to the executable or in a platform dependent
		read path. We need to tell the class where that read path is.
		Additionally, it is possible to wrap files into cpp modules and
		link them directly into the executable. In this case no path will be
		used. Files on disk will override "memory files".
	*/

	// Get and set the read path for content files
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));

	// Get and set the load/release functions for loading external files.
	// In the majority of cases the PVRShell will return NULL function pointers implying that
	// nothing special is required to load external files.
	CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc));

	// Load the scene
	if(m_Scene.ReadFromFile(c_pszSceneFile) != PVR_SUCCESS)
	{
		CPVRTString ErrorStr = "ERROR: Couldn't load '" + CPVRTString(c_pszSceneFile) + "'.\n";
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	// The cameras are stored in the file. We check it contains at least one.
	if(m_Scene.nNumCamera == 0)
	{
		PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a camera. Please add one and re-export.\n");
		return false;
	}

	// We also check that the scene contains at least one light
	if(m_Scene.nNumLight == 0)
	{
		PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a light. Please add one and re-export.\n");
		return false;
	}

	// Initialize variables used for the animation.
	m_fFrame      = 0.0f;
	m_fBandScroll = -c_fBandWidth;
	m_ulTimePrev = PVRShellGetTime();

	return true;
}
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @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 relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES3TextureStreaming::RenderScene()
{
	// Clears 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);
	m_fBandScroll += (float)ulDeltaTime * (60.0f/1000.0f) * c_fBandScrollSpeed;
	if(m_fFrame > m_Scene.nNumFrame - 1)
		m_fFrame = 0.0f;

	if(m_fBandScroll > 1.0f)
		m_fBandScroll = -c_fBandWidth;

	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

	m_Scene.SetFrame(m_fFrame);

	// Setup the main camera
	PVRTVec3	vFrom, vTo(0.0f), vUp(0.0f, 1.0f, 0.0f);
	float fFOV;

	// Camera nodes are after the mesh and light nodes in the array
	int i32CamID = m_Scene.pNode[m_Scene.nNumMeshNode + m_Scene.nNumLight + c_ui32Camera].nIdx;

	// Get the camera position, target and field of view (fov)
	if(m_Scene.pCamera[i32CamID].nIdxTarget != -1) // Does the camera have a target?
		fFOV = m_Scene.GetCameraPos( vFrom, vTo, c_ui32Camera); // vTo is taken from the target node
	else
		fFOV = m_Scene.GetCamera( vFrom, vTo, vUp, c_ui32Camera); // vTo is calculated from the rotation

    float fTargetAspect = 960.0f/640.0f;
    float fAspect       = (float)PVRShellGet(prefWidth) / (float)PVRShellGet(prefHeight);
    fFOV               *= fTargetAspect / fAspect;

	PVRTMat4 mView           = PVRTMat4::LookAtRH(vFrom, vTo, vUp);
	PVRTMat4 mProjection     = PVRTMat4::PerspectiveFovRH(fFOV, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), c_fCameraNear,
														  c_fCameraFar, PVRTMat4::OGL, bRotate);
	PVRTMat4 mViewProjection = mProjection * mView;

	DrawPODScene(mViewProjection);

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

	++m_i32Frame;
	return true;
}
Example #13
0
/*******************************************************************************
 * Function Name  : RenderScene
 * Returns		  : true if no error occured
 * Description    : Main rendering loop function of the program. The shell will
 *					call this function every frame.
 *******************************************************************************/
bool CTransforms::RenderScene()
{
	m_ui32AbsTime = PVRShellGetTime();

	// Clear the screen with clear color.
	vgClear(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));

	// Set fill paint
	vgSetPaint(m_vgPaint, VG_FILL_PATH);

	unsigned int ui32TimeSinceStart = PVRShellGetTime() - m_ui32StartTime;
	// toggle segment type every 3 seconds
	int ui32ActiveTransform = (ui32TimeSinceStart % (3000 * 7)) / 3000;

	switch(ui32ActiveTransform)
	{
		case 0: DoTranslate(); break;
		case 1: DoScaleCentered(); break;
		case 2: DoScaleOrigin(); break;
		case 3: DoRotateCentered(); break;
		case 4: DoRotateOrigin(); break;
		case 5: DoShearCentered(); break;
		case 6: DoShearOrigin(); break;
	}

	// Draw user interface
	static char* apszTransforms[] = {
		"Translation",
		"Scaling (centered on object)",
		"Scaling (from origin)",
		"Rotate (centered on object)",
		"Rotate (around origin)",
		"Shear (centered on object)",
		"Shear (from origin)",
	};

	m_PrintVG.DisplayDefaultTitle("Transforms", apszTransforms[ui32ActiveTransform], ePVRTPrint3DLogoIMG);
	return true;
}
Example #14
0
/*!****************************************************************************
 @Function		UpdateParticles
 @Description	Updates particle positions and attributes, e.g. lifespan.
******************************************************************************/
void OGLES2ParticleSystem::UpdateParticles()
{	
	static long lastTime = PVRShellGetTime();
	long nowTime = PVRShellGetTime();
	long elapsedTime = nowTime - lastTime;
	float step = elapsedTime / 140.0f;
	lastTime = nowTime;
		
	static float rot_angle = 0.0f;
	rot_angle += step / 2.0f;		
	float el_angle = ((float) sin(rot_angle / 4.0f) + 1.0f) * 0.2f + 0.2f;

	PVRTMat4 rot = PVRTMat4::RotationY(rot_angle);
	PVRTMat4 skew = PVRTMat4::RotationZ(el_angle);
	
	Emitter sEmitter;
	sEmitter.mTransformation = rot * skew;
	sEmitter.fHeight = 2.0f;
	sEmitter.fRadius = 0.35f;

	m_pParticleSystem->SetEmitter(sEmitter);
	m_pParticleSystem->Update(step);
}
Example #15
0
/*!****************************************************************************
 @Function		Update
 @Description	Handles user input and updates all timing data.
******************************************************************************/
void OGLES3ShadowMapping::Update()
{
	if (PVRShellIsKeyPressed(PVRShellKeyNameSELECT)) m_bDebug = !m_bDebug;
	if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT)) m_fBias *= 0.9f;
	if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) m_fBias *= 1.1f;

	// Calculates the frame number to animate in a time-based manner.
	// Uses the shell function PVRShellGetTime() to get the time in milliseconds.
	static unsigned long ulTimePrev = PVRShellGetTime();
	unsigned long ulTime = PVRShellGetTime();
	unsigned long ulDeltaTime = ulTime - ulTimePrev;
	ulTimePrev = ulTime;
	static float fFrame = 0;
	if (!m_bDebug)
		fFrame += (float)ulDeltaTime * 0.05f;

	if (fFrame > m_Scene.nNumFrame-1)
		fFrame = 0;

	// Update the animation data
	m_Scene.SetFrame(fFrame);

	PVRTVec3 vFrom, vTo, vUp;	
	float fFOV = m_Scene.GetCamera(vFrom, vTo, vUp, 0) * 0.75f;
		

	m_mProjection = PVRTMat4::PerspectiveFovRH(fFOV, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), m_Scene.pCamera[0].fNear, m_Scene.pCamera[0].fFar, PVRTMat4::OGL, m_bRotate);
	m_mView = PVRTMat4::LookAtRH(vFrom, vTo, vUp);
	
	m_Scene.GetLight(m_vLightPosition, m_vLightDirection, 0);
	
	PVRTVec3 lightFrom, lightTo, lightUp;
	m_Scene.GetCamera(lightFrom, lightTo, lightUp, 1);
	m_mLightView = PVRTMat4::LookAtRH(lightFrom, lightTo, lightUp);
	m_mLightProjection = PVRTMat4::PerspectiveFovRH(PVRT_PI_OVER_TWO, 1.0f, m_Scene.pCamera[1].fNear, m_Scene.pCamera[1].fFar, PVRTMat4::OGL, m_bRotate);	
}
Example #16
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @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 relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES2RenderToTexture::RenderScene()
{
	/* vary the branch angles on the fractal sinusoidally */
	m_fAngle = (float)(sin(0.25*PVRT_PIf*(float)(m_ui32Framenum)/256.0f))* 70.0f;

	/* largeish prime number in the angular frequency here, so the motion's not obviously periodic */
	m_fAngle2 = (float)(sin((79.0f/256.0f)*2.0*PVRT_PIf*(float)(m_ui32Framenum)/256.0f))*100.0f + 30.0f;

	/* Convert the angles to radians. */
	m_fAngle  *= 0.017453f;
	m_fAngle2 *= 0.017453f;

	/* Increase the frame count */
	if(PVRShellGetTime() - m_ui32Time > 10)
	{
		m_ui32Time = PVRShellGetTime();
		m_ui32Framenum += 2;

		if(m_ui32Framenum > 20000)
			m_ui32Framenum = 0;
	}

	// Disable depth test and culling as we don't need it
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);

	// Draw the RenderToTexture
	if(!DrawScreen())
		return false;

	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	m_Print3D.DisplayDefaultTitle("Render to Texture", "Using FBO", ePVRTPrint3DLogoIMG);
	m_Print3D.Flush();

	return true;
}
Example #17
0
// ---------------------------------------------------------------
bool MyPVRDemo::RenderScene()
	{
	// --- Work out DT
	unsigned long ulPrevTime = m_ulCurrTime;
	m_ulCurrTime = PVRShellGetTime();
	m_fDT = ((float)m_ulCurrTime - (float)ulPrevTime) * 0.001f;

	// Calculate a new light matrix
	PVRTVec3 vLightPos = PVRTVec4(m_vLightPos, 1.0f) * PVRTMat4::RotationY(m_fLightAngle);
	m_mxLightView = PVRTMat4::LookAtRH(vLightPos, PVRTVec3(0,25,0), PVRTVec3(0,1,0));

	// --- Render the scene from the light's POV
	RenderShadowScene();

	// --- Clear buffers
	glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	PVRTMat4 mxCam = m_mxCam * PVRTMat4::RotationY(m_fAngleY);
	PVRTMat4 mxModel = PVRTMat4::Identity();

	// --- Draw the Statue
	glUseProgram(m_StatueShader.uiID);
	glBindTexture(GL_TEXTURE_2D, m_tex[enumTEXTURE_StatueNormals]);
	RenderStatue(mxModel, mxCam, vLightPos, &m_StatueShader);

	// --- Draw the Statue reflected
	glCullFace(GL_FRONT);
	PVRTMat4 mxModelRefl = PVRTMat4::Scale(1,-1,1) * mxModel;
	RenderStatue(mxModelRefl, mxCam, vLightPos, &m_StatueShader);
	glCullFace(GL_BACK);

	// --- Draw the Floor (with shadow)
	RenderCurch(mxCam);

	// --- Render the bloom effect
	RenderBloom(mxModel, mxCam, vLightPos);

	// --- Increment the camera angle
	m_fAngleY += 0.5f * m_fDT;

	// --- Increment the light angle
	m_fLightAngle += 0.5f * m_fDT;
	return true;
	}
Example #18
0
void OGLES2FilmTV::CalcMiniCameraView()
{
	float fValue = PVRShellGetTime() * 0.001f * 2.0f * PVRT_PIf;

	float fZ = 1.0f + (2.40f * (float)sin(fValue * 1.0f / g_ui32CameraLoopSpeed));
	float fX = 0.50f * (float)cos(fValue * 2.0f / g_ui32CameraLoopSpeed);
	float fCamRot = 0.16f * (float)sin(fValue * 1.0f / g_ui32CameraLoopSpeed) - 0.17f;

	m_MiniCamView  = PVRTMat4::RotationX((float)atan2(fX, 10.0f));
	m_MiniCamView *= PVRTMat4::RotationY(fCamRot);
	m_MiniCamView *= PVRTMat4::RotationZ((float)atan2(fZ, 10.0f));

	// Setup the mini camera's view projection matrix
	PVRTMat4 mProjection = PVRTMat4::PerspectiveFovRH(70.0f * (PVRT_PIf / 180.0f), 1, g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, false);
	m_MiniCamViewProj = mProjection * m_MiniCamView;
}
/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occured
 @Description	Code in InitApplication() will be called by PVRShell once per
				run, before the rendering context is created.
				Used to initialize variables that are not dependant on it
				(e.g. external modules, loading meshes, etc.)
				If the rendering context is lost, InitApplication() will
				not be called again.
******************************************************************************/
bool OGLES3Skinning::InitApplication()
{
	m_puiVbo = 0;
	m_puiIndexVbo = 0;

	// Get and set the read path for content files
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));

	// Get and set the load/release functions for loading external files.
	// In the majority of cases the PVRShell will return NULL function pointers implying that
	// nothing special is required to load external files.
	CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc));

	// Load the scene
	if (m_Scene.ReadFromFile(c_szSceneFile) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Couldn't load the .pod file\n");
		return false;
	}

	// The cameras are stored in the file. We check it contains at least one.
	if (m_Scene.nNumCamera == 0)
	{
		PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a camera\n");
		return false;
	}

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

	// Initialise variables used for the animation
	m_fFrame = 0;
	m_iTimePrev = PVRShellGetTime();
	m_Transform = PVRTMat4::Identity();
	m_fAngle = 0.0f;
	m_fDistance = 0.0f;

	return true;
}
/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occured
 @Description	Code in InitApplication() will be called by PVRShell once per
				run, before the rendering context is created.
				Used to initialize variables that are not dependant on it
				(e.g. external modules, loading meshes, etc.)
				If the rendering context is lost, InitApplication() will
				not be called again.
******************************************************************************/
bool OGLES3IntroducingPFX::InitApplication()
{
	// Get and set the read path for content files
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));

	// Get and set the load/release functions for loading external files.
	// In the majority of cases the PVRShell will return NULL function pointers implying that
	// nothing special is required to load external files.
	CPVRTResourceFile::SetLoadReleaseFunctions(PVRShellGet(prefLoadFileFunc), PVRShellGet(prefReleaseFileFunc));

	// Load the scene
	if (m_Scene.ReadFromFile(c_szSceneFile) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Couldn't load the .pod file\n");
		return false;
	}

	// The cameras are stored in the file. We check it contains at least one.
	if(m_Scene.nNumCamera == 0)
	{
		PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a camera\n");
		return false;
	}

	// Ensure that all meshes use an indexed triangle list
	for(unsigned int i = 0; i < m_Scene.nNumMesh; ++i)
	{
		if(m_Scene.pMesh[i].nNumStrips || !m_Scene.pMesh[i].sFaces.pData)
		{
			PVRShellSet(prefExitMessage, "ERROR: The meshes in the scene should use an indexed triangle list\n");
			return false;
		}
	}

	// Initialize variables used for the animation
	m_fFrame = 0;
	m_ulTimePrev = PVRShellGetTime();

	return true;
}
Example #21
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @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 relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES2ParticleSystem::RenderScene()
{
	HandleInput();
	UpdateParticles();
	UpdateFramerateCounter();

	float time_delta = PVRShellGetTime() / 10000.0f;
	PVRTVec3 vFrom = PVRTVec3((float) sin(time_delta) * 50.0f, 30.0f, (float) cos(time_delta) * 50.0f);
	m_mView = PVRTMat4::LookAtRH(vFrom, PVRTVec3(0.0f, 5.0f, 0.0f), PVRTVec3(0.0f, 1.0f, 0.0f));
	m_mViewProjection = m_mProjection * m_mView;

	// Clear colour and depth buffers
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Enables depth testing
	glEnable(GL_DEPTH_TEST);
	
	// Render floor
	RenderFloor();

	for (unsigned int i=0; i < g_cuiNumSpheres; i++)
		RenderSphere(g_caSpheres[i].aPosition, g_caSpheres[i].fRadius);

	// Render particles
	RenderParticles();	
	
	// Display info text.

	char lower_buffer[64];
	unsigned int numParticles = m_pParticleSystem->GetNumberOfParticles();
	sprintf(lower_buffer, "No. of Particles: %d", numParticles);
	m_Print3D.DisplayDefaultTitle("Particle System", NULL, ePVRTPrint3DSDKLogo);
	m_Print3D.Print3D(2.0f, 90.0f, 1.0f, 0xFFFFFFFF, "No. of Particles: %d", numParticles);
	m_Print3D.Flush();

	return true;
}
Example #22
0
/*!****************************************************************************
 @Function		UpdateScene
 @Description	Moves the scene.
******************************************************************************/
void OGLES2Glass::UpdateScene() {
	// Fetch current time and make sure the previous time isn't greater
	unsigned long ulCurrentTime = PVRShellGetTime();
	if (ulCurrentTime < m_ulTime) m_ulTime = ulCurrentTime;

	// Calculate the time difference
	unsigned long ulTimeDifference = ulCurrentTime - m_ulTime;

	// Store the current time for the next frame
	m_ulTime = ulCurrentTime;

	m_afAngles[0] += ulTimeDifference * 0.0002f;
	m_afAngles[1] -= ulTimeDifference * 0.00008f;

	float fRise = sin(m_afAngles[0] * 3.0f);

	// Rotate the camera
	m_mView = PVRTMat4::LookAtRH(PVRTVec3(0, 0, -10), PVRTVec3(0, 0, 0), PVRTVec3(0, 1, 0)) * PVRTMat4::RotationY(m_afAngles[0] * 0.2f);

	// Rotate the balloon model matrices
	m_mModels[0] = PVRTMat4::RotationY(m_afAngles[0]) * PVRTMat4::Translation(120.0f, fRise * 20.0f, 0.0f) * PVRTMat4::Scale(3.0f, 3.0f, 3.0f);
	m_mModels[1] = PVRTMat4::RotationY(m_afAngles[1]) * PVRTMat4::Translation(-180.0f, -fRise * 20.0f, 0.0f) * PVRTMat4::Scale(3.0f, 3.0f, 3.0f);
}
Example #23
0
/*!****************************************************************************
 @Function		InitApplication
 @Return		bool		true if no error occured
 @Description	Code in InitApplication() will be called by PVRShell once per
				run, before the rendering context is created.
				Used to initialize variables that are not dependant on it
				(e.g. external modules, loading meshes, etc.)
				If the rendering context is lost, InitApplication() will
				not be called again.
******************************************************************************/
bool OGLES2IntroducingPOD::InitApplication()
{
	m_puiVbo = 0;
	m_puiIndexVbo = 0;
	m_puiTextureIDs = 0;

	// Get and set the read path for content files
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));

	// Load the scene
	if(m_Scene.ReadFromFile(c_szSceneFile) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Couldn't load the .pod file\n");
		return false;
	}

	// The cameras are stored in the file. We check it contains at least one.
	if(m_Scene.nNumCamera == 0)
	{
		PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a camera. Please add one and re-export.\n");
		return false;
	}

	// We also check that the scene contains at least one light
	if(m_Scene.nNumLight == 0)
	{
		PVRShellSet(prefExitMessage, "ERROR: The scene does not contain a light. Please add one and re-export.\n");
		return false;
	}

	// Initialize variables used for the animation
	m_fFrame = 0;
	m_iTimePrev = PVRShellGetTime();

	return true;
}
/*!****************************************************************************
 @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 dependant on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLES3EdgeDetection::InitView()
{
	// Store width and height of the viewport.
	m_i32WinWidth = PVRShellGet(prefWidth);
	m_i32WinHeight = PVRShellGet(prefHeight);

	// Set our texture dimensions to be the same as our windows
	m_i32TexWidth = m_i32WinWidth;
	m_i32TexHeight = m_i32WinHeight;

	/*	Get the current frame buffer object. As the program hasn't set it yet, this is the default buffer.
		On most platforms this just gives 0, but there are exceptions.	*/
	glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFramebuffer);

	// Create string for error codes.
	CPVRTString ErrorStr;

	// Checks to see if the screen is rotated or not.
    bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

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

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

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

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

	// Creates and checks FBO creation
	if (!CreateFBO(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	SetupView(bRotate);

	//Initialises the time variables.
	m_ulCurrentTime = PVRShellGetTime();
	m_ulPreviousTimeAngle = m_ulCurrentTime;
	m_ulPreviousTimeFPS = m_ulCurrentTime;

	return true;
}
Example #25
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 OGLES3Skybox2::RenderScene()
{
	unsigned int i, j;

	// Clears the colour and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	/*
		Calculates the frame number to animate in a time-based manner.
		Uses the shell function PVRShellGetTime() to get the time in milliseconds.
	*/

	unsigned long iTime = PVRShellGetTime();

	if(!bPause)
	{
		// Calculate the model view matrix turning around the balloon
		ComputeViewMatrix();

		if(iTime > m_iTimePrev)
		{
			float fDelta = (float) (iTime - m_iTimePrev) * g_fFrameRate;
			m_fFrame   += fDelta;
			fDemoFrame += fDelta;
			fBurnAnim  += fDelta * 0.02f;

			if(fBurnAnim >= 1.0f)
				fBurnAnim = 1.0f;
		}
	}

	m_iTimePrev	= iTime;

	/* KeyBoard input processing */

	if(PVRShellIsKeyPressed(PVRShellKeyNameACTION1))
		bPause=!bPause;

	if(PVRShellIsKeyPressed(PVRShellKeyNameACTION2))
		fBurnAnim = 0.0f;

	/* Keyboard Animation and Automatic Shader Change over time */
	if(!bPause && (fDemoFrame > 500 || (m_i32Effect == 2 && fDemoFrame > 80)))
	{
		if(++m_i32Effect >= (int) g_ui32NoOfEffects)
		{
			m_i32Effect = 1;
			m_fFrame = 0.0f;
		}

		fDemoFrame = 0.0f;
		fBurnAnim  = 0.0f;
	}

	/* Change Shader Effect */

	if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		if(++m_i32Effect >= (int) g_ui32NoOfEffects)
			m_i32Effect = 1;

		fDemoFrame = 0.0f;
		fBurnAnim  = 0.0f;
		m_fFrame = 0.0f;
	}
	if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		if(--m_i32Effect < 1)
			m_i32Effect = g_ui32NoOfEffects - 1;

		fDemoFrame = 0.0f;
		fBurnAnim  = 0.0f;
		m_fFrame = 0.0f;
	}

	/* Change Skybox Texture */
	if(PVRShellIsKeyPressed(PVRShellKeyNameUP))
	{
		for(i = 0; i < g_ui32NoOfEffects; ++i)
			ChangeSkyboxTo(m_ppEffects[i], m_ui32TextureIDs[4]);

		fBurnAnim = 0.0f;
	}

	if(PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
	{
		for(i = 0; i < g_ui32NoOfEffects; ++i)
			ChangeSkyboxTo(m_ppEffects[i], m_ui32TextureIDs[3]);

		fBurnAnim = 0.0f;
	}

	/* Setup Shader and Shader Constants */
	int location;

	glDisable(GL_CULL_FACE);

	DrawSkybox();

	glEnable(GL_CULL_FACE);

	m_ppEffects[m_i32Effect]->Activate();

	for(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];

		// Gets the node model matrix
		PVRTMat4 mWorld, mWORLDVIEW;
		mWorld = m_Scene.GetWorldMatrix(*pNode);

		mWORLDVIEW = m_mView * mWorld;

		glBindBuffer(GL_ARRAY_BUFFER, m_aiVboID[i]);

		const CPVRTArray<SPVRTPFXUniform>& Uniforms = m_ppEffects[m_i32Effect]->GetUniformArray();
		for(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_UsWORLDVIEWPROJECTION:
				{
					PVRTMat4 mMVP;

					/* Passes the model-view-projection matrix (MVP) to the shader to transform the vertices */
					mMVP = m_mProjection * mWORLDVIEW;
					glUniformMatrix4fv(Uniforms[j].nLocation, 1, GL_FALSE, mMVP.f);
				}
				break;
				case ePVRTPFX_UsWORLDVIEW:
				{
					glUniformMatrix4fv(Uniforms[j].nLocation, 1, GL_FALSE, mWORLDVIEW.f);
				}
				break;
				case ePVRTPFX_UsWORLDVIEWIT:
				{
					PVRTMat4 mWORLDVIEWI, mWORLDVIEWIT;

					mWORLDVIEWI = mWORLDVIEW.inverse();
					mWORLDVIEWIT= mWORLDVIEWI.transpose();

					PVRTMat3 WORLDVIEWIT = PVRTMat3(mWORLDVIEWIT);

					glUniformMatrix3fv(Uniforms[j].nLocation, 1, GL_FALSE, WORLDVIEWIT.f);
				}
				break;
				case ePVRTPFX_UsVIEWIT:
				{
					PVRTMat4 mViewI, mViewIT;

					mViewI  = m_mView.inverse();
					mViewIT = mViewI.transpose();

					PVRTMat3 ViewIT = PVRTMat3(mViewIT);

					glUniformMatrix3fv(Uniforms[j].nLocation, 1, GL_FALSE, ViewIT.f);
				}
				break;
				case ePVRTPFX_UsLIGHTDIREYE:
				{
					PVRTVec4 vLightDirectionEyeSpace;

					// Passes the light direction in eye space to the shader
					vLightDirectionEyeSpace = m_mView * PVRTVec4(1.0,1.0,-1.0,0.0);
					glUniform3f(Uniforms[j].nLocation, vLightDirectionEyeSpace.x, vLightDirectionEyeSpace.y, vLightDirectionEyeSpace.z);
				}
				break;
				case ePVRTPFX_UsTEXTURE:
				{
					// Set the sampler variable to the texture unit
					glUniform1i(Uniforms[j].nLocation, Uniforms[j].nIdx);
				}
				break;
			}
		}

		location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "myEyePos");

		if(location != -1)
			glUniform3f(location, vCameraPosition.x, vCameraPosition.y, vCameraPosition.z);

		//set animation
		location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "fAnim");

		if(location != -1)
			glUniform1f(location, fBurnAnim);

		location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "myFrame");

		if(location != -1)
			glUniform1f(location, m_fFrame);

		if(g_bBlendShader[m_i32Effect])
		{
			glEnable(GL_BLEND);

			// Correct render order for alpha blending through culling
			// Draw Back faces
			glCullFace(GL_FRONT);

			location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "bBackFace");

			glUniform1i(location, 1);

			DrawMesh(pMesh);

			glUniform1i(location, 0);

			glCullFace(GL_BACK);
		}
		else
		{
			location = glGetUniformLocation(m_ppEffects[m_i32Effect]->GetProgramHandle(), "bBackFace");

			if(location != -1)
				glUniform1i(location, 0);

			glDisable(GL_BLEND);
		}

		/* Everything should now be setup, therefore draw the mesh*/
		DrawMesh(pMesh);

		glBindBuffer(GL_ARRAY_BUFFER, 0);

		for(j = 0; j < Uniforms.GetSize(); ++j)
		{
			switch(Uniforms[j].nSemantic)
			{
			case ePVRTPFX_UsPOSITION:
				{
					glDisableVertexAttribArray(Uniforms[j].nLocation);
				}
				break;
			case ePVRTPFX_UsNORMAL:
				{
					glDisableVertexAttribArray(Uniforms[j].nLocation);
				}
				break;
			case ePVRTPFX_UsUV:
				{
					glDisableVertexAttribArray(Uniforms[j].nLocation);
				}
				break;
			}
		}
	}

	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	if(!bPause)
		m_Print3D.DisplayDefaultTitle("Skybox2", "", ePVRTPrint3DSDKLogo);
	else
		m_Print3D.DisplayDefaultTitle("Skybox2", "Paused", ePVRTPrint3DSDKLogo);

	m_Print3D.Flush();

	return true;
}
Example #26
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;
}
Example #27
0
/*!****************************************************************************
 @Function		DoAnimation
 @Description	Calculate the duck and camera animation as well as the cloud and
				water.
******************************************************************************/
void OGLESFur::DoAnimation()
{
	PVRTMat4		mCamera, mTmp;
	PVRTVec3		pvPlane[5];
	unsigned long	ui32Time;
	float			fDeltaTime;
	int i;

	if(!m_bPause)
	{
		ui32Time = PVRShellGetTime();

		fDeltaTime = (float) (ui32Time < m_ui32PrevTime ? m_ui32PrevTime - ui32Time : ui32Time - m_ui32PrevTime) + 0.1f;

		if(fDeltaTime > 50.0f) // Cap delta time
			fDeltaTime = 50.0f;

		m_ui32PrevTime = ui32Time;

		m_fCameraRot += 0.00006f * fDeltaTime;
		fDeltaTime = fDeltaTime * 0.001f;
	}
	else
		fDeltaTime = 0.0f;

	if(m_bViewMode)
	{
		// Viewing duck alone
		mCamera = PVRTMat4::Translation(0, 0, 160.0f);
		mTmp = PVRTMat4::RotationX(0.35f * (float) sin(0.0003f * m_ui32PrevTime) + 0.2f);
		mCamera = mTmp * mCamera;
		mTmp = PVRTMat4::RotationY(m_fCameraRot);
		mCamera = mTmp * mCamera;
		mTmp = PVRTMat4::Translation(m_mDuckWorld.f[12], m_mDuckWorld.f[13], m_mDuckWorld.f[14]);
		mCamera = mTmp * mCamera;

		m_vCamFrom.x += fDeltaTime * (mCamera.f[12] - m_vCamFrom.x);
		m_vCamFrom.y += fDeltaTime * (mCamera.f[13] - m_vCamFrom.y);
		m_vCamFrom.z += fDeltaTime * (mCamera.f[14] - m_vCamFrom.z);

		m_vCamTo.x	+= fDeltaTime * (m_mDuckWorld.f[12] - m_vCamTo.x);
		m_vCamTo.y	+= fDeltaTime * (m_mDuckWorld.f[13] + 25.0f - m_vCamTo.y);
		m_vCamTo.z	+= fDeltaTime * (m_mDuckWorld.f[14] - m_vCamTo.z);

		// Build view matrix
		m_mView = PVRTMat4::LookAtRH(m_vCamFrom, m_vCamTo, c_vUp);
	}
	else
	{
		//	Viewing duck in a wee river
		m_fDuckRot -= 0.1f * fDeltaTime;

		// Duck world transform
		m_mDuckWorld = PVRTMat4::Translation(140.0f, 0, 0);

		mTmp = PVRTMat4::RotationY(m_fDuckRot);
		m_mDuckWorld = mTmp * m_mDuckWorld;

		PVRTVec3	vFrom, vTo;

		// We can get the camera position, target with GetCameraPos()
		m_Scene.GetCameraPos(vFrom, vTo, 0);

		// Position camera
		mCamera = PVRTMat4::Translation(vFrom.x, vFrom.y, vFrom.z);

		mTmp = PVRTMat4::RotationY(m_fCameraRot);
		mCamera = mTmp * mCamera;

		m_vCamFrom.x += fDeltaTime * (mCamera.f[12] - m_vCamFrom.x);
		m_vCamFrom.y += fDeltaTime * (mCamera.f[13] - m_vCamFrom.y);
		m_vCamFrom.z += fDeltaTime * (mCamera.f[14] - m_vCamFrom.z);

		m_vCamTo.x	+= fDeltaTime * (2.0f * (m_mDuckWorld.f[12] - m_vCamTo.x));
		m_vCamTo.y	+= fDeltaTime * (2.0f * (m_mDuckWorld.f[13] + 25.0f - m_vCamTo.y));
		m_vCamTo.z	+= fDeltaTime * (2.0f * (m_mDuckWorld.f[14] - m_vCamTo.z));

		// Build view matrix
		m_mView = PVRTMat4::LookAtRH(m_vCamFrom, m_vCamTo, c_vUp);

		// Calc ViewProjInv matrix
		mTmp = m_mProj * m_mView;
		mTmp = mTmp.inverseEx();

		// Calculate the ground plane
		m_i32WaterPlaneNo = PVRTMiscCalculateInfinitePlane(&pvPlane->x, sizeof(*pvPlane), &c_vPlaneWater, &mTmp, &m_vCamFrom, g_fFar);

		for(i = 0; i < m_i32WaterPlaneNo; ++i)
		{
			m_pvPlaneWater[i].x		= pvPlane[i].x;
			m_pvPlaneWater[i].y		= pvPlane[i].y;
			m_pvPlaneWater[i].z		= pvPlane[i].z;
			m_pvPlaneWater[i].nx	= c_vPlaneWater.x;
			m_pvPlaneWater[i].ny	= c_vPlaneWater.y;
			m_pvPlaneWater[i].nz	= c_vPlaneWater.z;
			m_pvPlaneWater[i].tu	= pvPlane[i].x * 0.005f;
			m_pvPlaneWater[i].tv	= pvPlane[i].z * 0.005f;
		}

		// Calculate the Cloud plane
		m_i32CloudPlaneNo = PVRTMiscCalculateInfinitePlane(&pvPlane->x, sizeof(*pvPlane), &c_vPlaneCloud, &mTmp, &m_vCamFrom, g_fFar);

		for(i = 0; i < m_i32CloudPlaneNo; ++i)
		{
			m_pvPlaneCloud[i].x		= pvPlane[i].x;
			m_pvPlaneCloud[i].y		= pvPlane[i].y;
			m_pvPlaneCloud[i].z		= pvPlane[i].z;
			m_pvPlaneCloud[i].nx	= c_vPlaneCloud.x;
			m_pvPlaneCloud[i].ny	= c_vPlaneCloud.y;
			m_pvPlaneCloud[i].nz	= c_vPlaneCloud.z;
			m_pvPlaneCloud[i].tu	= pvPlane[i].x * ((1.0f / 100.0f) + m_ui32PrevTime * 0.0002f);
			m_pvPlaneCloud[i].tv	= pvPlane[i].z * (1.0f / 100.0f);
		}
	}
}
Example #28
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @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 relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES3IntroducingPOD::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use shader program
	glUseProgram(m_ShaderProgram.uiId);

	/*
		Calculates the frame number to animate in a time-based manner.
		Uses the shell function PVRShellGetTime() to get the time in milliseconds.
	*/
	unsigned long ulTime = PVRShellGetTime();

	if(m_ulTimePrev > ulTime)
		m_ulTimePrev = ulTime;

	unsigned long ulDeltaTime = ulTime - m_ulTimePrev;
	m_ulTimePrev	= ulTime;
	m_fFrame += (float)ulDeltaTime * g_fDemoFrameRate;
	if (m_fFrame > m_Scene.nNumFrame - 1) m_fFrame = 0;

	// Sets the scene animation to this frame
	m_Scene.SetFrame(m_fFrame);

	/*
		Get the direction of the first light from the scene.
	*/
	PVRTVec4 vLightDirection;
	vLightDirection = m_Scene.GetLightDirection(0);
	// For direction vectors, w should be 0
	vLightDirection.w = 0.0f;

	/*
		Set up the view and projection matrices from the camera
	*/
	PVRTMat4 mView, mProjection;
	PVRTVec3	vFrom, vTo(0.0f), vUp(0.0f, 1.0f, 0.0f);
	float fFOV;

	// Setup the camera

	// Camera nodes are after the mesh and light nodes in the array
	int i32CamID = m_Scene.pNode[m_Scene.nNumMeshNode + m_Scene.nNumLight + g_ui32Camera].nIdx;

	// Get the camera position, target and field of view (fov)
	if(m_Scene.pCamera[i32CamID].nIdxTarget != -1) // Does the camera have a target?
		fFOV = m_Scene.GetCameraPos( vFrom, vTo, g_ui32Camera); // vTo is taken from the target node
	else
		fFOV = m_Scene.GetCamera( vFrom, vTo, vUp, g_ui32Camera); // vTo is calculated from the rotation

	// We can build the model view matrix from the camera position, target and an up vector.
	// For this we use PVRTMat4::LookAtRH()
	mView = PVRTMat4::LookAtRH(vFrom, vTo, vUp);

	// Calculate the projection matrix
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	mProjection = PVRTMat4::PerspectiveFovRH(fFOV, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, bRotate);

	/*
		A scene is composed of nodes. There are 3 types of nodes:
		- MeshNodes :
			references a mesh in the pMesh[].
			These nodes are at the beginning of the pNode[] array.
			And there are nNumMeshNode number of them.
			This way the .pod format can instantiate several times the same mesh
			with different attributes.
		- lights
		- cameras
		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 node model matrix
		PVRTMat4 mWorld;
		mWorld = m_Scene.GetWorldMatrix(Node);

		// Pass the model-view-projection matrix (MVP) to the shader to transform the vertices
		PVRTMat4 mModelView, mMVP;
		mModelView = mView * mWorld;
		mMVP = mProjection * mModelView;
		glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.f);

		// Pass the light direction in model space to the shader
		PVRTVec4 vLightDir;
		vLightDir = mWorld.inverse() * vLightDirection;

		PVRTVec3 vLightDirModel = *(PVRTVec3*)&vLightDir;
		vLightDirModel.normalize();

		glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, &vLightDirModel.x);

		// Load the correct texture using our texture lookup table
		GLuint uiTex = 0;

		if(Node.nIdxMaterial != -1)
			uiTex = m_puiTextureIDs[Node.nIdxMaterial];

		glBindTexture(GL_TEXTURE_2D, uiTex);

		/*
			Now that the model-view matrix is set and the materials are ready,
			call another function to actually draw the mesh.
		*/
		DrawMesh(i);
	}

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

	return true;
}
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @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 relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLESIntroducingPFX::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use the loaded effect
	m_pEffect->Activate();

	/*
		Calculates the frame number to animate in a time-based manner.
		Uses the shell function PVRShellGetTime() to get the time in milliseconds.
	*/
	int iTime = PVRShellGetTime();
	int iDeltaTime = iTime - m_iTimePrev;
	m_iTimePrev	= iTime;
	m_fFrame	+= (float)iDeltaTime * DEMO_FRAME_RATE;
	if (m_fFrame > m_Scene.nNumFrame-1)
		m_fFrame = 0;

	// Sets the scene animation to this frame
	m_Scene.SetFrame(m_fFrame);

	{
		PVRTVec3	vFrom, vTo, vUp;
		VERTTYPE	fFOV;
		vUp.x = 0.0f;
		vUp.y = 1.0f;
		vUp.z = 0.0f;

		// We can get the camera position, target and field of view (fov) with GetCameraPos()
		fFOV = m_Scene.GetCameraPos(vFrom, vTo, 0) * 0.4f;

		/*
			We can build the world view matrix from the camera position, target and an up vector.
			For this we use PVRTMat4LookAtRH().
		*/
		m_mView = PVRTMat4::LookAtRH(vFrom, vTo, vUp);

		// Calculates the projection matrix
		bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
		m_mProjection = PVRTMat4::PerspectiveFovRH(fFOV, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate);
	}

	/*
		A scene is composed of nodes. There are 3 types of nodes:
		- MeshNodes :
			references a mesh in the pMesh[].
			These nodes are at the beginning of the pNode[] array.
			And there are nNumMeshNode number of them.
			This way the .pod format can instantiate several times the same mesh
			with different attributes.
		- lights
		- cameras
		To draw a scene, you must go through all the MeshNodes and draw the referenced meshes.
	*/
	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];

		glBindBuffer(GL_ARRAY_BUFFER, m_aiVboID[i]);

		// Gets the node model matrix
		PVRTMat4 mWorld;
		mWorld = m_Scene.GetWorldMatrix(*pNode);

		PVRTMat4 mWorldView;
		mWorldView = m_mView * mWorld;

		for(unsigned int j = 0; j < m_nUniformCnt; ++j)
		{
			switch(m_psUniforms[j].nSemantic)
			{
			case eUsPOSITION:
				{
					glVertexAttribPointer(m_psUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
					glEnableVertexAttribArray(m_psUniforms[j].nLocation);
				}
				break;
			case eUsNORMAL:
				{
					glVertexAttribPointer(m_psUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
					glEnableVertexAttribArray(m_psUniforms[j].nLocation);
				}
				break;
			case eUsUV:
				{
					glVertexAttribPointer(m_psUniforms[j].nLocation, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);
					glEnableVertexAttribArray(m_psUniforms[j].nLocation);
				}
				break;
			case eUsWORLDVIEWPROJECTION:
				{
					PVRTMat4 mWVP;

					/* Passes the world-view-projection matrix (WVP) to the shader to transform the vertices */
					mWVP = m_mProjection * mWorldView;
					glUniformMatrix4fv(m_psUniforms[j].nLocation, 1, GL_FALSE, mWVP.f);
				}
				break;
			case eUsWORLDVIEWIT:
				{
					PVRTMat4 mWorldViewI, mWorldViewIT;

					/* Passes the inverse transpose of the world-view matrix to the shader to transform the normals */
					mWorldViewI  = mWorldView.inverse();
					mWorldViewIT = mWorldViewI.transpose();

					PVRTMat3 WorldViewIT = PVRTMat3(mWorldViewIT);

					glUniformMatrix3fv(m_psUniforms[j].nLocation, 1, GL_FALSE, WorldViewIT.f);
				}
				break;
			case eUsLIGHTDIREYE:
				{
					// Reads the light direction from the scene.
					PVRTVec4 vLightDirection;
					PVRTVec3 vPos;
					vLightDirection = m_Scene.GetLightDirection(0);

					vLightDirection.x = -vLightDirection.x;
					vLightDirection.y = -vLightDirection.y;
					vLightDirection.z = -vLightDirection.z;

					/*
						Sets the w component to 0, so when passing it to glLight(), it is
						considered as a directional light (as opposed to a spot light).
					*/
					vLightDirection.w = 0;

					// Passes the light direction in eye space to the shader
					PVRTVec4 vLightDirectionEyeSpace;
					vLightDirectionEyeSpace = m_mView * vLightDirection;

					glUniform3f(m_psUniforms[j].nLocation, vLightDirectionEyeSpace.x, vLightDirectionEyeSpace.y, vLightDirectionEyeSpace.z);
				}
				break;
			case eUsTEXTURE:
				{
					// Set the sampler variable to the texture unit
					glUniform1i(m_psUniforms[j].nLocation, m_psUniforms[j].nIdx);
				}
				break;
			}
		}

		/*
			Now that the model-view matrix is set and the materials ready,
			call another function to actually draw the mesh.
		*/
		DrawMesh(pMesh);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		for(unsigned int j = 0; j < m_nUniformCnt; ++j)
		{
			switch(m_psUniforms[j].nSemantic)
			{
			case eUsPOSITION:
				{
					glDisableVertexAttribArray(m_psUniforms[j].nLocation);
				}
				break;
			case eUsNORMAL:
				{
					glDisableVertexAttribArray(m_psUniforms[j].nLocation);
				}
				break;
			case eUsUV:
				{
					glDisableVertexAttribArray(m_psUniforms[j].nLocation);
				}
				break;
			}
		}
	}

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

	return true;
}
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @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 and relevant OS events.
				The user has access to these events through an abstraction
				layer provided by PVRShell.
******************************************************************************/
bool OGLES3EdgeDetection::RenderScene()
{
	// Declares world orientation variables.
	PVRTMat4 mWorld, mMVP;

	// Updates the current time.
	m_ulCurrentTime=PVRShellGetTime();

#ifdef SHOW_MAX_FPS
	//Updates and checks framerate.
	m_iFrameCount+=1;
	if (m_ulCurrentTime-m_ulPreviousTimeFPS>=1000)
	{
		m_fFPS=(GLfloat)m_iFrameCount/(GLfloat)(m_ulCurrentTime-m_ulPreviousTimeFPS)*1000.0f;
		m_ulPreviousTimeFPS=m_ulCurrentTime;
		m_iFrameCount=0;
	}
	// Display fps data
	m_Print3D.Print3D(2.0f, 10.0f, 0.75f, 0xff0000ff, "%i fps", (int)m_fFPS);
#endif

	// Time dependant updates for the rotational velocity of the scene.
	m_fAngleY += 0.0002f*PVRT_PI*(m_ulCurrentTime-m_ulPreviousTimeAngle);
	m_ulPreviousTimeAngle=PVRShellGetTime();

	// Render to our texture (bracketed for viewing convenience)
	{
		// Use the first shader program to perform the initial render of the mask.
		glUseProgram(m_PreShader.uiId);

		// Bind render-to-texture frame buffer and set the viewPort
		glBindFramebuffer(GL_FRAMEBUFFER, m_uiFramebufferObject);

		if(m_i32TexWidth != m_i32WinWidth || m_i32TexHeight != m_i32WinHeight)
			glViewport(0, 0, m_i32TexWidth, m_i32TexHeight);

#if defined(__PALMPDK__)
		// Enable writing to the alpha channel again as usually it is disabled so
		// we don't blend with the video layer on webOS devices.
		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
#endif
		// Clear the color and depth buffer of our FBO
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// Rotates the scene and sets the model-view-projection matrix
		mWorld = PVRTMat4::RotationY(m_fAngleY);
		mMVP = m_mR2TProjection * m_mR2TView * mWorld;

		// Send the view matrix information to the shader.
		glUniformMatrix4fv(m_PreShader.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.f);

		// Enable vertex attribute array
		glEnableVertexAttribArray(eVERTEX_ARRAY);

		//Enable depth testing and culling.
		glEnable(GL_DEPTH_TEST);
		glFrontFace(GL_CCW);
		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);

		// Draw our models by looping through each mesh as defined by nNumMesh.
		for (unsigned int i=0; i<m_Scene.nNumMeshNode; i++)
		{
			DrawMesh(i);
		}

		// Unbind the VBO and index buffer.
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
		glDisable(GL_DEPTH_TEST);
		glDisable(GL_CULL_FACE);

		//Invalidate the framebuffer attachments we don't need to avoid unnecessary copying to system memory
		const GLenum attachment = GL_DEPTH_ATTACHMENT;
		glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &attachment);
	}

	// Bind the original frame buffer to draw to screen and set the Viewport.
	glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFramebuffer);

	if(m_i32TexWidth != m_i32WinWidth || m_i32TexHeight != m_i32WinHeight)
		glViewport(0, 0, m_i32WinWidth, m_i32WinHeight);

	// Clear the color and depth buffers for the screen.
	glClear(GL_COLOR_BUFFER_BIT);

	// Uses PVRShell input handling to update the line width in the edge detection shaders.
	if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_fLineWidth++;
		if (m_fLineWidth>10) m_fLineWidth=10;
	}
	if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_fLineWidth--;
		if (m_fLineWidth<1) m_fLineWidth=1;
	}
	// Uses PVRShell input to choose which post shader program to use for post processing.
	// Loops through all shaders defined in EPostShaders
	if (PVRShellIsKeyPressed(PVRShellKeyNameUP))
	{
		if (m_uiShaderID==eNumPostShaders-1) m_uiShaderID=0;
		else m_uiShaderID++;
	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
	{
		if (m_uiShaderID==0) m_uiShaderID=eNumPostShaders-1;
		else m_uiShaderID--;
	}

	// Sets the shader based on the shader ID value, and sets the line width each frame (as it can change);
	glUseProgram(m_PostShaders[m_uiShaderID].uiId);
	glUniform2f(m_PostShaders[m_uiShaderID].auiLoc[ePixelSize],m_fLineWidth/(float)m_i32TexWidth,m_fLineWidth/(float)m_i32TexHeight);

	/*  Note: We do not need to pass any projection data to these shaders as they are used only to render a texture to a
		full screen quad which is parallel with the viewport. The model meshes have already been positioned in the previous
		shader and now only exist as a 2D image.*/

	// Enable texture attribute array
	glEnableVertexAttribArray(eTEXCOORD_ARRAY);
	// Draw the fullscreen quad to render the screen to.
	DrawQuad();

	// Disable the vertex and texture attribute arrays
	glDisableVertexAttribArray(eTEXCOORD_ARRAY);
	glDisableVertexAttribArray(eVERTEX_ARRAY);

	// Print the demo title, current post shader's name and the line width if applicable
	m_Print3D.DisplayDefaultTitle("Edge Detection", "", ePVRTPrint3DSDKLogo);
	m_Print3D.Print3D(5,80,1,0xff885500,g_aszPostShaderNames[m_uiShaderID]);
	if (!strcmp(c_aszPostShaderDefines[m_uiShaderID][0],"EDGE_DETECTION"))
		m_Print3D.Print3D(5,90,0.7f,0xff000055,"Line Width = %i", (int)m_fLineWidth);
	m_Print3D.Flush();

	return true;
}