查看: 2531|回复: 6

如何绘制带背景的Text

[复制链接]

该用户从未签到

发表于 2011-3-28 16:01:58 | 显示全部楼层 |阅读模式
如何绘制带背景的Text,要求背景可以挡住文字后的场景,当然不能挡住文字。
我自己尝试继承了osgText::Text,然后重写drawImplementation,该函数基本与osgText::Text中相同,只是在if ()drawMode & BOUNDINGBOX){}中添加了一个GL_QUADS,但是效果有点不理想,虽然quad挡住了挡住文字后的场景,但是文字附近是透明的,可以看见后面的场景。各位是否有更好的方法或者意见,谢谢各位!

该用户从未签到

发表于 2011-3-28 16:30:25 | 显示全部楼层
您所叙述的是否是HUD文字的意思?

该用户从未签到

 楼主| 发表于 2011-3-28 16:35:52 | 显示全部楼层
不是HUD相机中的文字,是那种始终面朝观众setAutoRorateToScreen(true)的文字

该用户从未签到

发表于 2011-3-29 08:32:42 | 显示全部楼层
那么我不是特别理解您所表述的意思,能否用示意图之类的方式来明确一下您的需求?

该用户从未签到

 楼主| 发表于 2011-3-30 09:03:32 | 显示全部楼层
本帖最后由 anlingbin 于 2011-3-30 09:05 编辑

文字周围透出文字后的颜色

文字周围透出文字后的颜色

上图文字周围透出背景色。

这些是继承自osgText::Text的drawImplementation:
void BackgrandText::drawImplementation(osg::RenderInfo& renderInfo) const
{
        //cout << "drawImplementation" << endl;
        drawImplementation( *renderInfo.getState(), osg::Vec4(1.0f,1.0f,1.0f,1.0f) );
}

