Пример #1
0
bool PVRTTextureAtlas::GetTextureSpan(const std::string &szTextureName, PVRTVec2 &span) const
{
	map<string, TexRegistrationInfo>::const_iterator iter = m_vRegistrationMap.find(szTextureName);
	if (iter == m_vRegistrationMap.end())
	{
		span = PVRTVec2(0.0f, 0.0f);
		return false;
	}

	span = iter->second.uv_coords.span;
	return true;
}
Пример #2
0
bool PVRTTextureAtlas::GetTextureOffset(const std::string &szTextureName, PVRTVec2 &offset) const
{
	map<string, TexRegistrationInfo>::const_iterator iter = m_vRegistrationMap.find(szTextureName);
	if (iter == m_vRegistrationMap.end())
	{
		offset = PVRTVec2(0.0f, 0.0f);
		return false;
	}

	offset = iter->second.uv_coords.offset;
	return true;
}
Пример #3
0
/*!***********************************************************************
 @Function		BuildQuads
 @Access		private 
 @Returns		void
 @Description	
*************************************************************************/
void Particle::BuildQuads()
	{
	// Quads require 4 vertices with Position, Colour and UVs.
	const PVRTMat3 mxRot = PVRTMat3::RotationZ(m_desc.m_fRotCur);
	const Float32 fHW = (m_pParent->m_tex->GetWidth()  * 0.5f) * m_desc.m_vScale.x;
	const Float32 fHH = (m_pParent->m_tex->GetHeight() * 0.5f) * m_desc.m_vScale.y;
	const RGBA& rgba = m_desc.m_RGBA;
	PrimQuad* pPrim = (PrimQuad*)m_pPrimitive;

	static const PVRTVec2 UVs[4] =
		{
			PVRTVec2(0.0f, 0.0f),	// TL
			PVRTVec2(0.0f, 1.0f),	// BL
			PVRTVec2(1.0f, 0.0f),	// TR
			PVRTVec2(1.0f, 1.0f),	// BR
		};

	static const Float32 fSigns[4*2] =
		{
		-1.0f, +1.0f,				// TL
		-1.0f, -1.0f,				// BL
		+1.0f, +1.0f,				// TR
		+1.0f, -1.0f,				// BR
		};

	PrimVertex* pV = NULL;
	for(Uint32 i = 0; i < 4; ++i)
		{
		pV = &pPrim->vert[i];
		memset(pV, 0, sizeof(PrimVertex));
		pV->v.x = fHW*fSigns[i*2];
		pV->v.y = fHH*fSigns[i*2+1];
		pV->uv  = UVs[i];
		pV->rgba[0] = rgba.RedChannel();	pV->rgba[1] = rgba.GreenChannel();	
		pV->rgba[2] = rgba.BlueChannel();	pV->rgba[3] = rgba.AlphaChannel();
		pV->v *= mxRot;
		pV->v += m_desc.m_vPos;
		}
	}
/*!***********************************************************************
 @Function		OnTouchUp
 @Access		public 
 @Param			Touch * pTouches
 @Param			Uint32 uiNum
 @Returns		void
 @Description	
*************************************************************************/
void ViewGameFinished::OnTouchUp(Touch* pTouches, Uint32 uiNum)
	{
	if(m_eGUIState & enumGUISTATE_Off_Mask)
		return;
		
	// Scale touch to our local view coords (iPad or Retina)
	Float32 fCoordX = (Float32)GetScreenDimensions(false).x;
	Float32 fCoordY = (Float32)GetScreenDimensions(false).y;
	PVRTVec2 vTouchWorld((pTouches[0].fX / (Float32)GFX->GetDeviceWidth()) * fCoordX, (pTouches[0].fY / (Float32)GFX->GetDeviceHeight()) * fCoordY);

	PVRTVec2 vTouch = PVRTVec2(vTouchWorld.x,	fCoordY - vTouchWorld.y);

	if(m_RectMainMenu.Contains(vTouch))
		Close();
	}
