OSG--二维纹理映射--全屏静止显示
OSG--Win32 Console Application下二维纹理映射--全屏静止显示
转自:http://blog.sina.com.cn/s/blog_67d069a90100rany.html
#include "stdafx.h" #include <osgViewer/Viewer> #include <osg/Node> #include <osg/Geode> #include <osg/Group> #include <osg/Image> #include <osg/TexGen> #include <osg/Texture1D> #include <osg/TexEnv> #include <osg/StateSet> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgUtil/Optimizer> #include <osg/Camera> #include <osg/Texture2D> #include <osg/PositionAttitudeTransform> #include <osgGA/GUIEventHandler> #include <osgViewer/ViewerEventHandlers> // 创建一个四边形节点 osg::ref_ptr<osg::Geode> createNode() { //叶节点Geode,即几何节点,叶节点的工作就是保存和管理一个或多个可绘制物体的信息, //这些可绘制体的容纳者称为Drawable类。 //Geode节点没有子节点,有一个或多个Drawable对象,同Group节点一样,均继承自Node节点 // //创建一个叶节点对象 osg::ref_ptr<osg::Geode> geode = new osg::Geode(); //几何体类(osg::Geometry),它继承自osg::Drawable类,它的主要作用就是对指定绘制几何体的顶点数和对数据的解析 //使用Geometry类,用户可以通过指定顶点,颜色和法线的方式,绘制简单的线段,三角形,多边形。并将绘图的结果添加到场景的叶结点Geode中。 //创建一个几何体对象 osg::ref_ptr<osg::Geometry> geom = new osg::Geometry(); //vc为三维顶点数组,注意是逆时针添加的 osg::ref_ptr<osg::Vec3Array> vc = new osg::Vec3Array(); vc->push_back(osg::Vec3(0.0f,0.0f,-1.0f)); vc->push_back(osg::Vec3(1000.0f,0.0f,-1.0f)); vc->push_back(osg::Vec3(1000.0f,900.0f,-1.0f)); vc->push_back(osg::Vec3(0.0f,900.0f,-1.0f)); //设置顶点数据 geom->setVertexArray(vc.get()); //创建纹理坐标 osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array(); //添加数据 vt->push_back(osg::Vec2(0.0f,0.0f)); vt->push_back(osg::Vec2(1.0f,0.0f)); vt->push_back(osg::Vec2(1.0f,1.0f)); vt->push_back(osg::Vec2(0.0f,1.0f)); //设置纹理坐标 geom->setTexCoordArray(0,vt.get()); //设置法线 osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array(); nc->push_back(osg::Vec3(0.0f,1.0f,0.0f));//根据法线方向,我们绘制的正方形在x-z平面,故其法线为y方向,即人眼正视正方形的方向 //设置法线数组 geom->setNormalArray(nc.get()); //设置法线的绑定方式为全部顶点 geom->setNormalBinding(osg::Geometry::BIND_OVERALL); //添加图元,绘图基元为四边形 geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); //绘制 geode->addDrawable(geom.get()); return geode.get(); } //创建二维纹理状态对象 osg::ref_ptr<osg::StateSet> createTexture2DState(osg::ref_ptr<osg::Image> image) { //创建状态集对象 osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet(); //创建二维纹理对象 osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D(); texture->setDataVariance(osg::Object::DYNAMIC); //设置贴图 texture->setImage(image.get()); stateset->setTextureAttributeAndModes(0,texture.get(),osg::StateAttribute::ON); return stateset.get(); } osg::ref_ptr<osg::Camera> createBackground(void) { //创建相机节点 osg::ref_ptr<osg::Camera> camera = new osg::Camera; //直接设置/获取投影矩阵的内容--平行投影 camera->setProjectionMatrix(osg::Matrix::ortho2D(0,1000,0,900)); //设置/获取该相机的参考系。使用ABSOLUTE_RF绝对参考系表示该相机将不受父节点任何变换的影响 camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); //直接设置/获取观察矩阵的内容 camera->setViewMatrix(osg::Matrix::identity()); //清除深度缓存 camera->setClearMask(GL_DEPTH_BUFFER_BIT); //设置相机的渲染顺序,在主场景之前(PRE_RENDER)还是之后(POST_RENDER)。 camera->setRenderOrder(osg::Camera::POST_RENDER); camera->setAllowEventFocus(false); camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON); osg::ref_ptr<osg::Image> image = osgDB::readImageFile("earth.jpg"); //创建几何体 osg::ref_ptr<osg::Geode> geode = createNode(); //创建状态集对象 osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet(); stateset = createTexture2DState(image.get()); //使用二维纹理 geode->setStateSet(stateset.get()); geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); geode->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); osg::ref_ptr<osg::PositionAttitudeTransform> pos = new osg::PositionAttitudeTransform; pos->addChild(geode.get()); pos->setPosition(osg::Vec3(0,0,-1)); camera->addChild(pos.get()); return camera.get(); } int main(void) { osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer; osg::ref_ptr<osg::Group> root = new osg::Group; //创建背景 root->addChild(createBackground()); viewer->addEventHandler(new osgViewer::StatsHandler); viewer->setSceneData(root.get()); viewer->run(); return 0; }

