osg osgViewer::View::setUpViewInWindow()

当前位置:osgViewer/View.cpp 第 575 行,osgViewer::View::setUpViewInWindow()这个函数有五个传入参数:窗口左上角坐标 x,y,宽度 width,高度 height,以及屏幕数 screenNum。它的作用顾名思义是根据给定的窗口参数来创建一个图形设备。

_displayType:显示器类型,默认为 MONITOR(监视器),此外还支持 POWERWALL(威力墙),REALITY_CENTER(虚拟实境中心)和 HEAD_MOUNTED_DISPLAY(头盔显示器)。

_stereoMode :立体显示模式,默认为 ANAGLYPHIC (互补色),此外还支持QUAD_BUFFER(四方体缓冲),HORIZONTAL_SPLIT(水平分割),VERTICAL_SPLIT(垂直分割),LEFT_EYE(左眼用),RIGHT_EYE(右眼用),HORIZONTAL_INTERLACE(水平交错),VERTICAL_INTERLACE(垂直交错),CHECKERBOARD(棋盘式交错,用于DLP 显示器)。
_eyeSeparation:双眼的物理距离,默认为 0.05。
_screenWidth,_screenHeight:屏幕的实际宽度和高度,分别默认设置为 0.325 和 0.26,目前它们影响的仅仅是视图采用透视投影时的宽高比。
_screenDistance:人眼到屏幕的距离,默认为 0.5。
_splitStereoHorizontalEyeMapping:默认为 LEFT_EYE_LEFT_VIEWPORT(左眼渲染左视口),也可设为 LEFT_EYE_RIGHT_VIEWPORT(左眼渲染右视口)。
_splitStereoHorizontalSeparation:左视口和右视口之间的距离(像素数),默认为 0。
_splitStereoVerticalEyeMapping:默认为 LEFT_EYE_TOP_VIEWPORT(左眼渲染顶视口),也可设为 LEFT_EYE_BOTTOM_VIEWPORT(左眼渲染底视口)。
_splitStereoVerticalSeparation:顶视口和底视口之间的距离(像素数),默认为 0。
_splitStereoAutoAdjustAspectRatio:默认为 true,用于屏幕分割之后对其宽高比进行补偿。
_maxNumOfGraphicsContexts:用户程序中最多可用的 GraphicsContext(图形设备上下文)数目,默认为 32 个。
_numMultiSamples:多重采样的子像素样本数,默认为 0。如果显示卡支持的话,打开多重采样可以大幅改善反走样(anti-aliasing)的效果。

此外还有很多可以设置的类变量,如_minimumNumberStencilBits(模板缓存的最小位数)等,其默认设置均在 osg::DisplaySettings::setDefaults 函数中完成,其中有些变量可能还没有作用。要注意的是,DisplaySettings 的作用仅仅是保存所有可能在系统显示中用到的数据,这个类本身并不会据此改变任何系统设置和渲染方式。

值得称道的是,DisplaySettings 可以很方便地从系统环境变量或者命令行参数中获取用户对显示设备的设置,详细的调用方法可以参阅 DisplaySettings::readEnvironmentalVariables和 DisplaySettings::readCommandLine 两个函数的内容,十分通俗易懂。

如果希望在用户程序中更改 DisplaySettings 中的显示设置,请务必在执行视景器的realize 函数之前,当然也就是仿真循环开始之前。这一点也是要切记的。

