2011-09-14 149 views
5

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

renderableObject.renderObject(gl, glu); 

这导致通过openGL的被渲染对象的大名单,但是它只能使用时如下:

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

如果我所说的行重写的显示方法以外,我得到一个异常说有在当前线程上没有glContext,其实如果我叫任何GL得出这样的方法我得到相同的异常之外的命令

现在最好我想创造了很多显示列表一次,然后渲染他们的每一帧奇数显示列表定期重新创建。但是我必须通过这个单一的display()方法,这意味着如果显示列表已经创建或者需要更改等,我将不得不测试每一帧。每秒60次!当我需要时可以单独处理它们时,多少浪费处理能力。

因此,无论调用display()方法,我都希望能够复制它,使我可以创建大量我自己的自定义显示方法,而无需通过这一种方法处理所有事情!

那么是否有一个简单的电话我可以让自己?

回答

2

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

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

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

有几种方法可以专门创建一个GLContext并使其自己处于最新状态,但它们很少是必需的。在这里使用这种方法几乎总是更好。

+1

幕后JOGL正在做一堆工作。它正在创建一个GLContext,并使其成为当前线程的GLCanvas。 -------我不能自己做这个吗? – Troyseph

+0

塞巴斯蒂安特洛伊,你可以但它做什么并不是微不足道的。您可以执行严格的最小操作(从GLAutoDrawable获取GLContext并使其成为最新版本),但请记住,JOGL包含许多不错的怪癖和解决方法,这些操作比C中的本地纯OpenGL或Java中的其他绑定更安全, C#,Python,...而且,如果你做了不好的事情,那么破坏你的性能真的很容易。当我将Ardor3D移植到JOGL 2时,我发现makeCurrent()被无用地调用了一次,当v-sync关闭时,删除这个调用给了我一个巨大的提升。 – gouessej

相关问题