Login  Register

Re: Blank Window - Porting Joe Groff's OpenGL Tutorial to JOGL

Posted by gouessej on Oct 06, 2010; 11:36am
URL: https://forum.jogamp.org/Blank-Window-Porting-Joe-Groff-s-OpenGL-Tutorial-to-JOGL-tp1623993p1641922.html

I get this when using your source code:

java.lang.Exception: Previously locked by Thread[main,5,main], lock: com.jogamp.nativewindow.impl.RecursiveToolkitLock@36baa466
        at com.jogamp.nativewindow.impl.RecursiveToolkitLock.lock(RecursiveToolkitLock.java:112)
        at com.jogamp.nativewindow.impl.jawt.JAWTWindow.lockSurface(JAWTWindow.java:109)
        at com.jogamp.opengl.impl.GLDrawableImpl.lockSurface(GLDrawableImpl.java:173)
        at com.jogamp.opengl.impl.GLDrawableImpl.setRealized(GLDrawableImpl.java:137)
        at javax.media.opengl.awt.GLCanvas.addNotify(GLCanvas.java:436)
        at java.awt.Container.addNotify(Container.java:2578)
        at java.awt.Window.addNotify(Window.java:663)
        at java.awt.Frame.addNotify(Frame.java:470)
        at java.awt.Window.show(Window.java:859)
        at java.awt.Component.show(Component.java:1563)
        at java.awt.Component.setVisible(Component.java:1515)
        at java.awt.Window.setVisible(Window.java:842)
        at org.maoni.jogl.test.JOGLTest.main(JOGLTest.java:29)
Exception in thread "Timer-0" javax.media.opengl.GLException: java.lang.RuntimeException: Waited 5000ms for: Thread[main,5,main] - Thread[AWT-EventQueue-0,6,main], with recursionCount 0, lock: com.jogamp.nativewindow.impl.RecursiveToolkitLock@36baa466
        at com.jogamp.opengl.impl.awt.AWTThreadingPlugin.invokeOnOpenGLThread(AWTThreadingPlugin.java:101)
        at com.jogamp.opengl.impl.ThreadingImpl.invokeOnOpenGLThread(ThreadingImpl.java:192)
        at javax.media.opengl.Threading.invokeOnOpenGLThread(Threading.java:164)
        at javax.media.opengl.awt.GLCanvas.maybeDoSingleThreadedWorkaround(GLCanvas.java:594)
        at javax.media.opengl.awt.GLCanvas.display(GLCanvas.java:302)
        at com.jogamp.opengl.util.AnimatorImpl.display(AnimatorImpl.java:51)
        at com.jogamp.opengl.util.AnimatorBase.display(AnimatorBase.java:98)
        at com.jogamp.opengl.util.FPSAnimator$1.run(FPSAnimator.java:114)
        at java.util.TimerThread.mainLoop(Timer.java:512)
        at java.util.TimerThread.run(Timer.java:462)
Caused by: java.lang.RuntimeException: Waited 5000ms for: Thread[main,5,main] - Thread[AWT-EventQueue-0,6,main], with recursionCount 0, lock: com.jogamp.nativewindow.impl.RecursiveToolkitLock@36baa466
        at com.jogamp.nativewindow.impl.RecursiveToolkitLock.lock(RecursiveToolkitLock.java:106)
        at com.jogamp.nativewindow.impl.jawt.JAWTWindow.lockSurface(JAWTWindow.java:109)
        at com.jogamp.opengl.impl.GLDrawableImpl.lockSurface(GLDrawableImpl.java:173)
        at com.jogamp.opengl.impl.GLContextImpl.makeCurrentLocking(GLContextImpl.java:352)
        at com.jogamp.opengl.impl.GLContextImpl.makeCurrent(GLContextImpl.java:314)
        at com.jogamp.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:276)
        at javax.media.opengl.awt.GLCanvas$DisplayOnEventDispatchThreadAction.run(GLCanvas.java:677)
        at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:199)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:597)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

It works a bit better by replacing JOGLTest by this:
package org.maoni.jogl.test;

