Ejemplo n.º 1
0
/*!***************************************************************************
@Function		PVRTTextureCreate
@Input			w			Size of the texture
@Input			h			Size of the texture
@Input			wMin		Minimum size of a texture level
@Input			hMin		Minimum size of a texture level
@Input			nBPP		Bits per pixel of the format
@Input			bMIPMap		Create memory for MIP-map levels also?
@Return			Allocated texture memory (must be free()d)
@Description	Creates a PVR_Texture_Header structure, including room for
				the specified texture, in memory.
*****************************************************************************/
PVR_Texture_Header *PVRTTextureCreate(
	unsigned int		w,
	unsigned int		h,
	const unsigned int	wMin,
	const unsigned int	hMin,
	const unsigned int	nBPP,
	const bool			bMIPMap)
{
	size_t			len;
	unsigned char	*p;

	len = 0;
	do
	{
		len += PVRT_MAX(w, wMin) * PVRT_MAX(h, hMin);
		w >>= 1;
		h >>= 1;
	}
	while(bMIPMap && (w || h));

	len = (len * nBPP) / 8;
	len += sizeof(PVR_Texture_Header);

	p = (unsigned char*)malloc(len);
	_ASSERT(p);
	return (PVR_Texture_Header*)p;
}
Ejemplo n.º 2
0
/*******************************************************************************
 * Function Name  : DoShearCentered
 * Description    : Demonstrate the effect of shearing centred on a
 *                  shape. Each path is transformed separately.
 *******************************************************************************/
void CTransforms::DoShearCentered()
{
	// Make sure we're operating on the path user-to-surface matrix
	vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);

	// Load Identity matrix. This clears all previous transformations
	vgLoadIdentity();

	// To be independent of screen resolution, we need to scale the
	// coordinates so everything in the range [0, 1] will be visible
	vgScale((float)PVRShellGet(prefWidth), (float)PVRShellGet(prefHeight));

	// Unlike OpenGL, OpenVG does not maintain a matrix stack. So instead of
	// pushing the current matrix to the stack, we have to store it ourselves
	float afUnitMatrix[3 * 3];
	vgGetMatrix(afUnitMatrix);

	// turn time(ms) into a clipped periodic triangle function
	int i32Zigzag1 = m_ui32AbsTime % 2000;

	if(i32Zigzag1 > 1000)
		i32Zigzag1 = 2000 - i32Zigzag1;

	i32Zigzag1 = PVRT_MAX(250, PVRT_MIN(750, i32Zigzag1)) - 500;

	// and again, now with shifted phase
	int i32Zigzag2 = (m_ui32AbsTime + 500) % 2000;

	if(i32Zigzag2 > 1000)
		i32Zigzag2 = 2000 - i32Zigzag2;

	i32Zigzag2 = PVRT_MAX(250, PVRT_MIN(750, i32Zigzag2)) - 500;

	// Scaling a shape from its center is identical to moving it to the
	// origin, scaling it there, and moving it back where it was.
	//
	// IMPORTANT:
	// Since OpenVG right-multiplies matrices, you conceptually need to
	// call the transformation functions in backwards order.
	vgTranslate(0.5f, 0.75f);
	vgShear(0.001f * i32Zigzag1, 0);
	vgTranslate(-0.5f, -0.75f);

	// draw first path
	vgDrawPath(m_avgPaths[0], VG_STROKE_PATH | VG_FILL_PATH);

	// restore the unit matrix ([0, 1] visible)
	vgLoadMatrix(afUnitMatrix);

	// transformation for second path
	vgTranslate(0.5f, 0.25f);
	vgShear(0.001f * i32Zigzag2, 0);
	vgTranslate(-0.5f, -0.25f);

	// draw second path
	vgDrawPath(m_avgPaths[1], VG_STROKE_PATH | VG_FILL_PATH);
}
Ejemplo n.º 3
0
/*!***************************************************************************
@Function		PVRTTextureCreate
@Input			w			Size of the texture
@Input			h			Size of the texture
@Input			wMin		Minimum size of a texture level
@Input			hMin		Minimum size of a texture level
@Input			nBPP		Bits per pixel of the format
@Input			bMIPMap		Create memory for MIP-map levels also?
@Return			Allocated texture memory (must be free()d)
@Description	Creates a PVR_Texture_Header structure, including room for
				the specified texture, in memory.
*****************************************************************************/
PVR_Texture_Header *PVRTTextureCreate(
	const unsigned int	w,
	const unsigned int	h,
	const unsigned int	wMin,
	const unsigned int	hMin,
	const unsigned int	nBPP,
	const bool			bMIPMap)
{
	size_t			len;
	unsigned char	*p;

	{
		unsigned int	wTmp = w, hTmp = h;

		len = 0;
		do
		{
			len += PVRT_MAX(wTmp, wMin) * PVRT_MAX(hTmp, hMin);
			wTmp >>= 1;
			hTmp >>= 1;
		}
		while(bMIPMap && (wTmp || hTmp));
	}

	len = (len * nBPP) / 8;
	len += sizeof(PVR_Texture_Header);

	p = (unsigned char*)malloc(len);
	_ASSERT(p);

	if(p)
	{
		PVR_Texture_Header * const psTexHeader = (PVR_Texture_Header*)p;

		psTexHeader->dwHeaderSize		= sizeof(PVR_Texture_Header);
		psTexHeader->dwWidth			= w;
		psTexHeader->dwHeight			= h;
		psTexHeader->dwMipMapCount		= 0;
		psTexHeader->dwpfFlags			= 0;
		psTexHeader->dwTextureDataSize	= (PVRTuint32)(len - sizeof(PVR_Texture_Header));
		psTexHeader->dwBitCount			= nBPP;
		psTexHeader->dwRBitMask			= 0;
		psTexHeader->dwGBitMask			= 0;
		psTexHeader->dwBBitMask			= 0;
		psTexHeader->dwAlphaBitMask		= 0;
		psTexHeader->dwPVR				= 0;
		psTexHeader->dwNumSurfs			= 1;

		return psTexHeader;
	}
	else
	{
		return 0;
	}
}
Ejemplo n.º 4
0
/*******************************************************************************
 * Function Name  : DoTranslate
 * Description    : Demonstrate the effect of translations. Each path is
 *                  translated separately
 *******************************************************************************/