void View::setUpViewInWindow(int x, int y, int width, int height, unsigned int screenNum)
{
    apply(new osgViewer::SingleWindow(x, y, width, height, screenNum));
}
void View::apply(ViewConfig* config)
{
    if (config)
    {
        OSG_INFO<<"Applying osgViewer::ViewConfig : "<<config->className()<<std::endl;
        config->configure(*this);
    }
    _lastAppliedViewConfig = config;
}
View::View():
    _fusionDistanceMode(osgUtil::SceneView::PROPORTIONAL_TO_SCREEN_DISTANCE),
    _fusionDistanceValue(1.0f)
{
    // OSG_NOTICE<<"Constructing osgViewer::View"<<std::endl;

    _startTick = 0;

    _frameStamp = new osg::FrameStamp;
    _frameStamp->setFrameNumber(0);
    _frameStamp->setReferenceTime(0);
    _frameStamp->setSimulationTime(0);

    _scene = new Scene;

    // make sure View is safe to reference multi-threaded.
    setThreadSafeRefUnref(true);

    // need to attach a Renderer to the master camera which has been default constructed
    getCamera()->setRenderer(createRenderer(getCamera()));

    setEventQueue(new osgGA::EventQueue);

    setStats(new osg::Stats("View"));
}
View::View(const osgViewer::View& view, const osg::CopyOp& copyop):
    osg::Object(view, copyop),
    osg::View(view,copyop),
    osgGA::GUIActionAdapter(),
    _startTick(0),
    _fusionDistanceMode(view._fusionDistanceMode),
    _fusionDistanceValue(view._fusionDistanceValue)
{
    _scene = new Scene;

    // need to attach a Renderer to the master camera which has been default constructed
    getCamera()->setRenderer(createRenderer(getCamera()));

    setEventQueue(new osgGA::EventQueue);

    setStats(new osg::Stats("View"));
}
void SingleWindow::configure(osgViewer::View& view) const
{
    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();
    if (!wsi)
    {
        OSG_NOTICE<<"SingleWindow::configure() : Error, no WindowSystemInterface available, cannot create windows."<<std::endl;
        return;
    }

    osg::DisplaySettings* ds = getActiveDisplaySetting(view);

    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits(ds);

    traits->readDISPLAY();
    if (traits->displayNum<0) traits->displayNum = 0;

    traits->screenNum = _screenNum;
    traits->x = _x;
    traits->y = _y;
    traits->width = _width;
    traits->height = _height;
    traits->windowDecoration = _windowDecoration;
    traits->overrideRedirect = _overrideRedirect;
    traits->doubleBuffer = true;
    traits->sharedContext = 0;

    if (traits->width<=0 || traits->height<=0 )
    {
        osg::GraphicsContext::ScreenIdentifier si;
        si.readDISPLAY();

        // displayNum has not been set so reset it to 0.
        if (si.displayNum<0) si.displayNum = 0;

        si.screenNum = _screenNum;

        unsigned int width, height;
        wsi->getScreenResolution(si, width, height);
        if (traits->width<=0) traits->width = width;
        if (traits->height<=0) traits->height = height;
    }

    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

    view.getCamera()->setGraphicsContext(gc.get());

    osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(gc.get());
    if (gw)
    {
        OSG_INFO<<"SingleWindow::configure - GraphicsWindow has been created successfully."<<std::endl;
        gw->getEventQueue()->getCurrentEventState()->setWindowRectangle(traits->x, traits->y, traits->width, traits->height );
    }
    else
    {
        OSG_NOTICE<<"SingleWindow::configure - GraphicsWindow has not been created successfully."<<std::endl;
        return;
    }

    double fovy, aspectRatio, zNear, zFar;
    view.getCamera()->getProjectionMatrixAsPerspective(fovy, aspectRatio, zNear, zFar);

    double newAspectRatio = double(traits->width) / double(traits->height);
    double aspectRatioChange = newAspectRatio / aspectRatio;
    if (aspectRatioChange != 1.0)
    {
        view.getCamera()->getProjectionMatrix() *= osg::Matrix::scale(1.0/aspectRatioChange,1.0,1.0);
    }

    view.getCamera()->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));

    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;

    view.getCamera()->setDrawBuffer(buffer);
    view.getCamera()->setReadBuffer(buffer);

    if (ds->getKeystoneHint())
    {
        if (ds->getKeystoneHint() && !ds->getKeystoneFileNames().empty())
        {
            osgViewer::Keystone::loadKeystoneFiles(ds);
        }
        if (ds->getKeystones().empty()) ds->getKeystones().push_back(new Keystone);

        view.assignStereoOrKeystoneToCamera(view.getCamera(), ds);
    }
    else if (ds->getStereo() && ds->getUseSceneViewForStereoHint())
    {
        view.assignStereoOrKeystoneToCamera(view.getCamera(), ds);
    }
}

文字参考:王锐老师《最长的一帧》

代码参考:OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield    (osg3.4)

原文地址:https://www.cnblogs.com/herd/p/11110529.html

时间: 2024-10-13 23:08:10

osg osgViewer::View::setUpViewInWindow()的相关文章

探索未知种族之osg类生物---器官初始化三