Пример #5
0
bool PVRTTextureAtlas::LoadAtlasDefinitionFromFile(PVRParser &parser)
{	
	unsigned int ui32Width = parser.parse_unsigned_int();
	unsigned int ui32Height = parser.parse_unsigned_int();

	const unsigned int numTextures = parser.parse_unsigned_int();
	
	for (unsigned int i=0; i < numTextures; i++)
	{
		string name = parser.parse_string();

		TexRegistrationInfo info;

		info.uv_coords.offset.x = parser.parse_float();
		info.uv_coords.offset.y = parser.parse_float();
		info.uv_coords.span.x = parser.parse_float();
		info.uv_coords.span.y = parser.parse_float();

		info.transformation = CalculateTransformation(info.uv_coords.offset, info.uv_coords.span, PVRTVec2(0.0f, 0.0f));
		
		m_vRegistrationMap[name] = info;
	}
	
	return true;
}
Пример #6
0
void OGLESAntialiasedLines::TessellateLine(const PVRTVec2& vPointA, const PVRTVec2& vPointB, 
	float fWidth, GLuint uiColor, STexVertex* pVertexArray, 
	GLushort u16StartIndex, GLushort* pu16IndexArray)
{
	// Calculate the normalised tangent and normal for the line,
	// multiplied by the line width
	PVRTVec2 vDiff = vPointA - vPointB;
	PVRTVec2 vTangent = vDiff * VERTTYPEDIV(f2vt(fWidth), vDiff.length());
	PVRTVec2 vNormal = vTangent.rotated90();

    /*
	We write eight vertices to the vertex array. The rectangles (0,1,2,3) and
	(4,5,6,7) represent the round line caps. The rectangle (2,3,4,5) is the
	main line segment.

	  -t                 +t
	0---->2--  ...  --4<----6
	^\    |\_         |\    ^ +n
	| \   |  \        | \   | 
	A  \  |    ...    |  \  B
	|   \ |        \_ |   \ | 
	v    \|          \|    \v -n
	1---->3--  ...  --5<----7
	  cap      line     cap

	Note that for this example the caps are entirely between the end points
	(A and B in the diagram above). Even vertices are displaced along the
	positive normal (+n), odd vertices are displaced along the negative normal.
	The pairs (2, 3) and (4, 5) are shifted inwards along the line tangent.

	To achieve the antialiasing we use a special texture where on the U-axis 
	there is an opaque segment from 0.25 to 0.5. We then use 0.125 as texcoord
	for the even vertices and 0.625 for the odd vertices. This is necessary so
	it still looks ok when the 4 texel wide mip level is used.
	Texture filtering and blending then results in smooth lines.

	The method breaks down when the line geometry gets less than 2 pixels
	wide (actual line width < 1). In this case we should clamp the line
	width to 1 and use the actual line width as an alpha factor, so very thin
	lines will smoothly fade out.

	texcoords:  0  1/8             5/8          1 
                |   |               |           |
	miplevel 2: |   0       1       0       0   |
	miplevel 1: | 0   0   1   1   0   0   0   0 |
	miplevel 0: |0 0 0 0 1 1 1 1 0 0 0 0 0 0 0 0|
	*/

	pVertexArray[0].vPosition = vPointA + vNormal;
	pVertexArray[0].vTexcoord = PVRTVec2(f2vt(1/8.f), f2vt(0.245f));
	pVertexArray[1].vPosition = vPointA - vNormal;
	pVertexArray[1].vTexcoord = PVRTVec2(f2vt(5/8.f), f2vt(0.245f));

	pVertexArray[2].vPosition = vPointA + vNormal - vTangent;
	pVertexArray[2].vTexcoord = PVRTVec2(f2vt(1/8.f), f2vt(0.75f));
	pVertexArray[3].vPosition = vPointA - vNormal - vTangent;
	pVertexArray[3].vTexcoord = PVRTVec2(f2vt(5/8.f), f2vt(0.75f));

	pVertexArray[4].vPosition = vPointB + vNormal + vTangent;
	pVertexArray[4].vTexcoord = PVRTVec2(f2vt(1/8.f), f2vt(0.75f));
	pVertexArray[5].vPosition = vPointB - vNormal + vTangent;
	pVertexArray[5].vTexcoord = PVRTVec2(f2vt(5/8.f), f2vt(0.75f));

	pVertexArray[6].vPosition = vPointB + vNormal;
	pVertexArray[6].vTexcoord = PVRTVec2(f2vt(1/8.f), f2vt(0.245f));
	pVertexArray[7].vPosition = vPointB - vNormal;
	pVertexArray[7].vTexcoord = PVRTVec2(f2vt(5/8.f), f2vt(0.245f));

	// The color is constant for each line, but we write it to the vertex
	// array so we can render multiple lines in one draw call
	int i;
	for (i = 0; i < 8; ++i)
	{
		pVertexArray[i].uiColor = uiColor;
	}

	// Write indices to index buffer
	GLushort au16Indices[18] = { 0, 1, 2,  2, 1, 3,  2, 3, 4,  4, 3, 5,  4, 5, 6,  6, 5, 7 };
	for (i = 0; i < 18; ++i)
	{
		pu16IndexArray[i] = au16Indices[i] + u16StartIndex;
	}
}
bool TriangulatePolygon(const PVRTCoordinateVector &coordinates, const PVRTPolygon &polygon, PVRTCoordinateVector &triangle_coords, PVRTTriangleVector &triangles)
{
	unsigned int numPoints = polygon.indices.size();

	InitialiseTriangulationModule(numPoints,
								  2*numPoints,
								  NULL);

	int paths = 1;
	int pathlens[1] = { polygon.indices.size() };
	float maxDimension = -FLT_MAX;
	float *pCoordinates = new float[polygon.indices.size()*2];

	for (unsigned int i=0; i < polygon.indices.size(); i++)
	{
		PVRTVec3 coord = coordinates[polygon.indices[i]].position;
		pCoordinates[i*2] = coord.x;
		pCoordinates[i*2+1] = coord.y;

		maxDimension = PVRT_MAX(coord.x, maxDimension);
		maxDimension = PVRT_MAX(coord.y, maxDimension);
	}

	ExternalTrapStruct TrapezoidsResult;

	TRI_ERROR_TYPES status = BuildPolygonTrapeziation(NULL, //do all subpaths at once
									                  maxDimension,
											          // path data
											          paths,
											          pathlens,
											          pCoordinates,
											          // Specify a seed for the random number generator
											          // This isn't critcal if the processing is offline so just use 0
											          0,											 
											          // the resulting trap structure											 
											          &TrapezoidsResult);
	delete [] pCoordinates;
	if (!AnalyzeTriangulationError(status))
	{
		FreeTriangulationModuleMemory();
		return false;
	}

	int MaxFFRecursionDepth = 10000;
	int FillModeIsOddEven = 0;
	int numVertices = 0;
	float *pVertices = NULL;
	int numTriangles = 0;
	TriIndicesType *pTriangleIndices = NULL;

	numTriangles = OutputIndexedTriangles(&TrapezoidsResult,
										  MaxFFRecursionDepth,
										  FillModeIsOddEven,
										  true, 
										  &numVertices,
										  &pVertices,
										  &pTriangleIndices);

	for (int i=0; i < numTriangles; i++)
	{
		TriIndicesType triangle = pTriangleIndices[i];		
		PVRTVertex a = { PVRTVec3(pVertices[triangle.Ind[0]*2], pVertices[triangle.Ind[0]*2+1], 0.0f), PVRTVec2(0.0f, 0.0f) };
		PVRTVertex b = { PVRTVec3(pVertices[triangle.Ind[1]*2], pVertices[triangle.Ind[1]*2+1], 0.0f), PVRTVec2(0.0f, 0.0f) };
		PVRTVertex c = { PVRTVec3(pVertices[triangle.Ind[2]*2], pVertices[triangle.Ind[2]*2+1], 0.0f), PVRTVec2(0.0f, 0.0f) };

		const unsigned int index_start = triangle_coords.size();
		triangle_coords.push_back(a);
		triangle_coords.push_back(b);
		triangle_coords.push_back(c);

		PVRTTriangle tri = { index_start, index_start+1, index_start+2 };
		triangles.push_back(tri);
	}

	FreeTriangulationModuleMemory();

	return true;
}
Пример #8
0
// ---------------------------------------------------------------
void MyPVRDemo::RenderBloom(const PVRTMat4& mxModel, const PVRTMat4& mxCam, const PVRTVec3& vLightPos)
	{
	// --- Bind an empty frame buffer.
	glBindFramebuffer(GL_FRAMEBUFFER, m_uiFBO[enumFB_1]);
	glViewport(0, 0, RTT_SIZE, RTT_SIZE);
	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// --- Render the statue with Bloom Stage 1 Shader. This basically renders the statue with the normal map
	// and uses a texture lookup to effectively high-pass filter the resultant output.
	glUseProgram(m_Bloom1Shader.uiID);
	glUniform1f(m_Bloom1Shader.uiBloomMulti, m_fBloomMulti);
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_tex[enumTEXTURE_StatueNormals]);
	glActiveTexture(GL_TEXTURE1);
	glBindTexture(GL_TEXTURE_2D, m_tex[enumTEXTURE_BloomMap]);
	RenderStatue(mxModel, mxCam, vLightPos, &m_Bloom1Shader);
	glBindTexture(GL_TEXTURE_2D, 0);
	glActiveTexture(GL_TEXTURE0);

	// --- BLUR PASSES
	glUseProgram(m_BloomBlurShader.uiID);

	// Horizontal blur
	glBindFramebuffer(GL_FRAMEBUFFER, m_uiFBO[enumFB_2]);
	glViewport(0, 0, RTT_SIZE, RTT_SIZE);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glBindTexture(GL_TEXTURE_2D, m_uiRTT[enumFB_1]);

	glUniform2f(m_BloomBlurShader.uiTexelOffset, m_fTexelOffset, 0.0f);
	RenderScreenAlignedTexture(PVRTVec2(-1.0f, 1.0f), PVRTVec2(1.0f, -1.0f), PVRTVec2(0.0f, 1.0f), PVRTVec2(1.0f, 0.0f));

	// Vertical blur
	glBindFramebuffer(GL_FRAMEBUFFER, m_uiFBO[enumFB_1]);
	glViewport(0, 0, RTT_SIZE, RTT_SIZE);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glBindTexture(GL_TEXTURE_2D, m_uiRTT[enumFB_2]);

	glUniform2f(m_BloomBlurShader.uiTexelOffset, 0.0f, m_fTexelOffset);
	RenderScreenAlignedTexture(PVRTVec2(-1.0f, 1.0f), PVRTVec2(1.0f, -1.0f), PVRTVec2(0.0f, 1.0f), PVRTVec2(1.0f, 0.0f));


	// --- OVERLAY PASS
	glBindFramebuffer(GL_FRAMEBUFFER, m_nOrigFBO);		// Done. Use the original framebuffer.
	glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));

	// --- Render the texture to a screen aligned quad over the original mode. NOTE: We should use scissor or bounding rect instead.
	glUseProgram(m_SATexShader.uiID);
	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE);				// Additive blending
	glBindTexture(GL_TEXTURE_2D, m_uiRTT[enumFB_1]);

	// This needs to be recalculated whenever either of the following change:
	PVRTMat4 mxMVP = m_mxProjection * m_mxCam * mxModel;
	PVRTVec4 vTL = mxMVP * m_bbStatueTL;
	PVRTVec4 vBR = mxMVP * m_bbStatueBR;
	vTL /= vTL.w;
	vBR /= vBR.w;

	if(m_bRotated)
		{
		float fTmp = vBR.y;			// Swap coordinates around if the screen is rotated.
		vBR.y = vTL.y;
		vTL.y = fTmp;
		}
	PVRTVec2 vTTL(vTL.x * 0.5f + 0.5f, vTL.y * 0.5f + 0.5f);
	PVRTVec2 vTBR(vBR.x * 0.5f + 0.5f, vBR.y * 0.5f + 0.5f);
	
	RenderScreenAlignedTexture(PVRTVec2(vTL.x, vTL.y), PVRTVec2(vBR.x, vBR.y), vTTL, vTBR);
	glDisable(GL_BLEND);
	}
