/*!****************************************************************************
 @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;
}
示例#2
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;
}
示例#3
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 OGLES2Shaders::RenderScene()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Keyboard input (cursor to change shaders and meshes)
	if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_nCurrentShader--;
		if(m_nCurrentShader<0) m_nCurrentShader=(g_numShaders-1);
	}
	if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_nCurrentShader++;
		if(m_nCurrentShader>(g_numShaders-1)) m_nCurrentShader=0;
	}
	if (PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
	{
		m_nCurrentSurface--;
		if(m_nCurrentSurface<0) m_nCurrentSurface=(g_numSurfaces-1);
		ComputeSurface(m_nCurrentSurface);
	}
	if (PVRShellIsKeyPressed(PVRShellKeyNameUP))
	{
		m_nCurrentSurface++;
		if(m_nCurrentSurface>(g_numSurfaces-1)) m_nCurrentSurface=0;
		ComputeSurface(m_nCurrentSurface);
	}

	// Draw the mesh
	ComputeViewMatrix();
	DrawModel();

	// Display screen info
	m_Print3D.DisplayDefaultTitle("Shaders", NULL, ePVRTPrint3DSDKLogo);
	m_Print3D.Print3D(0.3f, 7.5f, 0.75f, 0xFFFFFFFF, "Shader: %s\nMesh: %s", g_ShaderList[m_nCurrentShader], g_SurfacesList[m_nCurrentSurface]);
	m_Print3D.Flush();

	return true;
}
示例#4
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES2ParticleSystem::RenderScene()
{
	HandleInput();
	UpdateParticles();
	UpdateFramerateCounter();

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

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

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

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

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

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

	return true;
}
/*!****************************************************************************
 @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;
}
示例#6
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES2RenderToTexture::RenderScene()
{
	/* vary the branch angles on the fractal sinusoidally */
	m_fAngle = (float)(sin(0.25*PVRT_PIf*(float)(m_ui32Framenum)/256.0f))* 70.0f;

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

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

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

		if(m_ui32Framenum > 20000)
			m_ui32Framenum = 0;
	}

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

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

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

	return true;
}
/*!****************************************************************************
 @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 OGLES3AlphaBlend::RenderScene()
{
	// Do our clear
	glClear(GL_COLOR_BUFFER_BIT);

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

	// Draws the background
	glDisable(GL_BLEND);
	DrawQuad(-1, -1, +1, +1, m_uiTexBackground);

	/*
		Prepares to draw the different blend modes, activate blending.
		Now we can use glBlendFunc() to specify the blending mode wanted.
	*/
	glEnable(GL_BLEND);

	// Prepares the variables used to divide the screen in NUM_BLEND x NUM_BLEND rectangles
	float fX1 = -1;
	float fX2 = +1;
	float fY1 = -1;
	float fY2 = +.85f;
	float fPosX = fX1;
	float fPosY = fY1;
	float fMarginX = .25f;
	float fMarginY = .25f;
	float fBlockWidth = ((fX2-fX1) - fMarginX * 3.0f) * 0.5f;
	float fBlockHeight= ((fY2-fY1) - fMarginY * 3.0f) * 0.5f;

	//Position and draw the first quad (Transparency)
	fPosY = fY2 - fBlockHeight - fMarginY;
	fPosX += fMarginX;

	//Set up the blend function for this quad
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	DrawQuad(fPosX, fPosY, fPosX + fBlockWidth, fPosY + fBlockHeight, m_uiTexForeground);

	//Draw the text for this quad to the screen.
	m_Print3D.Print3D(18,12, 0.6f, 0xff00ffff, "Transparency");
	m_Print3D.Print3D(7,16, 0.6f, 0xff00ffff, "(SRC_ALPHA, 1 - SRC_ALPHA)");

	//Position and draw the second quad (Additive)
	fPosX += fMarginX + fBlockWidth;
	glBlendFunc(GL_ONE, GL_ONE);
	DrawQuad(fPosX, fPosY, fPosX + fBlockWidth, fPosY + fBlockHeight, m_uiTexForeground);

	m_Print3D.Print3D(66,12, 0.6f, 0xff00ffff, "Additive");
	m_Print3D.Print3D(64,16, 0.6f, 0xff00ffff, "(ONE, ONE)");

	//Position and draw the third quad (Modulate)
	fPosX = fX1 + fMarginX;
	fPosY -= fMarginY + fBlockHeight;

	glBlendFunc(GL_DST_COLOR, GL_ZERO);
	DrawQuad(fPosX, fPosY, fPosX + fBlockWidth, fPosY + fBlockHeight, m_uiTexForeground);

	m_Print3D.Print3D(22,52, 0.6f, 0xff00ffff, "Modulate");
	m_Print3D.Print3D(14,56, 0.6f, 0xff00ffff, "(DST_COLOR, ZERO)");

	//Position and draw the fourth quad (Modulate X 2)
	fPosX += fMarginX + fBlockWidth;
	glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
	DrawQuad(fPosX, fPosY, fPosX + fBlockWidth, fPosY + fBlockHeight, m_uiTexForeground);

	m_Print3D.Print3D(64,52, 0.6f, 0xff00ffff, "Modulate X2");
	m_Print3D.Print3D(53,56, 0.6f, 0xff00ffff, "(DST_COLOR, SRC_COLOR)");

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

	return true;
}
示例#8
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 OGLES2ShadowMapping::RenderScene()
{
	//rotate light position
	m_fLightAngle += 0.01f;
	m_vLightPosition.x = m_fLightDistance * (float) cos(m_fLightAngle);
	m_vLightPosition.z = m_fLightDistance * (float) sin(m_fLightAngle);
	m_vLightDirection.x = -m_vLightPosition.x;
	m_vLightDirection.z = -m_vLightPosition.z;

	SetUpMatrices();

	glEnable(GL_DEPTH_TEST);

	// Bind the frame buffer object
	glBindFramebuffer(GL_FRAMEBUFFER, m_uiFrameBufferObject);

	if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE)
	{
		// Clear the screen and depth buffer so we can render from the light's view
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		// Set the current viewport to our texture size
		glViewport(0, 0, m_ui32ShadowMapSize, m_ui32ShadowMapSize);

		// Since we don't care about colour when rendering the depth values to
		// the shadow-map texture, we disable color writing to increase speed.
		glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 

		// Enable the simple shader for the light view pass. This render will not be shown to the user 
		// so only the simplest render needs to be implemented
		glUseProgram(m_SimpleShaderProgram.uiId);

		// Set the light projection matrix
		glUniformMatrix4fv(m_SimpleShaderProgram.uiProjectionMatrixLoc, 1, GL_FALSE, m_LightProjection.f);

		// Render the world according to the light's view
		DrawScene(m_LightView);

		// We can turn color writing back on since we already stored the depth values
		glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 

		// Restore our normal viewport size to our screen width and height
		glViewport(0, 0,PVRShellGet(prefWidth),PVRShellGet(prefHeight));
	}

	glBindFramebuffer(GL_FRAMEBUFFER, 0);

	// Clear the colour and depth buffers, we are now going to render the scene again from scratch
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	// Load the shadow shader. This shader requires additional parameters; texProjMatrix for the depth buffer 
	// look up and the light direction for diffuse light (the effect is a lot nicer with the additon of the 
	// diffuse light).
	glUseProgram(m_ShadowShaderProgram.uiId);
	
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiShadowMapTexture);

	glUniformMatrix4fv(m_ShadowShaderProgram.uiProjectionMatrixLoc, 1, GL_FALSE, m_Projection.f);

	PVRTMat4 mViewInv, mTextureMatrix, mMatrix;
	mViewInv = m_View.inverse();

	// We need to calculate the texture projection matrix. This matrix takes the pixels from world space to previously rendered light projection space
	//where we can look up values from our saved depth buffer. The matrix is constructed from the light view and projection matrices as used for the previous render and 
	//then multiplied by the inverse of the current view matrix. 
	mTextureMatrix = m_BiasMatrix * m_LightProjection *  m_LightView * mViewInv;

	glUniformMatrix4fv(m_ShadowShaderProgram.uiTexProjMatrixLoc, 1, GL_FALSE, mTextureMatrix.f);

	DrawSceneWithShadow(m_View);

	// Re-enable the simple shader to draw the light source object
	glUseProgram(m_SimpleShaderProgram.uiId);

	SPODNode& Node = m_Scene.pNode[1];

	PVRTMat4 mWorld, mModelView;

	m_Scene.GetWorldMatrix(mWorld, Node);

	mWorld.f[12] = m_vLightPosition.x;
	mWorld.f[13] = m_vLightPosition.y;
	mWorld.f[14] = m_vLightPosition.z;

	mModelView = m_View * mWorld;

	glUniformMatrix4fv(m_SimpleShaderProgram.uiModelViewMatrixLoc, 1, GL_FALSE, mModelView.f);
	glUniformMatrix4fv(m_SimpleShaderProgram.uiProjectionMatrixLoc, 1, GL_FALSE, m_LightProjection.f);

	DrawMesh(1);

	m_Print3D.DisplayDefaultTitle("ShadowMap", "", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();

	return true;
}
示例#9
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 OGLESEvilSkull::RenderScene()
{
	unsigned int i;
	float fCurrentfJawRotation, fCurrentfBackRotation;
	float fFactor, fInvFactor;

	// Update Skull Weights and Rotations using Animation Info
	if(m_i32Frame > g_fExprTime)
	{
		m_i32Frame = 0;
		m_i32BaseAnim = m_i32TargetAnim;

		++m_i32TargetAnim;

		if(m_i32TargetAnim > 6)
		{
			m_i32TargetAnim = 0;
		}
	}

	fFactor = float(m_i32Frame) / g_fExprTime;
	fInvFactor = 1.0f - fFactor;

	m_fSkullWeights[0] = (m_fExprTable[0][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[0][m_i32TargetAnim] * fFactor);
	m_fSkullWeights[1] = (m_fExprTable[1][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[1][m_i32TargetAnim] * fFactor);
	m_fSkullWeights[2] = (m_fExprTable[2][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[2][m_i32TargetAnim] * fFactor);
	m_fSkullWeights[3] = (m_fExprTable[3][m_i32BaseAnim] * fInvFactor) + (m_fExprTable[3][m_i32TargetAnim] * fFactor);

	fCurrentfJawRotation = m_fJawRotation[m_i32BaseAnim] * fInvFactor + (m_fJawRotation[m_i32TargetAnim] * fFactor);
	fCurrentfBackRotation = m_fBackRotation[m_i32BaseAnim] * fInvFactor + (m_fBackRotation[m_i32TargetAnim] * fFactor);

	// Update Base Animation Value - FrameBased Animation for now
	++m_i32Frame;

	// Update Skull Vertex Data using Animation Params
	for(i = 0; i < m_Scene.pMesh[eSkull].nNumVertex * 3; ++i)
	{
		m_pMorphedVertices[i]= f2vt(m_pAVGVertices[i] + (m_pDiffVertices[0][i] * m_fSkullWeights[0]) \
													  + (m_pDiffVertices[1][i] * m_fSkullWeights[1]) \
													  + (m_pDiffVertices[2][i] * m_fSkullWeights[2]) \
													  + (m_pDiffVertices[3][i] * m_fSkullWeights[3]));

	}

	// Buffer Clear
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Render Skull and Jaw Opaque with Lighting
	glDisable(GL_BLEND);		// Opaque = No Blending
	glEnable(GL_LIGHTING);		// Lighting On

	// Set skull and jaw texture
	glBindTexture(GL_TEXTURE_2D, m_ui32Texture[1]);

	// Enable and set vertices, normals and index data
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	// Render Animated Jaw - Rotation Only
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	glLoadIdentity();

	myglMultMatrix(m_mView.f);

	myglTranslate(f2vt(0),f2vt(-50.0f),f2vt(-50.0f));

	myglRotate(f2vt(-fCurrentfJawRotation), f2vt(1.0f), f2vt(0.0f), f2vt(0.0f));
	myglRotate(f2vt(fCurrentfJawRotation) - f2vt(30.0f), f2vt(0), f2vt(1.0f), f2vt(-1.0f));

	RenderJaw();

	glPopMatrix();

	// Render Morphed Skull
	glPushMatrix();

	myglRotate(f2vt(fCurrentfJawRotation) - f2vt(30.0f), f2vt(0), f2vt(1.0f), f2vt(-1.0f));

	RenderSkull();

	// Render Eyes and Background with Alpha Blending and No Lighting

	glEnable(GL_BLEND);			// Enable Alpha Blending
	glDisable(GL_LIGHTING);		// Disable Lighting


	// Disable the normals as they aren't needed anymore
	glDisableClientState(GL_NORMAL_ARRAY);

	// Render Eyes using Skull Model Matrix
	DrawQuad(-30.0f ,0.0f ,50.0f ,20.0f , m_ui32Texture[0]);
	DrawQuad( 33.0f ,0.0f ,50.0f ,20.0f , m_ui32Texture[0]);

	glPopMatrix();

	// Render Dual Texture Background with different base color, rotation, and texture rotation
	glPushMatrix();

	glDisable(GL_BLEND);			// Disable Alpha Blending

	myglColor4(f2vt(0.7f+0.3f*((m_fSkullWeights[0]))), f2vt(0.7f), f2vt(0.7f), f2vt(1.0f));	// Animated Base Color
	myglTranslate(f2vt(10.0f), f2vt(-50.0f), f2vt(0.0f));
	myglRotate(f2vt(fCurrentfBackRotation*4.0f),f2vt(0),f2vt(0),f2vt(-1.0f));	// Rotation of Quad

	// Animated Texture Matrix
	glActiveTexture(GL_TEXTURE0);
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();

	myglTranslate(f2vt(-0.5f), f2vt(-0.5f), f2vt(0.0f));
	myglRotate(f2vt(fCurrentfBackRotation*-8.0f), f2vt(0), f2vt(0), f2vt(-1.0f));
	myglTranslate(f2vt(-0.5f), f2vt(-0.5f), f2vt(0.0f));

	// Draw Geometry
	DrawDualTexQuad (0.0f ,0.0f ,-100.0f ,300.0f, m_ui32Texture[3], m_ui32Texture[2]);

	// Disable Animated Texture Matrix
	glActiveTexture(GL_TEXTURE0);
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();

	// Make sure to disable the arrays
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisableClientState(GL_VERTEX_ARRAY);

	glMatrixMode(GL_MODELVIEW);
	glPopMatrix();

	// Reset Colour
	myglColor4(f2vt(1.0f), f2vt(1.0f), f2vt(1.0f), f2vt(1.0f));

	// Display info text
	m_Print3D.DisplayDefaultTitle("EvilSkull", "Morphing.", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();

	return true;
}
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLESIntroducingPFX::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

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

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

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

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

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

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

	/*
		A scene is composed of nodes. There are 3 types of nodes:
		- MeshNodes :
			references a mesh in the pMesh[].
			These nodes are at the beginning of the pNode[] array.
			And there are nNumMeshNode number of them.
			This way the .pod format can instantiate several times the same mesh
			with different attributes.
		- lights
		- cameras
		To draw a scene, you must go through all the MeshNodes and draw the referenced meshes.
	*/
	for (int i=0; i<(int)m_Scene.nNumMeshNode; i++)
	{
		SPODNode* pNode = &m_Scene.pNode[i];

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

		glBindBuffer(GL_ARRAY_BUFFER, m_aiVboID[i]);

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

		PVRTMat4 mWorldView;
		mWorldView = m_mView * mWorld;

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

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

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

					PVRTMat3 WorldViewIT = PVRTMat3(mWorldViewIT);

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

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

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

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

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

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

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

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

	return true;
}
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES2PVRScopeExample::RenderScene()
{
	// Keyboard input (cursor up/down to cycle through counters)
	if(PVRShellIsKeyPressed(PVRShellKeyNameUP))
	{
		m_i32Counter++;

		if(m_i32Counter > (int) m_pScopeGraph->GetCounterNum())
			m_i32Counter = m_pScopeGraph->GetCounterNum();
	}

	if(PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
	{
		m_i32Counter--;

		if(m_i32Counter < 0)
			m_i32Counter = 0;
	}

	if(PVRShellIsKeyPressed(PVRShellKeyNameACTION2))
		m_pScopeGraph->ShowCounter(m_i32Counter, !m_pScopeGraph->IsCounterShown(m_i32Counter));

	// Keyboard input (cursor left/right to change active group)
	if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_pScopeGraph->SetActiveGroup(m_pScopeGraph->GetActiveGroup()+1);
	}

	if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_pScopeGraph->SetActiveGroup(m_pScopeGraph->GetActiveGroup()-1);
	}

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

	char Description[256];

	if(m_pScopeGraph->GetCounterNum())
	{
		sprintf(Description, "Active Grp %i\n\nCounter %i (Grp %i) \nName: %s\nShown: %s\nuser y-axis: %.2f  max: %.2f%s",
			m_pScopeGraph->GetActiveGroup(), m_i32Counter,
			m_pScopeGraph->GetCounterGroup(m_i32Counter),
			m_pScopeGraph->GetCounterName(m_i32Counter),
			m_pScopeGraph->IsCounterShown(m_i32Counter) ? "Yes" : "No",
			m_pScopeGraph->GetMaximum(m_i32Counter),
			m_pScopeGraph->GetMaximumOfData(m_i32Counter),
			m_pScopeGraph->IsCounterPercentage(m_i32Counter) ? "%%" : "");
	}
	else
	{
		sprintf(Description, "No counters present");
	}

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

	// Update counters and draw the graph
	m_pScopeGraph->Ping();

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

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

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

    // Enable culling
    glEnable(GL_CULL_FACE);

    // Enable depth testing
    glEnable(GL_DEPTH_TEST);

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

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

    glUseProgram(ProgramID);

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

    if(ulTime > m_ulTimePrev)
    {
        unsigned long ulDeltaTime = ulTime - m_ulTimePrev;
        m_fFrame += (float)ulDeltaTime * g_fDemoFrameRate;

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

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

    m_ulTimePrev = ulTime;

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

    // Setup the camera
    bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

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

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

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

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

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

    SPODNode& Node = m_Scene.pNode[0];

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

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

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

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

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

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

    // Print text on screen

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

    m_Print3D.Flush();

    return true;
}
示例#13
0
/*******************************************************************************
 * Function Name  : RenderScene
 * Returns		  : true if no error occured
 * Description    : Main rendering loop function of the program. The shell will
 *					call this function every frame.
 *******************************************************************************/
bool OGLESVase::RenderScene()
{
	PVRTMat4 RotationMatrix, RotateX, RotateY;

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

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

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

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

	// Setup the vase rotation

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

	RotationMatrix = RotateY * RotateX;

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

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

	// Draw the scene

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


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

	// Enable depth test
	glEnable(GL_DEPTH_TEST);

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

	// Draw glass
	glEnable(GL_BLEND);

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

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

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

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

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

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

	// Display info text
	m_Print3D.DisplayDefaultTitle("Vase", "Translucency and reflections.", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();
	return true;
}
示例#14
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;
}
/*!****************************************************************************
 @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;
}
示例#16
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES3IntroducingPOD::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

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

	if(m_ulTimePrev > ulTime)
		m_ulTimePrev = ulTime;

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

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

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

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

	// Setup the camera

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

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

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

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

	/*
		A scene is composed of nodes. There are 3 types of nodes:
		- MeshNodes :
			references a mesh in the pMesh[].
			These nodes are at the beginning of the pNode[] array.
			And there are nNumMeshNode number of them.
			This way the .pod format can instantiate several times the same mesh
			with different attributes.
		- lights
		- cameras
		To draw a scene, you must go through all the MeshNodes and draw the referenced meshes.
	*/
	for (unsigned int i = 0; i < m_Scene.nNumMeshNode; ++i)
	{
		SPODNode& Node = m_Scene.pNode[i];

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

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

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

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

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

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

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

		glBindTexture(GL_TEXTURE_2D, uiTex);

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

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

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

	// Binds the loaded texture
	glBindTexture(GL_TEXTURE_2D, m_uiTexture);

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

	/*
		Creates the Model View Projection (MVP) matrix using the PVRTMat4 class from the tools.
		The tools contain a complete set of functions to operate on 4x4 matrices.
	*/
	PVRTMat4 mMVP = PVRTMat4::Identity();

	if(PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen)) // If the screen is rotated
		mMVP = PVRTMat4::RotationZ(-1.57f);

	/*
		Pass this matrix to the shader.
		The .m field of a PVRTMat4 contains the array of float used to
		communicate with OpenGL ES.
	*/
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mMVP.ptr());

	/*
		Draw a triangle.
		Please refer to the training course IntroducingPVRShell for a detailed explanation.
	*/

	// Bind the VBO
	glBindBuffer(GL_ARRAY_BUFFER, m_ui32Vbo);

	// Pass the vertex data
	glEnableVertexAttribArray(VERTEX_ARRAY);
	glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, m_ui32VertexStride, 0);

	// Pass the texture coordinates data
	glEnableVertexAttribArray(TEXCOORD_ARRAY);
	glVertexAttribPointer(TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, m_ui32VertexStride, (void*) (sizeof(GLfloat) * 3) /* Uvs start after the position */);

	// Draws a non-indexed triangle array
	glDrawArrays(GL_TRIANGLES, 0, 3);

	/*
		Display some text.
		Print3D() function allows to draw text anywhere on the screen using any color.
		Param 1: Position of the text along X (from 0 to 100 scale independent)
		Param 2: Position of the text along Y (from 0 to 100 scale independent)
		Param 3: Scale of the text
		Param 4: Colour of the text (0xAABBGGRR format)
		Param 5: Formated string (uses the same syntax as printf)
	*/
	m_Print3D.Print3D(8.0f, 30.0f, 1.0f, 0xFFAA4040, "example");

	/*
		DisplayDefaultTitle() writes a title and description text on the top left of the screen.
		It can also display the PVR logo (ePVRTPrint3DLogoPVR), the IMG logo (ePVRTPrint3DLogoIMG) or both (ePVRTPrint3DLogoPVR | ePVRTPrint3DLogoIMG).
		Set this last parameter to NULL not to display the logos.
	*/
	m_Print3D.DisplayDefaultTitle("IntroducingPVRTools", "Description", ePVRTPrint3DLogoIMG);

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

	return true;
}
示例#19
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 OGLESFur::RenderScene()
{
	// Reset the states that print3D changes
	glDisable(GL_CULL_FACE);
	glEnable(GL_FOG);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);
	glEnable(GL_DEPTH_TEST);

	//	User input
	bool bNewPage = false;

	if(PVRShellIsKeyPressed(PVRShellKeyNameSELECT))
		m_bPause = !m_bPause;

	if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		if(--m_i32WndPage < 0)
			m_i32WndPage = 5;

		bNewPage = true;
	}

	if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		if(++m_i32WndPage > 5)
			m_i32WndPage = 0;

		bNewPage = true;
	}

	if(bNewPage)
	{
		switch(m_i32WndPage)
		{
			case 0:
				m_bViewMode = false;
				m_i32FurShellNo = 7;
				break;
			case 1:
				m_bViewMode = true;
				m_i32FurShellNo = 0;
				break;
			case 2:
				m_bViewMode = true;
				m_i32FurShellNo = 1;
				break;
			case 3:
				m_bViewMode = true;
				m_i32FurShellNo = 2;
				break;
			case 4:
				m_bViewMode = true;
				m_i32FurShellNo = 7;
				break;
			case 5:
				m_bViewMode = false;
				m_i32FurShellNo = 7;
				break;
		}

		// Since the number of fur shells has changed, update them
		UpdateFurShells();
	}

	// Clear
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Animation
	DoAnimation();

	// View matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadMatrixf(m_mView.f);

	// Enable the vertex and normal arrays
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	// Begin Scene
	if(!m_bViewMode)
		DrawEnvironment();

	// Draw the Duck
	DrawDuck();

	// Display Paused if the app is paused
	if(m_bPause)
		m_Print3D.Print3D(78.0f, 2.0f, 1.0f, PVRTRGBA(255,255,255,255), "Paused");

	// Disable the normals before our drawing of the print3D content
	glDisableClientState(GL_NORMAL_ARRAY);
	
	char szDesc[256];
	snprintf(szDesc, 256, "Displaying %d shells", m_i32FurShellNo);

	// Display the IMG logo
	m_Print3D.DisplayDefaultTitle("Fur", szDesc, ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();
	return true;
}
示例#20
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 OGLESCoverflow::RenderScene()
{
	// Clears the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	glDisable(GL_CULL_FACE);

	if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT)) //input permmanently set for demo purposes
		m_bGoRight = true;

	if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
		m_bGoRight = false;

	m_fLerpDir = m_bGoRight ? 1.0f : -1.0f;

	unsigned long ulTime = PVRShellGetTime();
	unsigned long ulDeltaTime = ulTime - m_ulTimePrev;
	m_ulTimePrev = ulTime;

	m_fLerp += (ulDeltaTime*.0001f)*m_fCyclesPerSecond*m_fLerpDir;

	if(m_fLerpDir && (m_fLerp >= 1.0 || m_fLerp <= -1.0))
	{
		if(m_fLerpDir < 0)
		{
			m_iCoverIndex++;
			if(m_iCoverIndex > g_i32CoverNo)
				m_iCoverIndex = 1;
		}
		else
		{
			m_iCoverIndex--;
			if(m_iCoverIndex < 0)
				m_iCoverIndex = g_i32CoverNo-1;
		}
		m_fLerpDir = 0.f;
		m_fLerp = 0;
	}

	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
	glEnableClientState(GL_COLOR_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	//the order in which the covers are drawn is very important for the transparency here. As the covers flip from
	//one position to the next there is a point in the cycle where the center cover moves from being in front of the
	//position following it to behind it. The draw order needs to reflect this so that the blend is still drawn correctly.
	if(m_fLerp < -0.5)
	{
		DrawLeftCovers();
		DrawInPosition(eFront, m_fLerp, m_iCoverIndex);
		DrawRightCovers();
	}
	else if(m_fLerp >  0.5)
	{
		DrawRightCovers();
		DrawInPosition(eFront, m_fLerp, m_iCoverIndex);
		DrawLeftCovers();
	}
	else
	{
		DrawRightCovers();
		DrawLeftCovers();
		DrawInPosition(eFront, m_fLerp, m_iCoverIndex);
	}

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

	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	glDisableClientState(GL_NORMAL_ARRAY);
	glDisableClientState(GL_COLOR_ARRAY);

	m_Print3D.DisplayDefaultTitle("Coverflow", "", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();

	return true;
}
示例#21
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES3ShadowVolumes::RenderScene()
{
	//Calculate the time passes since the last frame so we can rotate the cogs in a time-based manner
	unsigned long ulTime = PVRShellGetTime();
	unsigned long ulDeltaTime = ulTime - m_ulTimePrev;

	m_ulTimePrev = ulTime;

    // If the cog is classed as dynamic then we need to update its angle of rotation
	if(m_i32ObjectType[eBigCog] == eDynamicObject)
	{
		m_fBigCogAngle   += ulDeltaTime * 0.001f;

		while(m_fBigCogAngle > PVRT_TWO_PI)
			m_fBigCogAngle -= PVRT_TWO_PI;
	}

	if(m_i32ObjectType[eSmallCog] == eDynamicObject)
	{
		m_fSmallCogAngle -= ulDeltaTime * 0.004f;

		while(m_fSmallCogAngle > PVRT_TWO_PI)
			m_fSmallCogAngle -= PVRT_TWO_PI;
	}

	// If the action key has been pressed then switch between drawing and not drawing the shadow volumes
	if (PVRShellIsKeyPressed(PVRShellKeyNameACTION1))
		m_bDisplayVolumes = !m_bDisplayVolumes;

	// Clear the colour, stencil and depth buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	/*
		To create shadows we are going to do the following steps

		1) Using the tools we are going to update any of the shadow volumes for the dynamic objects
		2) Draw the scene as we would any other.
		3) Enable the stencil test.
		4) Draw Shadow Volumes to fill the stencil buffer with data.
		5) Then we are going to draw a fullscreen quad which will only appear where the stencil buffer is not zero.
		6) Disable the stencil test
	*/

	/*
		Update the shadow volumes for any dynamic objects as they have moved so we requrie a different
		shadow volume. If the light position was also dynamic we would have to update volumes for all
		the static objects as well.
	*/

	for(unsigned int i = 0; i < m_ui32NoOfShadows; ++i)
	{
		if(m_i32ObjectType[m_pui32MeshIndex[i]] == eDynamicObject)
		{
			BuildVolume(i, &m_vLightPosWorld);
		}
	}

	// Draw the scene lit.
	DrawScene();

	// Enable the stencil test
	glEnable(GL_STENCIL_TEST);

	// Do the stencil test
	DoStencilTest();

	// Draw a full screen quad
	DrawFullScreenQuad();

	// Disable the stencil test as it is no longer needed.
	glDisable(GL_STENCIL_TEST);

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

	return true;
}
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES2ChameleonMan::RenderScene()
{
	// Clear the color and depth buffer
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

	if(PVRShellIsKeyPressed(PVRShellKeyNameACTION1))
	{
		m_bEnableDOT3 = !m_bEnableDOT3;
		glUniform1i(m_SkinnedShaderProgram.auiLoc[ebUseDot3], m_bEnableDOT3);
	}

	/*
		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(iTime > m_iTimePrev)
	{
		float fDelta = (float) (iTime - m_iTimePrev);
		m_fFrame += fDelta * g_fDemoFrameRate;

		// Increment the counters to make sure our animation works
		m_fLightPos	+= fDelta * 0.0034f;
		m_fWallPos	+= fDelta * 0.00027f;
		m_fBackgroundPos += fDelta * -0.000027f;

		// Wrap the Animation back to the Start
		if(m_fLightPos >= PVRT_TWO_PI)
			m_fLightPos -= PVRT_TWO_PI;

		if(m_fWallPos >= PVRT_TWO_PI)
			m_fWallPos -= PVRT_TWO_PI;

		if(m_fBackgroundPos <= 0)
			m_fBackgroundPos += 1.0f;

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

	m_iTimePrev	= iTime;

	// Set the scene animation to the current frame
	m_Scene.SetFrame(m_fFrame);

	// Set up camera
	PVRTVec3	vFrom, vTo, vUp(0.0f, 1.0f, 0.0f);
	PVRTMat4 mView, mProjection;
	PVRTVec3	LightPos;
	float fFOV;
	int i;

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

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

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

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

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

	// Update Light Position and related VGP Program constant
	LightPos.x = 200.0f;
	LightPos.y = 350.0f;
	LightPos.z = 200.0f * PVRTABS(sin((PVRT_PI / 4.0f) + m_fLightPos));

	glUniform3fv(m_SkinnedShaderProgram.auiLoc[eLightPos], 1, LightPos.ptr());

	// Set up the View * Projection Matrix
	PVRTMat4 mViewProjection;

	mViewProjection = mProjection * mView;
	glUniformMatrix4fv(m_SkinnedShaderProgram.auiLoc[eViewProj], 1, GL_FALSE, mViewProjection.ptr());

	// Enable the vertex attribute arrays
	for(i = 0; i < eNumAttribs; ++i) glEnableVertexAttribArray(i);

	// Draw skinned meshes
	for(unsigned int i32NodeIndex = 0; i32NodeIndex < 3; ++i32NodeIndex)
	{
		// Bind correct texture
		switch(i32NodeIndex)
		{
			case eBody:
				glActiveTexture(GL_TEXTURE1);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexHeadNormalMap);
				glActiveTexture(GL_TEXTURE0);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexHeadBody);
				break;
			case eLegs:
				glActiveTexture(GL_TEXTURE1);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexLegsNormalMap);
				glActiveTexture(GL_TEXTURE0);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexLegs);
				break;
			default:
				glActiveTexture(GL_TEXTURE1);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexBeltNormalMap);
				glActiveTexture(GL_TEXTURE0);
				glBindTexture(GL_TEXTURE_2D, m_ui32TexBelt);
				break;
		}

		DrawSkinnedMesh(i32NodeIndex);
	}

	// Safely disable the vertex attribute arrays
	for(i = 0; i < eNumAttribs; ++i) glDisableVertexAttribArray(i);

	// Draw non-skinned meshes
	glUseProgram(m_DefaultShaderProgram.uiId);

	// Enable the vertex attribute arrays
	for(i = 0; i < eNumDefaultAttribs; ++i) glEnableVertexAttribArray(i);

	for(unsigned int i32NodeIndex = 3; i32NodeIndex < m_Scene.nNumMeshNode; ++i32NodeIndex)
	{
		SPODNode& Node = m_Scene.pNode[i32NodeIndex];
		SPODMesh& Mesh = m_Scene.pMesh[Node.nIdx];

		// bind the VBO for the mesh
		glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[Node.nIdx]);

		// bind the index buffer, won't hurt if the handle is 0
		glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[Node.nIdx]);

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

		// Setup the appropriate texture and transformation (if needed)
		switch(i32NodeIndex)
		{
			case eWall:
				glBindTexture(GL_TEXTURE_2D, m_ui32TexWall);

				// Rotate the wall mesh which is circular
				mWorld *= PVRTMat4::RotationY(m_fWallPos);

				glUniform1f(m_DefaultShaderProgram.auiLoc[eDefaultUOffset], 0);

				break;
			case eBackground:
				glBindTexture(GL_TEXTURE_2D, m_ui32TexSkyLine);

				glUniform1f(m_DefaultShaderProgram.auiLoc[eDefaultUOffset], m_fBackgroundPos);
				break;
			case eLights:
				{
					glBindTexture(GL_TEXTURE_2D, m_ui32TexLamp);

					PVRTMat4 mWallWorld = m_Scene.GetWorldMatrix(m_Scene.pNode[eWall]);
					mWorld = mWallWorld * PVRTMat4::RotationY(m_fWallPos) * mWallWorld.inverse() * mWorld;

					glUniform1f(m_DefaultShaderProgram.auiLoc[eDefaultUOffset], 0);
				}
				break;
			default:
			break;
		};

		// Set up shader uniforms
		PVRTMat4 mModelViewProj;
		mModelViewProj = mViewProjection * mWorld;
		glUniformMatrix4fv(m_DefaultShaderProgram.auiLoc[eDefaultMVPMatrix], 1, GL_FALSE, mModelViewProj.ptr());

		// Set the vertex attribute offsets
		glVertexAttribPointer(DEFAULT_VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, Mesh.sVertex.nStride,  Mesh.sVertex.pData);
		glVertexAttribPointer(DEFAULT_TEXCOORD_ARRAY, 2, GL_FLOAT, GL_FALSE, Mesh.psUVW[0].nStride, Mesh.psUVW[0].pData);

		// Indexed Triangle list
		glDrawElements(GL_TRIANGLES, Mesh.nNumFaces*3, GL_UNSIGNED_SHORT, 0);
	}

	// Safely disable the vertex attribute arrays
	for(i = 0; i < eNumAttribs; ++i) glDisableVertexAttribArray(i);

	// unbind the VBOs
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

	// Display the demo name using the tools. For a detailed explanation, see the training course IntroducingPVRTools
	const char * pDescription;

	if(m_bEnableDOT3)
		pDescription = "Skinning with DOT3 Per Pixel Lighting";
	else
		pDescription = "Skinning with Vertex Lighting";

	m_Print3D.DisplayDefaultTitle("Chameleon Man", pDescription, 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;
}
/*!****************************************************************************
 @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 OGLES2StencilBuffer::RenderScene()
{
	m_fAngle += 0.005f;

	// Clear the color, depth and stencil buffers
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

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

	/*
		Set up the transformation matrices for our two shapes (the cylinder and the sphere)
	*/
	PVRTMat4 mSphere, mCylinder;
	PVRTMat4 mTrans, mRotZ, mRotX, mScale;

	mScale = PVRTMat4::Scale((float)PVRShellGet(prefHeight)/(float)PVRShellGet(prefWidth), 1.0f, 1.0f);
	mRotZ  = PVRTMat4::RotationX(m_fAngle);

	mSphere = mRotZ * mScale;

	mTrans = PVRTMat4::Translation(-0.4f, -0.5f, 0.0f);
	mRotZ  = PVRTMat4::RotationZ(m_fAngle);
	mRotX  = PVRTMat4::RotationX(m_fAngle);

	mCylinder = mScale * mRotX * mRotZ * mTrans;

	// Bind texture and set transform
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiStoneTex);
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mSphere.ptr());

	// Set culling to cull the back faces
	glCullFace(GL_BACK);

	/*
		Draw the sphere

		This sphere is textured with the stone texture and will be visible outside the stencil volume as
		we are drawing a second sphere with a green tiles texture everywhere within the stencil
		geometry.

		Also this sphere is used to set the depth values in the Z-Buffer.
	*/
	m_Sphere.DrawMesh(0);


	/*
		Enable the stencil test, disable color and depth writes
	*/
	glEnable(GL_STENCIL_TEST);
	glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
	glDepthMask(GL_FALSE);

	/*
		What we are going to do is draw a volume (a cylinder) so that all front faces that are in front of
		the already rendered geometry (the sphere) increase the stencil value by one, while all back faces
		that are in front of the rendered geometry decrease the stencil value. This way only surfaces that
		intersect the stencil volume will get a stencil value != 0.

		Since OpenGL ES 2.0 offers two-sided stencil, we can do this in a single pass.
	*/
	// Disable culling as we want to use the back and front faces of the geometry.
	glDisable(GL_CULL_FACE);

	/*
		glStencilFunc tells OGLES2 the type of per-pixel test that we want to do. In the case below GL_ALWAYS says we
		want the test to always pass. The third value is the mask value which is ANDed with the second value
		(the reference value) to create the value that is put in the stencil buffer.

		Alternative values for the first value are

		GL_NEVER which causes the test to never pass.
		GL_LESS	    Passes if (	ref & mask ) < ( stencil & mask ).
		GL_LEQUAL	Passes if (	ref & mask ) < ( stencil & mask ).
		GL_GREATER	Passes if (	ref & mask ) > ( stencil & mask ).
		GL_GEQUAL	Passes if (	ref & mask ) > ( stencil & mask ).
		GL_EQUAL	Passes if (	ref & mask ) = ( stencil & mask ).
		GL_NOTEQUAL	Passes if (	ref & mask ) / ( stencil & mask ).

		A call to glStencilFunc is the same as calling glStencilFuncSeparate with GL_FRONT_AND_BACK
	*/
	glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);

	/*
		glStencilOp has 3 parameters. The first parameter specifies the action to take if the
		stencil test fails. The second specifies the stencil action to take if the stencil test passes
		but the depth test fails. The third one specifies the stencil action when the stencil test and
		the depth test pass, or when the stencil test passes and their is no depth testing done.

		These three parameters can be set to one of the following

		GL_KEEP Keeps the current value.
		GL_ZERO Sets the stencil buffer value to zero.
		GL_REPLACE Sets the stencil buffer value to ref, as specified by glStencilFunc.
		GL_INCR Increments the current stencil buffer value. Clamps to the maximum representable unsigned value.
		GL_DECR Decrements the current stencil buffer value. Clamps to zero.
		GL_INCR_WRAP Increments the current stencil buffer value and wraps round to zero if the value is above the maximum.
		GL_DECR_WRAP Decrements the current stencil buffer value and wraps it round to the maximum if it goes below zero.
		GL_INVERT	Bitwise inverts the current stencil buffer value.

		We're going to do our stencil operations in one pass so we need to specify an operation for each face type
		using the glStencilOpSeparate function which takes an extra variable. This variable will define
		which face type we'll work on and it can be set to

		GL_FRONT
		GL_BACK
		GL_FRONT_AND_BACK

		In our case we are going to use GL_INCR_WRAP for the front faces and GL_DECR_WRAP for the back faces.
		As the geometry will be processed in the order it is submitted we can't guarantee that we'll do all
		the INCR operations first therefore we are using INCR_WRAP and DECR_WRAP so the values don't get clamped
		at the minimum and maximum possible values.
	*/
	glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_INCR_WRAP);
	glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_DECR_WRAP);

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

	m_Cylinder.DrawMesh(0);


	/*
		Enable drawing to the colour buffer again as what we draw now we want to be visible.
		Switch back to back face culling and enable the depth test again.
	*/
	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	glDepthMask(GL_TRUE);
	glEnable(GL_CULL_FACE);
	glCullFace(GL_BACK);

	/*
		Set the stencil test to draw only pixels that are inside the stencil volume
	*/
	glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

	glBindTexture(GL_TEXTURE_2D, m_uiTileTex);
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mSphere.ptr());

	m_Sphere.DrawMesh(0);

	/* Disable the stencil test as it is no longer needed.*/
	glDisable(GL_STENCIL_TEST);

	/*
		Draw the cylinder with alpha blending, back faces first then front faces
	*/
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glBindTexture(GL_TEXTURE_2D, m_uiCylinderTex);
	glUniformMatrix4fv(m_ShaderProgram.auiLoc[eMVPMatrix], 1, GL_FALSE, mCylinder.ptr());

	// Draw back faces of the cylinder
	glCullFace(GL_FRONT);
	m_Cylinder.DrawMesh(0);

	// Draw the front faces
	glCullFace(GL_BACK);
	m_Cylinder.DrawMesh(0);

	// Disable blending as it is no longer required
	glDisable(GL_BLEND);

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

	return true;
}
示例#25
0
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occurred
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevant OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool OGLES3Skybox2::RenderScene()
{
	unsigned int i, j;

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

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

	unsigned long iTime = PVRShellGetTime();

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

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

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

	m_iTimePrev	= iTime;

	/* KeyBoard input processing */

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

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

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

		fDemoFrame = 0.0f;
		fBurnAnim  = 0.0f;
	}

	/* Change Shader Effect */

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

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

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

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

		fBurnAnim = 0.0f;
	}

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

		fBurnAnim = 0.0f;
	}

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

	glDisable(GL_CULL_FACE);

	DrawSkybox();

	glEnable(GL_CULL_FACE);

	m_ppEffects[m_i32Effect]->Activate();

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

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

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

		mWORLDVIEW = m_mView * mWorld;

		glBindBuffer(GL_ARRAY_BUFFER, m_aiVboID[i]);

		const CPVRTArray<SPVRTPFXUniform>& Uniforms = m_ppEffects[m_i32Effect]->GetUniformArray();
		for(j = 0; j < Uniforms.GetSize(); ++j)
		{
			switch(Uniforms[j].nSemantic)
			{
				case ePVRTPFX_UsPOSITION:
				{
					glVertexAttribPointer(Uniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sVertex.nStride, pMesh->sVertex.pData);
					glEnableVertexAttribArray(Uniforms[j].nLocation);
				}
				break;
				case ePVRTPFX_UsNORMAL:
				{
					glVertexAttribPointer(Uniforms[j].nLocation, 3, GL_FLOAT, GL_FALSE, pMesh->sNormals.nStride, pMesh->sNormals.pData);
					glEnableVertexAttribArray(Uniforms[j].nLocation);
				}
				break;
				case ePVRTPFX_UsUV:
				{
					glVertexAttribPointer(Uniforms[j].nLocation, 2, GL_FLOAT, GL_FALSE, pMesh->psUVW[0].nStride, pMesh->psUVW[0].pData);
					glEnableVertexAttribArray(Uniforms[j].nLocation);
				}
				break;
				case ePVRTPFX_UsWORLDVIEWPROJECTION:
				{
					PVRTMat4 mMVP;

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

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

					PVRTMat3 WORLDVIEWIT = PVRTMat3(mWORLDVIEWIT);

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

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

					PVRTMat3 ViewIT = PVRTMat3(mViewIT);

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

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

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

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

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

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

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

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

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

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

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

			glUniform1i(location, 1);

			DrawMesh(pMesh);

			glUniform1i(location, 0);

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

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

			glDisable(GL_BLEND);
		}

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

		glBindBuffer(GL_ARRAY_BUFFER, 0);

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

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

	m_Print3D.Flush();

	return true;
}
示例#26
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;
}
/*!****************************************************************************
 @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;
}
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important and relevant OS events.
				The user has access to these events through an abstraction
				layer provided by PVRShell.
******************************************************************************/
bool OGLES3EdgeDetection::RenderScene()
{
	// Declares world orientation variables.
	PVRTMat4 mWorld, mMVP;

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

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

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

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

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

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

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

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

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

		// Enable vertex attribute array
		glEnableVertexAttribArray(eVERTEX_ARRAY);

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

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

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

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

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

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

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

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

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

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

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

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

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

	return true;
}
/*******************************************************************************
 * Function Name  : RenderScene
 * Returns		  : true if no error occured
 * Description    : Main rendering loop function of the program. The shell will
 *					call this function every frame.
 *******************************************************************************/