void CTransforms::DoTranslate()
{
	// Make sure we're operating on the path user-to-surface matrix
	vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);

	// Load Identity matrix. This clears all previous transformations
	vgLoadIdentity();

	// To be independent of screen resolution, we need to scale the
	// coordinates so everything in the range [0, 1] will be visible
	vgScale((float) PVRShellGet(prefWidth), (float) PVRShellGet(prefHeight));

	// Unlike OpenGL, OpenVG does not maintain a matrix stack. So instead of
	// pushing the current matrix to the stack, we have to store it ourselves
	float afUnitMatrix[3 * 3];
	vgGetMatrix(afUnitMatrix);

	// turn time(ms) into a clipped periodic triangle function
	int i32Zigzag1 = m_ui32AbsTime % 2000;

	if(i32Zigzag1 > 1000)
		i32Zigzag1 = 2000 - i32Zigzag1;

	i32Zigzag1 = PVRT_MAX(250, PVRT_MIN(750, i32Zigzag1)) - 500;

	// and again, now with shifted phase
	int i32Zigzag2 = (m_ui32AbsTime + 500) % 2000;

	if(i32Zigzag2 > 1000)
		i32Zigzag2 = 2000 - i32Zigzag2;

	i32Zigzag2 = PVRT_MAX(250, PVRT_MIN(750, i32Zigzag2)) - 250;

	// translation for first path
	vgTranslate(-0.001f * i32Zigzag1, -0.001f * i32Zigzag2);

	// draw first path
	vgDrawPath(m_avgPaths[0], VG_STROKE_PATH | VG_FILL_PATH);

	// restore the unit matrix ([0, 1] visible)
	vgLoadMatrix(afUnitMatrix);

	// translation for second path
	vgTranslate(0.001f * i32Zigzag1, 0.001f * i32Zigzag2);

	// draw second path
	vgDrawPath(m_avgPaths[1], VG_STROKE_PATH | VG_FILL_PATH);
}
Ejemplo n.º 5
0
/*******************************************************************************
 * Function Name  : DoShearOrigin
 * Description    : Demonstrate the effect of shearing from the origin.
 *******************************************************************************/
void CTransforms::DoShearOrigin()
{
	// Make sure we're operating on the path user-to-surface matrix
	vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);

	// Load Identity matrix. This clears all previous transformations
	vgLoadIdentity();

	// To be independent of screen resolution, we need to scale the
	// coordinates so everything in the range [0, 1] will be visible
	vgScale((float)PVRShellGet(prefWidth), (float)PVRShellGet(prefHeight));

	// turn time(ms) into a periodic triangle function
	int i32Zigzag = m_ui32AbsTime % 2000;

	if(i32Zigzag > 1000)
		i32Zigzag = 2000 - i32Zigzag;

	i32Zigzag = PVRT_MAX(100, PVRT_MIN(900, i32Zigzag)) - 500;

	vgShear(i32Zigzag * 0.001f, 0);

	// draw first path
	vgDrawPath(m_avgPaths[0], VG_STROKE_PATH | VG_FILL_PATH);
	// draw second path
	vgDrawPath(m_avgPaths[1], VG_STROKE_PATH | VG_FILL_PATH);
}
Ejemplo n.º 6
0
/*******************************************************************************
 * Function Name  : DoScaleOrigin
 * Description    : Demonstrate the effect of scaling from the origin.
 *******************************************************************************/
