/* * Stellarium Scenery3d Plug-in * * Copyright (C) 2014 Simon Parzer, Peter Neubauer, Georg Zotti, Andrei Borza, Florian Schaukowitsch * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. */ #include "StelOpenGL.hpp" #include "ShaderManager.hpp" #include "StelFileMgr.hpp" #include #include #include #include Q_LOGGING_CATEGORY(shaderMgr, "stel.plugin.scenery3d.shadermgr") ShaderMgr::t_UniformStrings ShaderMgr::uniformStrings; ShaderMgr::t_FeatureFlagStrings ShaderMgr::featureFlagsStrings; ShaderMgr::ShaderMgr() { if(uniformStrings.size()==0) { //initialize the strings uniformStrings["u_mModelView"] = UNIFORM_MAT_MODELVIEW; uniformStrings["u_mProjection"] = UNIFORM_MAT_PROJECTION; uniformStrings["u_mMVP"] = UNIFORM_MAT_MVP; uniformStrings["u_mNormal"] = UNIFORM_MAT_NORMAL; uniformStrings["u_mShadow0"] = UNIFORM_MAT_SHADOW0; uniformStrings["u_mShadow1"] = UNIFORM_MAT_SHADOW1; uniformStrings["u_mShadow2"] = UNIFORM_MAT_SHADOW2; uniformStrings["u_mShadow3"] = UNIFORM_MAT_SHADOW3; uniformStrings["u_mCubeMVP"] = UNIFORM_MAT_CUBEMVP; uniformStrings["u_mCubeMVP[]"] = UNIFORM_MAT_CUBEMVP; uniformStrings["u_mCubeMVP[0]"] = UNIFORM_MAT_CUBEMVP; //textures uniformStrings["u_texDiffuse"] = UNIFORM_TEX_DIFFUSE; uniformStrings["u_texEmissive"] = UNIFORM_TEX_EMISSIVE; uniformStrings["u_texBump"] = UNIFORM_TEX_BUMP; uniformStrings["u_texHeight"] = UNIFORM_TEX_HEIGHT; uniformStrings["u_texShadow0"] = UNIFORM_TEX_SHADOW0; uniformStrings["u_texShadow1"] = UNIFORM_TEX_SHADOW1; uniformStrings["u_texShadow2"] = UNIFORM_TEX_SHADOW2; uniformStrings["u_texShadow3"] = UNIFORM_TEX_SHADOW3; //materials uniformStrings["u_vMatShininess"] = UNIFORM_MTL_SHININESS; uniformStrings["u_vMatAlpha"] = UNIFORM_MTL_ALPHA; //pre-modulated lighting (light * material) uniformStrings["u_vMixAmbient"] = UNIFORM_MIX_AMBIENT; uniformStrings["u_vMixDiffuse"] = UNIFORM_MIX_DIFFUSE; uniformStrings["u_vMixSpecular"] = UNIFORM_MIX_SPECULAR; uniformStrings["u_vMixTorchDiffuse"] = UNIFORM_MIX_TORCHDIFFUSE; uniformStrings["u_vMixEmissive"] = UNIFORM_MIX_EMISSIVE; //light uniformStrings["u_vLightDirectionView"] = UNIFORM_LIGHT_DIRECTION_VIEW; uniformStrings["u_fTorchAttenuation"] = UNIFORM_TORCH_ATTENUATION; //others uniformStrings["u_vColor"] = UNIFORM_VEC_COLOR; uniformStrings["u_vSplits"] = UNIFORM_VEC_SPLITDATA; uniformStrings["u_vLightOrthoScale"] = UNIFORM_VEC_LIGHTORTHOSCALE; uniformStrings["u_vLightOrthoScale[]"] = UNIFORM_VEC_LIGHTORTHOSCALE; uniformStrings["u_vLightOrthoScale[0]"] = UNIFORM_VEC_LIGHTORTHOSCALE; uniformStrings["u_fAlphaThresh"] = UNIFORM_FLOAT_ALPHA_THRESH; } if(featureFlagsStrings.size()==0) { featureFlagsStrings["TRANSFORM"] = TRANSFORM; featureFlagsStrings["SHADING"] = SHADING; featureFlagsStrings["PIXEL_LIGHTING"] = PIXEL_LIGHTING; featureFlagsStrings["SHADOWS"] = SHADOWS; featureFlagsStrings["BUMP"] = BUMP; featureFlagsStrings["HEIGHT"] = HEIGHT; featureFlagsStrings["ALPHATEST"] = ALPHATEST; featureFlagsStrings["SHADOW_FILTER"] = SHADOW_FILTER; featureFlagsStrings["SHADOW_FILTER_HQ"] = SHADOW_FILTER_HQ; featureFlagsStrings["MAT_SPECULAR"] = MAT_SPECULAR; featureFlagsStrings["MAT_DIFFUSETEX"] = MAT_DIFFUSETEX; featureFlagsStrings["MAT_EMISSIVETEX"] = MAT_EMISSIVETEX; featureFlagsStrings["GEOMETRY_SHADER"] = GEOMETRY_SHADER; featureFlagsStrings["CUBEMAP"] = CUBEMAP; featureFlagsStrings["BLENDING"] = BLENDING; featureFlagsStrings["TORCH"] = TORCH; featureFlagsStrings["DEBUG"] = DEBUG; featureFlagsStrings["PCSS"] = PCSS; featureFlagsStrings["SINGLE_SHADOW_FRUSTUM"] = SINGLE_SHADOW_FRUSTUM; featureFlagsStrings["OGL_ES2"] = OGL_ES2; featureFlagsStrings["HW_SHADOW_SAMPLERS"] = HW_SHADOW_SAMPLERS; } } ShaderMgr::~ShaderMgr() { clearCache(); } void ShaderMgr::clearCache() { qCDebug(shaderMgr)<<"Clearing"<(file.size())); //use a text stream for "parsing" QTextStream in(&file),lineStream; QString line,word; while(!in.atEnd()) { line = in.readLine(); lineStream.setString(&line,QIODevice::ReadOnly); QString write = line; //read first word lineStream>>word; if(word == "#define") { //read second word lineStream>>word; //try to find it in our flags list auto it = featureFlagsStrings.find(word); if(it!=featureFlagsStrings.end()) { bool val = it.value() & flags; write = "#define " + word + (val?" 1":" 0"); #ifdef NDEBUG } #else //output matches for debugging //qCDebug(shaderMgr)<<"preprocess match: "< "<functions(); GL(gl->glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &numUniforms)); GL(gl->glGetProgramiv(prog, GL_ACTIVE_UNIFORM_MAX_LENGTH, &bufSize)); QByteArray buf(bufSize,'\0'); GLsizei length; GLint size; GLenum type; #ifndef NDEBUG //qCDebug(shaderMgr)<<"Shader has"<(numUniforms);++i) { GL(gl->glGetActiveUniform(prog,i,bufSize,&length,&size,&type,buf.data())); QString str(buf); str = str.trimmed(); // no idea if this is required GLint loc = program.uniformLocation(str); auto it = uniformStrings.find(str); // This may also return Q_NULLPTR if the load failed. //We wait until user explictly forces shader reload until we try again to avoid spamming errors. if(it!=uniformStrings.end()) { //this is uniform we recognize //need to get the uniforms location (!= index) m_uniformCache[&program][*it] = static_cast(loc); //output mapping for debugging //qCDebug(shaderMgr)<