Off-screen rendering with Qt/Jambi & JOGL
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:
- Create a QGLWidget with the scene you want to draw;
- 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
- 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 - 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! ;-)