Re: [PyOpenGL-Users] extremely large screen capture]
Brought to you by:
mcfletch
From: Rich D. <dr...@in...> - 2005-05-02 22:55:50
|
On Thu, 17 Mar 2005, stephan) wrote: > Hi Rich, > As I understand it there are generally 3 approaches to this: > []mesa off screen rendering > []glReadPixels > []pbuffers > > glReadPixels seems to be the simplest and has the advantage of being > hardware accelarated but is also restricted to whatever max resolution > the opengl implemntation supports. This calls for tiled rendering as it > is described here: > http://www.mesa3d.org/brianp/TR.html > > I did not have time yet to translate this code to python...should be > fairly easy though. It comes down to calling glViewport for each tile > and then patching the parts together with PIL. > > If you go for the challenge (on a rainy sunday afternoon with a > delicious cup of darjeeling maybe) please be so kind and post the code > on this list. After considerable experimentation, I did finally get up to 4096x4096 screen dumps with ReadPixels() to work, though I'm not quite sure about some aspects of it--perhaps you could help me understand why this works. Code fragment is at the end of the message. What has me confused is why the viewport is constructed 'left' (negative) of the origin. This is what the example program showed at the URL in the comment in the code above (though that code seemed to have some other bugs which I can't recall at the moment), and building the viewports negative was the only way I could get things to work. Any ideas on why things work that way? For a Linux Journal article that was just published, I generated an image of a neural network model using PyOpenGL and some of the above code, of about 2K pixels by 3K pixels that I hoped would take up the entire cover of the magazine (with text overlaid) . . . however they ended up shrinking my image to about 1 inch by 2 inches for the cover of the June issue and placed it next to a picture of a computer sitting on top of a penguin :/ You can see the image (if you squint) at http://www.linuxjournal.com. Rich http://www.interstice.com/drewes -- code follows -- -- download brainlab.tgz from homepage and look at netplot.py for full code -- vw=self.w*self.nvpx; vh=self.h*self.nvpy # cycle through each viewport and take a snapshot bigimage=Image.new('RGB', (vw, vh)) px=0 cx=0 # I don't understand why the viewport coordinates are specified all negative of 0, per example # at http://astronomy.swin.edu.au/~pbourke/opengl/windowdump/ for vpx in range(0, self.nvpx): cy=-(self.nvpy-1)*self.h py=0 for vpy in range(0, self.nvpy): print "vpx, vpy", vpx, vpy, "cx, cy", cx, cy glMatrixMode(GL_PROJECTION) glLoadIdentity() glViewport(cx, cy, vw, vh) gluPerspective(120.0, float(self.w)/float(self.h), self.near, self.far) glMatrixMode(GL_MODELVIEW) # we actually have to force a redraw *now* so we can't just post a redisplay self.on_display() # now save this viewport data = glReadPixels(0, 0, self.w, self.h, GL_RGB, GL_UNSIGNED_BYTE) image = Image.fromstring("RGB", (self.w, self.h), data) image = image.transpose(Image.FLIP_TOP_BOTTOM) oo=(px, py) print "pasting viewport section to", oo bigimage.paste(image, oo) py+=self.h cy+=self.h cx-=self.w px+=self.w # restore default viewport glMatrixMode(GL_PROJECTION) glLoadIdentity() sx,sy=self.ScreenCenter() glViewport(sx, sy, w*self.nvpx, h*self.nvpy) gluPerspective(120.0, float(self.w)/float(self.h), self.near, self.far) glMatrixMode(GL_MODELVIEW) glutPostRedisplay() bigimage.save('snap.png', 'PNG') |