示例#1
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 OGLESParticles::RenderScene()
{
	int				i;
	PVRTMat4		mRotY;

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

	// Enables depth testing
	glEnable(GL_DEPTH_TEST);

	//	Modify per-frame variables controlling the particle mouvements.
	float fSpeedCtrl = (float) (PVRTFSIN(m_fRot*0.01f)+1.0f)/2.0f;
	float fStopNo = 0.8f;
	float fStep = 0.1f;

	if(fSpeedCtrl > fStopNo)
		fStep = 0.0f;

	// Generate particles as needed.
	if((m_i32NumParticles < (int) g_ui32MaxParticles) && (fSpeedCtrl <= fStopNo))
	{
		int num_to_gen = (int) (RandPositiveFloat()*(g_ui32MaxParticles/100.0));

		if(num_to_gen == 0)
			num_to_gen = 1;

		for(i = 0; (i < num_to_gen) && (m_i32NumParticles < (int) g_ui32MaxParticles); ++i)
			SpawnParticle(&m_Particles[m_i32NumParticles++]);
	}

	// Build rotation matrix around axis Y.
	mRotY = PVRTMat4::RotationY(f2vt((m_fRot2*PVRT_PIf)/180.0f));

	for(i = 0; i < m_i32NumParticles; ++i)
	{
		// Transform particle with rotation matrix
		m_sParticleVTXPSBuf[i].x =	VERTTYPEMUL(mRotY.f[ 0], m_Particles[i].m_fPosition.x) +
								VERTTYPEMUL(mRotY.f[ 4], m_Particles[i].m_fPosition.y) +
								VERTTYPEMUL(mRotY.f[ 8], m_Particles[i].m_fPosition.z) +
											mRotY.f[12];
		m_sParticleVTXPSBuf[i].y =	VERTTYPEMUL(mRotY.f[ 1], m_Particles[i].m_fPosition.x) +
								VERTTYPEMUL(mRotY.f[ 5], m_Particles[i].m_fPosition.y) +
								VERTTYPEMUL(mRotY.f[ 9], m_Particles[i].m_fPosition.z) +
											mRotY.f[13];
		m_sParticleVTXPSBuf[i].z =	VERTTYPEMUL(mRotY.f[ 2], m_Particles[i].m_fPosition.x) +
								VERTTYPEMUL(mRotY.f[ 6], m_Particles[i].m_fPosition.y) +
								VERTTYPEMUL(mRotY.f[10], m_Particles[i].m_fPosition.z) +
											mRotY.f[14];

		m_sParticleVTXPSBuf[i].fSize = m_Particles[i].m_fSize;

		m_sNormalColour[i].r  = vt2b(m_Particles[i].m_fColour.x);
		m_sNormalColour[i].g  = vt2b(m_Particles[i].m_fColour.y);
		m_sNormalColour[i].b  = vt2b(m_Particles[i].m_fColour.z);
		m_sNormalColour[i].a  = (unsigned char)255;

		m_sReflectColour[i].r  = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.x, g_fFactor));
		m_sReflectColour[i].g  = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.y, g_fFactor));
		m_sReflectColour[i].b  = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.z, g_fFactor));
		m_sReflectColour[i].a  = (unsigned char)255;
	}

	glBindBuffer(GL_ARRAY_BUFFER, m_i32VertVboID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(SVtxPointSprite)*m_i32NumParticles, m_sParticleVTXPSBuf,GL_DYNAMIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, m_i32ColAVboID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(SColors)*m_i32NumParticles, m_sNormalColour,GL_DYNAMIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, m_i32ColBVboID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(SColors)*m_i32NumParticles, m_sReflectColour,GL_DYNAMIC_DRAW);

	// clean up render states
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);

	//	Draw floor.

	// Save modelview matrix
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	myglRotate(f2vt(-m_fRot), f2vt(0.0f), f2vt(1.0f), f2vt(0.0f));

	// setup render states
	glDisable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glDisable(GL_CULL_FACE);
	glEnable(GL_BLEND);

	// Set texture and texture environment
	glBindTexture(GL_TEXTURE_2D, m_ui32FloorTexName);
	glBlendFunc(GL_ONE, GL_ONE);

	// Render floor
	RenderFloor();

	// clean up render states
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);

	glPopMatrix();

	//	Render particles reflections.

	// set up render states
	glDisable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);

	glDepthFunc(GL_ALWAYS);
	glDisable(GL_CULL_FACE);

	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE);

	myglTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glBindTexture(GL_TEXTURE_2D, m_ui32TexName);

	// Set model view matrix
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	myglScale(f2vt(1.0f), f2vt(-1.0f), f2vt(1.0f));
	myglTranslate(f2vt(0.0f), f2vt(0.01f), f2vt(0.0f));

	glEnable(GL_POINT_SPRITE_OES);

	if(((int)(m_i32NumParticles * 0.5f)) > 0)
       RenderParticle(((int)(m_i32NumParticles*0.5f)),true);

	glPopMatrix();

	//	Render particles.

	// Sets the model view matrix
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	if(m_i32NumParticles > 0)
        RenderParticle(m_i32NumParticles,false);

	glPopMatrix();

	glDisable(GL_POINT_SPRITE_OES);

	PVRTVec3 Force = PVRTVec3(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f));
	Force.x = f2vt(1000.0f*(float)PVRTFSIN(m_fRot*0.01f));

	for(i = 0; i < m_i32NumParticles; ++i)
	{
		/*
			Move the particle.
			If the particle exceeds its lifetime, create a new one in its place.
		*/
		if(m_Particles[i].Step(f2vt(fStep), Force))
			SpawnParticle(&m_Particles[i]);
	}

	// clean up render states
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);

	// Increase rotation angles
	m_fRot += 1;
	m_fRot2 = m_fRot + 36;

	// Unbinds the vertex buffer if we are using OpenGL ES 1.1
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	// Display info text.
	m_Print3D.DisplayDefaultTitle("Particles", "Using point sprites", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();

	return true;
}
示例#2
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 OGLESEvilSkull::InitView()
{
	PVRTMat4		mPerspective;
	SPVRTContext	sContext;

	// Initialize Print3D textures
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

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

	/***********************
	** LOAD TEXTURES     **
	***********************/
	if(PVRTTextureLoadFromPVR(c_szIrisTexFile, &m_ui32Texture[0]) != PVR_SUCCESS)
		return false;

	myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
	myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	if(PVRTTextureLoadFromPVR(c_szMetalTexFile, &m_ui32Texture[1]) != PVR_SUCCESS)
		return false;

	myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
	myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	if(PVRTTextureLoadFromPVR(c_szFire02TexFile, &m_ui32Texture[2]) != PVR_SUCCESS)
		return false;

	myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
	myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	if(PVRTTextureLoadFromPVR(c_szFire03TexFile, &m_ui32Texture[3]) != PVR_SUCCESS)
		return false;

	myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
	myglTexParameter(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	/******************************
	** GENERIC RENDER STATES     **
	*******************************/

	// The Type Of Depth Test To Do
	glDepthFunc(GL_LEQUAL);

	// Enables Depth Testing
	glEnable(GL_DEPTH_TEST);

	// Enables Smooth Color Shading
	glShadeModel(GL_SMOOTH);

	// Blending mode
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	// Culling
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);

	// Create perspective matrix
	mPerspective = PVRTMat4::PerspectiveFovRH(f2vt(70.0f*(3.14f/180.0f)), f2vt((float)PVRShellGet(prefWidth) /(float)PVRShellGet(prefHeight) ), f2vt(10.0f), f2vt(10000.0f), PVRTMat4::OGL, bRotate);

	glMatrixMode(GL_PROJECTION);
	myglLoadMatrix(mPerspective.f);

	// Create viewing matrix
	m_mView = PVRTMat4::LookAtRH(m_CameraPos, m_CameraTo, m_CameraUp);

	glMatrixMode(GL_MODELVIEW);
	myglLoadMatrix(m_mView.f);

	// Enable texturing
	glEnable(GL_TEXTURE_2D);

	// Lights (only one side lighting)
	glEnable(GL_LIGHTING);

	// Light 0 (White directional light)
	PVRTVec4 fAmbient  = PVRTVec4(f2vt(0.2f), f2vt(0.2f), f2vt(0.2f), f2vt(1.0f));
	PVRTVec4 fDiffuse  = PVRTVec4(f2vt(1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(1.0f));
	PVRTVec4 fSpecular = PVRTVec4(f2vt(1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(1.0f));

	myglLightv(GL_LIGHT0, GL_AMBIENT,  fAmbient.ptr());
	myglLightv(GL_LIGHT0, GL_DIFFUSE,  fDiffuse.ptr());
	myglLightv(GL_LIGHT0, GL_SPECULAR, fSpecular.ptr());
	myglLightv(GL_LIGHT0, GL_POSITION, m_LightPos.ptr());

	glEnable(GL_LIGHT0);

	glDisable(GL_LIGHTING);

	// Create the data used for the morphing
	CreateMorphData();

	// Sets the clear color
	myglClearColor(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f), f2vt(1.0f));

	// Create vertex buffer objects
	LoadVbos();

	return true;
}
示例#3
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;
}
示例#4
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 OGLESFur::InitView()
{
	// Setup the projection matrix
	glMatrixMode(GL_PROJECTION);

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

	m_mProj = PVRTMat4::PerspectiveFovRH(g_fFOV, f2vt((float)PVRShellGet(prefWidth) / (float)PVRShellGet(prefHeight)), g_fNear, g_fFar, PVRTMat4::OGL, bRotate);
	myglLoadMatrix(m_mProj.f);

	// Set clear colour
	myglClearColor(c_vFogColour.x, c_vFogColour.y, c_vFogColour.z, c_vFogColour.w);

	// Enable Smooth Color Shading
	glShadeModel(GL_SMOOTH);

	// Enable the depth buffer
	glEnable(GL_DEPTH_TEST);

	// Load fur data
	glGenBuffers(g_ui32MaxNoOfFurShells, m_uiShellVbo);
	UpdateFurShells();

	// Initialise 3D text
	if(m_Print3D.SetTextures(NULL, PVRShellGet(prefWidth), PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
		return false;

	// Load textures
	CPVRTString ErrorStr;

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

	// Create VBOs
	if(!LoadVbos(&ErrorStr))
	{
		PVRShellSet(prefExitMessage, ErrorStr.c_str());
		return false;
	}

	// Initialise camera
	m_Scene.GetCameraPos(m_vCamFrom, m_vCamTo, 0);
	
	m_vCamFrom = PVRTVec3(f2vt(0.0f), f2vt(400.0f), f2vt(0.0f));

	// Enable fog
	myglFog(GL_FOG_MODE, GL_EXP2);
	myglFog(GL_FOG_DENSITY, c_fFogDensity);
	myglFogv(GL_FOG_COLOR, &c_vFogColour.x);
	glEnable(GL_FOG);

	// Enable lighting
	myglLightv(GL_LIGHT0, GL_POSITION, &c_vLightPosition.x);
	myglLightv(GL_LIGHT0, GL_DIFFUSE, &c_vLightColour.x);
	myglLightv(GL_LIGHT0, GL_AMBIENT, &c_vLightAmbient.x);
	myglLightv(GL_LIGHT0, GL_SPECULAR, &c_vLightColour.x);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);

	// Disable culling
	glDisable(GL_CULL_FACE);

	// Initialise time
	m_ui32PrevTime = PVRShellGetTime();
	return true;
}
示例#5
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 OGLESAntialiasedLines::InitView()
{
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	m_iWidth  = PVRShellGet(prefWidth);
	m_iHeight = PVRShellGet(prefHeight);

	myglClearColor(f2vt(0.6f), f2vt(0.8f), f2vt(1.0f), f2vt(1.0f));

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

	// Initialise the texture
	if (PVRTTextureLoadFromPVR("LineRound.pvr", &m_uiTexture) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Failed to load texture.\n");
		return false;
	}
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	// Initialise geometry
	SVertex *paVertices = new SVertex[c_iNumLines * 2];       // 2 vertices per GL_LINE
	STexVertex *paTexVertices = new STexVertex[c_iNumLines * 8]; // 8 vertices per AA line (includes caps)
	GLushort *paui16Indices = new GLushort[c_iNumLines * 18];  // 18 indices per AA line (6 triangles) 

	if(!paVertices || !paTexVertices || !paui16Indices)
	{
		delete[] paVertices;
		delete[] paTexVertices;
		delete[] paui16Indices;
		PVRShellSet(prefExitMessage, "ERROR: Failed to allocate line vertices and indices.\n");
		return false;
	}

	srand(0);
	float fAngleStep = PVRT_TWO_PI / c_iNumLines;
	VERTTYPE fSize = f2vt(PVRT_MIN(m_iWidth, m_iHeight) * 0.4f);
	for (int i = 0; i < c_iNumLines; ++i)
	{
		// Place the line vertices on a circle 
		paVertices[i*2].vPosition.x = VERTTYPEMUL(fSize, PVRTSIN(fAngleStep * (i + c_fLineArc)));
		paVertices[i*2].vPosition.y = VERTTYPEMUL(fSize, PVRTCOS(fAngleStep * (i + c_fLineArc)));
		paVertices[i*2+1].vPosition.x = VERTTYPEMUL(fSize, PVRTSIN(fAngleStep * i));
		paVertices[i*2+1].vPosition.y = VERTTYPEMUL(fSize, PVRTCOS(fAngleStep * i));

		// Pick a random RGB color
		paVertices[i*2].uiColor = (0xFF << 24) + 
			((rand() & 0xFF) << 16) + ((rand() & 0xFF) << 8) + (rand() & 0xFF);
		paVertices[i*2+1].uiColor = paVertices[i*2].uiColor;

		// Tessellate the antialiased line
		TessellateLine(paVertices[i*2].vPosition, paVertices[i*2+1].vPosition, 
			c_fLineWidth, paVertices[i*2].uiColor, 
			&paTexVertices[i * 8], i * 8, &paui16Indices[i * 18]);
	}

	// We use 3 VBOs for clarity:
	// 0: AA line vertex data
	// 1: AA line index data
	// 2: GL_LINES vertex data
	glGenBuffers(3, m_uiVbos);

	// Bind the VBOs and fill them with data
	glBindBuffer(GL_ARRAY_BUFFER, m_uiVbos[0]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(*paTexVertices) * c_iNumLines * 8, paTexVertices, GL_STATIC_DRAW);

	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiVbos[1]);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(*paui16Indices) * c_iNumLines * 18, paui16Indices, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, m_uiVbos[2]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(*paVertices) * c_iNumLines * 2, paVertices, GL_STATIC_DRAW);

	// Unbind buffers
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	// Set projection to use pixel coordinates
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	myglOrtho(0, f2vt((float)PVRShellGet(prefWidth)), f2vt((float)PVRShellGet(prefHeight)), 0, 0, 1);

	delete[] paVertices;
	delete[] paTexVertices;
	delete[] paui16Indices;

	return true;
}
示例#6
0
/*******************************************************************************
 * Function Name  : InitView
 * Inputs		  :
 * 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 OGLESOptimizeMesh::InitView()
{
	SPVRTContext sContext;

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

	// Init Print3D to display text on screen
	if(m_Print3D.SetTextures(&sContext, PVRShellGet(prefWidth), PVRShellGet(prefHeight), bRotate) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot initialise Print3D.\n");
		return false;
	}

	/******************************
	** Create Textures           **
	*******************************/
	if(PVRTTextureLoadFromPVR(c_szModelTexFile, &m_Texture) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Failed to load texture for model.\n");
		return false;
	}

	/*********************************
	** View and Projection Matrices **
	*********************************/

	// Get Camera info from POD file
	PVRTVec3 From, To;
	VERTTYPE fFOV;

	if(m_Model.nNumCamera)
	{
		// Get Camera data from POD Geometry File
		fFOV = m_Model.GetCameraPos(From, To, 0);
		fFOV = VERTTYPEMUL(fFOV, f2vt(0.75f));		// Convert from horizontal FOV to vertical FOV (0.75 assumes a 4:3 aspect ratio)
	}
	else
	{
		fFOV = f2vt(PVRT_PIf / 6);
	}

	// View
	m_mView = PVRTMat4::LookAtRH(From, To, PVRTVec3(f2vt(0.0f), f2vt(1.0f), f2vt(0.0f)));

	// Projection
	m_mProj = PVRTMat4::PerspectiveFovRH(fFOV, f2vt((float) PVRShellGet(prefWidth) / (float) PVRShellGet(prefHeight)), g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, bRotate);

	glMatrixMode(GL_PROJECTION);
	myglLoadMatrix(m_mProj.f);

	/******************************
	** GENERIC RENDER STATES     **
	******************************/

	// The Type Of Depth Test To Do
	glDepthFunc(GL_LEQUAL);

	// Enables Depth Testing
	glEnable(GL_DEPTH_TEST);

	// Enables Smooth Color Shading
	glShadeModel(GL_SMOOTH);

	// Define front faces
	glFrontFace(GL_CW);

	// Sets the clear colour
	myglClearColor(f2vt(0.6f), f2vt(0.8f), f2vt(1.0f), f2vt(1.0f));

	// Reset the model view matrix to position the light
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	// Setup timing variables
	m_ui32LastTime = PVRShellGetTime();
	m_ui32FPSFrameCnt = 0;
	m_fFPS = 0;
	m_fViewAngle = 0;
	m_ui32SwitchTimeDiff = 0;

#ifndef ENABLE_LOAD_TIME_STRIP
	LoadVbos();
#endif

	return true;
}