/*!****************************************************************************
 @Function		LoadTextures
 @Output		pErrorStr		A string describing the error on failure
 @Return		bool			true if no error occured
 @Description	Loads the textures required for this training course
 ******************************************************************************/
bool OGLES3TextureStreaming::LoadTextures(CPVRTString* pErrorStr)
{
	/*
	 Loads the textures.
	 For a more detailed explanation, see Texturing and IntroducingPVRTools
	 */

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

	if(!m_puiTextureIDs)
	{
		*pErrorStr = "ERROR: Insufficient memory.\n";
		return false;
	}

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

		if(strcmp(pMaterial->pszName, "ScreenMat") == 0)
			m_uiTVScreen = i;
		else if(strcmp(pMaterial->pszName, "RecordGlow") == 0)
			m_uiRecordGlow = i;

		if(pMaterial->nIdxTexDiffuse != -1)
		{
			/*
			 Using the tools function PVRTTextureLoadFromPVR load the textures required by the pod file.

			 Note: This function only loads .pvr files. You can set the textures in 3D Studio Max to .pvr
			 files using the PVRTexTool plug-in for max. Alternatively, the pod material properties can be
			 modified in PVRShaman.
			 */

			const char* pszTexFile = m_Scene.pTexture[pMaterial->nIdxTexDiffuse].pszName;

			if(PVRTTextureLoadFromPVR(pszTexFile, &m_puiTextureIDs[i]) != PVR_SUCCESS)
			{
				*pErrorStr += PVRTStringFromFormattedStr("ERROR: Failed to load %s\n", pszTexFile);
				return false;
			}
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

		}
	}

	// Load random texture
	if(PVRTTextureLoadFromPVR(c_pszNoiseTexFile, &m_uiNoiseTex) != PVR_SUCCESS)
	{
		*pErrorStr += "ERROR: Failed to load noise texture.\n";
		return false;
	}
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	return true;
}
Example #2
0
/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no error occurred
 @Description	Code in InitView() will be called by PVRShell upon
				initialization or after a change in the rendering context.
				Used to initialize variables that are dependant on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLES2Shaders::InitView()
{
	// Is the screen rotated
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

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

	glClearColor(0.6f, 0.8f, 1.0f, 1.0f);

	m_mProjection = PVRTMat4::PerspectiveFovRH(PVRT_PI/6, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), CAM_NEAR, CAM_FAR, PVRTMat4::OGL, bRotate);

	m_mView = PVRTMat4::Identity();

	/*
		Loads the textures.
	*/

	// Textures

	// Get pointer to the texture name
	CPVRTString ErrorStr;

	char *pTexture = 0;
	PVRTextureHeaderV3 Header;

	for(int i = 0; i < g_numTextures; ++i)
	{
		if(strcmp(g_TextureList[i], "base") == 0)
			pTexture = (char*) g_aszTextureNames[eTexBase];
		else if(strcmp(g_TextureList[i], "reflection") == 0)
			pTexture = (char*) g_aszTextureNames[eTexReflection];
		else if(strcmp(g_TextureList[i], "cubemap") == 0)
			pTexture = (char*) g_aszTextureNames[eTexCubeMap];
		else if(strcmp(g_TextureList[i], "anisotropicmap") == 0)
			pTexture = (char*) g_aszTextureNames[eTexAnisotropic];

		if(PVRTTextureLoadFromPVR(pTexture, &m_puiTextureHandle[i], &Header) != PVR_SUCCESS)
		{
			ErrorStr = CPVRTString("ERROR: Could not open texture file ") + pTexture;
			PVRShellSet(prefExitMessage, ErrorStr.c_str());
			return false;
		}

		// Get texture flags form the header
		m_uiTextureFlags[i] = (Header.u32NumFaces==6?PVRTEX_CUBEMAP:0) | (Header.u32MIPMapCount>1?PVRTEX_MIPMAP:0) | (Header.u32Depth>1?PVRTEX_VOLUME:0);
	}

	/*
		Load the effect file
	*/
	for(int j = 0; j < g_numShaders; j++)
	{
		CPVRTString		fileName;
		unsigned int	nUnknownUniformCount;
		CPVRTString error;

		/*
			Parse the file
		*/
		m_ppEffectParser[j] = new CPVRTPFXParser();
		fileName = CPVRTString(g_ShaderList[j]) + ".pfx";

		if(m_ppEffectParser[j]->ParseFromFile(fileName.c_str(), &error) != PVR_SUCCESS)
		{
			error = CPVRTString("Parse failed for ") + fileName + ":\n\n" + error;
			PVRShellSet(prefExitMessage, error.c_str());
			FreeMemory();
			return false;
		}

		/*
			Load the effect from the file
		*/
		error = "";
		m_ppEffect[j] = new CPVRTPFXEffect();
		if(m_ppEffect[j]->Load(*(m_ppEffectParser[j]), "myEffect", fileName.c_str(), NULL, nUnknownUniformCount, &error)  != PVR_SUCCESS)
		{
			PVRShellSet(prefExitMessage, error.c_str());
			FreeMemory();
			return false;
		}

		if(nUnknownUniformCount)
		{
			error = PVRTStringFromFormattedStr("PFX File: %s\n%s Unknown uniform semantic count: %d\n", fileName.c_str(), error.c_str(), nUnknownUniformCount);
			PVRShellSet(prefExitMessage, error.c_str());

			FreeMemory();
			return false;
		}
		if(!error.empty())
		{
			PVRShellOutputDebug(error.c_str());
		}

		/*
			Link the textrues to the effect.
		*/
		const CPVRTArray<SPVRTPFXTexture>& sTex = m_ppEffect[j]->GetTextureArray();

		// Loop over textures used in the CPVRTPFXEffect
		for(unsigned int i = 0; i < sTex.GetSize(); ++i)
		{
			int iTexIdx = m_ppEffectParser[j]->FindTextureByName(sTex[i].Name);
			const CPVRTStringHash& FileName = m_ppEffectParser[j]->GetTexture(iTexIdx)->FileName;

			int k;
			// Loop over available textures
			for( k = 0; k < g_numTextures; k++)
			{
				CPVRTString texName;
				texName =  CPVRTString(g_TextureList[k]) + ".pvr";
				if(FileName == texName)
				{
					// Set the current texture
					if((m_uiTextureFlags[k] & CUBEMAP_FLAG) != 0)
						glBindTexture(GL_TEXTURE_CUBE_MAP, m_puiTextureHandle[k]);
					else
						glBindTexture(GL_TEXTURE_2D, m_puiTextureHandle[k]);

					// Link the texture to the CPVRTPFXEffect and apply filtering
					m_ppEffect[j]->SetTexture(i, m_puiTextureHandle[k], m_uiTextureFlags[k]);

					break;
				}
			}
			if(k == g_numTextures)
			{
				// Texture not found
				PVRShellOutputDebug("Warning: effect file requested unrecognised texture: \"%s\"\n", FileName.c_str());
				m_ppEffect[j]->SetTexture(i, 0);
			}
		}
	}

	glEnable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);

	// Create the surface
	m_Surface = new ParametricSurface(50,50);
	ComputeSurface(m_nCurrentSurface);

	return true;
}
Example #3
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 OGLESOptimizeMesh::RenderScene()
{
	unsigned long ui32Time;

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

	//	Time
	ui32Time = PVRShellGetTime();
	m_ui32TimeDiff = ui32Time - m_ui32LastTime;
	m_ui32LastTime = ui32Time;

	// FPS
	++m_ui32FPSFrameCnt;
	m_ui32FPSTimeDiff += m_ui32TimeDiff;

	if(m_ui32FPSTimeDiff >= g_ui32TimeFPSUpdate)
	{
		m_fFPS = m_ui32FPSFrameCnt * 1000.0f / (float) m_ui32FPSTimeDiff;
		m_ui32FPSFrameCnt = 0;
		m_ui32FPSTimeDiff = 0;
	}

	// Change mode when necessary
	m_ui32SwitchTimeDiff += m_ui32TimeDiff;

	if((m_ui32SwitchTimeDiff > g_ui32TimeAutoSwitch) || PVRShellIsKeyPressed(PVRShellKeyNameACTION1))
	{
		m_ui32SwitchTimeDiff = 0;
		++m_i32Page;

		if(m_i32Page >= (int) m_ui32PageNo)
			m_i32Page = 0;
	}

	PVRTVec3 From;
	float fFactor;

	From.x = g_fViewDistance * PVRTSIN(m_fViewAngle);
	From.y = 0.0f;
	From.z = g_fViewDistance * PVRTCOS(m_fViewAngle);

	// Increase the rotation
	fFactor = 0.005f * (float) m_ui32TimeDiff;
	m_fViewAngle += fFactor;

	// Ensure it doesn't grow huge and lose accuracy over time
	while(m_fViewAngle > PVRT_PI)
		m_fViewAngle -= PVRT_TWO_PI;

	// Compute and set the matrix
	m_mView = PVRTMat4::LookAtRH(From, PVRTVec3(0,0,0), PVRTVec3(0,1,0));

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

	// Setup the lighting
	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);

	PVRTVec4 vLightDir(From.x, From.y, From.z, 0);
	vLightDir = vLightDir.normalize();

	// Set the light direction
	glLightfv(GL_LIGHT0, GL_POSITION, vLightDir.ptr());
	glLightfv(GL_LIGHT0, GL_DIFFUSE, PVRTVec4(0.8f,0.8f,0.8f,1.0f).ptr());

	// Draw the model
	DrawModel(m_i32Page);

	// Display the frame rate
	CPVRTString title;
	const char * pDesc;

	title = PVRTStringFromFormattedStr("Optimize Mesh %.1ffps", m_fFPS);

	// Print text on screen
	switch(m_i32Page)
	{
	default:
		pDesc = "Indexed Tri List: Unoptimized";
		break;
	case 1:
		pDesc = "Indexed Tri List: Optimized (at export time)";
		break;
	}

	m_Print3D.DisplayDefaultTitle(title.c_str(), pDesc, ePVRTPrint3DSDKLogo);

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

	return true;
}