You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nifty升级至1.4.2版本后的初始化问题求助

升级Nifty v1.4.2、Jogamp v2.4.0、JDK 11.0.2后的代码适配问题

环境信息

  • Eclipse版本:Eclipse IDE for RCP and RAP Developers 2020-06(4.16.0)
  • 系统:Windows 10

升级前代码

public class ISOView extends Object2D
{
  private IViewManipulation viewerInteraction;
  private IRenderEvent renderEvent;
  private ISOViewNiftyController isoNiftyController;
  private JoglInputSystem inputSystem;
  private Nifty nifty;

  public ISOView(IViewManipulation viewerInteraction, IRenderEvent renderEvent) 
  {
    super(RenderOption.TOP);
    this.renderEvent = renderEvent;
    this.viewerInteraction = viewerInteraction;
  }

  @Override
  public void render(GL gl, RenderParameters params, boolean selection)
  {
    if( params == null || params.getCamera() == null || !params.getCamera().hasFrustum() )
      return;
    
    GL2 gl2 = OpenGLUtil.getMinGL(gl);
    renderNifty(gl2, selection);
    isoNiftyController.update();
  }

  private void renderNifty(GL2 gl2, boolean selection)
  {
    if (ISOViewNiftyController.isNiftyUsed()) {
      // some code
    }
  }

  private void initNifty()
  {
    Logger.getLogger("de.lessvoid").setLevel(Level.OFF);
    inputSystem = new JoglInputSystem();
    nifty = new Nifty(new JoglRenderDevice(), new NullSoundDevice(), inputSystem, new AccurateTimeProvider());
    // other code
  }

  @Override
  public void cleanUp(GL gl)
  {
    // TODO Auto-generated method stub

  }

  public JoglInputSystem getInputSystem()
  {
    return inputSystem;
  }

  @Override
  public boolean belongsToScene(SceneType type)
  {
    // some code
  }
  
  @Override
  public void dispose( BaseViewer baseViewer )
  {
    // some code
  }
}

遇到的问题

  • 实例化JoglInputSystem现在需要传入新参数,无参构造已不可用
  • 原JoglRenderDevice()构造方法已废弃,无法再用它初始化Nifty

目前修改后的initNifty方法(待完善):

private void initNifty(){
  Logger.getLogger("de.lessvoid").setLevel(Level.OFF);
  com.jogamp.newt.Window newtWindow = null;//Fix!!!
  inputSystem = new JoglInputSystem(newtWindow);
  de.lessvoid.nifty.spi.render.RenderDevice renderDevice = null;//Fix!!!
  nifty = new Nifty(renderDevice, new NullSoundDevice(), inputSystem, new AccurateTimeProvider());
  // some code
}

已尝试的操作

试过通过以下代码创建JoglInputSystem,能成功编译,但不确定是否正确:

GLCapabilities caps = new GLCapabilities(GLProfile.getMaxProgrammable(true));

GLWindow glW = GLWindow.create(caps);// implements com.jogamp.newt.Window
inputSystem = new JoglInputSystem(glW);

但卡在RenderDevice的创建上:RenderDevice接口只有两个实现类,尝试创建ScalingRenderDevice需要NiftyRenderEngine,而NiftyRenderEngineImpl的构造又依赖RenderDevice,陷入循环依赖。相关类结构如下:

Nifty(RenderDevice newRenderDevice, SoundDevice newSoundDevice, InputSystem newInputSystem, TimeProvider newTimeProvider) 
    Interface RenderDevice - All Known Implementing Classes:
        BatchRenderDevice
            BatchRenderDevice(BatchRenderBackend renderBackend)
            BatchRenderDevice(BatchRenderBackend renderBackend, BatchRenderConfiguration renderConfig)
        ScalingRenderDevice
            ScalingRenderDevice(NiftyRenderEngine renderEngine, RenderDevice interal)
                Interface NiftyRenderEngine - All Known Implementing Classes:
                    NiftyRenderEngineImpl(RenderDevice renderDeviceParam)

解决方案

1. 正确创建JoglInputSystem

你的尝试方向正确,但要传入当前渲染使用的窗口实例,而非新创建的空窗口。如果程序中已有GLWindow实例(比如从渲染上下文获取),直接传入即可;若没有,可通过GLDrawable获取关联窗口:

// 从当前GL上下文获取GLDrawable
GLDrawable drawable = gl2.getGLDrawable();
com.jogamp.newt.Window newtWindow = null;
if (drawable instanceof GLWindow) {
    newtWindow = (GLWindow) drawable;
}
inputSystem = new JoglInputSystem(newtWindow);

2. 创建可用的RenderDevice

Nifty v1.4.2废弃JoglRenderDevice后,推荐用BatchRenderDevice配合JOGL提供的后端实现。先创建JoglBatchRenderBackend,再用它实例化BatchRenderDevice:

// 创建JOGL渲染后端
JoglBatchRenderBackend renderBackend = new JoglBatchRenderBackend(gl2);
// 创建BatchRenderDevice
RenderDevice renderDevice = new BatchRenderDevice(renderBackend);

完整initNifty方法示例

结合上述修正,完整的初始化方法需在GL上下文可用时调用(比如第一次执行render时):

private void initNifty(GL2 gl2) {
    Logger.getLogger("de.lessvoid").setLevel(Level.OFF);
    
    // 初始化InputSystem
    GLDrawable drawable = gl2.getGLDrawable();
    com.jogamp.newt.Window newtWindow = null;
    if (drawable instanceof GLWindow) {
        newtWindow = (GLWindow) drawable;
    }
    inputSystem = new JoglInputSystem(newtWindow);
    
    // 初始化RenderDevice
    JoglBatchRenderBackend renderBackend = new JoglBatchRenderBackend(gl2);
    RenderDevice renderDevice = new BatchRenderDevice(renderBackend);
    
    // 初始化Nifty
    nifty = new Nifty(renderDevice, new NullSoundDevice(), inputSystem, new AccurateTimeProvider());
    
    // 后续Nifty初始化代码(如加载XML布局等)
    // ...
}

注意事项

  • 确保initNifty在GL上下文初始化后调用,比如在render方法中检查nifty是否为null,再执行初始化
  • 若需自定义渲染行为,可创建BatchRenderConfiguration并传入BatchRenderDevice构造方法

内容的提问来源于stack exchange,提问作者know

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 23:45:33