Дублирую мой ответ на ваш другой вопрос:
Как ни странно, именно так и должно быть.
За кулисами происходит то, что, когда GLCanvas, который вы создали, начинает рисоваться, за кулисами JOGL выполняет целую кучу работы. Он создает GLContext и делает его текущим для GLCanvas для текущего потока. Только когда это будет сделано, вы сможете делать рендеринг звонков. GLContext, который не был сделан текущим, или объект GL, являющийся его производным, бесполезен для вас.
Почти все приложения JOGL работают таким образом. Вы создаете GLEventListener и реализуете в нем display (), извлекаете GL из GLAutoDrawable и используете его для выполнения вызовов рендеринга. Вы не хотите делать рендеринг вызовов в любом другом месте, равно как и делать вызовы Graphics2D вне метода paint (). (Конечно, вы можете написать подметоды, которые вызываются из метода display () и которые принимают GL или GLAutoDrawable в качестве аргумента).
Есть способы для вас специально создать GLContext и сделать его текущим самостоятельно, но они редко необходимы. Здесь почти всегда лучше использовать подход.
Если вы используете низкоуровневые буферы, такие как BufferStrategy, лучше всего делать рендеринг JOGL в GLPBuffer, который является зарисовкой JOGL вне экрана. Создайте GLPBuffer, выполните рендеринг к нему, а затем скопируйте рендеринг растрового изображения в ваш буфер. Некоторые реализации GLDrawable допускают явное создание закадровых элементов рисования с помощью «createOffscreenDrawable (...). Эта статья даст вам несколько указателей.
Вы также можете явно вызывать GLDrawable.display (), если вы находитесь в потоке рендеринга.
Если вы хотите выполнить инициализацию, такую как создание списка отображения, вы можете использовать метод GLDrawable.init (...), который вызывается перед первым вызовом display (...), хотя он может быть вызванным более одного раза.