Пример #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 OGLES2Bloom::RenderScene()
{
	HandleInput();

	// Calculate the mask and light rotation based on the passed time
	static unsigned long ulPreviousTime = PVRShellGetTime();
	unsigned long ulNowTime = PVRShellGetTime();
	m_fRotation += PVRT_PI * (ulNowTime - ulPreviousTime) * 0.0002f;
	ulPreviousTime = ulNowTime;
	if (m_fRotation > (PVRT_PI * 2.0f))
		m_fRotation -= PVRT_PI * 2.0f;
	
	// Calculate the model, view and projection matrix
	float fModelAngleY = m_fRotation;
	float fLightAngleY = -m_fRotation;

	PVRTMat4 mWorld = PVRTMat4::RotationY(fModelAngleY);
	PVRTMat4 mLight = PVRTMat4::RotationY(fLightAngleY);
	PVRTMat4 mView = PVRTMat4::LookAtRH(PVRTVec3(0, 0, 150), PVRTVec3(0, 0, 0), PVRTVec3(0, 1, 0));

	bool bRotate = PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen);
	PVRTMat4 mProjection = PVRTMat4::PerspectiveFovRH(g_fCameraFOV, (float)PVRShellGet(prefWidth)/(float)PVRShellGet(prefHeight), g_fCameraNear, g_fCameraFar, PVRTMat4::OGL, bRotate);
	PVRTMat4 mMVP = mProjection * mView * mWorld;

	// Simple rotating directional light in model-space
	PVRTVec4 vMsLightPos = mWorld.inverse() * mLight * PVRTVec4(0.5f, -1, -0.5f, 0).normalize();

	glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo);
	glClearColor(0.075f, 0.1f, 0.125f, 0.0f);
	glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Use simple shader program to render the mask
	glUseProgram(m_ShaderProgram.uiId);
	glUniformMatrix4fv(m_ShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.f);
	glUniform3fv(m_ShaderProgram.uiLightDirLoc, 1, &vMsLightPos.x);

	// Draw the mesh
	glActiveTexture(GL_TEXTURE0);
	glBindTexture(GL_TEXTURE_2D, m_uiBaseTex);
	DrawMesh(0);

	if (m_bApplyBloom)
	{
		// First render the objects which shall have the bloom effect to a texture
		glBindFramebuffer(GL_FRAMEBUFFER, m_uiBlurFramebufferObjects[0]);
		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		glViewport(0, 0, m_i32TexSize, m_i32TexSize);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glUseProgram(m_PreBloomShaderProgram.uiId);
		glUniformMatrix4fv(m_PreBloomShaderProgram.uiMVPMatrixLoc, 1, GL_FALSE, mMVP.f);
		glUniform3fv(m_PreBloomShaderProgram.uiLightDirLoc, 1, &vMsLightPos.x);
		glUniform1f(m_PreBloomShaderProgram.uiBloomIntensity, m_fBloomIntensity);

		// Draw the mesh
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, m_uiBloomMappingTexture);
		DrawMesh(0);

		if(m_bDiscard) // Was GL_EXT_discard_framebuffer supported?
		{
			//Give the drivers a hint that we don't want depth information to be stored for later.
			const GLenum attachment = GL_DEPTH_ATTACHMENT;
			m_Extensions.glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachment);
		}
		/*
		  Blur the generated image n-times
		*/
		for (unsigned int i=0; i < m_ui32BlurPasses; i++)
		{
			/*
			 Apply horizontal blur
			*/
			glBindFramebuffer(GL_FRAMEBUFFER, m_uiBlurFramebufferObjects[1]);
			glViewport(0, 0, m_i32TexSize, m_i32TexSize);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_2D, m_uiBlurTextures[0]);

			// Use the shader program for the scene
			glUseProgram(m_BlurShaderProgram.uiId);
			glUniform1f(m_BlurShaderProgram.uiTexelOffsetX, m_fTexelOffset);
			glUniform1f(m_BlurShaderProgram.uiTexelOffsetY, 0.0f);

			DrawAxisAlignedQuad(PVRTVec2(-1, -1), PVRTVec2(1, 1));


			//No attachments we can invalidate here, as only color was used which is necessary.
			/*
			   Apply vertical blur
			*/
			glBindFramebuffer(GL_FRAMEBUFFER, m_uiBlurFramebufferObjects[0]);
			glViewport(0, 0, m_i32TexSize, m_i32TexSize);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glActiveTexture(GL_TEXTURE0);
			glBindTexture(GL_TEXTURE_2D, m_uiBlurTextures[1]);

			// Use the shader program for the scene
			glUseProgram(m_BlurShaderProgram.uiId);
			glUniform1f(m_BlurShaderProgram.uiTexelOffsetX, 0.0f);
			glUniform1f(m_BlurShaderProgram.uiTexelOffsetY, m_fTexelOffset);

			DrawAxisAlignedQuad(PVRTVec2(-1, -1), PVRTVec2(1, 1));

			if(m_bDiscard) // Was GL_EXT_discard_framebuffer supported?
			{
				//Give the drivers a hint that we don't want depth information to be stored for later.
				const GLenum attachment = GL_DEPTH_ATTACHMENT;
				m_Extensions.glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, &attachment);
			}
		}

		/*
		  Draw scene with bloom
		*/
		glBindFramebuffer(GL_FRAMEBUFFER, m_i32OriginalFbo);
		glViewport(0, 0, PVRShellGet(prefWidth), PVRShellGet(prefHeight));

		glEnable(GL_BLEND);
		glBlendFunc(GL_ONE, GL_ONE);

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, m_uiBlurTextures[0]);

		// Use the shader program for the scene
		glUseProgram(m_PostBloomShaderProgram.uiId);

		/*
		    The following section will draw a quad on the screen
			where the post processing pixel shader shall be executed.
			Try to minimize the area by only drawing where the actual
			post processing should happen, as this is a very costly operation.
		*/
		if (PVRShellGet(prefIsRotated) && PVRShellGet(prefFullScreen)) {
			DrawAxisAlignedQuad(PVRTVec2(-0.875f, -0.5f), PVRTVec2(0.0625f, 0.25f),
					            PVRTVec2(0.8755f, 0.5f), PVRTVec2(0.9375f, 0.75f));
		}
		else
		{
			DrawAxisAlignedQuad(PVRTVec2(-0.5f, -0.875f), PVRTVec2(0.25f, 0.0625f),
				                PVRTVec2(0.5f, 0.875f), PVRTVec2(0.75f, 0.9375f));
		}

		glDisable(GL_BLEND);
	}

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


	return true;
}