void BackgrandText::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplier) const
{
        unsigned int contextID = state.getContextID();

        state.applyMode(GL_BLEND,true);
#if 1   
        state.applyTextureMode(0,GL_TEXTURE_2D,true);
#else
        state.applyTextureMode(0,GL_TEXTURE_2D,false);
#endif
        state.applyTextureAttribute(0,getActiveFont()->getTexEnv());

        if (_characterSizeMode!=OBJECT_COORDS || _autoRotateToScreen)
        {
                int frameNumber = state.getFrameStamp()?state.getFrameStamp()->getFrameNumber():0;
                AutoTransformCache& atc = _autoTransformCache[contextID];
                const osg::Matrix& modelview = state.getModelViewMatrix();
                const osg::Matrix& projection = state.getProjectionMatrix();

                osg::Vec3 newTransformedPosition = _position*modelview;

                int width = atc._width;
                int height = atc._height;

                const osg::Viewport* viewport = state.getCurrentViewport();
                if (viewport)
                {
                        width = static_cast<int>(viewport->width());
                        height = static_cast<int>(viewport->height());
                }

                bool doUpdate = atc._traversalNumber==-1;
                if (atc._traversalNumber>=0)
                {
                        if (atc._modelview!=modelview)
                        {
                                doUpdate = true;
                        }
                        else if (width!=atc._width || height!=atc._height)
                        {
                                doUpdate = true;
                        }
                        else if (atc._projection!=projection)
                        {
                                doUpdate = true;
                        }
                }

                atc._traversalNumber = frameNumber;
                atc._width = width;
                atc._height = height;

                if (doUpdate)
                {   
                        atc._transformedPosition = newTransformedPosition;
                        atc._projection = projection;
                        atc._modelview = modelview;

                        computePositions(contextID);
                }

        }


        // Ensure that the glyph coordinates have been transformed for
        // this context id.

        if ( !_textureGlyphQuadMap.empty() )
        {
                const GlyphQuads& glyphquad = (_textureGlyphQuadMap.begin())->second;
                if ( glyphquad._transformedCoords[contextID].empty() )
                {
                        computePositions(contextID);
                }
        }

        glNormal3fv(_normal.ptr());

        if (_drawMode & TEXT)
        {

                state.disableAllVertexArrays();

                // Okay, since ATI's cards/drivers are not working correctly,
                // we need alternative solutions to glPolygonOffset.
                // So this is a pick your poison approach. Each alternative
                // backend has trade-offs associated with it, but with luck,
                // the user may find that works for them.
                if(_backdropType != NONE)
                {
                        switch(_backdropImplementation)
                        {
                        case POLYGON_OFFSET:
                                renderWithPolygonOffset(state,colorMultiplier);
                                break;
                        case NO_DEPTH_BUFFER:
                                renderWithNoDepthBuffer(state,colorMultiplier);
                                break;
                        case DEPTH_RANGE:
                                renderWithDepthRange(state,colorMultiplier);
                                break;
                        case STENCIL_BUFFER:
                                renderWithStencilBuffer(state,colorMultiplier);
                                break;
                        default:
                                renderWithPolygonOffset(state,colorMultiplier);
                        }
                }
                else
                {
                        renderOnlyForegroundText(state,colorMultiplier);
                }
        }

        if (_drawMode & BOUNDINGBOX)
        {
                if (_textBB.valid())
                {
                        state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);

                        const osg::Matrix& matrix = _autoTransformCache[contextID]._matrix;

                        osg::BoundingBox bb( _textBB.xMin()-10,_textBB.yMin()-10,_textBB.zMax()-0.01,
                                                                 _textBB.xMax()+10,_textBB.yMax()+10,_textBB.zMax()-0.01 );

                        osg::Vec3 l00(osg::Vec3(bb.xMin(),bb.yMin(),bb.zMax())*matrix);
                        osg::Vec3 l10(osg::Vec3(bb.xMax(),bb.yMin(),bb.zMax())*matrix);
                        osg::Vec3 l11(osg::Vec3(bb.xMax(),bb.yMax(),bb.zMax())*matrix);
                        osg::Vec3 l01(osg::Vec3(bb.xMin(),bb.yMax(),bb.zMax())*matrix);

                        osg::Vec4 color( 1-_backColor.x(),1-_backColor.y(),1-_backColor.z(), 1 );
                        glColor4fv(color.ptr());
                        //glLineWidth(1.5);
                        glBegin(GL_LINE_LOOP);
                        glVertex3fv(l00.ptr());
                        glVertex3fv(l10.ptr());
                        glVertex3fv(l11.ptr());
                        glVertex3fv(l01.ptr());
                        glEnd();

                        if ( _drawBack )
                        {
                                glColor4fv(_backColor.ptr());
                                glBegin(GL_QUADS);
                                glVertex3fv(l00.ptr());
                                glVertex3fv(l10.ptr());
                                glVertex3fv(l11.ptr());
                                glVertex3fv(l01.ptr());
                                glEnd();
                        }

                }
        }   

        if (_drawMode & ALIGNMENT)
        {
                glColor4fv(colorMultiplier.ptr());

                float cursorsize = _characterHeight*0.5f;

                const osg::Matrix& matrix = _autoTransformCache[contextID]._matrix;

                osg::Vec3 hl(osg::Vec3(_offset.x()-cursorsize,_offset.y(),_offset.z())*matrix);
                osg::Vec3 hr(osg::Vec3(_offset.x()+cursorsize,_offset.y(),_offset.z())*matrix);
                osg::Vec3 vt(osg::Vec3(_offset.x(),_offset.y()-cursorsize,_offset.z())*matrix);
                osg::Vec3 vb(osg::Vec3(_offset.x(),_offset.y()+cursorsize,_offset.z())*matrix);

                state.applyTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::OFF);

                glBegin(GL_LINES);
                glVertex3fv(hl.ptr());
                glVertex3fv(hr.ptr());
                glVertex3fv(vt.ptr());
                glVertex3fv(vb.ptr());
                glEnd();

        }  
}




main函数:
#include <osgViewer/Viewer>
#include <osgGA/TrackballManipulator>
#include "BackgrandText.h"

using namespace std;

void main()
{
        osgViewer::Viewer viewer;
        viewer.setUpViewInWindow(100,100,1000,800);

        osg::Geode* geode = new osg::Geode;
        viewer.setSceneData( geode );


        BackgrandText* text = new BackgrandText;
        text->setFont( osgText::readFontFile("simhei.ttf") );
        text->setText( L"直abcgzxy123456线7890是" );
        text->setColor( osg::Vec4( 1, 0, 0, 1 ) );

        text->setAutoRotateToScreen( true );
        text->setCharacterSize( 80 );
        text->setCharacterSizeMode( osgText::Text::SCREEN_COORDS );

        text->setAlignment( osgText::Text::CENTER_CENTER );
        text->setDrawMode( osgText::Text::TEXT | osgText::Text::BOUNDINGBOX );
        geode->addDrawable( text );


        viewer.setCameraManipulator( new osgGA::TrackballManipulator() );

        viewer.realize();
        while(!viewer.done())
        {
                viewer.frame();
        }

}

该用户从未签到

发表于 2011-3-31 16:04:27 | 显示全部楼层
注意那个对象的绘制顺序,它应该在最后被绘制

该用户从未签到

发表于 2012-4-20 20:34:23 | 显示全部楼层
anlingbin 发表于 2011-3-30 09:03
上图文字周围透出背景色。

这些是继承自osgText::Text的drawImplementation:

你做的是船体标注?我现在也在做耶?这个效果你实现了吗?能共享一下吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表