Jeff Storey
Jeff Storey

Reputation: 57162

Java OpenGL draw offscreen buffer to image

I'm trying to write a java opengl (JOGL) method that writes to an offscreen drawable and then writes that to an image. I have verified this works when using an onscreen drawable as well as GLP buffers, but the output image in its current state is just solid black. The code is below.

GLProfile glp = GLProfile.getDefault();
GLCapabilities caps = new GLCapabilities(glp);
caps.setOnscreen(false);

// create the offscreen drawable
GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
GLOffscreenAutoDrawable drawable = factory.createOffscreenAutoDrawable(null,caps,null,width,height);
drawable.display();
drawable.getContext().makeCurrent();

// a series of x/y coordinates
FloatBuffer buffer = generateData();

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

// use pixel coordinates
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity();    
gl.glOrtho(0d, width, height, 0d, -1d, 1d);

// draw some points to the drawable
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);

BufferedImage im = new AWTGLReadBufferUtil(drawable.getGLProfile(), false).readPixelsToBufferedImage(drawable.getGL(), 0, 0, width, height, true /* awtOrientation */);
ImageIO.write(im,"png",new File("im.png"));

Upvotes: 1

Views: 2025

Answers (2)

Chinnaswamy Gounder
Chinnaswamy Gounder

Reputation: 11

Most likely you might have found the required answer for your query.
If not, I suggest to add a line, for example:

gl.glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 

I have tested it, and it works.

Upvotes: 0

Zoodinger
Zoodinger

Reputation: 152

This is a bit old, but I found a solution to the problem that seems to work for me. I just added an ordinary GLEventListener object right before calling .display() on the drawable, as such:

//...
drawable.addGLEventListener(new OffscreenJOGL());
drawable.display();

//Move drawing code to OffscreenJOGL

BufferedImage im = new AWTGLReadBufferUtil(drawable.getGLProfile(), false).readPixelsToBufferedImage(drawable.getGL(), 0, 0, width, height, true /* awtOrientation */);
ImageIO.write(im,"png",new File("im.png"));

The code to draw now should be in your custom OffscreenJOGL class, under the init(...), reshape(...) and display(...) methods. Note that setting the current context must be in the init(...) method of OffscreenJOGL. I get an exception thrown otherwise.

class OffscreenJOGL implements GLEventListener {
    public void init(GLAutoDrawable drawable) {
        drawable.getContext().makeCurrent();
        //Other init code here
    }

    public void display(GLAutodrawable drawable) {
        //Code for drawing here
    }

    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        //Called at least once after init(...) and before display(...)
    }

    public void dispose(GLAutoDrawable drawable) {
        //Dispose code here
    }
}

Upvotes: 1

Related Questions