Example #1
0
/*!****************************************************************************
 @Function		DrawBalloons
 @Input			psProgram			Program to use
				mProjection			Projection matrix to use
				mView				View matrix to use
				pmModels			A pointer to an array of model matrices
				iNum				Number of balloons to draw
 @Description	Draws balloons.
******************************************************************************/
void OGLES2Glass::DrawBalloons(Program* psProgram, PVRTMat4 mProjection, PVRTMat4 mView, PVRTMat4* pmModels, int iNum) {
	// Use shader program
	glUseProgram(psProgram->uiId);

	// Bind texture
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiBalloonTex);

	PVRTMat4 mModelView, mMVP;

	for (int i = 0; i < iNum; ++i)
	{
		mModelView = mView * pmModels[i];
		mMVP =  mProjection * mModelView;
	
		glUniformMatrix4fv(psProgram->auiLoc[eMVMatrix], 1, GL_FALSE, mModelView.ptr());
		glUniformMatrix4fv(psProgram->auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr());

		// Calculate and set the model space light direction
		PVRTVec3 vLightDir = pmModels[i].inverse() * PVRTVec4(19, 22, -50, 0);
		vLightDir = vLightDir.normalize();
		glUniform3fv(psProgram->auiLoc[eLightDir], 1, vLightDir.ptr());

		// Calculate and set the model space eye position
		PVRTVec3 vEyePos = mModelView.inverse() * PVRTVec4(0.0f, 0.0f, 0.0f, 1.0f);
		glUniform3fv(psProgram->auiLoc[eEyePos], 1, vEyePos.ptr());

		// Now that the uniforms are set, call another function to actually draw the mesh.
		DrawMesh(0, &m_Balloon, &m_puiBalloonVbo, &m_puiBalloonIndexVbo, 3);
	}
}
Example #2
0
/*******************************************************************************
 * Function Name  : DrawModel
 * Inputs		  : iOptim
 * Description    : Draws the balloon
 *******************************************************************************/
void OGLESOptimizeMesh::DrawModel( int iOptim )
{
	SPODMesh *pMesh;

	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	PVRTMATRIX worldMatrix;
	m_Model.GetWorldMatrix(worldMatrix, m_Model.pNode[0]);
	glMultMatrixf(worldMatrix.f);

	// Enable States
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);

	// Set Data Pointers and bing the VBOs
	switch(iOptim)
	{
	default:
		pMesh = m_Model.pMesh;

		glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[0]);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[0]);
		break;
	case 1:
		pMesh = m_ModelOpt.pMesh;

		glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[1]);
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[1]);
		break;
	}

	// Load the meshes material properties
	SPODMaterial& Material = m_Model.pMaterial[m_Model.pNode[0].nIdxMaterial];

	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,  PVRTVec4(Material.pfMatAmbient,  1.0f).ptr());
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,  PVRTVec4(Material.pfMatDiffuse,  1.0f).ptr());

	// Used to display interleaved geometry
	glVertexPointer(3, GL_FLOAT, pMesh->sVertex.nStride, pMesh->sVertex.pData);
	glNormalPointer(GL_FLOAT, pMesh->sNormals.nStride, pMesh->sNormals.pData);

	// Draw
	glDrawElements(GL_TRIANGLES, pMesh->nNumFaces * 3, GL_UNSIGNED_SHORT, 0);

	// Disable States
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);

	// unbind the vertex buffers as we don't need them bound anymore
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	glPopMatrix();
}
Example #3
0
// ---------------------------------------------------------------
bool MyPVRDemo::InitApplication()
	{
#ifdef PLATFORM_IOS
	CPVRTResourceFile::SetReadPath((char*)PVRShellGet(prefReadPath));
#endif
	
	if (m_Model.ReadFromFile(c_szSceneFile) != PVR_SUCCESS)
		{
		PVRShellSet(prefExitMessage, "ERROR: Couldn't load the .pod file\n");
		return false;
		}

	assert(enumMODEL_MAX == m_Model.nNumMesh);

	// Calculate a bounding box around the statue that we can use later on
	SPODMesh* pMesh = &m_Model.pMesh[m_Model.pNode[enumMODEL_Statue].nIdx];
	PVRTBOUNDINGBOX bb;
	PVRTBoundingBoxComputeInterleaved(&bb, pMesh->pInterleaved, pMesh->nNumVertex, 0, pMesh->sVertex.nStride);

	// We need to calculate the longest possible length for our bounding box on the X and Z axis (as we're rotating around Y).
	float fLen[4];
	fLen[0] = sqrt(bb.Point[7].x * bb.Point[7].x + bb.Point[7].z * bb.Point[7].z);	// FR quadrant
	fLen[1] = sqrt(bb.Point[3].x * bb.Point[3].x + bb.Point[3].z * bb.Point[3].z);	// FL quadrant
	fLen[2] = sqrt(bb.Point[6].x * bb.Point[6].x + bb.Point[6].z * bb.Point[6].z);	// BR quadrant
	fLen[3] = sqrt(bb.Point[2].x * bb.Point[2].x + bb.Point[2].z * bb.Point[2].z);	// BL quadrant
	
	float fLongest = max(fLen[0], fLen[1]);
	fLongest = max(fLongest, fLen[2]);
	fLongest = max(fLongest, fLen[3]);
		
	// Calculate the top left and bottom right of the bounding box in 2D space
	m_bbStatueTL = PVRTVec4(-fLongest, bb.Point[3].y, bb.Point[3].z, 1.0f);
	m_bbStatueBR = PVRTVec4( fLongest, bb.Point[5].y, bb.Point[5].z, 1.0f);

	// Some nice variables
	m_fAngleY = 0.0f;
	m_fBloomMulti = 0.3f;
	m_ulCurrTime = 0;
	m_fLightAngle = PVRT_PI / 8;	// Offset by 22.5degrees to begin with, so we see the shadow slightly offset from behind the model.

	m_fTexelOffset = 1.0f / RTT_SIZE;
	float w1 = 0.0555555f;
	float w2 = 0.2777777f;
	float intraTexelOffset = (w2 / (w1 + w2)) * m_fTexelOffset;		// Weight between 2 texels so that hardware filtering will
																	// interpolate the texels for us. Effectively reducing a 5x5 kernel
																	// to a 3x3.
	m_fTexelOffset += intraTexelOffset;

	return true;
	}
