The Viewer Class

来源:互联网 发布:中兴算法工程师面试 编辑:程序博客网 时间:2024/05/16 08:15

继续快速入门指导 第三章 Using OpenSceneGraph in Your Application的学习

3.1.1 The Viewer Class

Viewer

 

The Viewer example in this book’s source code demonstrates the minimal code required to render OSG in an application. Viewer instantiates an osgViewer::Viewer object, attaches a scene graph to it, and allows it to render. The source code is effectively three lines long, as Listing 3-1 show.

本书中关于Viewer的例子列出了在程序中渲染OSG所需要的基本代码。Viewer实例化了一个osgViewer::Viewer对象,同时附加了一个场景,并允许对其渲染。源代码一共就三行。

 

#include <osgViewer/Viewer>

#include<osgDB/ReadFile>

 

int main(int, char**)

{

osgViewer::Viewer viewer;

viewer.setSceneData(osgDB::readNodeFile(“cow.osg”));     //不怎么喜欢这头牛,个人比//较心水robot.osg或者fountain.osg

    return viewer.run();

}

 

The similarity is no coincidence. Under the hood, the osgviewer application uses Viewer for its rendering. osgviewer configures its Viewer for additional functionality to do more than the code.

相似并不是巧合。Under the hood, osgviewer程序通过使用Viewer来渲染。Osgviewer配置给其本身Viewer更多附加的功能。

 

Changing the View

改变视图

 

Under the hood, Viewer creates an osg::Camera object to manage the OpenGL model-view matrix. There are two ways you can control the camera.

Viewer通过创建一个osg::Camear对象来管理OpenGL model-view矩阵。可以通过以下两种方式来控制摄像机:

 

l  Attach a camera manipulator to the Viewer. If your application doesn’t do this, Viewer::run() creates an osgGA::TrackballManipulator to control the Camera. The osgGA library defines several manipulators that you can use. Call Viwer::setCameraManipulator() to specify your own manipulator

l  Set the Camera projection and view matrices to matrices that you define. This gives your application complete control over the view.

l  Viewer定义一个摄像机漫游器。如果你在程序中没有这样做,那么Viewer::run()自动生成一个osgGA::TrackballManipulator来控制摄像机。osgGA库文件中定义了几种漫游器。通过Viewer::setCameraManipulator()来指定你将使用的漫游器

l  设置摄像机投影,并按照你的定义一个矩阵一个矩阵的view。这给了你对于视图的完全控制。

 

If you choose to set the Camera matrices directly, using Viewer::run() is impractical, because it doesn’t allow view changes per frame. Instead, you’ll need to code a small loop that iteratively updates the view and renders a frame.

如果你试图直接设置摄像机矩阵,那么Viewer::run()是无用的。因为它并不允许视图每一帧都变化。相反的,你需要编写一个小的循环语句来反复的更新视图并按帧渲染。

Direct view control

This listing demonstrates how to control the Viewer object’s Camera to change the view each frame.

直接视图控制

本列表演示了该如何通过控制Viewer对象的摄像机来改变每一帧的视图

 

osgViewer::Viewer viewer;

viewer.setSceneData( osgDB::readNodeFile(“cow.osg”));

viewer.getCamera()->setProjectionMatrixAsPerspective(40.,1.,1.,100.);

 

//create a matrix to specify a distance from the viewpoint.

osg::Matrix trans;

trans.makeTranslate(0.,0.,-12.);

 

//rotation angle (in radians)

Double angle(0.);

While (!viewer.done())

{

//create the rotation matrix

osg::Matrix rot;

rot.makeRotate( angle, osg::Vec3(1., 0., 0.));

angle +=0.01;

 

//set the view matrix (the concatenation of the rotation and translation matrices) 

viewer.getCamera()->setViewMatrix(rot*trans);

 

//Draw the next frame

Viewer.frame();                   //这个很重要!!

}

 

Section 2.2 Geodes and Geometry briefly describes OSG’s default world coordinate system orientation. The default Camera matrices orient the world coordinate system with positive x to the right, positive z up, and positive y into the screen. The following text describes how to change the default Camera matrices.

2.2GeodesGeometry已经简要的介绍过了OSG的系统默认坐标。默认的朝向世界坐标的摄像机矩阵是:x轴指向右,z轴向上,y轴指向屏幕。接下来,将会指出如何改变默认的摄像机矩阵。

 

The code below sets the Camera object’s projection matrix once outside the rendering loop. Camera provides several methods for specifying the projection matrix, which should look familiar to most OpenGL programmers.

以下代码将用在渲染循环之外来设定摄像机对象的投影矩阵。Camera提供了好几种可以设置投影矩阵的方法,熟悉OpenGL的程序员应该非常的熟悉。

 

  void setProjectionMatrix( const osg::Matrix& matrix);  //可以认为是设置照相机镜头

 

void setProjectionMatrixAsOrtho( double left, double right, double bottom, double top, double zNear, double zFar);

  void setProjectionMatrixAsOrtho2D( double left, double right, double bottom, double top);

 

void setProjectionMatrixAsFrustum( double left, double right, double bottom, double top, double zNear, double zFar);

void setProjectionMatrixAsPerspective( double fovy, double aspectRation, double zNear, double zFar);

Fovy: specifies the field of view angle, in degrees

Aspect: specifies the aspect ratio (屏幕高宽比) that determines the field of view.

 

