示例#1
0
/*!****************************************************************************
 @Function		ReleaseView
 @Return		bool		true if no error occurred
 @Description	Code in ReleaseView() will be called by PVRShell when the
				application quits or before a change in the rendering context.
******************************************************************************/
bool OGLES3PhantomMask::ReleaseView()
{
    // Release all Textures
    glDeleteTextures(1, &m_ui32TexMask);
    glDeleteTextures(1, &m_ui32TexBackground);

    // Delete program and shader objects
    glDeleteProgram(m_SHShaderProgram.uiId);
    glDeleteProgram(m_DiffuseShaderProgram.uiId);

    glDeleteShader(m_uiSHVertShader);
    glDeleteShader(m_uiDifVertShader);
    glDeleteShader(m_uiFragShader);

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

    // Release Print3D Textures
    m_Print3D.ReleaseTextures();

    m_Background.Destroy();

    return true;
}
示例#2
0
/*!***************************************************************************
@Function		GenerateBackgroundTexture
@Input			uiScreenWidth
@Input			uiScreenHeight
@Description	Generates a simple background texture procedurally.
*****************************************************************************/
void OGLES2IntroducingPrint3D::GenerateBackgroundTexture(unsigned int uiScreenWidth, unsigned int uiScreenHeight)
{
	// Generate star texture
	unsigned int uiStarW = PVRTGetPOTHigher(uiScreenWidth, 1);
	unsigned int uiStarH = PVRTGetPOTHigher(uiScreenHeight, 1);

	glGenTextures(1, &m_uiStarTex);
	glBindTexture(GL_TEXTURE_2D, m_uiStarTex);
	PVRTuint8* pTexData = new PVRTuint8[uiStarW*uiStarH];
	memset(pTexData, 0, uiStarW*uiStarH);
	for (unsigned int uiY = 0; uiY < uiStarH; uiY++)
	{
		for (unsigned int uiX = 0; uiX < uiStarW; uiX++)
		{
			unsigned int uiIdx = (uiY*uiStarW+uiX);
			if(rand() % 200 == 1)
			{
				pTexData[uiIdx] = rand() % 255;
			}
		}
	}
	glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, uiStarW, uiStarH, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, pTexData);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	delete [] pTexData;

	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	m_BG.Init(NULL, bRotate, NULL);
}
示例#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 OGLES2IntroducingPrint3D::ReleaseView()
{
	// Release Print3D Textures
	m_Print3D.ReleaseTextures();
	m_CentralText.ReleaseTextures();
	m_IntroText.ReleaseTextures();
	m_TitleText.ReleaseTextures();
	m_BG.Destroy();

	return true;
}
示例#4
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 dependant on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLES3PhantomMask::InitView()
{
    CPVRTString ErrorStr;

    // Initialise 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(!LoadShaders(&ErrorStr))
    {
        PVRShellSet(prefExitMessage, ErrorStr.c_str());
        return false;
    }

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

    // Initialise the background
    if(m_Background.Init(0, bRotate, &ErrorStr) != PVR_SUCCESS)
    {
        PVRShellSet(prefExitMessage, ErrorStr.c_str());
        return false;
    }

    // Use a nice bright blue as clear colour
    glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
    return true;
}
/*!****************************************************************************
 @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 OGLES3Refraction::ReleaseView()
{
	// Delete textures
	glDeleteTextures(1, &m_uiTexture);

	// Delete program and shader objects
	glDeleteProgram(m_ShaderProgram.uiId);

	glDeleteShader(m_uiVertShader);
	glDeleteShader(m_uiFragShader);

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

	// Release Print3D Textures
	m_Print3D.ReleaseTextures();

    m_Background.Destroy();

	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 OGLES3Refraction::RenderScene()
{
	// Keyboard input (cursor to change Reflection Flag)
	if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT) || PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_bSpecular = !m_bSpecular;
	}

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

	m_Background.Draw(m_uiTexture);

	// Enable backface culling and depth test
	glCullFace(GL_BACK);
	glFrontFace(GL_CCW);
	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);

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

	// Bind textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiTexture);

	// Calculate the model matrix
	PVRTMat4 mRotX, mRotY, mModel;
	mRotX = PVRTMat4::RotationX(m_fAngleX);
	mRotY = PVRTMat4::RotationY(m_fAngleY);
	mModel = mRotX * mRotY;

	m_fAngleX += PVRT_PI / 111;
	m_fAngleY += PVRT_PI / 150;

	// Set model view projection matrix
	PVRTMat4 mModelView, mMVP;
	mModelView = m_mView * mModel;
	mMVP = m_mProjection * mModelView;

	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr());

	// Set light direction in model space
	PVRTVec4 vLightDirModel;
	vLightDirModel =  mModelView.inverse() * PVRTVec4(0.57735f, 0.57735f, 0.57735f, 0);

	glUniform3fv(m_ShaderProgram.auiLoc[eLightDirModel], 1, &vLightDirModel.x);

	// Set eye position in model space
	PVRTVec4 vEyePosModel;
	vEyePosModel = mModelView.inverse() * PVRTVec4(0, 0, 0, 1);

	glUniform3fv(m_ShaderProgram.auiLoc[eEyePosModel], 1, &vEyePosModel.x);

	// Set specular flag
	glUniform1i(m_ShaderProgram.auiLoc[eSpecular], m_bSpecular);

	// Set rotation flag
	glUniform1i(m_ShaderProgram.auiLoc[eRotate], m_bRotate);

	/*
		Now that the uniforms are set, call another function to actually draw the mesh.
	*/
	DrawMesh(0);

	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	m_Print3D.DisplayDefaultTitle("Refraction", m_bSpecular ? "Specular reflection: on" : "Specular reflection: off", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();
	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 OGLES3Refraction::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;
	}

	// Set the sampler2D uniforms to corresponding texture units
	glUniform1i(glGetUniformLocation(m_ShaderProgram.uiId, "sTexture"), 0);

	// Is the screen rotated?
	m_bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	/*
		Initialize Print3D
	*/
	if(m_Print3D.SetTextures(0,PVRShellGet(prefWidth),PVRShellGet(prefHeight), m_bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D\n");
		return false;
	}

	/*
		Initalise the background
	*/

	if(m_Background.Init(0, m_bRotate, &ErrorStr) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	/*
		Calculate the projection and view matrices
	*/
	m_mProjection = PVRTMat4::PerspectiveFovRH(PVRT_PI/6, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), CAM_NEAR, CAM_FAR, PVRTMat4::OGL, m_bRotate);

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

	/*
		Set OpenGL ES render states needed for this training course
	*/

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

	return true;
}
示例#8
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 OGLESVase::RenderScene()
{
	PVRTMat4 RotationMatrix, RotateX, RotateY;

	// Increase rotation angles
	m_fAngleX += VERTTYPEDIV(PVRT_PI, f2vt(100.0f));
	m_fAngleY += VERTTYPEDIV(PVRT_PI, f2vt(150.0f));

	if(m_fAngleX >= PVRT_PI)
		m_fAngleX -= PVRT_TWO_PI;

	if(m_fAngleY >= PVRT_PI)
		m_fAngleY -= PVRT_TWO_PI;

	// Clear the buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Setup the vase rotation

	// Calculate rotation matrix
	RotateX = PVRTMat4::RotationX(m_fAngleX);
	RotateY = PVRTMat4::RotationY(m_fAngleY);

	RotationMatrix = RotateY * RotateX;

	// Modelview matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	myglTranslate(f2vt(0.0f), f2vt(0.0f), f2vt(-200.0f));
	myglMultMatrix(RotationMatrix.f);

	// Draw the scene

	// Use PVRTools to draw a background image
	m_Background.Draw(m_uiBackTex);


	// Enable client states
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	// Enable depth test
	glEnable(GL_DEPTH_TEST);

	// Draw vase outer
	glBindTexture(GL_TEXTURE_2D, m_pui32Textures[m_Scene.pNode[eVase].nIdxMaterial]);
	DrawReflectiveMesh(m_Scene.pNode[eVase].nIdx, &RotationMatrix);

	// Draw glass
	glEnable(GL_BLEND);

	glBindTexture(GL_TEXTURE_2D, m_pui32Textures[m_Scene.pNode[eGlass].nIdxMaterial]);

	// Pass 1: only render back faces (model has reverse winding)
	glFrontFace(GL_CW);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);

	DrawMesh(m_Scene.pNode[eGlass].nIdx);

	// Pass 2: only render front faces (model has reverse winding)
	glCullFace(GL_FRONT);
	DrawMesh(m_Scene.pNode[eGlass].nIdx);

	// Disable blending as it isn't needed
	glDisable(GL_BLEND);

	// Disable client states
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);

	// Display info text
	m_Print3D.DisplayDefaultTitle("Vase", "Translucency and reflections.", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();
	return true;
}
示例#9
0
/*******************************************************************************
 * Function Name  : InitView
 * 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 initialize variables that are dependant on the rendering
 *					context (e.g. textures, vertex buffers, etc.)
 *******************************************************************************/