Example #4
0
/*!****************************************************************************
 @Function		DrawBall
 @Description	Draws the reflective and refractive ball onto the screen.
******************************************************************************/
void OGLES2Glass::DrawBall() {
	// Set model view projection matrix
	PVRTMat4 mModel, mModelView, mMVP;

	mModel = PVRTMat4::Scale(6.0f, 6.0f, 6.0f);
	mModelView = m_mView * mModel;
	mMVP = m_mProjection * mModelView;

	// Use shader program
	glUseProgram(m_aEffectPrograms[m_iEffect].uiId);

	// Bind textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiParaboloidTexture);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_CUBE_MAP, m_uiCubeTex);

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

	// Set model matrix
	PVRTMat3 Model3x3 = PVRTMat3(mModel);
	glUniformMatrix3fv(m_aEffectPrograms[m_iEffect].auiLoc[eMMatrix], 1, GL_FALSE, Model3x3.ptr());

	// Set eye position in model space
	PVRTVec4 vEyePosModel;
	vEyePosModel = mModelView.inverse() * PVRTVec4(0, 0, 0, 1);
	glUniform3fv(m_aEffectPrograms[m_iEffect].auiLoc[eEyePos], 1, &vEyePosModel.x);

	// Now that the uniforms are set, call another function to actually draw the mesh
	DrawMesh(0, &m_Ball, &m_puiVbo, &m_puiIndexVbo, 2);
}
Example #5
0
/*!****************************************************************************
 @Function		RenderFloor
 @Description	Renders the floor as a quad.
******************************************************************************/
void OGLES2ParticleSystem::RenderFloor()
{
	glUseProgram(m_SimpleShaderProgram.uiId);

	PVRTMat3 mViewIT(m_mView.inverse().transpose());
	glUniformMatrix4fv(m_SimpleShaderProgram.iModelViewProjectionMatrixLoc, 1, GL_FALSE, m_mViewProjection.f);
	glUniformMatrix4fv(m_SimpleShaderProgram.iModelViewMatrixLoc, 1, GL_FALSE, m_mView.f);
	glUniformMatrix3fv(m_SimpleShaderProgram.iModelViewITMatrixLoc, 1, GL_FALSE, mViewIT.f);

	PVRTVec3 vLightPosition = m_mView * PVRTVec4(g_caLightPosition, 1.0f);
	glUniform3fv(m_SimpleShaderProgram.iLightPosition, 1, &vLightPosition.x);

	// Enable vertex arributes
	glEnableVertexAttribArray(VERTEX_ARRAY);
	glEnableVertexAttribArray(NORMAL_ARRAY);

	PVRTVec2 minCorner(-100.0f, -100.0f);
	PVRTVec2 maxCorner( 100.0f,  100.0f);

	const float afVertexData[] = { minCorner.x, 0.0f, minCorner.y,  maxCorner.x, 0.0f, minCorner.y,  
		                           minCorner.x, 0.0f, maxCorner.y,  maxCorner.x, 0.0f, maxCorner.y };
	const float afNormalData[] = { 0.0f, 1.0f, 0.0f,  0.0f, 1.0f, 0.0f,  0.0f, 1.0f, 0.0f,  0.0f, 1.0f, 0.0f };

	glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, afVertexData);
	glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, afNormalData);

	// Draw the quad
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

		// Safely disable the vertex attribute arrays
	glDisableVertexAttribArray(VERTEX_ARRAY);
	glDisableVertexAttribArray(NORMAL_ARRAY);	
}
Example #6
0
/*!****************************************************************************
 @Function		DrawSkybox
 @Description	Draws the skybox onto the screen.
******************************************************************************/
void OGLES2Glass::DrawSkybox()
{
	glUseProgram(m_SkyboxProgram.uiId);

	PVRTMat4 mVP = m_mProjection * m_mView;
	PVRTMat4 mInvVP = mVP.inverseEx();

	glUniformMatrix4fv(m_SkyboxProgram.auiLoc[eInvVPMatrix], 1, GL_FALSE, mInvVP.ptr());

	PVRTVec3 vEyePos = m_mView.inverse() * PVRTVec4(0, 0, 0, 1);

	glUniform3fv(m_SkyboxProgram.auiLoc[eEyePos], 1, vEyePos.ptr());

	glBindBuffer(GL_ARRAY_BUFFER, m_uiSquareVbo);

	glEnableVertexAttribArray(VERTEX_ARRAY);
	glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 3, 0);

	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_CUBE_MAP, m_uiCubeTex);

	glDrawArrays(GL_TRIANGLES, 0, 6);

	glDisableVertexAttribArray(VERTEX_ARRAY);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
}
	bool UniformHandler::isVisibleSphere(const PVRTVec3& v3Centre, const VERTTYPE fRadius)
	{
		// get in view space
		PVRTVec4 v4TransCentre = m_mWorldView * PVRTVec4(v3Centre,f2vt(1.0f));

		// find clip space coord for centre
		v4TransCentre = m_mProjection * v4TransCentre;

		VERTTYPE fRadX,fRadY;
		// scale radius according to perspective
		if(m_bRotate)
		{
		fRadX = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(0,1)));
		fRadY = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(1,0)));
		}
		else
		{
		fRadX = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(0,0)));
		fRadY = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(1,1)));
		}
		VERTTYPE fRadZ = PVRTABS(VERTTYPEMUL(fRadius,m_mProjection(2,2)));


		// check if inside frustums
		// X
		if(v4TransCentre.x+fRadX<-v4TransCentre.w)
		{	// 'right' side out to 'left' def out
			return false;
		}
		if(v4TransCentre.x-fRadX>v4TransCentre.w)
		{	// 'left' side out to 'right' def out
			return false;
		}

		// Y
		if(v4TransCentre.y+fRadY<-v4TransCentre.w)
		{	// 'up' side out to 'top' def out
			return false;
		}
		if(v4TransCentre.y-fRadY>v4TransCentre.w)
		{	// 'down' side out to 'bottom' def out
			return false;
		}

		// Z
		if(v4TransCentre.z+fRadZ<-v4TransCentre.w)
		{	// 'far' side out to 'back' def out
			return false;
		}
		if(v4TransCentre.z-fRadZ>v4TransCentre.w)
		{	// 'near' side out to 'front' def out
			return false;
		}

		return true;
	}
