用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十六课
来源:互联网 发布:普通话考试准备软件 编辑:程序博客网 时间:2024/05/16 11:45
简介
NeHe教程在这节课向我们介绍了OpenGL的扩展(ARB_MULTISAMPLE)多重采样技术。利用这种技术可以实现全屏反走样。这样可以使图形看起来更美观。
在OSG中多重采样是作为节点的StateSet来开启和关闭的,实现过程十分简单。
实现
首先添加四边形到场景中,这一过程前面已经重复很多遍了,代码如下:
for(int i=-10;i<10;i++){for(int j=-10;j<10;j++){osg::MatrixTransform *transMT = new osg::MatrixTransform;transMT->addUpdateCallback(new TransCallback(i, j));osg::MatrixTransform *rotMT = new osg::MatrixTransform;rotMT->addUpdateCallback(new RotCallback);osg::Geode *geode = new osg::Geode;osg::Geometry *geometry = new osg::Geometry;osg::Vec3Array *vertexArray = new osg::Vec3Array;osg::Vec3Array *colorArray = new osg::Vec3Array;colorArray->push_back(osg::Vec3(1, 0, 0));vertexArray->push_back(osg::Vec3(i, j, 0.0));colorArray->push_back(osg::Vec3(0, 1, 0));vertexArray->push_back(osg::Vec3(i + 2.0f,j,0.0f));colorArray->push_back(osg::Vec3(0,0,1));vertexArray->push_back(osg::Vec3(i + 2.0f,j + 2.0f,0.0f));colorArray->push_back(osg::Vec3(1,1,1));vertexArray->push_back(osg::Vec3(i,j + 2.0f,0.0f));geometry->setVertexArray(vertexArray);geometry->setColorArray(colorArray, osg::Array::BIND_PER_VERTEX);geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));geode->addDrawable(geometry);transMT->addChild(rotMT);rotMT->addChild(geode);root->addChild(transMT);}}
在创建窗口Traits的时候需要将窗口采样值设置为4,这样才能开启多重采样:
traits->sampleBuffers = ds->getMultiSamples();traits->samples = 4/*ds->getNumMultiSamples()*/;
之后为了让这些四边形旋转和移动,在节点中添加若干的回调:
class TransCallback : public osg::NodeCallback{public:TransCallback(float i, float j) : _i(i), _j(j){}virtual void operator()(osg::Node* node, osg::NodeVisitor* nv){osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);if(!mt)return;mt->setMatrix(osg::Matrix::translate(_i*2.0f,_j*2.0f,-5.0f));traverse(node, nv);}float _i;float _j;};
对节点启用多重采样:
osg::Multisample *ms = new osg::Multisample;ms->setHint(osg::Multisample::NICEST);root->getOrCreateStateSet()->setAttributeAndModes(ms, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
与键盘交互中切换多重采样的开启和关闭模式:
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space){if(!g_Root)return false;static bool flag = true;if (flag){g_Root->getOrCreateStateSet()->setMode(GL_MULTISAMPLE_ARB, false);}else{g_Root->getOrCreateStateSet()->setMode(GL_MULTISAMPLE_ARB, true);}flag = !flag;}
编译运行程序,可以看到在按下空格的时候四边形的边缘锯齿感有明显的变化:
附:本课源码(源码中可能存在错误和不足之处,仅供参考)
#include "../osgNeHe.h"#include <QtCore/QTimer>#include <QtGui/QApplication>#include <QtGui/QVBoxLayout>#include <osgViewer/Viewer>#include <osgDB/ReadFile>#include <osgQt/GraphicsWindowQt>#include <osg/MatrixTransform>#include <osg/Multisample>osg::Group*g_Root = NULL;class ManipulatorSceneHandler : public osgGA::GUIEventHandler{public:ManipulatorSceneHandler(){}public:virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){osgViewer::Viewer *viewer = dynamic_cast<osgViewer::Viewer*>(&aa);if (!viewer)return false;if (!viewer->getSceneData())return false;if (ea.getHandled()) return false;osg::Group *root = viewer->getSceneData()->asGroup();switch(ea.getEventType()){case(osgGA::GUIEventAdapter::KEYDOWN):{if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space){if(!g_Root)return false;static bool flag = true;if (flag){g_Root->getOrCreateStateSet()->setMode(GL_MULTISAMPLE_ARB, false);}else{g_Root->getOrCreateStateSet()->setMode(GL_MULTISAMPLE_ARB, true);}flag = !flag;}}break;default: break;}return false;}};class ViewerWidget : public QWidget, public osgViewer::Viewer{public:ViewerWidget(osg::Node *scene = NULL){QWidget* renderWidget = getRenderWidget( createGraphicsWindow(0,0,100,100), scene);QVBoxLayout* layout = new QVBoxLayout;layout->addWidget(renderWidget);layout->setContentsMargins(0, 0, 0, 1);setLayout( layout );connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );_timer.start( 10 );}QWidget* getRenderWidget( osgQt::GraphicsWindowQt* gw, osg::Node* scene ){osg::Camera* camera = this->getCamera();camera->setGraphicsContext( gw );const osg::GraphicsContext::Traits* traits = gw->getTraits();camera->setClearColor( osg::Vec4(0.0, 0.0, 0.0, 1.0) );camera->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) );camera->setProjectionMatrixAsPerspective(45.0f, static_cast<double>(traits->width)/static_cast<double>(traits->height), 0.1f, 100.0f );camera->setViewMatrixAsLookAt(osg::Vec3d(0, 0, 1), osg::Vec3d(0, 0, 0), osg::Vec3d(0, 1, 0));this->setSceneData( scene );this->addEventHandler(new ManipulatorSceneHandler);return gw->getGLWidget();}osgQt::GraphicsWindowQt* createGraphicsWindow( int x, int y, int w, int h, const std::string& name="", bool windowDecoration=false ){osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;traits->windowName = name;traits->windowDecoration = windowDecoration;traits->x = x;traits->y = y;traits->width = w;traits->height = h;traits->doubleBuffer = true;traits->alpha = ds->getMinimumNumAlphaBits();traits->stencil = ds->getMinimumNumStencilBits();traits->sampleBuffers = ds->getMultiSamples();traits->samples = 4/*ds->getNumMultiSamples()*/;return new osgQt::GraphicsWindowQt(traits.get());}virtual void paintEvent( QPaintEvent* event ){ frame(); }protected:QTimer _timer;};class TransCallback : public osg::NodeCallback{public:TransCallback(float i, float j) : _i(i), _j(j){}virtual void operator()(osg::Node* node, osg::NodeVisitor* nv){osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);if(!mt)return;mt->setMatrix(osg::Matrix::translate(_i*2.0f,_j*2.0f,-5.0f));traverse(node, nv);}float _i;float _j;};class RotCallback : public osg::NodeCallback{public:virtual void operator()(osg::Node* node, osg::NodeVisitor* nv){static float angle = 0.0;osg::MatrixTransform *mt = dynamic_cast<osg::MatrixTransform*>(node);if(!mt)return;mt->setMatrix(osg::Matrix::rotate(angle, osg::Z_AXIS));angle += osg::DegreesToRadians(0.001f);traverse(node, nv);}};osg::Node*buildScene(){osg::Group *root = new osg::Group;g_Root = root;osg::Multisample *ms = new osg::Multisample;ms->setHint(osg::Multisample::NICEST);root->getOrCreateStateSet()->setAttributeAndModes(ms, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);for(int i=-10;i<10;i++){for(int j=-10;j<10;j++){osg::MatrixTransform *transMT = new osg::MatrixTransform;transMT->addUpdateCallback(new TransCallback(i, j));osg::MatrixTransform *rotMT = new osg::MatrixTransform;rotMT->addUpdateCallback(new RotCallback);osg::Geode *geode = new osg::Geode;osg::Geometry *geometry = new osg::Geometry;osg::Vec3Array *vertexArray = new osg::Vec3Array;osg::Vec3Array *colorArray = new osg::Vec3Array;colorArray->push_back(osg::Vec3(1, 0, 0));vertexArray->push_back(osg::Vec3(i, j, 0.0));colorArray->push_back(osg::Vec3(0, 1, 0));vertexArray->push_back(osg::Vec3(i + 2.0f,j,0.0f));colorArray->push_back(osg::Vec3(0,0,1));vertexArray->push_back(osg::Vec3(i + 2.0f,j + 2.0f,0.0f));colorArray->push_back(osg::Vec3(1,1,1));vertexArray->push_back(osg::Vec3(i,j + 2.0f,0.0f));geometry->setVertexArray(vertexArray);geometry->setColorArray(colorArray, osg::Array::BIND_PER_VERTEX);geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, vertexArray->size()));geode->addDrawable(geometry);transMT->addChild(rotMT);rotMT->addChild(geode);root->addChild(transMT);}}return root;}int main( int argc, char** argv ){QApplication app(argc, argv);ViewerWidget* viewWidget = new ViewerWidget(buildScene());viewWidget->setGeometry( 100, 100, 640, 480 );viewWidget->show();return app.exec();}
0 0
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十六课
- OpenSceneGraph实现的NeHe OpenGL教程 - 第四十六课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第二十六课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第三十六课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十一课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十二课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十三课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十四课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十五课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十七课
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十八课
- OpenSceneGraph实现的NeHe OpenGL教程 - 第二十六课
- OpenSceneGraph实现的NeHe OpenGL教程 - 第三十六课
- OpenSceneGraph实现的NeHe OpenGL教程 - 第四课
- OpenSceneGraph实现的NeHe OpenGL教程 - 第四十一课
- OpenSceneGraph实现的NeHe OpenGL教程 - 第四十二课
- OpenSceneGraph实现的NeHe OpenGL教程 - 第四十三课
- Android Loader
- 中国邮票
- 《学习opencv》笔记——矩阵和图像操作——cvGertDims,cvGetDimSize,cvGetRow,cvGetRow,cvGetSize and cvGetSubRect
- Swift简介 教程
- winpcap学习笔记--(Capturing the packets without the callback)
- 用OpenSceneGraph实现的NeHe OpenGL教程 - 第四十六课
- Linux下查看文件和文件夹大小
- 【iOS开发】iOS7 兼容及部分细节
- Vi/Vim查找替换使用方法
- layoutSubviews何时调用的问题
- Swift编程语言 瞬间复制出Flappy Bird火爆游戏
- Unity导出iOS真机测试教程
- 奇怪的recv函数
- 关于xcode的Build Settings 和一些路径设置