From c36e47188b4ca951b6cb587e15345e57640fc9f1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 29 Aug 2017 12:21:14 +0100 Subject: [PATCH 01/74] Added argument parsing to viewer constructor --- examples/osgfont/osgfont.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 9255bea0c..5f3eb9bee 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -84,8 +84,8 @@ typedef std::list Sizes; int main(int argc, char** argv) { - osgViewer::Viewer viewer; osg::ArgumentParser args(&argc, argv); + osgViewer::Viewer viewer(args); // Make sure we have the minimum args... if(argc <= 2) From 37487b0c0b7c299f8a710c1f151e5eebb098f90c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 29 Aug 2017 13:48:06 +0100 Subject: [PATCH 02/74] Added --ortho command line option to toggle use of orthographic camera or default perspective one --- examples/osgfont/osgfont.cpp | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 5f3eb9bee..5090422ce 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -56,12 +57,12 @@ osg::Camera* createOrthoCamera(double width, double height) return camera; } -osgText::Text* createLabel(const std::string& l, const char* f, unsigned int size) +osgText::Text* createLabel(const std::string& l, const std::string& fontfile, unsigned int size) { static osg::Vec3 pos(10.0f, 10.0f, 0.0f); osgText::Text* label = new osgText::Text(); - osg::ref_ptr font = osgText::readRefFontFile(f); + osg::ref_ptr font = osgText::readRefFontFile(fontfile); label->setFont(font); label->setCharacterSize(size); @@ -100,8 +101,27 @@ int main(int argc, char** argv) viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); - osg::Group* group = new osg::Group(); - osg::Camera* camera = createOrthoCamera(1280.0f, 1024.0f); + + osg::ref_ptr root = new osg::Group; + + bool ortho = args.read("--ortho"); + if (ortho) + { + osg::ref_ptr camera = createOrthoCamera(1280.0f, 1024.0f); + root->addChild(camera.get()); + root = camera; + } + else + { + osg::ref_ptr transform = new osg::MatrixTransform; + transform->setMatrix(osg::Matrixd::rotate(osg::DegreesToRadians(90.0), 1.0, 0.0, 0.0)); + root->addChild(transform.get()); + root = transform; + } + + std::string fontfile("arial.ttf"); + + fontfile = argv[1]; // Create the list of desired sizes. Sizes sizes; @@ -122,14 +142,12 @@ int main(int argc, char** argv) ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - geode->addDrawable(createLabel(ss.str(), args[1], *i)); + geode->addDrawable(createLabel(ss.str(), fontfile, *i)); } - camera->addChild(geode); + root->addChild(geode); - group->addChild(camera); - - viewer.setSceneData(group); + viewer.setSceneData(root.get()); return viewer.run(); } From 5566a025b53ef57133c282c75d489927d78c5e9a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 29 Aug 2017 17:19:26 +0100 Subject: [PATCH 03/74] Added TextSettings struct to manage values used to set up the text. with the addition of following command line parameters: --outline // enable outlne --shadow // enable shadow --offset ratio // set the backdrop offset --text-color r g b a // set the text body color --bd-color r g b a // set the shadow/outline color --bg-color r g b a // window background color -o filename // write create subgraph to disk using specified filename --- examples/osgfont/osgfont.cpp | 74 ++++++++++++++++++++++++++++++++---- src/osgText/Text.cpp | 9 +++++ 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 5090422ce..f7c068acd 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -57,30 +58,74 @@ osg::Camera* createOrthoCamera(double width, double height) return camera; } -osgText::Text* createLabel(const std::string& l, const std::string& fontfile, unsigned int size) +struct TextSettings +{ + TextSettings(): + fontFilename("fonts/arial.ttf"), + textColor(1.0f, 1.0f, 1.0f, 1.0f), + backdropType(osgText::Text::NONE), + backdropOffset(0.04f, 0.04f), + backdropColor(0.0f, 0.0f, 0.0f, 1.0f) + { + } + + void read(osg::ArgumentParser& arguments) + { + if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; + if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; + + float offset; + if (arguments.read("--offset", offset)) backdropOffset.set(offset, offset); + + if (arguments.read("--text-color", textColor.r(), textColor.g(), textColor.b(), textColor.a())) {} + if (arguments.read("--bd-color", backdropColor.r(), backdropColor.g(), backdropColor.b(), backdropColor.a())) {} + } + + void setText(osgText::Text& text) + { + OSG_NOTICE<<"Settings::setText()"< font = osgText::readRefFontFile(fontfile); + osg::ref_ptr font = osgText::readRefFontFile(settings.fontFilename); + + settings.setText(*label); - label->setFont(font); label->setCharacterSize(size); label->setFontResolution(size, size); - label->setColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); label->setPosition(pos); label->setAlignment(osgText::Text::LEFT_BOTTOM); + // It seems to be important we do this last to get best results? label->setText(l); - textInfo(label); + + // textInfo(label); pos.y() += size + 10.0f; return label; } + + typedef std::list Sizes; int main(int argc, char** argv) @@ -101,6 +146,11 @@ int main(int argc, char** argv) viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); + osg::Vec4d backgroudColor = viewer.getCamera()->getClearColor(); + if (args.read("--bg-color", backgroudColor.r(), backgroudColor.g(), backgroudColor.b(), backgroudColor.a())) + { + viewer.getCamera()->setClearColor(backgroudColor); + } osg::ref_ptr root = new osg::Group; @@ -119,9 +169,10 @@ int main(int argc, char** argv) root = transform; } - std::string fontfile("arial.ttf"); + TextSettings settings; + settings.fontFilename = argv[1]; + settings.read(args); - fontfile = argv[1]; // Create the list of desired sizes. Sizes sizes; @@ -142,11 +193,18 @@ int main(int argc, char** argv) ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - geode->addDrawable(createLabel(ss.str(), fontfile, *i)); + geode->addDrawable(createLabel(ss.str(), settings, *i)); } root->addChild(geode); + std::string filename; + if (args.read("-o", filename)) + { + osgDB::writeNodeFile(*root, filename); + return 0; + } + viewer.setSceneData(root.get()); return viewer.run(); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 53a5d3b1a..af9b4eccc 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1131,6 +1131,8 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo #if 1 if(_backdropType != NONE) { + OSG_NOTICE<<"Text::drawImplementationSinglePass() Drawing backdrop"<draw(state, usingVertexBufferObjects); } } From f3bbb686d2765dd4df1a95d8d0b6bc1ec4426630 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 29 Aug 2017 17:32:14 +0100 Subject: [PATCH 04/74] Removed debug messages --- src/osgText/Text.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index af9b4eccc..53a5d3b1a 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1131,8 +1131,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo #if 1 if(_backdropType != NONE) { - OSG_NOTICE<<"Text::drawImplementationSinglePass() Drawing backdrop"<draw(state, usingVertexBufferObjects); } } From 20ecd5c60dc8e30e4ab2a2d7047c5951a44fbb21 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 10:16:18 +0100 Subject: [PATCH 05/74] Added --test command line option that sets up all the sizes and font settings required for a useufl unit test. --- examples/osgfont/osgfont.cpp | 73 +++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index f7c068acd..6b8ca7c80 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -58,6 +58,8 @@ osg::Camera* createOrthoCamera(double width, double height) return camera; } +typedef std::list Sizes; + struct TextSettings { TextSettings(): @@ -71,6 +73,23 @@ struct TextSettings void read(osg::ArgumentParser& arguments) { + if (arguments.read("--test")) + { + backgroundColor = osg::Vec4(1.0, 1.0, 1.0, 1.0); + + fontFilename = "fonts/arialbd.ttf"; + backdropType = osgText::Text::OUTLINE; + + sizes.clear(); + sizes.push_back(8); + sizes.push_back(16); + sizes.push_back(32); + sizes.push_back(64); + sizes.push_back(128); + } + + if (arguments.read("--font",fontFilename)) {} + if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; @@ -79,6 +98,8 @@ struct TextSettings if (arguments.read("--text-color", textColor.r(), textColor.g(), textColor.b(), textColor.a())) {} if (arguments.read("--bd-color", backdropColor.r(), backdropColor.g(), backdropColor.b(), backdropColor.a())) {} + if (arguments.read("--bg-color", backgroundColor.r(), backgroundColor.g(), backgroundColor.b(), backgroundColor.a())) {} + } void setText(osgText::Text& text) @@ -96,6 +117,8 @@ struct TextSettings osgText::Text::BackdropType backdropType; osg::Vec2 backdropOffset; osg::Vec4 backdropColor; + osg::Vec4 backgroundColor; + Sizes sizes; }; osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size) @@ -126,31 +149,23 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne -typedef std::list Sizes; int main(int argc, char** argv) { osg::ArgumentParser args(&argc, argv); osgViewer::Viewer viewer(args); - // Make sure we have the minimum args... - if(argc <= 2) - { - osg::notify(osg::FATAL) << "usage: " << args[0] << " fontfile size1 [size2 ...]" << std::endl; - - return 1; - } - viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); - osg::Vec4d backgroudColor = viewer.getCamera()->getClearColor(); - if (args.read("--bg-color", backgroudColor.r(), backgroudColor.g(), backgroudColor.b(), backgroudColor.a())) - { - viewer.getCamera()->setClearColor(backgroudColor); - } + TextSettings settings; + settings.backgroundColor = viewer.getCamera()->getClearColor(); + + settings.read(args); + + viewer.getCamera()->setClearColor(settings.backgroundColor); osg::ref_ptr root = new osg::Group; @@ -169,25 +184,31 @@ int main(int argc, char** argv) root = transform; } - TextSettings settings; - settings.fontFilename = argv[1]; - settings.read(args); - - - // Create the list of desired sizes. - Sizes sizes; - - for(int i = 2; i < argc; i++) + if (args.argc() > 1) { - if(!args.isNumber(i)) continue; + settings.fontFilename = argv[1]; - sizes.push_back(std::atoi(args[i])); + // Create the list of desired sizes. + for(int i = 2; i < args.argc(); i++) + { + if(!args.isNumber(i)) continue; + + settings.sizes.push_back(std::atoi(args[i])); + } + } + + if (settings.sizes.empty()) + { + settings.sizes.push_back(8); + settings.sizes.push_back(16); + settings.sizes.push_back(32); + settings.sizes.push_back(64); } osg::Geode* geode = new osg::Geode(); // Add all of our osgText drawables. - for(Sizes::const_iterator i = sizes.begin(); i != sizes.end(); i++) + for(Sizes::const_iterator i = settings.sizes.begin(); i != settings.sizes.end(); i++) { std::stringstream ss; From 7323bb776bf83f789b567f802f442a56a0eccee3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 10:50:26 +0100 Subject: [PATCH 06/74] Added --margin texel_width and --margin-ration ratio to control the spacing between glyphs in the font. --- examples/osgfont/osgfont.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 6b8ca7c80..5da7e495c 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -64,6 +64,8 @@ struct TextSettings { TextSettings(): fontFilename("fonts/arial.ttf"), + glyphImageMargin(1), + glyphImageMarginRatio(0.02), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.04f, 0.04f), @@ -90,6 +92,11 @@ struct TextSettings if (arguments.read("--font",fontFilename)) {} + + if (arguments.read("--margin", glyphImageMargin)) {} + if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} + + if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; @@ -113,6 +120,9 @@ struct TextSettings } std::string fontFilename; + unsigned int glyphImageMargin; + float glyphImageMarginRatio; + osg::Vec4 textColor; osgText::Text::BackdropType backdropType; osg::Vec2 backdropOffset; @@ -128,6 +138,9 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne osgText::Text* label = new osgText::Text(); osg::ref_ptr font = osgText::readRefFontFile(settings.fontFilename); + font->setGlyphImageMargin(settings.glyphImageMargin); + font->setGlyphImageMarginRatio(settings.glyphImageMarginRatio); + settings.setText(*label); label->setCharacterSize(size); From 1289c4ee41288299509ef91ede05285a5beae734 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 16:21:03 +0100 Subject: [PATCH 07/74] Added osgText::Font::s/getGlyphInterval(int) and GlyphTexture::s/getGlyphInterval(int) and internal support for clmapping positions of glyph images an defined intervals, defaults to 1. --- include/osgText/Font | 6 ++++++ include/osgText/Glyph | 5 +++++ src/osgText/Font.cpp | 2 ++ src/osgText/Glyph.cpp | 23 ++++++++++++++--------- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/include/osgText/Font b/include/osgText/Font index 952a6fda4..369493891 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -122,6 +122,11 @@ public: void setGlyphImageMarginRatio(float margin); float getGlyphImageMarginRatio() const; + /** Set the interval that glyph positions are clamped to. + * Default interval is 1 texels.*/ + void setGlyphInterval(int interval); + int getGlyphInterval() const; + /** Set the size of texture to create to store the glyph images when rendering. * Note, this doesn't affect already created Texture Glhph's.*/ @@ -197,6 +202,7 @@ protected: FontResolution _fontSize; unsigned int _margin; float _marginRatio; + int _glyphInterval; unsigned int _textureWidthHint; unsigned int _textureHeightHint; diff --git a/include/osgText/Glyph b/include/osgText/Glyph index f08686841..bb7d5192a 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -260,6 +260,9 @@ public: void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; } float getGlyphImageMarginRatio() const { return _marginRatio; } + void setGlyphInterval(int interval) { _interval = interval; } + int getGlyphInterval() const { return _interval; } + bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY); void addGlyph(Glyph* glyph,int posX, int posY); @@ -282,6 +285,8 @@ protected: // in the texture which could accommodate new glyphs. int _margin; float _marginRatio; + int _interval; + int _usedY; int _partUsedX; int _partUsedY; diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index c06392640..155acadff 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -301,6 +301,7 @@ Font::Font(FontImplementation* implementation): osg::Object(true), _margin(1), _marginRatio(0.02), + _glyphInterval(1), _textureWidthHint(1024), _textureHeightHint(1024), _minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR), @@ -604,6 +605,7 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* // reserve enough space for the glyphs. glyphTexture->setGlyphImageMargin(_margin); glyphTexture->setGlyphImageMarginRatio(_marginRatio); + glyphTexture->setGlyphInterval(_glyphInterval); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 3bc346c8f..2699b0627 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -31,6 +31,7 @@ using namespace std; GlyphTexture::GlyphTexture(): _margin(1), _marginRatio(0.02f), + _interval(1), _usedY(0), _partUsedX(0), _partUsedY(0) @@ -60,18 +61,22 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) int width = glyph->s()+2*margin; int height = glyph->t()+2*margin; - // first check box (_partUsedX,_usedY) to (width,height) - if (width <= (getTextureWidth()-_partUsedX) && - height <= (getTextureHeight()-_usedY)) + int partUsedX = ((_partUsedX % _interval) == 0) ? _partUsedX : (((_partUsedX/_interval)+1)*_interval); + int partUsedY = ((_partUsedY % _interval) == 0) ? _partUsedY : (((_partUsedY/_interval)+1)*_interval); + int usedY = ((_usedY % _interval) == 0) ? _usedY : (((_usedY/_interval)+1)*_interval); + + // first check box (partUsedX, usedY) to (width,height) + if (width <= (getTextureWidth()-partUsedX) && + height <= (getTextureHeight()-usedY)) { // can fit in existing row. // record the position in which the texture will be stored. - posX = _partUsedX+margin; - posY = _usedY+margin; + posX = partUsedX+margin; + posY = usedY+margin; // move used markers on. - _partUsedX += width; + _partUsedX = posX+width; if (_usedY+height>_partUsedY) _partUsedY = _usedY+height; return true; @@ -83,14 +88,14 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) { // can fit next row. _partUsedX = 0; - _usedY = _partUsedY; + _usedY = partUsedY; posX = _partUsedX+margin; posY = _usedY+margin; // move used markers on. - _partUsedX += width; - if (_usedY+height>_partUsedY) _partUsedY = _usedY+height; + _partUsedX = posX+width; + _partUsedY = _usedY+height; return true; } From 81f93e34b82ded6e0c51c57f61e4cf132ef86294 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 16:22:25 +0100 Subject: [PATCH 08/74] Added --interval value commnad line option for setting the Font::setGlyphInterval() to experimentation of clamping of glyph images to user specified intervals in the glyph texture --- examples/osgfont/osgfont.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 5da7e495c..43a8653d5 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -66,6 +66,7 @@ struct TextSettings fontFilename("fonts/arial.ttf"), glyphImageMargin(1), glyphImageMarginRatio(0.02), + glyphInterval(1), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.04f, 0.04f), @@ -95,6 +96,7 @@ struct TextSettings if (arguments.read("--margin", glyphImageMargin)) {} if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} + if (arguments.read("--interval", glyphInterval)) {} if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; @@ -122,6 +124,7 @@ struct TextSettings std::string fontFilename; unsigned int glyphImageMargin; float glyphImageMarginRatio; + int glyphInterval; osg::Vec4 textColor; osgText::Text::BackdropType backdropType; From 07a8d082e414c21182aeecb9096da78153e34862 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 30 Aug 2017 17:43:29 +0100 Subject: [PATCH 09/74] Added --shader filename command line parsing and associated set up of osg::Program to allow shaders to be passed into example to customize rendering --- examples/osgfont/osgfont.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 43a8653d5..823e7ae24 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -200,6 +201,29 @@ int main(int argc, char** argv) root = transform; } + osg::ref_ptr program = new osg::Program; + std::string shaderFilename; + while(args.read("--shader", shaderFilename)) + { + osg::ref_ptr shader = osgDB::readRefShaderFile(shaderFilename); + if (shader.get()) + { + OSG_NOTICE<<"Loading shader "<addShader(shader.get()); + } + } + + if (program->getNumShaders()>0) + { + OSG_NOTICE<<"Using shaders"<getOrCreateStateSet()->setAttribute(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); + root->getOrCreateStateSet()->addUniform(new osg::Uniform("glyphTexture", 0)); + } + + + std::string outputFilename; + if (args.read("-o", outputFilename)) {} + if (args.argc() > 1) { settings.fontFilename = argv[1]; @@ -235,10 +259,9 @@ int main(int argc, char** argv) root->addChild(geode); - std::string filename; - if (args.read("-o", filename)) + if (!outputFilename.empty()) { - osgDB::writeNodeFile(*root, filename); + osgDB::writeNodeFile(*root, outputFilename); return 0; } From 20ee12e9866112f9d9dbf42132e665311683de03 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 6 Sep 2017 10:40:05 +0100 Subject: [PATCH 10/74] To control the GlyphTexture Min/MagFilter values Added --min and --mag filter with LINEAR, NEAREST and LINEAR_MIPMAP_LINER options for values --- examples/osgfont/osgfont.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 823e7ae24..55f893f36 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -65,6 +65,8 @@ struct TextSettings { TextSettings(): fontFilename("fonts/arial.ttf"), + minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), + magFilter(osg::Texture::LINEAR), glyphImageMargin(1), glyphImageMarginRatio(0.02), glyphInterval(1), @@ -75,6 +77,14 @@ struct TextSettings { } + + void readFilterMode(const std::string& value, osg::Texture::FilterMode& filterMode) + { + if (value=="LINEAR") filterMode = osg::Texture::LINEAR; + if (value=="NEAREST") filterMode = osg::Texture::NEAREST; + if (value=="LINEAR_MIPMAP_LINEAR") filterMode = osg::Texture::LINEAR_MIPMAP_LINEAR; + } + void read(osg::ArgumentParser& arguments) { if (arguments.read("--test")) @@ -94,6 +104,10 @@ struct TextSettings if (arguments.read("--font",fontFilename)) {} + std::string value; + if (arguments.read("--min", value)) { readFilterMode(value, minFilter); } + if (arguments.read("--mag", value)) { readFilterMode(value, magFilter); } + if (arguments.read("--margin", glyphImageMargin)) {} if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} @@ -123,6 +137,8 @@ struct TextSettings } std::string fontFilename; + osg::Texture::FilterMode minFilter; + osg::Texture::FilterMode magFilter; unsigned int glyphImageMargin; float glyphImageMarginRatio; int glyphInterval; @@ -144,6 +160,8 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne font->setGlyphImageMargin(settings.glyphImageMargin); font->setGlyphImageMarginRatio(settings.glyphImageMarginRatio); + font->setMinFilterHint(settings.minFilter); + font->setMagFilterHint(settings.magFilter); settings.setText(*label); From 77d4705182a3fe89bb6195a3052f9f6836eba853 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 6 Sep 2017 16:53:54 +0100 Subject: [PATCH 11/74] Added KeyHandler for toggling "SIGNED_DISTANCE_FIELD" and "OUTLINE" #pragma(tic) shader defines to control the different shader paths. Keys to press are 'd' for toggle SIGNED_DISTANCE_FIELD and 'o' for OUTLINE. --- examples/osgfont/osgfont.cpp | 57 +++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 55f893f36..3e70be384 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -182,7 +182,61 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne return label; } +class KeyHandler : public osgGA::GUIEventHandler +{ +public: + KeyHandler() {} + + ~KeyHandler() {} + + bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) + { + osgViewer::View* view = dynamic_cast(&aa); + if (!view) return false; + +#if 1 + osg::StateSet* stateset = view->getSceneData()->getOrCreateStateSet(); +#else + osg::StateSet* stateset = view->getCamera()->getOrCreateStateSet(); +#endif + switch(ea.getEventType()) + { + case(osgGA::GUIEventAdapter::KEYUP): + { + if (ea.getKey()=='d') + { + toggleDefine(stateset, "SIGNED_DISTANCE_FIELD"); + return true; + } + else if (ea.getKey()=='o') + { + toggleDefine(stateset, "OUTLINE"); + return true; + } + break; + } + default: + break; + } + return false; + } + + void toggleDefine(osg::StateSet* stateset, const std::string& define) + { + osg::StateSet::DefinePair* dp = stateset->getDefinePair(define); + if (dp) + { + OSG_NOTICE<<"Disabling "<removeDefine(define); + } + else + { + OSG_NOTICE<<"Enabling "<setDefine(define); + } + } +}; int main(int argc, char** argv) @@ -191,9 +245,10 @@ int main(int argc, char** argv) osgViewer::Viewer viewer(args); - viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); + viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); + viewer.addEventHandler(new KeyHandler()); TextSettings settings; settings.backgroundColor = viewer.getCamera()->getClearColor(); From de47eb3666cde64bc474115d8c81a21da413456d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 Sep 2017 16:59:43 +0100 Subject: [PATCH 12/74] Add support for generating outline and signed distance field channels in a RGBA packed GlyphTexture Image. --- include/osgText/Font | 11 +- include/osgText/Glyph | 33 +++-- src/osgText/Font.cpp | 15 ++- src/osgText/Glyph.cpp | 291 ++++++++++++++++++++++++++++++++++-------- src/osgText/Text.cpp | 6 +- 5 files changed, 292 insertions(+), 64 deletions(-) diff --git a/include/osgText/Font b/include/osgText/Font index 369493891..e77a0e035 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -128,6 +128,10 @@ public: int getGlyphInterval() const; + void setGyphTextureFeatures(GlyphTexture::Features features) { _glyphTextureFeatures = features; } + GlyphTexture::Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + + /** Set the size of texture to create to store the glyph images when rendering. * Note, this doesn't affect already created Texture Glhph's.*/ void setTextureSizeHint(unsigned int width,unsigned int height); @@ -145,6 +149,9 @@ public: void setMagFilterHint(osg::Texture::FilterMode mode); osg::Texture::FilterMode getMagFilterHint() const; + void setMaxAnisotropy(float anis) { _maxAnisotropy = anis; } + float getMaxAnisotropy() const { return _maxAnisotropy; } + unsigned int getFontDepth() const { return _depth; } void setNumberCurveSamples(unsigned int numSamples) { _numCurveSamples = numSamples; } @@ -203,11 +210,13 @@ protected: unsigned int _margin; float _marginRatio; int _glyphInterval; + GlyphTexture::Features _glyphTextureFeatures; unsigned int _textureWidthHint; unsigned int _textureHeightHint; osg::Texture::FilterMode _minFilterHint; osg::Texture::FilterMode _magFilterHint; + float _maxAnisotropy; unsigned int _depth; unsigned int _numCurveSamples; @@ -253,8 +262,6 @@ public: virtual bool getVerticalSize(float & /*ascender*/, float & /*descender*/) const { return false; } }; - - }; } diff --git a/include/osgText/Glyph b/include/osgText/Glyph index bb7d5192a..8dac38051 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -58,6 +58,9 @@ public: unsigned int getGlyphCode() const { return _glyphCode; } + void setFontResolution(const FontResolution& fontRes) { _fontResolution = fontRes; } + const FontResolution& getFontResolution() const { return _fontResolution; } + void setWidth(float width) { _width = width; } float getWidth() const { return _width; } @@ -90,8 +93,6 @@ public: void setMaxTexCoord(const osg::Vec2& coord); const osg::Vec2& getMaxTexCoord() const; - void subload() const; - protected: virtual ~Glyph(); @@ -99,6 +100,8 @@ protected: Font* _font; unsigned int _glyphCode; + FontResolution _fontResolution; + float _width; float _height; @@ -263,6 +266,17 @@ public: void setGlyphInterval(int interval) { _interval = interval; } int getGlyphInterval() const { return _interval; } + enum Features + { + GREYSCALE, + OUTLINE_GREYSCALE, + SIGNED_DISTANCE_FIELD, + ALL_FEATURES + }; + + void setGlyphTextureFeatures(Features features) { _glyphTextureFeatures = features; } + Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY); void addGlyph(Glyph* glyph,int posX, int posY); @@ -280,16 +294,19 @@ protected: virtual ~GlyphTexture(); + void copyGlyphImage(Glyph* glyph); + // parameter used to compute the size and position of empty space // in the texture which could accommodate new glyphs. - int _margin; - float _marginRatio; - int _interval; + int _margin; + float _marginRatio; + int _interval; + Features _glyphTextureFeatures; - int _usedY; - int _partUsedX; - int _partUsedY; + int _usedY; + int _partUsedX; + int _partUsedY; typedef std::vector< osg::ref_ptr > GlyphRefList; typedef std::vector< const Glyph* > GlyphPtrList; diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index 155acadff..c09285046 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -302,10 +302,16 @@ Font::Font(FontImplementation* implementation): _margin(1), _marginRatio(0.02), _glyphInterval(1), +#if 0 + _glyphTextureFeatures(GlyphTexture::ALL_FEATURES), +#else + _glyphTextureFeatures(GlyphTexture::GREYSCALE), +#endif _textureWidthHint(1024), _textureHeightHint(1024), _minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR), _magFilterHint(osg::Texture::LINEAR), + _maxAnisotropy(16), _depth(1), _numCurveSamples(10) { @@ -411,6 +417,12 @@ float Font::getGlyphImageMarginRatio() const return _marginRatio; } +void Font::setGlyphInterval(int interval) +{ + _glyphInterval = interval; +} + + void Font::setTextureSizeHint(unsigned int width,unsigned int height) { _textureWidthHint = width; @@ -606,10 +618,11 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyphTexture->setGlyphImageMargin(_margin); glyphTexture->setGlyphImageMarginRatio(_marginRatio); glyphTexture->setGlyphInterval(_glyphInterval); + glyphTexture->setGlyphTextureFeatures(_glyphTextureFeatures); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); - glyphTexture->setMaxAnisotropy(8); + glyphTexture->setMaxAnisotropy(_maxAnisotropy); _glyphTextureList.push_back(glyphTexture); diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 2699b0627..fd6d61f9c 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -28,6 +28,14 @@ using namespace osgText; using namespace std; +#if 0 + #define TEXTURE_IMAGE_NUM_CHANNELS 1 + #define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT +#else + #define TEXTURE_IMAGE_NUM_CHANNELS 4 + #define TEXTURE_IMAGE_FORMAT GL_RGBA +#endif + GlyphTexture::GlyphTexture(): _margin(1), _marginRatio(0.02f), @@ -121,8 +129,227 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) glyph->setMaxTexCoord( osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ) ); - _image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); - _image->dirty(); + copyGlyphImage(glyph); +} + +void GlyphTexture::copyGlyphImage(Glyph* glyph) +{ + + if (_glyphTextureFeatures==GREYSCALE) + { + // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copy"<copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); + _image->dirty(); + return; + } + + // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() generating signed distance field."<s(); + int src_rows = glyph->t(); + unsigned char* src_data = glyph->data(); + + int dest_columns = _image->s(); + int dest_rows = _image->t(); + unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY()); + + int search_distance = glyph->getFontResolution().second/8; + + int left = -search_distance; + int right = glyph->s()+search_distance; + int lower = -search_distance; + int upper = glyph->t()+search_distance; + + float multiplier = 1.0/255.0f; + float max_distance = sqrtf(float(search_distance*search_distance)*2.0f); + + int num_channels = TEXTURE_IMAGE_NUM_CHANNELS; + + if ((left+glyph->getTexturePositionX())<0) left = -glyph->getTexturePositionX(); + if ((right+glyph->getTexturePositionX())>=dest_columns) right = dest_columns-glyph->getTexturePositionX()-1; + + if ((lower+glyph->getTexturePositionY())<0) lower = -glyph->getTexturePositionY(); + if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; + + + for(int dr=lower; dr<=upper; ++dr) + { + for(int dc=left; dc<=right; ++dc) + { + unsigned char value = 0; + + unsigned char center_value = 0; + if (dr>=0 && dr=0 && dc0 && center_value<255) + { + if (center_value_f>=0.5f) + { + min_distance = center_value_f-0.5f; + value = 128+(min_distance/max_distance)*127; + } + else + { + min_distance = 0.5f-center_value_f; + value = 127-(min_distance/max_distance)*127; + } + } + else + { + for(int radius=1; radius=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + } + } + + { + // top + int dx = radius; + int dy = span; + + int c = dc+dx; + int r = dr+dy; + + unsigned char local_value = 0; + if (r>=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + } + } + + { + // right + int dx = radius; + int dy = -span; + + int c = dc+dx; + int r = dr+dy; + + unsigned char local_value = 0; + if (r>=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (local_distance=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (local_distance=0.5) + { + value = 128+(min_distance/max_distance)*127; + } + else + { + value = 127-(min_distance/max_distance)*127; + } + } + + + unsigned char* dest_ptr = dest_data + (dr*dest_columns + dc)*num_channels; + if (num_channels==4) + { + // signed distance field value + *(dest_ptr++) = value; + + float outline_distance = max_distance/4.0f; + + // compute the alpha value of outline, one texel thick + unsigned char outline = center_value; + if (center_value<255) + { + if (min_distanceallocateImage(getTextureWidth(), getTextureHeight(), 1, OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE); + + #if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) + GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_RED : GL_RGBA; + #else + GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_ALPHA : GL_RGBA; + #endif + + _image->allocateImage(getTextureWidth(), getTextureHeight(), 1, imageFormat, GL_UNSIGNED_BYTE); memset(_image->data(), 0, _image->getTotalSizeInBytes()); for(GlyphRefList::iterator itr = _glyphs.begin(); @@ -161,7 +397,7 @@ osg::Image* GlyphTexture::createImage() ++itr) { Glyph* glyph = itr->get(); - _image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); + copyGlyphImage(glyph); } } @@ -217,53 +453,6 @@ const osg::Vec2& Glyph::getMinTexCoord() const { return _minTexCoord; } void Glyph::setMaxTexCoord(const osg::Vec2& coord) { _maxTexCoord=coord; } const osg::Vec2& Glyph::getMaxTexCoord() const { return _maxTexCoord; } -void Glyph::subload() const -{ - GLenum errorNo = glGetError(); - if (errorNo!=GL_NO_ERROR) - { - const GLubyte* msg = osg::gluErrorString(errorNo); - if (msg) { OSG_WARN<<"before Glyph::subload(): detected OpenGL error: "<(data())<<");"<getMaxTexCoord(); osg::Vec2 vDiff = maxtc - mintc; - float fHorizTCMargin = 1.0f / glyph->getTexture()->getTextureWidth(); - float fVertTCMargin = 1.0f / glyph->getTexture()->getTextureHeight(); + float texelMargin = 4.0f; + + float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); + float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y(); From 2b010f019f28f65c13178f4701df74ba5d5cfb68 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 Sep 2017 17:02:38 +0100 Subject: [PATCH 13/74] Added setting of the original font reoslution to the created Glyph --- src/osgPlugins/freetype/FreeTypeFont.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osgPlugins/freetype/FreeTypeFont.cpp b/src/osgPlugins/freetype/FreeTypeFont.cpp index c647e2cf9..5d7aee6e9 100644 --- a/src/osgPlugins/freetype/FreeTypeFont.cpp +++ b/src/osgPlugins/freetype/FreeTypeFont.cpp @@ -351,6 +351,8 @@ osgText::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, u osg::ref_ptr glyph = new osgText::Glyph(_facade, charcode); + glyph->setFontResolution(fontRes); + unsigned int dataSize = width*height; unsigned char* data = new unsigned char[dataSize]; From f98c23d4606ec50dd82a10cf26343803216b6085 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 8 Sep 2017 17:03:15 +0100 Subject: [PATCH 14/74] Added extra command line paramter and osgText::Font settings to add better control of osgText::GlyphTexture generation to support signed distance field and outline image data. --- examples/osgfont/osgfont.cpp | 59 +++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 3e70be384..2d37f4862 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -67,9 +67,11 @@ struct TextSettings fontFilename("fonts/arial.ttf"), minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), magFilter(osg::Texture::LINEAR), + maxAnisotropy(16.0f), glyphImageMargin(1), glyphImageMarginRatio(0.02), glyphInterval(1), + glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.04f, 0.04f), @@ -81,8 +83,8 @@ struct TextSettings void readFilterMode(const std::string& value, osg::Texture::FilterMode& filterMode) { if (value=="LINEAR") filterMode = osg::Texture::LINEAR; - if (value=="NEAREST") filterMode = osg::Texture::NEAREST; - if (value=="LINEAR_MIPMAP_LINEAR") filterMode = osg::Texture::LINEAR_MIPMAP_LINEAR; + else if (value=="NEAREST") filterMode = osg::Texture::NEAREST; + else if (value=="LINEAR_MIPMAP_LINEAR") filterMode = osg::Texture::LINEAR_MIPMAP_LINEAR; } void read(osg::ArgumentParser& arguments) @@ -102,12 +104,18 @@ struct TextSettings sizes.push_back(128); } + if (arguments.read("--GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; } + if (arguments.read("--OUTLINE_GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::OUTLINE_GREYSCALE; } + if (arguments.read("--SIGNED_DISTANCE_FIELD")) { glyphTextureFeatures = osgText::GlyphTexture::SIGNED_DISTANCE_FIELD; } + if (arguments.read("--ALL_FEATURES")) { glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; } + if (arguments.read("--font",fontFilename)) {} std::string value; if (arguments.read("--min", value)) { readFilterMode(value, minFilter); } if (arguments.read("--mag", value)) { readFilterMode(value, magFilter); } + if (arguments.read("--anisotropy",maxAnisotropy)) {} if (arguments.read("--margin", glyphImageMargin)) {} if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} @@ -129,26 +137,39 @@ struct TextSettings void setText(osgText::Text& text) { OSG_NOTICE<<"Settings::setText()"< font = osgText::readRefFontFile(fontFilename); + + font->setGlyphImageMargin(glyphImageMargin); + font->setGlyphImageMarginRatio(glyphImageMarginRatio); + font->setMinFilterHint(minFilter); + font->setMagFilterHint(magFilter); + font->setMaxAnisotropy(maxAnisotropy); + font->setGlyphInterval(glyphInterval); + font->setGyphTextureFeatures(glyphTextureFeatures); + text.setFont(font.get()); + text.setColor(textColor); text.setBackdropType(backdropType); text.setBackdropOffset(backdropOffset.x(), backdropOffset.y()); text.setBackdropColor(backdropColor); } - std::string fontFilename; - osg::Texture::FilterMode minFilter; - osg::Texture::FilterMode magFilter; - unsigned int glyphImageMargin; - float glyphImageMarginRatio; - int glyphInterval; + std::string fontFilename; + osg::Texture::FilterMode minFilter; + osg::Texture::FilterMode magFilter; + float maxAnisotropy; + unsigned int glyphImageMargin; + float glyphImageMarginRatio; + int glyphInterval; + osgText::GlyphTexture::Features glyphTextureFeatures; - osg::Vec4 textColor; - osgText::Text::BackdropType backdropType; - osg::Vec2 backdropOffset; - osg::Vec4 backdropColor; - osg::Vec4 backgroundColor; - Sizes sizes; + osg::Vec4 textColor; + osgText::Text::BackdropType backdropType; + osg::Vec2 backdropOffset; + osg::Vec4 backdropColor; + osg::Vec4 backgroundColor; + Sizes sizes; }; osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size) @@ -156,12 +177,6 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne static osg::Vec3 pos(10.0f, 10.0f, 0.0f); osgText::Text* label = new osgText::Text(); - osg::ref_ptr font = osgText::readRefFontFile(settings.fontFilename); - - font->setGlyphImageMargin(settings.glyphImageMargin); - font->setGlyphImageMarginRatio(settings.glyphImageMarginRatio); - font->setMinFilterHint(settings.minFilter); - font->setMagFilterHint(settings.magFilter); settings.setText(*label); @@ -291,6 +306,8 @@ int main(int argc, char** argv) OSG_NOTICE<<"Using shaders"<getOrCreateStateSet()->setAttribute(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); root->getOrCreateStateSet()->addUniform(new osg::Uniform("glyphTexture", 0)); + + settings.glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; } From 722ed6fc5ecc89620cc90a03317bf25e22d38a5e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 12 Sep 2017 11:50:47 +0100 Subject: [PATCH 15/74] Shifted set up of osgText related StateSet from osgText::Font into into osg::TextBase/Text to enable grater control over state required for specific Text implementations --- include/osgText/Font | 15 ++-- include/osgText/Text | 16 ++-- include/osgText/TextBase | 4 + src/osgText/Font.cpp | 133 +++------------------------- src/osgText/Text.cpp | 184 +++++++++++++++++++++++++++++++++------ src/osgText/TextBase.cpp | 12 ++- 6 files changed, 193 insertions(+), 171 deletions(-) diff --git a/include/osgText/Font b/include/osgText/Font index e77a0e035..7b7fd0186 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -27,6 +27,7 @@ namespace osgText { // forward declare Font class Font; +class TextBase; #ifdef OSG_PROVIDE_READFILE /** Read a font from specified file. The filename may contain a path. @@ -84,13 +85,9 @@ public: static osg::ref_ptr& getDefaultFont(); - void setTexEnv(osg::TexEnv* texenv) { if (texenv) _texenv = texenv; } - inline osg::TexEnv* getTexEnv() { return _texenv.get(); } - inline const osg::TexEnv* getTexEnv() const { return _texenv.get(); } - - void setStateSet(osg::StateSet* stateset) { _stateset = stateset; } - osg::StateSet* getStateSet() { return _stateset.get(); } - const osg::StateSet* getStateSet() const { return _stateset.get(); } + typedef std::vector< osg::ref_ptr > StateSets; + StateSets& getCachedStateSets() { return _statesets; } + const StateSets& getCachedStateSets() const { return _statesets; } /** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes and a font resolution.*/ @@ -188,7 +185,6 @@ protected: void addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph); - typedef std::vector< osg::ref_ptr > StateSetList; typedef std::map< unsigned int, osg::ref_ptr > GlyphMap; typedef std::map< unsigned int, osg::ref_ptr > Glyph3DMap; @@ -197,8 +193,7 @@ protected: mutable OpenThreads::Mutex _glyphMapMutex; - osg::ref_ptr _texenv; - osg::ref_ptr _stateset; + StateSets _statesets; FontSizeGlyphMap _sizeGlyphMap; GlyphTextureList _glyphTextureList; diff --git a/include/osgText/Text b/include/osgText/Text index db497792f..fc6fbfc0f 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -36,16 +36,6 @@ public: virtual const char* className() const { return "Text"; } virtual const char* libraryName() const { return "osgText"; } - virtual void setFont(Font* font=0) { setFont(osg::ref_ptr(font)); }; - - /** Set the Font to use to render the text.*/ - virtual void setFont(osg::ref_ptr font); - - /** Set the font, loaded from the specified front file, to use to render the text, - * setFont("") sets the use of the default font. - * See the osgText::readFontFile function for how the font file will be located. */ - virtual void setFont(const std::string& fontfile) { TextBase::setFont(fontfile); } - /** * Turns off writing to the depth buffer when rendering text. This only affects text * with no backdrop or text using the DELAYED_DEPTH_WRITES implementation, since @@ -92,7 +82,9 @@ public: * buffer. But if you don't need the depth buffer updated for * your, this extra pass can be disabled by calling * enableDepthWrites(false).*/ - DELAYED_DEPTH_WRITES + DELAYED_DEPTH_WRITES, + + USE_SHADERS }; /** @@ -284,6 +276,8 @@ protected: virtual ~Text(); + virtual osg::StateSet* createStateSet(); + Font* getActiveFont(); const Font* getActiveFont() const; diff --git a/include/osgText/TextBase b/include/osgText/TextBase index 64fe785f1..dceac86b7 100644 --- a/include/osgText/TextBase +++ b/include/osgText/TextBase @@ -284,6 +284,10 @@ protected: virtual ~TextBase(); + virtual osg::StateSet* createStateSet(); + + virtual void assignStateSet(); + void initArraysAndBuffers(); osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const; diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index c09285046..c1aa0e077 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -32,81 +32,6 @@ using namespace osgText; using namespace std; -#if (!defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GLES3_AVAILABLE)) - #define GLSL_VERSION_STR "330 core" - #define GLYPH_CMP "r" -#else - #define GLSL_VERSION_STR "300 es" - #define GLYPH_CMP "a" -#endif - -static const char* gl3_TextVertexShader = { - "#version " GLSL_VERSION_STR "\n" - "// gl3_TextVertexShader\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_TextFragmentShader = { - "#version " GLSL_VERSION_STR "\n" - "// gl3_TextFragmentShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "uniform sampler2D glyphTexture;\n" - "in vec2 texCoord;\n" - "in vec4 vertexColor;\n" - "out vec4 color;\n" - "void main(void)\n" - "{\n" - " if (texCoord.x>=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" -}; - osg::ref_ptr& Font::getDefaultFont() { static OpenThreads::Mutex s_DefaultFontMutex; @@ -317,47 +242,6 @@ Font::Font(FontImplementation* implementation): { setImplementation(implementation); - _texenv = new osg::TexEnv; - _stateset = new osg::StateSet; - - _stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - _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"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); -#endif - - osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); - if (shaderHint==osg::DisplaySettings::SHADER_GL3 || shaderHint==osg::DisplaySettings::SHADER_GLES3) - { - - 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)); - - } - else if (shaderHint==osg::DisplaySettings::SHADER_GL2 || shaderHint==osg::DisplaySettings::SHADER_GLES2) - { - - - 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)); - - } - char *ptr; if( (ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0) { @@ -531,9 +415,6 @@ void Font::setThreadSafeRefUnref(bool threadSafe) { osg::Object::setThreadSafeRefUnref(threadSafe); - if (_texenv.valid()) _texenv->setThreadSafeRefUnref(threadSafe); - if (_stateset.valid()) _stateset->setThreadSafeRefUnref(threadSafe); - for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); itr!=_glyphTextureList.end(); ++itr) @@ -544,7 +425,12 @@ void Font::setThreadSafeRefUnref(bool threadSafe) void Font::resizeGLObjectBuffers(unsigned int maxSize) { - if (_stateset.valid()) _stateset->resizeGLObjectBuffers(maxSize); + for(StateSets::iterator itr = _statesets.begin(); + itr != _statesets.end(); + ++itr) + { + (*itr)->resizeGLObjectBuffers(maxSize); + } for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); itr!=_glyphTextureList.end(); @@ -556,7 +442,12 @@ void Font::resizeGLObjectBuffers(unsigned int maxSize) void Font::releaseGLObjects(osg::State* state) const { - if (_stateset.valid()) _stateset->releaseGLObjects(state); + for(StateSets::const_iterator itr = _statesets.begin(); + itr != _statesets.end(); + ++itr) + { + (*itr)->releaseGLObjects(state); + } for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); itr!=_glyphTextureList.end(); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 7cac3d0a9..f4cb94bd7 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -28,10 +28,92 @@ using namespace osg; using namespace osgText; +#if (!defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GLES3_AVAILABLE)) + #define GLSL_VERSION_STR "330 core" + #define GLYPH_CMP "r" +#else + #define GLSL_VERSION_STR "300 es" + #define GLYPH_CMP "a" +#endif + +static const char* gl3_TextVertexShader = { + "#version " GLSL_VERSION_STR "\n" + "// gl3_TextVertexShader\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_TextFragmentShader = { + "#version " GLSL_VERSION_STR "\n" + "// gl3_TextFragmentShader\n" + "#ifdef GL_ES\n" + " precision highp float;\n" + "#endif\n" + "uniform sampler2D glyphTexture;\n" + "in vec2 texCoord;\n" + "in vec4 vertexColor;\n" + "out vec4 color;\n" + "void main(void)\n" + "{\n" + " if (texCoord.x>=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), +#if 1 _backdropImplementation(DELAYED_DEPTH_WRITES), +#else + _backdropImplementation(USE_SHADERS), +#endif _backdropHorizontalOffset(0.07f), _backdropVerticalOffset(0.07f), _backdropColor(0.0f, 0.0f, 0.0f, 1.0f), @@ -42,6 +124,8 @@ Text::Text(): _colorGradientTopRight(1.0f, 1.0f, 1.0f, 1.0f) { _supportsVertexBufferObjects = true; + + assignStateSet(); } Text::Text(const Text& text,const osg::CopyOp& copyop): @@ -65,21 +149,59 @@ Text::~Text() { } -void Text::setFont(osg::ref_ptr font) +osg::StateSet* Text::createStateSet() { - if (_font==font) return; + Font* activeFont = getActiveFont(); + if (!activeFont) return 0; - osg::StateSet* previousFontStateSet = _font.valid() ? _font->getStateSet() : Font::getDefaultFont()->getStateSet(); - osg::StateSet* newFontStateSet = font.valid() ? font->getStateSet() : Font::getDefaultFont()->getStateSet(); + Font::StateSets& statesets = activeFont->getCachedStateSets(); - if (getStateSet() == previousFontStateSet) + if (!statesets.empty()) { - setStateSet( newFontStateSet ); + return statesets.front().get(); } - TextBase::setFont(font); -} + osg::ref_ptr stateset = new osg::StateSet; + statesets.push_back(stateset.get()); + + stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + 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"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); +#endif + + osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); + if (shaderHint==osg::DisplaySettings::SHADER_GL3 || shaderHint==osg::DisplaySettings::SHADER_GLES3) + { + 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)); + + } + else if (shaderHint==osg::DisplaySettings::SHADER_GL2 || shaderHint==osg::DisplaySettings::SHADER_GLES2) + { + 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)); + + } + + return stateset.release(); +} Font* Text::getActiveFont() { @@ -632,7 +754,7 @@ void Text::computePositionsImplementation() // Presumes the atc matrix is already up-to-date void Text::computeBackdropPositions() { - if(_backdropType == NONE) + if(_backdropType == NONE || _backdropImplementation == USE_SHADERS) { return; } @@ -1130,33 +1252,39 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo const GlyphQuads& glyphquad = titr->second; -#if 1 if(_backdropType != NONE) { - unsigned int backdrop_index; - unsigned int max_backdrop_index; - if(_backdropType == OUTLINE) + if (_backdropImplementation != USE_SHADERS) { - backdrop_index = 1; - max_backdrop_index = 8; + unsigned int backdrop_index; + unsigned int max_backdrop_index; + if(_backdropType == OUTLINE) + { + backdrop_index = 1; + max_backdrop_index = 8; + } + else + { + backdrop_index = _backdropType+1; + max_backdrop_index = backdrop_index+1; + } + + if (max_backdrop_index>glyphquad._primitives.size()) max_backdrop_index=glyphquad._primitives.size(); + + state.disableColorPointer(); + state.Color(_backdropColor.r(),_backdropColor.g(),_backdropColor.b(),_backdropColor.a()); + + for( ; backdrop_index < max_backdrop_index; backdrop_index++) + { + glyphquad._primitives[backdrop_index]->draw(state, usingVertexBufferObjects); + } } else { - backdrop_index = _backdropType+1; - max_backdrop_index = backdrop_index+1; - } - - if (max_backdrop_index>glyphquad._primitives.size()) max_backdrop_index=glyphquad._primitives.size(); - - state.disableColorPointer(); - state.Color(_backdropColor.r(),_backdropColor.g(),_backdropColor.b(),_backdropColor.a()); - - for( ; backdrop_index < max_backdrop_index; backdrop_index++) - { - glyphquad._primitives[backdrop_index]->draw(state, usingVertexBufferObjects); + OSG_NOTICE<<"Using shaders for backdrop"<disableColorArray(state); diff --git a/src/osgText/TextBase.cpp b/src/osgText/TextBase.cpp index 5c5e5460e..c0da7b679 100644 --- a/src/osgText/TextBase.cpp +++ b/src/osgText/TextBase.cpp @@ -50,7 +50,6 @@ TextBase::TextBase(): _lineCount(0), _glyphNormalized(false) { - setStateSet(Font::getDefaultFont()->getStateSet()); setUseDisplayList(false); setSupportsDisplayList(false); @@ -89,6 +88,11 @@ TextBase::~TextBase() { } +osg::StateSet* TextBase::createStateSet() +{ + return 0; +} + void TextBase::initArraysAndBuffers() { _vbo = new osg::VertexBufferObject; @@ -182,6 +186,10 @@ void TextBase::setColor(const osg::Vec4& color) _color = color; } +void TextBase::assignStateSet() +{ + setStateSet(createStateSet()); +} void TextBase::setFont(osg::ref_ptr font) { @@ -189,6 +197,8 @@ void TextBase::setFont(osg::ref_ptr font) _font = font; + assignStateSet(); + computeGlyphRepresentation(); } From 7a50bdafe38b3c538ae3ce085b4c270652a49f5e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 12 Sep 2017 16:03:35 +0100 Subject: [PATCH 16/74] Changed the margin computation to properly account of the Signed Distance Function data --- src/osgText/Glyph.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index fd6d61f9c..efdf1cfb0 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -64,7 +64,10 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) { int maxAxis = osg::maximum(glyph->s(), glyph->t()); - int margin = _margin + (int)((float)maxAxis * _marginRatio); + int margin_from_ratio = (int)((float)maxAxis * _marginRatio); + int search_distance = glyph->getFontResolution().second/8; + + int margin = _margin + osg::maximum(margin_from_ratio, search_distance); int width = glyph->s()+2*margin; int height = glyph->t()+2*margin; From 0d5a42f635d7e5b433995e9b86e91d87135a7e6e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 12 Sep 2017 19:13:01 +0100 Subject: [PATCH 17/74] Added setting of the Text::BackdropImplementation type to USE_SHADERS when setting up shaders --- examples/osgfont/osgfont.cpp | 10 ++++- src/osgText/Text.cpp | 74 ++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 2d37f4862..3c3fd6128 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -147,12 +147,20 @@ struct TextSettings font->setMaxAnisotropy(maxAnisotropy); font->setGlyphInterval(glyphInterval); font->setGyphTextureFeatures(glyphTextureFeatures); - text.setFont(font.get()); + // text.setFont(font.get()); text.setColor(textColor); text.setBackdropType(backdropType); text.setBackdropOffset(backdropOffset.x(), backdropOffset.y()); text.setBackdropColor(backdropColor); + + if (glyphTextureFeatures==osgText::GlyphTexture::ALL_FEATURES) + { + text.setBackdropImplementation(osgText::Text::USE_SHADERS); + } + + text.setFont(font.get()); + } std::string fontFilename; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index f4cb94bd7..97e7c2c70 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -149,6 +149,8 @@ Text::~Text() { } +#include + osg::StateSet* Text::createStateSet() { Font* activeFont = getActiveFont(); @@ -156,13 +158,79 @@ osg::StateSet* Text::createStateSet() Font::StateSets& statesets = activeFont->getCachedStateSets(); - if (!statesets.empty()) + osg::StateSet::DefineList defineList; + if (_backdropType!=NONE && _backdropImplementation==USE_SHADERS) { - return statesets.front().get(); + std::stringstream ss; + + ss.str(""); + ss << "vec4("<<_backdropColor.r()<<", "<<_backdropColor.g()<<", "<<_backdropColor.b()<<", "<<_backdropColor.a()<<")"; + + defineList["BACKDROP_COLOR"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); + + if (_backdropType==OUTLINE) + { + ss.str(""); + ss <<_backdropHorizontalOffset; + defineList["OUTLINE"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); + } + else + { + osg::Vec2 offset(_backdropHorizontalOffset, _backdropVerticalOffset); + switch(_backdropType) + { + case(DROP_SHADOW_BOTTOM_RIGHT) : offset.set(_backdropHorizontalOffset, -_backdropVerticalOffset); break; + case(DROP_SHADOW_CENTER_RIGHT) : offset.set(_backdropHorizontalOffset, 0.0f); break; + case(DROP_SHADOW_TOP_RIGHT) : offset.set(_backdropHorizontalOffset, _backdropVerticalOffset); break; + case(DROP_SHADOW_BOTTOM_CENTER) : offset.set(0.0f, -_backdropVerticalOffset); break; + case(DROP_SHADOW_TOP_CENTER) : offset.set(0.0f, _backdropVerticalOffset); break; + case(DROP_SHADOW_BOTTOM_LEFT) : offset.set(-_backdropHorizontalOffset, -_backdropVerticalOffset); break; + case(DROP_SHADOW_CENTER_LEFT) : offset.set(-_backdropHorizontalOffset, 0.0f); break; + case(DROP_SHADOW_TOP_LEFT) : offset.set(-_backdropHorizontalOffset, _backdropVerticalOffset); break; + default : break; + } + + ss.str(""); + ss << "vec2("<first<<"] = "<second.first<getDefineList()==defineList) + { + // OSG_NOTICE<<"Text::createStateSet() : Matched DefineList, return StateSet "<get()<get(); + } + else + { + } + } + } + + // OSG_NOTICE<<"Text::createStateSet() : Not Matched DefineList, creating new StateSet"< stateset = new osg::StateSet; + stateset->setDefineList(defineList); + statesets.push_back(stateset.get()); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); @@ -1281,7 +1349,7 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo } else { - OSG_NOTICE<<"Using shaders for backdrop"< Date: Wed, 13 Sep 2017 11:08:51 +0100 Subject: [PATCH 18/74] Added --shadow-* command line variants to provide full control over the position of the text shadow --- examples/osgfont/osgfont.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 3c3fd6128..6ccff4f47 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -124,6 +124,16 @@ struct TextSettings if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; + if (arguments.read("--shadow-br")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; + if (arguments.read("--shadow-cr")) backdropType = osgText::Text::DROP_SHADOW_CENTER_RIGHT; + if (arguments.read("--shadow-tr")) backdropType = osgText::Text::DROP_SHADOW_TOP_RIGHT; + if (arguments.read("--shadow-bc")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_CENTER; + if (arguments.read("--shadow-tc")) backdropType = osgText::Text::DROP_SHADOW_TOP_CENTER; + if (arguments.read("--shadow-bl")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_LEFT; + if (arguments.read("--shadow-cl")) backdropType = osgText::Text::DROP_SHADOW_CENTER_LEFT; + if (arguments.read("--shadow-tl")) backdropType = osgText::Text::DROP_SHADOW_TOP_LEFT; + + float offset; if (arguments.read("--offset", offset)) backdropOffset.set(offset, offset); From 70b3a3a4421eff88d85def8d16ca10fb71831242 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 13 Sep 2017 11:09:56 +0100 Subject: [PATCH 19/74] Fixed of shadow --- src/osgText/Text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 97e7c2c70..e930386c2 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -864,7 +864,7 @@ void Text::computeBackdropPositions() { float horizontal_shift_direction; float vertical_shift_direction; - switch(backdrop_index) + switch(backdrop_index-1) { case DROP_SHADOW_BOTTOM_RIGHT: { From a12a43d3528fcbdac92d0356dfe1629e25f6da25 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 14 Sep 2017 15:58:38 +0100 Subject: [PATCH 20/74] Impprovide the computation of the Signed Distance Field --- src/osgText/Glyph.cpp | 42 ++++++++++++++++++++++++++++++++++++++++-- src/osgText/Text.cpp | 2 +- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index efdf1cfb0..d418c5829 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -226,6 +226,8 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float local_distance = sqrtf(float(radius*radius)+float(span*span)); if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; else local_distance += (local_value_f - 0.5f)*local_multiplier; + + if (local_distancecenter_value) + { + outline -= center_value; + } +#endif *(dest_ptr++) = outline; + outline_distance *= 2.0f; +#if 0 // compute the alpha vlaue of outline two texel thick outline = center_value; if (center_value<255) @@ -342,6 +365,21 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else if (min_distancecenter_value) + { + outline -= center_value; + } +#endif *(dest_ptr++) = outline; // original alpha value from glyph image diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index e930386c2..3f102ea86 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -684,7 +684,7 @@ void Text::computeGlyphRepresentation() osg::Vec2 maxtc = glyph->getMaxTexCoord(); osg::Vec2 vDiff = maxtc - mintc; - float texelMargin = 4.0f; + float texelMargin = 5.0f; float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); From 5ade85217259877d5723c1dd1d3ecc0e8c3c49d3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 15 Sep 2017 15:14:19 +0100 Subject: [PATCH 21/74] Added constant sizeing vs changing label size relatve to font resolution, controlled by --constant-size and --scale-size command line options. --- examples/osgfont/osgfont.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 6ccff4f47..7340a4251 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -75,7 +75,8 @@ struct TextSettings textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.04f, 0.04f), - backdropColor(0.0f, 0.0f, 0.0f, 1.0f) + backdropColor(0.0f, 0.0f, 0.0f, 1.0f), + scaleFontSizeToFontResolution(false) { } @@ -142,6 +143,9 @@ struct TextSettings if (arguments.read("--bd-color", backdropColor.r(), backdropColor.g(), backdropColor.b(), backdropColor.a())) {} if (arguments.read("--bg-color", backgroundColor.r(), backgroundColor.g(), backgroundColor.b(), backgroundColor.a())) {} + if (arguments.read("--constant-size")) scaleFontSizeToFontResolution = false; + if (arguments.read("--scale-size")) scaleFontSizeToFontResolution = true; + } void setText(osgText::Text& text) @@ -188,6 +192,7 @@ struct TextSettings osg::Vec4 backdropColor; osg::Vec4 backgroundColor; Sizes sizes; + bool scaleFontSizeToFontResolution; }; osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size) @@ -198,7 +203,13 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne settings.setText(*label); - label->setCharacterSize(size); + + if (settings.scaleFontSizeToFontResolution) + { + label->setCharacterSize(size); + } + + label->setFontResolution(size, size); label->setPosition(pos); label->setAlignment(osgText::Text::LEFT_BOTTOM); @@ -210,7 +221,7 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne // textInfo(label); - pos.y() += size + 10.0f; + pos.y() += label->getCharacterHeight()*2.0; return label; } From cc7cf54353d9393d86a92c7ecece0235133d3cfa Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 18 Sep 2017 18:09:15 +0100 Subject: [PATCH 22/74] Added support for subsititing $VAR_NAME entries in shaders to enable writing shaders that work across GLSL versions. --- include/osg/DisplaySettings | 15 ++++- include/osg/State | 5 +- src/osg/DisplaySettings.cpp | 110 ++++++++++++++++++++++++++++++------ src/osg/Shader.cpp | 2 +- src/osg/State.cpp | 68 +++++++++++++++++++++- 5 files changed, 179 insertions(+), 21 deletions(-) diff --git a/include/osg/DisplaySettings b/include/osg/DisplaySettings index 6821d14e9..393aa7415 100644 --- a/include/osg/DisplaySettings +++ b/include/osg/DisplaySettings @@ -20,6 +20,7 @@ #include #include +#include namespace osg { @@ -319,7 +320,9 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced SHADER_GLES3 }; - void setShaderHint(ShaderHint hint) { _shaderHint = hint; } + /** set the ShaderHint to tells shader generating cdoes version to create. + * By default also OSG_GLSL_VERSION and OSG_PRECISION_FLOAT values that can get use directly in shaders using $OSG_GLSL_VERSION and $OSG_PRECISION_FLOAT respectively.*/ + void setShaderHint(ShaderHint hint, bool setShaderValues=true); ShaderHint getShaderHint() const { return _shaderHint; } @@ -358,6 +361,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced /** helper function for computing the right eye view matrix.*/ virtual osg::Matrixd computeRightEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale=1.0) const; + + void setValue(const std::string& name, const std::string& value); + + bool getValue(const std::string& name, std::string& value, bool use_getenv_fallback=true) const; + protected: virtual ~DisplaySettings(); @@ -422,6 +430,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced OSXMenubarBehavior _OSXMenubarBehavior; + typedef std::map ValueMap; + + mutable OpenThreads::Mutex _valueMapMutex; + mutable ValueMap _valueMap; + }; } diff --git a/include/osg/State b/include/osg/State index ee5415660..97b6fec2a 100644 --- a/include/osg/State +++ b/include/osg/State @@ -823,9 +823,12 @@ class OSG_EXPORT State : public Referenced * during rendering. */ inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; } - /** Get the DisplaySettings */ + /** Get the const DisplaySettings */ inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); } + /** Get the const DisplaySettings that is current active DisplaySettings to be used by osg::State, - if DisplaySettings is not directly assigned then fallback to DisplaySettings::instance(). */ + inline const DisplaySettings* getActiveDisplaySettings() const { return _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get(); } + /** Set flag for early termination of the draw traversal.*/ diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 1df3e7e89..a07d7e58b 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -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"< lock(_valueMapMutex); + + _valueMap[name] = value; +} + +bool DisplaySettings::getValue(const std::string& name, std::string& value, bool use_getenv_fallback) const +{ + OpenThreads::ScopedLock lock(_valueMapMutex); + + ValueMap::iterator itr = _valueMap.find(name); + if (itr!=_valueMap.end()) + { + value = itr->second; + OSG_NOTICE<<"DisplaySettings::getValue("<getShaderSource(); - if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms())) + // if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms())) { state.convertVertexShaderSourceToOsgBuiltIns(source); } diff --git a/src/osg/State.cpp b/src/osg/State.cpp index c652d4cc6..e684c6ae7 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -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 : ["< Date: Tue, 19 Sep 2017 16:35:28 +0100 Subject: [PATCH 23/74] Added osgText/shaders to support greyscale and Signed Distance Field based text --- src/osg/State.cpp | 2 +- src/osgText/Text.cpp | 128 +++++------------- src/osgText/shaders/text_greyscale_frag.cpp | 33 +++++ src/osgText/shaders/text_sdf_frag.cpp | 136 ++++++++++++++++++++ src/osgText/shaders/text_vert.cpp | 13 ++ 5 files changed, 214 insertions(+), 98 deletions(-) create mode 100644 src/osgText/shaders/text_greyscale_frag.cpp create mode 100644 src/osgText/shaders/text_sdf_frag.cpp create mode 100644 src/osgText/shaders/text_vert.cpp 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"; From 370ca2b8a3dd0b6ab8df913b9f9e5cb8144ef6ad Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 19 Sep 2017 17:01:58 +0100 Subject: [PATCH 24/74] Fixed X11 GLES2 build --- include/osgViewer/api/X11/GraphicsWindowX11 | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/osgViewer/api/X11/GraphicsWindowX11 b/include/osgViewer/api/X11/GraphicsWindowX11 index 1efb990fe..fe40d7f8c 100644 --- a/include/osgViewer/api/X11/GraphicsWindowX11 +++ b/include/osgViewer/api/X11/GraphicsWindowX11 @@ -37,10 +37,11 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub _parent(0), _window(0), _visualInfo(0), - _fbConfig(0), #ifdef OSG_USE_EGL _eglDisplay(0), _eglSurface(0), + #else + _fbConfig(0), #endif _currentCursor(0), _initialized(false), @@ -177,11 +178,12 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub Window _parent; Window _window; XVisualInfo* _visualInfo; - GLXFBConfig _fbConfig; #ifdef OSG_USE_EGL EGLDisplay _eglDisplay; EGLSurface _eglSurface; + #else + GLXFBConfig _fbConfig; #endif Cursor _currentCursor; From fafa468fea781fb890e9a1369e98cfaba12ee7b1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 19 Sep 2017 17:07:59 +0100 Subject: [PATCH 25/74] Fixed OSG_PRECISION_FLOAT usage --- src/osgText/shaders/text_greyscale_frag.cpp | 2 +- src/osgText/shaders/text_sdf_frag.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osgText/shaders/text_greyscale_frag.cpp b/src/osgText/shaders/text_greyscale_frag.cpp index 51738a2cf..cc1625bf7 100644 --- a/src/osgText/shaders/text_greyscale_frag.cpp +++ b/src/osgText/shaders/text_greyscale_frag.cpp @@ -1,5 +1,5 @@ char text_greyscale_frag[] = "$OSG_GLSL_VERSION\n" - "$OSG_GLSL_PRECISION_FLOAT\n" + "$OSG_PRECISION_FLOAT\n" "\n" "#pragma import_defines( BACKDROP_COLOR, OUTLINE, ALPHA )\n" "\n" diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index 379bcba46..d04362a0f 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -1,5 +1,5 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" - "$OSG_GLSL_PRECISION_FLOAT\n" + "$OSG_PRECISION_FLOAT\n" "\n" "#pragma import_defines( BACKDROP_COLOR, OUTLINE )\n" "\n" @@ -14,7 +14,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "#endif\n" "\n" - "#undef USE_SIGNED_DISTNACE_FIELD\n" + "//#undef USE_SIGNED_DISTNACE_FIELD\n" "\n" "#if __VERSION__>=130\n" " #define TEXTURE texture\n" From 420094174e591dcb105b91dc944ea3edbefe0771 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 11:01:04 +0100 Subject: [PATCH 26/74] Added commented out debug output to make it easier to test in future --- src/osg/Shader.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 167d016b1..1b11789fc 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -633,7 +633,7 @@ void Shader::PerContextShader::compileShader(osg::State& state) GLint compiled = GL_FALSE; - // OSG_NOTICE<<"Compiling PerContextShader "<(versionLine.c_str()); sourceText[1] = reinterpret_cast(_defineStr.c_str()); sourceText[2] = reinterpret_cast(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 3, sourceText, NULL ); + + + // OSG_NOTICE<<" Version Line : ["<(_defineStr.c_str()); sourceText[1] = reinterpret_cast(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 2, sourceText, NULL ); + + // OSG_NOTICE<<" DefineStr : ["<glCompileShader( _glShaderHandle ); From b0829cc3521cc85f49d3d3bc0ce9316e44025989 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 11:02:06 +0100 Subject: [PATCH 27/74] Updated text_sdf.frag shader to handle GLES2+ versions --- src/osgText/shaders/text_sdf_frag.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index d04362a0f..38f508f09 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -1,19 +1,23 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" - "$OSG_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" + "#if !defined(GL_ES)\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" "#endif\n" "\n" + "\n" + "$OSG_PRECISION_FLOAT\n" + "\n" "//#undef USE_SIGNED_DISTNACE_FIELD\n" "\n" "#if __VERSION__>=130\n" @@ -35,7 +39,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" "\n" - " #if 0\n" + " #if 1\n" " float blend_ratio = OUTLINE*17.0;\n" "\n" " float outline_alpha = 0.0;\n" From e8eb1ee0c7e27b5961986bff1a655427a4a8fc53 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 14:29:05 +0100 Subject: [PATCH 28/74] Added Text::assignStateSet() and usage to make sure the correct StateSet is setup for each combination of backdrop settings --- include/osgText/Text | 2 ++ src/osgText/Text.cpp | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/osgText/Text b/include/osgText/Text index fc6fbfc0f..0d991a805 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -278,6 +278,8 @@ protected: virtual osg::StateSet* createStateSet(); + void assignStateSet(); + Font* getActiveFont(); const Font* getActiveFont() const; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 25585d0d6..665147bd7 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -205,6 +205,11 @@ osg::StateSet* Text::createStateSet() return stateset.release(); } +void Text::assignStateSet() +{ + setStateSet(createStateSet()); +} + Font* Text::getActiveFont() { return _font.valid() ? _font.get() : Font::getDefaultFont().get(); @@ -1454,6 +1459,9 @@ void Text::setBackdropType(BackdropType type) if (_backdropType==type) return; _backdropType = type; + + assignStateSet(); + computeGlyphRepresentation(); } @@ -1462,6 +1470,9 @@ void Text::setBackdropImplementation(BackdropImplementation implementation) if (_backdropImplementation==implementation) return; _backdropImplementation = implementation; + + assignStateSet(); + computeGlyphRepresentation(); } @@ -1470,6 +1481,9 @@ void Text::setBackdropOffset(float offset) { _backdropHorizontalOffset = offset; _backdropVerticalOffset = offset; + + assignStateSet(); + computeGlyphRepresentation(); } @@ -1477,6 +1491,9 @@ void Text::setBackdropOffset(float horizontal, float vertical) { _backdropHorizontalOffset = horizontal; _backdropVerticalOffset = vertical; + + assignStateSet(); + computeGlyphRepresentation(); } From fb0a995d7b7f8c2e9cb756ceec484470f1ceab9b Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 14:30:23 +0100 Subject: [PATCH 29/74] cleaned up exmple --- examples/osgfont/osgfont.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 7340a4251..460b6280d 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -161,7 +161,6 @@ struct TextSettings font->setMaxAnisotropy(maxAnisotropy); font->setGlyphInterval(glyphInterval); font->setGyphTextureFeatures(glyphTextureFeatures); - // text.setFont(font.get()); text.setColor(textColor); text.setBackdropType(backdropType); From 78811462f1c8651dbcf465379fd80323d0b6aa18 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 15:51:03 +0100 Subject: [PATCH 30/74] Added support for only enabling SignedDistanceField shader path when font resolution is greater than 16. --- include/osgText/Text | 2 -- src/osgText/Text.cpp | 17 +++++++++++----- src/osgText/TextBase.cpp | 3 +++ src/osgText/shaders/text_sdf_frag.cpp | 29 +++++++++++++++------------ 4 files changed, 31 insertions(+), 20 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index 0d991a805..fc6fbfc0f 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -278,8 +278,6 @@ protected: virtual osg::StateSet* createStateSet(); - void assignStateSet(); - Font* getActiveFont(); const Font* getActiveFont() const; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 665147bd7..efb9312a5 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -117,6 +117,18 @@ osg::StateSet* Text::createStateSet() defineList["SHADOW"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); } + + if (_fontSize.second>16) + { + OSG_NOTICE<<"Requesting SDF support _fontSize.second="<<_fontSize.second<=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" + "#ifdef SIGNED_DISTNACE_FIELD\n" + "\n" + " #if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #define SIGNED_DISTNACE_FIELD_SUPPORTED\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_SUPPORTED\n" + " #endif\n" " #endif\n" " #endif\n" - "#endif\n" "\n" + "#endif\n" "\n" "$OSG_PRECISION_FLOAT\n" "\n" @@ -63,7 +66,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "}\n" "\n" - "#ifdef USE_SIGNED_DISTNACE_FIELD\n" + "#ifdef USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" "vec4 distanceFieldColor()\n" "{\n" " float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" @@ -115,7 +118,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "void main(void)\n" "{\n" "\n" - "#ifdef USE_SIGNED_DISTNACE_FIELD\n" + "#ifdef USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" "\n" " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" "\n" From e565a5e1c310b344e1b2c3b3797b5c33b95b5f7e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 20 Sep 2017 16:51:30 +0100 Subject: [PATCH 31/74] Removed no longer used code paths --- src/osgText/Glyph.cpp | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index d418c5829..58f25aca4 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -327,16 +327,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float outline_distance = max_distance/3.0f; -#if 0 - // compute the alpha value of outline, one texel thick - unsigned char outline = center_value; - if (center_value<255) - { - if (min_distance Date: Thu, 21 Sep 2017 14:32:17 +0100 Subject: [PATCH 32/74] Umproved SDF computation. --- src/osgText/Glyph.cpp | 121 ++++++++++++++++++++++++++++-------------- 1 file changed, 80 insertions(+), 41 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 58f25aca4..4b0658a36 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -175,6 +175,11 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; + bool use_SDF_for_Outline = true; + + float outer_outline_distance = float(search_distance); + float inner_outline_distance = float(outer_outline_distance)/2.0f; + for(int dr=lower; dr<=upper; ++dr) { for(int dc=left; dc<=right; ++dc) @@ -184,11 +189,17 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) unsigned char center_value = 0; if (dr>=0 && dr=0 && dc0 && center_value<255) { + inner_max_value = 255; + outer_max_value = 255; + if (center_value_f>=0.5f) { min_distance = center_value_f-0.5f; @@ -204,7 +215,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) { for(int radius=1; radiusinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; + if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } { // top + int dx = span; + int dy = radius; + + int c = dc+dx; + int r = dr+dy; + + unsigned char local_value = 0; + if (r>=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); + + float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - 0.5f)*local_multiplier; + + if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; + if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; + } + } + + { + // right int dx = radius; int dy = span; @@ -249,42 +291,21 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float local_multiplier = (abs(dx)>abs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); float local_distance = sqrtf(float(radius*radius)+float(span*span)); + if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; else local_distance += (local_value_f - 0.5f)*local_multiplier; if (local_distance=0 && r=0 && cabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); - - float local_distance = sqrtf(float(radius*radius)+float(span*span)); - if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; - else local_distance += (local_value_f - 0.5f)*local_multiplier; - - if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; + if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } { // bottom - int dx = -radius; - int dy = -span; + int dx = span; + int dy = -radius; int c = dc+dx; int r = dr+dy; @@ -303,6 +324,9 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - 0.5f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; + if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } } @@ -329,16 +353,24 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) // compute the alpha value of outline, one texel thick unsigned char outline = 0; - if (center_value<255) + + if (use_SDF_for_Outline) { - float inner_outline = outline_distance-1.0f; - if (min_distancecenter_value) + { + outline -= center_value; + } } - if (outline>center_value) + else { - outline -= center_value; + outline = inner_max_value-center_value; } *(dest_ptr++) = outline; @@ -348,16 +380,23 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) // compute the alpha value of outline, one texel thick outline = 0; - if (center_value<255) + if (use_SDF_for_Outline) { - float inner_outline = outline_distance-1.0f; - if (min_distancecenter_value) + { + outline -= center_value; + } } - if (outline>center_value) + else { - outline -= center_value; + outline = outer_max_value-center_value; } *(dest_ptr++) = outline; From 957a7d4e9251962c0532881f770a8981b3bed71f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Sep 2017 14:35:31 +0100 Subject: [PATCH 33/74] Moved enabling/disabling of SDF so it's done regardless of whether a backdrop is used. --- src/osgText/Text.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index efb9312a5..c00cbb2eb 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -118,17 +118,17 @@ osg::StateSet* Text::createStateSet() defineList["SHADOW"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); } - if (_fontSize.second>16) - { - OSG_NOTICE<<"Requesting SDF support _fontSize.second="<<_fontSize.second<second; - OSG_NOTICE<<"DisplaySettings::getValue("< Date: Thu, 21 Sep 2017 15:52:07 +0100 Subject: [PATCH 35/74] Added support for toggling on use of the new SignedDistanceFunction function now built into osgText, just use --sdf to enable. --- examples/osglogo/osglogo.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 67d1eff5d..db0a4bff0 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -184,11 +184,6 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, text->setFont(font); text->setFontResolution(110,120); - if (s_useSDF) - { - text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); - text->setBackdropImplementation(osgText::Text::USE_SHADERS); - } text->setAlignment(osgText::Text::RIGHT_CENTER); text->setAxisAlignment(osgText::Text::XZ_PLANE); @@ -198,17 +193,23 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour - text->setText(label); - text->setBackdropType(osgText::Text::OUTLINE); text->setBackdropOffset(0.03f); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); + if (s_useSDF) + { + text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); + text->setBackdropImplementation(osgText::Text::USE_SHADERS); + } + text->setColorGradientMode(osgText::Text::OVERALL); osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f); osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f); text->setColorGradientCorners(lightblue, blue, blue, lightblue); + text->setText(label); + geode->addDrawable( text ); From 4b6722ab44bd87db9a75aa7169b89d016df50701 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Sep 2017 16:01:27 +0100 Subject: [PATCH 36/74] Added assignStateSet() to Text::setBackgroundColor() --- examples/osglogo/osglogo.cpp | 12 +++++++++--- src/osgText/Text.cpp | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index db0a4bff0..61526fb06 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -193,9 +193,7 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour - text->setBackdropType(osgText::Text::OUTLINE); - text->setBackdropOffset(0.03f); - text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); + OSG_NOTICE<setBackdropImplementation(osgText::Text::USE_SHADERS); } + OSG_NOTICE<setBackdropType(osgText::Text::OUTLINE); + text->setBackdropOffset(0.03f); + text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); + + OSG_NOTICE<setColorGradientMode(osgText::Text::OVERALL); osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f); osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 227976e28..d67f2dbf1 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1507,6 +1507,8 @@ void Text::setBackdropOffset(float horizontal, float vertical) void Text::setBackdropColor(const osg::Vec4& color) { _backdropColor = color; + + assignStateSet(); } void Text::setColorGradientMode(ColorGradientMode mode) From b6bb0caf8df5684e3bfc6819adae6b013edf3db5 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 21 Sep 2017 16:04:10 +0100 Subject: [PATCH 37/74] Removed debug output --- examples/osglogo/osglogo.cpp | 19 ++++++------------- src/osgText/Text.cpp | 2 +- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 61526fb06..9d02e6141 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -185,30 +185,23 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, text->setFont(font); text->setFontResolution(110,120); - text->setAlignment(osgText::Text::RIGHT_CENTER); - text->setAxisAlignment(osgText::Text::XZ_PLANE); - text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f); - - text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.1f)); - //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour - text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour - - OSG_NOTICE<getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); text->setBackdropImplementation(osgText::Text::USE_SHADERS); } - OSG_NOTICE<setAlignment(osgText::Text::RIGHT_CENTER); + text->setAxisAlignment(osgText::Text::XZ_PLANE); + text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f); + + text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.1f)); + text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour text->setBackdropType(osgText::Text::OUTLINE); text->setBackdropOffset(0.03f); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); - OSG_NOTICE<setColorGradientMode(osgText::Text::OVERALL); osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f); osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index d67f2dbf1..fea327527 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -131,7 +131,7 @@ osg::StateSet* Text::createStateSet() OSG_NOTICE<<"Disabling SDF support _fontSize.second="<<_fontSize.second< Date: Fri, 22 Sep 2017 08:39:38 +0200 Subject: [PATCH 38/74] addShader fix --- src/osgText/Text.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index fea327527..7b1afe6dc 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -204,14 +204,14 @@ osg::StateSet* Text::createStateSet() OSG_NOTICE<<"Using shaders/text_greyscale.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text_greyscale.frag", text_greyscale_frag)); + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "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)); + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text_sdf.frag", text_sdf_frag)); } return stateset.release(); From 708ae1c076f7552a531350980644a290458a7ed1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 22 Sep 2017 12:22:58 +0100 Subject: [PATCH 39/74] Fixed rendering old sytel outline --- src/osgText/Text.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 7b1afe6dc..b83557955 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1275,7 +1275,7 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo if(_backdropType == OUTLINE) { backdrop_index = 1; - max_backdrop_index = 8; + max_backdrop_index = backdrop_index+8; } else { From 6d4128324bff4dd2ba74952aec975a5506a38df0 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Sep 2017 10:42:47 +0100 Subject: [PATCH 40/74] Improvements to SDF and outline generation --- src/osgText/Glyph.cpp | 39 ++++++++++++++++++++++----------------- src/osgText/Text.cpp | 11 ++++++----- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 4b0658a36..e9236e41e 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -164,7 +164,8 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) int upper = glyph->t()+search_distance; float multiplier = 1.0/255.0f; - float max_distance = sqrtf(float(search_distance*search_distance)*2.0f); + + float max_distance = glyph->getFontResolution().first/4; int num_channels = TEXTURE_IMAGE_NUM_CHANNELS; @@ -177,8 +178,12 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) bool use_SDF_for_Outline = true; - float outer_outline_distance = float(search_distance); - float inner_outline_distance = float(outer_outline_distance)/2.0f; + float outer_outline_distance = float(glyph->getFontResolution().first)*0.14f; + float inner_outline_distance = outer_outline_distance*0.5f; + + unsigned char full_on = 255; + unsigned char mid_point = full_on/2; + float mid_point_f = float(mid_point)*multiplier; for(int dr=lower; dr<=upper; ++dr) { @@ -195,19 +200,19 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float center_value_f = center_value*multiplier; float min_distance = FLT_MAX; - if (center_value>0 && center_value<255) + if (center_value>0 && center_value=0.5f) + if (center_value_f>=mid_point_f) { - min_distance = center_value_f-0.5f; + min_distance = center_value_f-mid_point_f; value = 128+(min_distance/max_distance)*127; } else { - min_distance = 0.5f-center_value_f; + min_distance = mid_point_f-center_value_f; value = 127-(min_distance/max_distance)*127; } } @@ -235,8 +240,8 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float local_multiplier = (abs(dx)>abs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); float local_distance = sqrtf(float(radius*radius)+float(span*span)); - if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; - else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); float local_distance = sqrtf(float(radius*radius)+float(span*span)); - if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; - else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceabs(dy)) ? D/float(abs(dx)) : D/float(abs(dy)); float local_distance = sqrtf(float(radius*radius)+float(span*span)); - if (center_value==0) local_distance += (0.5f-local_value_f)*local_multiplier; - else local_distance += (local_value_f - 0.5f)*local_multiplier; + if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier; + else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distance8) + if (_fontSize.second>16/* && _backdropImplementation==USE_SHADERS*/) { OSG_NOTICE<<"Requesting SDF support _fontSize.second="<<_fontSize.second<getDefineList()==defineList) { - // OSG_NOTICE<<"Text::createStateSet() : Matched DefineList, return StateSet "<get()<get()<get(); } else @@ -159,7 +160,7 @@ osg::StateSet* Text::createStateSet() } } - // OSG_NOTICE<<"Text::createStateSet() : Not Matched DefineList, creating new StateSet"< stateset = new osg::StateSet; @@ -463,6 +464,8 @@ void Text::computeGlyphRepresentation() float hr = _characterHeight; float wr = hr/getCharacterAspectRatio(); + float texelMargin = 5.0f; + for(String::iterator itr=_text.begin(); itr!=_text.end(); ) @@ -630,8 +633,6 @@ void Text::computeGlyphRepresentation() osg::Vec2 maxtc = glyph->getMaxTexCoord(); osg::Vec2 vDiff = maxtc - mintc; - float texelMargin = 5.0f; - float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); From 845e1d446381fa3f4b34347f1f5403933a478419 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Sep 2017 10:44:14 +0100 Subject: [PATCH 41/74] Updated shaders using latest OpenSceneGraph-Data/shader versions --- src/osgText/shaders/text_greyscale_frag.cpp | 10 ++++++---- src/osgText/shaders/text_sdf_frag.cpp | 21 ++++++++++----------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/osgText/shaders/text_greyscale_frag.cpp b/src/osgText/shaders/text_greyscale_frag.cpp index cc1625bf7..6d561fbce 100644 --- a/src/osgText/shaders/text_greyscale_frag.cpp +++ b/src/osgText/shaders/text_greyscale_frag.cpp @@ -16,10 +16,12 @@ char text_greyscale_frag[] = "$OSG_GLSL_VERSION\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" + "#ifndef ALPHA\n" + " #if !defined(GL_ES) && __VERSION__>=130\n" + " #define ALPHA r\n" + " #else\n" + " #define ALPHA a\n" + " #endif\n" "#endif\n" "\n" "void main(void)\n" diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index 0db10880d..c357073e0 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -12,7 +12,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\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_SUPPORTED\n" + " #define SIGNED_DISTNACE_FIELD_SUPPORTED\n" " #endif\n" " #endif\n" " #endif\n" @@ -42,16 +42,15 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" "\n" - " #if 1\n" - " float blend_ratio = OUTLINE*17.0;\n" + " #ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" + " float blend_ratio = OUTLINE*20.0; // assume inner boundary starts at OUTLINE==0.05\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" + " float outline_alpha = (OUTLINE<=0.075) ? glyph.g : glyph.b;\n" " #endif\n" "\n" " float alpha = glyph.a+outline_alpha;\n" @@ -66,17 +65,17 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "}\n" "\n" - "#ifdef USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" + "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\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 blend_width = 0.005;\n" + " float distance_scale = 0.25;\n" " float edge_distance = (center_alpha-0.5)*distance_scale;\n" "\n" " #ifdef OUTLINE\n" - " float outline_width = OUTLINE*17.0;//0.5;\n" + " float outline_width = OUTLINE*0.5;;\n" " if (edge_distance>blend_width*0.5)\n" " {\n" " return vertexColor;\n" @@ -118,12 +117,12 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "void main(void)\n" "{\n" "\n" - "#ifdef USE_SIGNED_DISTNACE_FIELD_SUPPORTED\n" + "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" "\n" " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" "\n" " float near_transition = 0.0;\n" - " float far_transition = 1.0;\n" + " float far_transition = near_transition+1.0;\n" "\n" " vec4 color;\n" " if (mml Date: Tue, 26 Sep 2017 10:57:09 +0100 Subject: [PATCH 42/74] Updated wiht OpenSceneGraph-Data/shader version that introduced use of textureLOD to reduce aliasing artifacts with SDF --- src/osgText/shaders/text_sdf_frag.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index c357073e0..9f32c1e9a 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -25,9 +25,11 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#if __VERSION__>=130\n" " #define TEXTURE texture\n" + " #define TEXTURELOD textureLod\n" " out vec4 osg_FragColor;\n" "#else\n" " #define TEXTURE texture2D\n" + " #define TEXTURELOD texture2DLod\n" " #define osg_FragColor gl_FragColor\n" "#endif\n" "\n" @@ -68,7 +70,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" "vec4 distanceFieldColor()\n" "{\n" - " float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" + " float center_alpha = TEXTURELOD(glyphTexture, texCoord, 0.0).r;\n" "\n" " float blend_width = 0.005;\n" " float distance_scale = 0.25;\n" From 6ec9f0a3d35d979322c43c307a7e6c1dea83258d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Sep 2017 12:51:03 +0100 Subject: [PATCH 43/74] Updated shader from OpenSceneGraph-Data/shaders to add fade out for SDF and non SDF pathways --- src/osgText/shaders/text_sdf_frag.cpp | 50 ++++++++++++--------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index 9f32c1e9a..ea4b675ae 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -2,21 +2,15 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD )\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD\n" - "\n" - " #if !defined(GL_ES)\n" - " #if __VERSION__>=400\n" - " #define osg_TextureQueryLOD textureQueryLod\n" - " #define SIGNED_DISTNACE_FIELD_SUPPORTED\n" - " #else\n" - " #extension GL_ARB_texture_query_lod : enable\n" - " #ifdef GL_ARB_texture_query_lod\n" - " #define osg_TextureQueryLOD textureQueryLOD\n" - " #define SIGNED_DISTNACE_FIELD_SUPPORTED\n" - " #endif\n" + "#if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" " #endif\n" " #endif\n" - "\n" "#endif\n" "\n" "$OSG_PRECISION_FLOAT\n" @@ -44,16 +38,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " // glyph.rgba = (signed_distance, thin_outline, thick_outline, glyph_alpha)\n" " vec4 glyph = TEXTURE(glyphTexture, texCoord);\n" "\n" - " #ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" - " float blend_ratio = OUTLINE*20.0; // assume inner boundary starts at OUTLINE==0.05\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 = (OUTLINE<=0.075) ? glyph.g : glyph.b;\n" - " #endif\n" + " float outline_alpha = (OUTLINE<=0.1) ? glyph.g : glyph.b;\n" "\n" " float alpha = glyph.a+outline_alpha;\n" " if (alpha>1.0) alpha = 1.0;\n" @@ -67,17 +52,18 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "}\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" "vec4 distanceFieldColor()\n" "{\n" " float center_alpha = TEXTURELOD(glyphTexture, texCoord, 0.0).r;\n" + " //float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" "\n" " float blend_width = 0.005;\n" " float distance_scale = 0.25;\n" " float edge_distance = (center_alpha-0.5)*distance_scale;\n" "\n" " #ifdef OUTLINE\n" - " float outline_width = OUTLINE*0.5;;\n" + " float outline_width = OUTLINE*0.5;\n" " if (edge_distance>blend_width*0.5)\n" " {\n" " return vertexColor;\n" @@ -118,10 +104,18 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "void main(void)\n" "{\n" + " float near_fade_away = 2.0;\n" + " float far_fade_away = near_fade_away+5.0;\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD_SUPPORTED\n" - "\n" + "#ifdef osg_TextureQueryLOD\n" " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" + " if (mml>far_fade_away) discard;\n" + "#else\n" + " float mml = 0.0;\n" + "#endif\n" + "\n" + "\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" "\n" " float near_transition = 0.0;\n" " float far_transition = near_transition+1.0;\n" @@ -137,6 +131,8 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#endif\n" "\n" + " if (mml>near_fade_away) color.a *= (far_fade_away-mml)/(far_fade_away-near_fade_away);\n" + "\n" " if (color.a==0.0) discard;\n" "\n" " osg_FragColor = color;\n" From 8c575c0cea62bb0ab813acffad5bf330a93550d3 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 26 Sep 2017 15:32:41 +0100 Subject: [PATCH 44/74] UPdated from OpenSceneGraph-Data with handling of non textured text decoration --- examples/osgfont/osgfont.cpp | 93 +++++++++++++++++++++------ src/osgText/Font.cpp | 10 ++- src/osgText/shaders/text_sdf_frag.cpp | 7 ++ 3 files changed, 90 insertions(+), 20 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 460b6280d..b063325cf 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -74,7 +74,7 @@ struct TextSettings glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), - backdropOffset(0.04f, 0.04f), + backdropOffset(0.07f, 0.07f), backdropColor(0.0f, 0.0f, 0.0f, 1.0f), scaleFontSizeToFontResolution(false) { @@ -194,10 +194,8 @@ struct TextSettings bool scaleFontSizeToFontResolution; }; -osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size) +osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size, osg::Vec3& pos) { - static osg::Vec3 pos(10.0f, 10.0f, 0.0f); - osgText::Text* label = new osgText::Text(); settings.setText(*label); @@ -302,21 +300,52 @@ int main(int argc, char** argv) osg::ref_ptr root = new osg::Group; - bool ortho = args.read("--ortho"); - if (ortho) + bool split_screen = args.read("--split"); + + if (split_screen) { - osg::ref_ptr camera = createOrthoCamera(1280.0f, 1024.0f); - root->addChild(camera.get()); - root = camera; - } - else - { - osg::ref_ptr transform = new osg::MatrixTransform; - transform->setMatrix(osg::Matrixd::rotate(osg::DegreesToRadians(90.0), 1.0, 0.0, 0.0)); - root->addChild(transform.get()); - root = transform; + viewer.realize(); + + // quite an dirty divusion of the master Camera's window if one is assigned. + if (viewer.getCamera()->getGraphicsContext()) + { + viewer.stopThreading(); + + osg::ref_ptr gc = viewer.getCamera()->getGraphicsContext(); + osg::ref_ptr traits = gc->getTraits(); + + // left half + { + osg::ref_ptr camera = new osg::Camera; + camera->setCullMask(0x1); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(0,0, traits->width/2, traits->height)); + viewer.addSlave(camera.get(), osg::Matrixd::translate(1.0,0.0,0.0), osg::Matrixd::scale(2.0, 1.0, 1.0)); + } + + { + osg::ref_ptr camera = new osg::Camera; + camera->setCullMask(0x2); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(traits->width/2+2,0, traits->width/2, traits->height)); + viewer.addSlave(camera.get(), osg::Matrixd::translate(-1.0,0.0,0.0), osg::Matrixd::scale(2.0, 1.0, 1.0)); + } + + viewer.getCamera()->setGraphicsContext(0); + + viewer.startThreading(); + } + else + { + split_screen = false; + } } + osg::ref_ptr transform = new osg::MatrixTransform; + transform->setMatrix(osg::Matrixd::rotate(osg::DegreesToRadians(90.0), 1.0, 0.0, 0.0)); + root->addChild(transform.get()); + root = transform; + osg::ref_ptr program = new osg::Program; std::string shaderFilename; while(args.read("--shader", shaderFilename)) @@ -363,7 +392,9 @@ int main(int argc, char** argv) settings.sizes.push_back(64); } - osg::Geode* geode = new osg::Geode(); + osg::ref_ptr geode = new osg::Geode(); + + osg::Vec3 pos(0.0f, 0.0f, 0.0f); // Add all of our osgText drawables. for(Sizes::const_iterator i = settings.sizes.begin(); i != settings.sizes.end(); i++) @@ -372,10 +403,34 @@ int main(int argc, char** argv) ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - geode->addDrawable(createLabel(ss.str(), settings, *i)); + geode->addDrawable(createLabel(ss.str(), settings, *i, pos)); + } + + root->addChild(geode.get()); + + if (split_screen) + { + geode->setNodeMask(0x1); + + osg::ref_ptr right_geode = new osg::Geode; + right_geode->setNodeMask(0x2); + + settings.glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; + + pos.set(0.0f, 0.0f, 0.0f); + + for(Sizes::const_iterator i = settings.sizes.begin(); i != settings.sizes.end(); i++) + { + std::stringstream ss; + + ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + right_geode->addDrawable(createLabel(ss.str(), settings, *i, pos)); + } + + root->addChild(right_geode); } - root->addChild(geode); if (!outputFilename.empty()) { diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index c1aa0e077..b8ae6ef1d 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -243,7 +243,7 @@ Font::Font(FontImplementation* implementation): setImplementation(implementation); char *ptr; - if( (ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0) + if ((ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0) { unsigned int osg_max_size = atoi(ptr); @@ -251,6 +251,14 @@ Font::Font(FontImplementation* implementation): if (osg_max_size<_textureHeightHint) _textureHeightHint = osg_max_size; } + if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + { + _glyphTextureFeatures = GlyphTexture::ALL_FEATURES; + } + else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) + { + _glyphTextureFeatures = GlyphTexture::GREYSCALE; + } } Font::~Font() diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index ea4b675ae..fde9f406d 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -104,6 +104,13 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "void main(void)\n" "{\n" + " if (texCoord.x<0.0 && texCoord.y<0.0)\n" + " {\n" + " osg_FragColor = vertexColor;\n" + " return;\n" + " }\n" + "\n" + "\n" " float near_fade_away = 2.0;\n" " float far_fade_away = near_fade_away+5.0;\n" "\n" From 75d23b2c10936e20e2f4b9234db0b329e4b4e22e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 27 Sep 2017 11:09:22 +0100 Subject: [PATCH 45/74] Fixed update of GlyphTexture Image when copying new Glyph image's to it. --- src/osgText/Glyph.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index e9236e41e..25d9764cd 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -137,16 +137,16 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) void GlyphTexture::copyGlyphImage(Glyph* glyph) { + _image->dirty(); if (_glyphTextureFeatures==GREYSCALE) { - // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copy"<setText(str.str()); @@ -670,7 +670,7 @@ int main(int argc, char** argv) text->setUpdateCallback(new TextCounterCallback()); text->setFont("fonts/times.ttf"); text->setAxisAlignment(osgText::Text::XZ_PLANE); - text->setText("This is a counter test"); + text->setText("Text Counter :"); viewer.setSceneData(text.get()); } From 468d6d8eeaff2959421ec93403af202f0a13aa93 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 29 Sep 2017 10:20:59 +0100 Subject: [PATCH 47/74] Added command line support for specifying "default" for osgText::DefaultFont --- examples/osgfont/osgfont.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index b063325cf..f17a0ed9a 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -152,7 +152,11 @@ struct TextSettings { OSG_NOTICE<<"Settings::setText()"< font = osgText::readRefFontFile(fontFilename); + osg::ref_ptr font; + + if (fontFilename!="default") font = osgText::readRefFontFile(fontFilename); + + if (!font) font = osgText::Font::getDefaultFont(); font->setGlyphImageMargin(glyphImageMargin); font->setGlyphImageMarginRatio(glyphImageMarginRatio); From 1f36f5bd8d032dc0dd423a5ec404ec1951777e3c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 29 Sep 2017 10:25:04 +0100 Subject: [PATCH 48/74] Added setting of the FontResolution of the DefaultFont --- src/osgText/DefaultFont.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index cf0b55cc4..1dc251f68 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -24,8 +24,15 @@ using namespace osgText; DefaultFont::DefaultFont() { + _fontSize = FontResolution(8,12); + _minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR; _magFilterHint = osg::Texture::NEAREST; + + _margin = 8; + _marginRatio = 0.0; + _glyphInterval = 16; + constructGlyphs(); } @@ -233,6 +240,8 @@ void DefaultFont::constructGlyphs() glyph->setVerticalBearing(osg::Vec2(0.5f,1.0f)); // top middle. glyph->setVerticalAdvance(sourceHeight*coord_scale); + glyph->setFontResolution(fontRes); + addGlyph(fontRes,i,glyph.get()); } } From beb5801eeeb902038351a1ce6ff58a7cba928e06 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 29 Sep 2017 10:39:02 +0100 Subject: [PATCH 49/74] Improved SDF generation --- src/osgText/Glyph.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 25d9764cd..b0eac3ec8 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -156,7 +156,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) int dest_rows = _image->t(); unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY()); - int search_distance = glyph->getFontResolution().second/8; + int search_distance = glyph->getFontResolution().second/4; int left = -search_distance; int right = glyph->s()+search_distance; @@ -165,7 +165,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float multiplier = 1.0/255.0f; - float max_distance = glyph->getFontResolution().first/4; + float max_distance = sqrtf(float(search_distance)*float(search_distance)*2.0); int num_channels = TEXTURE_IMAGE_NUM_CHANNELS; @@ -175,10 +175,9 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) if ((lower+glyph->getTexturePositionY())<0) lower = -glyph->getTexturePositionY(); if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; - bool use_SDF_for_Outline = true; - float outer_outline_distance = float(glyph->getFontResolution().first)*0.14f; + float outer_outline_distance = float(glyph->getFontResolution().first)*0.1f; float inner_outline_distance = outer_outline_distance*0.5f; unsigned char full_on = 255; @@ -198,7 +197,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) unsigned char outer_max_value = center_value; float center_value_f = center_value*multiplier; - float min_distance = FLT_MAX; + float min_distance = max_distance; if (center_value>0 && center_value Date: Fri, 29 Sep 2017 20:21:13 +0100 Subject: [PATCH 50/74] Simplified and improved the glyph margin computation and usage --- examples/osgfont/osgfont.cpp | 17 --------- include/osgText/Font | 21 +---------- include/osgText/Glyph | 24 +++++-------- src/osgPlugins/freetype/FreeTypeFont.cpp | 13 ------- src/osgText/DefaultFont.cpp | 3 -- src/osgText/Font.cpp | 32 ----------------- src/osgText/Glyph.cpp | 44 +++++++++++++++++------- src/osgText/Text.cpp | 3 +- 8 files changed, 41 insertions(+), 116 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index f17a0ed9a..b39b19b59 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -68,9 +68,6 @@ struct TextSettings minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), magFilter(osg::Texture::LINEAR), maxAnisotropy(16.0f), - glyphImageMargin(1), - glyphImageMarginRatio(0.02), - glyphInterval(1), glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), @@ -118,10 +115,6 @@ struct TextSettings if (arguments.read("--anisotropy",maxAnisotropy)) {} - if (arguments.read("--margin", glyphImageMargin)) {} - if (arguments.read("--margin-ratio", glyphImageMarginRatio)) {} - if (arguments.read("--interval", glyphInterval)) {} - if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; @@ -158,12 +151,9 @@ struct TextSettings if (!font) font = osgText::Font::getDefaultFont(); - font->setGlyphImageMargin(glyphImageMargin); - font->setGlyphImageMarginRatio(glyphImageMarginRatio); font->setMinFilterHint(minFilter); font->setMagFilterHint(magFilter); font->setMaxAnisotropy(maxAnisotropy); - font->setGlyphInterval(glyphInterval); font->setGyphTextureFeatures(glyphTextureFeatures); text.setColor(textColor); @@ -184,9 +174,6 @@ struct TextSettings osg::Texture::FilterMode minFilter; osg::Texture::FilterMode magFilter; float maxAnisotropy; - unsigned int glyphImageMargin; - float glyphImageMarginRatio; - int glyphInterval; osgText::GlyphTexture::Features glyphTextureFeatures; osg::Vec4 textColor; @@ -204,22 +191,18 @@ osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigne settings.setText(*label); - if (settings.scaleFontSizeToFontResolution) { label->setCharacterSize(size); } - label->setFontResolution(size, size); label->setPosition(pos); label->setAlignment(osgText::Text::LEFT_BOTTOM); - // It seems to be important we do this last to get best results? label->setText(l); - // textInfo(label); pos.y() += label->getCharacterHeight()*2.0; diff --git a/include/osgText/Font b/include/osgText/Font index 7b7fd0186..0af593b91 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -107,23 +107,6 @@ public: * return true on success, return false when not supported.*/ virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; } - /** Set the margin around each glyph, - * to ensure that texture filtering doesn't bleed adjacent glyph's into each other. - * Default margin is 1 texels.*/ - void setGlyphImageMargin(unsigned int margin); - unsigned int getGlyphImageMargin() const; - - /** Set the margin ratio around each glyph, relative to the glyph's size. - * to ensure that texture filtering doesn't bleed adjacent glyph's into each other. - * Default margin is 0.05.*/ - void setGlyphImageMarginRatio(float margin); - float getGlyphImageMarginRatio() const; - - /** Set the interval that glyph positions are clamped to. - * Default interval is 1 texels.*/ - void setGlyphInterval(int interval); - int getGlyphInterval() const; - void setGyphTextureFeatures(GlyphTexture::Features features) { _glyphTextureFeatures = features; } GlyphTexture::Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } @@ -202,9 +185,7 @@ protected: // current active size of font FontResolution _fontSize; - unsigned int _margin; - float _marginRatio; - int _glyphInterval; + GlyphTexture::Features _glyphTextureFeatures; unsigned int _textureWidthHint; diff --git a/include/osgText/Glyph b/include/osgText/Glyph index 8dac38051..fb842eb8b 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -93,6 +93,9 @@ public: void setMaxTexCoord(const osg::Vec2& coord); const osg::Vec2& getMaxTexCoord() const; + void setTexelMargin(float margin) { _texelMargin = margin; } + float getTexelMargin() const { return _texelMargin; } + protected: virtual ~Glyph(); @@ -116,6 +119,7 @@ protected: int _texturePosY; osg::Vec2 _minTexCoord; osg::Vec2 _maxTexCoord; + float _texelMargin; typedef osg::buffered_value GLObjectList; mutable GLObjectList _globjList; @@ -256,16 +260,6 @@ public: /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ virtual int compare(const osg::StateAttribute& rhs) const; - /** Set the margin around each glyph, to ensure that texture filtering doesn't bleed adjacent glyph's into each other.*/ - void setGlyphImageMargin(unsigned int margin) { _margin = margin; } - unsigned int getGlyphImageMargin() const { return _margin; } - - void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; } - float getGlyphImageMarginRatio() const { return _marginRatio; } - - void setGlyphInterval(int interval) { _interval = interval; } - int getGlyphInterval() const { return _interval; } - enum Features { GREYSCALE, @@ -277,6 +271,10 @@ public: void setGlyphTextureFeatures(Features features) { _glyphTextureFeatures = features; } Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + + int getEffectMargin(const Glyph* glyph); + int getTexelMargin(const Glyph* glyph); + bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY); void addGlyph(Glyph* glyph,int posX, int posY); @@ -296,12 +294,6 @@ protected: void copyGlyphImage(Glyph* glyph); - - // parameter used to compute the size and position of empty space - // in the texture which could accommodate new glyphs. - int _margin; - float _marginRatio; - int _interval; Features _glyphTextureFeatures; int _usedY; diff --git a/src/osgPlugins/freetype/FreeTypeFont.cpp b/src/osgPlugins/freetype/FreeTypeFont.cpp index 5d7aee6e9..323a874b6 100644 --- a/src/osgPlugins/freetype/FreeTypeFont.cpp +++ b/src/osgPlugins/freetype/FreeTypeFont.cpp @@ -278,19 +278,6 @@ void FreeTypeFont::setFontResolution(const osgText::FontResolution& fontSize) int width = fontSize.first; int height = fontSize.second; - int maxAxis = std::max(width, height); - int margin = _facade->getGlyphImageMargin() + (int)((float)maxAxis * _facade->getGlyphImageMarginRatio()); - - if ((unsigned int)(width+2*margin) > _facade->getTextureWidthHint() || - (unsigned int)(width+2*margin) > _facade->getTextureHeightHint()) - { - OSG_WARN<<"Warning: FreeTypeFont::setSize("<getTextureWidthHint()-2*margin; - height = _facade->getTextureHeightHint()-2*margin; - - OSG_WARN<<" sizes capped ("< osgText::readRefFontStream(std::istream& stream, const osgDB: Font::Font(FontImplementation* implementation): osg::Object(true), - _margin(1), - _marginRatio(0.02), - _glyphInterval(1), #if 0 _glyphTextureFeatures(GlyphTexture::ALL_FEATURES), #else @@ -289,32 +286,6 @@ std::string Font::getFileName() const return std::string(); } -void Font::setGlyphImageMargin(unsigned int margin) -{ - _margin = margin; -} - -unsigned int Font::getGlyphImageMargin() const -{ - return _margin; -} - -void Font::setGlyphImageMarginRatio(float ratio) -{ - _marginRatio = ratio; -} - -float Font::getGlyphImageMarginRatio() const -{ - return _marginRatio; -} - -void Font::setGlyphInterval(int interval) -{ - _glyphInterval = interval; -} - - void Font::setTextureSizeHint(unsigned int width,unsigned int height) { _textureWidthHint = width; @@ -514,9 +485,6 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<setGlyphImageMargin(_margin); - glyphTexture->setGlyphImageMarginRatio(_marginRatio); - glyphTexture->setGlyphInterval(_glyphInterval); glyphTexture->setGlyphTextureFeatures(_glyphTextureFeatures); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index b0eac3ec8..4953c2913 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -37,9 +37,6 @@ using namespace std; #endif GlyphTexture::GlyphTexture(): - _margin(1), - _marginRatio(0.02f), - _interval(1), _usedY(0), _partUsedX(0), _partUsedY(0) @@ -60,21 +57,39 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const return 0; } +int GlyphTexture::getEffectMargin(const Glyph* glyph) +{ + if (_glyphTextureFeatures==GREYSCALE) return 0; + else return glyph->getFontResolution().second/4; +} + +int GlyphTexture::getTexelMargin(const Glyph* glyph) +{ + int width = glyph->s(); + int height = glyph->t(); + int effect_margin = getEffectMargin(glyph); + + int max_dimension = std::max(width, height) + 2 * effect_margin; + int margin = osg::maximum(max_dimension/4, 2) + effect_margin; + + return margin; +} bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) { - int maxAxis = osg::maximum(glyph->s(), glyph->t()); - int margin_from_ratio = (int)((float)maxAxis * _marginRatio); - int search_distance = glyph->getFontResolution().second/8; + int width = glyph->s(); + int height = glyph->t(); - int margin = _margin + osg::maximum(margin_from_ratio, search_distance); + int margin = getTexelMargin(glyph); - int width = glyph->s()+2*margin; - int height = glyph->t()+2*margin; + width += 2*margin; + height += 2*margin; - int partUsedX = ((_partUsedX % _interval) == 0) ? _partUsedX : (((_partUsedX/_interval)+1)*_interval); - int partUsedY = ((_partUsedY % _interval) == 0) ? _partUsedY : (((_partUsedY/_interval)+1)*_interval); - int usedY = ((_usedY % _interval) == 0) ? _usedY : (((_usedY/_interval)+1)*_interval); + int interval = 4; + + int partUsedX = ((_partUsedX % interval) == 0) ? _partUsedX : (((_partUsedX/interval)+1)*interval); + int partUsedY = ((_partUsedY % interval) == 0) ? _partUsedY : (((_partUsedY/interval)+1)*interval); + int usedY = ((_usedY % interval) == 0) ? _usedY : (((_usedY/interval)+1)*interval); // first check box (partUsedX, usedY) to (width,height) if (width <= (getTextureWidth()-partUsedX) && @@ -132,6 +147,9 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) glyph->setMaxTexCoord( osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ) ); + + glyph->setTexelMargin(float(getTexelMargin(glyph))); + copyGlyphImage(glyph); } @@ -156,7 +174,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) int dest_rows = _image->t(); unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY()); - int search_distance = glyph->getFontResolution().second/4; + int search_distance = getEffectMargin(glyph); int left = -search_distance; int right = glyph->s()+search_distance; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index c9062386f..3e7e1f49a 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -464,8 +464,6 @@ void Text::computeGlyphRepresentation() float hr = _characterHeight; float wr = hr/getCharacterAspectRatio(); - float texelMargin = 5.0f; - for(String::iterator itr=_text.begin(); itr!=_text.end(); ) @@ -632,6 +630,7 @@ void Text::computeGlyphRepresentation() osg::Vec2 mintc = glyph->getMinTexCoord(); osg::Vec2 maxtc = glyph->getMaxTexCoord(); osg::Vec2 vDiff = maxtc - mintc; + float texelMargin = glyph->getTexelMargin(); float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); From 2f19cd4b87bb202c9aaf277cf3e6868a512ac593 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 4 Oct 2017 18:06:42 +0100 Subject: [PATCH 51/74] Improvements to the Signed Distance Field implementation. --- src/osgText/DefaultFont.cpp | 7 +- src/osgText/Glyph.cpp | 4 +- src/osgText/Text.cpp | 34 ++-- src/osgText/shaders/text_sdf_frag.cpp | 216 ++++++++++++++++---------- 4 files changed, 166 insertions(+), 95 deletions(-) diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index ad7036b2b..cf3669cef 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -27,8 +27,13 @@ DefaultFont::DefaultFont() _fontSize = FontResolution(8,12); _minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR; - _magFilterHint = osg::Texture::NEAREST; + _magFilterHint = osg::Texture::LINEAR; + char *ptr; + if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + { + _glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; + } constructGlyphs(); } diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 4953c2913..e8a11ea87 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -60,7 +60,9 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const int GlyphTexture::getEffectMargin(const Glyph* glyph) { if (_glyphTextureFeatures==GREYSCALE) return 0; - else return glyph->getFontResolution().second/4; +// else return glyph->getFontResolution().second/4; + else return osg::maximum(glyph->getFontResolution().second/6, 2u); +// else return osg::maximum(glyph->getFontResolution().second/8,1u); } int GlyphTexture::getTexelMargin(const Glyph* glyph) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 3e7e1f49a..23d146372 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -47,6 +47,17 @@ Text::Text(): { _supportsVertexBufferObjects = true; + char *ptr; + if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + { + _backdropImplementation = USE_SHADERS; + } + else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) + { + _backdropImplementation = DELAYED_DEPTH_WRITES; + } + + assignStateSet(); } @@ -80,11 +91,10 @@ osg::StateSet* Text::createStateSet() Font::StateSets& statesets = activeFont->getCachedStateSets(); + std::stringstream ss; osg::StateSet::DefineList defineList; if (_backdropType!=NONE && _backdropImplementation==USE_SHADERS) { - std::stringstream ss; - ss.str(""); ss << "vec4("<<_backdropColor.r()<<", "<<_backdropColor.g()<<", "<<_backdropColor.b()<<", "<<_backdropColor.a()<<")"; @@ -122,15 +132,19 @@ osg::StateSet* Text::createStateSet() } - if (_fontSize.second>16/* && _backdropImplementation==USE_SHADERS*/) + if (activeFont->getGlyphTextureFeatures()!=GlyphTexture::GREYSCALE) { - OSG_NOTICE<<"Requesting SDF support _fontSize.second="<<_fontSize.second<getTextureWidthHint(); + defineList["TEXTURE_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); + defineList["SIGNED_DISTNACE_FIELD"] = osg::StateSet::DefinePair("1", osg::StateAttribute::ON); } - else - { - OSG_NOTICE<<"Disabling SDF support _fontSize.second="<<_fontSize.second<get()<get()<get(); } else @@ -180,7 +194,7 @@ osg::StateSet* Text::createStateSet() osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) { - OSG_INFO<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); return stateset.release(); diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index fde9f406d..fa2ed3c10 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -1,21 +1,17 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" - "#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD )\n" + "#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" "\n" - "#if !defined(GL_ES)\n" - " #if __VERSION__>=400\n" - " #define osg_TextureQueryLOD textureQueryLod\n" - " #else\n" - " #extension GL_ARB_texture_query_lod : enable\n" - " #ifdef GL_ARB_texture_query_lod\n" - " #define osg_TextureQueryLOD textureQueryLOD\n" - " #endif\n" + "#ifdef GL_ES\n" + " #extension GL_OES_standard_derivatives : enable\n" + " #ifndef GL_OES_standard_derivatives\n" + " #undef SIGNED_DISTNACE_FIELD\n" " #endif\n" "#endif\n" "\n" "$OSG_PRECISION_FLOAT\n" "\n" - "//#undef USE_SIGNED_DISTNACE_FIELD\n" + "#undef SIGNED_DISTNACE_FIELD\n" "\n" "#if __VERSION__>=130\n" " #define TEXTURE texture\n" @@ -32,13 +28,138 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "$OSG_VARYING_IN vec2 texCoord;\n" "$OSG_VARYING_IN vec4 vertexColor;\n" "\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" + "\n" + "float distanceFromEdge(vec2 tc)\n" + "{\n" + " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).r;\n" + " if (center_alpha==0.0) return -1.0;\n" + "\n" + " //float distance_scale = (1.0/4.0)*1.41;\n" + " float distance_scale = (1.0/6.0)*1.41;\n" + " //float distance_scale = (1.0/8.0)*1.41;\n" + "\n" + " return (center_alpha-0.5)*distance_scale;\n" + "}\n" + "\n" + "vec4 distanceFieldColorSample(float edge_distance, float blend_width, float blend_half_width)\n" + "{\n" + "#ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if (edge_distance>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return mix(vertexColor, BACKDROP_COLOR, smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else if (edge_distance>(blend_half_width-outline_width))\n" + " {\n" + " return BACKDROP_COLOR;\n" + " }\n" + " else if (edge_distance>-(outline_width+blend_half_width))\n" + " {\n" + " return vec4(BACKDROP_COLOR.rgb, ((blend_half_width+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>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return vec4(vertexColor.rgb, smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "#endif\n" + "}\n" + "\n" + "vec4 distanceFieldColor()\n" + "{\n" + " float sample_distance_scale = 0.75;\n" + " vec2 dx = dFdx(texCoord)*sample_distance_scale;\n" + " vec2 dy = dFdy(texCoord)*sample_distance_scale;\n" + "\n" + " #ifndef TEXTURE_DIMENSION\n" + " float TEXTURE_DIMENSION = 1024.0;\n" + " #endif\n" + "\n" + " #ifndef GLYPH_DIMENSION\n" + " float GLYPH_DIMENSION = 32.0;\n" + " #endif\n" + "\n" + " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" + "\n" + " // compute the appropriate number of samples required to avoid aliasing.\n" + " int maxNumSamplesAcrossSide = 4;\n" + "\n" + " int numSamplesX = int(TEXTURE_DIMENSION * length(dx));\n" + " int numSamplesY = int(TEXTURE_DIMENSION * length(dy));\n" + " if (numSamplesX<2) numSamplesX = 2;\n" + " if (numSamplesY<2) numSamplesY = 2;\n" + " if (numSamplesX>maxNumSamplesAcrossSide) numSamplesX = maxNumSamplesAcrossSide;\n" + " if (numSamplesY>maxNumSamplesAcrossSide) numSamplesY = maxNumSamplesAcrossSide;\n" + "\n" + "\n" + " vec2 delta_tx = dx/float(numSamplesX-1);\n" + " vec2 delta_ty = dy/float(numSamplesY-1);\n" + "\n" + " float numSamples = float(numSamplesX)*float(numSamplesY);\n" + " float scale = 1.0/numSamples;\n" + " vec4 total_color = vec4(0.0,0.0,0.0,0.0);\n" + "\n" + " float blend_width = 1.5*distance_across_pixel/numSamples;\n" + " float blend_half_width = blend_width*0.5;\n" + "\n" + " // check whether fragment is wholly within or outwith glyph body+outline\n" + " float cd = distanceFromEdge(texCoord); // central distance (distance from center to edge)\n" + " if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n" + "\n" + " #ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if ((-cd-outline_width-blend_half_width)>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside outline+glyph body\n" + " #else\n" + " if (-cd-blend_half_width>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside glyph body\n" + " #endif\n" + "\n" + "\n" + " // use multi-sampling to provide high quality antialised fragments\n" + " vec2 origin = texCoord - dx*0.5 - dy*0.5;\n" + " for(;numSamplesY>0; --numSamplesY)\n" + " {\n" + " vec2 pos = origin;\n" + " int numX = numSamplesX;\n" + " for(;numX>0; --numX)\n" + " {\n" + " vec4 c = distanceFieldColorSample(distanceFromEdge(pos), blend_width, blend_half_width);\n" + " total_color = total_color + c * c.a;\n" + " pos += delta_tx;\n" + " }\n" + " origin += delta_ty;\n" + " }\n" + "\n" + " total_color.rgb /= total_color.a;\n" + " total_color.a *= scale;\n" + "\n" + " return total_color;\n" + "}\n" + "#else\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" - " float outline_alpha = (OUTLINE<=0.1) ? glyph.g : glyph.b;\n" + " float outline_alpha = (OUTLINE<=0.05) ? glyph.g : glyph.b;\n" "\n" " float alpha = glyph.a+outline_alpha;\n" " if (alpha>1.0) alpha = 1.0;\n" @@ -52,53 +173,6 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "}\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD\n" - "vec4 distanceFieldColor()\n" - "{\n" - " float center_alpha = TEXTURELOD(glyphTexture, texCoord, 0.0).r;\n" - " //float center_alpha = TEXTURE(glyphTexture, texCoord).r;\n" - "\n" - " float blend_width = 0.005;\n" - " float distance_scale = 0.25;\n" - " float edge_distance = (center_alpha-0.5)*distance_scale;\n" - "\n" - " #ifdef OUTLINE\n" - " float outline_width = OUTLINE*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" @@ -110,36 +184,12 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " return;\n" " }\n" "\n" - "\n" - " float near_fade_away = 2.0;\n" - " float far_fade_away = near_fade_away+5.0;\n" - "\n" - "#ifdef osg_TextureQueryLOD\n" - " float mml = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" - " if (mml>far_fade_away) discard;\n" - "#else\n" - " float mml = 0.0;\n" - "#endif\n" - "\n" - "\n" "#ifdef SIGNED_DISTNACE_FIELD\n" - "\n" - " float near_transition = 0.0;\n" - " float far_transition = near_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" + " vec4 color = distanceFieldColor();\n" "#else\n" - "\n" " vec4 color = textureColor();\n" - "\n" "#endif\n" "\n" - " if (mml>near_fade_away) color.a *= (far_fade_away-mml)/(far_fade_away-near_fade_away);\n" - "\n" " if (color.a==0.0) discard;\n" "\n" " osg_FragColor = color;\n" From eebb679754796742f2330520bf2f98e5f3623e1a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 12 Oct 2017 11:12:47 +0100 Subject: [PATCH 52/74] Updated text_sdf_frag.cpp from OpenSceneGraph-Data changes that add outline generation for non SIGNED_DISTANCE_FIELD text. --- src/osgText/shaders/text_sdf_frag.cpp | 81 ++++++++++++++++++++------- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index fa2ed3c10..90bd739ab 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -9,9 +9,18 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " #endif\n" "#endif\n" "\n" - "$OSG_PRECISION_FLOAT\n" + "#if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" + " #endif\n" + " #endif\n" + "#endif\n" "\n" - "#undef SIGNED_DISTNACE_FIELD\n" + "$OSG_PRECISION_FLOAT\n" "\n" "#if __VERSION__>=130\n" " #define TEXTURE texture\n" @@ -28,6 +37,14 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "$OSG_VARYING_IN vec2 texCoord;\n" "$OSG_VARYING_IN vec4 vertexColor;\n" "\n" + "#ifndef TEXTURE_DIMENSION\n" + "const float TEXTURE_DIMENSION = 1024.0;\n" + "#endif\n" + "\n" + "#ifndef GLYPH_DIMENSION\n" + "const float GLYPH_DIMENSION = 32.0;\n" + "#endif\n" + "\n" "#ifdef SIGNED_DISTNACE_FIELD\n" "\n" "float distanceFromEdge(vec2 tc)\n" @@ -88,13 +105,6 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " vec2 dx = dFdx(texCoord)*sample_distance_scale;\n" " vec2 dy = dFdy(texCoord)*sample_distance_scale;\n" "\n" - " #ifndef TEXTURE_DIMENSION\n" - " float TEXTURE_DIMENSION = 1024.0;\n" - " #endif\n" - "\n" - " #ifndef GLYPH_DIMENSION\n" - " float GLYPH_DIMENSION = 32.0;\n" - " #endif\n" "\n" " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" "\n" @@ -151,26 +161,57 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" " return total_color;\n" "}\n" + "\n" "#else\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" + " float alpha = TEXTURE(glyphTexture, texCoord).a;\n" "\n" - " float outline_alpha = (OUTLINE<=0.05) ? glyph.g : glyph.b;\n" + "#ifdef OUTLINE\n" "\n" - " float alpha = glyph.a+outline_alpha;\n" - " if (alpha>1.0) alpha = 1.0;\n" + " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" "\n" - " return vec4( vertexColor.rgb*glyph.a + BACKDROP_COLOR.rgb*outline_alpha, alpha);\n" + " float outline_alpha = alpha;\n" + " vec2 origin = texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\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" + " float numSamples = 3.0;\n" + " delta_tc = delta_tc/(numSamples-1);\n" + "\n" + " float background_alpha = 1.0;\n" + "\n" + " for(float i=0.0; i1.0) outline_alpha = 1.0;\n" + "\n" + " if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline\n" + "\n" + " vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));\n" + " color.a = smoothstep(0.0, 1.0, outline_alpha);\n" + "\n" + " return color;\n" + "\n" + "#else\n" + " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" + " return vec4(vertexColor.rgb, vertexColor.a * alpha);\n" + "#endif\n" "}\n" "\n" "#endif\n" From 846204ed9e5a4f855fad23afbd1f25bc0923a229 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 12 Oct 2017 18:45:38 +0100 Subject: [PATCH 53/74] Updated from OpenSceneGraph-Data/shaders/text_sdf.frag to add support for SHADOW --- src/osgText/shaders/text_sdf_frag.cpp | 35 +++++++++++++++++---------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/osgText/shaders/text_sdf_frag.cpp b/src/osgText/shaders/text_sdf_frag.cpp index 90bd739ab..567e6a1bc 100644 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ b/src/osgText/shaders/text_sdf_frag.cpp @@ -1,6 +1,6 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" - "#pragma import_defines( BACKDROP_COLOR, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" + "#pragma import_defines( BACKDROP_COLOR, SHADOW, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" "\n" "#ifdef GL_ES\n" " #extension GL_OES_standard_derivatives : enable\n" @@ -99,11 +99,11 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "#endif\n" "}\n" "\n" - "vec4 distanceFieldColor()\n" + "vec4 textColor(vec2 src_texCoord)\n" "{\n" " float sample_distance_scale = 0.75;\n" - " vec2 dx = dFdx(texCoord)*sample_distance_scale;\n" - " vec2 dy = dFdy(texCoord)*sample_distance_scale;\n" + " vec2 dx = dFdx(src_texCoord)*sample_distance_scale;\n" + " vec2 dy = dFdy(src_texCoord)*sample_distance_scale;\n" "\n" "\n" " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" @@ -130,7 +130,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " float blend_half_width = blend_width*0.5;\n" "\n" " // check whether fragment is wholly within or outwith glyph body+outline\n" - " float cd = distanceFromEdge(texCoord); // central distance (distance from center to edge)\n" + " float cd = distanceFromEdge(src_texCoord); // central distance (distance from center to edge)\n" " if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n" "\n" " #ifdef OUTLINE\n" @@ -142,7 +142,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "\n" " // use multi-sampling to provide high quality antialised fragments\n" - " vec2 origin = texCoord - dx*0.5 - dy*0.5;\n" + " vec2 origin = src_texCoord - dx*0.5 - dy*0.5;\n" " for(;numSamplesY>0; --numSamplesY)\n" " {\n" " vec2 pos = origin;\n" @@ -164,16 +164,16 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#else\n" "\n" - "vec4 textureColor()\n" + "vec4 textColor(vec2 src_texCoord)\n" "{\n" - " float alpha = TEXTURE(glyphTexture, texCoord).a;\n" "\n" "#ifdef OUTLINE\n" "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).a;\n" " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" "\n" " float outline_alpha = alpha;\n" - " vec2 origin = texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" + " vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" "\n" " float numSamples = 3.0;\n" " delta_tc = delta_tc/(numSamples-1);\n" @@ -191,7 +191,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " }\n" "\n" " #ifdef osg_TextureQueryLOD\n" - " float mipmapLevel = osg_TextureQueryLOD(glyphTexture, texCoord).x;\n" + " float mipmapLevel = osg_TextureQueryLOD(glyphTexture, src_texCoord).x;\n" " if (mipmapLevel<1.0)\n" " {\n" " outline_alpha = mix(1.0-background_alpha, outline_alpha, mipmapLevel/1.0);\n" @@ -209,8 +209,11 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " return color;\n" "\n" "#else\n" + "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).a;\n" " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" " return vec4(vertexColor.rgb, vertexColor.a * alpha);\n" + "\n" "#endif\n" "}\n" "\n" @@ -225,10 +228,16 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " return;\n" " }\n" "\n" - "#ifdef SIGNED_DISTNACE_FIELD\n" - " vec4 color = distanceFieldColor();\n" + "#ifdef SHADOW\n" + " float scale = -1.0*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" + " vec2 delta_tc = SHADOW*scale;\n" + " vec4 shadow_color = textColor(texCoord+delta_tc);\n" + " shadow_color.rgb = BACKDROP_COLOR.rgb;\n" + "\n" + " vec4 glyph_color = textColor(texCoord);\n" + " vec4 color = mix(shadow_color, glyph_color, glyph_color.a);\n" "#else\n" - " vec4 color = textureColor();\n" + " vec4 color = textColor(texCoord);\n" "#endif\n" "\n" " if (color.a==0.0) discard;\n" From 28561b2b7705f751657984a8371790ac8b9fc60f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Oct 2017 08:40:58 +0100 Subject: [PATCH 54/74] Removed old multipass implemenmtations of backdrops as effect is now fully implememted in shaders --- include/osgText/Text | 3 +- src/osgText/Text.cpp | 226 +++---------------------------------------- 2 files changed, 13 insertions(+), 216 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index fc6fbfc0f..95b8e7d46 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -231,7 +231,7 @@ public: typedef std::vector Glyphs; Glyphs _glyphs; - Primitives _primitives; + osg::ref_ptr _primitives; GlyphQuads(); GlyphQuads(const GlyphQuads& gq); @@ -296,7 +296,6 @@ protected: virtual void computePositionsImplementation(); - void computeBackdropPositions(); void computeBackdropBoundingBox(); void computeBoundingBoxMargin(); diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 23d146372..7f05d1021 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -380,18 +380,14 @@ void Text::addGlyphQuad(Glyph* glyph, const osg::Vec2& minc, const osg::Vec2& ma glyphquad._glyphs.push_back(glyph); - osg::DrawElements* primitives = 0; - if (glyphquad._primitives.empty()) + osg::DrawElements* primitives = glyphquad._primitives.get(); + if (!primitives) { unsigned int maxIndices = _text.size()*4; if (maxIndices>=16384) primitives = new osg::DrawElementsUInt(GL_TRIANGLES); else primitives = new osg::DrawElementsUShort(GL_TRIANGLES); primitives->setBufferObject(_ebo.get()); - glyphquad._primitives.push_back(primitives); - } - else - { - primitives = glyphquad._primitives[0].get(); + glyphquad._primitives = primitives; } @@ -431,25 +427,18 @@ void Text::computeGlyphRepresentation() if (!_texcoords) { _texcoords = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX); _texcoords->setBufferObject(_vbo.get()); } else _texcoords->clear(); -#if 0 - _textureGlyphQuadMap.clear(); -#else for(TextureGlyphQuadMap::iterator itr = _textureGlyphQuadMap.begin(); itr != _textureGlyphQuadMap.end(); ++itr) { GlyphQuads& glyphquads = itr->second; glyphquads._glyphs.clear(); - for(Primitives::iterator pitr = glyphquads._primitives.begin(); - pitr != glyphquads._primitives.end(); - ++pitr) + if (glyphquads._primitives.valid()) { - (*pitr)->resizeElements(0); - (*pitr)->dirty(); + glyphquads._primitives->resizeElements(0); + glyphquads._primitives->dirty(); } } -#endif - _lineCount = 0; @@ -774,153 +763,10 @@ void Text::computePositionsImplementation() { TextBase::computePositionsImplementation(); - computeBackdropPositions(); computeBackdropBoundingBox(); computeBoundingBoxMargin(); } -// Presumes the atc matrix is already up-to-date -void Text::computeBackdropPositions() -{ - if(_backdropType == NONE || _backdropImplementation == USE_SHADERS) - { - return; - } - - float avg_width = 0.0f; - float avg_height = 0.0f; - - // FIXME: OPTIMIZE: This function produces the same value regardless of contextID. - // Since we tend to loop over contextID, we should cache this value some how - // instead of recomputing it each time. - bool is_valid_size = computeAverageGlyphWidthAndHeight(avg_width, avg_height); - if (!is_valid_size) return; - - unsigned int backdrop_index; - unsigned int max_backdrop_index; - if(_backdropType == OUTLINE) - { - // For outline, we want to draw the in every direction - backdrop_index = 1; - max_backdrop_index = backdrop_index+8; - } - else - { - // Yes, this may seem a little strange, - // but since the code is using references, - // I would have to duplicate the following code twice - // for each part of the if/else because I can't - // declare a reference without setting it immediately - // and it wouldn't survive the scope. - // So it happens that the _backdropType value matches - // the index in the array I want to store the coordinates - // in. So I'll just setup the for-loop so it only does - // the one direction I'm interested in. - backdrop_index = _backdropType+1; - max_backdrop_index = backdrop_index+1; - } - - for( ; backdrop_index < max_backdrop_index; backdrop_index++) - { - float horizontal_shift_direction; - float vertical_shift_direction; - switch(backdrop_index-1) - { - case DROP_SHADOW_BOTTOM_RIGHT: - { - horizontal_shift_direction = 1.0f; - vertical_shift_direction = -1.0f; - break; - } - case DROP_SHADOW_CENTER_RIGHT: - { - horizontal_shift_direction = 1.0f; - vertical_shift_direction = 0.0f; - break; - } - case DROP_SHADOW_TOP_RIGHT: - { - horizontal_shift_direction = 1.0f; - vertical_shift_direction = 1.0f; - break; - } - case DROP_SHADOW_BOTTOM_CENTER: - { - horizontal_shift_direction = 0.0f; - vertical_shift_direction = -1.0f; - break; - } - case DROP_SHADOW_TOP_CENTER: - { - horizontal_shift_direction = 0.0f; - vertical_shift_direction = 1.0f; - break; - } - case DROP_SHADOW_BOTTOM_LEFT: - { - horizontal_shift_direction = -1.0f; - vertical_shift_direction = -1.0f; - break; - } - case DROP_SHADOW_CENTER_LEFT: - { - horizontal_shift_direction = -1.0f; - vertical_shift_direction = 0.0f; - break; - } - case DROP_SHADOW_TOP_LEFT: - { - horizontal_shift_direction = -1.0f; - vertical_shift_direction = 1.0f; - break; - } - default: // error - { - horizontal_shift_direction = 1.0f; - vertical_shift_direction = -1.0f; - } - } - - // now apply matrix to the glyphs. - for(TextureGlyphQuadMap::iterator titr=_textureGlyphQuadMap.begin(); - titr!=_textureGlyphQuadMap.end(); - ++titr) - { - GlyphQuads& glyphquad = titr->second; - - osg::DrawElements* src_primitives = glyphquad._primitives[0].get(); - - for(unsigned int i=glyphquad._primitives.size(); i<=backdrop_index; ++i) - { - osg::DrawElementsUShort* dst_primitives = new osg::DrawElementsUShort(GL_TRIANGLES); - dst_primitives->setBufferObject(src_primitives->getBufferObject()); - glyphquad._primitives.push_back(dst_primitives); - } - - osg::DrawElements* dst_primitives = glyphquad._primitives[backdrop_index].get(); - dst_primitives->resizeElements(0); - - unsigned int numCoords = src_primitives->getNumIndices(); - - Coords& src_coords = _coords; - TexCoords& src_texcoords = _texcoords; - - Coords& dst_coords = _coords; - TexCoords& dst_texcoords = _texcoords; - - for(unsigned int i=0;isize(); - (*dst_primitives).addElement(di); - (*dst_coords).push_back(v); - (*dst_texcoords).push_back((*src_texcoords)[si]); - } - } - } -} - // This method adjusts the bounding box to account for the expanded area caused by the backdrop. // This assumes that the bounding box has already been computed for the text without the backdrop. void Text::computeBackdropBoundingBox() @@ -1269,7 +1115,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo } if (_drawMode & TEXT) -// if (false) { for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); titr!=_textureGlyphQuadMap.end(); @@ -1280,39 +1125,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo const GlyphQuads& glyphquad = titr->second; - if(_backdropType != NONE) - { - if (_backdropImplementation != USE_SHADERS) - { - unsigned int backdrop_index; - unsigned int max_backdrop_index; - if(_backdropType == OUTLINE) - { - backdrop_index = 1; - max_backdrop_index = backdrop_index+8; - } - else - { - backdrop_index = _backdropType+1; - max_backdrop_index = backdrop_index+1; - } - - if (max_backdrop_index>glyphquad._primitives.size()) max_backdrop_index=glyphquad._primitives.size(); - - state.disableColorPointer(); - state.Color(_backdropColor.r(),_backdropColor.g(),_backdropColor.b(),_backdropColor.a()); - - for( ; backdrop_index < max_backdrop_index; backdrop_index++) - { - glyphquad._primitives[backdrop_index]->draw(state, usingVertexBufferObjects); - } - } - else - { - // OSG_NOTICE<<"Using shaders for backdrop"<disableColorArray(state); @@ -1326,7 +1138,7 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo } } - glyphquad._primitives[0]->draw(state, usingVertexBufferObjects); + glyphquad._primitives->draw(state, usingVertexBufferObjects); } } } @@ -1374,9 +1186,6 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie vas->applyDisablingOfVertexAttributes(state); } -#if 0 - drawImplementationSinglePass(state, colorMultiplier); -#else glDepthMask(GL_FALSE); drawImplementationSinglePass(state, colorMultiplier); @@ -1393,7 +1202,6 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie } state.haveAppliedAttribute(osg::StateAttribute::DEPTH); -#endif if (usingVertexBufferObjects && !usingVertexArrayObjects) { @@ -1431,16 +1239,16 @@ void Text::accept(osg::PrimitiveFunctor& pf) const ++titr) { const GlyphQuads& glyphquad = titr->second; - if (!glyphquad._primitives.empty()) + if (glyphquad._primitives.valid()) { - const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast(glyphquad._primitives[0].get()); + const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast(glyphquad._primitives.get()); if (drawElementsUShort) { pf.drawElements(GL_TRIANGLES, drawElementsUShort->size(), &(drawElementsUShort->front())); } else { - const osg::DrawElementsUInt* drawElementsUInt = dynamic_cast(glyphquad._primitives[0].get()); + const osg::DrawElementsUInt* drawElementsUInt = dynamic_cast(glyphquad._primitives.get()); if (drawElementsUInt) { pf.drawElements(GL_TRIANGLES, drawElementsUInt->size(), &(drawElementsUInt->front())); @@ -1563,20 +1371,10 @@ Text::GlyphQuads::GlyphQuads(const GlyphQuads&) void Text::GlyphQuads::resizeGLObjectBuffers(unsigned int maxSize) { - for(Primitives::iterator itr = _primitives.begin(); - itr != _primitives.end(); - ++itr) - { - (*itr)->resizeGLObjectBuffers(maxSize); - } + if (_primitives.valid()) _primitives->resizeGLObjectBuffers(maxSize); } void Text::GlyphQuads::releaseGLObjects(osg::State* state) const { - for(Primitives::const_iterator itr = _primitives.begin(); - itr != _primitives.end(); - ++itr) - { - (*itr)->releaseGLObjects(state); - } + if (_primitives.valid()) _primitives->releaseGLObjects(state); } From 8b12d2d71a1cfd680d3ed9c27c56b744c178070f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Oct 2017 11:42:25 +0100 Subject: [PATCH 55/74] Deprecated Text:BackdropImplementation, removing the backend as it no longer required when using shaders for backdrop effects --- examples/osgSSBO/osgSSBO.cpp | 1 - examples/osgfont/osgfont.cpp | 5 -- examples/osglogo/osglogo.cpp | 2 - examples/osgviewerCocoa/ViewerCocoa.mm | 1 - examples/osgwidgetlabel/osgwidgetlabel.cpp | 6 --- include/osgText/Text | 54 +++++-------------- src/osgPlugins/ive/Text.cpp | 4 +- src/osgText/Text.cpp | 34 +----------- src/osgWidget/Label.cpp | 1 - .../deprecated-dotosg/osgText/IO_Text.cpp | 30 ----------- 10 files changed, 17 insertions(+), 121 deletions(-) diff --git a/examples/osgSSBO/osgSSBO.cpp b/examples/osgSSBO/osgSSBO.cpp index 9db8161dc..2fa6c21d0 100644 --- a/examples/osgSSBO/osgSSBO.cpp +++ b/examples/osgSSBO/osgSSBO.cpp @@ -473,7 +473,6 @@ void ComputeNode::addDataMonitor(osg::Vec3 placement, osg::Vec3 relativePlacemen pat->setName(labelCaption); text->setText(pat->getName()); text->setBackdropType(osgText::Text::OUTLINE); - text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET); text->setBackdropOffset(0.05f); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index b39b19b59..b20ad43e1 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -161,11 +161,6 @@ struct TextSettings text.setBackdropOffset(backdropOffset.x(), backdropOffset.y()); text.setBackdropColor(backdropColor); - if (glyphTextureFeatures==osgText::GlyphTexture::ALL_FEATURES) - { - text.setBackdropImplementation(osgText::Text::USE_SHADERS); - } - text.setFont(font.get()); } diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 9d02e6141..fe8a12475 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -154,7 +154,6 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label if (s_useSDF) { text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); - text->setBackdropImplementation(osgText::Text::USE_SHADERS); } text->setAlignment(osgText::Text::CENTER_CENTER); @@ -188,7 +187,6 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, if (s_useSDF) { text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); - text->setBackdropImplementation(osgText::Text::USE_SHADERS); } text->setAlignment(osgText::Text::RIGHT_CENTER); diff --git a/examples/osgviewerCocoa/ViewerCocoa.mm b/examples/osgviewerCocoa/ViewerCocoa.mm index aded53820..84333c449 100644 --- a/examples/osgviewerCocoa/ViewerCocoa.mm +++ b/examples/osgviewerCocoa/ViewerCocoa.mm @@ -432,7 +432,6 @@ static void Internal_SetAlpha(NSBitmapImageRep *imageRep, unsigned char alpha_va default_text->setAlignment(osgText::Text::CENTER_CENTER); default_text->setBackdropType(osgText::Text::OUTLINE); -// default_text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET); default_text->setColor(osg::Vec4(1.0, 1.0, 0.0, 1.0)); default_text->setBackdropColor(osg::Vec4(0.0, 0.0, 0.0, 1.0)); default_text->setAxisAlignment(osgText::Text::XZ_PLANE); diff --git a/examples/osgwidgetlabel/osgwidgetlabel.cpp b/examples/osgwidgetlabel/osgwidgetlabel.cpp index 39d86fefe..a29320cdf 100644 --- a/examples/osgwidgetlabel/osgwidgetlabel.cpp +++ b/examples/osgwidgetlabel/osgwidgetlabel.cpp @@ -30,12 +30,6 @@ osgWidget::Label* createLabel(const std::string& l, unsigned int size=13) { label->setFontColor(1.0f, 1.0f, 1.0f, 1.0f); label->setLabel(l); - /* - text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); - text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER); - text->setBackdropOffset(0.2f); - */ - return label; } diff --git a/include/osgText/Text b/include/osgText/Text index 95b8e7d46..acb8323f9 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -60,33 +60,6 @@ public: NONE }; - enum BackdropImplementation - { - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - POLYGON_OFFSET = 0, - - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - NO_DEPTH_BUFFER, - - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - DEPTH_RANGE, - - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - STENCIL_BUFFER, - - /* DELAYED_DEPTH_WRITES - * This mode renders all text with depth writes turned off, then - * again with depth writes on, but with the color buffer disabled. - * This should render text accurately for all graphics cards. The - * only downside is the additional pass to render to the depth - * buffer. But if you don't need the depth buffer updated for - * your, this extra pass can be disabled by calling - * enableDepthWrites(false).*/ - DELAYED_DEPTH_WRITES, - - USE_SHADERS - }; - /** * BackdropType gives you a background shadow text behind your regular * text. This helps give text extra contrast which can be useful when @@ -141,18 +114,6 @@ public: const osg::Vec4& getBackdropColor() const { return _backdropColor; } - /** - * This specifies the underlying backdrop rendering implementation. - * Unfortunately, at this time, there is no "perfect" rendering solution - * so this function is provided to let you 'pick your poison'. Each - * implementation has trade-offs. See BackdropImplementation enum - * docs for details.*/ - void setBackdropImplementation(BackdropImplementation implementation); - - BackdropImplementation getBackdropImplementation() const { return _backdropImplementation; } - - - enum ColorGradientMode { SOLID = 0, // a.k.a. ColorGradients off @@ -224,6 +185,20 @@ public: public: + /** deprecated, value ignored.*/ + enum BackdropImplementation + { + POLYGON_OFFSET = 0, + NO_DEPTH_BUFFER, + DEPTH_RANGE, + STENCIL_BUFFER, + DELAYED_DEPTH_WRITES + }; + + /** deprecated, value ignored.*/ + void setBackdropImplementation(BackdropImplementation) {} + /** deprecated, value should be ignored.*/ + BackdropImplementation getBackdropImplementation() const { return DELAYED_DEPTH_WRITES; } // internal structures, variable and methods used for rendering of characters. struct OSGTEXT_EXPORT GlyphQuads @@ -310,7 +285,6 @@ protected: bool _enableDepthWrites; BackdropType _backdropType; - BackdropImplementation _backdropImplementation; float _backdropHorizontalOffset; float _backdropVerticalOffset; diff --git a/src/osgPlugins/ive/Text.cpp b/src/osgPlugins/ive/Text.cpp index ae9da298f..0139695c5 100644 --- a/src/osgPlugins/ive/Text.cpp +++ b/src/osgPlugins/ive/Text.cpp @@ -90,7 +90,7 @@ void Text::write(DataOutputStream* out){ out->writeFloat(getBackdropVerticalOffset()); out->writeVec4(getBackdropColor()); - out->writeUInt(getBackdropImplementation()); + out->writeUInt(4); // old DELAYED_DEPTH_WRITES out->writeUInt(getColorGradientMode()); out->writeVec4(getColorGradientTopLeft()); @@ -213,7 +213,7 @@ void Text::read(DataInputStream* in){ setBackdropOffset(horizontalOffset,verticalOffset); setBackdropColor(in->readVec4()); - setBackdropImplementation((osgText::Text::BackdropImplementation) in->readUInt()); + in->readUInt(); // read old BackdropImplementation value, no longer used setColorGradientMode((osgText::Text::ColorGradientMode) in->readUInt()); osg::Vec4 colorGradientTopLeft,colorGradientBottomLeft,colorGradientBottomRight,colorGradientTopRight; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 7f05d1021..54cd841c1 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -31,11 +31,6 @@ using namespace osgText; Text::Text(): _enableDepthWrites(true), _backdropType(NONE), -#if 1 - _backdropImplementation(DELAYED_DEPTH_WRITES), -#else - _backdropImplementation(USE_SHADERS), -#endif _backdropHorizontalOffset(0.07f), _backdropVerticalOffset(0.07f), _backdropColor(0.0f, 0.0f, 0.0f, 1.0f), @@ -47,17 +42,6 @@ Text::Text(): { _supportsVertexBufferObjects = true; - char *ptr; - if ((ptr = getenv("OSG_SDF_TEXT")) != 0) - { - _backdropImplementation = USE_SHADERS; - } - else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) - { - _backdropImplementation = DELAYED_DEPTH_WRITES; - } - - assignStateSet(); } @@ -65,7 +49,6 @@ Text::Text(const Text& text,const osg::CopyOp& copyop): osgText::TextBase(text,copyop), _enableDepthWrites(text._enableDepthWrites), _backdropType(text._backdropType), - _backdropImplementation(text._backdropImplementation), _backdropHorizontalOffset(text._backdropHorizontalOffset), _backdropVerticalOffset(text._backdropVerticalOffset), _backdropColor(text._backdropColor), @@ -93,7 +76,7 @@ osg::StateSet* Text::createStateSet() std::stringstream ss; osg::StateSet::DefineList defineList; - if (_backdropType!=NONE && _backdropImplementation==USE_SHADERS) + if (_backdropType!=NONE) { ss.str(""); ss << "vec4("<<_backdropColor.r()<<", "<<_backdropColor.g()<<", "<<_backdropColor.b()<<", "<<_backdropColor.a()<<")"; @@ -128,8 +111,6 @@ osg::StateSet* Text::createStateSet() defineList["SHADOW"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); } - - } if (activeFont->getGlyphTextureFeatures()!=GlyphTexture::GREYSCALE) @@ -147,7 +128,6 @@ osg::StateSet* Text::createStateSet() } #if 0 - OSG_NOTICE<<"Text::createStateSet() _backdropType="<<_backdropType<<", _backdropImplementation="<<_backdropImplementation<setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); - _text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER); _text->setBackdropOffset(offset); _calculateSize(getTextSize()); diff --git a/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp b/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp index e34c1d46e..c2bb99e6a 100644 --- a/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp @@ -57,27 +57,6 @@ std::string convertBackdropTypeEnumToString(osgText::Text::BackdropType backdrop } } - -osgText::Text::BackdropImplementation convertBackdropImplementationStringToEnum(std::string & str) -{ - if (str=="POLYGON_OFFSET") return osgText::Text::POLYGON_OFFSET; - else if (str=="NO_DEPTH_BUFFER") return osgText::Text::NO_DEPTH_BUFFER; - else if (str=="DEPTH_RANGE") return osgText::Text::DEPTH_RANGE; - else if (str=="STENCIL_BUFFER") return osgText::Text::STENCIL_BUFFER; - else return static_cast(-1); -} -std::string convertBackdropImplementationEnumToString(osgText::Text::BackdropImplementation backdropImplementation) -{ - switch (backdropImplementation) - { - case osgText::Text::POLYGON_OFFSET: return "POLYGON_OFFSET"; - case osgText::Text::NO_DEPTH_BUFFER: return "NO_DEPTH_BUFFER"; - case osgText::Text::DEPTH_RANGE: return "DEPTH_RANGE"; - case osgText::Text::STENCIL_BUFFER: return "STENCIL_BUFFER"; - default : return ""; - } -} - osgText::Text::ColorGradientMode convertColorGradientModeStringToEnum(std::string & str) { if (str=="SOLID") return osgText::Text::SOLID; @@ -155,12 +134,6 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) // backdropImplementation if (fr[0].matchWord("backdropImplementation")) { - std::string str = fr[1].getStr(); - osgText::Text::BackdropImplementation backdropImplementation = convertBackdropImplementationStringToEnum(str); - - if (backdropImplementation != static_cast(-1)) - text.setBackdropImplementation(backdropImplementation); - fr += 2; itAdvanced = true; } @@ -254,9 +227,6 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw) osg::Vec4 c = text.getBackdropColor(); fw.indent() << "backdropColor " << c.x() << " " << c.y() << " " << c.z() << " " << c.w() << std::endl; - // backdropImplementation - fw.indent() << "backdropImplementation " << convertBackdropImplementationEnumToString(text.getBackdropImplementation()) << std::endl; - // colorGradientMode fw.indent() << "colorGradientMode " << convertColorGradientModeEnumToString(text.getColorGradientMode()) << std::endl; From 24bec09b9e56fe87044ffae1f0203e988110e8a2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Oct 2017 13:01:57 +0100 Subject: [PATCH 56/74] Removed the glyph image outline support as it's no longer required. --- examples/osgfont/osgfont.cpp | 1 - include/osgText/Glyph | 1 - src/osgText/Glyph.cpp | 84 ++---------------------------------- 3 files changed, 4 insertions(+), 82 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index b20ad43e1..f65e607fc 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -103,7 +103,6 @@ struct TextSettings } if (arguments.read("--GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; } - if (arguments.read("--OUTLINE_GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::OUTLINE_GREYSCALE; } if (arguments.read("--SIGNED_DISTANCE_FIELD")) { glyphTextureFeatures = osgText::GlyphTexture::SIGNED_DISTANCE_FIELD; } if (arguments.read("--ALL_FEATURES")) { glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; } diff --git a/include/osgText/Glyph b/include/osgText/Glyph index fb842eb8b..5dcfd12b3 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -263,7 +263,6 @@ public: enum Features { GREYSCALE, - OUTLINE_GREYSCALE, SIGNED_DISTANCE_FIELD, ALL_FEATURES }; diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index e8a11ea87..8ca21f5bc 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -32,7 +32,7 @@ using namespace std; #define TEXTURE_IMAGE_NUM_CHANNELS 1 #define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT #else - #define TEXTURE_IMAGE_NUM_CHANNELS 4 + #define TEXTURE_IMAGE_NUM_CHANNELS 2 #define TEXTURE_IMAGE_FORMAT GL_RGBA #endif @@ -60,9 +60,7 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const int GlyphTexture::getEffectMargin(const Glyph* glyph) { if (_glyphTextureFeatures==GREYSCALE) return 0; -// else return glyph->getFontResolution().second/4; else return osg::maximum(glyph->getFontResolution().second/6, 2u); -// else return osg::maximum(glyph->getFontResolution().second/8,1u); } int GlyphTexture::getTexelMargin(const Glyph* glyph) @@ -195,10 +193,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) if ((lower+glyph->getTexturePositionY())<0) lower = -glyph->getTexturePositionY(); if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; - bool use_SDF_for_Outline = true; - - float outer_outline_distance = float(glyph->getFontResolution().first)*0.1f; - float inner_outline_distance = outer_outline_distance*0.5f; unsigned char full_on = 255; unsigned char mid_point = full_on/2; @@ -213,17 +207,11 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) unsigned char center_value = 0; if (dr>=0 && dr=0 && dc0 && center_value=mid_point_f) { min_distance = center_value_f-mid_point_f; @@ -263,9 +251,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; - if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } @@ -291,9 +276,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; - if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } @@ -320,9 +302,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; - if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } @@ -348,9 +327,6 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) else local_distance += (local_value_f - mid_point_f)*local_multiplier; if (local_distanceinner_max_value && local_distance<=inner_outline_distance) inner_max_value = local_value; - if (local_value>outer_max_value && local_distance<=outer_outline_distance) outer_max_value = local_value; } } } @@ -368,63 +344,11 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) unsigned char* dest_ptr = dest_data + (dr*dest_columns + dc)*num_channels; - if (num_channels==4) + if (num_channels==2) { // signed distance field value *(dest_ptr++) = value; - float outline_distance = inner_outline_distance; - - // compute the alpha value of outline, one texel thick - unsigned char outline = 0; - - if (use_SDF_for_Outline) - { - if (center_value<255) - { - float inner_outline = outline_distance-1.0f; - if (min_distancecenter_value) - { - outline -= center_value; - } - } - else - { - outline = inner_max_value-center_value; - } - - *(dest_ptr++) = outline; - - - outline_distance = outer_outline_distance; - - // compute the alpha value of outline, one texel thick - outline = 0; - if (use_SDF_for_Outline) - { - if (center_value<255) - { - float inner_outline = outline_distance-1.0f; - if (min_distancecenter_value) - { - outline -= center_value; - } - } - else - { - outline = outer_max_value-center_value; - } - - *(dest_ptr++) = outline; - // original alpha value from glyph image *(dest_ptr) = center_value; } @@ -468,9 +392,9 @@ osg::Image* GlyphTexture::createImage() _image = new osg::Image; #if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) - GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_RED : GL_RGBA; + GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_RED : GL_RG; #else - GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_ALPHA : GL_RGBA; + GLenum imageFormat = (_glyphTextureFeatures==GREYSCALE) ? GL_ALPHA : GL_LUMINANCE_ALPHA; #endif _image->allocateImage(getTextureWidth(), getTextureHeight(), 1, imageFormat, GL_UNSIGNED_BYTE); From 2303d6afc4a48adf3b7b8a309249b1f834808d42 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 13 Oct 2017 17:03:31 +0100 Subject: [PATCH 57/74] Cleaned up support for GL3 build --- include/osgText/Glyph | 9 ----- src/osgPlugins/freetype/FreeTypeFont.cpp | 6 ++-- src/osgText/DefaultFont.cpp | 6 ++-- src/osgText/Glyph.cpp | 44 ++++++++++++++++++------ src/osgText/shaders/text_sdf_frag.cpp | 18 +++++++--- 5 files changed, 51 insertions(+), 32 deletions(-) diff --git a/include/osgText/Glyph b/include/osgText/Glyph index 5dcfd12b3..adba880bc 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -30,15 +30,6 @@ #include -// GL_ALPHA is deprecated in GL3/GL4 core profile, use GL_RED and a shader in this case. See osgText example. -#if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) -#define OSGTEXT_GLYPH_FORMAT GL_RED -#define OSGTEXT_GLYPH_INTERNALFORMAT GL_R8 -#else -#define OSGTEXT_GLYPH_FORMAT GL_ALPHA -#define OSGTEXT_GLYPH_INTERNALFORMAT GL_ALPHA -#endif - namespace osgText { class Font; diff --git a/src/osgPlugins/freetype/FreeTypeFont.cpp b/src/osgPlugins/freetype/FreeTypeFont.cpp index 323a874b6..d39f984c2 100644 --- a/src/osgPlugins/freetype/FreeTypeFont.cpp +++ b/src/osgPlugins/freetype/FreeTypeFont.cpp @@ -348,14 +348,12 @@ osgText::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, u for(unsigned char* p=data;psetImage(width,height,1, - OSGTEXT_GLYPH_INTERNALFORMAT, - OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE, + GL_ALPHA, + GL_ALPHA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE, 1); - glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT); - // copy image across to osgText::Glyph image. switch(glyphslot->bitmap.pixel_mode) { diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index cf3669cef..94aac9be3 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -207,14 +207,12 @@ void DefaultFont::constructGlyphs() for(unsigned char* p=data;psetImage(sourceWidth,sourceHeight,1, - OSGTEXT_GLYPH_INTERNALFORMAT, - OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE, + GL_ALPHA, + GL_ALPHA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE, 1); - glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT); - // now populate data array by converting bitmap into a luminance_alpha map. unsigned char* ptr = rasters[i-32]; unsigned char value_on = 255; diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 8ca21f5bc..114f6649a 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -28,6 +28,22 @@ using namespace osgText; using namespace std; +// GL_ALPHA and GL_LUMINANCE_ALPHA are deprecated in GL3/GL4 core profile, use GL_RED & GL_RB in this case. +#if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) +#define OSGTEXT_GLYPH_ALPHA_FORMAT GL_RED +#define OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT GL_R8 +#define OSGTEXT_GLYPH_SDF_FORMAT GL_RG +#define OSGTEXT_GLYPH_SDF_INTERNALFORMAT GL_RG8 +#else +#define OSGTEXT_GLYPH_ALPHA_FORMAT GL_ALPHA +#define OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT GL_ALPHA +#define OSGTEXT_GLYPH_SDF_FORMAT GL_LUMINANCE_ALPHA +#define OSGTEXT_GLYPH_SDF_INTERNALFORMAT GL_LUMINANCE_ALPHA +#endif + + + + #if 0 #define TEXTURE_IMAGE_NUM_CHANNELS 1 #define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT @@ -160,6 +176,9 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) if (_glyphTextureFeatures==GREYSCALE) { // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copying. glyphTexture="<=130\n" + " #define ALPHA r\n" + " #define SDF g\n" + "#else\n" + " #define ALPHA a\n" + " #define SDF r\n" + "#endif\n" + "\n" + "\n" "uniform sampler2D glyphTexture;\n" "\n" "$OSG_VARYING_IN vec2 texCoord;\n" @@ -49,7 +59,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "float distanceFromEdge(vec2 tc)\n" "{\n" - " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).r;\n" + " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).SDF;\n" " if (center_alpha==0.0) return -1.0;\n" "\n" " //float distance_scale = (1.0/4.0)*1.41;\n" @@ -169,7 +179,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" "\n" "#ifdef OUTLINE\n" "\n" - " float alpha = TEXTURE(glyphTexture, src_texCoord).a;\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" "\n" " float outline_alpha = alpha;\n" @@ -184,7 +194,7 @@ char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" " {\n" " for(float j=0.0; j Date: Sat, 14 Oct 2017 09:03:08 +0100 Subject: [PATCH 58/74] Improved the formating of GLSL source that is passed to OpenGL to make debugging shaders easier. --- src/osg/Shader.cpp | 28 +++++++++++++++++++++------- src/osg/State.cpp | 6 +++--- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/osg/Shader.cpp b/src/osg/Shader.cpp index 1b11789fc..349c55edf 100644 --- a/src/osg/Shader.cpp +++ b/src/osg/Shader.cpp @@ -624,13 +624,6 @@ void Shader::PerContextShader::compileShader(osg::State& state) } - if (osg::getNotifyLevel()>=osg::INFO) - { - std::string sourceWithLineNumbers = insertLineNumbers(source); - OSG_INFO << "\nCompiling " << _shader->getTypename() - << " source:\n" << sourceWithLineNumbers << std::endl; - } - GLint compiled = GL_FALSE; // OSG_NOTICE<<"Compiling PerContextShader "<getTypename() + << " source:\n" << sourceWithLineNumbers << std::endl; + } } else { @@ -681,6 +681,12 @@ void Shader::PerContextShader::compileShader(osg::State& state) sourceText[2] = reinterpret_cast(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 3, sourceText, NULL ); + if (osg::getNotifyLevel()>=osg::INFO) + { + std::string sourceWithLineNumbers = insertLineNumbers(versionLine+_defineStr+source); + OSG_INFO << "\nCompiling B: " << _shader->getTypename() + << " source:\n" << sourceWithLineNumbers << std::endl; + } // OSG_NOTICE<<" Version Line : ["<(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 2, sourceText, NULL ); + + if (osg::getNotifyLevel()>=osg::INFO) + { + std::string sourceWithLineNumbers = insertLineNumbers(_defineStr+source); + OSG_INFO << "\nCompiling C: " << _shader->getTypename() + << " source:\n" << sourceWithLineNumbers << std::endl; + } + // OSG_NOTICE<<" DefineStr : ["< Date: Sat, 14 Oct 2017 09:06:37 +0100 Subject: [PATCH 59/74] Changed the precision setting of #pargma(tic) shader composition define setup to address GLES compatibility issues --- src/osgText/Text.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 54cd841c1..8e213d15c 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -66,6 +66,7 @@ Text::~Text() } #include +#include osg::StateSet* Text::createStateSet() { @@ -75,6 +76,8 @@ osg::StateSet* Text::createStateSet() Font::StateSets& statesets = activeFont->getCachedStateSets(); std::stringstream ss; + ss<getGlyphTextureFeatures()!=GlyphTexture::GREYSCALE) { + ss<getTextureWidthHint(); + ss << float(activeFont->getTextureWidthHint()); defineList["TEXTURE_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); defineList["SIGNED_DISTNACE_FIELD"] = osg::StateSet::DefinePair("1", osg::StateAttribute::ON); From 97aeb16551659c18f71987de78d5faa72718f474 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 20 Oct 2017 17:03:25 +0100 Subject: [PATCH 60/74] Moved osgText::GlyphTechnique::Features enum to osgText::ShaderTechinque enum to make it's roll clearer --- examples/osgfont/osgfont.cpp | 16 ++++++++-------- examples/osglogo/osglogo.cpp | 4 ++-- include/osgText/Font | 6 +++--- include/osgText/Glyph | 25 +++++++++++++------------ src/osgText/DefaultFont.cpp | 2 +- src/osgText/Font.cpp | 10 +++++----- src/osgText/Glyph.cpp | 8 ++++---- src/osgText/Text.cpp | 8 ++++---- 8 files changed, 40 insertions(+), 39 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index f65e607fc..e16ab4079 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -68,7 +68,7 @@ struct TextSettings minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), magFilter(osg::Texture::LINEAR), maxAnisotropy(16.0f), - glyphTextureFeatures(osgText::GlyphTexture::GREYSCALE), + shaderTechnique(osgText::GREYSCALE), textColor(1.0f, 1.0f, 1.0f, 1.0f), backdropType(osgText::Text::NONE), backdropOffset(0.07f, 0.07f), @@ -102,9 +102,9 @@ struct TextSettings sizes.push_back(128); } - if (arguments.read("--GREYSCALE")) { glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; } - if (arguments.read("--SIGNED_DISTANCE_FIELD")) { glyphTextureFeatures = osgText::GlyphTexture::SIGNED_DISTANCE_FIELD; } - if (arguments.read("--ALL_FEATURES")) { glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; } + if (arguments.read("--GREYSCALE")) { shaderTechnique = osgText::GREYSCALE; } + if (arguments.read("--SIGNED_DISTANCE_FIELD")) { shaderTechnique = osgText::SIGNED_DISTANCE_FIELD; } + if (arguments.read("--ALL_FEATURES")) { shaderTechnique = osgText::ALL_FEATURES; } if (arguments.read("--font",fontFilename)) {} @@ -153,7 +153,7 @@ struct TextSettings font->setMinFilterHint(minFilter); font->setMagFilterHint(magFilter); font->setMaxAnisotropy(maxAnisotropy); - font->setGyphTextureFeatures(glyphTextureFeatures); + font->setShaderTechnique(shaderTechnique); text.setColor(textColor); text.setBackdropType(backdropType); @@ -168,7 +168,7 @@ struct TextSettings osg::Texture::FilterMode minFilter; osg::Texture::FilterMode magFilter; float maxAnisotropy; - osgText::GlyphTexture::Features glyphTextureFeatures; + osgText::ShaderTechnique shaderTechnique; osg::Vec4 textColor; osgText::Text::BackdropType backdropType; @@ -345,7 +345,7 @@ int main(int argc, char** argv) root->getOrCreateStateSet()->setAttribute(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); root->getOrCreateStateSet()->addUniform(new osg::Uniform("glyphTexture", 0)); - settings.glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; + settings.shaderTechnique = osgText::ALL_FEATURES; } @@ -396,7 +396,7 @@ int main(int argc, char** argv) osg::ref_ptr right_geode = new osg::Geode; right_geode->setNodeMask(0x2); - settings.glyphTextureFeatures = osgText::GlyphTexture::GREYSCALE; + settings.shaderTechnique = osgText::GREYSCALE; pos.set(0.0f, 0.0f, 0.0f); diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index fe8a12475..c419103cb 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -153,7 +153,7 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label if (s_useSDF) { - text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); + text->getFont()->setShaderTechnique(osgText::ALL_FEATURES); } text->setAlignment(osgText::Text::CENTER_CENTER); @@ -186,7 +186,7 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, if (s_useSDF) { - text->getFont()->setGyphTextureFeatures(osgText::GlyphTexture::ALL_FEATURES); + text->getFont()->setShaderTechnique(osgText::ALL_FEATURES); } text->setAlignment(osgText::Text::RIGHT_CENTER); diff --git a/include/osgText/Font b/include/osgText/Font index 0af593b91..f8fcc89b0 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -108,8 +108,8 @@ public: virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; } - void setGyphTextureFeatures(GlyphTexture::Features features) { _glyphTextureFeatures = features; } - GlyphTexture::Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + void setShaderTechnique(ShaderTechnique features) { _shaderTechnique = features; } + ShaderTechnique getShaderTechnique() const { return _shaderTechnique; } /** Set the size of texture to create to store the glyph images when rendering. @@ -186,7 +186,7 @@ protected: // current active size of font FontResolution _fontSize; - GlyphTexture::Features _glyphTextureFeatures; + ShaderTechnique _shaderTechnique; unsigned int _textureWidthHint; unsigned int _textureHeightHint; diff --git a/include/osgText/Glyph b/include/osgText/Glyph index adba880bc..c7d717f25 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -38,6 +38,13 @@ class Glyph3D; class GlyphGeometry; class GlyphTexture; +enum ShaderTechnique +{ + GREYSCALE = 0x1, + SIGNED_DISTANCE_FIELD = 0x2, + ALL_FEATURES = GREYSCALE | SIGNED_DISTANCE_FIELD +}; + class OSGTEXT_EXPORT Glyph : public osg::Image { public: @@ -251,15 +258,9 @@ public: /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ virtual int compare(const osg::StateAttribute& rhs) const; - enum Features - { - GREYSCALE, - SIGNED_DISTANCE_FIELD, - ALL_FEATURES - }; + void setShaderTechnique(ShaderTechnique technique) { _shaderTechnique = technique; } - void setGlyphTextureFeatures(Features features) { _glyphTextureFeatures = features; } - Features getGlyphTextureFeatures() const { return _glyphTextureFeatures; } + ShaderTechnique getShaderTechnique() const { return _shaderTechnique; } int getEffectMargin(const Glyph* glyph); @@ -284,11 +285,11 @@ protected: void copyGlyphImage(Glyph* glyph); - Features _glyphTextureFeatures; + ShaderTechnique _shaderTechnique; - int _usedY; - int _partUsedX; - int _partUsedY; + int _usedY; + int _partUsedX; + int _partUsedY; typedef std::vector< osg::ref_ptr > GlyphRefList; typedef std::vector< const Glyph* > GlyphPtrList; diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index 94aac9be3..ac1a5d8ba 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -32,7 +32,7 @@ DefaultFont::DefaultFont() char *ptr; if ((ptr = getenv("OSG_SDF_TEXT")) != 0) { - _glyphTextureFeatures = osgText::GlyphTexture::ALL_FEATURES; + _shaderTechnique = osgText::ALL_FEATURES; } constructGlyphs(); diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index 3e3402b53..bfe67cd74 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -225,9 +225,9 @@ osg::ref_ptr osgText::readRefFontStream(std::istream& stream, const osgDB: Font::Font(FontImplementation* implementation): osg::Object(true), #if 0 - _glyphTextureFeatures(GlyphTexture::ALL_FEATURES), + _shaderTechnique(ALL_FEATURES), #else - _glyphTextureFeatures(GlyphTexture::GREYSCALE), + _shaderTechnique(GREYSCALE), #endif _textureWidthHint(1024), _textureHeightHint(1024), @@ -250,11 +250,11 @@ Font::Font(FontImplementation* implementation): if ((ptr = getenv("OSG_SDF_TEXT")) != 0) { - _glyphTextureFeatures = GlyphTexture::ALL_FEATURES; + _shaderTechnique = ALL_FEATURES; } else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) { - _glyphTextureFeatures = GlyphTexture::GREYSCALE; + _shaderTechnique = GREYSCALE; } } @@ -485,7 +485,7 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<setGlyphTextureFeatures(_glyphTextureFeatures); + glyphTexture->setShaderTechnique(_shaderTechnique); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 114f6649a..d7f2395fb 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -75,7 +75,7 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const int GlyphTexture::getEffectMargin(const Glyph* glyph) { - if (_glyphTextureFeatures==GREYSCALE) return 0; + if (_shaderTechnique==GREYSCALE) return 0; else return osg::maximum(glyph->getFontResolution().second/6, 2u); } @@ -173,7 +173,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) { _image->dirty(); - if (_glyphTextureFeatures==GREYSCALE) + if (_shaderTechnique==GREYSCALE) { // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copying. glyphTexture="<getGlyphTextureFeatures()="<getGlyphTextureFeatures()<getShaderTechnique()="<getShaderTechnique()<getShaderHint(); - if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) + if (activeFont->getShaderTechnique()==GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) { OSG_NOTICE<<"Font::Font() Fixed function pipeline"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } - if (activeFont->getGlyphTextureFeatures()==GlyphTexture::GREYSCALE) + if (activeFont->getShaderTechnique()==GREYSCALE) { OSG_NOTICE<<"Using shaders/text_greyscale.frag"< Date: Sat, 21 Oct 2017 10:08:41 +0100 Subject: [PATCH 61/74] Added Text::s/getShaderTechnique() --- include/osgText/Text | 8 ++++++++ src/osgText/Text.cpp | 17 +++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/osgText/Text b/include/osgText/Text index acb8323f9..ab5e547a0 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -36,6 +36,13 @@ public: virtual const char* className() const { return "Text"; } virtual const char* libraryName() const { return "osgText"; } + /** Set the ShaderTechnique hint to specify what fatures in the text shaders to enable.*/ + void setShaderTechnique(ShaderTechnique technique); + + /** Get the ShaderTechnique hint.*/ + ShaderTechnique getShaderTechnique() { return _shaderTechnique; } + + /** * Turns off writing to the depth buffer when rendering text. This only affects text * with no backdrop or text using the DELAYED_DEPTH_WRITES implementation, since @@ -282,6 +289,7 @@ protected: void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const; + ShaderTechnique _shaderTechnique; bool _enableDepthWrites; BackdropType _backdropType; diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 82c77d548..f2ef6ecbb 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -25,10 +25,15 @@ #include +#include +#include + + using namespace osg; using namespace osgText; Text::Text(): + _shaderTechnique(GREYSCALE), _enableDepthWrites(true), _backdropType(NONE), _backdropHorizontalOffset(0.07f), @@ -47,6 +52,7 @@ Text::Text(): Text::Text(const Text& text,const osg::CopyOp& copyop): osgText::TextBase(text,copyop), + _shaderTechnique(text._shaderTechnique), _enableDepthWrites(text._enableDepthWrites), _backdropType(text._backdropType), _backdropHorizontalOffset(text._backdropHorizontalOffset), @@ -65,8 +71,15 @@ Text::~Text() { } -#include -#include + +void Text::setShaderTechnique(ShaderTechnique technique) +{ + if (_shaderTechnique==technique) return; + + _shaderTechnique = technique; + + assignStateSet(); +} osg::StateSet* Text::createStateSet() { From 4b295c46d16ef837b8fb8a93417df5bd2ca95596 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 23 Oct 2017 14:50:35 +0100 Subject: [PATCH 62/74] Restructed the way that GlyphTexture is set up to better support control of osgText::ShaderTechnique from osgText::Text --- examples/osgfont/osgfont.cpp | 2 +- examples/osglogo/osglogo.cpp | 4 +- include/osgText/Font | 9 +-- include/osgText/Glyph | 56 ++++++++++-------- src/osgText/DefaultFont.cpp | 6 -- src/osgText/Font.cpp | 21 ++----- src/osgText/Glyph.cpp | 80 +++++++++++++------------- src/osgText/Text.cpp | 108 +++++++++++++++++++++-------------- 8 files changed, 147 insertions(+), 139 deletions(-) diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index e16ab4079..bad750798 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -153,12 +153,12 @@ struct TextSettings font->setMinFilterHint(minFilter); font->setMagFilterHint(magFilter); font->setMaxAnisotropy(maxAnisotropy); - font->setShaderTechnique(shaderTechnique); text.setColor(textColor); text.setBackdropType(backdropType); text.setBackdropOffset(backdropOffset.x(), backdropOffset.y()); text.setBackdropColor(backdropColor); + text.setShaderTechnique(shaderTechnique); text.setFont(font.get()); diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index c419103cb..f5161c041 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -153,7 +153,7 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label if (s_useSDF) { - text->getFont()->setShaderTechnique(osgText::ALL_FEATURES); + text->setShaderTechnique(osgText::ALL_FEATURES); } text->setAlignment(osgText::Text::CENTER_CENTER); @@ -186,7 +186,7 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, if (s_useSDF) { - text->getFont()->setShaderTechnique(osgText::ALL_FEATURES); + text->setShaderTechnique(osgText::ALL_FEATURES); } text->setAlignment(osgText::Text::RIGHT_CENTER); diff --git a/include/osgText/Font b/include/osgText/Font index f8fcc89b0..ab4641c93 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -107,11 +107,6 @@ public: * return true on success, return false when not supported.*/ virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; } - - void setShaderTechnique(ShaderTechnique features) { _shaderTechnique = features; } - ShaderTechnique getShaderTechnique() const { return _shaderTechnique; } - - /** Set the size of texture to create to store the glyph images when rendering. * Note, this doesn't affect already created Texture Glhph's.*/ void setTextureSizeHint(unsigned int width,unsigned int height); @@ -162,6 +157,8 @@ public: typedef std::vector< osg::ref_ptr > GlyphTextureList; GlyphTextureList& getGlyphTextureList() { return _glyphTextureList; } + void assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique); + protected: virtual ~Font(); @@ -186,8 +183,6 @@ protected: // current active size of font FontResolution _fontSize; - ShaderTechnique _shaderTechnique; - unsigned int _textureWidthHint; unsigned int _textureHeightHint; osg::Texture::FilterMode _minFilterHint; diff --git a/include/osgText/Glyph b/include/osgText/Glyph index c7d717f25..782b402dd 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -77,22 +77,40 @@ public: void setVerticalAdvance(float advance); float getVerticalAdvance() const; - void setTexture(GlyphTexture* texture); - GlyphTexture* getTexture(); - const GlyphTexture* getTexture() const; + struct TextureInfo : public osg::Referenced + { + TextureInfo(): + texture(0), + texelMargin(0.0f) {} - void setTexturePosition(int posX,int posY); - int getTexturePositionX() const; - int getTexturePositionY() const; + TextureInfo(GlyphTexture* tex, int x, int y, const osg::Vec2& mintc, const osg::Vec2& maxtc, float margin): + texture(tex), + texturePositionX(x), + texturePositionY(y), + minTexCoord(mintc), + maxTexCoord(maxtc), + texelMargin(margin) {} - void setMinTexCoord(const osg::Vec2& coord); - const osg::Vec2& getMinTexCoord() const; + GlyphTexture* texture; + int texturePositionX; + int texturePositionY; + osg::Vec2 minTexCoord; + osg::Vec2 maxTexCoord; + float texelMargin; + }; - void setMaxTexCoord(const osg::Vec2& coord); - const osg::Vec2& getMaxTexCoord() const; + void setTextureInfo(ShaderTechnique technique, TextureInfo* info) + { + if (technique>=_textureInfoList.size()) _textureInfoList.resize(technique+1); + _textureInfoList[technique] = info; + } - void setTexelMargin(float margin) { _texelMargin = margin; } - float getTexelMargin() const { return _texelMargin; } + const TextureInfo* getTextureInfo(ShaderTechnique technique) const + { + return (technique<_textureInfoList.size()) ? _textureInfoList[technique].get() : 0; + } + + TextureInfo* getOrCreateTextureInfo(ShaderTechnique technique); protected: @@ -112,16 +130,8 @@ protected: osg::Vec2 _verticalBearing; float _verticalAdvance; - GlyphTexture* _texture; - int _texturePosX; - int _texturePosY; - osg::Vec2 _minTexCoord; - osg::Vec2 _maxTexCoord; - float _texelMargin; - - typedef osg::buffered_value GLObjectList; - mutable GLObjectList _globjList; - + typedef std::vector< osg::ref_ptr > TextureInfoList; + TextureInfoList _textureInfoList; }; class OSGTEXT_EXPORT GlyphGeometry : public osg::Referenced @@ -283,7 +293,7 @@ protected: virtual ~GlyphTexture(); - void copyGlyphImage(Glyph* glyph); + void copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info); ShaderTechnique _shaderTechnique; diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index ac1a5d8ba..dfc9b5945 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -29,12 +29,6 @@ DefaultFont::DefaultFont() _minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR; _magFilterHint = osg::Texture::LINEAR; - char *ptr; - if ((ptr = getenv("OSG_SDF_TEXT")) != 0) - { - _shaderTechnique = osgText::ALL_FEATURES; - } - constructGlyphs(); } diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index bfe67cd74..7d6c61c1f 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -224,11 +224,6 @@ osg::ref_ptr osgText::readRefFontStream(std::istream& stream, const osgDB: Font::Font(FontImplementation* implementation): osg::Object(true), -#if 0 - _shaderTechnique(ALL_FEATURES), -#else - _shaderTechnique(GREYSCALE), -#endif _textureWidthHint(1024), _textureHeightHint(1024), _minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR), @@ -247,15 +242,6 @@ Font::Font(FontImplementation* implementation): if (osg_max_size<_textureWidthHint) _textureWidthHint = osg_max_size; if (osg_max_size<_textureHeightHint) _textureHeightHint = osg_max_size; } - - if ((ptr = getenv("OSG_SDF_TEXT")) != 0) - { - _shaderTechnique = ALL_FEATURES; - } - else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) - { - _shaderTechnique = GREYSCALE; - } } Font::~Font() @@ -459,6 +445,10 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* _sizeGlyphMap[fontRes][charcode]=glyph; +} + +void Font::assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique) +{ int posX=0,posY=0; GlyphTexture* glyphTexture = 0; @@ -485,7 +475,7 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<setShaderTechnique(_shaderTechnique); + glyphTexture->setShaderTechnique(shaderTechnique); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); @@ -503,5 +493,4 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* // add the glyph into the texture. glyphTexture->addGlyph(glyph,posX,posY); - } diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index d7f2395fb..fbd793cfa 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -42,8 +42,6 @@ using namespace std; #endif - - #if 0 #define TEXTURE_IMAGE_NUM_CHANNELS 1 #define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT @@ -52,6 +50,11 @@ using namespace std; #define TEXTURE_IMAGE_FORMAT GL_RGBA #endif + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// GlyphTexture +// GlyphTexture::GlyphTexture(): _usedY(0), _partUsedX(0), @@ -154,22 +157,19 @@ void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) _glyphs.push_back(glyph); - // set up the details of where to place glyph's image in the texture. - glyph->setTexture(this); - glyph->setTexturePosition(posX,posY); + osg::ref_ptr info = new Glyph::TextureInfo( + this, + posX, posY, + osg::Vec2( static_cast(posX)/static_cast(getTextureWidth()), static_cast(posY)/static_cast(getTextureHeight()) ), // minTexCoord + osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ), // maxTexCoord + float(getTexelMargin(glyph))); // margin - glyph->setMinTexCoord( osg::Vec2( static_cast(posX)/static_cast(getTextureWidth()), - static_cast(posY)/static_cast(getTextureHeight()) ) ); - glyph->setMaxTexCoord( osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), - static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ) ); + glyph->setTextureInfo(_shaderTechnique, info.get()); - - glyph->setTexelMargin(float(getTexelMargin(glyph))); - - copyGlyphImage(glyph); + copyGlyphImage(glyph, info); } -void GlyphTexture::copyGlyphImage(Glyph* glyph) +void GlyphTexture::copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info) { _image->dirty(); @@ -179,7 +179,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) // make sure the glyph image settings and the target image are consisent before copying. glyph->setPixelFormat(_image->getPixelFormat()); glyph->setInternalTextureFormat(_image->getPixelFormat()); - _image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); + _image->copySubImage(info->texturePositionX, info->texturePositionY, 0, glyph); return; } @@ -191,7 +191,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) int dest_columns = _image->s(); int dest_rows = _image->t(); - unsigned char* dest_data = _image->data(glyph->getTexturePositionX(),glyph->getTexturePositionY()); + unsigned char* dest_data = _image->data(info->texturePositionX, info->texturePositionY); int search_distance = getEffectMargin(glyph); @@ -204,11 +204,11 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph) float max_distance = sqrtf(float(search_distance)*float(search_distance)*2.0); - if ((left+glyph->getTexturePositionX())<0) left = -glyph->getTexturePositionX(); - if ((right+glyph->getTexturePositionX())>=dest_columns) right = dest_columns-glyph->getTexturePositionX()-1; + if ((left+info->texturePositionX)<0) left = -info->texturePositionX; + if ((right+info->texturePositionX)>=dest_columns) right = dest_columns-info->texturePositionX-1; - if ((lower+glyph->getTexturePositionY())<0) lower = -glyph->getTexturePositionY(); - if ((upper+glyph->getTexturePositionY())>=dest_rows) upper = dest_rows-glyph->getTexturePositionY()-1; + if ((lower+info->texturePositionY)<0) lower = -info->texturePositionY; + if ((upper+info->texturePositionY)>=dest_rows) upper = dest_rows-info->texturePositionY-1; int num_components = osg::Image::computeNumComponents(_image->getPixelFormat()); @@ -427,13 +427,18 @@ osg::Image* GlyphTexture::createImage() ++itr) { Glyph* glyph = itr->get(); - copyGlyphImage(glyph); + // copyGlyphImage(glyph); // TODO!!!!! + OSG_NOTICE<<"GlyphTexture::createImage() need to implement copy"<=_textureInfoList.size()) _textureInfoList.resize(technique+1); + if (!_textureInfoList[technique]) + { + _font->assignGlyphToGlyphTexture(this, technique); + } + return _textureInfoList[technique].get(); +} +////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Glyph3D +// Glyph3D::Glyph3D(Font* font, unsigned int glyphCode): osg::Referenced(true), _font(font), diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index f2ef6ecbb..4651edb5d 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -47,6 +47,16 @@ Text::Text(): { _supportsVertexBufferObjects = true; + char* ptr = 0; + if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + { + _shaderTechnique = ALL_FEATURES; + } + else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) + { + _shaderTechnique = GREYSCALE; + } + assignStateSet(); } @@ -129,7 +139,7 @@ osg::StateSet* Text::createStateSet() } } - if (activeFont->getShaderTechnique()!=GREYSCALE) + if (_shaderTechnique!=GREYSCALE) { ss<setMode(GL_BLEND, osg::StateAttribute::ON); - OSG_NOTICE<<"Text::createStateSet() activeFont->getShaderTechnique()="<getShaderTechnique()<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } - if (activeFont->getShaderTechnique()==GREYSCALE) + if (_shaderTechnique==GREYSCALE) { OSG_NOTICE<<"Using shaders/text_greyscale.frag"<getTexture()]; + const Glyph::TextureInfo* info = glyph->getOrCreateTextureInfo(_shaderTechnique); + GlyphTexture* glyphTexture = info ? info->texture : 0; + GlyphQuads& glyphquad = _textureGlyphQuadMap[glyphTexture]; glyphquad._glyphs.push_back(glyph); @@ -625,46 +637,54 @@ void Text::computeGlyphRepresentation() local.x() += bearing.x() * wr; local.y() += bearing.y() * hr; - - // Adjust coordinates and texture coordinates to avoid - // clipping the edges of antialiased characters. - osg::Vec2 mintc = glyph->getMinTexCoord(); - osg::Vec2 maxtc = glyph->getMaxTexCoord(); - osg::Vec2 vDiff = maxtc - mintc; - float texelMargin = glyph->getTexelMargin(); - - float fHorizTCMargin = texelMargin / glyph->getTexture()->getTextureWidth(); - float fVertTCMargin = texelMargin / glyph->getTexture()->getTextureHeight(); - float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); - float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y(); - - mintc.x() -= fHorizTCMargin; - mintc.y() -= fVertTCMargin; - maxtc.x() += fHorizTCMargin; - maxtc.y() += fVertTCMargin; - osg::Vec2 minc = local+osg::Vec2(0.0f-fHorizQuadMargin,0.0f-fVertQuadMargin); - osg::Vec2 maxc = local+osg::Vec2(width+fHorizQuadMargin,height+fVertQuadMargin); - - addGlyphQuad(glyph, minc, maxc, mintc, maxtc); - - // move the cursor onto the next character. - // also expand bounding box - switch(_layout) + const Glyph::TextureInfo* info = glyph->getOrCreateTextureInfo(_shaderTechnique); + if (info) { - case LEFT_TO_RIGHT: - cursor.x() += glyph->getHorizontalAdvance() * wr; - _textBB.expandBy(osg::Vec3(minc.x(), minc.y(), 0.0f)); //lower left corner - _textBB.expandBy(osg::Vec3(maxc.x(), maxc.y(), 0.0f)); //upper right corner - break; - case VERTICAL: - cursor.y() -= glyph->getVerticalAdvance() * hr; - _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner - _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner - break; - case RIGHT_TO_LEFT: - _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner - _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner - break; + + // Adjust coordinates and texture coordinates to avoid + // clipping the edges of antialiased characters. + osg::Vec2 mintc = info->minTexCoord; + osg::Vec2 maxtc = info->maxTexCoord; + osg::Vec2 vDiff = maxtc - mintc; + float texelMargin = info->texelMargin; + + float fHorizTCMargin = texelMargin / info->texture->getTextureWidth(); + float fVertTCMargin = texelMargin / info->texture->getTextureHeight(); + float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); + float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y(); + + mintc.x() -= fHorizTCMargin; + mintc.y() -= fVertTCMargin; + maxtc.x() += fHorizTCMargin; + maxtc.y() += fVertTCMargin; + osg::Vec2 minc = local+osg::Vec2(0.0f-fHorizQuadMargin,0.0f-fVertQuadMargin); + osg::Vec2 maxc = local+osg::Vec2(width+fHorizQuadMargin,height+fVertQuadMargin); + + addGlyphQuad(glyph, minc, maxc, mintc, maxtc); + + // move the cursor onto the next character. + // also expand bounding box + switch(_layout) + { + case LEFT_TO_RIGHT: + cursor.x() += glyph->getHorizontalAdvance() * wr; + _textBB.expandBy(osg::Vec3(minc.x(), minc.y(), 0.0f)); //lower left corner + _textBB.expandBy(osg::Vec3(maxc.x(), maxc.y(), 0.0f)); //upper right corner + break; + case VERTICAL: + cursor.y() -= glyph->getVerticalAdvance() * hr; + _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner + _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner + break; + case RIGHT_TO_LEFT: + _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner + _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner + break; + } + } + else + { + OSG_NOTICE<<"No TextureInfo for "< Date: Mon, 23 Oct 2017 16:07:24 +0100 Subject: [PATCH 63/74] Renamed text_sdf.frag to text.frag and removed text_greyscale_frag. Cleaned up setup of osgText::ShaderTechnique adding a NO_SHADER_TECHNIQUE option. --- include/osgText/Glyph | 1 + src/osgText/Glyph.cpp | 15 +- src/osgText/Text.cpp | 24 +- src/osgText/shaders/text_frag.cpp | 257 ++++++++++++++++++++ src/osgText/shaders/text_greyscale_frag.cpp | 35 --- src/osgText/shaders/text_sdf_frag.cpp | 257 -------------------- 6 files changed, 272 insertions(+), 317 deletions(-) create mode 100644 src/osgText/shaders/text_frag.cpp delete mode 100644 src/osgText/shaders/text_greyscale_frag.cpp delete mode 100644 src/osgText/shaders/text_sdf_frag.cpp diff --git a/include/osgText/Glyph b/include/osgText/Glyph index 782b402dd..125cf7476 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -40,6 +40,7 @@ class GlyphTexture; enum ShaderTechnique { + NO_TEXT_SHADER = 0x0, GREYSCALE = 0x1, SIGNED_DISTANCE_FIELD = 0x2, ALL_FEATURES = GREYSCALE | SIGNED_DISTANCE_FIELD diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index fbd793cfa..229efd14c 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -173,7 +173,7 @@ void GlyphTexture::copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info) { _image->dirty(); - if (_shaderTechnique==GREYSCALE) + if (_shaderTechnique<=GREYSCALE) { // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copying. glyphTexture="<getTextureWidthHint()); defineList["TEXTURE_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); + } + if (_shaderTechnique>GREYSCALE) + { defineList["SIGNED_DISTNACE_FIELD"] = osg::StateSet::DefinePair("1", osg::StateAttribute::ON); } @@ -200,7 +206,7 @@ osg::StateSet* Text::createStateSet() #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); - if (_shaderTechnique==GREYSCALE && shaderHint==osg::DisplaySettings::SHADER_NONE) + if (_shaderTechnique==NO_TEXT_SHADER && shaderHint==osg::DisplaySettings::SHADER_NONE) { OSG_NOTICE<<"Font::Font() Fixed function pipeline"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } - if (_shaderTechnique==GREYSCALE) { - OSG_NOTICE<<"Using shaders/text_greyscale.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text_greyscale.frag", text_greyscale_frag)); - } - else - { - OSG_NOTICE<<"Using shaders/text_sdf.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text_sdf.frag", text_sdf_frag)); + #include "shaders/text_frag.cpp" + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text.frag", text_frag)); } return stateset.release(); diff --git a/src/osgText/shaders/text_frag.cpp b/src/osgText/shaders/text_frag.cpp new file mode 100644 index 000000000..09b68444b --- /dev/null +++ b/src/osgText/shaders/text_frag.cpp @@ -0,0 +1,257 @@ +char text_frag[] = "$OSG_GLSL_VERSION\n" + "\n" + "#pragma import_defines( BACKDROP_COLOR, SHADOW, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" + "\n" + "#ifdef GL_ES\n" + " #extension GL_OES_standard_derivatives : enable\n" + " #ifndef GL_OES_standard_derivatives\n" + " #undef SIGNED_DISTNACE_FIELD\n" + " #endif\n" + "#endif\n" + "\n" + "#if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" + " #endif\n" + " #endif\n" + "#endif\n" + "\n" + "$OSG_PRECISION_FLOAT\n" + "\n" + "#if __VERSION__>=130\n" + " #define TEXTURE texture\n" + " #define TEXTURELOD textureLod\n" + " out vec4 osg_FragColor;\n" + "#else\n" + " #define TEXTURE texture2D\n" + " #define TEXTURELOD texture2DLod\n" + " #define osg_FragColor gl_FragColor\n" + "#endif\n" + "\n" + "\n" + "#if !defined(GL_ES) && __VERSION__>=130\n" + " #define ALPHA r\n" + " #define SDF g\n" + "#else\n" + " #define ALPHA a\n" + " #define SDF r\n" + "#endif\n" + "\n" + "\n" + "uniform sampler2D glyphTexture;\n" + "\n" + "$OSG_VARYING_IN vec2 texCoord;\n" + "$OSG_VARYING_IN vec4 vertexColor;\n" + "\n" + "#ifndef TEXTURE_DIMENSION\n" + "const float TEXTURE_DIMENSION = 1024.0;\n" + "#endif\n" + "\n" + "#ifndef GLYPH_DIMENSION\n" + "const float GLYPH_DIMENSION = 32.0;\n" + "#endif\n" + "\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" + "\n" + "float distanceFromEdge(vec2 tc)\n" + "{\n" + " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).SDF;\n" + " if (center_alpha==0.0) return -1.0;\n" + "\n" + " //float distance_scale = (1.0/4.0)*1.41;\n" + " float distance_scale = (1.0/6.0)*1.41;\n" + " //float distance_scale = (1.0/8.0)*1.41;\n" + "\n" + " return (center_alpha-0.5)*distance_scale;\n" + "}\n" + "\n" + "vec4 distanceFieldColorSample(float edge_distance, float blend_width, float blend_half_width)\n" + "{\n" + "#ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if (edge_distance>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return mix(vertexColor, BACKDROP_COLOR, smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else if (edge_distance>(blend_half_width-outline_width))\n" + " {\n" + " return BACKDROP_COLOR;\n" + " }\n" + " else if (edge_distance>-(outline_width+blend_half_width))\n" + " {\n" + " return vec4(BACKDROP_COLOR.rgb, ((blend_half_width+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>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return vec4(vertexColor.rgb, smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "#endif\n" + "}\n" + "\n" + "vec4 textColor(vec2 src_texCoord)\n" + "{\n" + " float sample_distance_scale = 0.75;\n" + " vec2 dx = dFdx(src_texCoord)*sample_distance_scale;\n" + " vec2 dy = dFdy(src_texCoord)*sample_distance_scale;\n" + "\n" + "\n" + " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" + "\n" + " // compute the appropriate number of samples required to avoid aliasing.\n" + " int maxNumSamplesAcrossSide = 4;\n" + "\n" + " int numSamplesX = int(TEXTURE_DIMENSION * length(dx));\n" + " int numSamplesY = int(TEXTURE_DIMENSION * length(dy));\n" + " if (numSamplesX<2) numSamplesX = 2;\n" + " if (numSamplesY<2) numSamplesY = 2;\n" + " if (numSamplesX>maxNumSamplesAcrossSide) numSamplesX = maxNumSamplesAcrossSide;\n" + " if (numSamplesY>maxNumSamplesAcrossSide) numSamplesY = maxNumSamplesAcrossSide;\n" + "\n" + "\n" + " vec2 delta_tx = dx/float(numSamplesX-1);\n" + " vec2 delta_ty = dy/float(numSamplesY-1);\n" + "\n" + " float numSamples = float(numSamplesX)*float(numSamplesY);\n" + " float scale = 1.0/numSamples;\n" + " vec4 total_color = vec4(0.0,0.0,0.0,0.0);\n" + "\n" + " float blend_width = 1.5*distance_across_pixel/numSamples;\n" + " float blend_half_width = blend_width*0.5;\n" + "\n" + " // check whether fragment is wholly within or outwith glyph body+outline\n" + " float cd = distanceFromEdge(src_texCoord); // central distance (distance from center to edge)\n" + " if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n" + "\n" + " #ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if ((-cd-outline_width-blend_half_width)>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside outline+glyph body\n" + " #else\n" + " if (-cd-blend_half_width>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside glyph body\n" + " #endif\n" + "\n" + "\n" + " // use multi-sampling to provide high quality antialised fragments\n" + " vec2 origin = src_texCoord - dx*0.5 - dy*0.5;\n" + " for(;numSamplesY>0; --numSamplesY)\n" + " {\n" + " vec2 pos = origin;\n" + " int numX = numSamplesX;\n" + " for(;numX>0; --numX)\n" + " {\n" + " vec4 c = distanceFieldColorSample(distanceFromEdge(pos), blend_width, blend_half_width);\n" + " total_color = total_color + c * c.a;\n" + " pos += delta_tx;\n" + " }\n" + " origin += delta_ty;\n" + " }\n" + "\n" + " total_color.rgb /= total_color.a;\n" + " total_color.a *= scale;\n" + "\n" + " return total_color;\n" + "}\n" + "\n" + "#else\n" + "\n" + "vec4 textColor(vec2 src_texCoord)\n" + "{\n" + "\n" + "#ifdef OUTLINE\n" + "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" + " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" + "\n" + " float outline_alpha = alpha;\n" + " vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" + "\n" + " float numSamples = 3.0;\n" + " delta_tc = delta_tc/(numSamples-1);\n" + "\n" + " float background_alpha = 1.0;\n" + "\n" + " for(float i=0.0; i1.0) outline_alpha = 1.0;\n" + "\n" + " if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline\n" + "\n" + " vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));\n" + " color.a = smoothstep(0.0, 1.0, outline_alpha);\n" + "\n" + " return color;\n" + "\n" + "#else\n" + "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" + " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" + " return vec4(vertexColor.rgb, vertexColor.a * alpha);\n" + "\n" + "#endif\n" + "}\n" + "\n" + "#endif\n" + "\n" + "\n" + "void main(void)\n" + "{\n" + " if (texCoord.x<0.0 && texCoord.y<0.0)\n" + " {\n" + " osg_FragColor = vertexColor;\n" + " return;\n" + " }\n" + "\n" + "#ifdef SHADOW\n" + " float scale = -1.0*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" + " vec2 delta_tc = SHADOW*scale;\n" + " vec4 shadow_color = textColor(texCoord+delta_tc);\n" + " shadow_color.rgb = BACKDROP_COLOR.rgb;\n" + "\n" + " vec4 glyph_color = textColor(texCoord);\n" + " vec4 color = mix(shadow_color, glyph_color, glyph_color.a);\n" + "#else\n" + " vec4 color = textColor(texCoord);\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_greyscale_frag.cpp b/src/osgText/shaders/text_greyscale_frag.cpp deleted file mode 100644 index 6d561fbce..000000000 --- a/src/osgText/shaders/text_greyscale_frag.cpp +++ /dev/null @@ -1,35 +0,0 @@ -char text_greyscale_frag[] = "$OSG_GLSL_VERSION\n" - "$OSG_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" - "#ifndef ALPHA\n" - " #if !defined(GL_ES) && __VERSION__>=130\n" - " #define ALPHA r\n" - " #else\n" - " #define ALPHA a\n" - " #endif\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 deleted file mode 100644 index 1864fc3c3..000000000 --- a/src/osgText/shaders/text_sdf_frag.cpp +++ /dev/null @@ -1,257 +0,0 @@ -char text_sdf_frag[] = "$OSG_GLSL_VERSION\n" - "\n" - "#pragma import_defines( BACKDROP_COLOR, SHADOW, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" - "\n" - "#ifdef GL_ES\n" - " #extension GL_OES_standard_derivatives : enable\n" - " #ifndef GL_OES_standard_derivatives\n" - " #undef SIGNED_DISTNACE_FIELD\n" - " #endif\n" - "#endif\n" - "\n" - "#if !defined(GL_ES)\n" - " #if __VERSION__>=400\n" - " #define osg_TextureQueryLOD textureQueryLod\n" - " #else\n" - " #extension GL_ARB_texture_query_lod : enable\n" - " #ifdef GL_ARB_texture_query_lod\n" - " #define osg_TextureQueryLOD textureQueryLOD\n" - " #endif\n" - " #endif\n" - "#endif\n" - "\n" - "$OSG_PRECISION_FLOAT\n" - "\n" - "#if __VERSION__>=130\n" - " #define TEXTURE texture\n" - " #define TEXTURELOD textureLod\n" - " out vec4 osg_FragColor;\n" - "#else\n" - " #define TEXTURE texture2D\n" - " #define TEXTURELOD texture2DLod\n" - " #define osg_FragColor gl_FragColor\n" - "#endif\n" - "\n" - "\n" - "#if !defined(GL_ES) && __VERSION__>=130\n" - " #define ALPHA r\n" - " #define SDF g\n" - "#else\n" - " #define ALPHA a\n" - " #define SDF r\n" - "#endif\n" - "\n" - "\n" - "uniform sampler2D glyphTexture;\n" - "\n" - "$OSG_VARYING_IN vec2 texCoord;\n" - "$OSG_VARYING_IN vec4 vertexColor;\n" - "\n" - "#ifndef TEXTURE_DIMENSION\n" - "const float TEXTURE_DIMENSION = 1024.0;\n" - "#endif\n" - "\n" - "#ifndef GLYPH_DIMENSION\n" - "const float GLYPH_DIMENSION = 32.0;\n" - "#endif\n" - "\n" - "#ifdef SIGNED_DISTNACE_FIELD\n" - "\n" - "float distanceFromEdge(vec2 tc)\n" - "{\n" - " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).SDF;\n" - " if (center_alpha==0.0) return -1.0;\n" - "\n" - " //float distance_scale = (1.0/4.0)*1.41;\n" - " float distance_scale = (1.0/6.0)*1.41;\n" - " //float distance_scale = (1.0/8.0)*1.41;\n" - "\n" - " return (center_alpha-0.5)*distance_scale;\n" - "}\n" - "\n" - "vec4 distanceFieldColorSample(float edge_distance, float blend_width, float blend_half_width)\n" - "{\n" - "#ifdef OUTLINE\n" - " float outline_width = OUTLINE*0.5;\n" - " if (edge_distance>blend_half_width)\n" - " {\n" - " return vertexColor;\n" - " }\n" - " else if (edge_distance>-blend_half_width)\n" - " {\n" - " return mix(vertexColor, BACKDROP_COLOR, smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" - " }\n" - " else if (edge_distance>(blend_half_width-outline_width))\n" - " {\n" - " return BACKDROP_COLOR;\n" - " }\n" - " else if (edge_distance>-(outline_width+blend_half_width))\n" - " {\n" - " return vec4(BACKDROP_COLOR.rgb, ((blend_half_width+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>blend_half_width)\n" - " {\n" - " return vertexColor;\n" - " }\n" - " else if (edge_distance>-blend_half_width)\n" - " {\n" - " return vec4(vertexColor.rgb, smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" - " }\n" - " else\n" - " {\n" - " return vec4(0.0, 0.0, 0.0, 0.0);\n" - " }\n" - "#endif\n" - "}\n" - "\n" - "vec4 textColor(vec2 src_texCoord)\n" - "{\n" - " float sample_distance_scale = 0.75;\n" - " vec2 dx = dFdx(src_texCoord)*sample_distance_scale;\n" - " vec2 dy = dFdy(src_texCoord)*sample_distance_scale;\n" - "\n" - "\n" - " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" - "\n" - " // compute the appropriate number of samples required to avoid aliasing.\n" - " int maxNumSamplesAcrossSide = 4;\n" - "\n" - " int numSamplesX = int(TEXTURE_DIMENSION * length(dx));\n" - " int numSamplesY = int(TEXTURE_DIMENSION * length(dy));\n" - " if (numSamplesX<2) numSamplesX = 2;\n" - " if (numSamplesY<2) numSamplesY = 2;\n" - " if (numSamplesX>maxNumSamplesAcrossSide) numSamplesX = maxNumSamplesAcrossSide;\n" - " if (numSamplesY>maxNumSamplesAcrossSide) numSamplesY = maxNumSamplesAcrossSide;\n" - "\n" - "\n" - " vec2 delta_tx = dx/float(numSamplesX-1);\n" - " vec2 delta_ty = dy/float(numSamplesY-1);\n" - "\n" - " float numSamples = float(numSamplesX)*float(numSamplesY);\n" - " float scale = 1.0/numSamples;\n" - " vec4 total_color = vec4(0.0,0.0,0.0,0.0);\n" - "\n" - " float blend_width = 1.5*distance_across_pixel/numSamples;\n" - " float blend_half_width = blend_width*0.5;\n" - "\n" - " // check whether fragment is wholly within or outwith glyph body+outline\n" - " float cd = distanceFromEdge(src_texCoord); // central distance (distance from center to edge)\n" - " if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n" - "\n" - " #ifdef OUTLINE\n" - " float outline_width = OUTLINE*0.5;\n" - " if ((-cd-outline_width-blend_half_width)>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside outline+glyph body\n" - " #else\n" - " if (-cd-blend_half_width>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside glyph body\n" - " #endif\n" - "\n" - "\n" - " // use multi-sampling to provide high quality antialised fragments\n" - " vec2 origin = src_texCoord - dx*0.5 - dy*0.5;\n" - " for(;numSamplesY>0; --numSamplesY)\n" - " {\n" - " vec2 pos = origin;\n" - " int numX = numSamplesX;\n" - " for(;numX>0; --numX)\n" - " {\n" - " vec4 c = distanceFieldColorSample(distanceFromEdge(pos), blend_width, blend_half_width);\n" - " total_color = total_color + c * c.a;\n" - " pos += delta_tx;\n" - " }\n" - " origin += delta_ty;\n" - " }\n" - "\n" - " total_color.rgb /= total_color.a;\n" - " total_color.a *= scale;\n" - "\n" - " return total_color;\n" - "}\n" - "\n" - "#else\n" - "\n" - "vec4 textColor(vec2 src_texCoord)\n" - "{\n" - "\n" - "#ifdef OUTLINE\n" - "\n" - " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" - " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" - "\n" - " float outline_alpha = alpha;\n" - " vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" - "\n" - " float numSamples = 3.0;\n" - " delta_tc = delta_tc/(numSamples-1);\n" - "\n" - " float background_alpha = 1.0;\n" - "\n" - " for(float i=0.0; i1.0) outline_alpha = 1.0;\n" - "\n" - " if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline\n" - "\n" - " vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));\n" - " color.a = smoothstep(0.0, 1.0, outline_alpha);\n" - "\n" - " return color;\n" - "\n" - "#else\n" - "\n" - " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" - " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" - " return vec4(vertexColor.rgb, vertexColor.a * alpha);\n" - "\n" - "#endif\n" - "}\n" - "\n" - "#endif\n" - "\n" - "\n" - "void main(void)\n" - "{\n" - " if (texCoord.x<0.0 && texCoord.y<0.0)\n" - " {\n" - " osg_FragColor = vertexColor;\n" - " return;\n" - " }\n" - "\n" - "#ifdef SHADOW\n" - " float scale = -1.0*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" - " vec2 delta_tc = SHADOW*scale;\n" - " vec4 shadow_color = textColor(texCoord+delta_tc);\n" - " shadow_color.rgb = BACKDROP_COLOR.rgb;\n" - "\n" - " vec4 glyph_color = textColor(texCoord);\n" - " vec4 color = mix(shadow_color, glyph_color, glyph_color.a);\n" - "#else\n" - " vec4 color = textColor(texCoord);\n" - "#endif\n" - "\n" - " if (color.a==0.0) discard;\n" - "\n" - " osg_FragColor = color;\n" - "}\n" - "\n"; From 1cd0a5fe03c1cf07a5a5a5a45464ba2c2ebb03cd Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 24 Oct 2017 11:36:00 +0100 Subject: [PATCH 64/74] Fixed Glyph::TextureInfo assignment bug --- include/osgText/Glyph | 11 ++--------- src/osgText/Font.cpp | 4 ++-- src/osgText/Glyph.cpp | 20 +++++++++++++++++++- src/osgText/Text.cpp | 1 - 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/include/osgText/Glyph b/include/osgText/Glyph index 125cf7476..2d1eafa05 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -100,16 +100,9 @@ public: float texelMargin; }; - void setTextureInfo(ShaderTechnique technique, TextureInfo* info) - { - if (technique>=_textureInfoList.size()) _textureInfoList.resize(technique+1); - _textureInfoList[technique] = info; - } + void setTextureInfo(ShaderTechnique technique, TextureInfo* info); - const TextureInfo* getTextureInfo(ShaderTechnique technique) const - { - return (technique<_textureInfoList.size()) ? _textureInfoList[technique].get() : 0; - } + const TextureInfo* getTextureInfo(ShaderTechnique technique) const; TextureInfo* getOrCreateTextureInfo(ShaderTechnique technique); diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index 7d6c61c1f..599dd6f6e 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -456,12 +456,12 @@ void Font::assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechniq itr!=_glyphTextureList.end() && !glyphTexture; ++itr) { - if ((*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get(); + if ((*itr)->getShaderTechnique()==shaderTechnique && (*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get(); } if (glyphTexture) { - //cout << " found space for texture "< stateset = new osg::StateSet; @@ -201,14 +201,14 @@ osg::StateSet* Text::createStateSet() stateset->setMode(GL_BLEND, osg::StateAttribute::ON); - OSG_NOTICE<<"Text::createStateSet() ShaderTechnique="<<_shaderTechnique<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); return stateset.release(); @@ -222,14 +222,14 @@ osg::StateSet* Text::createStateSet() stateset->setAttributeAndModes(program.get()); { - OSG_NOTICE<<"Using shaders/text.vert"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } { - OSG_NOTICE<<"Using shaders/text.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text.frag", text_frag)); From 1ecae6d33ae186d67eaee2cfa74dde9842d38cc1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 24 Oct 2017 12:34:48 +0100 Subject: [PATCH 66/74] Improved the Text::_shaderTechnique default setting using OSG_TEXT_SHADER_TECHNIQUE env var, options are ALL_FEATURES, GREYSCALE, SIGNED_DISTANCE_FIELD, SDF, NO_TEXT_SHADER, NONE. --- src/osgText/Text.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 12931ffaf..0bd1efade 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -48,19 +48,16 @@ Text::Text(): _supportsVertexBufferObjects = true; char* ptr = 0; - if ((ptr = getenv("OSG_SDF_TEXT")) != 0) + if ((ptr = getenv("OSG_TEXT_SHADER_TECHNIQUE")) != 0) { - _shaderTechnique = ALL_FEATURES; - } - else if ((ptr = getenv("OSG_GREYSCALE_TEXT")) != 0) - { - _shaderTechnique = GREYSCALE; - } - else if ((ptr = getenv("OSG_NO_TEXT_SHADER")) != 0) - { - _shaderTechnique = NO_TEXT_SHADER; + if (strcmp(ptr,"ALL_FEATURES")==0) _shaderTechnique = ALL_FEATURES; + else if (strcmp(ptr,"GREYSCALE")==0) _shaderTechnique = GREYSCALE; + else if (strcmp(ptr,"SIGNED_DISTANCE_FIELD")==0 || strcmp(ptr,"SDF")==0) _shaderTechnique = SIGNED_DISTANCE_FIELD; + else if (strcmp(ptr,"NO_TEXT_SHADER")==0 || strcmp(ptr,"NONE")==0) _shaderTechnique = NO_TEXT_SHADER; } + OSG_NOTICE<<"Text::Text() "<<_shaderTechnique< Date: Tue, 24 Oct 2017 14:46:13 +0100 Subject: [PATCH 67/74] Added DisplaySettings:s/getgTextShaderTechnique() and OSG_TEXT_SHADER_TECHNIQUE env var support to DisplaySettings. Added using of DisplaySettings:getgTextShaderTechnique() to Text default constructor. Added better debug output control in Text.cpp --- include/osg/DisplaySettings | 5 +++++ src/osg/DisplaySettings.cpp | 7 +++++++ src/osgText/Text.cpp | 40 +++++++++++++++++++++++-------------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/include/osg/DisplaySettings b/include/osg/DisplaySettings index 393aa7415..0609cf0c6 100644 --- a/include/osg/DisplaySettings +++ b/include/osg/DisplaySettings @@ -325,6 +325,10 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced void setShaderHint(ShaderHint hint, bool setShaderValues=true); ShaderHint getShaderHint() const { return _shaderHint; } + /** Set the TextShaderTechnique that is used in the Text default constructor to choose which osgText::ShaderTechnique to use.*/ + void setTextShaderTechnique(const std::string& str) { _textShaderTechnique = str; } + const std::string& getTextShaderTechnique() const { return _textShaderTechnique; } + void setKeystoneHint(bool enabled) { _keystoneHint = enabled; } bool getKeystoneHint() const { return _keystoneHint; } @@ -423,6 +427,7 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced VertexBufferHint _vertexBufferHint; ShaderHint _shaderHint; + std::string _textShaderTechnique; bool _keystoneHint; FileNames _keystoneFileNames; diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 8346d11ed..5e7259956 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -385,6 +385,9 @@ static ApplicationUsageProxy DisplaySetting_e31(ApplicationUsage::ENVIRONMENTAL_ static ApplicationUsageProxy DisplaySetting_e32(ApplicationUsage::ENVIRONMENTAL_VARIABLE, "OSG_VERTEX_BUFFER_HINT ", "Set the hint to what backend osg::Geometry implementation to use. NO_PREFERENCE | VERTEX_BUFFER_OBJECT | VERTEX_ARRAY_OBJECT"); +static ApplicationUsageProxy DisplaySetting_e33(ApplicationUsage::ENVIRONMENTAL_VARIABLE, + "OSG_TEXT_SHADER_TECHNIQUE ", + "Set the defafult osgText::ShaderTechnique. ALL_FEATURES | ALL | GREYSCALE | SIGNED_DISTANCE_FIELD | SDF | NO_TEXT_SHADER | NONE"); void DisplaySettings::readEnvironmentalVariables() { @@ -740,6 +743,10 @@ void DisplaySettings::readEnvironmentalVariables() } } + if ((ptr = getenv("OSG_TEXT_SHADER_TECHNIQUE")) != 0) + { + setTextShaderTechnique(ptr); + } if( (ptr = getenv("OSG_KEYSTONE")) != 0) { diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 0bd1efade..cfc7cf969 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -28,6 +28,8 @@ #include #include +#define DEBUG_MESSAGE_LEVEL osg::INFO +#define DEBUG_MESSAGE osg::notify(DEBUG_MESSAGE_LEVEL) using namespace osg; using namespace osgText; @@ -47,17 +49,15 @@ Text::Text(): { _supportsVertexBufferObjects = true; - char* ptr = 0; - if ((ptr = getenv("OSG_TEXT_SHADER_TECHNIQUE")) != 0) + const std::string& str = osg::DisplaySettings::instance()->getTextShaderTechnique(); + if (!str.empty()) { - if (strcmp(ptr,"ALL_FEATURES")==0) _shaderTechnique = ALL_FEATURES; - else if (strcmp(ptr,"GREYSCALE")==0) _shaderTechnique = GREYSCALE; - else if (strcmp(ptr,"SIGNED_DISTANCE_FIELD")==0 || strcmp(ptr,"SDF")==0) _shaderTechnique = SIGNED_DISTANCE_FIELD; - else if (strcmp(ptr,"NO_TEXT_SHADER")==0 || strcmp(ptr,"NONE")==0) _shaderTechnique = NO_TEXT_SHADER; + if (str=="ALL_FEATURES" || str=="ALL") _shaderTechnique = ALL_FEATURES; + else if (str=="GREYSCALE") _shaderTechnique = GREYSCALE; + else if (str=="SIGNED_DISTANCE_FIELD" || str=="SDF") _shaderTechnique = SIGNED_DISTANCE_FIELD; + else if (str=="NO_TEXT_SHADER" || str=="NONE") _shaderTechnique = NO_TEXT_SHADER; } - OSG_NOTICE<<"Text::Text() "<<_shaderTechnique< stateset = new osg::StateSet; @@ -198,14 +211,11 @@ osg::StateSet* Text::createStateSet() stateset->setMode(GL_BLEND, osg::StateAttribute::ON); - OSG_INFO<<"Text::createStateSet() ShaderTechnique="<<_shaderTechnique<getShaderHint(); if (_shaderTechnique==NO_TEXT_SHADER && shaderHint==osg::DisplaySettings::SHADER_NONE) { - OSG_INFO<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); return stateset.release(); @@ -219,14 +229,14 @@ osg::StateSet* Text::createStateSet() stateset->setAttributeAndModes(program.get()); { - OSG_INFO<<"Using shaders/text.vert"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); } { - OSG_INFO<<"Using shaders/text.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text.frag", text_frag)); From 8f658fbc3212dd1f03c99e5d92374e2676f6f1f9 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 24 Oct 2017 15:14:23 +0100 Subject: [PATCH 68/74] Updated from OpenSceneGraph-Data/shaders/text.frag to address GLSL int to float conversion warning --- src/osgText/shaders/text_frag.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osgText/shaders/text_frag.cpp b/src/osgText/shaders/text_frag.cpp index 09b68444b..03661dd92 100644 --- a/src/osgText/shaders/text_frag.cpp +++ b/src/osgText/shaders/text_frag.cpp @@ -186,7 +186,7 @@ char text_frag[] = "$OSG_GLSL_VERSION\n" " vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" "\n" " float numSamples = 3.0;\n" - " delta_tc = delta_tc/(numSamples-1);\n" + " delta_tc = delta_tc/(numSamples-1.0);\n" "\n" " float background_alpha = 1.0;\n" "\n" From c8bd6fd1006b16c4ea64a8d1e3912ac2d01532d7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 24 Oct 2017 16:04:14 +0100 Subject: [PATCH 69/74] Added stats handler --- examples/osglauncher/osglauncher.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/osglauncher/osglauncher.cpp b/examples/osglauncher/osglauncher.cpp index 00c98b42c..ce7e4c553 100644 --- a/examples/osglauncher/osglauncher.cpp +++ b/examples/osglauncher/osglauncher.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -424,6 +425,9 @@ int main( int argc, char **argv ) // add the handler for doing the picking viewer.addEventHandler(new PickHandler(&viewer,updateText.get())); + // add the stats handler + viewer.addEventHandler(new osgViewer::StatsHandler); + osg::Group* root = new osg::Group(); root->addChild( setupGraph() ); From 248805fedd53dc3ed74e88711f72b8a7b62fc687 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 25 Oct 2017 16:13:26 +0100 Subject: [PATCH 70/74] Fixed pre compilation osg::Program state leaking into the main scene graph rendering --- include/osgUtil/GLObjectsVisitor | 3 +++ src/osgUtil/GLObjectsVisitor.cpp | 17 +++++++++++++++++ src/osgViewer/Renderer.cpp | 3 +-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/osgUtil/GLObjectsVisitor b/include/osgUtil/GLObjectsVisitor index b9a130f3e..c52d6cce6 100644 --- a/include/osgUtil/GLObjectsVisitor +++ b/include/osgUtil/GLObjectsVisitor @@ -97,6 +97,9 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor void apply(osg::Drawable& drawable); void apply(osg::StateSet& stateset); + /** Do a compile traversal and then reset any state,*/ + void compile(osg::Node& node); + protected: typedef std::set DrawableAppliedSet; diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index b194b7990..25aa8c896 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -153,6 +153,23 @@ void GLObjectsVisitor::apply(osg::StateSet& stateset) } } +void GLObjectsVisitor::compile(osg::Node& node) +{ + if (_renderInfo.getState()) + { + node.accept(*this); + + if (_lastCompiledProgram.valid()) + { + osg::State* state = _renderInfo.getState(); + osg::GLExtensions* extensions = state->get(); + extensions->glUseProgram(0); + _renderInfo.getState()->setLastAppliedProgramObject(0); + } + } +} + + ///////////////////////////////////////////////////////////////// // // GLObjectsOperation diff --git a/src/osgViewer/Renderer.cpp b/src/osgViewer/Renderer.cpp index 71f93ccc5..06620af32 100644 --- a/src/osgViewer/Renderer.cpp +++ b/src/osgViewer/Renderer.cpp @@ -571,7 +571,6 @@ void Renderer::compile() { DEBUG_MESSAGE<<"Renderer::compile()"<getState()); - sceneView->getSceneData()->accept(glov); + glov.compile(*(sceneView->getSceneData())); } sceneView->getState()->checkGLErrors("After Renderer::compile"); From fa58d0164463dbec8a4fe69fbaf2c0d95b56a747 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 25 Oct 2017 16:29:25 +0100 Subject: [PATCH 71/74] Added optimization for text where the colour alpha value is 0.0, returning early to aovid any GL calls. --- src/osgText/Text.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index cfc7cf969..94ac0e923 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -1115,6 +1115,8 @@ void Text::drawImplementation(osg::RenderInfo& renderInfo) const void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const { + if (colorMultiplier.a()==0.0f || _color.a()==0.0f) return; + osg::VertexArrayState* vas = state.getCurrentVertexArrayState(); bool usingVertexBufferObjects = state.useVertexBufferObject(_supportsVertexBufferObjects && _useVertexBufferObjects); bool usingVertexArrayObjects = usingVertexBufferObjects && state.useVertexArrayObject(_useVertexArrayObject); From 671ea7ae7453262f6e97943dbf504edc80a24df1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Oct 2017 12:02:56 +0100 Subject: [PATCH 72/74] Added command line parsing to aid with testing of osgText by allowing osgText::FadeText to be created with various options --- examples/osgfadetext/osgfadetext.cpp | 70 +++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/examples/osgfadetext/osgfadetext.cpp b/examples/osgfadetext/osgfadetext.cpp index 37b0eafe2..308b482b6 100644 --- a/examples/osgfadetext/osgfadetext.cpp +++ b/examples/osgfadetext/osgfadetext.cpp @@ -121,10 +121,70 @@ osg::Node* createFadeText(osg::EllipsoidModel* ellipsoid) } -int main(int, char**) +class TextSettings : public osg::NodeVisitor { +public: + TextSettings(osg::ArgumentParser& arguments): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _backdropTypeSet(false), + _backdropType(osgText::Text::NONE), + _shaderTechniqueSet(false), + _shaderTechnique(osgText::GREYSCALE) + { + if (arguments.read("--outline")) + { + _backdropTypeSet = true; + _backdropType = osgText::Text::OUTLINE; + } + if (arguments.read("--sdf")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::SIGNED_DISTANCE_FIELD; + } + if (arguments.read("--all")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::ALL_FEATURES; + } + if (arguments.read("--greyscale")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::GREYSCALE; + } + if (arguments.read("--no-shader")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::NO_TEXT_SHADER; + } + } + + void apply(osg::Drawable& drawable) + { + osgText::Text* text = dynamic_cast(&drawable); + if (text) + { + if (_backdropTypeSet) + { + text->setBackdropType(_backdropType); + text->setBackdropOffset(0.1f); + text->setBackdropColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); + } + if (_shaderTechniqueSet) text->setShaderTechnique(_shaderTechnique); + } + } + + bool _backdropTypeSet; + osgText::Text::BackdropType _backdropType; + bool _shaderTechniqueSet; + osgText::ShaderTechnique _shaderTechnique; +}; + +int main(int argc, char** argv) +{ + osg::ArgumentParser arguments(&argc, argv); + // construct the viewer. - osgViewer::Viewer viewer; + osgViewer::Viewer viewer(arguments); viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); viewer.getCamera()->setNearFarRatio(0.00001f); @@ -144,6 +204,12 @@ int main(int, char**) csn->addChild(createFadeText(csn->getEllipsoidModel())); } + if (arguments.argc()>1) + { + TextSettings textSettings(arguments); + root->accept(textSettings); + } + viewer.setCameraManipulator(new osgGA::TerrainManipulator); return viewer.run(); From 5918735ebca45b71554c7446d31fa08d7b073ff1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Oct 2017 12:03:56 +0100 Subject: [PATCH 73/74] Added update of glyph representation to ensure all the glyphs are assigned to the required GlyphTextures --- src/osgText/Text.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 94ac0e923..46c857639 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -90,6 +90,8 @@ void Text::setShaderTechnique(ShaderTechnique technique) _shaderTechnique = technique; assignStateSet(); + + computeGlyphRepresentation(); } osg::StateSet* Text::createStateSet() From 1e896777d1e52fbaf0e0cb6232c27d849cc63fac Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 26 Oct 2017 12:08:00 +0100 Subject: [PATCH 74/74] Updated from OpenSceneGraph-Data/shader/text.frag to add fixes to handling of vertexColor's alpha values --- src/osgText/shaders/text_frag.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/osgText/shaders/text_frag.cpp b/src/osgText/shaders/text_frag.cpp index 03661dd92..02c253100 100644 --- a/src/osgText/shaders/text_frag.cpp +++ b/src/osgText/shaders/text_frag.cpp @@ -79,15 +79,15 @@ char text_frag[] = "$OSG_GLSL_VERSION\n" " }\n" " else if (edge_distance>-blend_half_width)\n" " {\n" - " return mix(vertexColor, BACKDROP_COLOR, smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " return mix(vertexColor, vec4(BACKDROP_COLOR.rgb, BACKDROP_COLOR.a*vertexColor.a), smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" " }\n" " else if (edge_distance>(blend_half_width-outline_width))\n" " {\n" - " return BACKDROP_COLOR;\n" + " return vec4(BACKDROP_COLOR.rgb, BACKDROP_COLOR.a*vertexColor.a);\n" " }\n" " else if (edge_distance>-(outline_width+blend_half_width))\n" " {\n" - " return vec4(BACKDROP_COLOR.rgb, ((blend_half_width+outline_width+edge_distance)/blend_width));\n" + " return vec4(BACKDROP_COLOR.rgb, vertexColor.a * ((blend_half_width+outline_width+edge_distance)/blend_width));\n" " }\n" " else\n" " {\n" @@ -100,7 +100,7 @@ char text_frag[] = "$OSG_GLSL_VERSION\n" " }\n" " else if (edge_distance>-blend_half_width)\n" " {\n" - " return vec4(vertexColor.rgb, smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " return vec4(vertexColor.rgb, vertexColor.a * smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" " }\n" " else\n" " {\n" @@ -214,7 +214,7 @@ char text_frag[] = "$OSG_GLSL_VERSION\n" " if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline\n" "\n" " vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));\n" - " color.a = smoothstep(0.0, 1.0, outline_alpha);\n" + " color.a = vertexColor.a * smoothstep(0.0, 1.0, outline_alpha);\n" "\n" " return color;\n" "\n"