Example #8
0
	OGLESEvilSkull() : m_puiVbo(0),
					   m_puiIndexVbo(0),
					   m_pMorphedVertices(0),
					   m_pAVGVertices(0),
					   m_i32BaseAnim(0),
					   m_i32TargetAnim(1),
					   m_i32Frame(0)
	{

		for(unsigned int i = 0; i < g_ui32NoOfMorphTargets; ++i)
			m_pDiffVertices[i] = 0;

		// Setup base constants in contructor

		// Camera and Light details
		m_LightPos  = PVRTVec4(f2vt(-1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(0.0f));

		m_CameraPos = PVRTVec3(f2vt(0.0f), f2vt(0.0f), f2vt(300.0f));
		m_CameraTo  = PVRTVec3(f2vt(0.0f), f2vt(-30.0f), f2vt(0.0f));
		m_CameraUp  = PVRTVec3(f2vt(0.0f), f2vt(1.0f), f2vt(0.0f));

		// Animation Table
		m_fSkullWeights[0] = 0.0f;
		m_fSkullWeights[1] = 1.0f;
		m_fSkullWeights[2] = 0.0f;
		m_fSkullWeights[3] = 0.0f;
		m_fSkullWeights[4] = 0.0f;

		m_fExprTable[0][0] = 1.0f;	m_fExprTable[1][0] = 1.0f;	m_fExprTable[2][0] = 1.0f;	m_fExprTable[3][0] = 1.0f;
		m_fExprTable[0][1] = 0.0f;	m_fExprTable[1][1] = 0.0f;	m_fExprTable[2][1] = 0.0f;	m_fExprTable[3][1] = 1.0f;
		m_fExprTable[0][2] = 0.0f;	m_fExprTable[1][2] = 0.0f;	m_fExprTable[2][2] = 1.0f;	m_fExprTable[3][2] = 1.0f;
		m_fExprTable[0][3] = 0.3f;	m_fExprTable[1][3] = 0.0f;	m_fExprTable[2][3] = 0.3f;	m_fExprTable[3][3] = 0.0f;
		m_fExprTable[0][4] =-1.0f;	m_fExprTable[1][4] = 0.0f;	m_fExprTable[2][4] = 0.0f;	m_fExprTable[3][4] = 0.0f;
		m_fExprTable[0][5] = 0.0f;	m_fExprTable[1][5] = 0.0f;	m_fExprTable[2][5] =-0.7f;	m_fExprTable[3][5] = 0.0f;
		m_fExprTable[0][6] = 0.0f;	m_fExprTable[1][6] = 0.0f;	m_fExprTable[2][6 ]= 0.0f;	m_fExprTable[3][6] =-0.7f;

		m_fJawRotation[0] = 45.0f;
		m_fJawRotation[1] = 25.0f;
		m_fJawRotation[2] = 40.0f;
		m_fJawRotation[3] = 20.0f;
		m_fJawRotation[4] = 45.0f;
		m_fJawRotation[5] = 25.0f;
		m_fJawRotation[6] = 30.0f;

		m_fBackRotation[0] = 0.0f;
		m_fBackRotation[1] = 25.0f;
		m_fBackRotation[2] = 40.0f;
		m_fBackRotation[3] = 90.0f;
		m_fBackRotation[4] = 125.0f;
		m_fBackRotation[5] = 80.0f;
		m_fBackRotation[6] = 30.0f;
	}
/*!****************************************************************************
 @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 OGLES3CellShading::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

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

	// Calculate the model matrix
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += PVRT_PI / 210;

	// Set model view projection matrix
	PVRTMat4 mMVP = m_mViewProj * mModel;
	glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

	// Set eye position in model space
	PVRTVec4 vMsEyePos = PVRTVec4(0, 0, 125, 1) * mModel;
	glUniform3fv(m_ShaderProgram.uiEyePosLoc, 1, vMsEyePos.ptr());

	// transform directional light from world space to model space
	PVRTVec3 vMsLightDir = PVRTVec3(PVRTVec4(1, 2, 1, 0) * mModel).normalized();
	glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, vMsLightDir.ptr());

	DrawMesh(0);

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

	return true;
}
Example #10
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 #11
0
void ShaderEnvMap::UseProgram()
{
	Shader::UseProgram();
	
	glUniform1i(myCubeReflection, false);
	
	glUniform1i(my2DMap, 0);
	glUniform1i(myCubeMap, 1);

	CameraManager * pCameraManager = CameraManager::GetCameraManager();
	Camera * pCurrentCamera = pCameraManager->GetCurrentCamera();
	RenderLayerManager & renderManager = RenderLayerManager::GetRenderLayerManager();
	Mesh * pCurrentMesh = renderManager.GetCurrentMesh();

	PVRTMat4 viewMtx(pCurrentCamera->GetViewMtx().f);
	
	static float m_fAngleX = 0.0;
	static float m_fAngleY = 0.0;

	PVRTMat4 mModel, mRotX, mRotY;
	mRotX = PVRTMat4::RotationX(m_fAngleX);
	mRotY = PVRTMat4::RotationY(m_fAngleY);
	
	mModel = mRotY * mRotX;

	m_fAngleX += 0.01f;
	//m_fAngleY += 0.011f;

	//PVRTMat4 meshWorld( pCurrentMesh->GetWorldMtx().f );
	PVRTMat4 meshWorld = mModel;
	PVRTMat4 modelView = viewMtx * meshWorld;
	
	// Set model matrix
	PVRTMat3 model3x3 = PVRTMat3(meshWorld);
	glUniformMatrix3fv( myModelWorld, 1, GL_FALSE, model3x3.ptr());

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

	glUniform3fv(myEyePosModel, 1, &eyePosModel.x);


}
Example #12
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 OGLES3PerturbedUvs::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

	// Bind textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiReflectTex);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, m_uiNormalTex);

	// Rotate and translate the model matrix
	PVRTMat4 mModel;
	mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += PVRT_PI / 210;

	// 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 eye position in model space
	PVRTVec4 vEyePosModel;
	vEyePosModel = mModelView.inverse() * PVRTVec4(0, 0, 0, 1);

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

	/*
		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("PerturbedUvs", "", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();

	return true;
}
Example #13
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 OGLES3Bumpmap::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

	// Bind textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiBaseTex);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, m_uiNormalMap);

	// Calculate the model matrix
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += PVRT_PI / 150;

	// Set model view projection matrix
	PVRTMat4 mMVP = m_mViewProj * mModel;
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr());

	// Set light position in model space
	/*
		The inverse of a rotation matrix is the transposed matrix
		Because of v * M = transpose(M) * v, this means:
		v * R == inverse(R) * v
		So we don't have to actually invert or transpose the matrix
		to transform back from world space to model space
	*/
	PVRTVec4 vMsLightPos = PVRTVec4(50, 20, 40, 1) * mModel;
	glUniform3fv(m_ShaderProgram.auiLoc[eLightPos], 1, &vMsLightPos.x);

	DrawMesh(0);

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

	return true;
}
/*!****************************************************************************
 @Function		DrawMesh
 @Input			meshID		The number of the mesh to draw
 @Description	Draws a SPODMesh after the model view matrix has been set.
				Also works out and passes color and ID data to the shader in
				this case.
******************************************************************************/
void OGLES3EdgeDetection::DrawMesh(unsigned int ui32MeshID)
{
	// Calls the mesh and its material index.
	SPODMesh& Mesh = m_Scene.pMesh[ui32MeshID];
	GLuint ui32MaterialIndex = m_Scene.pNode[ui32MeshID].nIdxMaterial;

	// Works out an ID Number for the mesh - somewhere between 0 and 1.
	GLfloat ID = (GLfloat)ui32MeshID/(GLfloat)m_Scene.nNumMeshNode;

	// Binds color and ID data to the shader program.
	glUniform4fv(m_PreShader.auiLoc[eColorData], 1, PVRTVec4(m_pvColorData[ui32MaterialIndex],ID).ptr());

	// Bind the VBO for the mesh and the index buffer.
	glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[ui32MeshID]);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[ui32MeshID]);

	// Set the vertex attribute offsets from the mesh
	glVertexAttribPointer(eVERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, Mesh.sVertex.nStride, Mesh.sVertex.pData);

	// Indexed Triangle list
	glDrawElements(GL_TRIANGLES, Mesh.nNumFaces*3, GL_UNSIGNED_SHORT, 0);
}
Example #15
0
/*!****************************************************************************
 @Function		RenderSphere
 @Description	Renders a sphere at the specified position.
******************************************************************************/
void OGLES2ParticleSystem::RenderSphere(PVRTVec3 position, float radius)
{
	glUseProgram(m_SimpleShaderProgram.uiId);

	PVRTMat4 mModel = PVRTMat4::Translation(position) * PVRTMat4::Scale(radius, radius, radius);
	PVRTMat4 mModelView = m_mView * mModel;
	PVRTMat4 mModelViewProj = m_mProjection * mModelView;
	PVRTMat3 mModelViewIT(mModelView.inverse().transpose());
	glUniformMatrix4fv(m_SimpleShaderProgram.iModelViewProjectionMatrixLoc, 1, GL_FALSE, mModelViewProj.f);
	glUniformMatrix4fv(m_SimpleShaderProgram.iModelViewMatrixLoc, 1, GL_FALSE, mModelView.f);
	glUniformMatrix3fv(m_SimpleShaderProgram.iModelViewITMatrixLoc, 1, GL_FALSE, mModelViewIT.f);

	PVRTVec3 vLightPosition = m_mView * PVRTVec4(g_caLightPosition, 1.0f);
	glUniform3fv(m_SimpleShaderProgram.iLightPosition, 1, &vLightPosition.x);

	// Enable vertex arributes
	glEnableVertexAttribArray(VERTEX_ARRAY);
	glEnableVertexAttribArray(NORMAL_ARRAY);

	glBindBuffer(GL_ARRAY_BUFFER, m_uiVbo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiIbo);

	SPODMesh* pMesh = &m_Scene.pMesh[0];
	glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
	glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);

	// Indexed Triangle list
	glDrawElements(GL_TRIANGLES, pMesh->nNumFaces*3, GL_UNSIGNED_SHORT, 0);

	// Safely disable the vertex attribute arrays
	glDisableVertexAttribArray(VERTEX_ARRAY);
	glDisableVertexAttribArray(NORMAL_ARRAY);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 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 OGLES2AnisotropicLighting::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Keyboard input (cursor to change render mode)
	if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_eRenderMode = ERenderMode((m_eRenderMode + eNumRenderModes - 1) % eNumRenderModes);
	}
	if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_eRenderMode = ERenderMode((m_eRenderMode + 1) % eNumRenderModes);
	}

	// Rotate the model matrix
	PVRTMat4 mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += 0.02f;

	// Calculate model view projection matrix
	PVRTMat4 mMVP = m_mViewProj * mModel;

	if (m_eRenderMode == eTexLookup)
	{
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, m_uiTexture);

		glUseProgram(m_FastShader.uiId);

		glUniformMatrix4fv(m_FastShader.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

		/*
			The inverse of a rotation matrix is the transposed matrix
			Because of v * M = transpose(M) * v, this means:
			v * R == inverse(R) * v
			So we don't have to actually invert or transpose the matrix
			to transform back from world space to model space
		*/
		PVRTVec3 vMsEyePos = PVRTVec3(PVRTVec4(0, 0, 150, 1) * mModel);
		glUniform3fv(m_FastShader.uiMsEyePosLoc, 1, vMsEyePos.ptr());

		PVRTVec3 vMsLightDir = PVRTVec3(PVRTVec4(1, 1, 1, 1) * mModel).normalized();
		glUniform3fv(m_FastShader.uiMsLightDirLoc, 1, vMsLightDir.ptr());
	}
	else
	{
		glUseProgram(m_SlowShader.uiId);

		glUniformMatrix4fv(m_SlowShader.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

		PVRTVec3 vMsEyeDir = PVRTVec3(PVRTVec4(0, 0, 150, 1) * mModel).normalized();
		glUniform3fv(m_SlowShader.uiMsEyeDirLoc, 1, vMsEyeDir.ptr());

		PVRTVec3 vMsLightDir = PVRTVec3(PVRTVec4(1, 1, 1, 1) * mModel).normalized();
		glUniform3fv(m_SlowShader.uiMsLightDirLoc, 1, vMsLightDir.ptr());
	}

	/*
		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("AnisotropicLighting", "", ePVRTPrint3DLogoIMG);
	m_Print3D.Print3D(0.3f, 7.5f, 0.75f, PVRTRGBA(255,255,255,255), c_aszRenderModes[m_eRenderMode]);
	m_Print3D.Flush();

	return true;
}
Example #17
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 OGLES2MaximumIntensityBlend::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	// Enable blending
	glEnable(GL_BLEND);
	glBlendEquation(GL_MAX_EXT);
	
	/*
	 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();
	unsigned long ulDeltaTime = ulTime - m_ulTimePrev;
	m_ulTimePrev	= ulTime;
	m_fFrame	+= (float)ulDeltaTime * 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 vLightDir;
	
	{
		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.6;
		
		/*
		 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);
		
		vLightDir = vFrom;
		
		// 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;
		
		// Retrieve the list of required uniforms
		CPVRTPFXEffect* pEffect;
		
		SPODMaterial* pMat = &m_Scene.pMaterial[pNode->nIdxMaterial];
		if(pMat->nIdxTexDiffuse != -1)
		{
			pEffect = m_pEffectTextured;
		}
		else
		{
			pEffect = m_pEffect;
		}
		
		pEffect->Activate();
		const CPVRTArray<SPVRTPFXUniform>& aUniforms = pEffect->GetUniformArray();
		
		/*
		 Now we loop over the uniforms requested by the PFX file.
		 Using the switch statement allows us to handle all of the required semantics
		 */
		for(unsigned int j = 0; j < aUniforms.GetSize(); ++j)
		{
			switch(aUniforms[j].nSemantic)
			{
				case ePVRTPFX_UsPOSITION:
				{
					glVertexAttribPointer(aUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
					glEnableVertexAttribArray(aUniforms[j].nLocation);
				}
					break;
				case ePVRTPFX_UsNORMAL:
				{
					glVertexAttribPointer(aUniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
					glEnableVertexAttribArray(aUniforms[j].nLocation);
				}
					break;
				case ePVRTPFX_UsUV:
				{
					glVertexAttribPointer(aUniforms[j].nLocation, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);
					glEnableVertexAttribArray(aUniforms[j].nLocation);
				}
					break;
				case ePVRTPFX_UsWORLDVIEWPROJECTION:
				{
					PVRTMat4 mWVP;
					
					// Passes the world-view-projection matrix (WVP) to the shader to transform the vertices
					mWVP = m_mProjection * mWorldView;
					glUniformMatrix4fv(aUniforms[j].nLocation, 1, GL_FALSE, mWVP.f);
				}
					break;
				case eUsINTENSITY:
				{
					int iMat           = pNode->nIdxMaterial;
					SPODMaterial* pMat = &m_Scene.pMaterial[iMat];
					float fIntensity   = pMat->pfMatDiffuse[0];			// Take R value for intensity
					
					glUniform1f(aUniforms[j].nLocation, fIntensity);
				}
					break;
				case ePVRTPFX_UsTEXTURE:
				{
					glUniform1i(aUniforms[j].nLocation, 0);
				}
					break;
				case ePVRTPFX_UsWORLDVIEWIT:
				{
					PVRTMat3 mWorldViewIT3x3(mWorldView.inverse().transpose());
					glUniformMatrix3fv(aUniforms[j].nLocation, 1, GL_FALSE, mWorldViewIT3x3.f);
				}
					break;
				case ePVRTPFX_UsLIGHTDIREYE:
				{
					PVRTVec4 vLightDirView = (m_mView * PVRTVec4(-vLightDir, 1.0f)).normalize();
					glUniform3fv(aUniforms[j].nLocation, 1, vLightDirView.ptr());
				}
					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);
		
		/*
		 Now disable all of the enabled attribute arrays that the PFX requested.
		 */
		for(unsigned int j = 0; j < aUniforms.GetSize(); ++j)
		{
			switch(aUniforms[j].nSemantic)
			{
				case ePVRTPFX_UsNORMAL:
				case ePVRTPFX_UsUV:
				case ePVRTPFX_UsPOSITION:
				{
					glDisableVertexAttribArray(aUniforms[j].nLocation);
				}
					break;
			}
		}
	}
	
	// Reset blending
	// Enable blending
	glBlendEquation(GL_FUNC_ADD);
	glDisable(GL_BLEND);
	
	// Determine which title to show. The default title is quite long, so we display a shortened version if
	// it cannot fit on the screen.
	const char* pszTitle = NULL;
	{
		bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
		
		float fW, fH;
		m_Print3D.MeasureText(&fW, &fH, 1.0f, c_pszTitle);
		
		int iScreenW = bRotate ? PVRShellGet(prefHeight) : PVRShellGet(prefWidth);
		if((int)fW >= iScreenW)
		{
			pszTitle = c_pszTitleShort;
		}
		else
		{
			pszTitle = c_pszTitle;
		}
	}
	
	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	m_Print3D.DisplayDefaultTitle(pszTitle, "", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();
	
	return true;
}
Example #18
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;
}
/*!****************************************************************************
 @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 OGLESPVRScopeRemote::RenderScene()
{
	CPPLProcessingScoped PPLProcessingScoped(m_psSPSCommsData,
		__FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter);

	if(m_psSPSCommsData)
	{
		// mark every N frames
		if(!(m_i32FrameCounter % 100))
		{
			char buf[128];
			const int nLen = sprintf(buf, "frame %u", m_i32FrameCounter);
			m_bCommsError |= !pplSendMark(m_psSPSCommsData, buf, nLen);
		}

		// Check for dirty items
		m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "dirty", static_cast<unsigned int>(strlen("dirty")), m_i32FrameCounter);
		{
			unsigned int nItem, nNewDataLen;
			const char *pData;
			while(pplLibraryDirtyGetFirst(m_psSPSCommsData, &nItem, &nNewDataLen, &pData))
			{
				PVRShellOutputDebug("dirty item %u %u 0x%08x\n", nItem, nNewDataLen, pData);
				switch(nItem)
				{
				case 0:
					if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat))
					{
						const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData;
						m_fMinThickness = psData->fCurrent;
					}
					break;
				case 1:
					if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat))
					{
						const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData;
						m_fMaxVariation = psData->fCurrent;
					}
					break;
				}
			}
		}
		m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData);
	}

	if (m_psSPSCommsData)
	{
		m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "draw", static_cast<unsigned int>(strlen("draw")), m_i32FrameCounter);
	}

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

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

	// Specify the modelview matrix
	PVRTMat4 mModel;
	SPODNode& Node = m_Scene.pNode[0];

	m_Scene.GetWorldMatrix(mModel, Node);

	// Rotate and Translate the model matrix
	m_fAngleY += (2*PVRT_PIf/60)/7;

	// Set model view projection matrix
	PVRTMat4 mModelView;
	mModelView = m_mView * PVRTMat4::RotationY(m_fAngleY) * mModel;

	glMatrixMode(GL_MODELVIEW);
	glLoadMatrixf(mModelView.f);

	/*
		Load the light direction from the scene if we have one
	*/

	// Enables lighting. See BasicTnL for a detailed explanation
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	// Set light direction
	PVRTVec4 vLightDirModel;
	vLightDirModel = mModel.inverse() * PVRTVec4(1, 1, 1, 0);
	glLightfv(GL_LIGHT0, GL_POSITION, (float*)&vLightDirModel.x);

	// Enable the vertex position attribute array
	glEnableClientState(GL_VERTEX_ARRAY);

	// bind the texture
	glBindTexture(GL_TEXTURE_2D, m_uiTexture);

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

	// Disable the vertex positions
	glDisableClientState(GL_VERTEX_ARRAY);

	if (m_psSPSCommsData)
	{
		m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData);
		m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "Print3D", static_cast<unsigned int>(strlen("Print3D")), m_i32FrameCounter);
	}

	// Displays the demo name using the tools. For a detailed explanation, see the example IntroducingPVRTools
	if(m_bCommsError)
	{
		m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs\n\nError:\n  PVRScopeComms failed\n  Is PVRPerfServer connected?", ePVRTPrint3DSDKLogo);
		m_bCommsError = false;
	}
	else
		m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs", ePVRTPrint3DSDKLogo);

	m_Print3D.Flush();

	if (m_psSPSCommsData)
	{
		m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData);
	}

	// send counters
	m_anCounterReadings[eCounter]	= m_i32FrameCounter;
	m_anCounterReadings[eCounter10]	= m_i32Frame10Counter;
	if(m_psSPSCommsData)
	{
		m_bCommsError |= !pplCountersUpdate(m_psSPSCommsData, m_anCounterReadings);
	}

	// update some counters
	++m_i32FrameCounter;
	if(0 == (m_i32FrameCounter / 10) % 10)
	{
		m_i32Frame10Counter += 10;
	}

	return true;
}
#include "OGLES2Tools.h"



