예제 #1
0
// Execute OpenGL Material
void GLC_Material::glExecute(float overwriteTransparency)
{
	GLfloat pAmbientColor[4]= {ambientColor().redF(),
								ambientColor().greenF(),
								ambientColor().blueF(),
								overwriteTransparency};

	GLfloat pDiffuseColor[4]= {diffuseColor().redF(),
								diffuseColor().greenF(),
								diffuseColor().blueF(),
								overwriteTransparency};

	GLfloat pSpecularColor[4]= {specularColor().redF(),
								specularColor().greenF(),
								specularColor().blueF(),
								overwriteTransparency};

	GLfloat pLightEmission[4]= {emissiveColor().redF(),
								emissiveColor().greenF(),
								emissiveColor().blueF(),
								overwriteTransparency};

	const bool textureIsEnable= glIsEnabled(GL_TEXTURE_2D);

	if (m_pTexture != NULL)
	{
		if (!textureIsEnable) glEnable(GL_TEXTURE_2D);
		m_pTexture->glcBindTexture();
		if (GLC_State::glslUsed())
		{
			if (GLC_Shader::hasActiveShader())
			{
				GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("tex", GLint(0));
				GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("useTexture", true);
			}
		}
	}
	else
	{
		if (textureIsEnable) glDisable(GL_TEXTURE_2D);
		if (GLC_State::glslUsed())
		{
			if (GLC_Shader::hasActiveShader())
			{
				GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("tex", GLint(0));
				GLC_Shader::currentShaderHandle()->programShaderHandle()->setUniformValue("useTexture", false);
			}
		}
	}

	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, pAmbientColor);
	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, pDiffuseColor);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, pSpecularColor);
	glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, pLightEmission);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &m_Shininess);

	glColor4fv(pDiffuseColor);

	// OpenGL Error handler
	GLenum error= glGetError();
	if (error != GL_NO_ERROR)
	{
		GLC_OpenGlException OpenGlException("GLC_Material::glExecute(float overwriteTransparency) ", error);
		throw(OpenGlException);
	}
}
예제 #2
0
void Material::ExportMaterials(FbxScene* scene, FbxMesh* mesh, const ImporterMesh& importedMesh, const ImporterMaterial* importedMaterials)
{
	for (int i = 0; i < importedMesh.material_count; i++)
	{
		FbxNode* node = mesh->GetNode();
		FbxString materialName = importedMaterials[importedMesh.material_Id[i]].name;
		
		FbxString shadingName;

		FbxDouble3 diffuseColor(importedMaterials[importedMesh.material_Id[i]].diffuse[0], importedMaterials[importedMesh.material_Id[i]].diffuse[1], importedMaterials[importedMesh.material_Id[i]].diffuse[2]);
		FbxDouble3 ambientColor(importedMaterials[importedMesh.material_Id[i]].ambient[0], importedMaterials[importedMesh.material_Id[i]].ambient[1], importedMaterials[importedMesh.material_Id[i]].ambient[2]);
		FbxDouble3 emissiveColor(importedMaterials[importedMesh.material_Id[i]].incandescence[0], importedMaterials[importedMesh.material_Id[i]].incandescence[1], importedMaterials[importedMesh.material_Id[i]].incandescence[2]);
		FbxDouble3 transparencyColor(importedMaterials[importedMesh.material_Id[i]].transparency_color[0], importedMaterials[importedMesh.material_Id[i]].transparency_color[1], importedMaterials[importedMesh.material_Id[i]].transparency_color[2]);
		FbxDouble3 specularColor(importedMaterials[importedMesh.material_Id[i]].specular[0], importedMaterials[importedMesh.material_Id[i]].specular[1] , importedMaterials[importedMesh.material_Id[i]].specular[2]);
		
		const char* pathName = "C://Users/Litet/Documents/GitHub/SmallGameProject/FBX Export/FBX Export/";
		// Lambert
		if (importedMaterials[importedMesh.material_Id[i]].mtrl_type == 0)
		{
			shadingName = "Lambert";
			FbxSurfaceLambert* material = NULL;
			material= node->GetSrcObject<FbxSurfaceLambert>(0);
			material = FbxSurfaceLambert::Create(scene, materialName.Buffer());
			
			materialName += i;
			material->Emissive.Set(emissiveColor);

			material->Ambient.Set(ambientColor);

			material->Diffuse.Set(diffuseColor);
			material->DiffuseFactor.Set(importedMaterials[importedMesh.material_Id[i]].diffuse_factor);

			material->TransparentColor.Set(transparencyColor);

			FbxNode* node = mesh->GetNode();
			if (node)
			{
				node->AddMaterial(material);
			}

			// Diffuse Texture
			FbxFileTexture* texture = FbxFileTexture::Create(scene, "Diffuse Texture");
			std::cout << "DAFUSE MAP LENGTH: " << importedMaterials[importedMesh.material_Id[i]].duffuse_map_length << std::endl;
			if (importedMaterials[importedMesh.material_Id[i]].duffuse_map_length > 0)
			{
				std::string tmp(pathName);
				tmp += importedMaterials[importedMesh.material_Id[i]].diffuse_map;
				texture->SetFileName(tmp.c_str());
				texture->SetTextureUse(FbxTexture::eStandard);
				texture->SetMappingType(FbxTexture::eUV);
				texture->SetMaterialUse(FbxFileTexture::eModelMaterial);
				texture->SetSwapUV(false);
				texture->SetTranslation(0.0, 0.0);
				texture->SetScale(1.0, 1.0);
				texture->SetRotation(0.0, 0.0);

				if (material)
					material->Diffuse.ConnectSrcObject(texture);
			}

			// Normal Texture
			texture = FbxFileTexture::Create(scene, "Normal Texture");
			if (importedMaterials[importedMesh.material_Id[i]].normal_map_length > 0)
			{
				texture->SetFileName(importedMaterials[importedMesh.material_Id[i]].normal_map);
				texture->SetTextureUse(FbxTexture::eStandard);
				texture->SetMappingType(FbxTexture::eUV);
				texture->SetMaterialUse(FbxFileTexture::eModelMaterial);
				texture->SetSwapUV(false);
				texture->SetTranslation(0.0, 0.0);
				texture->SetScale(1.0, 1.0);
				texture->SetRotation(0.0, 0.0);

				if (material)
					material->NormalMap.ConnectSrcObject(texture);
			}

			

		}

		// Phong
		else
		{
			shadingName = "Phong";
			FbxSurfacePhong* material = NULL;
			material = node->GetSrcObject<FbxSurfacePhong>(0);
			
			material = FbxSurfacePhong::Create(scene, materialName.Buffer());
			materialName += i;
			material->Emissive.Set(emissiveColor);

			material->Ambient.Set(ambientColor);

			material->Diffuse.Set(diffuseColor);
			material->DiffuseFactor.Set(importedMaterials[importedMesh.material_Id[i]].diffuse_factor);

			material->TransparentColor.Set(transparencyColor);

			material->Specular.Set(specularColor);

			// No need... super boost?
			//material->SpecularFactor.Set(importedMaterials[importedMesh.material_Id[i]].specular_factor * 100);

			material->Shininess.Set(importedMaterials[importedMesh.material_Id[i]].specular_factor);
			
			material->Reflection.Set(FbxDouble3(importedMaterials[importedMesh.material_Id[i]].reflection[0], importedMaterials[importedMesh.material_Id[i]].reflection[1], importedMaterials[importedMesh.material_Id[i]].reflection[2]));
			
			// Bugged...?
			material->ReflectionFactor.Set(FbxDouble(importedMaterials[importedMesh.material_Id[i]].reflection_factor));
			cout << importedMaterials[importedMesh.material_Id[i]].shininess << endl;

			FbxNode* node = mesh->GetNode();
			if (node)
			{
				node->AddMaterial(material);
			}

			// Diffuse Texture
			FbxFileTexture* texture = FbxFileTexture::Create(scene, "Diffuse Texture");
			if (importedMaterials[importedMesh.material_Id[i]].duffuse_map_length > 0)
			{
				texture->SetFileName(importedMaterials[importedMesh.material_Id[i]].diffuse_map);
				texture->SetTextureUse(FbxTexture::eStandard);
				texture->SetMappingType(FbxTexture::eUV);
				texture->SetMaterialUse(FbxFileTexture::eModelMaterial);
				texture->SetSwapUV(false);
				texture->SetTranslation(0.0, 0.0);
				texture->SetScale(1.0, 1.0);
				texture->SetRotation(0.0, 0.0);

				if (material)
					material->Diffuse.ConnectSrcObject(texture);
			}

			// Specular Texture
			texture = FbxFileTexture::Create(scene, "Specular Texture");
			if (importedMaterials[importedMesh.material_Id[i]].specular_map_length > 0)
			{
				texture->SetFileName(importedMaterials[importedMesh.material_Id[i]].specular_map);
				texture->SetTextureUse(FbxTexture::eStandard);
				texture->SetMappingType(FbxTexture::eUV);
				texture->SetMaterialUse(FbxFileTexture::eModelMaterial);
				texture->SetSwapUV(false);
				texture->SetTranslation(0.0, 0.0);
				texture->SetScale(1.0, 1.0);
				texture->SetRotation(0.0, 0.0);

				if (material)
					material->Specular.ConnectSrcObject(texture);
			}

			// Normal Texture
			texture = FbxFileTexture::Create(scene, "Normal Texture");
			if (importedMaterials[importedMesh.material_Id[i]].normal_map_length > 0)
			{
				texture->SetFileName(importedMaterials[importedMesh.material_Id[i]].normal_map);
				texture->SetTextureUse(FbxTexture::eStandard);
				texture->SetMappingType(FbxTexture::eUV);
				texture->SetMaterialUse(FbxFileTexture::eModelMaterial);
				texture->SetSwapUV(false);
				texture->SetTranslation(0.0, 0.0);
				texture->SetScale(1.0, 1.0);
				texture->SetRotation(0.0, 0.0);

				if (material)
					material->NormalMap.ConnectSrcObject(texture);
			}


		}
	}

}
예제 #3
0
btTransform ConvertURDF2BulletInternal(
	const URDFImporterInterface& u2b, MultiBodyCreationInterface& creation,
	URDF2BulletCachedData& cache, int urdfLinkIndex,
	const btTransform& parentTransformInWorldSpace, btMultiBodyDynamicsWorld* world1,
	bool createMultiBody, const char* pathPrefix,
	int flags, UrdfVisualShapeCache* cachedLinkGraphicsShapesIn, UrdfVisualShapeCache* cachedLinkGraphicsShapesOut, bool recursive)
{
	B3_PROFILE("ConvertURDF2BulletInternal2");
	//b3Printf("start converting/extracting data from URDF interface\n");

	btTransform linkTransformInWorldSpace;
	linkTransformInWorldSpace.setIdentity();

	int mbLinkIndex = cache.getMbIndexFromUrdfIndex(urdfLinkIndex);

	int urdfParentIndex = cache.getParentUrdfIndex(urdfLinkIndex);
	int mbParentIndex = cache.getMbIndexFromUrdfIndex(urdfParentIndex);
	btRigidBody* parentRigidBody = 0;

	//b3Printf("mb link index = %d\n",mbLinkIndex);

	btTransform parentLocalInertialFrame;
	parentLocalInertialFrame.setIdentity();
	btScalar parentMass(1);
	btVector3 parentLocalInertiaDiagonal(1, 1, 1);

	if (urdfParentIndex == -2)
	{
		//b3Printf("root link has no parent\n");
	}
	else
	{
		//b3Printf("urdf parent index = %d\n",urdfParentIndex);
		//b3Printf("mb parent index = %d\n",mbParentIndex);
		parentRigidBody = cache.getRigidBodyFromLink(urdfParentIndex);
		u2b.getMassAndInertia2(urdfParentIndex, parentMass, parentLocalInertiaDiagonal, parentLocalInertialFrame, flags);
	}

	btScalar mass = 0;
	btTransform localInertialFrame;
	localInertialFrame.setIdentity();
	btVector3 localInertiaDiagonal(0, 0, 0);
	u2b.getMassAndInertia2(urdfLinkIndex, mass, localInertiaDiagonal, localInertialFrame, flags);

	btTransform parent2joint;
	parent2joint.setIdentity();

	int jointType;
	btVector3 jointAxisInJointSpace;
	btScalar jointLowerLimit;
	btScalar jointUpperLimit;
	btScalar jointDamping;
	btScalar jointFriction;
	btScalar jointMaxForce;
	btScalar jointMaxVelocity;

	bool hasParentJoint = u2b.getJointInfo2(urdfLinkIndex, parent2joint, linkTransformInWorldSpace, jointAxisInJointSpace, jointType, jointLowerLimit, jointUpperLimit, jointDamping, jointFriction, jointMaxForce, jointMaxVelocity);
	std::string linkName = u2b.getLinkName(urdfLinkIndex);

	if (flags & CUF_USE_SDF)
	{
		parent2joint = parentTransformInWorldSpace.inverse() * linkTransformInWorldSpace;
	}
	else
	{
		if (flags & CUF_USE_MJCF)
		{
			linkTransformInWorldSpace = parentTransformInWorldSpace * linkTransformInWorldSpace;
		}
		else
		{
			linkTransformInWorldSpace = parentTransformInWorldSpace * parent2joint;
		}
	}

	btCompoundShape* tmpShape = u2b.convertLinkCollisionShapes(urdfLinkIndex, pathPrefix, localInertialFrame);
	btCollisionShape* compoundShape = tmpShape;
	if (tmpShape->getNumChildShapes() == 1 && tmpShape->getChildTransform(0) == btTransform::getIdentity())
	{
		compoundShape = tmpShape->getChildShape(0);
	}

	int graphicsIndex;
	{
		B3_PROFILE("convertLinkVisualShapes");
		if (cachedLinkGraphicsShapesIn && cachedLinkGraphicsShapesIn->m_cachedUrdfLinkVisualShapeIndices.size() > (mbLinkIndex + 1))
		{
			graphicsIndex = cachedLinkGraphicsShapesIn->m_cachedUrdfLinkVisualShapeIndices[mbLinkIndex + 1];
			UrdfMaterialColor matColor = cachedLinkGraphicsShapesIn->m_cachedUrdfLinkColors[mbLinkIndex + 1];
			u2b.setLinkColor2(urdfLinkIndex, matColor);
		}
		else
		{
			graphicsIndex = u2b.convertLinkVisualShapes(urdfLinkIndex, pathPrefix, localInertialFrame);
			if (cachedLinkGraphicsShapesOut)
			{
				cachedLinkGraphicsShapesOut->m_cachedUrdfLinkVisualShapeIndices.push_back(graphicsIndex);
				UrdfMaterialColor matColor;
				u2b.getLinkColor2(urdfLinkIndex, matColor);
				cachedLinkGraphicsShapesOut->m_cachedUrdfLinkColors.push_back(matColor);
			}
		}
	}

	if (compoundShape)
	{
		UrdfMaterialColor matColor;
		btVector4 color2 = selectColor2();
		btVector3 specular(0.5, 0.5, 0.5);
		if (u2b.getLinkColor2(urdfLinkIndex, matColor))
		{
			color2 = matColor.m_rgbaColor;
			specular = matColor.m_specularColor;
		}

		/*
         if (visual->material.get())
         {
            color.setValue(visual->material->color.r,visual->material->color.g,visual->material->color.b);//,visual->material->color.a);
         }
         */
		if (mass)
		{
			if (!(flags & CUF_USE_URDF_INERTIA))
			{
				compoundShape->calculateLocalInertia(mass, localInertiaDiagonal);
				btAssert(localInertiaDiagonal[0] < 1e10);
				btAssert(localInertiaDiagonal[1] < 1e10);
				btAssert(localInertiaDiagonal[2] < 1e10);
			}
			URDFLinkContactInfo contactInfo;
			u2b.getLinkContactInfo(urdfLinkIndex, contactInfo);
			//temporary inertia scaling until we load inertia from URDF
			if (contactInfo.m_flags & URDF_CONTACT_HAS_INERTIA_SCALING)
			{
				localInertiaDiagonal *= contactInfo.m_inertiaScaling;
			}
		}

		btRigidBody* linkRigidBody = 0;
		btTransform inertialFrameInWorldSpace = linkTransformInWorldSpace * localInertialFrame;
		bool canSleep = (flags & CUF_ENABLE_SLEEPING) != 0;

		if (!createMultiBody)
		{
			btRigidBody* body = creation.allocateRigidBody(urdfLinkIndex, mass, localInertiaDiagonal, inertialFrameInWorldSpace, compoundShape);

			if (!canSleep)
			{
				body->forceActivationState(DISABLE_DEACTIVATION);
			}

			linkRigidBody = body;

			world1->addRigidBody(body);

			compoundShape->setUserIndex(graphicsIndex);

			URDFLinkContactInfo contactInfo;
			u2b.getLinkContactInfo(urdfLinkIndex, contactInfo);

			processContactParameters(contactInfo, body);
			creation.createRigidBodyGraphicsInstance2(urdfLinkIndex, body, color2, specular, graphicsIndex);
			cache.registerRigidBody(urdfLinkIndex, body, inertialFrameInWorldSpace, mass, localInertiaDiagonal, compoundShape, localInertialFrame);

			//untested: u2b.convertLinkVisualShapes2(linkIndex,urdfLinkIndex,pathPrefix,localInertialFrame,body);
		}
		else
		{
			if (cache.m_bulletMultiBody == 0)
			{
				bool isFixedBase = (mass == 0);  //todo: figure out when base is fixed
				int totalNumJoints = cache.m_totalNumJoints1;
				cache.m_bulletMultiBody = creation.allocateMultiBody(urdfLinkIndex, totalNumJoints, mass, localInertiaDiagonal, isFixedBase, canSleep);
				if (flags & CUF_GLOBAL_VELOCITIES_MB)
				{
					cache.m_bulletMultiBody->useGlobalVelocities(true);
				}
				if (flags & CUF_USE_MJCF)
				{
					cache.m_bulletMultiBody->setBaseWorldTransform(linkTransformInWorldSpace);
				}

				cache.registerMultiBody(urdfLinkIndex, cache.m_bulletMultiBody, inertialFrameInWorldSpace, mass, localInertiaDiagonal, compoundShape, localInertialFrame);
			}
		}

		//create a joint if necessary
		if (hasParentJoint)
		{
			btTransform offsetInA, offsetInB;
			offsetInA = parentLocalInertialFrame.inverse() * parent2joint;
			offsetInB = localInertialFrame.inverse();
			btQuaternion parentRotToThis = offsetInB.getRotation() * offsetInA.inverse().getRotation();

			bool disableParentCollision = true;

			if (createMultiBody && cache.m_bulletMultiBody)
			{
				cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointDamping = jointDamping;
				cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointFriction = jointFriction;
				cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointLowerLimit = jointLowerLimit;
				cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointUpperLimit = jointUpperLimit;
				cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointMaxForce = jointMaxForce;
				cache.m_bulletMultiBody->getLink(mbLinkIndex).m_jointMaxVelocity = jointMaxVelocity;
			}

			switch (jointType)
			{
				case URDFSphericalJoint:
				{
					if (createMultiBody)
					{
						creation.addLinkMapping(urdfLinkIndex, mbLinkIndex);
						cache.m_bulletMultiBody->setupSpherical(mbLinkIndex, mass, localInertiaDiagonal, mbParentIndex,
							parentRotToThis, offsetInA.getOrigin(), -offsetInB.getOrigin(),
							disableParentCollision);
					}
					else
					{
						btAssert(0);
					}
					break;
				}
				case URDFPlanarJoint:
				{
					
					if (createMultiBody)
					{
#if 0
						void setupPlanar(int i,  // 0 to num_links-1
							btScalar mass,
							const btVector3 &inertia,
							int parent,
							const btQuaternion &rotParentToThis,  // rotate points in parent frame to this frame, when q = 0
							const btVector3 &rotationAxis,
							const btVector3 &parentComToThisComOffset,  // vector from parent COM to this COM, in PARENT frame
							bool disableParentCollision = false);
#endif
						creation.addLinkMapping(urdfLinkIndex, mbLinkIndex);
						cache.m_bulletMultiBody->setupPlanar(mbLinkIndex, mass, localInertiaDiagonal, mbParentIndex,
							parentRotToThis, quatRotate(offsetInB.getRotation(), jointAxisInJointSpace), offsetInA.getOrigin(),
							disableParentCollision);
					}
					else
					{
#if 0
						//b3Printf("Fixed joint\n");

						btGeneric6DofSpring2Constraint* dof6 = 0;

						//backward compatibility
						if (flags & CUF_RESERVED)
						{
							dof6 = creation.createFixedJoint(urdfLinkIndex, *parentRigidBody, *linkRigidBody, offsetInA, offsetInB);
						}
						else
						{
							dof6 = creation.createFixedJoint(urdfLinkIndex, *linkRigidBody, *parentRigidBody, offsetInB, offsetInA);
						}
						if (enableConstraints)
							world1->addConstraint(dof6, true);
#endif
					}
					break;
				}
				case URDFFloatingJoint:
				
				case URDFFixedJoint:
				{
					if ((jointType == URDFFloatingJoint) || (jointType == URDFPlanarJoint))
					{
						printf("Warning: joint unsupported, creating a fixed joint instead.");
					}
					creation.addLinkMapping(urdfLinkIndex, mbLinkIndex);

					if (createMultiBody)
					{
						//todo: adjust the center of mass transform and pivot axis properly
						cache.m_bulletMultiBody->setupFixed(mbLinkIndex, mass, localInertiaDiagonal, mbParentIndex,
															parentRotToThis, offsetInA.getOrigin(), -offsetInB.getOrigin());
					}
					else
					{
						//b3Printf("Fixed joint\n");

						btGeneric6DofSpring2Constraint* dof6 = 0;

						//backward compatibility
						if (flags & CUF_RESERVED)
						{
							dof6 = creation.createFixedJoint(urdfLinkIndex, *parentRigidBody, *linkRigidBody, offsetInA, offsetInB);
						}
						else
						{
							dof6 = creation.createFixedJoint(urdfLinkIndex, *linkRigidBody, *parentRigidBody, offsetInB, offsetInA);
						}
						if (enableConstraints)
							world1->addConstraint(dof6, true);
					}
					break;
				}
				case URDFContinuousJoint:
				case URDFRevoluteJoint:
				{
					creation.addLinkMapping(urdfLinkIndex, mbLinkIndex);
					if (createMultiBody)
					{
						cache.m_bulletMultiBody->setupRevolute(mbLinkIndex, mass, localInertiaDiagonal, mbParentIndex,
															   parentRotToThis, quatRotate(offsetInB.getRotation(), 
																   jointAxisInJointSpace), 
																offsetInA.getOrigin(),
															   -offsetInB.getOrigin(),
															   disableParentCollision);

						if (jointType == URDFRevoluteJoint && jointLowerLimit <= jointUpperLimit)
						{
							//std::string name = u2b.getLinkName(urdfLinkIndex);
							//printf("create btMultiBodyJointLimitConstraint for revolute link name=%s urdf link index=%d (low=%f, up=%f)\n", name.c_str(), urdfLinkIndex, jointLowerLimit, jointUpperLimit);
							btMultiBodyConstraint* con = new btMultiBodyJointLimitConstraint(cache.m_bulletMultiBody, mbLinkIndex, jointLowerLimit, jointUpperLimit);
							world1->addMultiBodyConstraint(con);
						}
					}
					else
					{
						btGeneric6DofSpring2Constraint* dof6 = 0;
						if (jointType == URDFRevoluteJoint && jointLowerLimit <= jointUpperLimit)
						{
							//backwards compatibility
							if (flags & CUF_RESERVED)
							{
								dof6 = creation.createRevoluteJoint(urdfLinkIndex, *parentRigidBody, *linkRigidBody, offsetInA, offsetInB, jointAxisInJointSpace, jointLowerLimit, jointUpperLimit);
							}
							else
							{
								dof6 = creation.createRevoluteJoint(urdfLinkIndex, *linkRigidBody, *parentRigidBody, offsetInB, offsetInA, jointAxisInJointSpace, jointLowerLimit, jointUpperLimit);
							}
						}
						else
						{
							//disable joint limits
							if (flags & CUF_RESERVED)
							{
								dof6 = creation.createRevoluteJoint(urdfLinkIndex, *parentRigidBody, *linkRigidBody, offsetInA, offsetInB, jointAxisInJointSpace, 1, -1);
							}
							else
							{
								dof6 = creation.createRevoluteJoint(urdfLinkIndex, *linkRigidBody, *parentRigidBody, offsetInB, offsetInA, jointAxisInJointSpace, 1, -1);
							}
						}

						if (enableConstraints)
							world1->addConstraint(dof6, true);
						//b3Printf("Revolute/Continuous joint\n");
					}
					break;
				}
				case URDFPrismaticJoint:
				{
					creation.addLinkMapping(urdfLinkIndex, mbLinkIndex);

					if (createMultiBody)
					{
						cache.m_bulletMultiBody->setupPrismatic(mbLinkIndex, mass, localInertiaDiagonal, mbParentIndex,
																parentRotToThis, quatRotate(offsetInB.getRotation(), jointAxisInJointSpace), offsetInA.getOrigin(),  //parent2joint.getOrigin(),
																-offsetInB.getOrigin(),
																disableParentCollision);

						if (jointLowerLimit <= jointUpperLimit)
						{
							//std::string name = u2b.getLinkName(urdfLinkIndex);
							//printf("create btMultiBodyJointLimitConstraint for prismatic link name=%s urdf link index=%d (low=%f, up=%f)\n", name.c_str(), urdfLinkIndex, jointLowerLimit,jointUpperLimit);

							btMultiBodyConstraint* con = new btMultiBodyJointLimitConstraint(cache.m_bulletMultiBody, mbLinkIndex, jointLowerLimit, jointUpperLimit);
							world1->addMultiBodyConstraint(con);
						}
						//printf("joint lower limit=%d, upper limit = %f\n", jointLowerLimit, jointUpperLimit);
					}
					else
					{
						btGeneric6DofSpring2Constraint* dof6 = creation.createPrismaticJoint(urdfLinkIndex, *parentRigidBody, *linkRigidBody, offsetInA, offsetInB, jointAxisInJointSpace, jointLowerLimit, jointUpperLimit);

						if (enableConstraints)
							world1->addConstraint(dof6, true);

						//b3Printf("Prismatic\n");
					}
					break;
				}
				default:
				{
					//b3Printf("Error: unsupported joint type in URDF (%d)\n", jointType);
					btAssert(0);
				}
			}
		}

		if (createMultiBody)
		{
			//if (compoundShape->getNumChildShapes()>0)
			{
				btMultiBodyLinkCollider* col = creation.allocateMultiBodyLinkCollider(urdfLinkIndex, mbLinkIndex, cache.m_bulletMultiBody);

				compoundShape->setUserIndex(graphicsIndex);

				col->setCollisionShape(compoundShape);

				if (compoundShape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE)
				{
					btBvhTriangleMeshShape* trimeshShape = (btBvhTriangleMeshShape*)compoundShape;
					if (trimeshShape->getTriangleInfoMap())
					{
						col->setCollisionFlags(col->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
					}
				}

				btTransform tr;
				tr.setIdentity();
				tr = linkTransformInWorldSpace;
				//if we don't set the initial pose of the btCollisionObject, the simulator will do this
				//when syncing the btMultiBody link transforms to the btMultiBodyLinkCollider

				col->setWorldTransform(tr);

				//base and fixed? -> static, otherwise flag as dynamic
				bool isDynamic = (mbLinkIndex < 0 && cache.m_bulletMultiBody->hasFixedBase()) ? false : true;
				int collisionFilterGroup = isDynamic ? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
				int collisionFilterMask = isDynamic ? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);

				int colGroup = 0, colMask = 0;
				int collisionFlags = u2b.getCollisionGroupAndMask(urdfLinkIndex, colGroup, colMask);
				if (collisionFlags & URDF_HAS_COLLISION_GROUP)
				{
					collisionFilterGroup = colGroup;
				}
				if (collisionFlags & URDF_HAS_COLLISION_MASK)
				{
					collisionFilterMask = colMask;
				}
				world1->addCollisionObject(col, collisionFilterGroup, collisionFilterMask);

				btVector4 color2 = selectColor2();  //(0.0,0.0,0.5);
				btVector3 specularColor(1, 1, 1);
				UrdfMaterialColor matCol;
				if (u2b.getLinkColor2(urdfLinkIndex, matCol))
				{
					color2 = matCol.m_rgbaColor;
					specularColor = matCol.m_specularColor;
				}
				{
					B3_PROFILE("createCollisionObjectGraphicsInstance2");
					creation.createCollisionObjectGraphicsInstance2(urdfLinkIndex, col, color2, specularColor);
				}
				{
					B3_PROFILE("convertLinkVisualShapes2");
					u2b.convertLinkVisualShapes2(mbLinkIndex, urdfLinkIndex, pathPrefix, localInertialFrame, col, u2b.getBodyUniqueId());
				}
				URDFLinkContactInfo contactInfo;
				u2b.getLinkContactInfo(urdfLinkIndex, contactInfo);

				processContactParameters(contactInfo, col);

				if (mbLinkIndex >= 0)  //???? double-check +/- 1
				{
					cache.m_bulletMultiBody->getLink(mbLinkIndex).m_collider = col;
					if (flags & CUF_USE_SELF_COLLISION_INCLUDE_PARENT)
					{
						cache.m_bulletMultiBody->getLink(mbLinkIndex).m_flags &= ~BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION;
					}
					if (flags & CUF_USE_SELF_COLLISION_EXCLUDE_ALL_PARENTS)
					{
						cache.m_bulletMultiBody->getLink(mbLinkIndex).m_flags |= BT_MULTIBODYLINKFLAGS_DISABLE_ALL_PARENT_COLLISION;
					}
				}
				else
				{
					//					if (canSleep)
					{
						if (cache.m_bulletMultiBody->getBaseMass() == 0)
						//&& cache.m_bulletMultiBody->getNumDofs()==0)
						{
							//col->setCollisionFlags(btCollisionObject::CF_KINEMATIC_OBJECT);
							col->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT);
						}
					}

					cache.m_bulletMultiBody->setBaseCollider(col);
				}
			}
		}
		else
		{
			int mbLinkIndex = cache.getMbIndexFromUrdfIndex(urdfLinkIndex);
			//u2b.convertLinkVisualShapes2(mbLinkIndex, urdfLinkIndex, pathPrefix, localInertialFrame, col, u2b.getBodyUniqueId());
			u2b.convertLinkVisualShapes2(-1, urdfLinkIndex, pathPrefix, localInertialFrame, linkRigidBody, u2b.getBodyUniqueId());
		}
	}

	btAlignedObjectArray<int> urdfChildIndices;
	u2b.getLinkChildIndices(urdfLinkIndex, urdfChildIndices);

	int numChildren = urdfChildIndices.size();

	if (recursive)
	{
		for (int i = 0; i < numChildren; i++)
		{
			int urdfChildLinkIndex = urdfChildIndices[i];

			ConvertURDF2BulletInternal(u2b, creation, cache, urdfChildLinkIndex, linkTransformInWorldSpace, world1, createMultiBody, pathPrefix, flags, cachedLinkGraphicsShapesIn, cachedLinkGraphicsShapesOut, recursive);
		}
	}
	return linkTransformInWorldSpace;
}
예제 #4
0
파일: main.cpp 프로젝트: rodrimc/RayTracing
Color trace (const Ray& ray, std::set<IShape*>& sceneShapes,
						 std::set<Light*>& sceneLights, int depth)
{
	Color pixelColor (0.3);

	float near;
	Color color;
	Vector3D normal;
	IShape *shape = calculateIntersect (ray, sceneShapes, &near, normal, color);
	if (shape)
	{
		pixelColor = color;
		Point intersectionPoint = ray.calculate (near);

		Vector3D n;
		Color c;

		pixelColor = Color (0.0f);

		//Calculate illumination on intersected pixel
		for (auto light : sceneLights)
		{
			Vector3D lightDirection = (light->position () - intersectionPoint);

			float lightLenght = lightDirection.normalize ();

			const Ray shadowRay (intersectionPoint + normal * bias, lightDirection,
													 lightLenght);
			float near = INFINITY;

			IShape *s = calculateIntersect (shadowRay, sceneShapes, &near, n, c);
			if (!s) //There is no object between the intersected pixel and this light.
			{
				float diffuseCoefficient = shape->diffuse ();
				float specularCoefficient = shape->specular ();

				pixelColor += ambientColor (color);
				if (diffuseCoefficient > 0.0f)
					pixelColor += diffuseColor (lightDirection, light, normal, color,
																			diffuseCoefficient);

				if (specularCoefficient > 0.0f)
					pixelColor += specularColor (lightDirection, normal, ray, light,
																			 specularCoefficient);
			}
			else //Intersected pixel is shadowed!!!
			{
				pixelColor = color * 0.1;
				break;
			}
		}

		//Calculate the reflected color
		if ((shape->reflection () > 0)
				&& depth <= MAX_DEPTH)
		{
			Vector3D reflDir = ray.direction ()
					- normal * 2 * ray.direction ().dot (normal);
			reflDir.normalize ();

			Ray reflectionRay (intersectionPoint + normal * bias, reflDir);
			Color reflectionColor = trace (reflectionRay, sceneShapes, sceneLights,
			                               depth + 1);

			pixelColor += reflectionColor * shape->reflection ();
		}

	}

	pixelColor.clamp ();
	return pixelColor;
}
예제 #5
0
BxDF* XMLReader::LoadBxDF(QXmlStreamReader &xml_reader)
{
    BxDF* result = NULL;
    //First check what type of material we're supposed to load
    QXmlStreamAttributes attribs(xml_reader.attributes());
    QStringRef type = attribs.value(QString(), QString("type"));
    if(QStringRef::compare(type, QString("lambert")) == 0)
    {
        glm::vec3 diffuseColor(0.5f);
        QStringRef color = attribs.value(QString(), QString("diffuseColor"));
        if(QStringRef::compare(color, QString("")) != 0)
        {
            diffuseColor = ToVec3(color);
        }
        result = new LambertBxDF(diffuseColor);
    }
    else if(QStringRef::compare(type, QString("specularReflection")) == 0)
    {
        glm::vec3 refl_color(0.5f);
        QStringRef color = attribs.value(QString(), QString("reflectionColor"));
        if(QStringRef::compare(color, QString("")) != 0)
        {
            refl_color = ToVec3(color);
        }
        result = new SpecularReflectionBxDF(refl_color);
    }
    else if(QStringRef::compare(type, QString("blinnMicrofacet")) == 0)
    {
        glm::vec3 refl_color(0.5f);
        QStringRef color = attribs.value(QString(), QString("reflectionColor"));
        if(QStringRef::compare(color, QString("")) != 0)
        {
            refl_color = ToVec3(color);
        }
        result = new BlinnMicrofacetBxDF(refl_color);

        QStringRef exponent = attribs.value(QString(), QString("exponent"));
        if(QStringRef::compare(exponent, QString("")) != 0)
        {
            ((BlinnMicrofacetBxDF*)result)->exponent = exponent.toFloat();
        }
    }

    else if(QStringRef::compare(type, QString("anisotropic")) == 0)
    {
        glm::vec3 refl_color(0.5f);
        QStringRef color = attribs.value(QString(), QString("reflectionColor"));
        if(QStringRef::compare(color, QString("")) != 0)
        {
            refl_color = ToVec3(color);
        }

        float exp1 = 4.0f;
        QStringRef e1 = attribs.value(QString(), QString("exponent1"));
        if(QStringRef::compare(e1, QString("")) != 0)
        {
            exp1 =  e1.toFloat();
        }

        float exp2 = 20.0f;
        QStringRef e2 = attribs.value(QString(), QString("exponent2"));
        if(QStringRef::compare(e2, QString("")) != 0)
        {
            exp2 =  e2.toFloat();
        }
        result = new AnisotropicBxDF(refl_color, exp1, exp2);
    }

    else if(QStringRef::compare(type, QString("phong")) == 0)
    {
        glm::vec3 diffuseColor(0.5f);
        QStringRef diffuse_color = attribs.value(QString(), QString("diffuseColor"));
        if(QStringRef::compare(diffuse_color, QString("")) != 0)
        {
            diffuseColor = ToVec3(diffuse_color);
        }

        glm::vec3 specularColor(1);
        QStringRef specular_color = attribs.value(QString(), QString("specularColor"));
        if(QStringRef::compare(specular_color, QString("")) != 0)
        {
            specularColor = ToVec3(specular_color);
        }

        float specularPower = 5.0f;
        QStringRef specular_power = attribs.value(QString(), QString("specularPower"));
        if(QStringRef::compare(specular_power, QString("")) != 0)
        {
            specularPower = specular_power.toFloat();
        }

        result = new PhongBxDF(diffuseColor, specularColor, specularPower);
    }
    else if(QStringRef::compare(type, QString("transmission")) == 0)
    {

        float ei = 1.0f;
        float et = 1.0f;

        QStringRef eta_i = attribs.value(QString(), QString("etai"));
        if(QStringRef::compare(eta_i, QString("")) != 0)
        {
            ei = eta_i.toFloat();
        }

        QStringRef eta_t = attribs.value(QString(), QString("etat"));
        if(QStringRef::compare(eta_i, QString("")) != 0)
        {
            et = eta_t.toFloat();
        }

        glm::vec3 transmissionColor(1);
        QStringRef trans = attribs.value(QString(), QString("transmissionColor"));
        if(QStringRef::compare(trans, QString("")) != 0)
        {
            transmissionColor = ToVec3(trans);
        }

        result = new TransmissionBxDF(ei,et,transmissionColor);
    }
    else
    {
        std::cout << "Could not parse the BxDF!" << std::endl;
        return NULL;
    }
    result->name = attribs.value(QString(), QString("name")).toString();
    return result;
}
예제 #6
0
int main( int argc, char **argv )
{
    int width = 1024, height=768;
    float widthf = (float) width, heightf = (float) height;
    double t;
    float fps = 0.f;

    // Initialise GLFW
    if( !glfwInit() )
    {
        fprintf( stderr, "Failed to initialize GLFW\n" );
        exit( EXIT_FAILURE );
    }

    // Force core profile on Mac OSX
#ifdef __APPLE__
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3);
    glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2);
    glfwOpenWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#endif
    // Open a window and create its OpenGL context
    if( !glfwOpenWindow( width, height, 0,0,0,0, 24, 0, GLFW_WINDOW ) )
    {
        fprintf( stderr, "Failed to open GLFW window\n" );

        glfwTerminate();
        exit( EXIT_FAILURE );
    }

    glfwSetWindowTitle( "002_forward_a" );


    // Core profile is flagged as experimental in glew
