目标:(一二四)中问题211
1、添加默认着色器
这类着色器源代码是内置在程序里的,不会经过osgEarth着色器框架的整合。
1.1加载时处理
osg/StateSet.cpp
static const char* gl3_VertexShader = {
"#version " GLSL_VERSION_STR "\n"
"// gl3_VertexShader\n"
"#ifdef GL_ES\n"
" precision highp float;\n"
"#endif\n"
"in vec4 osg_Vertex;\n"
"in vec4 osg_Color;\n"
"in vec4 osg_MultiTexCoord0;\n"
"uniform mat4 osg_ModelViewProjectionMatrix;\n"
"out vec2 texCoord;\n"
"out vec4 vertexColor;\n"
"void main(void)\n"
"{\n"
" gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n"
" texCoord = osg_MultiTexCoord0.xy;\n"
" vertexColor = osg_Color; \n"
"}\n"
};
static const char* gl3_FragmentShader = {
"#version " GLSL_VERSION_STR "\n"
"// gl3_FragmentShader\n"
"#ifdef GL_ES\n"
" precision highp float;\n"
"#endif\n"
"uniform sampler2D baseTexture;\n"
"in vec2 texCoord;\n"
"in vec4 vertexColor;\n"
"out vec4 color;\n"
"void main(void)\n"
"{\n"
" color = vertexColor * texture(baseTexture, texCoord);\n"
"}\n"
};
static const char* gl2_VertexShader = {
"// gl2_VertexShader\n"
"#ifdef GL_ES\n"
" precision highp float;\n"
"#endif\n"
"varying vec2 texCoord;\n"
"varying vec4 vertexColor;\n"
"void main(void)\n"
"{\n"
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
" texCoord = gl_MultiTexCoord0.xy;\n"
" vertexColor = gl_Color; \n"
"}\n"
};
static const char* gl2_FragmentShader = {
"// gl2_FragmentShader\n"
"#ifdef GL_ES\n"
" precision highp float;\n"
"#endif\n"
"uniform sampler2D baseTexture;\n"
"varying vec2 texCoord;\n"
"varying vec4 vertexColor;\n"
"void main(void)\n"
"{\n"
" gl_FragColor = vertexColor * texture2D(baseTexture, texCoord);\n"
"}\n"
};
void StateSet::setGlobalDefaults()
{
_renderingHint = DEFAULT_BIN;
setRenderBinToInherit();
setMode(GL_DEPTH_TEST,StateAttribute::ON);
setAttributeAndModes(new BlendFunc,StateAttribute::OFF);
#if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE)
// setAttributeAndModes(new AlphaFunc,StateAttribute::OFF);
Material *material = new Material;
material->setColorMode(Material::AMBIENT_AND_DIFFUSE);
setAttributeAndModes(material,StateAttribute::ON);
#endif
OSG_INFO<<"void StateSet::setGlobalDefaults()"<<std::endl;
osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint();
if (shaderHint==osg::DisplaySettings::SHADER_GL3 || shaderHint==osg::DisplaySettings::SHADER_GLES3)
{
OSG_INFO<<" StateSet::setGlobalDefaults() Setting up GL3 compatible shaders"<<std::endl;
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(new osg::Shader(osg::Shader::VERTEX, gl3_VertexShader));
program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl3_FragmentShader));
setAttributeAndModes(program.get());
setTextureAttribute(0, createDefaultTexture());
addUniform(new osg::Uniform("baseTexture", 0));
}
else if (shaderHint==osg::DisplaySettings::SHADER_GL2 || shaderHint==osg::DisplaySettings::SHADER_GLES2)
{
OSG_INFO<<" StateSet::setGlobalDefaults() Setting up GL2 compatible shaders"<<std::endl;
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(new osg::Shader(osg::Shader::VERTEX, gl2_VertexShader));
program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl2_FragmentShader));
setAttributeAndModes(program.get());
setTextureAttribute(0, createDefaultTexture());
addUniform(new osg::Uniform("baseTexture", 0));
}
}
1.2编译时处理
替换一些变量,比如gl_ModelViewMatrix、gl_ProjectionMatrix、gl_ModelViewProjectionMatrix、gl_NormalMatrix,并且会增加定义,比如将gl_ModelViewMatrix替换osg_ModelViewMatrix,并增加uniform mat4 osg_ModelViewMatrix。
osg/State.cpp
bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const
{
OSG_DEBUG<<"State::convertShaderSourceToOsgBuiltIns()"<<std::endl;
OSG_DEBUG<<"++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
// precede a "#version" compiler directive, so we must insert new declarations after it.
std::string::size_type declPos = source.rfind( "#version " );
if ( declPos != std::string::npos )
{
declPos = source.find(" ", declPos); // move to the first space after "#version"
declPos = source.find_first_not_of(std::string(" "), declPos); // skip all the spaces until you reach the version number
std::string versionNumber(source, declPos, 3);
int glslVersion = atoi(versionNumber.c_str());
OSG_INFO<<"shader version found: "<< glslVersion <<std::endl;
if (glslVersion >= 130) attributeQualifier = "in ";
// found the string, now find the next linefe