示例#1
0
Matrix3 Matrix3::Adjoint ()
{
	/* Find the Adjoint
	 * http://www.mathwords.com/a/adjoint.htm
	 */

	Matrix3 temp;

	// CoFactor(Mirror of minors)
	temp._data[0] = this->_data[4]*this->_data[8] - this->_data[5]*this->_data[7];
	temp._data[1] = this->_data[3]*this->_data[8] - this->_data[5]*this->_data[6];
	temp._data[2] = this->_data[3]*this->_data[7] - this->_data[4]*this->_data[6];

	temp._data[3] = this->_data[1]*this->_data[8] - this->_data[2]*this->_data[7];
	temp._data[4] = this->_data[0]*this->_data[8] - this->_data[2]*this->_data[6];
	temp._data[5] = this->_data[0]*this->_data[7] - this->_data[1]*this->_data[6];

	temp._data[6] = this->_data[1]*this->_data[5] - this->_data[2]*this->_data[4];
	temp._data[7] = this->_data[0]*this->_data[5] - this->_data[2]*this->_data[3];
	temp._data[8] = this->_data[0]*this->_data[4] - this->_data[1]*this->_data[3];

	// Matrix of cofactors
	// + - +
	// - + -
	// + - +
	for(int i=1;i<9;i+=2)
		temp._data[i] *= -1;

	// Finally the adjoint of A is the transpose of the cofactor matrix
	temp = temp.Transpose();

	return temp;
}
示例#2
0
Matrix4 Camera::view_matrix() {	
	if (!view_needs_rebuild_) { return view_matrix_; }

	// http://stackoverflow.com/questions/12777675/view-matrix-from-quaternion
	// http://www.scratchapixel.com/lessons/3d-basic-lessons/lesson-4-geometry/conventions-again-row-major-vs-column-major-vector/
	// TODO Might need to revist this if this doesn't work out. 
	// Figure out what the transpose does.

	view_matrix_ = Matrix4::IDENTITY;

	// This is most efficiently done using 3x3 Matrices
	Matrix3 rotation;
	orientation_.ToRotationMatrix(rotation);

	// Make the translation relative to new axes
	Matrix3 transposeRotation = rotation.Transpose();
	Vector3 trans = -transposeRotation * position_;

	// Make final matrix
	view_matrix_ = transposeRotation; // fills upper 3x3
	view_matrix_[0][3] = trans.x;
	view_matrix_[1][3] = trans.y;
	view_matrix_[2][3] = trans.z;	

	view_needs_rebuild_ = false;

	return view_matrix_;
}
示例#3
0
    //-----------------------------------------------------------------------
	void Frustum::updateViewImpl(void) const
	{
		// ----------------------
		// Update the view matrix
		// ----------------------

		// View matrix is:
		//
		//  [ Lx  Uy  Dz  Tx  ]
		//  [ Lx  Uy  Dz  Ty  ]
		//  [ Lx  Uy  Dz  Tz  ]
		//  [ 0   0   0   1   ]
		//
		// Where T = -(Transposed(Rot) * Pos)

		// This is most efficiently done using 3x3 Matrices

		// Get orientation from quaternion

		if (!mCustomViewMatrix)
		{
			Matrix3 rot;
			const Quaternion& orientation = getOrientationForViewUpdate();
			const Vector3& position = getPositionForViewUpdate();
			orientation.ToRotationMatrix(rot);

			// Make the translation relative to new axes
			Matrix3 rotT = rot.Transpose();
			Vector3 trans = -rotT * position;

			// Make final matrix
			mViewMatrix = Matrix4::IDENTITY;
			mViewMatrix = rotT; // fills upper 3x3
			mViewMatrix[0][3] = trans.x;
			mViewMatrix[1][3] = trans.y;
			mViewMatrix[2][3] = trans.z;

			// Deal with reflections
			if (mReflect)
			{
				mViewMatrix = mViewMatrix * mReflectMatrix;
			}
		}

		mRecalcView = false;

		// Signal to update frustum clipping planes
		mRecalcFrustumPlanes = true;
		// Signal to update world space corners
		mRecalcWorldSpaceCorners = true;
		// Signal to update frustum if oblique plane enabled,
		// since plane needs to be in view space
		if (mObliqueDepthProjection)
		{
			mRecalcFrustum = true;
		}
	}
 void SpriteShader::SetParameter(const std::string &parameterName, const Matrix3 &value)
 {
     if(pimpl->uniforms.find(parameterName) == pimpl->uniforms.end())
         throw std::runtime_error("Couldn't find the named SpriteEffect parameter: " + parameterName);
     
     auto &uniformData = pimpl->uniforms[parameterName];
     
     if(uniformData.type != GL_FLOAT_MAT3)
         throw std::runtime_error("Type mismatch for named SpriteEffect paramater: " + parameterName);
     
     glUniformMatrix3fv(uniformData.location, 1, GL_FALSE, value.Transpose());
 }
