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
相关产品推荐
相关产品推荐

