Example #1
0
/*!****************************************************************************
 @Function		InitView
 @Return		bool		true if no error occured
 @Description	Code in InitView() will be called by PVRShell upon
				initialization or after a change in the rendering context.
				Used to initialize variables that are dependant on the rendering
				context (e.g. textures, vertex buffers, etc.)
******************************************************************************/
bool OGLESParticles::InitView()
{
	PVRTMat4		mProjection;
	SPVRTContext	sContext;

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

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

	// Initialize Extensions
	m_Extensions.LoadExtensions();

	//	Load textures.
	if(PVRTTextureLoadFromPVR(c_szLightTexFile, &m_ui32TexName) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot load light texture.\n");
		return false;
	}

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

	if(PVRTTextureLoadFromPVR(c_szFloorTexFile, &m_ui32FloorTexName) != PVR_SUCCESS)
	{
		PVRShellSet(prefExitMessage, "ERROR: Cannot load floor texture.\n");
		return false;
	}

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

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	if(bRotate)
		myglRotate(f2vt(90), f2vt(0), f2vt(0), f2vt(1));

	// Creates the projection matrix.
	mProjection = PVRTMat4::PerspectiveFovRH(f2vt(45.0f*(PVRT_PIf/180.0f)), f2vt((float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight)), f2vt(10.0f), f2vt(1200.0f), PVRTMat4::OGL);
	
	myglMultMatrix(mProjection.f);

	//	Calculates the attenuation coefficient for the points drawn.
	double H = bRotate ? PVRShellGet(prefWidth) : PVRShellGet(prefHeight);
	double h = 2.0 / mProjection.f[5];
	double D0 = sqrt(2.0) * H / h;
	double k = 1.0/(1.0 + 2.0 * (1 / mProjection.f[5]) * (1 / mProjection.f[5]));
	
	m_fPointAttenuationCoef = (float)(1.0 / (D0 * D0) * k);

	//	Creates the model view matrix.
	m_mView = PVRTMat4::LookAtRH(m_fFrom, m_fTo, g_fUp);

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

	/*
		Pre-Set TexCoords since they never change.
		Pre-Set the Index Buffer.
	*/

	for(unsigned int i = 0; i < g_ui32MaxParticles; ++i)
	{
		m_sParticleVTXBuf[i*4+0].u = 0;
		m_sParticleVTXBuf[i*4+0].v = 0;

		m_sParticleVTXBuf[i*4+1].u = 1;
		m_sParticleVTXBuf[i*4+1].v = 0;

		m_sParticleVTXBuf[i*4+2].u = 0;
		m_sParticleVTXBuf[i*4+2].v = 1;

		m_sParticleVTXBuf[i*4+3].u = 1;
		m_sParticleVTXBuf[i*4+3].v = 1;

		m_ui16ParticleINDXBuf[i*6+0] = (i*4) + 0;
		m_ui16ParticleINDXBuf[i*6+1] = (i*4) + 1;
		m_ui16ParticleINDXBuf[i*6+2] = (i*4) + 2;
		m_ui16ParticleINDXBuf[i*6+3] = (i*4) + 2;
		m_ui16ParticleINDXBuf[i*6+4] = (i*4) + 1;
		m_ui16ParticleINDXBuf[i*6+5] = (i*4) + 3;
	}


	//	Create vertex buffers.
	glGenBuffers(1, &m_i32VertVboID);
	glGenBuffers(1, &m_i32ColAVboID);
	glGenBuffers(1, &m_i32ColBVboID);
	glGenBuffers(1, &m_i32QuadVboID);

	//	Preset the floor uvs and vertices as they never change.
	PVRTVec3 pos(0, 0, 0);

	float szby2 = 100;

	m_sQuadVTXBuf[0].x = m_fFloorQuadVerts[0]  = pos.x - f2vt(szby2);
	m_sQuadVTXBuf[0].y = m_fFloorQuadVerts[1]  = pos.y;
	m_sQuadVTXBuf[0].z = m_fFloorQuadVerts[2]  = pos.z - f2vt(szby2);

	m_sQuadVTXBuf[1].x = m_fFloorQuadVerts[3]  = pos.x + f2vt(szby2);
	m_sQuadVTXBuf[1].y = m_fFloorQuadVerts[4]  = pos.y;
	m_sQuadVTXBuf[1].z = m_fFloorQuadVerts[5]  = pos.z - f2vt(szby2);

	m_sQuadVTXBuf[2].x = m_fFloorQuadVerts[6]  = pos.x - f2vt(szby2);
	m_sQuadVTXBuf[2].y = m_fFloorQuadVerts[7]  = pos.y;
	m_sQuadVTXBuf[2].z = m_fFloorQuadVerts[8]  = pos.z + f2vt(szby2);

	m_sQuadVTXBuf[3].x = m_fFloorQuadVerts[9]  = pos.x + f2vt(szby2);
	m_sQuadVTXBuf[3].y = m_fFloorQuadVerts[10] = pos.y;
	m_sQuadVTXBuf[3].z = m_fFloorQuadVerts[11] = pos.z + f2vt(szby2);

	m_fFloorQuadUVs[0] = f2vt(0);
	m_fFloorQuadUVs[1] = f2vt(0);
	m_sQuadVTXBuf[0].u = 0;
	m_sQuadVTXBuf[0].v = 0;

	m_fFloorQuadUVs[2] = f2vt(1);
	m_fFloorQuadUVs[3] = f2vt(0);
	m_sQuadVTXBuf[1].u = 255;
	m_sQuadVTXBuf[1].v = 0;

	m_fFloorQuadUVs[4] = f2vt(0);
	m_fFloorQuadUVs[5] = f2vt(1);
	m_sQuadVTXBuf[2].u = 0;
	m_sQuadVTXBuf[2].v = 255;

	m_fFloorQuadUVs[6] = f2vt(1);
	m_fFloorQuadUVs[7] = f2vt(1);
	m_sQuadVTXBuf[3].u = 255;
	m_sQuadVTXBuf[3].v = 255;

	glBindBuffer(GL_ARRAY_BUFFER, m_i32QuadVboID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(SVtx) * 4, m_sQuadVTXBuf, GL_STATIC_DRAW);

	return true;
}
/*******************************************************************************
 * Function Name  : InitView
 * Returns        : true if no error occured
 * Description    : Code in InitView() will be called by the Shell upon a change
 *					in the rendering context.
 *					Used to initialize variables that are dependant on the rendering
 *					context (e.g. textures, vertex buffers, etc.)
 *******************************************************************************/