bool OGLESVase::InitView()
{
	CPVRTString  ErrorStr;
	SPVRTContext Context;

	// Is the screen rotated?
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

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

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

	//	Initialize VBO data
	LoadVbos();

	// Initialize Background
	if(m_Background.Init(0, bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Background\n");
		return false;
	}

	/*
		Build an array to map the textures within the pod file
		to the textures we loaded earlier.
	*/

	m_pui32Textures = new GLuint[m_Scene.nNumMaterial];

	for(unsigned int i = 0; i < m_Scene.nNumMaterial; ++i)
	{
		m_pui32Textures[i] = 0;
		SPODMaterial* pMaterial = &m_Scene.pMaterial[i];

		if(!strcmp(pMaterial->pszName, "Flora"))
			m_pui32Textures[i] = m_uiFloraTex;
		else if(!strcmp(pMaterial->pszName, "Reflection"))
			m_pui32Textures[i] = m_uiReflectTex;
	}

	// Calculates the projection matrix
	m_mProjection = PVRTMat4::PerspectiveFovRH(f2vt(35.0f*(3.14f/180.0f)), f2vt((float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight)), f2vt(g_fCameraNear), f2vt(g_fCameraFar), PVRTMat4::OGL, bRotate);

	// Loads the projection matrix
	glMatrixMode(GL_PROJECTION);
	myglLoadMatrix(m_mProjection.f);

	// Enable texturing
	glEnable(GL_TEXTURE_2D);

	// Setup clear colour
	myglClearColor(f2vt(1.0f),f2vt(1.0f),f2vt(1.0f),f2vt(1.0f));

	// Set blend mode
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	return true;
}
示例#10
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 OGLES3PhantomMask::RenderScene()
{
    if(PVRShellIsKeyPressed(PVRShellKeyNameACTION1))
        m_bEnableSH = !m_bEnableSH;

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

    // Draw the background
    m_Background.Draw(m_ui32TexBackground);

    // Enable culling
    glEnable(GL_CULL_FACE);

    // Enable depth testing
    glEnable(GL_DEPTH_TEST);

    // Use shader program
    GLuint ProgramID, MVPLoc, ModelLoc;

    if(m_bEnableSH)
    {
        ProgramID = m_SHShaderProgram.uiId;
        MVPLoc	  = m_SHShaderProgram.auiLoc[eSHMVPMatrix];
        ModelLoc  = m_SHShaderProgram.auiLoc[eSHModel];
    }
    else
    {
        ProgramID = m_DiffuseShaderProgram.uiId;
        MVPLoc	  = m_DiffuseShaderProgram.auiLoc[eDifMVPMatrix];
        ModelLoc  = m_DiffuseShaderProgram.auiLoc[eDifModel];
    }

    glUseProgram(ProgramID);

    /*
    	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(ulTime > m_ulTimePrev)
    {
        unsigned long ulDeltaTime = ulTime - m_ulTimePrev;
        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);
    }

    m_ulTimePrev = ulTime;

    /*
    	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
    bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

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

    fFOV *= bRotate ? (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight) : (float)PVRShellGet(prefHeight)/(float)PVRShellGet(prefWidth);

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

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

    SPODNode& Node = m_Scene.pNode[0];

    // Get the node model matrix
    PVRTMat4 mWorld;
    mWorld = m_Scene.GetWorldMatrix(Node);

    // Set the model inverse transpose matrix
    PVRTMat3 mMat3 = PVRTMat3(mWorld);

    if(m_bEnableSH)
        mMat3 *= PVRTMat3::RotationY(-1.047197f);

    glUniformMatrix3fv(ModelLoc, 1, GL_FALSE, mMat3.f);

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

    glBindTexture(GL_TEXTURE_2D, m_ui32TexMask);
    DrawMesh(Node.nIdx);

    // Print text on screen

    if(m_bEnableSH)
    {
        // Base
        m_Print3D.DisplayDefaultTitle("PhantomMask", "Spherical Harmonics Lighting", ePVRTPrint3DSDKLogo);
    }
    else
    {
        // Base
        m_Print3D.DisplayDefaultTitle("PhantomMask", "Vertex Lighting", ePVRTPrint3DSDKLogo);
    }

    m_Print3D.Flush();

    return true;
}
示例#11
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 OGLES2IntroducingPrint3D::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	unsigned long ulCurrentTime = PVRShellGetTime() - m_ulStartTime;

	// Draw star background
	m_BG.Draw(m_uiStarTex);
	 
	// Render the 'Introducing Print3D' title for the first n seconds.
	if(ulCurrentTime < INTRO_TIME)
	{
		float fFadeAmount = 1.0f;
		
		// Fade in
		if(ulCurrentTime < INTRO_FADE_TIME)	
		{
			fFadeAmount = ulCurrentTime / (float)INTRO_FADE_TIME;
		}
		// Fade out
		else if(ulCurrentTime > INTRO_TIME - INTRO_FADE_TIME)
		{
			fFadeAmount = 1.0f - ((ulCurrentTime - (INTRO_TIME - INTRO_FADE_TIME)) / (float)INTRO_FADE_TIME);
		}

		RenderTitle(fFadeAmount);		
	}
	// Render the 3D text.
	else
	{
		RenderText();
	}

	/*
		Here we are passing in a wide-character string to Print3D function. This allows
		Unicode to be compiled in to string-constants, which this code snippet
		demonstrates.
		Because we are not setting a projection or a model-view matrix the default projection 
		matrix is used.
	*/
	unsigned int uiTitleLang = (unsigned int) ((ulCurrentTime / 1000) / (TITLE_TIME / 1000)) % eLang_Size;
	unsigned int uiNextLang  = (uiTitleLang + 1) % eLang_Size;
	unsigned int ulModTime   = (unsigned int) ulCurrentTime % TITLE_TIME;
	float fTitlePerc = 1.0f;
	float fNextPerc  = 0.0f;
	if(ulModTime > TITLE_TIME - TITLE_FADE_TIME)
	{
		fTitlePerc = 1.0f - ((ulModTime - (INTRO_TIME - INTRO_FADE_TIME)) / (float)INTRO_FADE_TIME);
		fNextPerc = 1.0f - fTitlePerc;
	}
	unsigned int uiTitleCol = (((unsigned int)(fTitlePerc * 255)) << 24) | 0xFFFFFF;
	unsigned int uiNextCol  = (((unsigned int)(fNextPerc  * 255)) << 24) | 0xFFFFFF;
	m_TitleText.Print3D(0, 0, 1, uiTitleCol, c_pwzTitles[uiTitleLang]);
	m_TitleText.Print3D(0, 0, 1, uiNextCol, c_pwzTitles[uiNextLang]);
	m_TitleText.Flush();
		
	/*
		DisplayDefaultTitle() writes a title and description text on the top left of the screen.
		It can also display the PVR logo (ePVRTPrint3DLogoPowerVR), the IMG logo (ePVRTPrint3DLogoIMG) or both (ePVRTPrint3DLogoPowerVR | ePVRTPrint3DLogoIMG)
		which is what we are using the function for here.
		Set this last parameter to NULL not to display the logos.
		Passing NULL for the first two parameters will not display any text.
	*/
	m_Print3D.DisplayDefaultTitle(NULL, NULL, ePVRTPrint3DSDKLogo);

	// Tells Print3D to do all the pending text rendering now
	m_Print3D.Flush();
	
	return true;
}