The same stupid triangle example: that's all you need! ;-)

Have you ever wondered how to make images at runtime (given that you know OpenGL)? Here's a solution (and a the same, stupid triangle example) using Java and Qt!

The trick is simple:

  1. Create a QGLWidget with the scene you want to draw;
  2. once you made your pixel perfect rendering - you can test it by running the app showing the new widget - render it to a pixel buffer
  3. Qt provides a nice way to save content from a GLWidget:
    QPixmap pixmap = glWidget.renderToPixmap() renders the scene and copies it in RAM to a QPixmap
  4. now you can do what you want with the newly created image, for example, save it to a file:
    pixmap.toImage().save(filename, format) where format is a java String representing the format (e.g.: "PNG", "JPEG", "BMP" etc)

Now: "Give me the code, Luke!"

import javax.media.opengl.GL;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;

import com.trolltech.qt.gui.QApplication;
import com.trolltech.qt.gui.QPushButton;
import com.trolltech.qt.opengl.QGLWidget;

public class GLWidget extends QGLWidget {

    class RenderButton extends QPushButton {
	public RenderButton() {
	    super("Render!");
	    resize(300, 100);
	    show();
	    clicked.connect(this, "render()");
	}

	public void render() {
	    renderPixmap().toImage().save("triangle.png", "PNG");
	}
    }

    public static void main(String[] args) {
	QApplication.initialize(args);
	GLWidget w = new GLWidget();
	QApplication.exec();
    }

    GL gl;
    GLContext ctx;
    RenderButton b;

    public GLWidget() {
	b = new RenderButton();
    }

    @Override
    protected void initializeGL() {
	GLDrawableFactory factory = GLDrawableFactory.getFactory();
	ctx = factory.createExternalGLContext();
	gl = ctx.getGL();
    }

    @Override
    protected void resizeGL(int w, int h) {
	gl.glViewport(0, 0, w, h);
	gl.glMatrixMode(GL.GL_PROJECTION);
	float r = 3.0f / 2.0f;
	gl.glLoadIdentity();
	gl.glFrustum(-0.2, 1 * r, -0.2, 1.2, 1, 2000);
    }

    @Override
    protected void paintGL() {
	gl.glMatrixMode(GL.GL_MODELVIEW);
	gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
	gl.glLoadIdentity();

	gl.glBegin(GL.GL_TRIANGLES);
	{
	    gl.glColor3f(1, 0, 0);
	    gl.glVertex3f(0, 0, -1);
	    gl.glColor3f(0, 1, 0);
	    gl.glVertex3f(0, 1, -1);
	    gl.glColor3f(0, 0, 1);
	    gl.glVertex3f(1, 0, -1);
	}
	gl.glEnd();
    }
}

Copy this to a new file (named GLWidget.java) in a new project in your complete Eclipse installation (have you set up in advance Qt/Jambi, it's Eclipse Integration & JOGL? :D) and the trick is done!

That's all, folks! ;-)