#include "MGCLStdAfx.h" #include <cstdio> #include <sstream> #include <sys/stat.h> #include "mgGL/glslprogram.h" #include "mgGL/Color.h" #include "mgGL/StaticGLAttrib.h" namespace{GLenum glErr;}; mgGLSLProgram::mgGLSLProgram():m_handle(0), m_linked(false){;} mgGLSLProgram::~mgGLSLProgram(){ freeProgram(); } ///Delete this program and initialize this. void mgGLSLProgram::freeProgram(){ if(m_handle) glDeleteProgram(m_handle); m_handle=0; m_linked=false; m_logString=""; } bool mgGLSLProgram::compileShaderFromFile( const char* fileName, GLSLShaderType type ){ if( !fileExists(fileName) ){ m_logString = "File not found."; return false; } if( m_handle <= 0 ){ m_handle = glCreateProgram(); if( m_handle == 0) { m_logString = "Unable to create shader program."; return false; } } std::ifstream inFile( fileName, std::ios::in ); if( !inFile ) { return false; } std::ostringstream code; while( inFile.good() ) { int c = inFile.get(); if( ! inFile.eof() ) code << (char) c; } inFile.close(); return compileShaderFromString(code.str(), type); } bool mgGLSLProgram::compileShaderFromString( const std::string& source, GLSLShaderType type ){ if( m_handle <= 0 ) { m_handle = glCreateProgram(); if( m_handle == 0) { m_logString = "Unable to create shader program."; return false; } } GLuint shaderHandle = 0; switch( type ) { case VERTEX: shaderHandle = glCreateShader(GL_VERTEX_SHADER); break; case FRAGMENT: shaderHandle = glCreateShader(GL_FRAGMENT_SHADER); break; case GEOMETRY: shaderHandle = glCreateShader(GL_GEOMETRY_SHADER); break; case TESS_CONTROL: shaderHandle = glCreateShader(GL_TESS_CONTROL_SHADER); break; case TESS_EVALUATION: shaderHandle = glCreateShader(GL_TESS_EVALUATION_SHADER); break; default: return false; } const char* c_code = source.c_str(); glShaderSource( shaderHandle, 1, &c_code, NULL ); // Compile the shader glCompileShader(shaderHandle ); // Check for errors int result; glGetShaderiv( shaderHandle, GL_COMPILE_STATUS, &result ); if( GL_FALSE == result ) { // Compile failed, store log and return false int length = 0; m_logString = ""; glGetShaderiv(shaderHandle, GL_INFO_LOG_LENGTH, &length ); if( length > 0 ) { char* c_log = new char[length]; int written = 0; glGetShaderInfoLog(shaderHandle, length, &written, c_log); m_logString = c_log; delete[] c_log; } return false; }else{ // Compile succeeded, attach shader and return true glAttachShader(m_handle, shaderHandle); return true; } } bool mgGLSLProgram::link(){ if( m_linked ) return true; if( m_handle <= 0 ) return false; glLinkProgram(m_handle); int status = 0; glGetProgramiv( m_handle, GL_LINK_STATUS, &status); if( GL_FALSE == status ) { // Store log and return false int length = 0; m_logString = ""; glGetProgramiv(m_handle, GL_INFO_LOG_LENGTH, &length ); if( length > 0 ) { char* c_log = new char[length]; int written = 0; glGetProgramInfoLog(m_handle, length, &written, c_log); m_logString = c_log; delete[] c_log; } return false; }else{ build_attribLocations(); build_attribLocationsLight(); m_linked = true; return m_linked; } } void DefaultLightsSetup(); void mgGLSLProgram::use(){ if( m_handle <= 0 || (! m_linked) ) return; glUseProgram( m_handle ); setCurrentGLSLProgram(this); // Set default lighting. DefaultLightsSetup(); } void mgGLSLProgram::setCurrentGLSLProgram(mgGLSLProgram* glsl){ m_CurrrentGLSL=glsl; } mgGLSLProgram* mgGLSLProgram::getCurrentGLSLProgram(){ return m_CurrrentGLSL; } std::string& mgGLSLProgram::log(){return m_logString;} int mgGLSLProgram::getHandle(){return m_handle;} bool mgGLSLProgram::isLinked(){return m_linked;} void mgGLSLProgram::bindAttribLocation( GLuint location, const char* name){ glBindAttribLocation(m_handle, location, name); } void mgGLSLProgram::bindFragDataLocation( GLuint location, const char* name ){ glBindFragDataLocation(m_handle, location, name); } ///in vec3 vPositionのlocationを求める。 int mgGLSLProgram::getvPositionLocation()const{ static char* name ={"vPosition"}; int loc = getAttribLocation(name); assert(loc>=0); return loc; } ///in vec4 vColorのlocationを求める。 int mgGLSLProgram::getvColorLocation()const{ static char* name ={"vColor"}; int loc = getAttribLocation(name); assert(loc>=0); return loc; } ///in vec3 vNormalのlocationを求める。 int mgGLSLProgram::getvNormalLocation()const{ static char* name ={"vNormal"}; int loc = getAttribLocation(name); //assert(loc>=0); return loc; } ///in vec2 vTextureのlocationを求める。 int mgGLSLProgram::getvTextureCoordLocation()const{ static char* name ={"vTextureCoord"}; int loc = getAttribLocation(name); //assert(loc>=0); return loc; } void mgGLSLProgram::setUniform( GLint loc, float x, float y, float z){ //ASSERT(loc>=0); glUniform3f(loc,x,y,z); } void mgGLSLProgram::setUniform( GLint loc, const glm::vec3 & v){ //ASSERT(loc>=0); glUniform3f(loc,v.x,v.y,v.z); } void mgGLSLProgram::setUniform( GLint loc, const glm::vec4 & v){ //ASSERT(loc>=0); glUniform4f(loc,v.x,v.y,v.z,v.w); } void mgGLSLProgram::setUniform( GLint loc, const glm::mat4 & m){ //ASSERT(loc>=0); glUniformMatrix4fv(loc, 1, GL_FALSE, &m[0][0]); } void mgGLSLProgram::setUniform( GLint loc, const glm::mat3 & m){ //ASSERT(loc>=0); glUniformMatrix3fv(loc, 1, GL_FALSE, &m[0][0]); } void mgGLSLProgram::setUniform( GLint loc, float val ){ //ASSERT(loc>=0); glUniform1f(loc, val); } void mgGLSLProgram::setUniform( GLint loc, int val ){ //ASSERT(loc>=0); glUniform1i(loc, val); } void mgGLSLProgram::setUniform( GLint loc, bool val ){ //ASSERT(loc>=0); glUniform1i(loc, val); } void mgGLSLProgram::printActiveUniforms(){ GLint nUniforms, size, location, maxLen; GLchar* name; GLsizei written; GLenum type; glGetProgramiv( m_handle, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen); glGetProgramiv( m_handle, GL_ACTIVE_UNIFORMS, &nUniforms); name = (GLchar*) malloc( maxLen ); COUT<<"Active uniforms, Name:Index"<<std::endl; for( int i = 0; i < nUniforms; ++i ) { glGetActiveUniform( m_handle, i, maxLen, &written, &size, &type, name ); location = glGetUniformLocation(m_handle, name); COUT<<name<<":"<<location<<std::endl; } free(name); } void mgGLSLProgram::printActiveAttribs(){ GLint written, size, location, maxLength, nAttribs; GLenum type; GLchar* name; glGetProgramiv(m_handle, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxLength); glGetProgramiv(m_handle, GL_ACTIVE_ATTRIBUTES, &nAttribs); name = (GLchar *) malloc( maxLength ); COUT<<"Active attribs, Name:Index"<<std::endl; for( int i = 0; i < nAttribs; i++ ) { glGetActiveAttrib( m_handle, i, maxLength, &written, &size, &type, name ); location = glGetAttribLocation(m_handle, name); COUT<<name<<":"<<location<<std::endl; } free(name); } int mgGLSLProgram::getUniformLocation(const char* name)const{ #if _DEBUG GLint loc = glGetUniformLocation(m_handle, name); if(loc<0){ std::cerr << "GLSL::getUniformLocation: ERROR!! " << name << std::endl; } return loc; #else return glGetUniformLocation(m_handle, name); #endif } int mgGLSLProgram::getAttribLocation(const char* name)const{ #if _DEBUG GLint loc = glGetAttribLocation(m_handle, name); if(loc<0){ std::cerr << "GLSL::getAttribLocation: ERROR!! " << name << std::endl; } return loc; #else return glGetAttribLocation(m_handle, name); #endif } bool mgGLSLProgram::fileExists( const std::string& fileName)const{ struct stat info; int ret = -1; ret = stat(fileName.c_str(), &info); return 0 == ret; } void mgGLSL::printOpenGLError(int errorCode){ CString msg(gluErrorString(errorCode)); COUT<<"glError:"<<(TCAST)msg<<std::endl; } int mgGLSL::checkForOpenGLError(const char* file, int line) { // // Returns 1 if an OpenGL error occurred, 0 otherwise. // GLenum glErr; int retCode = 0; glErr = glGetError(); while (glErr != GL_NO_ERROR){ glErr = glGetError(); CString msg(gluErrorString(glErr)); COUT<<"glError in file:"<<file<<" "<<line<<" "<<(TCAST)msg<<std::endl; retCode = 1; } return retCode; } void mgGLSL::dumpGLInfo(bool dumpExtensions) { CString renderer(glGetString( GL_RENDERER )); CString vendor(glGetString( GL_VENDOR )); CString version = glGetString( GL_VERSION ); CString glslVersion = glGetString( GL_SHADING_LANGUAGE_VERSION ); GLint major, minor; glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MINOR_VERSION, &minor); COUT<<"GL Vendor :"<<(TCAST)vendor<<std::endl; COUT<<"GL Renderer :"<<(TCAST)renderer<<std::endl; COUT<<"GL Version :"<<(TCAST)version<<","<<major<<"."<<minor<<std::endl; COUT<<"GLSL Version :"<<(TCAST)glslVersion<<std::endl; if( dumpExtensions ) { GLint nExtensions; glGetIntegerv(GL_NUM_EXTENSIONS, &nExtensions); for( int i = 0; i < nExtensions; i++ ) { CString msg(glGetStringi(GL_EXTENSIONS, i)); COUT<<(TCAST)msg<<std::endl; } } } ///Set static color as selection name. void mgGLSL::setColorAsSelectionName(unsigned name){ if(!name) return; mgGLSLProgram::SELECT_NAME nub; nub.uiName=name; GLuint vColorLoc=mgGLSLProgram::vColor; glVertexAttribPointer(vColorLoc,4,GL_FLOAT,GL_FALSE,0,0); glErr=glGetError(); glVertexAttrib4Nub(vColorLoc, nub.ucName[0],nub.ucName[1],nub.ucName[2],nub.ucName[3]); glDisableVertexAttribArray(vColorLoc); } /// UniformLocationのIndexをせっと /// Shaderがロードされてから呼ばれる void mgGLSLProgram::build_attribLocations(){ memset(m_uniform_locations, -1,MAX_ATTRIB_LOC); m_uniform_locations[modelViewProjMatrix]= getUniformLocation("modelViewProjMatrix"); m_uniform_locations[modelViewMatrix] = getUniformLocation("modelViewMatrix"); m_uniform_locations[projMatrix] = getUniformLocation("projMatrix"); m_uniform_locations[normalMatrix] = getUniformLocation("normalMatrix"); m_uniform_locations[ndcMarix] = getUniformLocation("ndcMarix"); m_uniform_locations[ndcScaleMatrix] = getUniformLocation("ndcScaleMatrix"); m_uniform_locations[dpiFactor] = getUniformLocation("dpiFactor"); m_uniform_locations[DrawType] = getUniformLocation("drawType"); m_uniform_locations[FuncType] = getUniformLocation("funcType"); m_uniform_locations[ShaderMode] = getUniformLocation("ShaderMode"); m_uniform_locations[CoordinateType] = getUniformLocation("coordinateType"); m_uniform_locations[texture2D] = getUniformLocation("texture2D"); m_uniform_locations[pointSize] = getUniformLocation("pointSize"); m_uniform_locations[anchorPoint] = getUniformLocation("anchorPoint"); m_uniform_locations[LightTwoSides] = getUniformLocation("LightTwoSides"); m_uniform_locations[ForceLight] = getUniformLocation("ForceLight"); m_uniform_locations[ZebraAxis] = getUniformLocation("ZebraAxis"); m_uniform_locations[ZebraSize] = getUniformLocation("ZebraSize"); } void mgGLSLProgram::build_attribLocationsLight(){ const size_t NAMESIZE = 80; char unifornName[NAMESIZE]; for(int lightNo = 0; lightNo<LIGHT_NUM; ++lightNo){ sprintf_s(unifornName, NAMESIZE, "Lights[%u].isEnabled", lightNo); m_LightPropsIds[lightNo][isEnabled] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].ambientColor", lightNo); m_LightPropsIds[lightNo][ambientColor] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].diffuseColor", lightNo); m_LightPropsIds[lightNo][diffuseColor] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].specularColor", lightNo); m_LightPropsIds[lightNo][specularColor] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].position", lightNo); m_LightPropsIds[lightNo][position] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].spotDirection", lightNo); m_LightPropsIds[lightNo][spotDirection] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].spotExponent", lightNo); m_LightPropsIds[lightNo][spotExponent] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].spotCutoff", lightNo); m_LightPropsIds[lightNo][spotCutoff] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].constantAttenuation", lightNo); m_LightPropsIds[lightNo][constantAttenuation] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].linearAttenuation", lightNo); m_LightPropsIds[lightNo][linearAttenuation] = getUniformLocation(unifornName); sprintf_s(unifornName, NAMESIZE, "Lights[%u].quadraticAttenuation", lightNo); m_LightPropsIds[lightNo][quadraticAttenuation] = getUniformLocation(unifornName); } } void mgGLSLProgram::setUniform( mgGLSLProgram::UniformName name, float x, float y, float z){ GLint loc = m_uniform_locations[name]; setUniform(loc, x, y, z); } void mgGLSLProgram::setUniform( mgGLSLProgram::UniformName name, const glm::vec3 & v){ GLint loc = m_uniform_locations[name]; setUniform(loc, v); } void mgGLSLProgram::setUniform( mgGLSLProgram::UniformName name, const glm::vec4 & v){ GLint loc = m_uniform_locations[name]; setUniform(loc, v); } void mgGLSLProgram::setUniform( mgGLSLProgram::UniformName name, const glm::mat4 & m){ GLint loc = m_uniform_locations[name]; setUniform(loc, m); } void mgGLSLProgram::setUniform( mgGLSLProgram::UniformName name, const glm::mat3 & m){ GLint loc = m_uniform_locations[name]; setUniform(loc, m); } void mgGLSLProgram::setUniform( mgGLSLProgram::UniformName name, float val ){ GLint loc = m_uniform_locations[name]; setUniform(loc, val); } void mgGLSLProgram::setUniform( mgGLSLProgram::UniformName name, int val ){ GLint loc = m_uniform_locations[name]; setUniform(loc, val); } void mgGLSLProgram::setUniform( mgGLSLProgram::UniformName name, bool val ){ GLint loc = m_uniform_locations[name]; setUniform(loc, val); } //// LightProps void mgGLSLProgram::setUniformLights( GLint lightNo, mgGLSLProgram::LightProps name, float x, float y, float z){ ASSERT(lightNo>=0 && lightNo<LIGHT_NUM); GLint loc = m_LightPropsIds[lightNo][name]; setUniform(loc, x, y, z); } void mgGLSLProgram::setUniformLights( GLint lightNo, mgGLSLProgram::LightProps name, const glm::vec3 & v){ ASSERT(lightNo>=0 && lightNo<LIGHT_NUM); GLint loc = m_LightPropsIds[lightNo][name]; setUniform(loc, v); } void mgGLSLProgram::setUniformLights( GLint lightNo, mgGLSLProgram::LightProps name, const glm::vec4 & v){ ASSERT(lightNo>=0 && lightNo<LIGHT_NUM); GLint loc = m_LightPropsIds[lightNo][name]; setUniform(loc, v); } void mgGLSLProgram::setUniformLights( GLint lightNo, mgGLSLProgram::LightProps name, const glm::mat4 & m){ ASSERT(lightNo>=0 && lightNo<LIGHT_NUM); GLint loc = m_LightPropsIds[lightNo][name]; setUniform(loc, m); } void mgGLSLProgram::setUniformLights( GLint lightNo, mgGLSLProgram::LightProps name, const glm::mat3 & m){ ASSERT(lightNo>=0 && lightNo<LIGHT_NUM); GLint loc = m_LightPropsIds[lightNo][name]; setUniform(loc, m); } void mgGLSLProgram::setUniformLights( GLint lightNo, mgGLSLProgram::LightProps name, float val ){ ASSERT(lightNo>=0 && lightNo<LIGHT_NUM); GLint loc = m_LightPropsIds[lightNo][name]; setUniform(loc, val); } void mgGLSLProgram::setUniformLights( GLint lightNo, mgGLSLProgram::LightProps name, int val ){ ASSERT(lightNo>=0 && lightNo<LIGHT_NUM); GLint loc = m_LightPropsIds[lightNo][name]; setUniform(loc, val); } void mgGLSLProgram::setUniformLights( GLint lightNo, mgGLSLProgram::LightProps name, bool val ){ ASSERT(lightNo>=0 && lightNo<LIGHT_NUM); GLint loc = m_LightPropsIds[lightNo][name]; setUniform(loc, val); } ///Get version by glGetInteger(), and set the info ///in this program. void mgGLSLProgram::setOpenGLVersion(){ glGetIntegerv(GL_MAJOR_VERSION, &m_VersionMajor); glGetIntegerv(GL_MINOR_VERSION, &m_VersionMinor); } void mgGLSLProgram::getOpenGLVerion(GLint& major, GLint& minor)const{ major=m_VersionMajor; minor=m_VersionMinor; } /// Debugまわり void CALLBACK mgGLSL::debugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, void* userParam) { std::ostream* stream = static_cast<std::ostream*>(userParam); if(stream!=NULL){ std::ostream& out = *stream; out<<"Severity:"; if(severity == GL_DEBUG_SEVERITY_HIGH_ARB) out<<"High"; else if(severity == GL_DEBUG_SEVERITY_MEDIUM_ARB) out<<"Medium"; else if(severity == GL_DEBUG_SEVERITY_LOW_ARB) out<<"Low"; out<<"\tType (DEBUG_TYPE):"; if(type == GL_DEBUG_TYPE_ERROR_ARB) out<<"ERROR"; else if(type == GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB) out <<"DEPRECATED_BEHAVIOR"; else if(type == GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB) out <<"UNDEFINED_BEHAVIOR"; else if(type == GL_DEBUG_TYPE_PORTABILITY_ARB) out <<"PORTABILITY "; else if(type == GL_DEBUG_TYPE_PERFORMANCE_ARB) out <<"PERFORMANCE"; else if(type == GL_DEBUG_TYPE_OTHER_ARB) out <<"OTHER"; out<< "\tSource:"; if(source == GL_DEBUG_SOURCE_API_ARB) out<<"GL_DEBUG_SOURCE_API_ARB"; else if(source == GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB) out<<"GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB"; else if(source == GL_DEBUG_SOURCE_SHADER_COMPILER_ARB) out<<"GL_DEBUG_SOURCE_SHADER_COMPILER_ARB"; else if(source == GL_DEBUG_SOURCE_THIRD_PARTY_ARB) out<<"GL_DEBUG_SOURCE_THIRD_PARTY_ARB"; else if(source == GL_DEBUG_SOURCE_APPLICATION_ARB) out<<"GL_DEBUG_SOURCE_APPLICATION_ARB"; else if(source == GL_DEBUG_SOURCE_OTHER_ARB) out<<"GL_DEBUG_SOURCE_OTHER_ARB"; else out<< source; out<<std::endl << "Message: "<< message << std::endl; } } // ShaderモードのOn/Offを設定する void mgGLSLProgram::EnableLights(bool bEnabled){ mgGLSL::ShadeMode mode = (bEnabled)?mgGLSL::Shading:mgGLSL::NoShading; setUniform(ShaderMode, mode); } // ShaderモードのOn/Offを取得する bool mgGLSLProgram::LightEnabled(){ ASSERT(isLinked()); GLint loc = m_uniform_locations[mgGLSLProgram::ShaderMode]; GLint lightEnabled; glGetUniformiv(m_handle, loc, &lightEnabled); return (lightEnabled == mgGLSL::Shading) ? true : false; } void mgGLSL::execLightMode( int mode/// <0: undefined, =0:Light is disabled, >0:Light is enabled. ){ if(mode<0) return; ASSERT(mgGLSLProgram::getCurrentGLSLProgram()!=NULL); mgGLSLProgram* pGLSL = mgGLSLProgram::getCurrentGLSLProgram(); ASSERT(pGLSL->isLinked()); mgGLSL::ShadeMode shadeMode = (mode) ? mgGLSL::Shading:mgGLSL::NoShading; pGLSL->setUniform(mgGLSLProgram::ShaderMode, shadeMode); mgStaticGLAttrib& cattr=mgGLSL::getCurrentStaticGLAttrib(); cattr.setLightMode(mode); } bool mgGLSL::LightEnabled(){ ASSERT(mgGLSLProgram::getCurrentGLSLProgram()!=NULL); mgGLSLProgram* pGLSL = mgGLSLProgram::getCurrentGLSLProgram(); ASSERT(pGLSL->isLinked()); return pGLSL->LightEnabled(); } void DefaultLightsSetup(){ mgGLSLProgram* pGLSL = mgGLSLProgram::getCurrentGLSLProgram(); // 両面描画 pGLSL->setUniform(mgGLSLProgram::LightTwoSides, true); // ForceLightモードをFALSEに。有効なライトがない場合は、 // Light-OFF状態で描画するように変更。Fugenの場合はTRUEとするところ。 pGLSL->setUniform(mgGLSLProgram::ForceLight, true); } void mgGLSL::execStaticColorAttrib( const float* colr ){ int vColorLoc=mgGLSLProgram::vColor; glDisableVertexAttribArray(vColorLoc); glErr=glGetError(); glVertexAttribPointer(vColorLoc,4,GL_FLOAT,GL_FALSE,0,0); glVertexAttrib4fv(vColorLoc,colr); mgStaticGLAttrib& cattr=mgGLSL::getCurrentStaticGLAttrib(); cattr.setColor(colr); } void mgGLSL::execStaticColorAttrib( const MGColor& color ){ if(color.defined()){ mgGLSL::execStaticColorAttrib(color.color()); } } void mgGLSL::execStaticLineWidth(float lineWidth){ if(lineWidth<=0.) return; glLineWidth(lineWidth); mgStaticGLAttrib& cattr=mgGLSL::getCurrentStaticGLAttrib(); cattr.setLineWidth(lineWidth); } ///Line stipple属性をセットする。 ///When factor=0 is input, line pattern is disabled. This means the line is solid. ///When factor<0, the stipple attribute is undefined. This means the attribute ///is defined by the environment. ///When factor<=0, pattern is unnecessary. void mgGLSL::execStaticLineStipple(short int factor, GLuint pattern){ if(factor<0) return; if(factor>0){ glEnable(GL_LINE_STIPPLE); glLineStipple((GLint)factor,pattern); }else glDisable(GL_LINE_STIPPLE); mgStaticGLAttrib& cattr=mgGLSL::getCurrentStaticGLAttrib(); cattr.setLineStipple(factor,pattern); } void mgGLSL::initializeStaticGLAttribStack(){ std::stack<mgStaticGLAttrib>& attribs=mgGLSL::getStaticGLAttribStack(); if(attribs.empty()){ attribs.push(mgStaticGLAttrib()); } } std::stack<mgStaticGLAttrib>& mgGLSL::getStaticGLAttribStack(){ static std::stack<mgStaticGLAttrib> m_attribStack; return m_attribStack; } mgStaticGLAttrib& mgGLSL::getCurrentStaticGLAttrib(){ std::stack<mgStaticGLAttrib>& attribs=mgGLSL::getStaticGLAttribStack(); return attribs.top(); } void mgGLSL::pushStaticGLAttrib(){ mgStaticGLAttrib& cattriv=mgGLSL::getCurrentStaticGLAttrib(); std::stack<mgStaticGLAttrib>& attribs=mgGLSL::getStaticGLAttribStack(); attribs.push(cattriv); } void mgGLSL::popStaticGLAttrib(){ std::stack<mgStaticGLAttrib>& attribs=mgGLSL::getStaticGLAttribStack(); if(attribs.size()>1) attribs.pop(); mgStaticGLAttrib& attrib=attribs.top(); mgGLSL::execStaticGLAttrib(attrib); } void mgGLSL::execStaticGLAttrib(const mgStaticGLAttrib& attrib){ mgGLSL::execStaticColorAttrib(attrib.color()); mgGLSL::execStaticLineWidth(attrib.getLineWidth()); short int factor; GLushort pattern; attrib.getLineStipple(factor, pattern); mgGLSL::execStaticLineStipple(factor, pattern); mgGLSL::execLightMode(attrib.getLightMode()); } void mgGLSLProgram:: setFuncType(mgGLSL::FuncType type) { // subroutine uniformに変更よてい GLint loc = getUniformLocation("funcType"); setUniform(loc, type); } int mgGLSLProgram:: getFuncType() { GLint loc = getUniformLocation("funcType"); GLint funcType; glGetUniformiv(m_handle, loc, &funcType); return funcType; } void printMatrix(glm::mat4& mat){ for(int i = 0; i<4;++i){ COUT<<"|"; for(int ii = 0; ii<4;++ii){ COUT <<mat[i][ii] <<" " ; } COUT<<std::endl; } } void printMatrix3(glm::mat3& mat){ for(int i = 0; i<3;++i){ COUT<<"|"; for(int ii = 0; ii<3;++ii){ COUT <<mat[i][ii] <<" " ; } COUT<<std::endl; } } void mgGLSLProgram::printPrjMatrix(){ glm::mat4 mvp; glGetUniformfv( m_handle, m_uniform_locations[mgGLSLProgram::modelViewProjMatrix], &mvp[0][0]); COUT<<"modelViewProjMatrix"<<":"<<std::endl; printMatrix(mvp); glm::mat4 mv; glGetUniformfv( m_handle, m_uniform_locations[mgGLSLProgram::modelViewMatrix], &mv[0][0]); COUT<<"modelViewMatrix"<<":"<<std::endl; printMatrix(mv); glm::mat4 prj; glGetUniformfv( m_handle, m_uniform_locations[mgGLSLProgram::projMatrix], &prj[0][0]); COUT<<"projMatrix"<<":"<<std::endl; printMatrix(prj); glm::mat3 mn; glGetUniformfv( m_handle, m_uniform_locations[mgGLSLProgram::normalMatrix], &mn[0][0]); COUT<<"normalMatrix"<<":"<<std::endl; printMatrix3(mn); } void mgGLSLProgram::printLightProps() { COUT<<"--Status-------"<<std::endl; GLint status = -1; glGetUniformiv( m_handle, m_uniform_locations[mgGLSLProgram::CoordinateType], &status); GLint drawType = -1; glGetUniformiv( m_handle, m_uniform_locations[mgGLSLProgram::DrawType], &drawType); COUT<<"DrawType:"<<drawType<<" CoordType:"<<status<< std::endl; glm::vec3 pos; glGetUniformfv( m_handle, m_uniform_locations[mgGLSLProgram::anchorPoint], &pos[0]); COUT<<"AnchoPos:"<<pos.x <<", "<< pos.y<<", "<<pos.z<<std::endl; } ///Utility class to invoke glsl's setFuncType. ///mgFuncTypeSwitcher saves the current function type and invoke input function type. ///When mgFuncTypeSwitcher is destructed, the saved original type is restored. mgFuncTypeSwitcher::mgFuncTypeSwitcher(mgGLSL::FuncType type){ m_pGLSL=mgGLSLProgram::getCurrentGLSLProgram(); m_orgFuncType = m_pGLSL->getFuncType(); m_pGLSL->setFuncType((mgGLSL::FuncType)type); } mgFuncTypeSwitcher::~mgFuncTypeSwitcher(){ m_pGLSL->setFuncType((mgGLSL::FuncType)m_orgFuncType); }