Added support for subsititing $VAR_NAME entries in shaders to enable writing shaders that work across GLSL versions.
This commit is contained in:
@@ -118,7 +118,8 @@ void DisplaySettings::setDisplaySettings(const DisplaySettings& vs)
|
||||
_swapMethod = vs._swapMethod;
|
||||
|
||||
_vertexBufferHint = vs._vertexBufferHint;
|
||||
_shaderHint = vs._shaderHint;
|
||||
|
||||
setShaderHint(_shaderHint);
|
||||
|
||||
_keystoneHint = vs._keystoneHint;
|
||||
_keystoneFileNames = vs._keystoneFileNames;
|
||||
@@ -250,23 +251,17 @@ void DisplaySettings::setDefaults()
|
||||
// _vertexBufferHint = VERTEX_ARRAY_OBJECT;
|
||||
|
||||
#if defined(OSG_GLES3_AVAILABLE)
|
||||
_shaderHint = SHADER_GLES3;
|
||||
OSG_INFO<<"DisplaySettings::SHADER_GLES3"<<std::endl;
|
||||
setShaderHint(SHADER_GLES3);
|
||||
#elif defined(OSG_GLES2_AVAILABLE)
|
||||
_shaderHint = SHADER_GLES2;
|
||||
OSG_INFO<<"DisplaySettings::SHADER_GLES2"<<std::endl;
|
||||
setShaderHint(SHADER_GLES2);
|
||||
#elif defined(OSG_GL3_AVAILABLE)
|
||||
_shaderHint = SHADER_GL3;
|
||||
OSG_INFO<<"DisplaySettings::SHADER_GL3"<<std::endl;
|
||||
setShaderHint(SHADER_GL3);
|
||||
#elif defined(OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE)
|
||||
OSG_INFO<<"DisplaySettings::SHADER_NONE"<<std::endl;
|
||||
_shaderHint = SHADER_NONE;
|
||||
setShaderHint(SHADER_NONE);
|
||||
#else
|
||||
OSG_INFO<<"DisplaySettings::SHADER_GL2"<<std::endl;
|
||||
_shaderHint = SHADER_GL2;
|
||||
setShaderHint(SHADER_GL2);
|
||||
#endif
|
||||
|
||||
|
||||
_keystoneHint = false;
|
||||
|
||||
_OSXMenubarBehavior = MENUBAR_AUTO_HIDE;
|
||||
@@ -725,23 +720,23 @@ void DisplaySettings::readEnvironmentalVariables()
|
||||
{
|
||||
if (strcmp(ptr,"GL2")==0)
|
||||
{
|
||||
_shaderHint = SHADER_GL2;
|
||||
setShaderHint(SHADER_GL2);
|
||||
}
|
||||
else if (strcmp(ptr,"GL3")==0)
|
||||
{
|
||||
_shaderHint = SHADER_GL3;
|
||||
setShaderHint(SHADER_GL3);
|
||||
}
|
||||
else if (strcmp(ptr,"GLES2")==0)
|
||||
{
|
||||
_shaderHint = SHADER_GLES2;
|
||||
setShaderHint(SHADER_GLES2);
|
||||
}
|
||||
else if (strcmp(ptr,"GLES3")==0)
|
||||
{
|
||||
_shaderHint = SHADER_GLES3;
|
||||
setShaderHint(SHADER_GLES3);
|
||||
}
|
||||
else if (strcmp(ptr,"NONE")==0)
|
||||
{
|
||||
_shaderHint = SHADER_NONE;
|
||||
setShaderHint(SHADER_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1098,3 +1093,84 @@ osg::Matrixd DisplaySettings::computeRightEyeViewImplementation(const osg::Matri
|
||||
0.0,0.0,1.0,0.0,
|
||||
-es,0.0,0.0,1.0);
|
||||
}
|
||||
|
||||
void DisplaySettings::setShaderHint(ShaderHint hint, bool setShaderValues)
|
||||
{
|
||||
_shaderHint = hint;
|
||||
if (setShaderValues)
|
||||
{
|
||||
switch(_shaderHint)
|
||||
{
|
||||
case(SHADER_GLES3) :
|
||||
setValue("OSG_GLSL_VERSION", "#version 300 es");
|
||||
setValue("OSG_PRECISION_FLOAT", "precision highp float;");
|
||||
setValue("OSG_VARYING_IN", "in");
|
||||
setValue("OSG_VARYING_OUT", "out");
|
||||
OSG_NOTICE<<"DisplaySettings::SHADER_GLES3"<<std::endl;
|
||||
break;
|
||||
case(SHADER_GLES2) :
|
||||
setValue("OSG_GLSL_VERSION", "");
|
||||
setValue("OSG_PRECISION_FLOAT", "precision highp float;");
|
||||
setValue("OSG_VARYING_IN", "varying");
|
||||
setValue("OSG_VARYING_OUT", "varying");
|
||||
OSG_NOTICE<<"DisplaySettings::SHADER_GLES2"<<std::endl;
|
||||
break;
|
||||
case(SHADER_GL3) :
|
||||
setValue("OSG_GLSL_VERSION", "#version 330");
|
||||
setValue("OSG_PRECISION_FLOAT", "");
|
||||
setValue("OSG_VARYING_IN", "in");
|
||||
setValue("OSG_VARYING_OUT", "out");
|
||||
OSG_NOTICE<<"DisplaySettings::SHADER_GL3"<<std::endl;
|
||||
break;
|
||||
case(SHADER_GL2) :
|
||||
setValue("OSG_GLSL_VERSION", "");
|
||||
setValue("OSG_PRECISION_FLOAT", "");
|
||||
setValue("OSG_VARYING_IN", "varying");
|
||||
setValue("OSG_VARYING_OUT", "varying");
|
||||
OSG_NOTICE<<"DisplaySettings::SHADER_GL2"<<std::endl;
|
||||
break;
|
||||
case(SHADER_NONE) :
|
||||
setValue("OSG_GLSL_VERSION", "");
|
||||
setValue("OSG_PRECISION_FLOAT", "");
|
||||
setValue("OSG_VARYING_IN", "varying");
|
||||
setValue("OSG_VARYING_OUT", "varying");
|
||||
OSG_NOTICE<<"DisplaySettings::NONE"<<std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisplaySettings::setValue(const std::string& name, const std::string& value)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_valueMapMutex);
|
||||
|
||||
_valueMap[name] = value;
|
||||
}
|
||||
|
||||
bool DisplaySettings::getValue(const std::string& name, std::string& value, bool use_getenv_fallback) const
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_valueMapMutex);
|
||||
|
||||
ValueMap::iterator itr = _valueMap.find(name);
|
||||
if (itr!=_valueMap.end())
|
||||
{
|
||||
value = itr->second;
|
||||
OSG_NOTICE<<"DisplaySettings::getValue("<<name<<") found existing value = ["<<value<<"]"<<std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!use_getenv_fallback) return false;
|
||||
|
||||
const char* str = getenv(name.c_str());
|
||||
if (str)
|
||||
{
|
||||
OSG_NOTICE<<"DisplaySettings::getValue("<<name<<") found getenv value = ["<<value<<"]"<<std::endl;
|
||||
_valueMap[name] = value = str;
|
||||
return true;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -618,7 +618,7 @@ void Shader::PerContextShader::compileShader(osg::State& state)
|
||||
#endif
|
||||
|
||||
std::string source = _shader->getShaderSource();
|
||||
if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms()))
|
||||
// if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms()))
|
||||
{
|
||||
state.convertVertexShaderSourceToOsgBuiltIns(source);
|
||||
}
|
||||
|
||||
@@ -1216,6 +1216,68 @@ namespace State_Utils
|
||||
source.insert(declPos, qualifier + declarationPrefix + newStr + std::string(";\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void replaceVar(const osg::State& state, std::string& str, std::string::size_type start_pos, std::string::size_type num_chars)
|
||||
{
|
||||
std::string var_str(str.substr(start_pos+1, num_chars-1));
|
||||
std::string value;
|
||||
OSG_NOTICE<<" Need to replace : ["<<var_str<<"] ds="<<state.getDisplaySettings()<< std::endl;
|
||||
if (state.getActiveDisplaySettings()->getValue(var_str, value))
|
||||
{
|
||||
OSG_NOTICE<<" Value : "<<value<<std::endl;
|
||||
str.replace(start_pos, num_chars, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_NOTICE<<" No value assignd, ereasing "<<std::endl;
|
||||
str.erase(start_pos, num_chars);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void substitudeEnvVars(const osg::State& state, std::string& str)
|
||||
{
|
||||
OSG_NOTICE<<"substitudeEnvVars()"<<std::endl;
|
||||
|
||||
std::string::size_type pos = 0;
|
||||
while (pos<str.size() && ((pos=str.find_first_of("$'\"", pos)) != std::string::npos))
|
||||
{
|
||||
if (pos==str.size())
|
||||
{
|
||||
OSG_NOTICE<<" Found "<<str[pos]<<" but it's the last character"<<std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
if (str[pos]=='"' || str[pos]=='\'')
|
||||
{
|
||||
std::string::size_type start_quote = pos;
|
||||
++pos;
|
||||
pos = str.find(str[start_quote], pos);
|
||||
if (pos != std::string::npos) { OSG_NOTICE<<" Found ending string : "<<str.substr(start_quote, pos-start_quote+1)<<std::endl; ++pos; }
|
||||
else { OSG_NOTICE<<" Found middle string : "<<str.substr(start_quote, std::string::npos)<<std::endl; break; }
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string::size_type start_var = pos;
|
||||
++pos;
|
||||
pos = str.find_first_not_of("ABCDEFGHIJKLMNOPQRTSUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_", pos);
|
||||
std::string var_str;
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
|
||||
OSG_NOTICE<<" Found $ : "<<str.substr(start_var, pos-start_var)<<" "<<pos<<std::endl;
|
||||
replaceVar(state, str, start_var, pos-start_var);
|
||||
pos = start_var;
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_NOTICE<<" Found $ at end of string : "<<str.substr(start_var, std::string::npos)<<" "<<pos<<std::endl;
|
||||
replaceVar(state, str, start_var, str.size()-start_var);
|
||||
pos = start_var;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const
|
||||
@@ -1224,6 +1286,10 @@ bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const
|
||||
|
||||
OSG_INFO<<"++Before Converted source "<<std::endl<<source<<std::endl<<"++++++++"<<std::endl;
|
||||
|
||||
|
||||
State_Utils::substitudeEnvVars(*this, source);
|
||||
|
||||
|
||||
std::string attributeQualifier("attribute ");
|
||||
|
||||
// find the first legal insertion point for replacement declarations. GLSL requires that nothing
|
||||
@@ -1279,7 +1345,7 @@ bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const
|
||||
}
|
||||
}
|
||||
|
||||
OSG_INFO<<"-------- Converted source "<<std::endl<<source<<std::endl<<"----------------"<<std::endl;
|
||||
OSG_NOTICE<<"-------- Converted source "<<std::endl<<source<<std::endl<<"----------------"<<std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user