? ? ? ?osg::Drawable類可以通過該類的setDrawCallback函數(shù)設(shè)置回調(diào)函數(shù)類對象。被設(shè)置的回調(diào)類對象必須從osg::Drawable::DrawCallback類派生,并重寫drawImplementation函數(shù),以實現(xiàn)自己特定的需求。這個回調(diào)函數(shù)在每次幀事件中都會被調(diào)用(如:在幀的更新遍歷事件), 可以在該類的drawImplementation函數(shù)對可繪制對象進行屬性的更改,這樣可繪制對象就好像時刻在變化一樣,osgViewer::StatsHandler類實時幀率統(tǒng)計就是這么實現(xiàn)的。osg::Drawable::DrawCallback類定義如下:
struct DrawCallback : public virtual osg::Object
{
DrawCallback() {}
DrawCallback(const DrawCallback& org,const CopyOp& copyop):
Object(org, copyop) {}
META_Object(osg,DrawCallback);
/** do customized draw code.*/
virtual void drawImplementation(osg::RenderInfo& /*renderInfo*/,const osg::Drawable* /*drawable*/) const {}
};
? ? ? ? 這個類中最重要的就是虛函數(shù)drawImplementation,該函數(shù)參數(shù)說明如下:
- 第1個參數(shù)是類型為osg::RenderInfo的引用。osg::RenderInfo是渲染信息類。這個類負責保存和管理與場景繪制息相關(guān)的幾個重要數(shù)據(jù):當前場景的視景器、當前場景對應(yīng)的所有攝像機、以及當前osg::State對象。這些數(shù)據(jù)將在場景篩選和渲染時為 OSG 系統(tǒng)后臺的工作提供重要依據(jù),并從中取出跟蹤此圖形上下文的當前OpenGL狀態(tài)的State對象??梢哉f,需要涉及繪制有關(guān)的視景器、場景類、狀態(tài)類、攝像機類都可以從渲染信息類對象獲取到。
-
第2個參數(shù)就是指向被繪制對象的指針。
? ? ?下面舉例說明,如下代碼:
#include<osgViewer/Viewer>
#include<osg/ArgumentParser>
#include<osg/ShapeDrawable>
#include<osgText/Text3D>
#include<osg/Timer>
class CUpdateTextValue : public osg::Drawable::DrawCallback
{
public:
CUpdateTextValue()
{
_lastTimer_t = osg::Timer::instance()->tick();
}
virtual void drawImplementation(osg::RenderInfo& renderInfo, const osg::Drawable* drawable) const
{
auto pText3D = (osgText::Text3D*)(drawable);
osg::Timer_t tCurTick = osg::Timer::instance()->tick();
double delta = osg::Timer::instance()->delta_m(_lastTimer_t, tCurTick);
char szValue[10]{0};
itoa(_value, szValue, 10);
if (delta > 20)
{
++_value;
}
else
{
--_value;
}
// 防止越界、溢出
if (_value >= INT_MAX)
{
_value = INT_MAX;
}
if (_value <= INT_MIN)
{
_value = INT_MIN;
}
pText3D->setText(szValue);
pText3D->drawImplementation(renderInfo);
_lastTimer_t = tCurTick;
}
private:
// 注意用mutable修飾符,因為函數(shù)是const函數(shù),否則不能對該值修改,下同。
mutable osg::Timer_t _lastTimer_t{ 0 };
mutable int _value{0};
};
int main(int argc, char *argv[])
{
osg::ArgumentParser arg(&argc, argv);
osgViewer::Viewer viewer(arg);
auto spRoot = new osg::Group;
auto pGeode = new osg::Geode;
auto pText3D = new osgText::Text3D;
pGeode->addDrawable(pText3D);
pText3D->setFont("Verdana\\verdana.ttf");
pText3D->setText(" 0");
pText3D->setDrawCallback(new CUpdateTextValue);
pText3D->setUseDisplayList(false); // 這個要最好設(shè)置為false,否則對某些可繪制幾何體如球體,drawImplementation函數(shù)只會調(diào)用一次
spRoot->addChild(pGeode);
viewer.setSceneData(spRoot);
return viewer.run();
}
上面的例子,繪制一個三維字符串,最開始時候,字符串是“0”,然后調(diào)用三維字符對象的setDrawCallback方法,安裝一個CUpdateTextValue繪制回調(diào)類對象,在回調(diào)類中的drawImplementation函數(shù),根據(jù)兩幀之間的時間間隔是否大于20ms,從而繪制不同值,效果如下:
?說明:
?setUseDisplayList(false); // 這個要最好設(shè)置為false,否則對某些可繪制幾何體如球體,drawImplementation函數(shù)只會調(diào)用一次。
? ? ? 本例因為較簡單,第1個參數(shù)即渲染信息對象沒用上,現(xiàn)實中的業(yè)務(wù)比較復(fù)雜,會涉及到場景、視景器、相機等對象,這些都可以通過第1個參數(shù)表示的渲染信息對象獲取到。本例用到字體,需要編譯freetype到osg,作為osg的插件,否則字符串不會顯示。請從
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??FreeType Downloads文章來源:http://www.zghlxwxcb.cn/news/detail-433552.html
下載freetype。關(guān)于如何編譯字體作為osg的插件,請參照
osg第三方插件的編譯方法(以jpeg插件來講解)? ? ? 博文。文章來源地址http://www.zghlxwxcb.cn/news/detail-433552.html
到了這里,關(guān)于osg::Drawable類通過setDrawCallback函數(shù)設(shè)置回調(diào)函數(shù)的說明的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!