1.HOOPS/3DGS Windows
当HOOPS/3DGS首次开发时,窗口系统并不常见——X-Windows和Microsoft Windows都还不存在。在那些日子里(例如,在DOS或UNIX上),当3D图形应用程序启动时,它通常会控制整个显示屏。如果您需要多个窗口,则由HOOPS来创建它们,因为没有窗口系统来提供它们。HOOPS/3DGS在一定程度上是当年遗留下来的,它有自己的窗口概念。
1.1 window属性
在HOOPS/3DGS中,窗口是使用set_window命令在段上设置的属性。此命令接受四个参数,这些参数定义了相对于父窗口指定的窗口的左、右、下和上坐标。在线段上设置窗口属性会导致该线段中的所有几何图形都在设定的窗口区域内绘制。窗口属性与任何常规属性一样继承,因此该分段的子分段中的任何几何体也会在该窗口内绘制(除非子分段上显式设置了窗口属性)。
正如我们在“相机”页面中所讨论的,相机将3D场景映射到2D窗口中。特别是,相机字段定义输出窗口的坐标。默认情况下,摄影机场将输出窗口的坐标设置为x和y的范围在-1.0和1.0之间。通过拉伸摄影机投影,摄影机输出场将精确映射到输出窗口上。对于非拉伸投影,填充相机场的宽度或高度以保持相机场的纵横比。
net window属性定义显示器上的窗口,摄影机场映射到该窗口中。因此,当在线段上设置窗口属性时,它会导致继承窗口属性的任何几何体映射到该窗口中。
该程序将输出窗口分为四个大小相等的子窗口(回想一下,如果没有窗口系统,段“?Picture”对应于HOOPS输出窗口或整个屏幕):
HC_Open_Segment("?Picture");
HC_Open_Segment("upper left window");
HC_Set_Window(-1.0, 0.0, 0.0, 1.0);
HC_Close_Segment();
HC_Open_Segment("upper right window");
HC_Set_Window(0.0, 1.0, 0.0, 1.0);
HC_Close_Segment();
HC_Open_Segment("lower left window");
HC_Set_Window(-1.0, 0.0, -1.0, 0.0);
HC_Close_Segment();
HC_Open_Segment("lower right window");
HC_Set_Window(0.0, 1.0, -1.0, 0.0);
HC_Close_Segment();
HC_Close_Segment();
HOOPS中的四个子窗口。
上面的代码为每个窗口创建一个新段,并用每个象限的坐标设置该段的窗口属性。例如,段“左上窗口”定义了一个在x中从-1.0到0.0,在y中从0.0到1.0的窗口。当我们将几何体添加到场景中时,它出现的窗口取决于几何体放置在四个子段中的哪个子段中。例如,如果我们想绘制一个仅出现在左上角窗口中的对象,我们将其放置在名为“左上角”的段中。如果我们希望相同的对象出现在所有四个窗口中,那么我们使用Include_Segment命令将相同的对象包含在所有四个子段中,并在每个子段上设置适当的摄影机。
当我们将一个窗口划分为子窗口时,每个新窗口都有自己的坐标系。摄影机场被映射到此坐标系中,就像子窗口是顶级窗口一样。因此,每个子窗口的x和y坐标范围从-1.0到1.0(除非其相机场已更改)。每个子窗口的中心对应于该段的网络摄像机目标,子窗口的尺寸对应于该分段的网络摄像机场。
请注意,段“?Picture”隐含地是一个窗口-与HOOPS输出窗口相对应的整个窗口。无法在“?Picture”上设置窗口属性(使用set_window),因为“?Picture”已经有一个隐式窗口,并且无法取消设置窗口属性。通常,您不能修改任何驱动程序实例的窗口属性(包括别名“?Picture”或“?Hardcopy”的值)。可以在驱动程序级别修改的一个窗口属性是全屏模式。如果在Set_Driver_Options中打开全屏模式,HOOPS会将“?Picture”窗口绘制为覆盖整个桌面的无边框窗口。请注意,此选项仅在HOOPS处于独立模式且未使用MFC或Qt等外部窗口系统时有效。
传递给Set_Window的参数大于父窗口相机字段的坐标是合法的。例如,如果相机场的默认值为-1.0到1.0,则可以将子窗口的坐标设置为-2.0到2.0。但是,只有子窗口中实际适合父窗口的部分才可见;其余部分将被剪裁。可以使用此功能在窗口内滚动场景。
HOOPS窗口本身可以递归地具有子窗口等。每个子窗口的坐标是根据其直接父窗口的坐标定义的。
1.2 重叠的窗口
通过创建坐标重叠的窗口,可以使用Set_Window命令创建重叠窗口:
子窗口总是出现在父窗口的前面,但是当重叠窗口是彼此的兄弟窗口(具有相同的父段)时,一个窗口将部分地隐藏其他窗口。在HOOPS中,每个窗口都创建在任何现有的同级窗口之前,因此最近创建的窗口将显示在所有同级窗口之前。对于多个重叠窗口,顺序(从后到前)与创建窗口的顺序相同。
可以使用Bring_To_Front命令更改同级窗口的顺序。Bring_To_Front使其参数子窗口的行为如同该子窗口的段是最近创建的一样。如果要指定一组同级子窗口的顺序,应该从后到前依次调用Bring_to_Front。
可以在非窗口线段上使用Bring_To_Front,在任何几何体上使用Brink_To_Front_By_Key,以对几何体和线段之间以及窗口进行排序。但是,请注意,Bring_To_Front和Bring_To_Front_By_Key仅在当前段的隐藏曲面处于禁用状态时才对几何体和非窗口段有效(请参见Set_Heuristics)。Bring_To_Front在子窗口上工作,无论是否启用隐藏曲面。您也可以使用优先级控制前面显示的内容。请参见第6.1节,了解有关移除隐藏表面和将物体带到前面的更多信息。
1.3其他窗口属性
Clear Windows
默认情况下,窗口是不透明的-它们会遮挡后面的任何窗口。但是,可以通过将窗口模式设置为“clear”来使窗口透明:
HC_Set_Window_Pattern("clear");
要使窗口透明,但同时允许子窗口中的几何体与父窗口中的图形交互,请在调用Set_window_Pattern时传递“invisible”选项。
Patterned Windows
此外,可以使用Set_Window_Pattern为窗口定义背景图案。除了“clear”和“invisible”图案外,可能的窗口图案与多边形面图案相同-例如,“##”表示十字线,“::”表示虚线,“[][]”表示棋盘。有关详细信息,请参阅Set_Window_Pattern命令。
Set_Color命令的两个选项适用于窗口。例如
HC_Set_Color("windows=light gray");
将窗口背景色设置为浅灰色。当窗口应用了图案(而不是“solid”或“clear”)时,将使用窗口对比色绘制图案。例如
HC_Set_Window_Pattern("::");
HC_Set_Color("windows=purple,window constrast=yellow");
在紫色背景上绘制由黄色点组成的窗口背景(此示例不应被视为对该特定颜色方案的认可)。
渐变窗口背景
为Set_window_Pattern设置“窗口着色”选项会告诉系统绘制渐变窗口背景。选项设置为“N”、“NE”等方向。窗口颜色为“from”颜色,窗口对比度颜色为“to”颜色。例如,“N”表示窗口底部将反映窗口颜色,而窗口顶部将是窗口对比度颜色。有关选项的完整列表,请参阅Set_Window_Pattern参考。
Windows边框
最后,当HOOPS创建一个窗口时,它会在窗口边缘周围绘制一条两像素宽的边界线作为窗口框架。窗口内的图像会稍微缩小,以考虑框架。您可以使用Set_window_frame命令控制HOOPS是否绘制此窗框。选项包括“on”、“single”和“off”。默认情况下,窗口框架选项设置为“on”。要绘制单个像素宽的框架,请选择“single”选项。要关闭帧,请使用
HC_Set_Window_Frame(“off”);
除了这些选项之外,“single”和“on”还有两个修饰符“decorative”和“insert”。“decorative”修饰符告诉HOOPS不要收缩图像。相反,它将按照数据库中的指定绘制图像,然后在渲染的图像上绘制框架。如果设置了“inset”修改器,则HOOPS将始终在父窗口框架内绘制整个窗口框架。
窗框使用窗口对比色绘制。
当HOOPS/3DGS与窗口系统一起使用时,通常整个窗口(对应于“? Picture”的窗口)将由窗口系统在其周围绘制边框,因此HOOPS/3D GS不会在该窗口周围绘制额外的边框。窗口系统绘制的边框通常还包含包含关闭框的控制区域、调整窗口大小的控件、滚动条等。您可以使用Set_Driver_options的“border”和“control area”选项控制整个窗口的框架。例如,以下命令指示HOOPS/3DGS告诉窗口系统不要在整个窗口周围绘制边框或控制区域:
HC_Set_Driver_Options(“no border,no control area”);
1.4 HOOPS/3DGS窗口使用
通常,HOOPS/3DGS窗口只能用于表示单个视图的“子部分”,并且每个单独的视图都应与唯一的HOOPS/3D GS驱动程序实例相关联(该实例具有自己的隐式“顶级”HOOPS/3DGS窗口)。例如,如果视图包含轴或图例,则可以使用HOOPS/3DGS窗口查看位于视图顶部的轴或图例。应用程序中的每个主视图都应该有自己独特的窗口系统(GUI)窗口,并且应该有自己的驱动程序实例。这将在下一节中详细讨论。
2.使用HOOPS的窗口系统Windows
2.1 多窗口例子
3.使用本地窗口系统
对于典型的图形应用程序,您将使用直接调用本地窗口系统来编写用户界面,而HOOPS/3DGS将严格用于存储和显示2D/3D矢量信息。然而,HOOPS/3DGS本身会调用窗口系统。例如,如果使用HOOPS/3DGS命令绘制三维线,则HOOPS可能需要将该线转换为二维屏幕空间,删除该线前面的对象隐藏的任何部分,然后使用本机窗口系统调用绘制一个或多个二维线段。因此,HOOPS/3DGS和您的应用程序都将调用本地窗口系统,将对象绘制到屏幕的同一区域。因此,HOOPS/3DGS和本地窗口系统需要协调它们的操作,例如决定何时清除屏幕、绘制对象的顺序、窗口最小化或被破坏时的操作等等。幸运的是,这种协调在HOOPS/3D GS中非常容易实现。
将HOOPS/3DGS连接到窗口系统涉及两项任务:将窗口系统的用户输入循环连接到HOOPS/3D GS,以便HOOPS/3DGS可以处理选择事件,以及将HOOPS/3DGS连接至窗口系统窗口,以便HOUPS/3DGS知道从何处绘制其输出。
3.1用户输入
当您使用窗口系统编写用户界面时,所有低级用户输入(如鼠标和键盘事件)都将由窗口系统处理。
HOOPS/3DGS对用户输入的唯一帮助是帮助处理选择事件。要选择3D对象,用户在包含HOOPS输出的窗口中单击鼠标。窗口系统处理鼠标事件并将其传递给应用程序。然后,应用程序的事件处理程序使用此事件中的鼠标位置,并使用HOOPS命令Compute_Selection计算已选择的3D对象。第4.2节介绍了选择事件。
3.2 连接到一个Window-system Window
通常,HOOPS/3DGS为每个驱动程序实例创建自己的输出窗口(如“?图片”)。当您使用窗口系统编写用户界面时,窗口系统将负责创建输出窗口。您所需要做的就是用“usewindowid”驱动程序选项告诉HOOPS/3DGS这个输出窗口是什么,这样HOOPS/3D GS就可以在其中绘制。
要将HOOPS/3DGS连接到窗口系统窗口,应用程序需要执行以下六个步骤:
1.删除与“?Picture”关联的驱动程序实例段,以便HOOPS/3DGS不会创建输出窗口或尝试向其发送输出。
2.创建窗口。使用本机窗口系统创建窗口;不涉及HOOPS/3DGS。
3.为窗口创建新的HOOPS/3DGS驱动程序实例段。
4.在新的驱动程序实例段上设置“use window id”驱动程序选项;此选项将驱动程序实例连接到windows系统窗口。
5.禁用HOOPS/3DGS输入,因为用户输入将由窗口系统处理。使用“disable input”或“disable input=all”驱动程序选项(下面将详细讨论)
6.当窗口系统破坏窗口时,删除驱动程序实例段。
注意,可以更改某些步骤的相对顺序。例如,我们可以在删除“?Picture”驱动程序实例(步骤1)之前创建窗口系统窗口(步骤2)。
不同的窗口系统使用不同的技术来创建窗口,因为本书不是关于如何使用窗口系统的,所以我们将不详细讨论这个主题(我们将简单地给出几个示例)。有关创建窗口系统窗口的详细信息,请参阅窗口系统的文档。无论您使用哪个窗口系统,它都会向应用程序返回标识窗口的id或句柄。该id是传递给“use window id”驱动程序选项的id。
步骤5中的驱动程序选项“禁用输入”告诉HOOPS/3DGS不要处理任何输入事件,如鼠标单击或按键。您的应用程序可以从窗口系统接收这些事件,并对其进行适当处理。然而,即使设置了“禁用输入”驱动程序选项,HOOPS/3DGS也会处理来自窗口系统的某些非输入事件,例如当HOOPS/3D GS窗口从另一个窗口后面打开时生成的“暴露”事件。如果希望HOOPS/3DGS完全禁用事件处理,则应指定“disable input=all”作为驱动程序选项。在这种情况下,当应用程序收到曝光事件或其他类似事件时,您需要明确告诉HOOPS/3DGS重新绘制场景(使用Update_Display)。上述步骤封装在HOOPS/GUI模块中,用于各种GUI环境和工具包,包括MFC、Motif、ActiveX和QT)