import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import javax.swing.SwingUtilities;

import com.jogamp.opengl.util.Animator;

public class JOGLTest {

    public static void main(String args[]) {
        GLProfile.initSingleton();
        GLCapabilities caps = new GLCapabilities(null);
        System.out.println("Created JOGL context successfully.");
        final GLCanvas canvas = new GLCanvas(caps);

        final Frame frame = new Frame("AWT Window Test");
        frame.setSize(800, 600);
        // FIXME: not sure that your window listener will be called...
        frame.addWindowListener(new Closer());

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                canvas.addGLEventListener(new SimpleScene());
                frame.add(canvas);
                Animator animator = new Animator(canvas);
                animator.start();
            }
        });
        frame.setVisible(true);
    }

    static class Closer extends WindowAdapter {
        @Override
        public void windowClosing(WindowEvent event) {
            System.exit(0);
        }
    }
}

package org.maoni.jogl.test;



import java.io.File;

import java.io.IOException;

import java.nio.FloatBuffer;

import java.nio.IntBuffer;



import javax.media.opengl.GL;

import javax.media.opengl.GL2;

import javax.media.opengl.GL2ES2;

import javax.media.opengl.GLAutoDrawable;

import javax.media.opengl.GLEventListener;

import javax.media.opengl.GLException;



import com.jogamp.common.nio.Buffers;

import com.jogamp.opengl.util.glsl.ShaderCode;

import com.jogamp.opengl.util.glsl.ShaderProgram;

import com.jogamp.opengl.util.glsl.ShaderUtil;

import com.jogamp.opengl.util.texture.Texture;

import com.jogamp.opengl.util.texture.TextureIO;



public class SimpleScene implements GLEventListener {



