Java:openGL:JOGL:当我调用display()方法时,幕后会发生什么?

我有这行代码:

renderableObject.renderObject(gl, glu); 

这会导致openGL呈现大量对象,但只有在使用时才会起作用:

 @Override public void display(GLAutoDrawable drawable) { renderableObject.renderObject(gl, glu); } 

如果我在重写的显示方法之外调用该行,我得到一个exception,说当前线程上没有glContext,实际上如果我在这个方法之外调用任何gl draw命令,我得到相同的exception

理想情况下,我想创建一次大量的显示列表,然后使用奇数显示列表每帧渲染它们以定期重新创建。 但是我必须通过这个单一的display()方法,这意味着如果显示列表已经创建,或者需要更改等,我必须测试每一帧…每秒60次! 当我需要时可以单独处理它们时会浪费处理能力。

所以无论调用display()方法做什么,我都希望能够复制它,这样我就可以创建大量自己的自定义显示方法,而无需通过这一方法来实现一切!

那么我可以做一个简单的电话吗?

虽然看起来很奇怪,但这是应该工作的方式。

在幕后发生的事情是,当您创建的GLCanvas被绘制出来时,幕后JOGL正在做一大堆工作。 它正在创建一个GLContext,并使其成为当前线程的GLCanvas的最新版本。 只有在完成后才能进行渲染调用。 尚未成为当前的GLContext或从中派生的GL对象对您没用。 此外,GLContext 仅为该线程设置为当前状态,并且在显示调用完成后立即变为非当前状态,因此挂起对它的引用或GL以供以后使用将不起作用。

几乎所有JOGL应用程序都以这种方式工作。 您创建一个GLEventListener,并在其中实现display(),从GLAutoDrawable中提取GL并使用它来进行渲染调用。 您不希望在任何其他地方进行渲染调用,只是想要在paint()方法之外进行Graphics2D调用。 大多数初学Java程序员都试图从paint方法之外进行绘制; 这是类似的。 如果你需要触发重绘,那么你就像使用Java2D一样:使用invalidate()。 (您当然可以编写从display()方法调用的子方法,并将GL或GLAutoDrawable作为参数)。

有一些方法可以让你专门创建一个GLContext并让它自己流行,但它们很少是必需的。 在这里使用这种方法几乎总是更好。