
/*
*************************************************************************************************

lib_graph::Materialと, OpenGLのカレントマテリアルの入出力機能

*************************************************************************************************
*/


#pragma once

#include "../graph/Color.h"
#include "../graph/Material.h"


namespace lib_gl
{


//! Phongのマテリアル. OpenGL版
class MaterialSetter
{
public:
	//! 指定した面にマテリアルを適用する
	static void SetGL( const lib_graph::Material& i_material , GLenum face_type = GL_FRONT_AND_BACK , bool set_diffuse_to_color = true );

	//! OpenGLのカレントマテリアルを取得.
	//! GL_FRONT_AND_BACKは取得できないので注意
	static void GetGL( lib_graph::Material& i_material , GLenum face_type = GL_FRONT );


	//! 指定した両面マテリアルを適用する
	static void SetGL( const lib_graph::DoublesideMaterial& i_material );

	//! OpenGLのカレントマテリアルを両面マテリアルオブジェクトに取得.
	static void GetGL( lib_graph::DoublesideMaterial& i_material );
};



// implements

//! 指定した面にマテリアルを適用する
//! @param face_type            - マテリアルを適用する面
//! @param set_diffuse_to_color - trueなら、diffuseをglColorにセットする
inline void MaterialSetter::SetGL( const lib_graph::Material& i_material , GLenum face_type , bool set_diffuse_to_color )
{
	glMaterialfv( face_type , GL_AMBIENT   , i_material.m_Ambient.v()  );
	glMaterialfv( face_type , GL_DIFFUSE   , i_material.m_Diffuse.v()  );
	glMaterialfv( face_type , GL_SPECULAR  , i_material.m_Specular.v() );
	glMaterialfv( face_type , GL_EMISSION  , i_material.m_Emission.v() );
	glMaterialfv( face_type , GL_SHININESS , &i_material.m_Shininess   );
	
	if( set_diffuse_to_color )
		glColor4fv( i_material.m_Diffuse.v() );
}

//! OpenGLのカレントマテリアルを取得.
//! GL_FRONT_AND_BACKは取得できないので注意
inline void MaterialSetter::GetGL( lib_graph::Material& i_material , GLenum face_type )
{
	glGetMaterialfv( face_type , GL_AMBIENT   , i_material.m_Ambient.v()  );
	glGetMaterialfv( face_type , GL_DIFFUSE   , i_material.m_Diffuse.v()  );
	glGetMaterialfv( face_type , GL_SPECULAR  , i_material.m_Specular.v() );
	glGetMaterialfv( face_type , GL_EMISSION  , i_material.m_Emission.v() );
	glGetMaterialfv( face_type , GL_SHININESS , &i_material.m_Shininess   );
}

//! 指定した両面マテリアルを適用する
inline void MaterialSetter::SetGL( const lib_graph::DoublesideMaterial& i_material )
{
	SetGL( i_material.m_FrontMaterial , GL_FRONT , false );
	SetGL( i_material.m_BackMaterial  , GL_BACK  , false );
}

//! OpenGLのカレントマテリアルを両面マテリアルオブジェクトに取得.
inline void MaterialSetter::GetGL( lib_graph::DoublesideMaterial& i_material )
{
	GetGL( i_material.m_FrontMaterial , GL_FRONT );
	GetGL( i_material.m_BackMaterial  , GL_BACK  );
}


}