当判断到viewer中没有一个graphicContext可用时,osg就会默认的进行一次对viewer的实现操作,这样可以保证osg以后可以安心的在屏幕上进行作画.那我们就来看看这个osgViewer::Viewer::realize()函数到底具备什么样神奇的功能. osgViewer::Viewer::realize()osgViewer::Viewer::realize()的最要作用可以总结为激活设置窗口以及初始化关联线程.Viewer::getContexts()上一节以及进行了详细的

osgViewer

/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later v

OSG世界坐标转屏幕坐标(转载)

OSG世界坐标转屏幕坐标 #define M(row,col) m[col * 4 + row] void Transform_Point(double out[4], const double m[16], const double in[4]){    out[0] = M(0, 0) * in[0] + M(0, 1) * in[1] + M(0, 2) * in[2] + M(0, 3) * in[3];    out[1] = M(1, 0) * in[0] + M(1, 1) * i

OSG开发概览(转载)

OSG开发概览 1 OSG基础知识 Ø OSG是Open Scene Graphic 的缩写,OSG于1997年诞生于以为滑翔机爱好者之手,Don burns  为了对滑翔机的飞行进行模拟,对openGL的库进行了封装,osg的雏形就这样诞生了,1998年Don burns 遇到了同样喜欢滑翔机和计算机图形学的Robert Osfield ,从此Robert Osfield加入了osg小组的开发并一直担任开发小组的组长. Ø OSG不但有openGL的跨平台的特性和较高的渲染性能,还提供了一系列

探索未知种族之osg类生物---器官初始化一

我们把ViewerBase::frame()比作osg这类生物的肺,首先我们先来大概的看一下'肺'长什么样子,有哪几部分组成.在这之前得对一些固定的零件进行说明,例如_done代表osg的viewer是否被删除释放内存:_firstFrame代表是否是第一次进入frame函数.那么接下来我们会发现frame函数表面上组成结构非常简单,逻辑上也非常的清晰---先判断当前的viewer是否被删除,也就是判断是否died,如果已经died,那么肺的功能就不会进行.然后判断这个osg小孩是否刚刚出生,是

探索未知种族之osg类生物---器官初始化二

那我们回到ViewerBase::frame函数中来,继续看看为什么osg生命刚刚出生的时候会大哭,除了初始化了eventQuene和cameraManipulator之外还对那些器官进行了初始化.在这之前我们先介绍一下上一节说到的osg的肢体或者器官但是没有展开介绍的. 前言osgGA::GUIEventAdapter,GUI事件适配器.它就是对所有平台windows linux mac平台上的鼠标.键盘.以及其他的窗口事件进行了封装,目的是使接口统一,用户在使用osg库的时候不用再自己区分平

探索未知种族之osg类生物---呼吸分解之事件循环一

事件循环和更新循环**终于到了我们嘴里经常念叨的事件循环.更新循环以及渲染循环了.首先我们来区分一下事件循环和渲染循环,他们两个首先是两个不同顺序执行的过程,我们有时候会用到任意node的updateCallback函数,这个就是在更新循环的时候遍历所有的node来调用updateCallback函数的:而事件循环是与用户操作和操作系统事件想关联的,以及调用我们设置的事件回调(EventCallback)函数.而事件循环函数(viewer::eventTraversal())是我们现在要探究的内

Win64下编译OSG详细过程(Win10+VS2015+OSG3.6.3)

目录 1. 数据资源准备 2. 编译第三方库 3. 编译GDAL 4. 编译OSG 1) CMAKE_INSTALL_PREFIX: 2) BUILD_OSG_EXAMPLES/BUILD_MFC_ EXAMPLE: 3) ACTUAL_3RDPARTY_DIR 4) BUILD_DOCUMENTATION 5) 编译过程的问题 6) 安装 5. 测试环境 6. 资源下载 7. 参考文献 1. 数据资源准备 在OSG官方网站上下载最新的源码包.一般要求下载三个包: OpenSceneGraph-

osgEarth基础入门(转载)

osgEarth基础入门 osgEarth是基于三维引擎osg开发的三维数字地球引擎库,在osg基础上实现了瓦片调度插件,可选的四叉树调度插件,更多的地理数据加载插件(包括GDAL,ogr,WMS,TMS,VPB,filesystem等),再结合一套地理投影转换插件,这样就能够实现高效处理加载调度地理数据在三维地球上的显示,实现三维虚拟地球. 想要实现一个简单的基于osgEarth的三维地球,有两种方式,这两种方式是互通的.一种基于XML标签的earth文件加载,另外一种是采用C++代码,本质是