예제 #1
0
/*!***************************************************************************
 @Function Name		PVRTMatrixRotationZF
 @Output			mOut	Rotation matrix
 @Input				fAngle	Angle of the rotation
 @Description		Create an Z rotation matrix mOut.
*****************************************************************************/
void PVRTMatrixRotationZF(
	PVRTMATRIXf	&mOut,
	const float fAngle)
{
	float		fCosine, fSine;

	/* Precompute cos and sin */
#if defined(BUILD_DX9) || defined(BUILD_D3DM) || defined(BUILD_DX10)
	fCosine =	(float)PVRTFCOS(-fAngle);
    fSine =		(float)PVRTFSIN(-fAngle);
#else
	fCosine =	(float)PVRTFCOS(fAngle);
    fSine =		(float)PVRTFSIN(fAngle);
#endif

	/* Create the trigonometric matrix corresponding to Z Rotation */
	mOut.f[ 0]=fCosine;		mOut.f[ 4]=fSine;	mOut.f[ 8]=0.0f;	mOut.f[12]=0.0f;
	mOut.f[ 1]=-fSine;		mOut.f[ 5]=fCosine;	mOut.f[ 9]=0.0f;	mOut.f[13]=0.0f;
	mOut.f[ 2]=0.0f;		mOut.f[ 6]=0.0f;	mOut.f[10]=1.0f;	mOut.f[14]=0.0f;
	mOut.f[ 3]=0.0f;		mOut.f[ 7]=0.0f;	mOut.f[11]=0.0f;	mOut.f[15]=1.0f;
}
예제 #2
0
/*!***************************************************************************
 @Function			PVRTMatrixQuaternionRotationAxisF
 @Output			qOut	Rotation quaternion
 @Input				vAxis	Axis to rotate around
 @Input				fAngle	Angle to rotate
 @Description		Create quaternion corresponding to a rotation of fAngle
					radians around submitted vector.
*****************************************************************************/
void PVRTMatrixQuaternionRotationAxisF(
	PVRTQUATERNIONf		&qOut,
	const PVRTVECTOR3f	&vAxis,
	const float			fAngle)
{
	float	fSin, fCos;

	fSin = (float)PVRTFSIN(fAngle * 0.5f);
	fCos = (float)PVRTFCOS(fAngle * 0.5f);

	/* Create quaternion */
	qOut.x = vAxis.x * fSin;
	qOut.y = vAxis.y * fSin;
	qOut.z = vAxis.z * fSin;
	qOut.w = fCos;

	/* Normalise it */
	PVRTMatrixQuaternionNormalizeF(qOut);
}
예제 #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 OGLESParticles::RenderScene()
{
	int				i;
	PVRTMat4		mRotY;

	// Clear colour and depth buffers
	myglClearColor(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f), f2vt(1.0f));
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Enables depth testing
	glEnable(GL_DEPTH_TEST);

	//	Modify per-frame variables controlling the particle mouvements.
	float fSpeedCtrl = (float) (PVRTFSIN(m_fRot*0.01f)+1.0f)/2.0f;
	float fStopNo = 0.8f;
	float fStep = 0.1f;

	if(fSpeedCtrl > fStopNo)
		fStep = 0.0f;

	// Generate particles as needed.
	if((m_i32NumParticles < (int) g_ui32MaxParticles) && (fSpeedCtrl <= fStopNo))
	{
		int num_to_gen = (int) (RandPositiveFloat()*(g_ui32MaxParticles/100.0));

		if(num_to_gen == 0)
			num_to_gen = 1;

		for(i = 0; (i < num_to_gen) && (m_i32NumParticles < (int) g_ui32MaxParticles); ++i)
			SpawnParticle(&m_Particles[m_i32NumParticles++]);
	}

	// Build rotation matrix around axis Y.
	mRotY = PVRTMat4::RotationY(f2vt((m_fRot2*PVRT_PIf)/180.0f));

	for(i = 0; i < m_i32NumParticles; ++i)
	{
		// Transform particle with rotation matrix
		m_sParticleVTXPSBuf[i].x =	VERTTYPEMUL(mRotY.f[ 0], m_Particles[i].m_fPosition.x) +
								VERTTYPEMUL(mRotY.f[ 4], m_Particles[i].m_fPosition.y) +
								VERTTYPEMUL(mRotY.f[ 8], m_Particles[i].m_fPosition.z) +
											mRotY.f[12];
		m_sParticleVTXPSBuf[i].y =	VERTTYPEMUL(mRotY.f[ 1], m_Particles[i].m_fPosition.x) +
								VERTTYPEMUL(mRotY.f[ 5], m_Particles[i].m_fPosition.y) +
								VERTTYPEMUL(mRotY.f[ 9], m_Particles[i].m_fPosition.z) +
											mRotY.f[13];
		m_sParticleVTXPSBuf[i].z =	VERTTYPEMUL(mRotY.f[ 2], m_Particles[i].m_fPosition.x) +
								VERTTYPEMUL(mRotY.f[ 6], m_Particles[i].m_fPosition.y) +
								VERTTYPEMUL(mRotY.f[10], m_Particles[i].m_fPosition.z) +
											mRotY.f[14];

		m_sParticleVTXPSBuf[i].fSize = m_Particles[i].m_fSize;

		m_sNormalColour[i].r  = vt2b(m_Particles[i].m_fColour.x);
		m_sNormalColour[i].g  = vt2b(m_Particles[i].m_fColour.y);
		m_sNormalColour[i].b  = vt2b(m_Particles[i].m_fColour.z);
		m_sNormalColour[i].a  = (unsigned char)255;

		m_sReflectColour[i].r  = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.x, g_fFactor));
		m_sReflectColour[i].g  = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.y, g_fFactor));
		m_sReflectColour[i].b  = vt2b(VERTTYPEMUL(m_Particles[i].m_fColour.z, g_fFactor));
		m_sReflectColour[i].a  = (unsigned char)255;
	}

	glBindBuffer(GL_ARRAY_BUFFER, m_i32VertVboID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(SVtxPointSprite)*m_i32NumParticles, m_sParticleVTXPSBuf,GL_DYNAMIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, m_i32ColAVboID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(SColors)*m_i32NumParticles, m_sNormalColour,GL_DYNAMIC_DRAW);

	glBindBuffer(GL_ARRAY_BUFFER, m_i32ColBVboID);
	glBufferData(GL_ARRAY_BUFFER, sizeof(SColors)*m_i32NumParticles, m_sReflectColour,GL_DYNAMIC_DRAW);

	// clean up render states
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);

	//	Draw floor.

	// Save modelview matrix
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	myglRotate(f2vt(-m_fRot), f2vt(0.0f), f2vt(1.0f), f2vt(0.0f));

	// setup render states
	glDisable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);
	glDisable(GL_CULL_FACE);
	glEnable(GL_BLEND);

	// Set texture and texture environment
	glBindTexture(GL_TEXTURE_2D, m_ui32FloorTexName);
	glBlendFunc(GL_ONE, GL_ONE);

	// Render floor
	RenderFloor();

	// clean up render states
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);

	glPopMatrix();

	//	Render particles reflections.

	// set up render states
	glDisable(GL_LIGHTING);
	glEnable(GL_TEXTURE_2D);

	glDepthFunc(GL_ALWAYS);
	glDisable(GL_CULL_FACE);

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

	myglTexEnv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glBindTexture(GL_TEXTURE_2D, m_ui32TexName);

	// Set model view matrix
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	myglScale(f2vt(1.0f), f2vt(-1.0f), f2vt(1.0f));
	myglTranslate(f2vt(0.0f), f2vt(0.01f), f2vt(0.0f));

	glEnable(GL_POINT_SPRITE_OES);

	if(((int)(m_i32NumParticles * 0.5f)) > 0)
       RenderParticle(((int)(m_i32NumParticles*0.5f)),true);

	glPopMatrix();

	//	Render particles.

	// Sets the model view matrix
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();

	if(m_i32NumParticles > 0)
        RenderParticle(m_i32NumParticles,false);

	glPopMatrix();

	glDisable(GL_POINT_SPRITE_OES);

	PVRTVec3 Force = PVRTVec3(f2vt(0.0f), f2vt(0.0f), f2vt(0.0f));
	Force.x = f2vt(1000.0f*(float)PVRTFSIN(m_fRot*0.01f));

	for(i = 0; i < m_i32NumParticles; ++i)
	{
		/*
			Move the particle.
			If the particle exceeds its lifetime, create a new one in its place.
		*/
		if(m_Particles[i].Step(f2vt(fStep), Force))
			SpawnParticle(&m_Particles[i]);
	}

	// clean up render states
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D);
	glEnable(GL_LIGHTING);

	// Increase rotation angles
	m_fRot += 1;
	m_fRot2 = m_fRot + 36;

	// Unbinds the vertex buffer if we are using OpenGL ES 1.1
	glBindBuffer(GL_ARRAY_BUFFER, 0);

	// Display info text.
	m_Print3D.DisplayDefaultTitle("Particles", "Using point sprites", ePVRTPrint3DSDKLogo);
	m_Print3D.Flush();

	return true;
}
예제 #4
0
/*!***************************************************************************
 @Function			PVRTMatrixQuaternionSlerpF
 @Output			qOut	Result of the interpolation
 @Input				qA		First quaternion to interpolate from
 @Input				qB		Second quaternion to interpolate from
 @Input				t		Coefficient of interpolation
 @Description		Perform a Spherical Linear intERPolation between quaternion A
					and quaternion B at time t. t must be between 0.0f and 1.0f
*****************************************************************************/
void PVRTMatrixQuaternionSlerpF(
	PVRTQUATERNIONf			&qOut,
	const PVRTQUATERNIONf	&qA,
	const PVRTQUATERNIONf	&qB,
	const float				t)
{
	float		fCosine, fAngle, A, B;

	/* Parameter checking */
	if (t<0.0f || t>1.0f)
	{
		_RPT0(_CRT_WARN, "PVRTMatrixQuaternionSlerp : Bad parameters\n");
		qOut.x = 0;
		qOut.y = 0;
		qOut.z = 0;
		qOut.w = 1;
		return;
	}

	/* Find sine of Angle between Quaternion A and B (dot product between quaternion A and B) */
	fCosine = qA.w*qB.w + qA.x*qB.x + qA.y*qB.y + qA.z*qB.z;

	if (fCosine < 0)
	{
		PVRTQUATERNIONf qi;

		/*
			<http://www.magic-software.com/Documentation/Quaternions.pdf>

			"It is important to note that the quaternions q and -q represent
			the same rotation... while either quaternion will do, the
			interpolation methods require choosing one over the other.

			"Although q1 and -q1 represent the same rotation, the values of
			Slerp(t; q0, q1) and Slerp(t; q0,-q1) are not the same. It is
			customary to choose the sign... on q1 so that... the angle
			between q0 and q1 is acute. This choice avoids extra
			spinning caused by the interpolated rotations."
		*/
		qi.x = -qB.x;
		qi.y = -qB.y;
		qi.z = -qB.z;
		qi.w = -qB.w;

		PVRTMatrixQuaternionSlerpF(qOut, qA, qi, t);
		return;
	}

	fCosine = PVRT_MIN(fCosine, 1.0f);
	fAngle = (float)PVRTFACOS(fCosine);

	/* Avoid a division by zero */
	if (fAngle==0.0f)
	{
		qOut = qA;
		return;
	}

	/* Precompute some values */
	A = (float)(PVRTFSIN((1.0f-t)*fAngle) / PVRTFSIN(fAngle));
	B = (float)(PVRTFSIN(t*fAngle) / PVRTFSIN(fAngle));

	/* Compute resulting quaternion */
	qOut.x = A * qA.x + B * qB.x;
	qOut.y = A * qA.y + B * qB.y;
	qOut.z = A * qA.z + B * qB.z;
	qOut.w = A * qA.w + B * qB.w;

	/* Normalise result */
	PVRTMatrixQuaternionNormalizeF(qOut);
}