This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
cn:orx:tutorials:viewport [2010/07/06 16:25 (15 years ago)] – jtianling | cn:orx:tutorials:viewport [2020/08/19 20:19 (5 years ago)] (current) – Old content sausage | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | 本页由 落后的簔羽鹤 翻译自[[en: | ||
- | ====== 视口与摄像机(viewport & camera) ====== | ||
- | |||
- | ===== 综述 ===== | ||
- | |||
- | 前面的基本教程[[cn: | ||
- | |||
- | 此教程显示了如何使用有多个摄像机的多视口技术。教程中将同时创建4个视口。 | ||
- | |||
- | 分别为左上角的(Viewport1),右下角的(Viewport4),它们共用一个摄像机(Camera1),实现此功能,只需要在配置文件中配置2个视口的Camera属性,为同一个(也就是Camera1)。当我们使用鼠标的左右键旋转摄像机(Camera1), | ||
- | |||
- | 右上角视口(Viewport2)是基于另一个摄像机(Camrea2),此摄像机的视锥较第一个窄,所以显示时比例是其的两倍大。在教程的程序中,我们不能通过任何操作设置此视口。 | ||
- | |||
- | 最后一个视口(Viewport3)是基于Camera3的,Camera3的配置与Camera1完全一样。 | ||
- | |||
- | NB:当两个视口重叠,较先创建的将显示在顶层。\\ | ||
- | |||
- | 最后,有一个固定不动的箱子和一个世界坐标随着鼠标实时移动的小兵,也就是说无论如何设置视口的摄像机,无论鼠标在那个视口上移动,小兵在它所属的视口中,相对于鼠标在在屏幕中的位置移动。 | ||
- | |||
- | 在配置文件中使用随机关键字符‘~’, | ||
- | |||
- | NB:摄像机将它的坐标/ | ||
- | |||
- | ===== 详细说明 ===== | ||
- | |||
- | 常我们需要首先载入配置文件,创建时钟和注册回调的 Update函数,最后创建主要的Object信息。关于实现的详情,请联系前面的教程。 | ||
- | |||
- | 虽然这次我们创建了4个视口,却没有什么新东西,仅仅是以下4行代码。 | ||
- | |||
- | <code c> | ||
- | orxViewport_CreateFromConfig(" | ||
- | orxViewport_CreateFromConfig(" | ||
- | orxViewport_CreateFromConfig(" | ||
- | |||
- | 正如你所看到的,我们只使用了 Viewport1的引用,以便后面进行操作。 | ||
- | |||
- | 让我们直接跳到Update函数的代码。 | ||
- | |||
- | 首先我们通过捕捉鼠标的坐标,设置士兵的位置。我们已经在frame tutorial里实现过了。这里我们做了一样的事情,但在4个视口中工作的都很完美。当鼠标离开视口时,世界坐标的指针,将被orxNull值所代替,也就不会触发士兵的移动了。 | ||
- | |||
- | <code c> | ||
- | |||
- | if(orxRender_GetWorldPosition(orxMouse_GetPosition(& | ||
- | { | ||
- | orxVECTOR vSoldierPos; | ||
- | |||
- | orxObject_GetWorldPosition(pstSoldier, | ||
- | vPos.fZ = vSoldierPos.fZ; | ||
- | |||
- | orxObject_SetPosition(pstSoldier, | ||
- | }</ | ||
- | |||
- | 在操作视口之前,我们先关注下视口所关联的摄像机,我们可以移动,旋转和缩放它。获取摄像机的代码如下所示: | ||
- | |||
- | <code c> | ||
- | |||
- | 非常简单。让我们实现旋转。 ((其他方向仅仅只有部分代码,但是逻辑是一样的)). | ||
- | |||
- | <code c> | ||
- | { | ||
- | orxCamera_SetRotation(pstCamera, | ||
- | }</ | ||
- | |||
- | 我们再次看到旋转的角度时间并不依赖于FPS而是时钟的DT。我们也可以通过设置System这个配置选项来设置旋转速度,而不是使用硬编码。 | ||
- | |||
- | 实现缩放如下: | ||
- | <code c> | ||
- | { | ||
- | orxCamera_SetZoom(pstCamera, | ||
- | }</ | ||
- | |||
- | |||
- | 因为这个代码没有使用时钟信息,所以他将会被时钟频率和帧率所影响。 | ||
- | 最后让我们移动摄像机。 | ||
- | |||
- | <code c> | ||
- | |||
- | if(orxInput_IsActive(" | ||
- | { | ||
- | vPos.fX += orx2F(500) * _pstClockInfo-> | ||
- | } | ||
- | |||
- | orxCamera_SetPosition(pstCamera, | ||
- | |||
- | 好了,与摄像机有关的先到这里吧。 | ||
- | 在下面的配置中我们将看到,同一个摄像机被连接到两个不同的视口。操作摄像机将同时影响两个视口。 | ||
- | |||
- | 我们可以直接修改视口的位置和尺寸,如下所示: | ||
- | |||
- | <code c> | ||
- | |||
- | orxViewport_GetRelativeSize(pstViewport, | ||
- | |||
- | if(orxInput_IsActive(" | ||
- | { | ||
- | fWidth *= orx2F(1.02f); | ||
- | fHeight*= orx2F(1.02f); | ||
- | } | ||
- | |||
- | orxViewport_SetRelativeSize(pstViewport, | ||
- | |||
- | orxViewport_GetPosition(pstViewport, | ||
- | |||
- | if(orxInput_IsActive(" | ||
- | { | ||
- | fX += orx2F(500) * _pstClockInfo-> | ||
- | } | ||
- | |||
- | orxViewport_SetPosition(pstViewport, | ||
- | |||
- | 如上 所示,没有什么惊奇的,非常简单。 | ||
- | |||
- | 让我们来接着看看 viewport的配置方面的东西。 | ||
- | |||
- | <code ini> | ||
- | Camera | ||
- | RelativeSize | ||
- | RelativePosition | ||
- | BackgroundColor | ||
- | |||
- | [Viewport2] | ||
- | Camera | ||
- | RelativeSize | ||
- | RelativePosition | ||
- | BackgroundColor | ||
- | |||
- | [Viewport3] | ||
- | Camera | ||
- | RelativeSize | ||
- | RelativePosition | ||
- | BackgroundColor | ||
- | |||
- | [Viewport4] | ||
- | Camera | ||
- | RelativeSize | ||
- | RelativePosition | ||
- | BackgroundColor | ||
- | |||
- | 我们可以看到,还是没有什么新的让人惊喜的东西。\\ | ||
- | 一共有3个摄像机,它们关联了4个视口,其中Camera1关联了Viewport1和Viewport4。\\ | ||
- | 我们注意到Viewport1的配置文件中relativeSize设置为(0.5, | ||
- | 接下来我们注意到其他视口的RelativeSize属性被设置成@Viewport1。它的意思是RelativeSize属性继承Viewport1的 RelativeSize属性,也就是说它们的RelativeSize属性和Viewport1的RelativeSize属性一样。我们也可以看到 Viewport4的Camera属性被设置成@Viewport1, | ||
- | |||
- | 为了避免视口在屏幕中互相重叠遮盖,我们可以设置RelativePosition属性为常量字符((由关键字 top, | ||
- | |||
- | 最后前三个视口使用随机的红色作为背景颜色,设置如下: | ||
- | |||
- | <code ini> | ||
- | |||
- | 意思是这个viewpor将使用一个随机的红色.((' | ||
- | 如果我们希望通过准确的随机颜色进行设置,可以使用一下列表的形式设置,随机的颜色分别为黄、青和品红,设置如下: | ||
- | |||
- | <code ini> | ||
- | |||
- | This gives three possibilities for our random color: yellow, cyan and magenta. | ||
- | 这种使用方式是相当于在三个颜色(黄色,蓝绿色,品红)中进行随机。 | ||
- | |||
- | 最后让我们关注摄像机的设置。 | ||
- | |||
- | <code ini> | ||
- | FrustumWidth | ||
- | FrustumHeight = @Display.ScreenHeight | ||
- | FrustumFar | ||
- | FrustumNear | ||
- | Position | ||
- | |||
- | [Camera2] | ||
- | FrustumWidth | ||
- | FrustumHeight = 300.0 | ||
- | FrustumFar | ||
- | FrustumNear | ||
- | Position | ||
- | |||
- | [Camera3@Camera1]</ | ||
- | |||
- | 我们仅仅定义了他们的[[wp> | ||
- | NB: 因为我们使用的" | ||
- | |||
- | 我们可以发现Camera3完全继承自Camera1,它没有覆盖Camera1的任何属性。他们有完全一样的属性。\\ | ||
- | NB: NB:使用完全继承所有属性可以写成:[MySection@ParentSection]。\\ | ||
- | 为什么实用两个不同的摄像头呢?仅仅因为可以有两个不同的物理实体(physical entities):我们在代码中修改了Camera1的属性,而 Camara3将保持不变。\\ | ||
- | 我们注意到Camera1的FrustumWidth和FrustumHeight属性继承自Display的屏幕设置。\\ | ||
- | NB: 当继承某个属性,可以写成MyKey = @ParentSection.ParentKey.当两个key一样时,其中父选关键字可以省略如:SameKey = @ParentSection.\\ | ||
- | |||
- | 最后我们注意到Camera2具有较小的视锥。\\ | ||
- | 也就是说Camera2只能看到世界空间的较小部分。所以视口看起来具有了放大的效果! =)\\ | ||
- | |||
- | ===== 资源 ===== | ||
- | |||
- | 源代码: [[https:// | ||
- | |||
- | 配置文件: |