    private final float[] vertexBufferData = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f };



    private final int[] element_buffer_data = { 0, 1, 2, 3 };



    private long startTime;



    private final GlResources gr = new GlResources();



    @Override

    public void display(GLAutoDrawable drawable) {

        update();

        render(drawable);

    }



    private void render(GLAutoDrawable drawable) {

        GL2 gl = drawable.getGL().getGL2();



        gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);

        gl.glClear(GL.GL_COLOR_BUFFER_BIT);



        gl.glUseProgram(gr.program);

        gl.glUniform1f(gr.uniforms.fade_factor, gr.fade_factor);



        gl.glActiveTexture(GL.GL_TEXTURE0);

        gl.glBindTexture(GL.GL_TEXTURE_2D, gr.textures[0]);

        gl.glUniform1i(gr.uniforms.textures[0], 0);



        gl.glActiveTexture(GL.GL_TEXTURE1);

        gl.glBindTexture(GL.GL_TEXTURE_2D, gr.textures[1]);

        gl.glUniform1i(gr.uniforms.textures[1], 1);



        gl.glBindBuffer(GL.GL_ARRAY_BUFFER, gr.vertex_buffer);

        gl.glVertexAttribPointer(gr.attributes.position, 2, GL.GL_FLOAT, false,

                Buffers.SIZEOF_FLOAT * 2, 0);



        gl.glEnableVertexAttribArray(gr.attributes.position);



        gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, gr.element_buffer);

        gl.glDrawElements(GL.GL_TRIANGLE_STRIP, 4, GL.GL_UNSIGNED_SHORT, 0);



        gl.glDisableVertexAttribArray(gr.attributes.position);

    }



    private void update() {

        gr.fade_factor = ((float) Math.sin(System.nanoTime() - this.startTime * 0.000001f)) * 0.5f + 0.5f;

        System.out.println(gr.fade_factor);

    }



    @Override

    public void dispose(GLAutoDrawable arg0) {

        // cleanup code



    }



    @Override

    public void init(GLAutoDrawable arg0) {

        this.startTime = System.nanoTime();

        System.out.println("Running GL Init code.");

        GL2 gl = arg0.getGL().getGL2();

        try {

            make_resources(gl);

        }

        catch (IOException e) {

            e.printStackTrace();

        }



    }



    @Override

    public void reshape(GLAutoDrawable gl, int x, int y, int width, int height) {



    }



    public int make_buffer(GL2 gl, int target, float[] bufferData, int buffer_size) {



        FloatBuffer fb = FloatBuffer.wrap(bufferData);

        fb.rewind();



        int buffer[] = new int[1];

        gl.glGenBuffers(1, buffer, 0);

        gl.glBindBuffer(target, buffer[0]);

        gl.glBufferData(target, buffer_size, fb, GL.GL_STATIC_DRAW);



        return buffer[0];

    }



    public int make_buffer(GL2 gl, int target, int[] bufferData, int buffer_size) {



        IntBuffer ib = IntBuffer.wrap(bufferData);

        ib.rewind();



        int buffer[] = new int[1];

        gl.glGenBuffers(1, buffer, 0);

        gl.glBindBuffer(target, buffer[0]);

        gl.glBufferData(target, buffer_size, ib, GL.GL_STATIC_DRAW);



        return buffer[0];

    }



    public int make_texture(final String filename) throws GLException, IOException {

        Texture t = TextureIO.newTexture(new File(filename), false);

        return t.getTextureObject();

    }



    public ShaderCode make_shader(final GL2 gl, int type, final String filename) throws IOException {

        ShaderCode sc = ShaderCode.create(gl, type, 1, getClass(), new String[] { filename });

        sc.compile(gl);

        if (!sc.isValid()) {

            throw new GLException("Shader " + filename + " is invalid");

        }

        return sc;

    }



    public int make_program(GL2 gl, final ShaderCode vertex_shader, final ShaderCode fragment_shader) {



        ShaderProgram sp = new ShaderProgram();

        sp.add(vertex_shader);

        sp.add(fragment_shader);

        sp.link(gl, null);

        if (!ShaderUtil.isProgramValid(gl, sp.program())) {

            throw new GLException("Shader program invalid, "

                    + ShaderUtil.getProgramInfoLog(gl, sp.program()));

        }

        return sp.id();

    }



    public int make_resources(GL2 gl) throws IOException {

        // Setup the buffers.

        gr.vertex_buffer = make_buffer(gl, GL.GL_ARRAY_BUFFER, vertexBufferData,

                vertexBufferData.length * Buffers.SIZEOF_FLOAT);



        gr.element_buffer = make_buffer(gl, GL.GL_ELEMENT_ARRAY_BUFFER, element_buffer_data,

                element_buffer_data.length * Buffers.SIZEOF_INT);



        // Setup the textures.

        gr.textures[0] = make_texture("resources/textures/hello1.tga");

        gr.textures[1] = make_texture("resources/textures/hello2.tga");



        // Make the shaders.

        gr.vertex_shader = make_shader(gl, GL2ES2.GL_VERTEX_SHADER,

                "resources/shaders/hello-gl.v.glsl");

        gr.fragment_shader = make_shader(gl, GL2ES2.GL_FRAGMENT_SHADER,

                "resources/shaders/hello-gl.f.glsl");

        gr.program = make_program(gl, gr.vertex_shader, gr.fragment_shader);



        // Setup the uniforms and attributes.

        gr.uniforms.fade_factor = gl.glGetUniformLocation(gr.program, "fade_factor");

        gr.uniforms.textures[0] = gl.glGetUniformLocation(gr.program, "textures[0]");

        gr.uniforms.textures[1] = gl.glGetUniformLocation(gr.program, "textures[1]");

        gr.attributes.position = gl.glGetAttribLocation(gr.program, "position");



        return 1;

    }



}


GL3 was not necessary. It is still white :(

Using this is a bad idea:
IntBuffer ib = IntBuffer.wrap(bufferData);
Rather create a really direct int buffer and fill it:
IntBuffer ib = Buffers.newDirectIntBuffer(bufferData);
Do the same for float buffers.

I rarely use shaders. I advise you to compare your example with examples provided with JOGL 2, several of them use shaders.
Julien Gouesse | Personal blog | Website