Search code examples
javaswingopengljogl

Proper way to draw images in GLJpanel


I m using the GLJpanel component in my Java swing application, I want to draw images that are Frames from FFmpegFrameGrabber in my GLJPanel, to do so my idea was to use the component graphics as mentioned below.

import org.bytedeco.javacv.Frame;
import com.jogamp.opengl.awt.GLJPanel;

public void showImage(GLJPanel panel, Frame frame) {
    Graphics2D graphics = (Graphics2D) panel.getGraphics();
    Java2DFrameConverter converter = new Java2DFrameConverter();
    BufferedImage bfimage = converter.convert(frame);
    graphics.drawImage(bfimage, null, 0,0);
}

Is this the proper way to draw images in GL enabled Components or there is another way, I have doubt that I m wrong but I can't prove it

My GLJPanel was created as below

final GLProfile profile = GLProfile.get(GLProfile.GL2);
        GLCapabilities capabilities = new GLCapabilities(profile);

        GLJPanel panel = new GLJPanel(capabilities);

Solution

  • All I had to do is to create a GLEventListener, this interface have 4 methods display, displayChanged, init and dispose then the common parameter GLAutoDrawable which is responsible for drawing

    in case of drawing images BufferedImage I believe that the first step is to convert any image input to BufferedImage in my case I enclosed this behaviour in a utility class and fed a queue with my converted images.

    to draw you have to use a Texture this one can be created using a TextureData which will use the buffered image as follow

    TextureData textureData = AWTTextureIO.newTextureData(gl.getGLProfile(), baseImage, false);
    Texture texture = TextureIO.newTexture(textureData);
    

    So finally my display should be like

    public synchronized void display(GLAutoDrawable drawable) {
    
        BufferedImage baseImage = frames.poll();        
        if(baseImage == null)return;
    
        final GL2 gl = drawable.getGL().getGL2(); 
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
    
    
         // Create a TextureData and Texture from it
        TextureData textureData = AWTTextureIO.newTextureData(gl.getGLProfile(), baseImage, false);
        Texture texture = TextureIO.newTexture(textureData);
        // Now draw one quad with the texture
        texture.enable(gl);
        texture.bind(gl);
        gl.glTexEnvi(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE);
        TextureCoords coords = texture.getImageTexCoords();
        gl.glBegin(GL2.GL_QUADS);
        gl.glTexCoord2f(coords.left(), coords.bottom());
        gl.glVertex3f(0, 0, 0);
        gl.glTexCoord2f(coords.right(), coords.bottom());
        gl.glVertex3f(1, 0, 0);
        gl.glTexCoord2f(coords.right(), coords.top());
        gl.glVertex3f(1, 1, 0);
        gl.glTexCoord2f(coords.left(), coords.top());
        gl.glVertex3f(0, 1, 0);
        gl.glEnd();
        texture.disable(gl);
    
    
        texture.destroy(gl);
        //baseImage = null;
    }