osgText使用版本osg3.6.5

前言

osgText 库定义了一个命名空间,osgText。在这个命名空间中有一些十分实
用的字体加载和文字渲染类。
osgText 库的核心组件是osgText::Text 类。Text 继承自Drawable,因此用户
程序应当使用addDrawable()方法把Text 实例添加到Geode 中(与添加Geometry
实例的方法相同)。Text 可用于显示一个任意长度的字符串。因此,用户程序可
以为每个将要显示的字符串创建一个相应的Text 对象。
osgText 库的另一个核心组件是osgText::Font 类。osgText 的函数可以根据字
体文件的名称来创建Font 对象。Font 类使用FreeType 插件来读取字体文件。用
户程序将Font 对象和Text 对象相关联时,Font 将创建一个用于绘制字符串图形
的纹理贴图。在渲染时,Text 将使用与该图形相符的纹理坐标,为文本中的每一
个字符绘制一个已添加纹理的四边形。osgText 库还定义了一个String 类,以支
持多字节字符(multibyte)和各类文字编码。

代码

#include "osg/Group"
#include "osgText/Text"
#include "osg/Geode"
#include "osg/Geometry"
#include "osgText/Font"
#include "osgDB/WriteFile"
#include "osgDB/ReadFile"
#include "osg/Node"
#include "osg/ref_ptr"
#include "osgViewer/View"
#include "osgViewer/Viewer"
#include "osg/Matrix"
#include "osg/MatrixTransform"

//创建背板
osg::ref_ptr<osg::Drawable> createBase()
{
    
    
	osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;

	osg::Matrix m;
	osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform();
	/*m.makeRotate(m,)*/


	osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array;
	geom->setVertexArray(v.get());
	v->push_back(osg::Vec3(-1.f, 0.f, -1.f));
	v->push_back(osg::Vec3(1.f, 0.f, -1.f));
	v->push_back(osg::Vec3(1.f, 0.f, 1.f));
	v->push_back(osg::Vec3(-1.f, 0.f, 1.f));

	osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array;
	geom->setColorArray(c.get());
	/*setColorBinding()和setNormalBinding() - 这些方法用于设置Geometry 类
		中颜色和法线数据的绑定方式。其输入参数为Geometry 类的枚举量。
		清单2 - 1 中,颜色绑定方式为osg::Geometry::BIND_PER_VERTEX,即
		每种颜色对应一个顶点。而法线的绑定方式为
		osg::Geometry::BIND_OVERALL,即整个Geometry 几何体对应唯一的
		一个法线数据。*/
	geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
	c->push_back(osg::Vec4(1.f, 1.f, 0.f, 1.f));
	c->push_back(osg::Vec4(0.f, 1.f, 0.f, 1.f));
	c->push_back(osg::Vec4(0.f, 0.f, 1.f, 1.f));
	c->push_back(osg::Vec4(1.f, 1.f, 1.f, 1.f));

	//法线
	osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array;
	geom->setNormalArray(n.get());
	/*而法线的绑定方式为
		osg::Geometry::BIND_OVERALL,即整个Geometry 几何体对应唯一的
		一个法线数据。*/
	geom->setNormalBinding(osg::Geometry::BIND_OVERALL);
	n->push_back(osg::Vec3(0.f, 1.f, 0.f));

	geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4));
	
	return (geom.release());

}