void CTransforms::DoScaleOrigin()
{
	// Make sure we're operating on the path user-to-surface matrix
	vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE);

	// Load Identity matrix. This clears all previous transformations
	vgLoadIdentity();

	// To be independent of screen resolution, we need to scale the
	// coordinates so everything in the range [0, 1] will be visible
	vgScale((float) PVRShellGet(prefWidth), (float) PVRShellGet(prefHeight));

	// turn time(ms) into a periodic triangle function
	int i32Zigzag = m_ui32AbsTime % 2000;

	if(i32Zigzag > 1000)
		i32Zigzag = 2000 - i32Zigzag;

	i32Zigzag = PVRT_MAX(100, PVRT_MIN(900, i32Zigzag));

	float fScaleFactor = 0.3f + (i32Zigzag * 0.0009f);

	// Scaling a scene from the origin means that objects will
	// either get pulled towards the origin or move away from it
	// along with being resized.
	vgScale(fScaleFactor, fScaleFactor);

	// draw first path
	vgDrawPath(m_avgPaths[0], VG_STROKE_PATH | VG_FILL_PATH);
	// draw second path
	vgDrawPath(m_avgPaths[1], VG_STROKE_PATH | VG_FILL_PATH);
}
Ejemplo n.º 7
0
/*!***************************************************************************
@Function		PVRTTextureCreate
@Input			w			Size of the texture
@Input			h			Size of the texture
@Input			wMin		Minimum size of a texture level
@Input			hMin		Minimum size of a texture level
@Input			nBPP		Bits per pixel of the format
@Input			bMIPMap		Create memory for MIP-map levels also?
@Return			Allocated texture memory (must be free()d)
@Description	Creates a PVRTextureHeaderV3 structure, including room for
				the specified texture, in memory.
*****************************************************************************/
PVRTextureHeaderV3 *PVRTTextureCreate(
	const unsigned int	w,
	const unsigned int	h,
	const unsigned int	wMin,
	const unsigned int	hMin,
	const unsigned int	nBPP,
	const bool			bMIPMap)
{
	size_t			len;
	unsigned char	*p;

	{
		unsigned int	wTmp = w, hTmp = h;

		len = 0;
		do
		{
			len += PVRT_MAX(wTmp, wMin) * PVRT_MAX(hTmp, hMin);
			wTmp >>= 1;
			hTmp >>= 1;
		}
		while(bMIPMap && (wTmp || hTmp));
	}

	len = (len * nBPP) / 8;
	len += PVRTEX3_HEADERSIZE;

	p = (unsigned char*)malloc(len);
	_ASSERT(p);

	if(p)
	{
		PVRTextureHeaderV3 * const psTexHeader = (PVRTextureHeaderV3*)p;

		*psTexHeader=PVRTextureHeaderV3();

		psTexHeader->u32Width=w;
		psTexHeader->u32Height=h;

		return psTexHeader;
	}
	else
	{
		return 0;
	}
}
Ejemplo n.º 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 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;
}
Ejemplo n.º 9
0
/*!****************************************************************************
 @Function		LoadVbos
 @Description	Loads the mesh data required for this training course into
				vertex buffer objects
******************************************************************************/
void OGLES2LevelOfDetail::LoadVbos()
{
	if (!m_puiVbo)      m_puiVbo = new GLuint[m_Scene.nNumMesh];
	if (!m_puiIndexVbo) m_puiIndexVbo = new GLuint[m_Scene.nNumMesh];

	/*
		Load vertex data of all meshes in the scene into VBOs

		The meshes have been exported with the "Interleave Vectors" option,
		so all data is interleaved in the buffer at pMesh->pInterleaved.
		Interleaving data improves the memory access pattern and cache efficiency,
		thus it can be read faster by the hardware.
	*/
	glGenBuffers(m_Scene.nNumMesh, m_puiVbo);
	for (unsigned int i = 0; i < m_Scene.nNumMesh; ++i)
	{
		// Load vertex data into buffer object
		SPODMesh& Mesh = m_Scene.pMesh[i];
		unsigned int uiSize = Mesh.nNumVertex * Mesh.sVertex.nStride;
		glBindBuffer(GL_ARRAY_BUFFER, m_puiVbo[i]);
		glBufferData(GL_ARRAY_BUFFER, uiSize, Mesh.pInterleaved, GL_STATIC_DRAW);

		// Load index data into buffer object if available
		m_puiIndexVbo[i] = 0;
		if (Mesh.sFaces.pData)
		{
			glGenBuffers(1, &m_puiIndexVbo[i]);
			uiSize = PVRTModelPODCountIndices(Mesh) * sizeof(GLshort);
			glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_puiIndexVbo[i]);
			glBufferData(GL_ELEMENT_ARRAY_BUFFER, uiSize, Mesh.sFaces.pData, GL_STATIC_DRAW);
		}

		if (i == 0)
		{
			PVRTVec3 vBoundingBoxMin, vBoundingBoxMax;

			// calculate bounding box for mesh 0
			float* pfData = (float*)Mesh.pInterleaved;
			vBoundingBoxMin.x = vBoundingBoxMax.x = pfData[0];
			vBoundingBoxMin.y = vBoundingBoxMax.y = pfData[1];
			vBoundingBoxMin.z = vBoundingBoxMax.z = pfData[2];

			for(unsigned int i = 1; i < Mesh.nNumVertex; ++i)
			{
				pfData = (float*)(((char*)pfData) + Mesh.sVertex.nStride);

				vBoundingBoxMin.x = PVRT_MIN(vBoundingBoxMin.x, pfData[0]);
				vBoundingBoxMin.y = PVRT_MIN(vBoundingBoxMin.y, pfData[1]);
				vBoundingBoxMin.z = PVRT_MIN(vBoundingBoxMin.z, pfData[2]);
				vBoundingBoxMax.x = PVRT_MAX(vBoundingBoxMax.x, pfData[0]);
				vBoundingBoxMax.y = PVRT_MAX(vBoundingBoxMax.y, pfData[1]);
				vBoundingBoxMax.z = PVRT_MAX(vBoundingBoxMax.z, pfData[2]);
			}

			for (int i = 0; i < 8; ++i)
			{
				m_avBoundingBox[i].x = (i & 1) ? vBoundingBoxMin.x : vBoundingBoxMax.x;
				m_avBoundingBox[i].y = (i & 2) ? vBoundingBoxMin.y : vBoundingBoxMax.y;
				m_avBoundingBox[i].z = (i & 4) ? vBoundingBoxMin.z : vBoundingBoxMax.z;
				m_avBoundingBox[i].w = 1.0f;
			}
		}
	}
	glBindBuffer(GL_ARRAY_BUFFER, 0);
	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