/******************************************************************************
 Constants
******************************************************************************/

// Camera constants used to generate the projection matrix
const float CAM_FOV  = PVRT_PI / 6;
const float CAM_NEAR = 75.0f;

const float g_SomeRotation = 45.0f/(2*PVRT_PI);
const PVRTVec3 g_CubeTranslation = PVRTVec3(0.0f, -20.0f, 0.f);
const PVRTVec3 g_CubeScale = PVRTVec3(1.4f, 1.4f, 1.4f);
const PVRTVec4 g_LightPos = PVRTVec4(0.f, 30.f, 10.f, 1);


/******************************************************************************
 shader attributes
******************************************************************************/
// vertex attributes
enum EVertexAttrib {
	VERTEX_ARRAY, NORMAL_ARRAY, TEXCOORD_ARRAY, TANGENT_ARRAY, eNumAttribs };
const char* g_aszAttribNames[] = {
	"vertPos", "vertNormal", "vertUV", "vertTangent" };

// shader uniforms
enum EUniform {
	eModelViewMatrix, eModelViewProj, eNormal, eLightEyeSpacePos, eNumUniforms };
const char* g_aszUniformNames[] = {
/*!****************************************************************************
 @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 OGLESRenderToTexture::InitView()
{
	CPVRTString ErrorStr;
	/*
		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;
	}

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

	// Create a FBO or PBuffer
	if(!CreateFBOorPBuffer())
		return false;

	// Setup some render states

	// Enable the depth test
	glEnable(GL_DEPTH_TEST);

	// Enable culling
	glEnable(GL_CULL_FACE);

	// Setup the material parameters our meshes will use
	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,  PVRTVec4(1.0f).ptr());
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,  PVRTVec4(1.0f).ptr());

	// Setup view and projection matrices used for when rendering to the texture

	// Caculate the view matrix
	m_mR2TView = PVRTMat4::LookAtRH(PVRTVec3(0, 0, 60), PVRTVec3(0, 0, 0), PVRTVec3(0, 1, 0));

	// Calculate the projection matrix
	// Note: As we'll be rendering to a texture we don't need to take the screen rotation into account
	m_mR2TProjection = PVRTMat4::PerspectiveFovRH(1, 1, g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, false);

	// Setup view and projection matrices used for when rendering the main scene

	// Caculate the view matrix
	m_mView = PVRTMat4::LookAtRH(PVRTVec3(0, 0, 125), PVRTVec3(0, 0, 0), PVRTVec3(0, 1, 0));

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

	return true;
}
Example #22
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;
}
/*!****************************************************************************
 @Function		RenderCubeScene
 @Input			iFrame
 @Description	Renders the pre-loaded scene.
******************************************************************************/
void OGLES2MultiThreading::RenderCubeScene(int iFrame)
{
    bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
    int  iW      = PVRShellGet(prefWidth);
    int  iH      = PVRShellGet(prefHeight);

    PVRTMat4 mxProjection = PVRTMat4::PerspectiveFovRH(0.7f, (float)iW / (float)iH, 1.0f, 1000.0f, PVRTMat4::OGL, bRotate);
    PVRTMat4 mxView       = PVRTMat4::Translation(0.0f, 0.0f, -200.0f);
    PVRTMat4 mxModel      = PVRTMat4::RotationX(-0.5f) * PVRTMat4::RotationY(iFrame * 0.016f) * PVRTMat4::Scale(30.0f, 30.0f, 30.0f);
    
    PVRTMat4 mxMVP        = mxProjection * mxView * mxModel;
    
    PVRTVec4 vLightDir    = PVRTVec4(0.0f, 0.3f, 1.0f, 0.0f) * mxModel;

    // Actually use the created program
    glUseProgram(handles.uiProgramObject);

    // Sets the clear color.
    // The colours are passed per channel (red,green,blue,alpha) as float values from 0.0 to 1.0
    glClearColor(0.6f, 0.8f, 1.0f, 1.0f); // clear blue
    
    glBindTexture(GL_TEXTURE_2D, handles.uiTexture);
    
    // Bind the VBO
    glBindBuffer(GL_ARRAY_BUFFER, handles.uiVbo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handles.uiIndexVbo);

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

    /*
        Bind the projection model view matrix (PMVMatrix) to
        the associated uniform variable in the shader
    */

    // First gets the location of that variable in the shader using its name
    int i32MVPLocation  = glGetUniformLocation(handles.uiProgramObject, "myPMVMatrix");
    int i32LDLocation   = glGetUniformLocation(handles.uiProgramObject, "vLightDir");
    int i32TexLocation  = glGetUniformLocation(handles.uiProgramObject, "sTexture");

    // Then passes the matrix to that variable
    glUniformMatrix4fv( i32MVPLocation, 1, GL_FALSE, mxMVP.ptr());
    
    // Pass light direction
    glUniform3fv( i32LDLocation, 1, vLightDir.ptr());
    
    // Set texture location
    glUniform1i( i32TexLocation, 0);

    /*
        Enable the custom vertex attribute at index VERTEX_ARRAY.
        We previously binded that index to the variable in our shader "vec4 MyVertex;"
     */
    glEnableVertexAttribArray(VERTEX_ARRAY);
    glEnableVertexAttribArray(NORMAL_ARRAY);
    glEnableVertexAttribArray(UV_ARRAY);

    // Sets the vertex data to this attribute index
    glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), 0);
    glVertexAttribPointer(NORMAL_ARRAY, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(3*sizeof(GLfloat)));
    glVertexAttribPointer(UV_ARRAY,     2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void*)(6*sizeof(GLfloat)));

    /*
        Draws a non-indexed triangle array from the pointers previously given.
        This function allows the use of other primitive types : triangle strips, lines, ...
        For indexed geometry, use the function glDrawElements() with an index list.
    */
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
    
    // Disable states
    glDisableVertexAttribArray(VERTEX_ARRAY);
    glDisableVertexAttribArray(NORMAL_ARRAY);
    glDisableVertexAttribArray(UV_ARRAY);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    
    glBindTexture(GL_TEXTURE_2D, 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 OGLES2PVRScopeRemote::RenderScene()
{
	CPPLProcessingScoped PPLProcessingScoped(m_psSPSCommsData,
		__FUNCTION__, static_cast<unsigned int>(strlen(__FUNCTION__)), m_i32FrameCounter);

	if(m_psSPSCommsData)
	{
		// mark every N frames
		if(!(m_i32FrameCounter % 100))
		{
			char buf[128];
			const int nLen = sprintf(buf, "frame %u", m_i32FrameCounter);
			m_bCommsError |= !pplSendMark(m_psSPSCommsData, buf, nLen);
		}

		// Check for dirty items
		m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "dirty", static_cast<unsigned int>(strlen("dirty")), m_i32FrameCounter);
		{
			unsigned int nItem, nNewDataLen;
			const char *pData;
			bool bRecompile = false;
			while(pplLibraryDirtyGetFirst(m_psSPSCommsData, &nItem, &nNewDataLen, &pData))
			{
				PVRShellOutputDebug("dirty item %u %u 0x%08x\n", nItem, nNewDataLen, pData);
				switch(nItem)
				{
				case 0:
					delete [] m_pszFragShader;
					m_pszFragShader = new char [nNewDataLen+1];
					strncpy(m_pszFragShader, (char*)pData, nNewDataLen);
					m_pszFragShader[nNewDataLen] = 0;
					bRecompile = true;
					break;

				case 1:
					delete [] m_pszVertShader;
					m_pszVertShader = new char [nNewDataLen+1];
					strncpy(m_pszVertShader, (char*)pData, nNewDataLen);
					m_pszVertShader[nNewDataLen] = 0;
					bRecompile = true;
					break;

				case 2:
					if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat))
					{
						const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData;
						m_fMinThickness = psData->fCurrent;
					}
					break;
				case 3:
					if(nNewDataLen == sizeof(SSPSCommsLibraryTypeFloat))
					{
						const SSPSCommsLibraryTypeFloat * const psData = (SSPSCommsLibraryTypeFloat*)pData;
						m_fMaxVariation = psData->fCurrent;
					}
					break;
				}
			}

			if(bRecompile)
			{
				CPVRTString ErrorStr;
				glDeleteProgram(m_ShaderProgram.uiId);
				glDeleteShader(m_uiVertShader);
				glDeleteShader(m_uiFragShader);
				if (!LoadShaders(&ErrorStr, m_pszFragShader, m_pszVertShader))
				{
					PVRShellOutputDebug("%s", ErrorStr.c_str());
				}
			}
		}
		m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData);
	}

	if (m_psSPSCommsData)
	{
		m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "draw", static_cast<unsigned int>(strlen("draw")), m_i32FrameCounter);
	}

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

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

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

	// Rotate and Translation the model matrix
	PVRTMat4 mModel;
	mModel = PVRTMat4::RotationY(m_fAngleY);
	m_fAngleY += (2*PVRT_PI/60)/7;

	// Set model view projection matrix
	PVRTMat4 mModelView, mMVP;
	mModelView = m_mView * mModel;
	mMVP =  m_mProjection * mModelView;
	glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.ptr());

	// Set light direction in model space
	PVRTVec4 vLightDirModel;
	vLightDirModel = mModel.inverse() * PVRTVec4(1, 1, 1, 0);

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

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

	/*
		Set the iridescent shading parameters
	*/
	// Set the minimum thickness of the coating in nm
	glUniform1f(m_ShaderProgram.uiMinThicknessLoc, m_fMinThickness);

	// Set the maximum variation in thickness of the coating in nm
	glUniform1f(m_ShaderProgram.uiMaxVariationLoc, m_fMaxVariation);

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

	if (m_psSPSCommsData)
	{
		m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData);
		m_bCommsError |= !pplSendProcessingBegin(m_psSPSCommsData, "Print3D", static_cast<unsigned int>(strlen("Print3D")), m_i32FrameCounter);
	}

	// Displays the demo name using the tools. For a detailed explanation, see the example IntroducingPVRTools
	if(m_bCommsError)
	{
		m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs\n\nError:\n  PVRScopeComms failed\n  Is PVRPerfServer connected?", ePVRTPrint3DSDKLogo);
		m_bCommsError = false;
	}
	else
		m_Print3D.DisplayDefaultTitle("PVRScopeRemote", "Remote APIs", ePVRTPrint3DSDKLogo);

	m_Print3D.Flush();

	if (m_psSPSCommsData)
	{
		m_bCommsError |= !pplSendProcessingEnd(m_psSPSCommsData);
	}

	// send counters
	m_anCounterReadings[eCounter]	= m_i32FrameCounter;
	m_anCounterReadings[eCounter10]	= m_i32Frame10Counter;
	if(m_psSPSCommsData)
	{
		m_bCommsError |= !pplCountersUpdate(m_psSPSCommsData, m_anCounterReadings);
	}

	// update some counters
	++m_i32FrameCounter;
	if(0 == (m_i32FrameCounter / 10) % 10)
	{
		m_i32Frame10Counter += 10;
	}

	return true;
}
Example #25
0
//this function creates the vertex position, colour, normal, and tex coordiante values for one cover.
void OGLESCoverflow::CreateCover()
{
	unsigned short i, row, col;
	float width = 6.0f;
	float height = 6.0f;
	float heightFromMirror = 0.0f;
	float dim = 0.5f; //initialise vertices to normalised size, can then also be used as uv coorda and scales up after
	m_fBorderFraction = 0.00f;
	float dimLess = 0.5f - (0.5f*m_fBorderFraction);//size minus the fraction of the border
	PVRTVec3 normal = PVRTVec3(0.0f, 1.0f, 0.0f); //all the normals are the same

	/* The covers are made up of 16 vertices, 9 quads, 18 triangles. The four colours of the center vertices are fully opaque while all the
	outside vertices are fully transparent. This produces a thin fade out at the edges which avoids antialiasing.

	0--1------2--3
	|  |      |  |
	4--5------6--7
	|  |      |  |
	|  |      |  |
	|  |      |  |
	8--9-----10--11
	|  |      |  |
	12-13----14--15

	*/

	m_coverPoints[0].p	=	PVRTVec3(-dim, dim, 0);
	m_coverPoints[1].p	=	PVRTVec3(-dimLess, dim, 0);
	m_coverPoints[2].p	=	PVRTVec3(dimLess, dim, 0);
	m_coverPoints[3].p	=	PVRTVec3(dim, dim, 0);
	m_coverPoints[4].p	=	PVRTVec3(-dim, dimLess, 0);
	m_coverPoints[5].p	=	PVRTVec3(-dimLess, dimLess, 0);
	m_coverPoints[6].p	=	PVRTVec3(dimLess, dimLess, 0);
	m_coverPoints[7].p	=	PVRTVec3(dim, -dimLess, 0);
	m_coverPoints[8].p	=	PVRTVec3(-dim, -dimLess, 0);
	m_coverPoints[9].p	=	PVRTVec3(-dimLess, -dimLess, 0);
	m_coverPoints[10].p	=	PVRTVec3(dimLess, -dimLess, 0);
	m_coverPoints[11].p	=	PVRTVec3(dim, -dimLess, 0);
	m_coverPoints[12].p	=	PVRTVec3(-dim, -dim, 0);
	m_coverPoints[13].p	=	PVRTVec3(-dimLess, -dim, 0);
	m_coverPoints[14].p	=	PVRTVec3(dimLess, -dim, 0);
	m_coverPoints[15].p	=	PVRTVec3(dim, -dim, 0);


	for(i = 0; i < 16; ++i)
	{
		m_coverPoints[i].n = normal;
		m_coverPoints[i].c = PVRTVec4(1.0f, 1.0f, 1.0f, 0.0f);

		//the uvs are matched to the positions (+0.5 for range 0-1)
		m_coverPoints[i].t.x = m_coverPoints[i].p.x + 0.5f;
		m_coverPoints[i].t.y = m_coverPoints[i].p.y + 0.5f;

		//scale up to desired size
		m_coverPoints[i].p.x = m_coverPoints[i].p.x * width;
		m_coverPoints[i].p.y = m_coverPoints[i].p.y * height;
	}

	//only the center 4 vertices have are fully opaque all the rest around the edge are tranparent
	m_coverPoints[5].c.w = 1.0f;
	m_coverPoints[6].c.w = 1.0f;
	m_coverPoints[9].c.w = 1.0f;
	m_coverPoints[10].c.w = 1.0f;


	//create indioes for the 2 triangles for every square
	int i32NumOpaque = 0;
	int i32NumBlend = 0;

	for(row = 0; row < 3; ++row)
	{
		for(col = 0; col < 3; ++col)
		{
			unsigned short start = (row*4)+col;
			//the centre indices are kept in a separate buffer to the border ones as they arew going
			//to be drawn in 2 separate passes.
			if(row == 1 && col == 1)
			{
				m_indicesOpaque[i32NumOpaque++] = start+1;
				m_indicesOpaque[i32NumOpaque++] = start;
				m_indicesOpaque[i32NumOpaque++] = start+4;
				m_indicesOpaque[i32NumOpaque++] = start+1;
				m_indicesOpaque[i32NumOpaque++] = start+4;
				m_indicesOpaque[i32NumOpaque++] = start+5;
			}
			else
			{
				m_indicesBlend[i32NumBlend++] = start+1;
				m_indicesBlend[i32NumBlend++] = start;
				m_indicesBlend[i32NumBlend++] = start+4;
				m_indicesBlend[i32NumBlend++] = start+1;
				m_indicesBlend[i32NumBlend++] = start+4;
				m_indicesBlend[i32NumBlend++] = start+5;

			}
		}
	}


	//adjusted the triangle alignment for two of the corners so that the transparency
	//falls off in the same direction as the other two corners (comment out to see what i mean!)
	//top left
	m_indicesBlend[0] = 1;
	m_indicesBlend[1] = 0;
	m_indicesBlend[2] = 5;
	m_indicesBlend[3] = 0;
	m_indicesBlend[4] = 4;
	m_indicesBlend[5] = 5;

	//bottom right
	m_indicesBlend[42] = 11;
	m_indicesBlend[43] = 10;
	m_indicesBlend[44] = 15;
	m_indicesBlend[45] = 10;
	m_indicesBlend[46] = 14;
	m_indicesBlend[47] = 15;

	//copy the indices for the mirrored versions
	for(i = 0; i < 48; ++i)
	{
		if(i < 6)
		{
			m_indicesOpaque[i+6] = m_indicesOpaque[i] + 16;
		}
		m_indicesBlend[i+48] = m_indicesBlend[i] + 16;
	}
	i32NumBlend *= 2;
	i32NumOpaque *= 2;

	//create the vertex points for the mirrored cover.
	for(row = 0; row < 4; ++row)
	{
		//the colours on the flip vertices are going to fade out the further away from the mirror they are
		// using the y coordinate of the coverpoints
		float dark = 1 - ((m_coverPoints[(row*4)].p.y/height)+ 0.5f);
		dark -= 0.5f; //made a little darker in the reflection to mimic properties of dull mirror

		for(col = 0; col < 4; ++col)
		{
			//copy the vertices with y values reversed for the mirrored equivalents
			m_coverPoints[((row*4)+col) + 16] = m_coverPoints[((row*4)+col)];
			m_coverPoints[((row*4)+col) + 16].p.y = m_coverPoints[((row*4)+col) + 16].p.y * -1.0f;
			m_coverPoints[((row*4)+col) + 16].p.y -= height + heightFromMirror;

			m_coverPoints[((row*4)+col) + 16].c.x = dark;
			m_coverPoints[((row*4)+col) + 16].c.y = dark;
			m_coverPoints[((row*4)+col) + 16].c.z = dark;
		}
	}

	for(i = 0; i < 96; ++i)
	{
		m_indicesAll[i] = m_indicesBlend[i];
	}

	for(i = 0; i < 12; ++i)
	{
		m_indicesAll[i+96] = m_indicesOpaque[i];
	}

	glGenBuffers(1, &m_uiVbo);
	glBindBuffer(GL_ARRAY_BUFFER, m_uiVbo);
	glBufferData(GL_ARRAY_BUFFER, 32 * sizeof(SVertex), m_coverPoints, GL_STATIC_DRAW);

	glGenBuffers(1, &m_uiBlendIndexVbo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiBlendIndexVbo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, i32NumBlend*2, m_indicesBlend, GL_STATIC_DRAW);

	glGenBuffers(1, &m_uiOpaqueIndexVbo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiOpaqueIndexVbo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, i32NumOpaque*2, m_indicesOpaque, GL_STATIC_DRAW);

	glGenBuffers(1, &m_uiAllIndexVbo);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiAllIndexVbo);
	glBufferData(GL_ELEMENT_ARRAY_BUFFER, 108*2, m_indicesAll, GL_STATIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 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 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;
}
Example #27
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 OGLES2LevelOfDetail::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

	// Bind textures
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiReflectTex);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, m_uiNormalTex);

	// Rotate and Translate the model matrix
	PVRTMat4 mModel, mRotY, mTrans;
	float fDistance = 1400.0f * cos(m_fPositionZ) - 1350.0f;
	
	mTrans = PVRTMat4::Translation(0.0, 0.0, fDistance);
	mRotY = PVRTMat4::RotationY(m_fAngleY);
	mModel = mTrans * mRotY;

	m_fAngleY += PVRT_PI / 210;
	m_fPositionZ += 2 * PVRT_PI * 0.0008f;

	// 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 model matrix
	PVRTMat3 Model3x3 = PVRTMat3(mModel);

	glUniformMatrix3fv(m_ShaderProgram.auiLoc[eModelWorld], 1, GL_FALSE, Model3x3.ptr());

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

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

	// Calculate the square of the pixel area that the mesh takes up on screen
	// This is done by projecting the vertices of the bounding box to screen space
	// then taking the axis aligned 2D bounding box of the projected vertices.
	// This is a very conservative estimate
	float fMinX, fMaxX, fMinY, fMaxY, fX, fY;
	ProjectVertex(m_avBoundingBox[0], mMVP, fX, fY);
	fMinX = fMaxX = fX;
	fMinY = fMaxY = fY;

	for (int i = 1; i < 8; ++i)
	{
		ProjectVertex(m_avBoundingBox[i], mMVP, fX, fY);
		fMinX = PVRT_MIN(fMinX, fX);
		fMinY = PVRT_MIN(fMinY, fY);
		fMaxX = PVRT_MAX(fMaxX, fX);
		fMaxY = PVRT_MAX(fMaxY, fY);
	}

	// Choose high detail if the mesh bounding box covers more than 2% of the screen
	m_bHighDetail = ((fMaxX - fMinX) * (fMaxY - fMinY) > 0.02);
	glUniform1i(m_ShaderProgram.auiLoc[eHighDetail], m_bHighDetail);

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

	// Displays the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	m_Print3D.DisplayDefaultTitle("Level of detail", (m_bHighDetail) ? "Detail: high" : "Detail: low", ePVRTPrint3DLogoIMG);
	m_Print3D.Flush();
	return true;
}
Example #28
0
/*!****************************************************************************
 @Function		UpdateFurShells
 @Description	Update the fur shells. This is only called when the number of
				shells change.
******************************************************************************/
void OGLESFur::UpdateFurShells()
{
	PVRTVec3	*pvSrcN, *pvSrcV;
	PVRTVec3	vTransNorm;
	PVRTVec4	vTransPos;
	SVertex		*pvData;
	int				i;
	unsigned int	j;
	float		fDepth, *pUV;

	int i32MeshIndex = m_Scene.pNode[eDuckBody].nIdx;
	SPODMesh* pMesh = &m_Scene.pMesh[i32MeshIndex];

	PVRTMat4 mModel;
	PVRTMat3 mModel3;

	m_Scene.GetWorldMatrix(mModel, m_Scene.pNode[eDuckBody]);
	mModel3 = PVRTMat3(mModel);

	pvData = new SVertex[pMesh->nNumVertex];

	if(!pvData)
		return;

	for(i = 0; i < m_i32FurShellNo; ++i)
	{
		fDepth = (c_fFurDepth * (float)(i+1) / (float)m_i32FurShellNo);

		for(j = 0; j < pMesh->nNumVertex; ++j)
		{
			pvSrcN	= (PVRTVec3*) (pMesh->pInterleaved + (size_t) pMesh->sNormals.pData + (j * pMesh->sNormals.nStride));
			pvSrcV	= (PVRTVec3*) (pMesh->pInterleaved + (size_t) pMesh->sVertex.pData  + (j * pMesh->sVertex.nStride));
			pUV		= (float*) (pMesh->pInterleaved + (size_t) pMesh->psUVW[0].pData + (j * pMesh->psUVW[0].nStride));

			// Transform the vertex position so it is in world space
			PVRTVec4 vPos4 = PVRTVec4(*pvSrcV, 1.0f);
			PVRTTransform(&vTransPos, &vPos4, &mModel);

			// Transform the vertex normal so it is in world space
			vTransNorm.x = mModel.f[0] * pvSrcN->x + mModel.f[4] * pvSrcN->y + mModel.f[8] * pvSrcN->z;
			vTransNorm.y = mModel.f[1] * pvSrcN->x + mModel.f[5] * pvSrcN->y + mModel.f[9] * pvSrcN->z;
			vTransNorm.z = mModel.f[2] * pvSrcN->x + mModel.f[6] * pvSrcN->y + mModel.f[10]* pvSrcN->z;
			vTransNorm.normalize();

			pvData[j].x = vTransPos.x + (vTransNorm.x * fDepth);
			pvData[j].y = vTransPos.y + (vTransNorm.y * fDepth);
			pvData[j].z = vTransPos.z + (vTransNorm.z * fDepth);

			pvData[j].nx = vTransNorm.x;
			pvData[j].ny = vTransNorm.y;
			pvData[j].nz = vTransNorm.z;

			pvData[j].tu = pUV[0];
			pvData[j].tv = pUV[1];
		}

		glBindBuffer(GL_ARRAY_BUFFER, m_uiShellVbo[i]);
		unsigned int uiSize = pMesh->nNumVertex * sizeof(SVertex);
		glBufferData(GL_ARRAY_BUFFER, uiSize, pvData, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
	}

	delete[] pvData;
}
/*******************************************************************************
 * 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 OGLESSkinning::InitView()
{
	CPVRTString error;

	//	Check to see whether the matrix palette extension is supported.
	if(!CPVRTglesExt::IsGLExtensionSupported("GL_OES_matrix_palette"))
	{
		PVRShellSet(prefExitMessage, "ERROR: The extension GL_OES_matrix_palette is unsupported.\n");
		return false;
	}

	// Initialise the matrix palette extensions
	m_Extensions.LoadExtensions();

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

	// Init Print3D to display text on screen
	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;
	}

	// Model View Matrix
	CameraGetMatrix();

	// Projection Matrix
	glMatrixMode(GL_PROJECTION);
	glLoadMatrixf(m_mProjection.f);

	// GENERIC RENDER STATES

	// Enables Depth Testing
	glEnable(GL_DEPTH_TEST);

	// Enables Smooth Colour Shading
	glShadeModel(GL_SMOOTH);

	// Enable texturing
	glEnable(GL_TEXTURE_2D);

	// Define front faces
	glFrontFace(GL_CW);

	// Enables texture clamping
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
	glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );

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

	// Setup ambiant light
    glEnable(GL_LIGHTING);

	PVRTVec4 lightGlobalAmbient = PVRTVec4(1.0f, 1.0f, 1.0f, 1.0f);
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightGlobalAmbient.ptr());

	// Setup a directional light source
	PVRTVec4 lightPosition = PVRTVec4(-0.7f, -1.0f, 0.2f, 0.0f);
    PVRTVec4 lightAmbient  = PVRTVec4(1.0f, 1.0f, 1.0f, 1.0f);
    PVRTVec4 lightDiffuse  = PVRTVec4(1.0f, 1.0f, 1.0f, 1.0f);
    PVRTVec4 lightSpecular = PVRTVec4(0.2f, 0.2f, 0.2f, 1.0f);

    glEnable(GL_LIGHT0);
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition.ptr());
    glLightfv(GL_LIGHT0, GL_AMBIENT,  lightAmbient.ptr());
    glLightfv(GL_LIGHT0, GL_DIFFUSE,  lightDiffuse.ptr());
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular.ptr());

	LoadVbos();

	/*
		Initialise an array to lookup the textures
		for each material in the scene.
	*/
	m_puiTextures = new GLuint[m_Scene.nNumMaterial];

	for(unsigned int i = 0; i < m_Scene.nNumMaterial; ++i)
	{
		m_puiTextures[i] = m_uiLegTex;

		SPODMaterial* pMaterial = &m_Scene.pMaterial[i];
		if(strcmp(pMaterial->pszName, "Mat_body") == 0)
		{
			m_puiTextures[i] = m_uiBodyTex;
		}
		else if(strcmp(pMaterial->pszName, "Mat_legs") == 0)
		{
			m_puiTextures[i] = m_uiLegTex;
		}
		else if(strcmp(pMaterial->pszName, "Mat_belt") == 0)
		{
			m_puiTextures[i] = m_uiBeltTex;
		}
	}

	return true;
}
	void UniformHandler::CalculateMeshUniform(const Uniform& sUniform, SPODMesh *pMesh, SPODNode *pNode)
	{
		switch(sUniform.getSemantic())
		{
		case eUsPosition:
			{
				glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsNormal:
			{
				glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsTangent:
			{
				glVertexAttribPointer(sUniform.getLocation(), 3, GL_FLOAT, GL_FALSE, pMesh->sTangents.nStride, pMesh->sTangents.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsBinormal:
			{
				glVertexAttribPointer(sUniform.getLocation(), 2, GL_FLOAT, GL_FALSE, pMesh->sBinormals.nStride, pMesh->sBinormals.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsUV:
			{
				glVertexAttribPointer(sUniform.getLocation(), 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsBoneIndex:
			{
				glVertexAttribPointer(sUniform.getLocation(), pMesh->sBoneIdx.n, GL_UNSIGNED_BYTE, GL_FALSE, pMesh->sBoneIdx.nStride, pMesh->sBoneIdx.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsBoneWeight:
			{
				glVertexAttribPointer(sUniform.getLocation(), pMesh->sBoneWeight.n, GL_FLOAT, GL_FALSE, pMesh->sBoneWeight.nStride, pMesh->sBoneWeight.pData);
				glEnableVertexAttribArray(sUniform.getLocation());
			}
			break;
		case eUsWORLD:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorld.f);
			}
			break;
		case eUsWORLDI:
			{
				PVRTMat4 mWorldI;
				mWorldI =  m_mWorld.inverse();
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldI.f);
			}
			break;
		case eUsWORLDIT:
			{
				PVRTMat3 mWorldIT;
				mWorldIT = m_mWorld.inverse().transpose();
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldIT.f);
			}
			break;
		case eUsWORLDVIEW:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorldView.f);
			}
			break;
		case eUsWORLDVIEWI:
			{
				PVRTMat4 mWorldViewI;
				mWorldViewI = m_mWorldView.inverse();
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewI.f);
			}
			break;
		case eUsWORLDVIEWIT:
			{
				PVRTMat3 mWorldViewIT;
				mWorldViewIT = m_mWorldView.inverse().transpose();
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewIT.f);
			}
			break;
		case eUsWORLDVIEWPROJECTION:
			{
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mWorldViewProjection.f);
			}
			break;
		case eUsWORLDVIEWPROJECTIONI:
			{
				PVRTMat4 mWorldViewProjectionI = (m_mProjection * m_mWorldView ).inverse();
				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewProjectionI.f);
			}
			break;
		case eUsWORLDVIEWPROJECTIONIT:
			{
				PVRTMat3 mWorldViewProjectionIT = (m_mProjection * m_mWorldView).inverse().transpose();
				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, mWorldViewProjectionIT.f);
			}
			break;
		case eUsLIGHTPOSMODEL:
			{
				// Passes the light position in eye space to the shader
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypePoint:
					{
						PVRTVec4 vLightPosModel = m_mWorld.inverse() * ((LightPoint*)pLight)->getPositionPVRTVec4() ;
						glUniform3f(sUniform.getLocation(),
							vLightPosModel.x,
							vLightPosModel.y,
							vLightPosModel.z);
					}
					break;
				case eLightTypePODPoint:
					{
						PVRTVec4 vLightPosModel = m_mWorld.inverse() * ((LightPODPoint*)pLight)->getPositionPVRTVec4() ;
						glUniform3f(sUniform.getLocation(),
							vLightPosModel.x,
							vLightPosModel.y,
							vLightPosModel.z);
					}
					break;
				default:
					{	// hack for directional lights
						// take the light direction and multiply it by a really big negative number
						// if you hit this code then the types of your lights do not match the types expected by your shaders
						PVRTVec4 vLightPosModel = (((LightDirectional*)pLight)->getDirectionPVRTVec4()*c_fFarDistance) ;
						vLightPosModel.w = f2vt(1.0f);
						vLightPosModel = m_mWorld * vLightPosModel;
						glUniform3f(sUniform.getLocation(),
							vLightPosModel.x,
							vLightPosModel.y,
							vLightPosModel.z);
					}
				}
			}
			break;
		case eUsOBJECT:
			{
				// Scale
				PVRTMat4 mObject = m_psScene->GetScalingMatrix(*pNode);
				// Rotation
				mObject = m_psScene->GetRotationMatrix(*pNode) * mObject;
				// Translation
				mObject = m_psScene->GetTranslationMatrix(*pNode) * mObject;

				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, mObject.f);
			}
			break;
		case eUsOBJECTI:
			{
				if(!getFlag(eUsOBJECT))
				{
					// Scale
					m_mObject = m_psScene->GetScalingMatrix(*pNode);
					// Rotation
					m_mObject = m_psScene->GetRotationMatrix(*pNode) * m_mObject;
					// Translation
					m_mObject = (m_psScene->GetTranslationMatrix(*pNode) * m_mObject);
					setFlag(eUsOBJECT);
				}
				m_mObjectI = m_mObject.inverse();

				glUniformMatrix4fv(sUniform.getLocation(), 1, GL_FALSE, m_mObjectI.f);
			}
			break;
		case eUsOBJECTIT:
			{
				if(!getFlag(eUsOBJECTI))
				{
					if(!getFlag(eUsOBJECT))
					{
						// Scale
						m_mObject = m_psScene->GetScalingMatrix(*pNode);
						// Rotation
						m_mObject = m_psScene->GetRotationMatrix(*pNode) * m_mObject;
						// Translation
						m_mObject = (m_psScene->GetTranslationMatrix(*pNode) * m_mObject);
						setFlag(eUsOBJECT);
					}
					m_mObjectI = m_mObject.inverse();
					setFlag(eUsOBJECTI);
				}

				m_mObjectIT = PVRTMat3(m_mObjectI).transpose();

				glUniformMatrix3fv(sUniform.getLocation(), 1, GL_FALSE, m_mObjectIT.f);
			}
			break;
		case eUsLIGHTDIRMODEL:
			{
				Light* pLight = m_pLightManager->get(sUniform.getIdx());
				switch(pLight->getType())
				{
				case eLightTypeDirectional:
					{
						// Passes the light direction in model space to the shader
						PVRTVec4 vLightDirectionModel,
							vLightDirection =((LightDirectional*)pLight)->getDirectionPVRTVec4();
						vLightDirectionModel = m_mWorld.inverse() * vLightDirection ;
						glUniform3f(sUniform.getLocation(), vLightDirectionModel.x, vLightDirectionModel.y, vLightDirectionModel.z);
					}
				case eLightTypePODDirectional:
					{
						// Passes the light direction in model space to the shader
						PVRTVec4 vLightDirectionModel,
							vLightDirection =((LightPODDirectional*)pLight)->getDirectionPVRTVec4();
						vLightDirectionModel = m_mWorld.inverse() * vLightDirection ;
						glUniform3f(sUniform.getLocation(), vLightDirectionModel.x, vLightDirectionModel.y, vLightDirectionModel.z);
					}
				default:
					{	// could mimic point lights
						// calculate vector between light position and mesh

						// implemented by getting hold of the nice centre point I calculated for all these meshes and using this point
					}
				}
			}
			break;
		case eUsEYEPOSMODEL:
			{	
				m_vEyePositionModel = m_mWorld.inverse() * PVRTVec4(m_vEyePositionWorld,VERTTYPE(1.0f));
				glUniform3f(sUniform.getLocation(), m_vEyePositionModel.x, m_vEyePositionModel.y, m_vEyePositionModel.z);
			}
			break;
		default:
			{	// something went wrong
				ConsoleLog::inst().log("Error: non-mesh uniform being interpreted as mesh uniform\n");
				return;
			}
		}
	}