Inside the rendering loop, the code updates the Camera object’s view matrix at each frame to increment the rotation angle. Again, Camera provides several entry points that OpenGL developers should be familiar with. The code above sets the view matrix explicitly with the setViewMatrix() method, and Camera also supplies the setViewMatrixAsLookat() method that takes parameters similar to the gluLookAt() entry point.

在渲染循环中,编写的代码更新了摄像机对象的视图矩阵(每帧都增加相同的旋转角)。同时,Camera提供了好几个入口点。程序中,直接使用setViewMatrix来设定视图矩阵,同时,Camera也提供setViewMatrixAlLookat方法。

它与OpenGL里面的gluLookAt()方法类似:

NAME

gluLookAt - define a viewing transformation

C SPECIFICATION

void gluLookAt( GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble

centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz )

PARAMETERS

eyex, eyey, eyez

Specifies the position of the eye point.

centerx, centery, centerz

Specifies the position of the reference point.

upx, upy, upz Specifies the direction of the up vector.

 

Setting the Clear Color

设置Clear颜色

 

The Camera object provides interfaces for several operations besides setting the view. Your application uses Camera to set the clear color. The following code shows how to set the clear color to black.

此外,摄像机对象提供了好几个设置视图之外的接口。在你的程序中,你可以使用Camera来设置clear 颜色,一下代码示范了如何将clear颜色设为黑色:

viewer.getCamera()->setClearColor(osg::Vec4(0.,0.,0.,1.));

 

By default, Camera clears the depth and color buffers. To change this default behavior, use the Camera::setClearMask() method and pass in the appropriate OpenGL buffer flags.

viewer.getCamera()->setClearMask  (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);

The above code snippet configures the Camera to clear the color, depth, and stencil buffers at the start of each frame.

以上的小段代码确保了摄像机在每一帧开始之前都会clear颜色、深度及stencil缓存。

3.1.2 CompositeViewer

多观察者

The osgViewer library supplies an additional viewer class that is outside the scope of this book. This section describes it only at a high level.

osgViewer类还提供了本书没有提到的一个viewer类。

 

While Viewer manages a single view into a scene (possibly with a group of Camera objects to support multipipe rendering), CompositeViewer supports multiple views into one or more scenes and allows your application to specify their rendering order. CompositeViewer supports render-to-texture (RTT) operations, which allows your application to use the rendered image from one view as a texture map in a subsequent view.

Viewer可以控制一个场景中的单一视图(可能是一组支持多管道渲染的摄像机对象),多观察者支持一个或多个场景中的多视图,同时允许你自定义自己的渲染顺序。多观察者支持render-to-texture操作,RTT允许在程序中使用在一视图中已经渲染过的图像作为子序列中的纹理。

 

3.2 Dynamic Modification

动态修改

 

OSG allows you to dynamically modify the scene as needed to create animations. This capability is a requirement of any interactive graphics application. You can modify the geometric data, state parameters, Switch node settings, or even the structure of the scene graph itself.

OSG使你可以按需要实时的修改场景。这个功能是包含任何交互的图像应用程序所必需的。你可以修改几何数据、状态参数、Switch节点设置、甚至场景图本身的结构。

 

As Chapter 1 explains, the cull traversal stores references to geometry and state in a render graph for processing during the draw traversal. The osgViewer library supports many threading models, some of which run the cull and draw traversals in one or more threads. For optimum performance, OSG doesn’t impose locks for thread safety. Instead, it requires that applications only modify the scene graph outside the cull and draw traversals.

如第一章中所说的,拣选遍历包含了在一个绘制遍历时渲染图形中对于geometrystate的引用。osgViewer库支持多线程模型,其中包括单or多线程的拣选遍历及绘制遍历。为了得到更好的性能,OSG没有强加锁来确保线程安全。相反的,它要求程序只改变拣选和绘制遍历之外的场景图。

 

There are a few ways to ensure that your modifications don’t collide with the cull and draw thread. One simple solution- modifying the scene graph outside of the Viewer::frame() call- requires addition code within the main rendering loop. If you desire a more elegant solution, you should perform modifications during the update traversal.

确保你的修改并不会与拣选及绘制线程冲突的方法有以下几个。一个简单的方案就是——在Viewer::frame()之外修改场景图即在主渲染循环中增加额外的代码。如果你想要寻求更加简练的方案,那么就应该在更新遍历中进行修改。

 

This section covers some basic topics related to dynamic scene graph modification.

本章节涵盖了一些基本的与动态场景图修改相关的话题

 

l  For optimum performance and thread safety, you need to tell OSG which parts of the scene graph you intend to modify. You do this by setting the data variance for any Object (Node, Drawable, StateSet, etc.).

l  OSG allows applications to assign callbacks to Node and Drawable objects. OSG executes these callbacks during specific traversals. To modify a Node or Drawable during the update traversal, applications set an update callback.

l  Applications don’t always know in advance which parts of a scene graph they’ll modify. They might need to search a scene graph to find the node of interest, or they might allow users to pick a node using the mouse or other input mechanism.

l  要确保性能最优及线程安全,我们需要告诉OSG我们想要修改场景图的哪一部分。可以通过设置各个对象的数据变量来做到

l  OSG允许对节点及Drawable分配回调。在特定的遍历中时,OSG将会执行这些。为了能够在更新遍历中修改NodeDrawalbe,程序应该设置一个更新回调。

l  程序没有必要永远都事先知道场景图的哪一个部分需要修改。他们可以通过搜寻场景图来找到目标节点,或者允许用户使用鼠标或其他输入机制来选择节点。

 

 

原创粉丝点击