Matrix3 RigidBody::GetInverseInertialTensor() const
{
	Vector3 diagonal = GetLocalInverseInertialTensor();
	Matrix3 localInverseTensor = Matrix3::ZERO;
	localInverseTensor[0][0] = diagonal.x;
	localInverseTensor[1][1] = diagonal.y;
	localInverseTensor[2][2] = diagonal.z;

	Matrix3 rotation;
	GetTransformation().extract3x3Matrix(rotation);

	return rotation.Transpose() * localInverseTensor * rotation;
}
示例#6
0
void GLSLProgram<real>::SetupCamera()
{
	RenderState<real>* glState = RenderState<real>::Get();
	Camera<real>* camera = glState->GetCamera();
	Matrix4<float> projectionMatrix = camera->GetProjectionMatrix();
	Matrix4<float> viewMatrix = camera->GetGlobalToLocal();
	Matrix4<float> modelMatrix = glState->GetModelMatrix();
	Matrix4<float> modelViewProjectionMatrix = projectionMatrix * viewMatrix * modelMatrix;
	Matrix3<float> normalMatrix = modelMatrix.SubMatrix3( 0, 0 );
	normalMatrix.Inverse();
	normalMatrix.Transpose();

	// Model, view and projection matrices, camera position
	glUniformMatrix4fv( mModelMatrixLocation, 1, true, modelMatrix.GetArray() );
	glUniformMatrix4fv( mViewMatrixLocation, 1, true, viewMatrix.GetArray() );
	glUniformMatrix4fv( mProjectionMatrixLocation, 1, true, projectionMatrix.GetArray() );
	glUniformMatrix4fv( mModelViewProjectionMatrixLocation, 1, true, modelViewProjectionMatrix.GetArray() );
	glUniformMatrix3fv( mNormalMatrixLocation, 1, true, normalMatrix.GetArray() );
	Vector3<float> cameraPosition = camera->GetGlobalPosition();
	glUniform3fv( mCameraPositionLocation, 1, (float*)&cameraPosition );
}
	//---------------------------------------------------------------------
	Matrix4 Math::makeViewMatrix(const Vector3& position, const Quaternion& orientation, 
		const Matrix4* reflectMatrix)
	{
		Matrix4 viewMatrix;

		// View matrix is:
		//
		//  [ Lx  Uy  Dz  Tx  ]
		//  [ Lx  Uy  Dz  Ty  ]
		//  [ Lx  Uy  Dz  Tz  ]
		//  [ 0   0   0   1   ]
		//
		// Where T = -(Transposed(Rot) * Pos)

		// This is most efficiently done using 3x3 Matrices
		Matrix3 rot;
		orientation.ToRotationMatrix(rot);

		// Make the translation relative to new axes
		Matrix3 rotT = rot.Transpose();
		Vector3 trans = -rotT * position;

		// Make final matrix
		viewMatrix = Matrix4::IDENTITY;
		viewMatrix = rotT; // fills upper 3x3
		viewMatrix[0][3] = trans.x;
		viewMatrix[1][3] = trans.y;
		viewMatrix[2][3] = trans.z;

		// Deal with reflections
		if (reflectMatrix)
		{
			viewMatrix = viewMatrix * (*reflectMatrix);
		}

		return viewMatrix;

	}
