Login  Register

Render offscreen buffer to image

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

Render offscreen buffer to image

jeffastorey
4 posts
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
| More
Print post
Permalink

Re: Render offscreen buffer to image

gouessej
Administrator
6044 posts
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
| More
Print post
Permalink

Re: Render offscreen buffer to image

jeffastorey
4 posts
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
| More
Print post
Permalink

Re: Render offscreen buffer to image

jeffastorey
4 posts
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
| More
Print post
Permalink

Re: Render offscreen buffer to image

gouessej
Administrator
6044 posts
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
| More
Print post
Permalink

Re: Render offscreen buffer to image

jeffastorey
4 posts
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
| More
Print post
Permalink

Re: Render offscreen buffer to image

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