/*!****************************************************************************
 @Function		RenderLoadingScene
 @Input			iFrame
 @Description	Renders an animated loading screen.
******************************************************************************/
void OGLES2MultiThreading::RenderLoadingScene(int iFrame)
{
    bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
    float fHW      = PVRShellGet(prefWidth) / 2.0f;
    float fHH      = PVRShellGet(prefHeight) / 2.0f;

    PVRTMat4 mxProjection = PVRTMat4::Ortho(-fHW, fHH, fHW, -fHH, -1.0f, 1.0f, PVRTMat4::OGL, bRotate);

    /*
        Clears the color buffer.
    */
    glClear(GL_COLOR_BUFFER_BIT);
    
    // Actually use the created program
    glUseProgram(handles.uiLoadProgram);
    
    // First gets the location of that variable in the shader using its name
    int i32MVPLocation = glGetUniformLocation(handles.uiLoadProgram, "myPMVMatrix");
    int i32ColLocation = glGetUniformLocation(handles.uiLoadProgram, "myCol");

    for(int iCircleIdx = 0; iCircleIdx < c_iNumCircles; ++iCircleIdx)
    {
        int iProg    = iFrame+iCircleIdx*4;
        float fScale = (0.75f + cos(iProg * 0.1f) * 0.25f);
        float fY     = sin(iProg * 0.1f) * 25.0f;
        
        // Then passes the matrix to that variable
        PVRTMat4 mxMVP = mxProjection * PVRTMat4::Translation(-175.0f + iCircleIdx * 50.0f, fY, 0.0f) * PVRTMat4::Scale(fScale,fScale,1.0f);
        glUniformMatrix4fv(i32MVPLocation, 1, GL_FALSE, mxMVP.ptr());
        
        // Pass the colour
        glUniform3f(i32ColLocation, c_vCircleCols[iCircleIdx].x, c_vCircleCols[iCircleIdx].y, c_vCircleCols[iCircleIdx].z);

        // Draw the loading circle
        glBindBuffer(GL_ARRAY_BUFFER, handles.uiLoadVbo);
        glEnableVertexAttribArray(VERTEX_ARRAY);
        glVertexAttribPointer(VERTEX_ARRAY, 3, GL_FLOAT, GL_FALSE, 0, 0);
        
        // Submit
        glDrawArrays(GL_TRIANGLE_FAN, 0, c_iNumCirclePoints+2);
        
        glDisableVertexAttribArray(VERTEX_ARRAY);
        glBindBuffer(GL_ARRAY_BUFFER, 0);   
    }
            
    float fW;
    loadingText.SetProjection(mxProjection);
    
    ELoadingProgress eProgress = eProgress_Init;
    EnterCriticalSection(&handles.mutex);
        eProgress = g_eProgress;
    LeaveCriticalSection(&handles.mutex);
    
    loadingText.MeasureText(&fW, NULL, 1.0f, c_pszLoadingProgress[eProgress]);
    loadingText.Print3D(-fW*0.5f, -50.0f, 1.0f, 0xFFFFFFFF, c_pszLoadingProgress[eProgress]);
    loadingText.Flush();
}
示例#2
0
/*!***************************************************************************
@Function		RenderTitle
@Input			fFadeAmount
@Description	Draws the title text.
*****************************************************************************/
void OGLES2IntroducingPrint3D::RenderTitle(float fFadeAmount)
{
	unsigned int uiCol = (((unsigned int)(fFadeAmount * 255)) << 24) | 0x00FFFF;

	float fW = PVRShellGet(prefWidth) * 0.5f;
	float fH = PVRShellGet(prefHeight) * 0.5f;
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

	/*
		Print3D can optionally be provided with user-defined projection and modelview matrices
		which allow custom layout of text. Here we are just providing a projection matrix
		so that text can be placed in viewport coordinates, rather than the default, more 
		abstract coordinate system of 0.0-100.0.
	*/
	PVRTMat4 mProjection = PVRTMat4::Ortho(-fW, fH, fW, -fH, -1.0f, 1.0f, PVRTMat4::OGL, bRotate);
	m_IntroText.SetProjection(mProjection);

	/*
		Using the MeasureText() method provided by Print3D, we can determine the bounding-box
		size of a string of text. This can be useful for justify text centrally, as we are
		doing here.
	*/
	float fLine1W = 0.0f;
	float fLine2W = 0.0f;
	m_IntroText.MeasureText(&fLine1W, NULL, 1.0f, "introducing");
	m_IntroText.MeasureText(&fLine2W, NULL, 1.0f, "print3d");

	/*
		Display some text.
		Print3D() function allows to draw text anywhere on the screen using any colour.
		Param 1: Position of the text along X
		Param 2: Position of the text along Y
		Param 3: Scale of the text
		Param 4: Colour of the text (0xAABBGGRR format)
		Param 5: Formatted string (uses the same syntax as printf)
		...
	*/
	m_IntroText.Print3D(-fLine1W*0.5f, 50.0f, 1.0f, uiCol, "introducing");
	m_IntroText.Print3D(-fLine2W*0.5f, 0.0f,   1.0f, uiCol, "print3d");

	// Tells Print3D to do all the pending text rendering now
	m_IntroText.Flush();
}
示例#3
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;
}
示例#4
0
/*!***************************************************************************
@Function		RenderText
@Description	Draws the 3D text and scrolls in to the screen.
*****************************************************************************/
void OGLES2IntroducingPrint3D::RenderText()
{
	float fAspect = (float)PVRShellGet(prefWidth) / (float)PVRShellGet(prefHeight);
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

	// Calculate the frame delta.
	unsigned long ulNow = PVRShellGetTime();
	if(m_ulPrevFrameT == 0)	m_ulPrevFrameT = ulNow;
	float fDT = (ulNow - m_ulPrevFrameT) * 0.001f;
	m_ulPrevFrameT = ulNow;
		
	// Calculate the FPS scale.
	float fFPSScale = fDT / c_fTargetFPS;
		
	// Move the text. Progressively speed up.
	float fSpeedInc = 0.0f;
	if(m_fTextOffset > 0.0f)
		fSpeedInc = m_fTextOffset / TEXT_END_Y;
	m_fTextOffset += (0.75f + (1.0f * fSpeedInc)) * fFPSScale;
	if(m_fTextOffset > TEXT_END_Y)
		m_fTextOffset = TEXT_START_Y;

	PVRTMat4 mProjection = PVRTMat4::PerspectiveFovRH(0.7f, fAspect, 1.0f, 2000.0f, PVRTMat4::OGL, bRotate);
	PVRTMat4 mScale      = PVRTMat4::Scale(PVRTVec3(1.0f, -1.0f, 1.0f)); 
	PVRTMat4 mCamera     = PVRTMat4::LookAtRH(PVRTVec3(0.0f, -900.0f, 700.0f), PVRTVec3(0.0f,-200.0f,0.0f), PVRTVec3(0.0f,1.0f,0.0f));
	PVRTMat4 mTrans		 = PVRTMat4::Translation(PVRTVec3(0.0f, m_fTextOffset, 0.0f));
	PVRTMat4 mModelView  = mCamera * mTrans;
	float fStrWidth = 0.0f;

	/*
		Print3D can optionally be provided with user-defined projection and model-view matrices
		which allow custom layout of text. Here we are proving both a projection and model-view
		matrix. The projection matrix specified here uses perspective projection which will
		provide the 3D effect. The model-view matrix positions the the text in world space
		providing the 'camera' position and the scrolling of the text.
	*/
	m_CentralText.SetProjection(mProjection);
	m_CentralText.SetModelView(mModelView);

	/*
		The previous method (RenderTitle()) explains the following functions in more detail
		however put simply, we are looping the entire array of loaded text which is encoded
		in UTF-8. Print3D batches this internally and the call to Flush() will render the
		text to the frame buffer. We are also fading out the text over a certain distance.
	*/
	float fPos, fFade;
	unsigned int uiCol;
	for(unsigned int uiIndex = 0; uiIndex < m_TextLines.GetSize(); ++uiIndex)
	{
		fPos = (m_fTextOffset - (uiIndex * 36.0f));
		fFade = 1.0f;
		if(fPos > TEXT_FADE_START)
		{
			fFade = PVRTClamp(1.0f - ((fPos - TEXT_FADE_START) / (TEXT_FADE_END - TEXT_FADE_START)), 0.0f, 1.0f);
		}

		uiCol = (((unsigned int)(fFade * 255)) << 24) | 0x00FFFF;

		m_CentralText.MeasureText(&fStrWidth, NULL, 1.0f, (const char*)m_TextLines[uiIndex]);
		m_CentralText.Print3D(-(fStrWidth*0.5f), -(uiIndex * 36.0f), 1.0f, uiCol, (const char*)m_TextLines[uiIndex]);
	}

	m_CentralText.Flush();
}