/* Take increments in strain and calculate new Particle: strains, rotation strain,
		stresses, strain energy,
	dvij are (gradient rates X time increment) to give deformation gradient change
	For Axisymmetry: x->R, y->Z, z->theta, np==AXISYMMEtRIC_MPM, otherwise dvzz=0
	This material tracks pressure and stores deviatoric stress only in particle stress tensor
 */
void ClampedNeohookean::MPMConstitutiveLaw(MPMBase *mptr,Matrix3 du,double delTime,int np,void *properties,
										   ResidualStrains *res,int historyOffset) const
{
	// Update total deformation gradient, and calculate trial B
    Tensor Btrial;
	double detDF = IncrementDeformation(mptr,du,&Btrial,np);
    
	// global J
	double J = detDF * mptr->GetHistoryDble(J_History,historyOffset);
	mptr->SetHistoryDble(J_History,J,historyOffset);
	
	// convert Btrial to matrix to get eigenvalues and check for clamping
	Matrix3 Belas(Btrial.xx,Btrial.xy,Btrial.xz,
				  Btrial.xy,Btrial.yy,Btrial.yz,
				  Btrial.xz,Btrial.yz,Btrial.zz);
	if(np!=THREED_MPM) Belas.setIs2D(true);
		
	// get Eigenvalues and Eigenvectors
	Vector lam2 = Belas.Eigenvalues();
	
	// clamp eigenvalues if needed
	bool clamped = false;
	if(lam2.x<lamMin2 || lam2.x>lamMax2 || lam2.y<lamMin2 || lam2.y>lamMax2 || lam2.z<lamMin2 || lam2.z>lamMax2)
		clamped = true;
	
	// Get Je and Jp, adjusting if clamped
	double Je,Jp;
	Matrix3 Ucol;
	if(clamped)
	{	// Find Belas = U.LAM.UT
		Ucol = Belas.Eigenvectors(lam2);
		// clamp values now
		if(lam2.x<lamMin2)
			lam2.x = lamMin2;
		else if(lam2.x>lamMax2)
			lam2.x = lamMax2;
		if(lam2.y<lamMin2)
			lam2.y = lamMin2;
		else if(lam2.y>lamMax2)
			lam2.y = lamMax2;
		if(lam2.z<lamMin2)
			lam2.z = lamMin2;
		else if(lam2.z>lamMax2)
			lam2.z = lamMax2;
		Matrix3 UcolT = Ucol.Transpose();
		Matrix3 Lam(lam2.x,0.,0.,lam2.y,lam2.z);
		Matrix3 LamUcolT = Lam*UcolT;
		Belas = Ucol*LamUcolT;
		
		// get Je and Jp
		Je = sqrt(lam2.x*lam2.y*lam2.z);
		Jp = J/Je;
		mptr->SetHistoryDble(JP_HISTORY,Jp,historyOffset);
	}
	else
	{	Jp = mptr->GetHistoryDble(JP_HISTORY,historyOffset);
		Je = J/Jp;
		if(elasticModel==ELASTIC_DISNEY)
			Ucol = Belas.Eigenvectors(lam2);
	}
	
	// store B elastic
	Tensor *sp=mptr->GetStressTensor();
    Tensor *B = mptr->GetAltStrainTensor();
	B->xx = Belas(0,0);
	B->yy = Belas(1,1);
	B->zz = Belas(2,2);
	B->xy = Belas(0,1);
	if(np==THREED_MPM)
	{	B->xz = Belas(0,2);
		B->yz = Belas(1,2);
	}
	
	// change mechanical properties by hardening
	double arg = exp(hardening*(1.-Jp));
	double altGsp = pr.Gsp*arg;
	double altLamesp = pr.Lamesp*arg;

	// account for residual stresses
	double dJres = GetIncrementalResJ(mptr,res);
	double Jres = dJres*mptr->GetHistoryDble(J_History+1,historyOffset);
	mptr->SetHistoryDble(J_History+1,Jres,historyOffset);
	double resStretch = pow(Jres,1./3.);
	double Jres23 = resStretch*resStretch;
		
	// account for residual stresses relative to elastic J
	double Jeff = Je/Jres;
		
	// for incremental energy, store initial stress and pressure
	Tensor *sporig=mptr->GetStressTensor();
	Tensor st0 = *sporig;
	double Pfinal,p0=mptr->GetPressure();
	
	if(elasticModel==ELASTIC_DISNEY)
	{	// Use model from Disney paper
		
		// Get Cauchy stress/rho0
		double sig[3][3];
		double lam[3];
		lam[0]=sqrt(lam2.x)/resStretch;
		lam[1]=sqrt(lam2.y)/resStretch;
		lam[2]=sqrt(lam2.z)/resStretch;
		for(int i=0;i<3;i++)
		{	for(int j=i;j<3;j++)
			{	sig[i][j] = 0.;
				for(int k=0;k<3;k++)
				{	sig[i][j] += (2.*altGsp*lam[k]*(lam[k]-1)/Jeff + altLamesp*(Jeff-1))*Ucol(i,k)*Ucol(j,k);
				}
			}
		}
		
		// update pressure (*J to get Kirchoff pressure)
		Pfinal = -J*(sig[0][0]+sig[1][1]+sig[2][2])/3.;
		mptr->SetPressure(Pfinal);

		// get and set deviatoric stress
		// find eviatoric (Kirchoff stress)/rho0 = deviatoric (Cauchy stress)J/rho0
		sp->xx = J*sig[0][0]+Pfinal;
		sp->yy = J*sig[1][1]+Pfinal;
		sp->zz = J*sig[2][2]+Pfinal;
		sp->xy = J*sig[0][1];
		if(np==THREED_MPM)
		{	sp->xz = J*sig[0][2];
			sp->yz = J*sig[1][2];
		}
	}
	else
	{	// Use standard neo-Hookean law
		
		// update pressure (*J to get Kirchoff pressure)
		Pfinal = -J*(GetVolumetricTerms(Jeff,altLamesp) + (altGsp/Jeff)*((B->xx+B->yy+B->zz)/(3.*Jres23) - 1.));
		mptr->SetPressure(Pfinal);
		
		// Account for density change in specific stress
		// i.e.. Get (Kirchoff Stress)/rho0
		double GJeff = J*resStretch*altGsp/Je;		// = J*(Jres^(1/3) G/Je) to get Kirchoff
		
		// find deviatoric (Kirchoff stress)/rho0 = deviatoric (Cauchy stress)J/rho0
		double I1third = (B->xx+B->yy+B->zz)/3.;
		sp->xx = GJeff*(B->xx-I1third);
		sp->yy = GJeff*(B->yy-I1third);
		sp->zz = GJeff*(B->zz-I1third);
		sp->xy = GJeff*B->xy;
		if(np==THREED_MPM)
		{	sp->xz = GJeff*B->xz;
			sp->yz = GJeff*B->yz;
		}
	}
	
	// work and residual energies
    double delV = 1. - 1./detDF;                        // total volume change
    double avgP = 0.5*(p0+Pfinal);
    double dilEnergy = -avgP*delV;
	
	// incremental residual energy
	double delVres = 1. - 1./dJres;
	double resEnergy = -avgP*delVres;

	// incremental work energy = shear energy
    double shearEnergy = 0.5*((sp->xx+st0.xx)*du(0,0) + (sp->yy+st0.yy)*du(1,1) + (sp->zz+st0.zz)*du(2,2)+
							  (sp->xy+st0.xy)*(du(0,1)+du(1,0)));
    if(np==THREED_MPM)
    {   shearEnergy += 0.5*((sp->xz+st0.xz)*(du(0,2)+du(2,0)) + (sp->yz+st0.yz)*(du(1,2)+du(2,1)));
    }
	
    // strain energy
    double dU = dilEnergy + shearEnergy;
    mptr->AddWorkEnergyAndResidualEnergy(dU,resEnergy);
	
	// thermodynamics heat and temperature
	// Should find energy dissipated by plasticity and add in third term
	IncrementHeatEnergy(mptr,res->dT,0.,0.);
}
示例#9
0
/*
============
Matrix3::InertiaRotate
============
*/
Matrix3 Matrix3::InertiaRotate( const Matrix3 &rotation ) const {
	// NOTE: the rotation matrix is stored column-major
	return rotation.Transpose() * (*this) * rotation;
}
void MeshRenderer::DoRender( BufferIndex bufferIndex, const Matrix& modelViewMatrix, const Matrix& modelMatrix, const Matrix& viewMatrix, const Matrix& projectionMatrix, const Vector4& color )
{
  MeshInfo& meshInfo = mMeshInfo[bufferIndex];
  Mesh*           mesh              =    meshInfo.mesh;
  RenderMaterial& material          =  *(meshInfo.material);
  BoneTransforms& boneTransforms    =    meshInfo.boneTransforms;

  if( ! meshInfo.boneTransforms.transforms.empty() )
  {
    ApplyViewToBoneTransforms( meshInfo.boneTransforms, viewMatrix );
  }

  const int stride = sizeof(Dali::MeshData::Vertex);
  Dali::MeshData::Vertex *v = 0;

  mesh->UploadVertexData( *mContext, bufferIndex );
  mesh->BindBuffers( *mContext );

  GeometryType geometryType = GEOMETRY_TYPE_TEXTURED_MESH;
  if( ! material.HasTexture() )
  {
    geometryType = GEOMETRY_TYPE_MESH;
  }

  GLsizei numBoneMatrices = (GLsizei)mesh->GetMeshData(Mesh::RENDER_THREAD).GetBoneCount();

  // Select program type
  ShaderSubTypes shaderType = SHADER_DEFAULT;
  if( mShader->AreSubtypesRequired( geometryType ) )
  {
    if( numBoneMatrices )
    {
      if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasColor() )
      {
        shaderType = SHADER_RIGGED_AND_VERTEX_COLOR;
      }
      else if( mAffectedByLighting )
      {
        shaderType = SHADER_RIGGED_AND_LIT;
      }
      else
      {
        shaderType = SHADER_RIGGED_AND_EVENLY_LIT;
      }
    }
    else
    {
      if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasColor() )
      {
        shaderType = SHADER_VERTEX_COLOR;
      }
      else if( ! mAffectedByLighting )
      {
        shaderType = SHADER_EVENLY_LIT;
      } // else default
    }
  }

  if( geometryType != mGeometryType || shaderType != mShaderType )
  {
    mGeometryType = geometryType;
    mShaderType = shaderType;
    ResetCustomUniforms();
  }

  Program& program = mShader->Apply( *mContext, bufferIndex, geometryType, modelMatrix, viewMatrix, modelViewMatrix, projectionMatrix, color, mShaderType );

  GLint location       = Program::UNIFORM_UNKNOWN;
  GLint positionLoc    = program.GetAttribLocation(Program::ATTRIB_POSITION);
  GLint texCoordLoc    = Program::ATTRIB_UNKNOWN;
  GLint boneWeightsLoc = Program::ATTRIB_UNKNOWN;
  GLint boneIndicesLoc = Program::ATTRIB_UNKNOWN;
  GLint normalLoc      = Program::ATTRIB_UNKNOWN;
  GLint colorLoc       = Program::ATTRIB_UNKNOWN;

  mContext->VertexAttribPointer( positionLoc, 3, GL_FLOAT, GL_FALSE, stride, &v->x );
  mContext->EnableVertexAttributeArray( positionLoc );

  if( numBoneMatrices > 0 )
  {
    location = mCustomUniform[ shaderType ][ 0 ].GetUniformLocation( program, "uBoneCount" );
    if( Program::UNIFORM_UNKNOWN != location )
    {
      program.SetUniform1i(location, numBoneMatrices);
    }

    location = mCustomUniform[ shaderType ][ 1 ].GetUniformLocation( program, "uBoneMatrices" );
    if( Program::UNIFORM_UNKNOWN != location )
    {
      program.SetUniformMatrix4fv(location, numBoneMatrices, boneTransforms.viewTransforms[0].AsFloat());
    }
    if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasNormals() )
    {
      location = mCustomUniform[ shaderType ][ 2 ].GetUniformLocation( program, "uBoneMatricesIT" );
      if( Program::UNIFORM_UNKNOWN != location )
      {
        program.SetUniformMatrix3fv( location, numBoneMatrices, boneTransforms.inverseTransforms[0].AsFloat() );
      }
    }

    boneWeightsLoc = program.GetAttribLocation( Program::ATTRIB_BONE_WEIGHTS );
    if( Program::ATTRIB_UNKNOWN != boneWeightsLoc )
    {
      mContext->VertexAttribPointer( boneWeightsLoc, 4, GL_FLOAT, GL_FALSE, stride, &v->boneWeights[0] );
      mContext->EnableVertexAttributeArray( boneWeightsLoc );
    }

    boneIndicesLoc = program.GetAttribLocation( Program::ATTRIB_BONE_INDICES );
    if( Program::ATTRIB_UNKNOWN != boneIndicesLoc )
    {
      mContext->VertexAttribPointer( boneIndicesLoc, 4, GL_UNSIGNED_BYTE, GL_FALSE, stride, &v->boneIndices[0] );
      mContext->EnableVertexAttributeArray( boneIndicesLoc );
    }
  }

  if( material.HasTexture() )
  {
    material.BindTextures( program );
  }
  // Always use UV's - may be being used for another purpose by a custom shader!
  texCoordLoc = program.GetAttribLocation(Program::ATTRIB_TEXCOORD);
  if( Program::ATTRIB_UNKNOWN != texCoordLoc )
  {
    mContext->VertexAttribPointer( texCoordLoc, 2, GL_FLOAT, GL_FALSE, stride, &v->u );
    mContext->EnableVertexAttributeArray( texCoordLoc );
  }

  if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasNormals() )
  {
    normalLoc = program.GetAttribLocation(Program::ATTRIB_NORMAL);
    if( Program::ATTRIB_UNKNOWN != normalLoc )
    {
      mContext->VertexAttribPointer( normalLoc, 3, GL_FLOAT, GL_FALSE, stride, &v->nX );
      mContext->EnableVertexAttributeArray( normalLoc );
    }
  }
  else if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasColor() )  // Normals & color are mutually exclusive
  {
    colorLoc = program.GetAttribLocation(Program::ATTRIB_COLOR);
    if( Program::ATTRIB_UNKNOWN != colorLoc)
    {
      mContext->VertexAttribPointer( colorLoc, 3, GL_FLOAT, GL_FALSE, stride, &v->vertexR );
      mContext->EnableVertexAttributeArray( colorLoc );
    }
  }

  material.SetUniforms( mRenderMaterialUniforms, program, shaderType );

  if( mAffectedByLighting )
  {
    // Set light parameters
    location = mCustomUniform[ shaderType ][ 3 ].GetUniformLocation( program, "uNumberOfLights" );
    if( Program::UNIFORM_UNKNOWN != location )
    {
      program.SetUniform1i( location, mLightController->GetNumberOfLights() );
    }

    // Model View IT matrix required for vertex normal lighting calculation
    location = mCustomUniform[ shaderType ][ 4 ].GetUniformLocation( program, "uModelViewIT" );
    if( Program::UNIFORM_UNKNOWN != location )
    {
      Matrix3 modelViewInverseTranspose = modelViewMatrix;
      modelViewInverseTranspose.Invert();
      modelViewInverseTranspose.Transpose();

      program.SetUniformMatrix3fv( location, 1, modelViewInverseTranspose.AsFloat() );
    }

    // only one active light supported at the moment (due to performance)
    //if( numberOfLights > 0 )
    {
      Vector2 tempVector2;
      Vector3 tempVector3;

      Node& lightNode = mLightController->GetLight( 0 );

      LightAttachment& light = dynamic_cast< LightAttachment& >( lightNode.GetAttachment() );

      location = mCustomUniform[ shaderType ][ 5 ].GetUniformLocation( program, "uLight0.mType" );
      if( Program::UNIFORM_UNKNOWN != location )
      {
        program.SetUniform1i( location, (GLint)light.GetType() );
      }

      location = mCustomUniform[ shaderType ][ 6 ].GetUniformLocation( program, "uLight0.mFallOff" );
      if( Program::UNIFORM_UNKNOWN != location )
      {
        tempVector2 = light.GetFallOff();
        program.SetUniform2f( location, tempVector2.x, tempVector2.y );
      }

      location = mCustomUniform[ shaderType ][ 7 ].GetUniformLocation( program, "uLight0.mSpotAngle" );
      if( Program::UNIFORM_UNKNOWN != location )
      {
        tempVector2 = light.GetSpotAngle();
        program.SetUniform2f( location, tempVector2.x, tempVector2.y );
      }

      location = mCustomUniform[ shaderType ][ 8 ].GetUniformLocation( program, "uLight0.mLightPos" );
      if( Program::UNIFORM_UNKNOWN != location )
      {
        // light position in eyespace
        Vector3 tempVector3( viewMatrix * Vector4(lightNode.GetWorldPosition(bufferIndex)) );
        program.SetUniform3f( location, tempVector3.x, tempVector3.y, tempVector3.z );
      }

      location = mCustomUniform[ shaderType ][ 9 ].GetUniformLocation( program, "uLight0.mLightDir" );
      if( Program::UNIFORM_UNKNOWN != location )
      {
        tempVector3 = light.GetDirection();
        tempVector3.Normalize();
        program.SetUniform3f( location, tempVector3.x, tempVector3.y, tempVector3.z );
      }

      location = mCustomUniform[ shaderType ][ 10 ].GetUniformLocation( program, "uLight0.mAmbient" );
      if( Program::UNIFORM_UNKNOWN != location )
      {
        tempVector3 = light.GetAmbientColor();
        program.SetUniform3f( location, tempVector3.r, tempVector3.g, tempVector3.b );
      }

      location = mCustomUniform[ shaderType ][ 11 ].GetUniformLocation( program, "uLight0.mDiffuse" );
      if( Program::UNIFORM_UNKNOWN != location )
      {
        tempVector3 = light.GetDiffuseColor();
        program.SetUniform3f( location, tempVector3.r, tempVector3.g, tempVector3.b );
      }

      location = mCustomUniform[ shaderType ][ 12 ].GetUniformLocation( program, "uLight0.mSpecular" );
      if( Program::UNIFORM_UNKNOWN != location )
      {
        tempVector3 = light.GetSpecularColor();
        program.SetUniform3f( location, tempVector3.r, tempVector3.g, tempVector3.b );
      }
    }
  }

  Dali::MeshData::VertexGeometryType vertexGeometry = mesh->GetMeshData(Mesh::RENDER_THREAD).GetVertexGeometryType();
  switch( vertexGeometry )
  {
    case Dali::MeshData::TRIANGLES:
      mContext->DrawElements(GL_TRIANGLES, mesh->GetFaceIndexCount(Mesh::RENDER_THREAD), GL_UNSIGNED_SHORT, 0);
      DRAW_ELEMENT_RECORD(mesh->GetFaceIndexCount());
      break;
    case Dali::MeshData::LINES:
      mContext->DrawElements(GL_LINES, mesh->GetFaceIndexCount(Mesh::RENDER_THREAD), GL_UNSIGNED_SHORT, 0);
      DRAW_ELEMENT_RECORD(mesh->GetFaceIndexCount());
      break;
    case Dali::MeshData::POINTS:
      mContext->DrawArrays(GL_POINTS, 0, mesh->GetFaceIndexCount(Mesh::RENDER_THREAD) );
      DRAW_ARRAY_RECORD(mesh->GetFaceIndexCount());
  }

  if( normalLoc != Program::ATTRIB_UNKNOWN )
  {
    mContext->DisableVertexAttributeArray( normalLoc );
  }

  if( colorLoc != Program::ATTRIB_UNKNOWN )
  {
    mContext->DisableVertexAttributeArray( colorLoc );
  }

  mContext->DisableVertexAttributeArray( positionLoc );

  if( texCoordLoc != Program::ATTRIB_UNKNOWN )
  {
    mContext->DisableVertexAttributeArray( texCoordLoc );
  }

  if( boneWeightsLoc != Program::ATTRIB_UNKNOWN )
  {
    mContext->DisableVertexAttributeArray( boneWeightsLoc );
  }

  if( boneIndicesLoc != Program::ATTRIB_UNKNOWN )
  {
    mContext->DisableVertexAttributeArray( boneIndicesLoc );
  }

  return;
}