#ifdef __APPLE__
    glewExperimental = GL_TRUE;
#endif
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
          /* Problem: glewInit failed, something is seriously wrong. */
          fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
          exit( EXIT_FAILURE );
    }

    // Ensure we can capture the escape key being pressed below
    glfwEnable( GLFW_STICKY_KEYS );

    // Enable vertical sync (on cards that support it)
    glfwSwapInterval( 1 );
    GLenum glerr = GL_NO_ERROR;
    glerr = glGetError();

    if (!imguiRenderGLInit(DroidSans_ttf, DroidSans_ttf_len))
    {
        fprintf(stderr, "Could not init GUI renderer.\n");
        exit(EXIT_FAILURE);
    }

    // Init viewer structures
    Camera camera;
    camera_defaults(camera);
    GUIStates guiStates;
    init_gui_states(guiStates);

    // GUI
    float intensity = 1.0;

    // Load images and upload textures
    GLuint textures[3];
    glGenTextures(3, textures);
    int x;
    int y;
    int comp; 
    unsigned char * diffuse = stbi_load("textures/spnza_bricks_a_diff.tga", &x, &y, &comp, 3);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, diffuse);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    fprintf(stderr, "Diffuse %dx%d:%d\n", x, y, comp);
    unsigned char * spec = stbi_load("textures/spnza_bricks_a_spec.tga", &x, &y, &comp, 1);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, textures[1]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, x, y, 0, GL_RED, GL_UNSIGNED_BYTE, spec);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    fprintf(stderr, "Spec %dx%d:%d\n", x, y, comp);

    // Try to load and compile shader
    ShaderGLSL shader;
    const char * shaderFile = "002/1.glsl";
    //int status = load_shader_from_file(shader, shaderFile, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER | ShaderGLSL::GEOMETRY_SHADER);
    int status = load_shader_from_file(shader, shaderFile, ShaderGLSL::VERTEX_SHADER | ShaderGLSL::FRAGMENT_SHADER);
    if ( status == -1 )
    {
        fprintf(stderr, "Error on loading  %s\n", shaderFile);
        exit( EXIT_FAILURE );
    }    

    // Apply shader
    GLuint program = shader.program;
    glUseProgram(program);
    GLuint projectionLocation = glGetUniformLocation(program, "Projection");
    GLuint viewLocation = glGetUniformLocation(program, "View");
    GLuint objectLocation = glGetUniformLocation(program, "Object");
    GLuint timeLocation = glGetUniformLocation(program, "Time");
    GLuint diffuseLocation = glGetUniformLocation(program, "Diffuse");
    GLuint specLocation = glGetUniformLocation(program, "Spec");
    GLuint intensityLocation = glGetUniformLocation(program, "Intensity");
    GLuint cameraPositionLocation = glGetUniformLocation(program, "CameraPosition");

    GLuint lightPositionLocation = glGetUniformLocation(program, "LightPosition");
    GLuint lightIntensityLocation = glGetUniformLocation(program, "LightIntensity");
    GLuint diffuseColorLocation = glGetUniformLocation(program, "DiffuseColor");
    GLuint specularColorLocation = glGetUniformLocation(program, "SpecularColor");
    GLuint specularFactorLocation = glGetUniformLocation(program, "SpecularFactor");

    GLuint lightPositionLocation2 = glGetUniformLocation(program, "LightPosition2");
    GLuint lightIntensityLocation2 = glGetUniformLocation(program, "LightIntensity2");
    GLuint diffuseColorLocation2 = glGetUniformLocation(program, "DiffuseColor2");
    GLuint specularColorLocation2 = glGetUniformLocation(program, "SpecularColor2");
    GLuint specularFactorLocation2 = glGetUniformLocation(program, "SpecularFactor2");

    GLuint spotLightExternalAngleLocation = glGetUniformLocation(program, "SpotLightExternalAngle");
    GLuint spotLightInternalAngleLocation = glGetUniformLocation(program, "SpotLightInternalAngle");


    // Load geometry
    int cube_triangleCount = 12;
    int cube_triangleList[] = {0, 1, 2, 2, 1, 3, 4, 5, 6, 6, 5, 7, 8, 9, 10, 10, 9, 11, 12, 13, 14, 14, 13, 15, 16, 17, 18, 19, 17, 20, 21, 22, 23, 24, 25, 26, };
    float cube_uvs[] = {0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f,  1.f, 0.f,  1.f, 1.f,  0.f, 1.f,  1.f, 1.f,  0.f, 0.f, 0.f, 0.f, 1.f, 1.f,  1.f, 0.f,  };
    float cube_vertices[] = {-0.5, -0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, -0.5, -0.5, 0.5, -0.5, -0.5, -0.5, 0.5, -0.5, 0.5, 0.5 };
    float cube_normals[] = {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, };
    int plane_triangleCount = 2;
    int plane_triangleList[] = {0, 1, 2, 2, 1, 3}; 
    float plane_uvs[] = {0.f, 0.f, 0.f, 10.f, 10.f, 0.f, 10.f, 10.f};
    float plane_vertices[] = {-50.0, -1.0, 50.0, 50.0, -1.0, 50.0, -50.0, -1.0, -50.0, 50.0, -1.0, -50.0};
    float plane_normals[] = {0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0};

    // Vertex Array Object
    GLuint vao[2];
    glGenVertexArrays(2, vao);

    // Vertex Buffer Objects
    GLuint vbo[8];
    glGenBuffers(8, vbo);

    // Cube
    glBindVertexArray(vao[0]);
    // Bind indices and upload data
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(cube_triangleList), cube_triangleList, GL_STATIC_DRAW);
    // Bind vertices and upload data
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices), cube_vertices, GL_STATIC_DRAW);
    // Bind normals and upload data
    glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cube_normals), cube_normals, GL_STATIC_DRAW);
    // Bind uv coords and upload data
    glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cube_uvs), cube_uvs, GL_STATIC_DRAW);

    // Plane
    glBindVertexArray(vao[1]);
    // Bind indices and upload data
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(plane_triangleList), plane_triangleList, GL_STATIC_DRAW);
    // Bind vertices and upload data
    glBindBuffer(GL_ARRAY_BUFFER, vbo[5]);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(plane_vertices), plane_vertices, GL_STATIC_DRAW);
    // Bind normals and upload data
    glBindBuffer(GL_ARRAY_BUFFER, vbo[6]);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*3, (void*)0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(plane_normals), plane_normals, GL_STATIC_DRAW);
    // Bind uv coords and upload data
    glBindBuffer(GL_ARRAY_BUFFER, vbo[7]);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(GL_FLOAT)*2, (void*)0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(plane_uvs), plane_uvs, GL_STATIC_DRAW);

    // Unbind everything. Potentially illegal on some implementations
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // Viewport 
    glViewport( 0, 0, width, height  );

    // Default states

    glm::vec3 lightPosition(0.0, 1.0, 10);
    float lightIntensity = 1.0f;
    glm::vec3 diffuseColor(1.0, 1.0, 1.0);
    glm::vec3 specularColor(1.0, 1.0, 1.0);
    float specularFactor = 100.f;

    glm::vec3 lightPosition2(1.0, 0.0, 10);
    float lightIntensity2 = 1.0f;
    glm::vec3 diffuseColor2(1.0, 0.0, 0.0);
    glm::vec3 specularColor2(1.0, 1.0, 1.0);
    float specularFactor2 = 100.f;

    float spotLightInternal = M_PI/32;
    float spotLightExternal = M_PI/16;

    bool checkedLight1 = true;
    bool checkedLight2 = false;
    bool checkedLight3 = false;

    do
    {
        t = glfwGetTime();
        glEnable(GL_DEPTH_TEST);

        // Mouse states
        int leftButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_LEFT );
        int rightButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_RIGHT );
        int middleButton = glfwGetMouseButton( GLFW_MOUSE_BUTTON_MIDDLE );

        if( leftButton == GLFW_PRESS )
            guiStates.turnLock = true;
        else
            guiStates.turnLock = false;

        if( rightButton == GLFW_PRESS )
            guiStates.zoomLock = true;
        else
            guiStates.zoomLock = false;

        if( middleButton == GLFW_PRESS )
            guiStates.panLock = true;
        else
            guiStates.panLock = false;

        // Camera movements
        int altPressed = glfwGetKey(GLFW_KEY_LSHIFT);
        if (!altPressed && (leftButton == GLFW_PRESS || rightButton == GLFW_PRESS || middleButton == GLFW_PRESS))
        {
            int x; int y;
            glfwGetMousePos(&x, &y);
            guiStates.lockPositionX = x;
            guiStates.lockPositionY = y;
        }
        if (altPressed == GLFW_PRESS)
        {
            int mousex; int mousey;
            glfwGetMousePos(&mousex, &mousey);
            int diffLockPositionX = mousex - guiStates.lockPositionX;
            int diffLockPositionY = mousey - guiStates.lockPositionY;
            if (guiStates.zoomLock)
            {
                float zoomDir = 0.0;
                if (diffLockPositionX > 0)
                    zoomDir = -1.f;
                else if (diffLockPositionX < 0 )
                    zoomDir = 1.f;
                camera_zoom(camera, zoomDir * GUIStates::MOUSE_ZOOM_SPEED);
            }
            else if (guiStates.turnLock)
            {
                camera_turn(camera, diffLockPositionY * GUIStates::MOUSE_TURN_SPEED,
                            diffLockPositionX * GUIStates::MOUSE_TURN_SPEED);

            }
            else if (guiStates.panLock)
            {
                camera_pan(camera, diffLockPositionX * GUIStates::MOUSE_PAN_SPEED,
                            diffLockPositionY * GUIStates::MOUSE_PAN_SPEED);
            }
            guiStates.lockPositionX = mousex;
            guiStates.lockPositionY = mousey;
        }
  
        // Get camera matrices
        glm::mat4 projection = glm::perspective(45.0f, widthf / heightf, 0.1f, 100.f); 
        glm::mat4 worldToView = glm::lookAt(camera.eye, camera.o, camera.up);
        glm::mat4 objectToWorld;

        // Clear the front buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        // Bind textures
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, textures[0]);
        glActiveTexture(GL_TEXTURE1);
        glBindTexture(GL_TEXTURE_2D, textures[1]);

        // Bind shader
        glUseProgram(program);

        // Upload uniforms
        glUniformMatrix4fv(projectionLocation, 1, 0, glm::value_ptr(projection));
        glUniformMatrix4fv(viewLocation, 1, 0, glm::value_ptr(worldToView));
        glUniformMatrix4fv(objectLocation, 1, 0, glm::value_ptr(objectToWorld));
        glUniform1f(timeLocation, t);
        glUniform3fv(cameraPositionLocation, 1, glm::value_ptr(camera.eye));
        glUniform1f(intensityLocation, intensity);
        glUniform1i(diffuseLocation, 0);
        glUniform1i(specLocation, 1);
        
        glUniform3fv(lightPositionLocation, 1, glm::value_ptr(lightPosition));
        glUniform1f(lightIntensityLocation, lightIntensity);
        glUniform3fv(diffuseColorLocation, 1, glm::value_ptr(diffuseColor));
        glUniform3fv(specularColorLocation, 1, glm::value_ptr(specularColor));
        glUniform1f(specularFactorLocation, specularFactor);

        glUniform3fv(lightPositionLocation2, 1, glm::value_ptr(lightPosition2));
        glUniform1f(lightIntensityLocation2, lightIntensity2);
        glUniform3fv(diffuseColorLocation2, 1, glm::value_ptr(diffuseColor2));
        glUniform3fv(specularColorLocation2, 1, glm::value_ptr(specularColor2));
        glUniform1f(specularFactorLocation2, specularFactor2);

        glUniform1f(spotLightInternalAngleLocation, spotLightInternal);
        glUniform1f(spotLightExternalAngleLocation, spotLightExternal);

        // Render vaos
        glBindVertexArray(vao[0]);
        glDrawElementsInstanced(GL_TRIANGLES, cube_triangleCount * 3, GL_UNSIGNED_INT, (void*)0, 4);
        glBindVertexArray(vao[1]);
        glDrawElements(GL_TRIANGLES, plane_triangleCount * 3, GL_UNSIGNED_INT, (void*)0);

