在第3.4节中,我们介绍了如何将HOOPS/3dGS连接到本地窗口系统,以便HOOPS知道将其输出发送到何处。这还需要禁用输入处理,本章将对此进行更详细的讨论。
您可以使用禁用输入驱动程序选项禁用HOOPS/3dGS输入处理。此驱动程序选项有两种变体:
HC_Set_Driver_Options("disable input");
HC_Set_Driver_Options("disable input = all");
这两种变体都告诉HOOPS/3dGS,您的应用程序将直接从窗口系统接收输入事件。因此,HOOPS/3dGS不会尝试读取鼠标或键盘等输入设备。
在第一个变体中,HOOPS/3dGS不读取输入设备,但它仍然从窗口系统接收绘画消息(有时称为曝光或损坏事件)。因此,当应用程序收到绘制消息(因为输出窗口的全部或部分被遮挡,然后变为可见)时,HOOPS/3dGS将自动重新绘制其输出窗口。
在第二种变体(“disable input = all”)中,HOOPS/3dGS根本不接收输入消息。因此,应用程序必须接收绘制消息并显式调用::Update_Display。
如果系统选项禁用输入设置为all,则当您调用::Update_Display时,HOOPS将重新绘制整个场景,即使只有一小部分场景需要重新绘制。为了解决这种效率低下的问题,HOOPS/3dGS提供了一个名为::Control_Update的命令。
可以使用::Control_Update命令指定需要重新绘制HOOPS/3dGS数据库的哪些部分。您可以指定要按段、按键(使用::Control_Update_by_key命令)或按区域(使用:Control_Uupdate_area或::Control_Update_area_by_key命令)重画的零件。例如,如果来自窗口系统的绘制消息指定只需要重新绘制输出窗口的一部分,则可以使用::Control_Update_area命令指定要绘制的区域。
在某些情况下,当修改HOOPS/3dGS数据库的一部分时,HOOPS会在该节点自动设置一个标志,然后将其传播到驱动程序段。在下一次显示更新期间,该标志向HOOPS发出信号,以重新绘制树的该部分。
但是,如果要修改不影响场景渲染的属性(如用户选项),则可能不希望触发重画。
要防止标志传播,可以关闭::Define_System_Options中的更新控制选项。
我们建议您在修改特定数据库之前将其关闭,然后再将其打开。默认情况下,更新控制处于打开状态。
当您使用::Control_Update命令(或相关命令)时,您将负责选择要更新的HOOPS数据库的哪些部分。这种责任可能需要认真工作。有关详细信息,请参阅HOOPS/3dGS参考手册中的::Control_Update条目。
在用户操纵模型的过程中,HOOPS提供了LOD等功能,以帮助应用程序在场景中保持尽可能多的视觉完整性,而对渲染性能的影响尽可能小。然而,更新有时会导致应用程序对用户输入无响应,特别是当HOOPS在一系列用户操作后渲染场景时。
为了确保应用程序在更新期间响应用户输入,可以在调用::update_Display之前使用::set_Driver_Options中的退出更新(exit update)选项设置回调。在更新过程中,HOOPS将定期调用回调。如果您想中断更新以响应用户事件或只是结束更新过程,可以在回调中调用::HIC_Abort_update。我们建议您仅在大量更新的情况下设置此回调。
当更新在渲染整个场景之前结束时,如果没有任何变化,HOOPS可能会在下次更新时继续绘制场景。例如,如果您已使用::Set_Heuristics设置要延迟的最大范围模式,并且正在使用定时更新,则可能会发生这种情况。要了解上次更新是否是上一次更新的延续,可以调用::Show_Device_Info传递恢复更新选项。如果HOOPS返回“是”,则上一次更新是试图完成绘制部分渲染的场景。
以下是如何在Microsoft Windows平台上设置和使用退出更新选项的示例:
void MainForm::MainForm()
{
...
//Registering the callback
HC_Define_Callback_Name("exit_update_handler", UpdateEventHandler);
...
}
void MainForm::SetExitUpdate()
{
HC_Open_Segment_By_Key(m_pView->GetViewKey());
//sets the exit update option to UpdateEventHandler
HC_Set_Driver_Options("exit update = exit_update_handler");
HC_Close_Segment();
}
void MainForm::UpdateEventHandler(struct ht_net_rendition *nr)
{
//Checks to see the left mouse button was pressed
int state = GetAsyncKeyState(VK_LBUTTON);
if (state & 32768)
HIC_Abort_Update(nr);
}