Render offscreen buffer to image

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Render offscreen buffer to image

jeffastorey
I'm trying to render an image to an offscreen buffer and then render that to a BufferedImage. I have it mostly working, but I'm running into 2 issues:

1. The background of my image is black, not transparent like I would expect it to be.
2. I tried using the offscreen autodrawable to do this, rather than the deprecated GLPBuffer. When I use the offscreen autodrawable, nothing seems to render at all.

I have posted a full working example below illustrating both of those problems with TODOs indicating the two issues. Any help would be greatly appreciated.

// FULL WORKING CODE EXAMPLE BELOW

import com.jogamp.opengl.util.awt.AWTGLReadBufferUtil;

import javax.imageio.ImageIO;
import javax.media.opengl.*;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class RenderExample {
    static int width = 500;
    static int height = 500;
    static int numPoints = 100;
    static Random r = new Random();

    public static void main(String[] args) throws Exception {

        GLProfile glp = GLProfile.getDefault();
        GLCapabilities caps = new GLCapabilities(glp);
        caps.setHardwareAccelerated(true);
        caps.setOnscreen(false);
        GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);

        // TODO: IF I USE OFFSCREEN DRAWABLE, THIS DOESN'T DRAW ANYTHING
        // GLOffscreenAutoDrawable drawable = factory.createOffscreenAutoDrawable(null,caps,null,width,height);

        GLAutoDrawable drawable = factory.createGLPbuffer(factory.getDefaultDevice(), factory.getAvailableCapabilities(factory.getDefaultDevice()).get(0), new DefaultGLCapabilitiesChooser(), width, height, null);
        drawable.display();
        drawable.getContext().makeCurrent();
        new RenderExample().render(drawable);

    }

    private void render(GLAutoDrawable drawable) throws Exception {

        List<Float> data = new ArrayList<Float>(numPoints * 2);

        // simulate some data here
        for (int i = 0; i < numPoints; i++) {
            float x = r.nextInt(width);
            float y = r.nextInt(height);
            data.add(x);
            data.add(y);
        }

        // x and y for each point, 4 bytes for each
        FloatBuffer buffer = ByteBuffer.allocateDirect(numPoints * 2 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        for (Float d : data) {
            buffer.put(d);
        }
        buffer.rewind();

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

        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glViewport(0, 0, width, height);

        // use pixel coordinates
        gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
        gl.glLoadIdentity();

        gl.glOrtho(0d, width, height, 0d, -1d, 1d);
        gl.glPointSize(4f);
        gl.glColor3f(1f, 0f, 0f);

        gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glVertexPointer(2, GL2.GL_FLOAT, 0, buffer);
        gl.glDrawArrays(GL2.GL_POINTS, 0, numPoints);
        gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);

        // TODO: THIS IMAGE HAS A BLACK BACKGROUND, NOT TRANSPARENT
        BufferedImage im = new AWTGLReadBufferUtil(drawable.getGLProfile(), true).readPixelsToBufferedImage(drawable.getGL(), 0, 0, width, height, true);

        ImageIO.write(im, "png", new File("im.png"));
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: Render offscreen buffer to image

gouessej
Administrator
Hi again

Please look at that:
https://jogamp.org/bugzilla/show_bug.cgi?id=709#c5
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Render offscreen buffer to image

jeffastorey
I'm not entirely sure how this relates...


On Thu, Apr 10, 2014 at 1:53 PM, gouessej [via jogamp] <[hidden email]> wrote:
Hi again

Please look at that:
https://jogamp.org/bugzilla/show_bug.cgi?id=709#c5


If you reply to this email, your message will be added to the discussion below:
http://forum.jogamp.org/Render-offscreen-buffer-to-image-tp4032144p4032152.html
To unsubscribe from Render offscreen buffer to image, click here.
NAML

Reply | Threaded
Open this post in threaded view
|

Re: Render offscreen buffer to image

jeffastorey
i was passing a new capabilities instead of the one I created. When I added an alpha channel to my capabilities and passed that instead, then this works.
Reply | Threaded
Open this post in threaded view
|

Re: Render offscreen buffer to image

gouessej
Administrator
Please can you post your working example in order to clarify what you did to fix it very concretely?
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Render offscreen buffer to image

jeffastorey
This is the updated code that fixed the issue. The fix was in the creation of the capabilities to support the alpha bits.

import com.jogamp.opengl.util.awt.AWTGLReadBufferUtil;

import javax.imageio.ImageIO;
import javax.media.opengl.*;
import javax.media.opengl.fixedfunc.GLMatrixFunc;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class RenderExample {
    static int width = 500;
    static int height = 500;
    static int numPoints = 100;
    static Random r = new Random();

    public static void main(String[] args) throws Exception {
        GLProfile glp = GLProfile.getDefault();
        GLCapabilities caps = new GLCapabilities(glp);
        caps.setHardwareAccelerated(true);
        caps.setDoubleBuffered(false);
        caps.setAlphaBits(8);
        caps.setRedBits(8);
        caps.setBlueBits(8);
        caps.setGreenBits(8);
        caps.setOnscreen(false);
        GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);

        GLAutoDrawable drawable = factory.createGLPbuffer(factory.getDefaultDevice(), caps, new DefaultGLCapabilitiesChooser(), width, height, null);
        drawable.display();
        drawable.getContext().makeCurrent();
        new RenderExample().render(drawable);

    }

    private void render(GLAutoDrawable drawable) throws Exception {

        List<Float> data = new ArrayList<Float>(numPoints * 2);

        // simulate some data here
        for (int i = 0; i < numPoints; i++) {
            float x = r.nextInt(width);
            float y = r.nextInt(height);
            data.add(x);
            data.add(y);
        }

        // x and y for each point, 4 bytes for each
        FloatBuffer buffer = ByteBuffer.allocateDirect(numPoints * 2 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        for (Float d : data) {
            buffer.put(d);
        }
        buffer.rewind();

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

        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glViewport(0, 0, width, height);

        // use pixel coordinates
        gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
        gl.glLoadIdentity();

        gl.glOrtho(0d, width, height, 0d, -1d, 1d);
        gl.glPointSize(4f);
        gl.glColor3f(1f, 0f, 0f);

        gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glVertexPointer(2, GL2.GL_FLOAT, 0, buffer);
        gl.glDrawArrays(GL2.GL_POINTS, 0, numPoints);
        gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);

        BufferedImage im = new AWTGLReadBufferUtil(drawable.getGLProfile(), true).readPixelsToBufferedImage(drawable.getGL(), 0, 0, width, height, true);

        ImageIO.write(im, "png", new File("im.png"));
    }
}
Reply | Threaded
Open this post in threaded view
|

Re: Render offscreen buffer to image

gouessej
Administrator
Thank you very much :)
Julien Gouesse | Personal blog | Website