/********************************************************************/ /* Copyright (c) 2017 System fugen G.K. and Yuzi Mizuno */ /* All rights reserved. */ /********************************************************************/ #include "MGCLStdAfx.h" #include "mg/Position.h" #include "mg/Transf.h" #include "mg/Ofstream.h" #include "mg/Ifstream.h" #include "mgGL/DirectionalLight.h" #include "mgGL/SpotLight.h" #include "mgGL/glslprogram.h" #if defined(_DEBUG) #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif //////////////////////////////////////////////////////////////////// MGLight::MGLight() :MGGLAttrib(0), m_intensity(1.), m_ambientIntensity(0.){ for(int i=0; i<3; i++) m_color[i]=1.; } MGLight::MGLight( float intensity, //applied to GL_DIFFUSE and GL_SPECULAR float ambientIntensity, //applied to GL_AMBIENT const float color[3] //applied to GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR ):MGGLAttrib(0), m_intensity(intensity), m_ambientIntensity(ambientIntensity){ for(int i=0; i<3; i++) m_color[i]=color[i]; } //assignment MGLight& MGLight::operator=(const MGLight& gel2){ set_light(gel2); return *this; } MGLight& MGLight::operator=(const MGGel& gel2){ const MGLight* gel2_is_this=dynamic_cast(&gel2); if(gel2_is_this) operator=(*gel2_is_this); return *this; } MGLight* MGLight::clone()const{ return new MGLight(*this); } //assignment MGLight& MGLight::set_light(const MGLight& gel2){ MGGLAttrib::operator=(gel2); m_intensity=gel2.m_intensity; m_ambientIntensity=gel2.m_ambientIntensity; for(int i=0; i<3;i++) m_color[i]=gel2.m_color[i]; return *this; } bool MGLight::operator<(const MGLight& gel2)const{ if(m_intensity==gel2.m_intensity) if(m_ambientIntensity==gel2.m_ambientIntensity) return m_color[0](&gel2); if(gel2_is_this) return operator<(*gel2_is_this); return false; } // int MGLight::exec()const{ GLenum lightNo=get_light_num(); // ライトの最大数は10こまで。mgclShader.fragより。 ASSERT(lightNo>=0 && lightNo < mgGLSLProgram::LIGHT_NUM); mgGLSLProgram* glsl=mgGLSLProgram::getCurrentGLSLProgram(); glsl->setUniformLights(lightNo, mgGLSLProgram::isEnabled , enabled()); if(enabled()){ int i; glm::vec4 color = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); //Ambient Color. GL_AMBIENT for(i=0; i<3; i++){ color[i]=m_color[i]*m_ambientIntensity; } glsl->setUniformLights(lightNo, mgGLSLProgram::ambientColor, color); //Light Color. GL_DIFFUSE and GL_SPECULAR for(i=0; i<3; i++){ color[i]=m_color[i]*m_intensity; } glsl->setUniformLights(lightNo, mgGLSLProgram::diffuseColor, color); glsl->setUniformLights(lightNo, mgGLSLProgram::specularColor, color); } return lightNo; } void MGLight::ResetLight(GLint lightNo){ ASSERT(lightNo >= 0 && lightNo<10); mgGLSLProgram* glsl=mgGLSLProgram::getCurrentGLSLProgram(); glsl->setUniformLights(lightNo, mgGLSLProgram::isEnabled, false); glsl->setUniformLights(lightNo, mgGLSLProgram::ambientColor, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); glsl->setUniformLights(lightNo, mgGLSLProgram::diffuseColor, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); glsl->setUniformLights(lightNo, mgGLSLProgram::specularColor, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); glsl->setUniformLights(lightNo, mgGLSLProgram::position, glm::vec4(0.0f, 0.0f, 1.0f, 0.0f)); glsl->setUniformLights(lightNo, mgGLSLProgram::spotDirection, glm::vec3(0.0f, 0.0f, -1.0f)); glsl->setUniformLights(lightNo, mgGLSLProgram::spotExponent, 0.0f); glsl->setUniformLights(lightNo, mgGLSLProgram::spotCutoff , 180.0f); glsl->setUniformLights(lightNo, mgGLSLProgram::constantAttenuation, 1.0f); glsl->setUniformLights(lightNo, mgGLSLProgram::linearAttenuation, 0.0f); glsl->setUniformLights(lightNo, mgGLSLProgram::quadraticAttenuation, 0.0f); } //Get light number available next. GLenum MGLight::get_light_num()const{ // return GL_LIGHT0+m_lightNum; return (GLenum)m_lightNum; } ///Turn off this light, returned is the old state(UNDEFINED/OFF/ON). int MGLight::turn_off(){ int old=m_flag; m_flag=OFF; return old; } ///Turn on this light, returned is the old state(UNDEFINED/OFF/ON). int MGLight::turn_on(){ int old=m_flag; m_flag=ON; return old; } // Output function. std::ostream& MGLight::out(std::ostream& ostrm) const{ ostrm<<"Lgiht="; if(m_flag==ON) ostrm<<"ON"; else if(m_flag==OFF) ostrm<<"OFF"; else{ MGGLAttrib::out(ostrm); return ostrm; } ostrm<<",intensity="<(&gel2); if(gel2_is_this) operator=(*gel2_is_this); return *this; } bool MGDirectionalLight::operator<(const MGDirectionalLight& gel2)const{ if(MGLight::operator<(gel2)) return true; return m_direction[0](&gel2); if(gel2_is_this) return operator<(*gel2_is_this); return false; } //exec GLAttribute process. int MGDirectionalLight::exec()const{ GLenum lightNo=MGLight::exec(); mgGLSLProgram* glsl=mgGLSLProgram::getCurrentGLSLProgram(); ////Light Positionは無限遠点(w=0なので), 位置はdirectionを負に // GL_POSITION glm::vec4 pos = glm::vec4(-m_direction[0], -m_direction[1],-m_direction[2], 0.0f); glsl->setUniformLights(lightNo, mgGLSLProgram::position , pos); //GL_SPOT_DIRECTION glm::vec3 dir = glm::vec3(m_direction[0], m_direction[1], m_direction[2]); glsl->setUniformLights(lightNo, mgGLSLProgram::spotDirection , dir); // GL_SPOT_CUTOFF glsl->setUniformLights(lightNo, mgGLSLProgram::spotCutoff, 180.0f); return lightNo; } //////// Set/Get /////////// void MGDirectionalLight::setDirection(const MGVector& direction){ for(int i=0; i<3; i++) m_direction[i]=float(direction[i]); } void MGDirectionalLight::getDirection(MGVector& direction)const{ direction.resize(3); for(int i=0; i<3; i++) direction(i)=m_direction[i]; } // Output function. std::ostream& MGDirectionalLight::out(std::ostream& ostrm) const{ ostrm<(&gel2); if(gel2_is_this) operator=(*gel2_is_this); return *this; } bool MGPointLight::operator<(const MGPointLight& gel2)const{ if(MGLight::operator<(gel2)) return true; return m_radius(&gel2); if(gel2_is_this) return operator<(*gel2_is_this); return false; } MGPointLight* MGPointLight::clone()const{ return new MGPointLight(*this); } //exec GLAttribute process. int MGPointLight::exec()const{ GLenum lightNo = MGLight::exec(); mgGLSLProgram* glsl=mgGLSLProgram::getCurrentGLSLProgram(); // Lightの方向を設定 // GL_POSITION glm::vec4 pos = glm::vec4(m_location[0], m_location[1], m_location[2], m_location[3]); glsl->setUniformLights(lightNo, mgGLSLProgram::position , pos); // GL_SPOT_CUTOFF cos(180) = -1.0f; glsl->setUniformLights(lightNo, mgGLSLProgram::spotCutoff, 180.0f); // GL_CONSTANT_ATTENUATION glsl->setUniformLights(lightNo, mgGLSLProgram::constantAttenuation, m_attenuation[0]); // GL_LINEAR_ATTENUATION glsl->setUniformLights(lightNo, mgGLSLProgram::linearAttenuation, m_attenuation[1]); // GL_QUADRATIC_ATTENUATION glsl->setUniformLights(lightNo, mgGLSLProgram::quadraticAttenuation, m_attenuation[2]); /// TODO by Tomoko. /// PointLightのm_radiusはOpenGL的にどういう意味なのかがわからない。 return lightNo; } // Output function. std::ostream& MGPointLight::out(std::ostream& ostrm) const{ ostrm<<"PointLight="; MGLight::out(ostrm); ostrm<