本例子展示osg渲染到纹理的技术,代码来自《OpenSceneGraph三维渲染引擎设计与实践.pdf》7.2.4节。以下 代码变量名有些和书中有点小差别,但功能是一样的,不影响学习:
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osgDB/Readfile>
#include <osgDB/WriteFile>
osg::Camera* createCamera(int nWidth, int nHeight, const osg::BoundingSphere&bs)
{
auto pCamera = new osg::Camera;
pCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
pCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
pCamera->setViewport(0, 0, nWidth, nHeight);
pCamera->setRenderOrder(osg::Camera::PRE_RENDER);
pCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
auto viewDistance = 2.0 * bs.radius();
auto znear = viewDistance - bs.radius();
auto zfar = viewDistance + bs.radius();
auto top = 0.6 * znear;
auto right = 0.8 * znear;
pCamera->setProjectionMatrixAsFrustum(-right, right, -top, top, znear, zfar);
osg::Vec3d upDirection(0, 0, 1);
osg::Vec3d viewDirection(0, -1, 0);
osg::Vec3d center = bs.center();
osg::Vec3d eyePoint = center + viewDirection * viewDistance;
pCamera->setViewMatrixAsLookAt(eyePoint, center, upDirection);
return pCamera;
}
osg::Texture2D* createTexture2D(int nWidth, int nHeight)
{
osg::Texture2D* pTx2d = new osg::Texture2D;
pTx2d->setInternalFormat(GL_RGBA); // 内部格式必须设置,否则模型不会显示在纹理对象上
pTx2d->setTextureWidth(nWidth);
pTx2d->setTextureHeight(nHeight);
pTx2d->setFilter(osg::Texture::FilterParameter::MIN_FILTER, osg::Texture::NEAREST);
pTx2d->setFilter(osg::Texture::FilterParameter::MAG_FILTER, osg::Texture::NEAREST);
return pTx2d;
}
int main()
{
osgViewer::Viewer viewr;
auto pCowNode = osgDB::readRefNodeFile("cow.osg");
if (nullptr == pCowNode)
{
return 1;
}
pCowNode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::Group* pRoot = new osg::Group;
osg::ref_ptr<osg::Geode> spGeode = new osg::Geode;
spGeode->addDrawable(osg::createTexturedQuadGeometry(osg::Vec3(0, 0, 0), osg::Vec3(1, 0, 0), osg::Vec3(0, 0, 1)));
const auto nWidth = 512;
const auto nHeight = 512;
auto pTx2D = createTexture2D(nWidth, nHeight);
spGeode->getOrCreateStateSet()->setTextureAttributeAndModes(0, pTx2D);
pRoot->addChild(spGeode);
auto spCamera = createCamera(nWidth, nHeight, pCowNode->getBound());
spCamera->addChild(pCowNode);
spCamera->attach(osg::Camera::COLOR_BUFFER, pTx2D);
pRoot->addChild(spCamera);
viewr.setSceneData(pRoot);
viewr.run();
return 0;
}
结果将奶牛渲染到了一个长方形中,如下为结果:
图1 初始结果图
图2.将长方形转动一定角度后的效果图