bool OGLESSkinning::RenderScene()
{
	// Increase the frame number
	m_fFrame += 0.3f;

	while(m_fFrame > m_Scene.nNumFrame-1)
		m_fFrame -= m_Scene.nNumFrame-1;

	// Modify the transformation matrix if it is needed
	bool bRebuildTransformation = false;

	if(PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_fAngle -= 0.03f;

		if(m_fAngle < PVRT_TWO_PIf)
			m_fAngle += PVRT_TWO_PIf;

		bRebuildTransformation = true;
	}

	if(PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_fAngle += 0.03f;

		if(m_fAngle > PVRT_TWO_PIf)
			m_fAngle -= PVRT_TWO_PIf;

		bRebuildTransformation = true;
	}

	if(PVRShellIsKeyPressed(PVRShellKeyNameUP))
	{
		m_fDistance -= 10.0f;

		if(m_fDistance < -500.0f)
			m_fDistance = -500.0f;

		bRebuildTransformation = true;
	}

	if(PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
	{
		m_fDistance += 10.0f;

		if(m_fDistance > 200.0f)
			m_fDistance = 200.0f;

		bRebuildTransformation = true;
	}

	if(bRebuildTransformation)
		m_mTransform = PVRTMat4::Translation(0,0, m_fDistance) * PVRTMat4::RotationY(m_fAngle);

	// Clear the depth and frame buffer
	glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Set Z compare properties
	glEnable(GL_DEPTH_TEST);

	// Disable Blending
	glDisable(GL_BLEND);

	// Calculate the model view matrix
	glMatrixMode(GL_MODELVIEW);
	glLoadMatrixf(m_mView.f);

	// Draw the model
	DrawModel();

	// Print text on screen
	m_Print3D.DisplayDefaultTitle("Skinning", "", ePVRTPrint3DSDKLogo);

	// Flush all Print3D commands
	m_Print3D.Flush();

	return true;
}
/*!****************************************************************************
 @Function		RenderScene
 @Return		bool		true if no error occured
 @Description	Main rendering loop function of the program. The shell will
				call this function every frame.
				eglSwapBuffers() will be performed by PVRShell automatically.
				PVRShell will also manage important OS events.
				Will also manage relevent OS events. The user has access to
				these events through an abstraction layer provided by PVRShell.
******************************************************************************/
bool 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;
}