2005/02/02

Rendering GL content to grids and printers

I'd like to render 3D graphics into the cells of a wxGrid, and am considering using an offscreen wxGLCanvas to prepare the contents of each cell as requested. This seems like a common approach; for example, NSTableViews in Cocoa use a single NSCell to paint the contents of each column.

How to render the contents of the wxGLCanvas into each grid cell? The easiest way seems to be to set the size of the canvas to match the size of the current cell, render the scene, copy the content into a wxBitmap, and draw the Bitmap into the cell rect.

Others have shown how to copy wxGLCanvas content into a wxBitmap, e.g. in order to print the contents of a canvas. But the sample code I've found has omitted a key step: a call to glPixelStorei to ensure proper packing of the data provided by glReadPixels.

Anyway, here's what works for me. This code assumes the GLCanvas size has been set and the scene already rendered:


def _getBitmap(self):
c = self.canvas
x, y, w, h = glGetIntegerv(GL_VIEWPORT)

glPixelStorei(GL_PACK_ALIGNMENT, 1)
pixels = glReadPixels(x, y, w, h, GL_RGB, GL_UNSIGNED_BYTE)
img = wx.EmptyImage(w, h)
img.SetData(pixels)
img = img.Mirror(False)
self.bm = wx.BitmapFromImage(img)