#if 1
        // Draw UI
        glDisable(GL_DEPTH_TEST);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glViewport(0, 0, width, height);

        unsigned char mbut = 0;
        int mscroll = 0;
        int mousex; int mousey;
        glfwGetMousePos(&mousex, &mousey);
        mousey = height - mousey;

        if( leftButton == GLFW_PRESS )
            mbut |= IMGUI_MBUT_LEFT;

        imguiBeginFrame(mousex, mousey, mbut, mscroll);
        int logScroll = 0;
        char lineBuffer[512];
        imguiBeginScrollArea("001", 0, 0, 200, height, &logScroll);
        sprintf(lineBuffer, "FPS %f", fps);
        imguiLabel(lineBuffer);
        
        int toggle = 0;
        toggle = imguiCollapse("Light1", "", checkedLight1);
            
        if(checkedLight1)
        { 
            imguiIndent();
            imguiIndent();
                imguiLabel("Light Position");
                imguiIndent();
                    imguiSlider("x", &lightPosition.x, -10, 10, 0.01);
                    imguiSlider("y", &lightPosition.y, -10, 10, 0.01);
                    imguiSlider("z", &lightPosition.z, -10, 10, 0.01);
                imguiUnindent();
                imguiSlider("Light Intensity", &lightIntensity, 0, 3, 0.01);
                imguiLabel("Diffuse Color");
                imguiIndent();
                    imguiSlider("r", &diffuseColor.x, 0, 1, 0.001);
                    imguiSlider("g", &diffuseColor.y, 0, 1, 0.001);
                    imguiSlider("b", &diffuseColor.z, 0, 1, 0.001);
                imguiUnindent();
                imguiLabel("Specular Color");
                imguiIndent();
                    imguiSlider("r", &specularColor.x, 0, 1, 0.001);
                    imguiSlider("g", &specularColor.y, 0, 1, 0.001);
                    imguiSlider("b", &specularColor.z, 0, 1, 0.001);
                imguiUnindent();
                imguiSlider("Specular Intensity", &specularFactor, 0, 100, 1);
            imguiUnindent();
            imguiUnindent();
        }
        if (toggle)
        {
            checkedLight1 = !checkedLight1;
        }

        toggle = imguiCollapse("Light2", "", checkedLight2);
        if(checkedLight2)
        { 
            imguiIndent();
            imguiIndent();
                imguiLabel("Light Position");
                imguiIndent();
                    imguiSlider("x", &lightPosition2.x, -10, 10, 0.01);
                    imguiSlider("y", &lightPosition2.y, -10, 10, 0.01);
                    imguiSlider("z", &lightPosition2.z, -10, 10, 0.01);
                imguiUnindent();
                imguiSlider("Light Intensity", &lightIntensity2, 0, 3, 0.01);
                imguiLabel("Diffuse Color");
                imguiIndent();
                    imguiSlider("r", &diffuseColor2.x, 0, 1, 0.001);
                    imguiSlider("g", &diffuseColor2.y, 0, 1, 0.001);
                    imguiSlider("b", &diffuseColor2.z, 0, 1, 0.001);
                imguiUnindent();
                imguiLabel("Specular Color");
                imguiIndent();
                    imguiSlider("r", &specularColor2.x, 0, 1, 0.001);
                    imguiSlider("g", &specularColor2.y, 0, 1, 0.001);
                    imguiSlider("b", &specularColor2.z, 0, 1, 0.001);
                imguiUnindent();
                imguiSlider("Specular Intensity", &specularFactor2, 0, 100, 1);
            imguiUnindent();
            imguiUnindent();
        }
        if (toggle)
        {
            checkedLight2 = !checkedLight2;
        }

        toggle = imguiCollapse("SpotLight", "", checkedLight3);
        if(checkedLight3)
        { 
            imguiIndent();
            imguiIndent();
                imguiSlider("External Angle", &spotLightExternal, 0, 2, 0.01);
                imguiSlider("Internal Angle", &spotLightInternal, 0, 2, 0.01);
            imguiUnindent();
            imguiUnindent();
        }
        if (toggle)
        {
            checkedLight3 = !checkedLight3;
        }

        imguiEndScrollArea();
        imguiEndFrame();
        imguiRenderGLDraw(width, height); 

        glDisable(GL_BLEND);
#endif
        
        // Check for errors
        GLenum err = glGetError();
        if(err != GL_NO_ERROR)
        {
            fprintf(stderr, "OpenGL Error : %s\n", gluErrorString(err));
            
        }

        // Swap buffers
        glfwSwapBuffers();

    } // Check if the ESC key was pressed or the window was closed
    while( glfwGetKey( GLFW_KEY_ESC ) != GLFW_PRESS &&
           glfwGetWindowParam( GLFW_OPENED ) );

    // Clean UI
    imguiRenderGLDestroy();

    // Close OpenGL window and terminate GLFW
    glfwTerminate();

    exit( EXIT_SUCCESS );
}