osg::ref_ptr<osg::Node> createSceneGraph()
{
    
    
	// Create the root (and only) node.
	osg::ref_ptr<osg::Geode> geode = new osg::Geode;
	geode->addDrawable(createBase());

	//字体
	osg::ref_ptr<osgText::Font> font = new osgText::Font;
	font = osgText::readFontFile("fonts/arial.ttf");


	

	osg::Vec4 white(osg::Vec4(1.f, 1.f, 1.f, 1.f));
	{
    
    
		//Text.osg文件中有个默认参数:autoRotateToScreen,始终保持字体面向屏幕
		osg::ref_ptr<osgText::Text> text = new osgText::Text;
		text->setFont(font.get());
		text->setColor(osg::Vec4(0.f, 1.f, 1.f, 1.f));  //青色
		text->setCharacterSize(.15f);
		text->setPosition(osg::Vec3(1.f, 0.f, 1.f));
		/*如果要创建一个一直朝向视口的广告牌形式的文
			字,可以使用Text::SCREEN。*/
		text->setAxisAlignment(osgText::Text::XY_PLANE);//因为没有设置SCREEN,所以在Text.osg文件中没有autoRotateToScreen TRUE 属性
		text->setAlignment(osgText::Text::LEFT_TOP);  //左上基准点开始的字体
		text->setText("right_right");
		geode->addDrawable(text.get());
	}

	{
    
    
		osg::ref_ptr<osgText::Text> text = new osgText::Text;
		text->setFont(font.get());
		text->setColor(osg::Vec4(1.f, 0.f, 0.f, 1.f));
		text->setCharacterSize(.15f);
		text->setPosition(osg::Vec3(-1.f, 0.f, 0.f));
		text->setAxisAlignment(osgText::Text::SCREEN); //因为没有设置SCREEN,所以在Text.osg文件中有autoRotateToScreen TRUE 属性
		text->setText("right_right");
		text->setText("Top_left");
		geode->addDrawable(text.get());
	}

	{
    
    
		osg::ref_ptr<osgText::Text> text = new osgText::Text;
		text->setFont(font.get());
		text->setColor(osg::Vec4(0.f, 1.f, 0.f, 1.f));
		text->setCharacterSize(.15f);
		text->setPosition(osg::Vec3(-1.f, -1.f, 0.f));
		text->setAxisAlignment(osgText::Text::SCREEN);
		text->setText("Bottom_left");
		geode->addDrawable(text.get());
	}

	{
    
    
		osg::ref_ptr<osgText::Text> text = new osgText::Text;
		text->setFont(font.get());
		text->setColor(osg::Vec4(0.f, 0.f, 1.f, 1.f));
		text->setCharacterSize(.15f);
		text->setPosition(osg::Vec3(1.f, -1.f, 0.f));
		text->setAxisAlignment(osgText::Text::SCREEN); //因为没有设置SCREEN,所以在Text.osg文件中有autoRotateToScreen TRUE 属性
		text->setText("Bottom_right");
		geode->addDrawable(text.get());
	}

	{
    
    
		osg::ref_ptr<osgText::Text> text = new osgText::Text;
		text->setFont(font.get());
		/*用户程序通常需要改变字体纹理贴图的图形分辨率,以避免文字出现模糊。
			缺省情况下,osgText 为每个图形分配了32×32 个像素元。要改变这个数值的话,
			可以使用Text::setFontResolution()方法。下面的代码增加了字体的分辨率,osgText
			将因此为每个图形分配128×128 个像素元。*/
		text->setFontResolution(128, 128);
		text->setColor(osg::Vec4(1.f, 0.f, 1.f, 1.f));
		text->setCharacterSize(.15f);
		text->setPosition(osg::Vec3(0.f, 0.f, 0.f));
		//text->setAxisAlignment(osgText::Text::SCREEN);
		text->setAxisAlignment(osgText::Text::XZ_PLANE);  //沿xz平面,倒下
		/*文字相对于自身坐标位置*/
		text->setAlignment(osgText::Text::CENTER_TOP);
		text->setText("Hello osg world");
		geode->addDrawable(text.get());
	}

	return geode.release();
}

int main(int argc, char** argv)
{
    
    
	osg::ref_ptr<osg::Node> root = createSceneGraph();
	if (!root.valid())
	{
    
    
		osg::notify(osg::FATAL) << "Failed in createSceneGraph()." << std::endl;
		return 1;
	}

	std::string out("Text.osg");
	if (!(osgDB::writeNodeFile(*(root.get()), out)))    //这里不能有封号, 切记 切记 切记!!!!!
	{
    
    
		osg::notify(osg::FATAL) << "Failed in osgDB::writeNodeFile()." << std::endl;
		return 1;
	}

	osg::notify(osg::ALWAYS) << "Successfully wrote \"" << out << "\". Execute \" osgviewer " << out << "\" to view." << std::endl;

	osgViewer::Viewer viewer;
	viewer.setSceneData(osgDB::readNodeFile("Text.osg"));
	return viewer.run();

	/*osg::ref_ptr<osgViewer::View> viewer = new osgViewer::View;
	auto node = osgDB::readNodeFile("Text.osg");
	return viewer.run();*/

	return 0;
}

里面包含大量注释

源码下载

源码工程下载地址

运行效果
在这里插入图片描述

おすすめ

転載: blog.csdn.net/aoxuestudy/article/details/121245109