Win32 Console Application 二维纹理映射 --旋转 非全屏
转自:http://blog.sina.com.cn/s/blog_67d069a90100rao4.html
来自:OpenSceneGraph三维渲染引擎编程指南 P126
#include "stdafx.h" #include <osgViewer/Viewer> #include <osg/Node> #include <osg/Geode> #include <osg/Group> #include <osg/Image> #include <osg/TexGen> #include <osg/Texture1D> #include <osg/TexEnv> #include <osg/StateSet> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgUtil/Optimizer> // 创建一个四边形节点 osg::ref_ptr<osg::Geode> createNode() { //叶节点Geode,即几何节点,叶节点的工作就是保存和管理一个或多个可绘制物体的信息, //这些可绘制体的容纳者称为Drawable类。 //Geode节点没有子节点,有一个或多个Drawable对象,同Group节点一样,均继承自Node节点 // //创建一个叶节点对象 osg::ref_ptr<osg::Geode> geode = new osg::Geode(); //几何体类(osg::Geometry),它继承自osg::Drawable类,它的主要作用就是对指定绘制几何体的顶点数和对数据的解析 //使用Geometry类,用户可以通过指定顶点,颜色和法线的方式,绘制简单的线段,三角形,多边形。并将绘图的结果添加到场景的叶结点Geode中。 //创建一个几何体对象 osg::ref_ptr<osg::Geometry> geom = new osg::Geometry(); //vc为三维顶点数组,注意是逆时针添加的 osg::ref_ptr<osg::Vec3Array> vc = new osg::Vec3Array(); vc->push_back(osg::Vec3(0.0f,0.0f,-1.0f)); vc->push_back(osg::Vec3(1000.0f,0.0f,-1.0f)); vc->push_back(osg::Vec3(1000.0f,900.0f,-1.0f)); vc->push_back(osg::Vec3(0.0f,900.0f,-1.0f)); //设置顶点数据 geom->setVertexArray(vc.get()); //创建纹理坐标 osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array(); //添加数据 vt->push_back(osg::Vec2(0.0f,0.0f)); vt->push_back(osg::Vec2(1.0f,0.0f)); vt->push_back(osg::Vec2(1.0f,1.0f)); vt->push_back(osg::Vec2(0.0f,1.0f)); //设置纹理坐标 geom->setTexCoordArray(0,vt.get()); //设置法线 osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array(); nc->push_back(osg::Vec3(0.0f,1.0f,0.0f));//根据法线方向,我们绘制的正方形在x-z平面,故其法线为y方向,即人眼正视正方形的方向 //设置法线数组 geom->setNormalArray(nc.get()); //设置法线的绑定方式为全部顶点 geom->setNormalBinding(osg::Geometry::BIND_OVERALL); //添加图元,绘图基元为四边形 geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); //绘制 geode->addDrawable(geom.get()); return geode.get(); } //创建二维纹理状态对象 osg::ref_ptr<osg::StateSet> createTexture2DState(osg::ref_ptr<osg::Image> image) { //创建状态集对象 osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet(); //创建二维纹理对象 osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D(); texture->setDataVariance(osg::Object::DYNAMIC); //设置贴图 texture->setImage(image.get()); stateset->setTextureAttributeAndModes(0,texture.get(),osg::StateAttribute::ON); return stateset.get(); } int main(void) { osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer; osg::ref_ptr<osg::Group> root = new osg::Group; ///////////////////////////////////////////////////////////////// //读取贴图文件 osg::ref_ptr<osg::Image>image=osgDB::readImageFile("earth.jpg"); osg::ref_ptr<osg::Node>node=createNode(); //创建状态集对象 osg::ref_ptr<osg::StateSet>stateset=new osg::StateSet(); stateset=createTexture2DState(image.get()); //使用二维纹理 node->setStateSet(stateset.get()); root->addChild(node.get()); //优化场景数据 osgUtil::Optimizer optimizer; optimizer.optimize(root.get()); viewer->setSceneData(root.get()); viewer->realize(); viewer->run(); ///////////////////////////////////////////////////////////////// return 0; }
MFC单文档下OSG二维纹理映射--地球--基本可以,就是屏幕缩小放大有点闪屏
转自:http://blog.sina.com.cn/s/blog_67d069a90100rd4f.html
1、先按照《
OSG VS2010 单文档 learn 1》
这篇博文做完。
2、更改MFC_OSG.h文件为:
#pragma once #include <string> #include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> #include <osgViewer/api/win32/GraphicsWindowWin32> #include <osgGA/TrackballManipulator> #include <osgGA/KeySwitchMatrixManipulator> #include <osgDB/DatabasePager> #include <osgDB/Registry> #include <osgDB/ReadFile> #include <osgUtil/Optimizer> //////////////////////////////////// #include <osg/Camera> #include <osg/Texture2D> #include <osg/PositionAttitudeTransform> #include <osgGA/GUIEventHandler> //////////////////////////////////// class cOSG { public: cOSG(HWND hWnd); ~cOSG(); void InitOSG(std::string filename); void InitManipulators(void); void InitSceneGraph(void); void InitCameraConfig(void); void SetupWindow(void); void SetupCamera(void); void PreFrameUpdate(void); void PostFrameUpdate(void); void Done(bool value) { mDone = value; } bool Done(void) { return mDone; } static void Render(void* ptr); osgViewer::Viewer* getViewer() { return mViewer; } ///////////////////////////////////////////////////////////////////////////////////////////////// // 创建一个四边形节点 osg::ref_ptr<osg::Geode> createNode(); //创建二维纹理状态对象 osg::ref_ptr<osg::StateSet> createTexture2DState(osg::ref_ptr<osg::Image> image); ///////////////////////////////////////////////////////////////////////////////////////////////// private: bool mDone; std::string m_ModelName; HWND m_hWnd; osgViewer::Viewer* mViewer; osg::ref_ptr<osg::Group> mRoot; osg::ref_ptr<osg::Node> mModel; osg::ref_ptr<osgGA::TrackballManipulator> trackball; osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator; //////////////////////////////////////////////////////////////////////// }; 3、更改MFC_OSG.cpp文件为: // MFC_OSG.cpp : implementation of the cOSG class // #include "stdafx.h" #include <string> #include <osgViewer/Viewer> #include "MFC_OSG.h" #include <osg/CoordinateSystemNode> cOSG::cOSG(HWND hWnd) : m_hWnd(hWnd) { } cOSG::~cOSG() { mViewer->setDone(true); Sleep(1000); mViewer->stopThreading(); delete mViewer; } void cOSG::InitOSG(std::string modelname) { //存储加载模型的文件名 m_ModelName = modelname; // 初始化osg InitManipulators(); InitSceneGraph(); InitCameraConfig(); } /////////////////////////////////////二维地球//////////////////////////////////////////////////////////// // 创建一个四边形节点 osg::ref_ptr<osg::Geode>cOSG::createNode() { //////////////////////////////////////////// //得到窗户客户区的大小 RECT rect3; // Get the current window size ::GetClientRect(m_hWnd, &rect3); int w=rect3.right; int h=rect3.bottom; ////////////////////////////////////////////// //叶节点Geode,即几何节点,叶节点的工作就是保存和管理一个或多个可绘制物体的信息, //这些可绘制体的容纳者称为Drawable类。 //Geode节点没有子节点,有一个或多个Drawable对象,同Group节点一样,均继承自Node节点 // //创建一个叶节点对象 osg::ref_ptr<osg::Geode>geodeQuadr = new osg::Geode(); //几何体类(osg::Geometry),它继承自osg::Drawable类,它的主要作用就是对指定绘制几何体的顶点数和对数据的解析 //使用Geometry类,用户可以通过指定顶点,颜色和法线的方式,绘制简单的线段,三角形,多边形。并将绘图的结果添加到场景的叶结点Geode中。 //创建一个几何体对象 osg::ref_ptr<osg::Geometry>geom = new osg::Geometry(); //vc为三维顶点数组,注意是逆时针添加的 osg::ref_ptr<osg::Vec3Array> vc = new osg::Vec3Array(); //显示的对,就是反了,光线暗 vc->push_back(osg::Vec3(0.0f,0.0f,-1.0f)); vc->push_back(osg::Vec3(w,0.0f,-1.0f)); vc->push_back(osg::Vec3(w,h,-1.0f)); vc->push_back(osg::Vec3(0.0f,h,-1.0f)); //////////////////////////////////// /////////////////////////////////// //设置顶点数据 geom->setVertexArray(vc.get()); //创建纹理坐标 osg::ref_ptr<osg::Vec2Array> vt = new osg::Vec2Array(); //添加数据 vt->push_back(osg::Vec2(0.0f,0.0f)); vt->push_back(osg::Vec2(1.0f,0.0f)); vt->push_back(osg::Vec2(1.0f,1.0f)); vt->push_back(osg::Vec2(0.0f,1.0f)); //设置纹理坐标 geom->setTexCoordArray(0,vt.get()); //设置法线 osg::ref_ptr<osg::Vec3Array> nc = new osg::Vec3Array(); nc->push_back(osg::Vec3(0.0f,1.0f,2.0f));//根据法线方向,我们绘制的正方形在x-z平面,故其法线为y方向,即人眼正视正方形的方向 //设置法线数组 geom->setNormalArray(nc.get()); //设置法线的绑定方式为全部顶点 geom->setNormalBinding(osg::Geometry::BIND_OVERALL); //添加图元,绘图基元为四边形 geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS,0,4)); //绘制 geodeQuadr->addDrawable(geom.get()); return geodeQuadr.get(); } //创建二维纹理状态对象 osg::ref_ptr<osg::StateSet> cOSG::createTexture2DState(osg::ref_ptr<osg::Image> image) { //创建状态集对象 osg::ref_ptr<osg::StateSet>stateset = new osg::StateSet(); //创建二维纹理对象 osg::ref_ptr<osg::Texture2D>texture = new osg::Texture2D(); texture->setDataVariance(osg::Object::DYNAMIC); //设置贴图 texture->setImage(image.get()); stateset->setTextureAttributeAndModes(0,texture.get(),osg::StateAttribute::ON); return stateset.get(); } //////////////////////////////////////二维地球///////////////////////////////////////////////////////////// void cOSG::InitManipulators(void) { // 创建一个追踪求操作器 trackball = new osgGA::TrackballManipulator(); //创建一个调度操作器 keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator; // 添加追踪球操作器到调度操作器中 keyswitchManipulator->addMatrixManipulator( '1', "Trackball", trackball.get()); // Init the switcher to the first manipulator (in this case the only manipulator) keyswitchManipulator->selectMatrixManipulator(0); // Zero based index Value } void cOSG::InitSceneGraph(void) { // 定义主节点 mRoot = new osg::Group; // 加载模型 //// mModel = osgDB::readNodeFile(m_ModelName); ////////////////////////二维地球///////////////////////////////////////////// osg::ref_ptr<osg::Image>imageEarth = osgDB::readImageFile("earth.jpg"); //创建几何体 osg::ref_ptr<osg::Geode>geodeQuadr =createNode(); //创建状态集对象 osg::ref_ptr<osg::StateSet>stateset= new osg::StateSet(); stateset = createTexture2DState(imageEarth.get()); //使用二维纹理 geodeQuadr->setStateSet(stateset.get()); geodeQuadr->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); geodeQuadr->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); mRoot->addChild(geodeQuadr.get()); ///////////////////////二维地球////////////////////////////// //优化模型 osgUtil::Optimizer optimizer; optimizer.optimize(mRoot.get()); optimizer.reset(); //添加模型到场景中 // mRoot->addChild(mModel.get()); } void cOSG::InitCameraConfig(void) { // Local Variable to hold window size data RECT rect; // 创建一个视图 mViewer = new osgViewer::Viewer(); // Add a Stats Handler to the viewer mViewer->addEventHandler(new osgViewer::StatsHandler); // Get the current window size ::GetWindowRect(m_hWnd, &rect); // Init the GraphicsContext Traits osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; // Init the Windata Variable that holds the handle for the Window to display OSG in. osg::ref_ptr<osg::Referenced> windata = new osgViewer::GraphicsWindowWin32::WindowData(m_hWnd); // Setup the traits parameters traits->x = 0; traits->y = 0; traits->width = rect.right - rect.left; traits->height = rect.bottom - rect.top; traits->windowDecoration = false; traits->doubleBuffer = true; traits->sharedContext = 0; traits->setInheritedWindowPixelFormat = true; traits->inheritedWindowData = windata; // Create the Graphics Context osg::GraphicsContext* gc = osg::GraphicsContext::createGraphicsContext(traits.get()); //设置相机 osg::ref_ptr<osg::Camera> camera = new osg::Camera; // Assign Graphics Context to the Camera camera->setGraphicsContext(gc); // Set the viewport for the Camera //////////////////////////////////////////// //得到窗户客户区的大小 RECT rect2; // Get the current window size ::GetClientRect(m_hWnd, &rect2); int w=rect2.right; int h=rect2.bottom; ////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////// //直接设置/获取观察矩阵的内容 camera->setViewMatrix(osg::Matrix::identity()); //设置/获取该相机的参考系。使用ABSOLUTE_RF绝对参考系表示该相机将不受父节点任何变换的影响 camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); //清除深度缓存 camera->setClearMask(GL_DEPTH_BUFFER_BIT); //设置相机的渲染顺序,在主场景之前(PRE_RENDER)还是之后(POST_RENDER)。 camera->setRenderOrder(osg::Camera::POST_RENDER); camera->setAllowEventFocus(false); camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::ON); //直接设置/获取投影矩阵的内容--平行投影 camera->setProjectionMatrix(osg::Matrix::ortho2D(0,w, 0,h)); //设置/获取该相机的参考系。使用ABSOLUTE_RF绝对参考系表示该相机将不受父节点任何变换的影响 camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); //osg::ref_ptr<osg::PositionAttitudeTransform> pos = new osg::PositionAttitudeTransform; // pos->addChild(geode2.get()); // pos->setPosition(osg::Vec3(0,0,-1)); // camera->addChild(pos.get()); /////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////// camera->setViewport(new osg::Viewport(traits->x, traits->y, traits->width, traits->height)); // Add the Camera to the Viewer mViewer->addSlave(camera.get()); // Add the Camera Manipulator to the Viewer mViewer->setCameraManipulator(keyswitchManipulator.get()); //osg::ref_ptr<osg::Group> root = new osg::Group(); //root->addChild(mRoot); osgUtil::Optimizer optimizer ; optimizer.optimize(mRoot) ; // Set the Scene Data mViewer->setSceneData(mRoot.get()); // Realize the Viewer mViewer->realize(); } void cOSG::PreFrameUpdate() { // Due any preframe updates in this routine } void cOSG::PostFrameUpdate() { // Due any postframe updates in this routine } void cOSG::Render(void* ptr) { cOSG* osg = (cOSG*)ptr; osgViewer::Viewer* viewer = osg->getViewer(); //viewer->run(); while(!viewer->done()) { osg->PreFrameUpdate(); viewer->frame(); osg->PostFrameUpdate(); //Sleep(10); // Use this command if you need to allow other processes to have cpu time } _endthread(); }
4、所使用的earth.jpg
5、结果如图:
浙公网安备 33010602011771号