Ejemplo n.º 10
0
/*!***************************************************************************
 @Function		PVRTTextureLoadFromPointer
 @Input			pointer				Pointer to header-texture's structure
 @Modified		texName				the OpenGL ES texture name as returned by glBindTexture
 @Modified		psTextureHeader		Pointer to a PVR_Texture_Header struct. Modified to
									contain the header data of the returned texture Ignored if NULL.
 @Input			bAllowDecompress	Allow decompression if PVRTC is not supported in hardware.
 @Input			nLoadFromLevel		Which mipmap level to start loading from (0=all)
 @Input			texPtr				If null, texture follows header, else texture is here.
 @Return		PVR_SUCCESS on success
 @Description	Allows textures to be stored in C header files and loaded in. Can load parts of a
				mipmaped texture (ie skipping the highest detailed levels).In OpenGL Cube Map, each
				texture's up direction is defined as next (view direction, up direction),
				(+x,-y)(-x,-y)(+y,+z)(-y,-z)(+z,-y)(-z,-y).
				Sets the texture MIN/MAG filter to GL_LINEAR_MIPMAP_NEAREST/GL_LINEAR
				if mipmaps are present, GL_LINEAR/GL_LINEAR otherwise.
*****************************************************************************/
EPVRTError PVRTTextureLoadFromPointer(	const void* pointer,
										GLuint *const texName,
										const void *psTextureHeader,
										bool bAllowDecompress,
										const unsigned int nLoadFromLevel,
										const void * const texPtr)
{
	PVR_Texture_Header* psPVRHeader = (PVR_Texture_Header*)pointer;
	unsigned int u32NumSurfs;

	// perform checks for old PVR psPVRHeader
	if(psPVRHeader->dwHeaderSize!=sizeof(PVR_Texture_Header))
	{	// Header V1
		if(psPVRHeader->dwHeaderSize==PVRTEX_V1_HEADER_SIZE)
		{	// react to old psPVRHeader: i.e. fill in numsurfs as this is missing from old header
			PVRTErrorOutputDebug("PVRTTextureLoadFromPointer warning: this is an old pvr"
				" - you can use PVRTexTool to update its header.\n");
			if(psPVRHeader->dwpfFlags&PVRTEX_CUBEMAP)
				u32NumSurfs = 6;
			else
				u32NumSurfs = 1;
		}
		else
		{	// not a pvr at all
			PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: not a valid pvr.\n");
			return PVR_FAIL;
		}
	}
	else
	{	// Header V2
		if(psPVRHeader->dwNumSurfs<1)
		{	// encoded with old version of PVRTexTool before zero numsurfs bug found.
			if(psPVRHeader->dwpfFlags & PVRTEX_CUBEMAP)
				u32NumSurfs = 6;
			else
				u32NumSurfs = 1;
		}
		else
		{
			u32NumSurfs = psPVRHeader->dwNumSurfs;
		}
	}

	GLuint textureName;
	GLenum eTextureFormat = 0;
	GLenum eTextureInternalFormat = 0;	// often this is the same as textureFormat, but not for BGRA8888 on the iPhone, for instance
	GLenum eTextureType = 0;
	GLenum eTarget;

	bool bIsPVRTCSupported = CPVRTgles2Ext::IsGLExtensionSupported("GL_IMG_texture_compression_pvrtc");
#ifndef TARGET_OS_IPHONE
	bool bIsBGRA8888Supported  = CPVRTgles2Ext::IsGLExtensionSupported("GL_IMG_texture_format_BGRA8888");
#else
	bool bIsBGRA8888Supported  = CPVRTgles2Ext::IsGLExtensionSupported("GL_APPLE_texture_format_BGRA8888");
#endif
	bool bIsFloat16Supported = CPVRTgles2Ext::IsGLExtensionSupported("GL_OES_texture_half_float");
	bool bIsFloat32Supported = CPVRTgles2Ext::IsGLExtensionSupported("GL_OES_texture_float");
#ifndef TARGET_OS_IPHONE
	bool bIsETCSupported = CPVRTgles2Ext::IsGLExtensionSupported("GL_OES_compressed_ETC1_RGB8_texture");
#endif
	*texName = 0;	// install warning value
	bool bIsCompressedFormatSupported = false, bIsCompressedFormat = false;

	/* Only accept untwiddled data UNLESS texture format is PVRTC */
	if ( ((psPVRHeader->dwpfFlags & PVRTEX_TWIDDLE) == PVRTEX_TWIDDLE)
		&& ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)!=OGL_PVRTC2)
		&& ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)!=OGL_PVRTC4) )
	{
		// We need to load untwiddled textures -- GL will twiddle for us.
		PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: texture should be untwiddled.\n");
		return PVR_FAIL;
	}
	
	unsigned int ePixelType = psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE;

	switch(ePixelType)
	{
	case OGL_RGBA_4444:
		eTextureFormat = eTextureInternalFormat = GL_RGBA;
		eTextureType = GL_UNSIGNED_SHORT_4_4_4_4;
		break;

	case OGL_RGBA_5551:
		eTextureFormat = eTextureInternalFormat = GL_RGBA ;
		eTextureType = GL_UNSIGNED_SHORT_5_5_5_1;
		break;

	case OGL_RGBA_8888:
		eTextureFormat = eTextureInternalFormat = GL_RGBA;
		eTextureType = GL_UNSIGNED_BYTE ;
		break;

	/* New OGL Specific Formats Added */

	case OGL_RGB_565:
		eTextureFormat = eTextureInternalFormat = GL_RGB ;
		eTextureType = GL_UNSIGNED_SHORT_5_6_5;
		break;

	case OGL_RGB_555:
		PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: pixel type OGL_RGB_555 not supported.\n");
		return PVR_FAIL; // Deal with exceptional case

	case OGL_RGB_888:
		eTextureFormat = eTextureInternalFormat = GL_RGB ;
		eTextureType = GL_UNSIGNED_BYTE;
		break;

	case OGL_I_8:
		eTextureFormat = eTextureInternalFormat = GL_LUMINANCE;
		eTextureType = GL_UNSIGNED_BYTE;
		break;

	case OGL_AI_88:
		eTextureFormat = eTextureInternalFormat = GL_LUMINANCE_ALPHA ;
		eTextureType = GL_UNSIGNED_BYTE;
		break;


	case MGLPT_PVRTC2:
	case OGL_PVRTC2:
		if(bIsPVRTCSupported)
		{
			bIsCompressedFormatSupported = bIsCompressedFormat = true;
			eTextureFormat = psPVRHeader->dwAlphaBitMask==0 ? GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG : GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG ;	// PVRTC2
		}
		else
		{
			if(bAllowDecompress)
			{
				bIsCompressedFormatSupported = false;
				bIsCompressedFormat = true;
				eTextureFormat = eTextureInternalFormat = GL_RGBA;
				eTextureType = GL_UNSIGNED_BYTE;
				PVRTErrorOutputDebug("PVRTTextureLoadFromPointer warning: PVRTC2 not supported. Converting to RGBA8888 instead.\n");
			}
			else
			{
				PVRTErrorOutputDebug("PVRTTextureLoadFromPointer error: PVRTC2 not supported.\n");
				return PVR_FAIL;
			}
		}
		break;

	case MGLPT_PVRTC4:
	case OGL_PVRTC4:
		if(bIsPVRTCSupported)
		{
			bIsCompressedFormatSupported = bIsCompressedFormat = true;
			eTextureFormat = psPVRHeader->dwAlphaBitMask==0 ? GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG : GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG ;	// PVRTC4
		}
		else
		{
			if(bAllowDecompress)
			{
				bIsCompressedFormatSupported = false;
				bIsCompressedFormat = true;
				eTextureFormat = eTextureInternalFormat = GL_RGBA;
				eTextureType = GL_UNSIGNED_BYTE;
				PVRTErrorOutputDebug("PVRTTextureLoadFromPointer warning: PVRTC4 not supported. Converting to RGBA8888 instead.\n");
			}
			else
			{
				PVRTErrorOutputDebug("PVRTTextureLoadFromPointer error: PVRTC4 not supported.\n");
				return PVR_FAIL;
			}
		}
		break;
	case OGL_A_8:
		eTextureFormat = eTextureInternalFormat = GL_ALPHA;
		eTextureType = GL_UNSIGNED_BYTE;
		break;

	case OGL_BGRA_8888:
		if(bIsBGRA8888Supported)
		{
			eTextureType = GL_UNSIGNED_BYTE;
#ifndef __APPLE__
			eTextureFormat = eTextureInternalFormat = GL_BGRA;
#else
			eTextureFormat = GL_BGRA;
			eTextureInternalFormat = GL_RGBA;
#endif
		}
		else
		{
			PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: Unable to load GL_BGRA texture as extension GL_IMG_texture_format_BGRA8888 is unsupported.\n");
			return PVR_FAIL;
		}
		break;
	case D3D_ABGR_16161616F:
		if(bIsFloat16Supported)
		{
			eTextureFormat = eTextureInternalFormat =  GL_RGBA ;
			eTextureType = GL_HALF_FLOAT_OES;
		}
		break;
	case D3D_ABGR_32323232F:
		if(bIsFloat32Supported)
		{
			eTextureFormat = eTextureInternalFormat =  GL_RGBA ;
			eTextureType = GL_FLOAT;
		}
		break;

#ifndef TARGET_OS_IPHONE
	case ETC_RGB_4BPP:
		if(bIsETCSupported)
		{
			bIsCompressedFormatSupported = bIsCompressedFormat = true;
			eTextureFormat = GL_ETC1_RGB8_OES;
		}
		else
		{
			if(bAllowDecompress)
			{
				bIsCompressedFormatSupported = false;
				bIsCompressedFormat = true;
				eTextureFormat = GL_RGBA;
				eTextureType = GL_UNSIGNED_BYTE;
				PVRTErrorOutputDebug("PVRTTextureLoadFromPointer warning: ETC not supported. Converting to RGBA8888 instead.\n");
			}
			else
			{
				PVRTErrorOutputDebug("PVRTTextureLoadFromPointer error: ETC not supported.\n");
				return PVR_FAIL;
			}
		}
		break;
#endif

	default:											// NOT SUPPORTED
		PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: pixel type not supported.\n");
		return PVR_FAIL;
	}

	// load the texture up
	glPixelStorei(GL_UNPACK_ALIGNMENT,1);				// Never have row-aligned in psPVRHeaders

	glGenTextures(1, &textureName);

	//  check that this data is cube map data or not.
	if(psPVRHeader->dwpfFlags & PVRTEX_CUBEMAP)
		eTarget = GL_TEXTURE_CUBE_MAP;
	else
		eTarget = GL_TEXTURE_2D;

	glBindTexture(eTarget, textureName);

	if(glGetError())
	{
		PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: glBindTexture() failed.\n");
		return PVR_FAIL;
	}

	for(unsigned int i=0; i<u32NumSurfs; i++)
	{
		char *theTexturePtr = (texPtr? (char*)texPtr :  (char*)psPVRHeader + psPVRHeader->dwHeaderSize) + psPVRHeader->dwTextureDataSize * i;
		char *theTextureToLoad = 0;
		int		nMIPMapLevel;
		int		nTextureLevelsNeeded = (psPVRHeader->dwpfFlags & PVRTEX_MIPMAP)? psPVRHeader->dwMipMapCount : 0;
		unsigned int		nSizeX= psPVRHeader->dwWidth, nSizeY = psPVRHeader->dwHeight;
		unsigned int		CompressedImageSize = 0;

		for(nMIPMapLevel = 0; nMIPMapLevel <= nTextureLevelsNeeded; nSizeX=PVRT_MAX(nSizeX/2, (unsigned int)1), nSizeY=PVRT_MAX(nSizeY/2, (unsigned int)1), nMIPMapLevel++)
		{
			theTextureToLoad = theTexturePtr;

			// Load the Texture

			// If the texture is PVRTC or ETC then use GLCompressedTexImage2D
			if(bIsCompressedFormat)
			{
				/* Calculate how many bytes this MIP level occupies */
				if ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)==OGL_PVRTC2)
				{
					CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC2_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC2_MIN_TEXHEIGHT) * psPVRHeader->dwBitCount) / 8;
				}
				else if ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)==OGL_PVRTC4)
				{
					CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC4_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC4_MIN_TEXHEIGHT) * psPVRHeader->dwBitCount) / 8;
				}
				else
				{// ETC
					CompressedImageSize = ( PVRT_MAX(nSizeX, ETC_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, ETC_MIN_TEXHEIGHT) * psPVRHeader->dwBitCount) / 8;
				}

				if(((signed int)nMIPMapLevel - (signed int)nLoadFromLevel) >= 0)
				{
					if(bIsCompressedFormatSupported)
					{
						if(psPVRHeader->dwpfFlags&PVRTEX_CUBEMAP)
						{
							/* Load compressed texture data at selected MIP level */
							glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, nMIPMapLevel-nLoadFromLevel, eTextureFormat, nSizeX, nSizeY, 0,
											CompressedImageSize, theTextureToLoad);
						}
						else
						{
							/* Load compressed texture data at selected MIP level */
							glCompressedTexImage2D(GL_TEXTURE_2D, nMIPMapLevel-nLoadFromLevel, eTextureFormat, nSizeX, nSizeY, 0,
											CompressedImageSize, theTextureToLoad);

						}
					}
					else
					{
						// Convert PVRTC to 32-bit
						PVRTuint8 *u8TempTexture = (PVRTuint8*)malloc(nSizeX*nSizeY*4);
						if ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)==OGL_PVRTC2)
						{
							PVRTDecompressPVRTC(theTextureToLoad, 1, nSizeX, nSizeY, u8TempTexture);
						}
						else if((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)==OGL_PVRTC4)
						{
							PVRTDecompressPVRTC(theTextureToLoad, 0, nSizeX, nSizeY, u8TempTexture);
						}
						else
						{	// ETC
							PVRTDecompressETC(theTextureToLoad, nSizeX, nSizeY, u8TempTexture, 0);
						}


						if(psPVRHeader->dwpfFlags&PVRTEX_CUBEMAP)
						{// Load compressed cubemap data at selected MIP level
							// Upload the texture as 32-bits
							glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i,nMIPMapLevel-nLoadFromLevel,GL_RGBA,
								nSizeX,nSizeY,0, GL_RGBA,GL_UNSIGNED_BYTE,u8TempTexture);
							FREE(u8TempTexture);
						}
						else
						{// Load compressed 2D data at selected MIP level
							// Upload the texture as 32-bits
							glTexImage2D(GL_TEXTURE_2D,nMIPMapLevel-nLoadFromLevel,GL_RGBA,
								nSizeX,nSizeY,0, GL_RGBA,GL_UNSIGNED_BYTE,u8TempTexture);
							FREE(u8TempTexture);
						}
					}
				}
			}
			else
			{
				if(((signed int)nMIPMapLevel - (signed int)nLoadFromLevel) >= 0)
				{
					if(psPVRHeader->dwpfFlags&PVRTEX_CUBEMAP)
					{
						/* Load uncompressed texture data at selected MIP level */
						glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i,nMIPMapLevel-nLoadFromLevel,eTextureInternalFormat,nSizeX,nSizeY,
							0, eTextureFormat,eTextureType,theTextureToLoad);
					}
					else
					{
						/* Load uncompressed texture data at selected MIP level */
						glTexImage2D(GL_TEXTURE_2D,nMIPMapLevel-nLoadFromLevel,eTextureInternalFormat,nSizeX,nSizeY,0,eTextureFormat,eTextureType,theTextureToLoad);
					}
				}
			}



			if(glGetError())
			{
				PVRTErrorOutputDebug("PVRTTextureLoadFromPointer failed: glTexImage2D() failed.\n");
				return PVR_FAIL;
			}

			// offset the texture pointer by one mip-map level

			/* PVRTC case */
			if ( bIsCompressedFormat )
			{
				theTexturePtr += CompressedImageSize;
			}
			else
			{
				/* New formula that takes into account bit counts inferior to 8 (e.g. 1 bpp) */
				theTexturePtr += (nSizeX * nSizeY * psPVRHeader->dwBitCount + 7) / 8;
			}
		}
	}

	*texName = textureName;

	if(psTextureHeader)
	{
		*(PVR_Texture_Header*)psTextureHeader = *psPVRHeader;
		((PVR_Texture_Header*)psTextureHeader)->dwPVR = PVRTEX_IDENTIFIER;
		((PVR_Texture_Header*)psTextureHeader)->dwNumSurfs = u32NumSurfs;
	}

	if(eTextureType==GL_FLOAT || eTextureType==GL_HALF_FLOAT_OES)
	{
		if(!psPVRHeader->dwMipMapCount)
		{	// Texture filter modes are limited to these for float textures
			glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri(eTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		}
		else
		{
			glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
			glTexParameteri(eTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		}
	}
	else
	{
		if(!psPVRHeader->dwMipMapCount)
		{
			glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
			glTexParameteri(eTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		}
		else
		{
			glTexParameteri(eTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
			glTexParameteri(eTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		}
	}

	if(
		(psPVRHeader->dwWidth & (psPVRHeader->dwWidth - 1)) |
		(psPVRHeader->dwHeight & (psPVRHeader->dwHeight - 1)))
	{
		/*
			NPOT textures requires the wrap mode to be set explicitly to
			GL_CLAMP_TO_EDGE or the texture will be inconsistent.
		*/
		glTexParameteri(eTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(eTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	}
	else
	{
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	}

	return PVR_SUCCESS;
}
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;
}
Ejemplo n.º 12
0
/*!***************************************************************************
 @Function		Draw
 @Input			i32StartPath Path to start drawing from
 @Input			i32EndPath	Path to end drawing on
 @Returns		True on success
 @Description	Draw a set of the paths loaded from the file. If no argument
				is specified this function will draw all paths.
*****************************************************************************/
bool CPVRTPVGObject::Draw(int i32StartPath, int i32EndPath)
{
	if (!m_bInitialized)
	{
		// This set has not been initialised so return.
		return false;
	}

	if(i32EndPath < i32StartPath)
	{
		i32EndPath = m_i32NumPaths;
	}

	i32StartPath = PVRT_MAX(0, i32StartPath);
	i32EndPath = PVRT_MIN(i32EndPath, m_i32NumPaths);

	for(int i = i32StartPath; i < i32EndPath; ++i)
	{
		// Set the blending options. PVG files only support standard translucency.
		if(m_pPaths[i].m_bNeedsBlending)
		{
			vgSeti(VG_BLEND_MODE, VG_BLEND_SRC_OVER);
		}
		else
		{
			vgSeti(VG_BLEND_MODE, VG_BLEND_SRC);
		}

		// Check whether this one is a path without fill or stroke and ignore it.
		if(m_pPaths[i].m_paintMode == 0)
		{
			continue;
		}

		// Fill the parameters for the current Fill Paint
		// Check if the paint is present, if it is different than the previous one or if it is the first one.
		if(((m_pPaths[i].m_paintMode & VG_FILL_PATH) && m_pPaths[i].m_bIsNewFill) || (i==i32StartPath))
		{
			vgSeti(VG_FILL_RULE, m_pPaths[i].m_fillRule);

			vgSetPaint(m_pPaths[i].m_fillPaint, VG_FILL_PATH);
		}

		// Fill the parameters for the current Stroke Paint
		if(((m_pPaths[i].m_paintMode & VG_STROKE_PATH) && m_pPaths[i].m_bIsNewStroke) || (i==i32StartPath))
        {
			vgSetf(VG_STROKE_LINE_WIDTH, m_pPaths[i].m_fStrokeWidth);
			vgSeti(VG_STROKE_CAP_STYLE,	 m_pPaths[i].m_capStyle);
			vgSeti(VG_STROKE_JOIN_STYLE, m_pPaths[i].m_joinStyle);
			vgSetf(VG_STROKE_MITER_LIMIT,m_pPaths[i].m_fMiterLimit);

			// Get current stroke 'dash' if any
			if (m_pPaths[i].m_ui32DashID != 666)
			{
				vgSetf(VG_STROKE_DASH_PHASE, m_pPaths[i].m_fDashPhase);
				vgSetfv(VG_STROKE_DASH_PATTERN, m_pPaths[i].m_ui32NumDashes, m_pPaths[i].m_fDashValues);
			}
			else
			{
				vgSetfv(VG_STROKE_DASH_PATTERN, 0, (VGfloat *) 0); // disable dashes
			}

 			vgSetPaint(m_pPaths[i].m_strokePaint, VG_STROKE_PATH);
        }

		// Draw this path.
		vgDrawPath(m_pPaths[i].m_path, m_pPaths[i].m_paintMode);
	}

	// Success!
	return true;
}
Ejemplo n.º 13
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 OGLES2Iridescence::RenderScene()
{
	// Keyboard input (cursor up/down to change thickness variation)
	if (PVRShellIsKeyPressed(PVRShellKeyNameUP))
	{
		m_fMaxVariation += 1.0f;
	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameDOWN))
	{
		m_fMaxVariation = PVRT_MAX(0.0f, m_fMaxVariation - 1.0f);
	}

	// Keyboard input (cursor left/right to change minimum thickness)
	if (PVRShellIsKeyPressed(PVRShellKeyNameRIGHT))
	{
		m_fMinThickness += 1.0f;
	}
	else if (PVRShellIsKeyPressed(PVRShellKeyNameLEFT))
	{
		m_fMinThickness = PVRT_MAX(0.0f, m_fMinThickness - 1.0f);
	}

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

	m_Print3D.Print3D(2.0f, 10.0f, 0.75f, 0xffffffff, "Minimum Thickness:");
	m_Print3D.Print3D(2.0f, 15.0f, 0.75f, 0xffffffff, "%8.0f nm", m_fMinThickness);
	m_Print3D.Print3D(2.0f, 20.0f, 0.75f, 0xffffffff, "Maximum Variation:");
	m_Print3D.Print3D(2.0f, 25.0f, 0.75f, 0xffffffff, "%8.0f nm", m_fMaxVariation);

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

	return true;
}
Ejemplo n.º 14
0
unsigned int GLES2D_CreateTexturePVRFromPointer( int *w, int *h, const void * const pointer, GLuint * const texName )
{
	const void * const texPtr = NULL;
	const unsigned int nLoadFromLevel = 0;
	const void *psTextureHeader = NULL;

	PVR_Texture_Header* psPVRHeader = (PVR_Texture_Header*)pointer;

	*w = (int) psPVRHeader->dwWidth;
	*h = (int) psPVRHeader->dwHeight;

	unsigned int u32NumSurfs;

	// perform checks for old PVR psPVRHeader
	if(psPVRHeader->dwHeaderSize!=sizeof(PVR_Texture_Header))
	{	// Header V1
		if(psPVRHeader->dwHeaderSize==PVRTEX_V1_HEADER_SIZE)
		{	// react to old psPVRHeader: i.e. fill in numsurfs as this is missing from old header
			printf("PVRTTexture:PVRTLoadPartialTextureFromPointer warning: this is an old pvr"
				" - you can use PVRTexTool to update its header.\n");
			if(psPVRHeader->dwpfFlags&PVRTEX_CUBEMAP)
				u32NumSurfs = 6;
			else
				u32NumSurfs = 1;
		}
		else
		{	// not a pvr at all
			printf("PVRTTexture:PVRTLoadPartialTextureFromPointer failed: not a valid pvr.\n");
			return 0;
		}
	}
	else
	{	// Header V2
		if(psPVRHeader->dwNumSurfs<1)
		{	// encoded with old version of PVRTexTool before zero numsurfs bug found.
			if(psPVRHeader->dwpfFlags & PVRTEX_CUBEMAP)
				u32NumSurfs = 6;
			else
				u32NumSurfs = 1;
		}
		else
		{
			u32NumSurfs = psPVRHeader->dwNumSurfs;
		}
	}

	GLuint textureName;
	GLenum textureFormat = 0;
	GLenum textureType = GL_RGB;

	int IsPVRTCSupported = 1;
	int IsBGRA8888Supported  = 0;

	*texName = 0;	// install warning value

	int IsCompressedFormatSupported = 0, IsCompressedFormat = 0;

	/* Only accept untwiddled data UNLESS texture format is PVRTC */
	if ( ((psPVRHeader->dwpfFlags & PVRTEX_TWIDDLE) == PVRTEX_TWIDDLE)
		&& ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)!=OGL_PVRTC2)
		&& ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)!=OGL_PVRTC4) )
	{
		// We need to load untwiddled textures -- hw will twiddle for us.
		printf("PVRTTexture:PVRTLoadPartialTextureFromPointer failed: texture should be untwiddled.\n");
		return 0;
	}

	switch(psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)
	{
	case OGL_RGBA_4444:
		textureFormat = GL_UNSIGNED_SHORT_4_4_4_4;
		textureType = GL_RGBA;
		break;

	case OGL_RGBA_5551:
		textureFormat = GL_UNSIGNED_SHORT_5_5_5_1;
		textureType = GL_RGBA;
		break;

	case OGL_RGBA_8888:
		textureFormat = GL_UNSIGNED_BYTE;
		textureType = GL_RGBA;
		break;

	/* New OGL Specific Formats Added */

	case OGL_RGB_565:
		textureFormat = GL_UNSIGNED_SHORT_5_6_5;
		textureType = GL_RGB;
		break;

	case OGL_RGB_555:
		printf("PVRTTexture:PVRTLoadPartialTextureFromPointer failed: pixel type OGL_RGB_555 not supported.\n");
		return 0; // Deal with exceptional case

	case OGL_RGB_888:
		textureFormat = GL_UNSIGNED_BYTE;
		textureType = GL_RGB;
		break;

	case OGL_I_8:
		textureFormat = GL_UNSIGNED_BYTE;
		textureType = GL_LUMINANCE;
		break;

	case OGL_AI_88:
		textureFormat = GL_UNSIGNED_BYTE;
		textureType = GL_LUMINANCE_ALPHA;
		break;

	case OGL_PVRTC2:
		if(IsPVRTCSupported)
		{
			IsCompressedFormatSupported = IsCompressedFormat = 1;
			textureFormat = psPVRHeader->dwAlphaBitMask==0 ? GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG : GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG ;	// PVRTC2
		}
		else
		{
			IsCompressedFormatSupported = 0;
			IsCompressedFormat = 1;
			textureFormat = GL_UNSIGNED_BYTE;
			textureType = GL_RGBA;
			printf("PVRTTexture:PVRTLoadPartialTextureFromPointer warning: PVRTC2 not supported. Converting to RGBA8888 instead.\n");
		}
		break;

	case OGL_PVRTC4:
		if(IsPVRTCSupported)
		{
			IsCompressedFormatSupported = IsCompressedFormat = 1;
			textureFormat = psPVRHeader->dwAlphaBitMask==0 ? GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG : GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG ;	// PVRTC4
		}
		else
		{
			IsCompressedFormatSupported = 0;
			IsCompressedFormat = 1;
			textureFormat = GL_UNSIGNED_BYTE;
			textureType = GL_RGBA;
			printf("PVRTTexture:PVRTLoadPartialTextureFromPointer warning: PVRTC4 not supported. Converting to RGBA8888 instead.\n");
		}
		break;

	case OGL_BGRA_8888:
		if(IsBGRA8888Supported)
		{
			textureFormat = GL_UNSIGNED_BYTE;
			textureType   = GL_BGRA;
			break;
		}
		else
		{
			printf("PVRTTexture:PVRTLoadPartialTextureFromPointer failed: Unable to load GL_BGRA texture as extension GL_IMG_texture_format_BGRA8888 is unsupported.\n");
			return 0;
		}
	default:											// NOT SUPPORTED
		printf("PVRTTexture:PVRTLoadPartialTextureFromPointer failed: pixel type not supported.\n");
		return 0;
	}

	// load the texture up
	glPixelStorei(GL_UNPACK_ALIGNMENT,1);				// Never have row-aligned in psPVRHeaders

	glGenTextures(1, &textureName);

	//  check that this data is cube map data or not.
	if(psPVRHeader->dwpfFlags & PVRTEX_CUBEMAP)
	{ // not in OGLES you don't
		printf("PVRTTexture:PVRTLoadPartialTextureFromPointer failed: cube map textures are not available in OGLES1.x.\n");
		return 0;
	}
	else
	{
		glBindTexture(GL_TEXTURE_2D, textureName);
	}

	if(glGetError())
	{
		printf("PVRTTexture:PVRTLoadPartialTextureFromPointer failed: glBindTexture() failed.\n");
		return 0;
	}

	int i;
	for(i=0; i<u32NumSurfs; i++)
	{
		char *theTexturePtr = (texPtr? (char*)texPtr :  (char*)psPVRHeader + psPVRHeader->dwHeaderSize) + psPVRHeader->dwTextureDataSize * i;
		char *theTextureToLoad = 0;
		int		nMIPMapLevel;
		int		nTextureLevelsNeeded = (psPVRHeader->dwpfFlags & PVRTEX_MIPMAP)? psPVRHeader->dwMipMapCount : 0;
		unsigned int		nSizeX= psPVRHeader->dwWidth, nSizeY = psPVRHeader->dwHeight;
		unsigned int		CompressedImageSize = 0;

		for(nMIPMapLevel = 0; nMIPMapLevel <= nTextureLevelsNeeded; nSizeX = PVRT_MAX(nSizeX/2, (unsigned int)1), nSizeY = PVRT_MAX(nSizeY/2, (unsigned int)1), nMIPMapLevel++)
		{
			// Do Alpha-swap if needed

			theTextureToLoad = theTexturePtr;

			// Load the Texture

			/* If the texture is PVRTC then use GLCompressedTexImage2D */
			if(IsCompressedFormat)
			{
				/* Calculate how many bytes this MIP level occupies */
				if ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)==OGL_PVRTC2)
				{
					CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC2_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC2_MIN_TEXHEIGHT) * psPVRHeader->dwBitCount + 7) / 8;
				}
				else
				{// PVRTC4 case
					CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC4_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC4_MIN_TEXHEIGHT) * psPVRHeader->dwBitCount + 7) / 8;
				}

				if(((signed int)nMIPMapLevel - (signed int)nLoadFromLevel) >= 0)
				{
					if(IsCompressedFormatSupported)
					{
						//if(psPVRHeader->dwpfFlags&PVRTEX_CUBEMAP)
						//{
						//	/* Load compressed texture data at selected MIP level */
						//	glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, nMIPMapLevel-nLoadFromLevel, textureFormat, nSizeX, nSizeY, 0,
						//					CompressedImageSize, theTextureToLoad);
						//}
						//else
						{
							/* Load compressed texture data at selected MIP level */
							glCompressedTexImage2D(GL_TEXTURE_2D, nMIPMapLevel-nLoadFromLevel, textureFormat, nSizeX, nSizeY, 0,
											CompressedImageSize, theTextureToLoad);

						}
					}
					else
					{
						// Convert PVRTC to 32-bit
						unsigned char *u8TempTexture = (unsigned char*)malloc(nSizeX*nSizeY*4);
						if ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)==OGL_PVRTC2)
						{
							printf("PVRTCDecompress Unsupported\n");
							//PVRTCDecompress(theTextureToLoad, 1, nSizeX, nSizeY, u8TempTexture);
						}
						else
						{// PVRTC4 case
							printf("PVRTCDecompress Unsupported\n");
							//PVRTCDecompress(theTextureToLoad, 0, nSizeX, nSizeY, u8TempTexture);
						}


						//if(psPVRHeader->dwpfFlags&PVRTEX_CUBEMAP)
						//{// Load compressed cubemap data at selected MIP level
						//	// Upload the texture as 32-bits
						//	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i,nMIPMapLevel-nLoadFromLevel,GL_RGBA,
						//		nSizeX,nSizeY,0, GL_RGBA,GL_UNSIGNED_BYTE,u8TempTexture);
						//	FREE(u8TempTexture);
						//}
						//else
						{// Load compressed 2D data at selected MIP level
							// Upload the texture as 32-bits
							glTexImage2D(GL_TEXTURE_2D,nMIPMapLevel-nLoadFromLevel,GL_RGBA,
								nSizeX,nSizeY,0, GL_RGBA,GL_UNSIGNED_BYTE,u8TempTexture);
							FREE(u8TempTexture);
						}
					}
				}
			}
			else
			{
				if(((signed int)nMIPMapLevel - (signed int)nLoadFromLevel) >= 0)
				{
					//if(psPVRHeader->dwpfFlags&PVRTEX_CUBEMAP)
					//{
					//	/* Load uncompressed texture data at selected MIP level */
					//	glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i,nMIPMapLevel-nLoadFromLevel,textureType,nSizeX,nSizeY,
					//		0, textureType,textureFormat,theTextureToLoad);
					//}
					//else
					{
						/* Load uncompressed texture data at selected MIP level */
						glTexImage2D(GL_TEXTURE_2D,nMIPMapLevel-nLoadFromLevel,textureType,nSizeX,nSizeY,0, textureType,textureFormat,theTextureToLoad);
					}
				}
			}



			if(glGetError())
			{
				printf("PVRTTexture:PVRTLoadPartialTextureFromPointer failed: glBindTexture() failed.\n");
				return 0;
			}

			// offset the texture pointer by one mip-map level

			/* PVRTC case */
			if ( IsCompressedFormat )
			{
				theTexturePtr += CompressedImageSize;
			}
			else
			{
				/* New formula that takes into account bit counts inferior to 8 (e.g. 1 bpp) */
				theTexturePtr += (nSizeX * nSizeY * psPVRHeader->dwBitCount + 7) / 8;
			}
		}
	}

	*texName = textureName;

	if(psTextureHeader)
	{
		*(PVR_Texture_Header*)psTextureHeader = *psPVRHeader;
		((PVR_Texture_Header*)psTextureHeader)->dwPVR = PVRTEX_IDENTIFIER;
		((PVR_Texture_Header*)psTextureHeader)->dwNumSurfs = u32NumSurfs;
	}

	return psPVRHeader->dwpfFlags|0x80000000;		// PVR psPVRHeader flags with topmost bit set so that it is non-zero
}