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;
}
View Code

 

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;
}
View Code

 

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();
}
View Code

 

 
4、所使用的earth.jpg
MFC单文档下OSG二维纹理映射--地球--基本可以,就是屏幕缩小放大有点闪屏

 
5、结果如图:
 
MFC单文档下OSG二维纹理映射--地球--基本可以,就是屏幕缩小放大有点闪屏

 
posted @ 2016-09-02 09:57  flylong0204  阅读(2163)  评论(0)    收藏  举报