diff --git a/src/osg/State.cpp b/src/osg/State.cpp index e684c6ae7..ffe6bc351 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -1345,7 +1345,7 @@ bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const } } - OSG_NOTICE<<"-------- Converted source "<=0.0) color = vertexColor * vec4(1.0, 1.0, 1.0, texture(glyphTexture, texCoord)." GLYPH_CMP ");\n" - " else color = vertexColor;\n" - "}\n" -}; - -static const char* gl2_TextVertexShader = { - "// gl2_TextVertexShader\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_TextFragmentShader = { - "// gl2_TextFragmentShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "uniform sampler2D glyphTexture;\n" - "varying vec2 texCoord;\n" - "varying vec4 vertexColor;\n" - "void main(void)\n" - "{\n" - " if (texCoord.x>=0.0) gl_FragColor = vertexColor * vec4(1.0, 1.0, 1.0, texture2D(glyphTexture, texCoord).a);\n" - " else gl_FragColor = vertexColor;\n" - "}\n" -}; - - - - Text::Text(): _enableDepthWrites(true), _backdropType(NONE), @@ -237,35 +159,47 @@ osg::StateSet* Text::createStateSet() stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); stateset->setMode(GL_BLEND, osg::StateAttribute::ON); -#if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) - OSG_INFO<<"Font::Font() Fixed function pipeline"<getGlyphTextureFeatures()="<getGlyphTextureFeatures()<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); -#endif + #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); - if (shaderHint==osg::DisplaySettings::SHADER_GL3 || shaderHint==osg::DisplaySettings::SHADER_GLES3) + if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) { - OSG_INFO<<"Font::Font() Setting up GL3 compatible shaders"< program = new osg::Program; - program->addShader(new osg::Shader(osg::Shader::VERTEX, gl3_TextVertexShader)); - program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl3_TextFragmentShader)); - stateset->setAttributeAndModes(program.get()); - stateset->addUniform(new osg::Uniform("glyphTexture", 0)); + OSG_INFO<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); + return stateset.release(); } - else if (shaderHint==osg::DisplaySettings::SHADER_GL2 || shaderHint==osg::DisplaySettings::SHADER_GLES2) + #endif + + // set up the StateSet to use shaders + stateset->addUniform(new osg::Uniform("glyphTexture", 0)); + + osg::ref_ptr program = new osg::Program; + stateset->setAttributeAndModes(program.get()); + { - OSG_INFO<<"Font::Font() Setting up GL2 compatible shaders"< program = new osg::Program; - program->addShader(new osg::Shader(osg::Shader::VERTEX, gl2_TextVertexShader)); - program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl2_TextFragmentShader)); - stateset->setAttributeAndModes(program.get()); - stateset->addUniform(new osg::Uniform("glyphTexture", 0)); + #include "shaders/text_vert.cpp" + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); + } + if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE) + { + OSG_NOTICE<<"Using shaders/text_greyscale.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text_greyscale.frag", text_greyscale_frag)); + } + else + { + OSG_NOTICE<<"Using shaders/text_sdf.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text_sdf.frag", text_sdf_frag)); } return stateset.release(); diff --git a/src/osgText/shaders/text_greyscale_frag.cpp b/src/osgText/shaders/text_greyscale_frag.cpp new file mode 100644 index 000000000..51738a2cf --- /dev/null +++ b/src/osgText/shaders/text_greyscale_frag.cpp @@ -0,0 +1,33 @@ +char text_greyscale_frag[] = "$OSG_GLSL_VERSION\n" + "$OSG_GLSL_PRECISION_FLOAT\n" + "\n" + "#pragma import_defines( BACKDROP_COLOR, OUTLINE, ALPHA )\n" + "\n" + "#if __VERSION__>=130\n" + " #define TEXTURE texture\n" + " out vec4 osg_FragColor;\n" + "#else\n" + " #define TEXTURE texture2D\n" + " #define osg_FragColor gl_FragColor\n" + "#endif\n" + "\n" + "uniform sampler2D glyphTexture;\n" + "\n" + "$OSG_VARYING_IN vec2 texCoord;\n" + "$OSG_VARYING_IN vec4 vertexColor;\n" + "\n" + "#if !defined(GL_ES) && __VERSION__>=130\n" + " #define ALPHA r\n" + "#else\n" + " #define ALPHA a\n" + "#endif\n" + "\n" + "void main(void)\n" + "{\n" + " float alpha = TEXTURE(glyphTexture, texCoord).ALPHA;\n" + "\n" + " if (alpha==0.0) discard;\n" + "\n" + " osg_FragColor = vec4(vertexColor.rgb, alpha);\n" + "}\n" + "\n"; diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp new file mode 100644 index 000000000..379bcba46 --- /dev/null +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -0,0 +1,136 @@ +char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" + "$OSG_GLSL_PRECISION_FLOAT\n" + "\n" + "#pragma import_defines( BACKDROP_COLOR, OUTLINE )\n" + "\n" + "#if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #define USE_SIGNED_DISTNACE_FIELD\n" + "#else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" + " #define USE_SIGNED_DISTNACE_FIELD\n" + " #endif\n" + "#endif\n" + "\n" + "#undef USE_SIGNED_DISTNACE_FIELD\n" + "\n" + "#if __VERSION__>=130\n" + " #define TEXTURE texture\n" + " out vec4 osg_FragColor;\n" + "#else\n" + " #define TEXTURE texture2D\n" + " #define osg_FragColor gl_FragColor\n" + "#endif\n" + "\n" + "uniform sampler2D glyphTexture;\n" + "\n" + "$OSG_VARYING_IN vec2 texCoord;\n" + "$OSG_VARYING_IN vec4 vertexColor;\n" + "\n" + "vec4 textureColor()\n" + "{\n" + " #ifdef OUTLINE\n" + " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" + " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" + "\n" + " #if 0\n" + " float blend_ratio = OUTLINE*17.0;\n" + "\n" + " float outline_alpha = 0.0;\n" + " if (blend_ratio>2.0) outline_alpha = glyph.b;\n" + " else if (blend_ratio>1.0) outline_alpha = mix(glyph.g, glyph.b, blend_ratio-1.0);\n" + " else outline_alpha = glyph.g*blend_ratio;\n" + " #else\n" + " float outline_alpha = glyph.g;\n" + " //float outline_alpha = glyph.b;\n" + " #endif\n" + "\n" + " float alpha = glyph.a+outline_alpha;\n" + " if (alpha>1.0) alpha = 1.0;\n" + "\n" + " return vec4( vertexColor.rgb*glyph.a + BACKDROP_COLOR.rgb*outline_alpha, alpha);\n" + "\n" + " #else\n" + " float alpha = TEXTURE(glyphTexture, texCoord).a;\n" + " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" + " return vec4(vertexColor.rgb, alpha);\n" + " #endif\n" + "}\n" + "\n" + "#ifdef USE_SIGNED_DISTNACE_FIELD\n" + "vec4 distanceFieldColor()\n" + "{\n" + " float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" + "\n" + " float blend_width = 0.2;\n" + " float distance_scale = 5.0;\n" + " float edge_distance = (center_alpha-0.5)*distance_scale;\n" + "\n" + " #ifdef OUTLINE\n" + " float outline_width = OUTLINE*17.0;//0.5;\n" + " if (edge_distance>blend_width*0.5)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_width*0.5)\n" + " {\n" + " return mix(vertexColor, BACKDROP_COLOR, (blend_width*0.5-edge_distance)/(blend_width));\n" + " }\n" + " else if (edge_distance>(blend_width-outline_width))\n" + " {\n" + " return BACKDROP_COLOR;\n" + " }\n" + " else if (edge_distance>-outline_width)\n" + " {\n" + " return vec4(BACKDROP_COLOR.rgb, (outline_width+edge_distance)/blend_width);\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + " #else\n" + " if (edge_distance>0.0)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_width)\n" + " {\n" + " return vec4(vertexColor.rgb, 1.0+edge_distance/blend_width);\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + " #endif\n" + "}\n" + "#endif\n" + "\n" + "\n" + "void main(void)\n" + "{\n" + "\n" + "#ifdef USE_SIGNED_DISTNACE_FIELD\n" + "\n" + " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" + "\n" + " float near_transition = 0.0;\n" + " float far_transition = 1.0;\n" + "\n" + " vec4 color;\n" + " if (mmlfar_transition) color = textureColor();\n" + " else color = mix(distanceFieldColor(), textureColor(), (mml-near_transition)/(far_transition-near_transition));\n" + "\n" + "#else\n" + "\n" + " vec4 color = textureColor();\n" + "\n" + "#endif\n" + "\n" + " if (color.a==0.0) discard;\n" + "\n" + " osg_FragColor = color;\n" + "}\n" + "\n"; diff --git a/src/osgText/shaders/text_vert.cpp b/src/osgText/shaders/text_vert.cpp new file mode 100644 index 000000000..72506284f --- /dev/null +++ b/src/osgText/shaders/text_vert.cpp @@ -0,0 +1,13 @@ +char text_vert[] = "$OSG_GLSL_VERSION\n" + "$OSG_PRECISION_FLOAT\n" + "\n" + "$OSG_VARYING_OUT vec2 texCoord;\n" + "$OSG_VARYING_OUT vec4 vertexColor;\n" + "\n" + "void main(void)\n" + "{\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + " texCoord = gl_MultiTexCoord0.xy;\n" + " vertexColor = gl_Color;\n" + "}\n" + "\n";