void ofMaterial::updateMaterial(const ofShader & shader,ofGLProgrammableRenderer & renderer) const{
	shader.setUniform4fv("mat_ambient", &data.ambient.r);
	shader.setUniform4fv("mat_diffuse", &data.diffuse.r);
	shader.setUniform4fv("mat_specular", &data.specular.r);
	shader.setUniform4fv("mat_emissive", &data.emissive.r);
	shader.setUniform4fv("global_ambient", &ofGetGlobalAmbientColor().r);
	shader.setUniform1f("mat_shininess",data.shininess);
}
void ofMaterial::updateMaterial(const ofShader & shader,ofGLProgrammableRenderer & renderer) const{
	shader.setUniform4fv("mat_ambient", &data.ambient.r);
	shader.setUniform4fv("mat_diffuse", &data.diffuse.r);
	shader.setUniform4fv("mat_specular", &data.specular.r);
	shader.setUniform4fv("mat_emissive", &data.emissive.r);
	shader.setUniform4fv("global_ambient", &ofGetGlobalAmbientColor().r);
	shader.setUniform1f("mat_shininess",data.shininess);
	for(auto & uniform: uniforms1f){
		shader.setUniform1f(uniform.first, uniform.second);
	}
	for (auto & uniform : uniforms2f) {
		shader.setUniform2f(uniform.first, uniform.second);
	}
	for (auto & uniform : uniforms3f) {
		shader.setUniform3f(uniform.first, uniform.second);
	}
	for (auto & uniform : uniforms4f) {
		shader.setUniform4f(uniform.first, uniform.second);
	}
	for (auto & uniform : uniforms1i) {
		shader.setUniform1i(uniform.first, uniform.second);
	}
	for (auto & uniform : uniforms2i) {
		shader.setUniform2i(uniform.first, uniform.second.x, uniform.second.y);
	}
	for (auto & uniform : uniforms3i) {
		shader.setUniform3i(uniform.first, uniform.second.x, uniform.second.y, uniform.second.z);
	}
	for (auto & uniform : uniforms4i) {
		shader.setUniform4i(uniform.first, uniform.second.x, uniform.second.y, uniform.second.z, uniform.second.w);
	}
	for (auto & uniform : uniformstex) {
		shader.setUniformTexture(uniform.first,
								 uniform.second.textureTarget,
								 uniform.second.textureID,
								 uniform.second.textureLocation);
	}
}
void ofMaterial::beginShader(int texType){
	initShaders();
	switch(texType){
	case OF_NO_TEXTURE:
		currentShader = &shaderNoTexture;
		break;
	case GL_TEXTURE_2D:
		currentShader = &shaderTexture2D;
		break;
	default:
		currentShader = &shaderTextureRect;
		break;
	}

	const ofMatrix4x4 & normalMatrix = ofGetCurrentNormalMatrix();
	currentShader->begin();
	currentShader->setUniformMatrix4f("normalMatrix",normalMatrix);
	currentShader->setUniform4fv("mat_ambient", &data.ambient.r);
	currentShader->setUniform4fv("mat_diffuse", &data.diffuse.r);
	currentShader->setUniform4fv("mat_specular", &data.specular.r);
	currentShader->setUniform4fv("mat_emissive", &data.emissive.r);
	currentShader->setUniform4fv("global_ambient", &ofGetGlobalAmbientColor().r);
	currentShader->setUniform1f("mat_shininess",data.shininess);

	for(size_t i=0;i<ofLightsData().size();i++){
		string idx = ofToString(i);
		if(ofLightsData()[i].expired() || !ofLightsData()[i].lock()->isEnabled){
			currentShader->setUniform1f("lights["+idx+"].enabled",0);
			continue;
		}

		shared_ptr<ofLight::Data> light = ofLightsData()[i].lock();
		ofVec4f lightEyePosition = light->position * ofGetCurrentViewMatrix();
		currentShader->setUniform1f("lights["+idx+"].enabled",1);
		currentShader->setUniform1f("lights["+idx+"].type", light->lightType);
		currentShader->setUniform4fv("lights["+idx+"].position", &lightEyePosition.x);
		currentShader->setUniform4fv("lights["+idx+"].ambient", &light->ambientColor.r);
		currentShader->setUniform4fv("lights["+idx+"].specular", &light->specularColor.r);
		currentShader->setUniform4fv("lights["+idx+"].diffuse", &light->diffuseColor.r);

		if(light->lightType==OF_LIGHT_POINT || light->lightType==OF_LIGHT_AREA){
			currentShader->setUniform1f("lights["+idx+"].constantAttenuation", light->attenuation_constant);
			currentShader->setUniform1f("lights["+idx+"].linearAttenuation", light->attenuation_linear);
			currentShader->setUniform1f("lights["+idx+"].quadraticAttenuation", light->attenuation_quadratic);
		}

		if(light->lightType==OF_LIGHT_SPOT){
			ofVec3f direction = light->position + light->direction;
			direction = direction * ofGetCurrentViewMatrix();
			direction = direction - lightEyePosition;
			currentShader->setUniform3fv("lights["+idx+"].spotDirection", &direction.x);
			currentShader->setUniform1f("lights["+idx+"].spotExponent", light->exponent);
			currentShader->setUniform1f("lights["+idx+"].spotCutoff", light->spotCutOff);
			currentShader->setUniform1f("lights["+idx+"].spotCosCutoff", cos(ofDegToRad(light->spotCutOff)));
		}else if(light->lightType==OF_LIGHT_DIRECTIONAL){
			ofVec3f halfVector = (ofVec3f(0,0,1) + lightEyePosition).getNormalized();
			currentShader->setUniform3fv("lights["+idx+"].halfVector", &halfVector.x);
		}else if(light->lightType==OF_LIGHT_AREA){
			currentShader->setUniform1f("lights["+idx+"].width", light->width);
			currentShader->setUniform1f("lights["+idx+"].height", light->height);
			ofVec3f direction = light->position + light->direction;
			direction = direction * ofGetCurrentViewMatrix();
			direction = direction - lightEyePosition;
			ofVec3f right = light->position + light->right;
			right = right * ofGetCurrentViewMatrix();
			right = right - lightEyePosition;
			ofVec3f up = right.getCrossed(direction);
			currentShader->setUniform3fv("lights["+idx+"].spotDirection", &direction.x);
			currentShader->setUniform3fv("lights["+idx+"].right", &right.x);
			currentShader->setUniform3fv("lights["+idx+"].up", &up.x);
		}
	}
}