bool OGLESSkinning::InitView()
{
	CPVRTString error;

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

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

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

	// Init Print3D to display text on screen
	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);

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

	// Model View Matrix
	CameraGetMatrix();

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

	// GENERIC RENDER STATES

	// Enables Depth Testing
	glEnable(GL_DEPTH_TEST);

	// Enables Smooth Colour Shading
	glShadeModel(GL_SMOOTH);

	// Enable texturing
	glEnable(GL_TEXTURE_2D);

	// Define front faces
	glFrontFace(GL_CW);

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

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

	// Setup ambiant light
    glEnable(GL_LIGHTING);

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

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

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

	LoadVbos();

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

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

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

	return true;
}
/*!****************************************************************************
 @Function		CreateFBOorPBuffer
 @Return		bool		true if no error occured
 @Description	Attempts to create our FBO if supported or a PBuffer if they
				are not.
******************************************************************************/
bool OGLESRenderToTexture::CreateFBOorPBuffer()
{
#if !defined(EGL_NOT_PRESENT)
	EGLConfig eglConfig = 0;
	EGLint list[9];
#endif

	// Find the largest square power of two texture that fits into the viewport
	m_i32TexSize = 1;
	int iSize = PVRT_MIN(PVRShellGet(prefWidth), PVRShellGet(prefHeight));
	while (m_i32TexSize * 2 < iSize) m_i32TexSize *= 2;

	// Check for FBO extension
	if(CPVRTglesExt::IsGLExtensionSupported("GL_OES_framebuffer_object"))
	{
		// FBOs are present so we're going to use them
		m_eR2TType = eFBO;

		// Load the extensions as they are required
		m_Extensions.LoadExtensions();

		// Check to see if the GL_EXT_discard_framebuffer extension is supported by seeing if
		// CPVRTglesExt has a valid pointer for glDiscardFramebufferEXT
		m_bDiscard = m_Extensions.glDiscardFramebufferEXT != 0;

		// Get the currently bound frame buffer object. On most platforms this just gives 0.
		glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &m_i32OriginalFbo);

		// Generate and bind a render buffer which will become a depth buffer shared between our two FBOs
		m_Extensions.glGenRenderbuffersOES(1, &m_uDepthBuffer);
		m_Extensions.glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_uDepthBuffer);

		/*
			Currently it is unknown to GL that we want our new render buffer to be a depth buffer.
			glRenderbufferStorage will fix this and in this case will allocate a depth buffer
			m_i32TexSize by m_i32TexSize.
		*/
		m_Extensions.glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, m_i32TexSize, m_i32TexSize);
	}
#if !defined(EGL_NOT_PRESENT)
	else
	{
		// FBOs aren't present so we're going to use PBuffers
		m_eR2TType = ePBuffer;

		// Set up a configuration and attribute list used for creating a PBuffer surface.
		eglConfig = SelectEGLConfig();

		// First we specify the width of the surface...
		list[0] = EGL_WIDTH;
		list[1] = m_i32TexSize;
		// ...then the height of the surface...
		list[2] = EGL_HEIGHT;
		list[3] = m_i32TexSize;
		/* ... then we specifiy the target for the texture
			that will be created when the pbuffer is created...*/
		list[4] = EGL_TEXTURE_TARGET;
		list[5] = EGL_TEXTURE_2D;
		/*..then the format of the texture that will be created
			when the pBuffer is bound to a texture...*/
		list[6] = EGL_TEXTURE_FORMAT;
		list[7] = EGL_TEXTURE_RGB;
		// The final thing is EGL_NONE which signifies the end.
		list[8] = EGL_NONE;

		/*
			Get the current display, context and surface so we can switch between the
			PBuffer surface and the main render surface.
		*/

		m_CurrentDisplay = eglGetCurrentDisplay();
		m_CurrentContext = eglGetCurrentContext();
		m_CurrentSurface = eglGetCurrentSurface(EGL_DRAW);
	}
#else
	else
	{