OpenGL Screen Capture

BlitzMax Forums/OpenGL Module/OpenGL Screen Capture

PGF(Posted 2005) [#1]
Has anybody made available a screen capture routine for OpenGL ?

Any help appreciated.


PGF(Posted 2005) [#2]
I'll answer my question with this attempt:
Function ScreenPrint()

	Local path:String = "C:\Temp\Test"
	Local fileName:String
	
	For Local serial = 0 To 9999
		fileName = path + Right("0000" + serial, 4) + ".PNG"
		
		If FileType(fileName) = 0
			Exit
		EndIf
	Next
	
	Local pm:TPixmap = CreatePixmap(G.ScreenWidth, G.ScreenHeight, PF_RGB888)
	
	glReadPixels(0, 0, G.ScreenWidth, G.ScreenHeight, GL_RGB, GL_UNSIGNED_BYTE, PixmapPixelPtr(pm))
	
	SavePixmapPNG(pm, fileName)
	
	FunctionMessage("ScreenPrint() to '" + fileName + "'")
		
End Function

G.ScreenWidth and G.ScreenHeight are just what you'd expect. FunctionMessage() is a message logger. Replace these with your equivalents.

It works with one small problem - The image is inverted !

I don't know if this is my misunderstanding or a bug in say SavePixmapPNG.

Any suggestions ?


Suco-X(Posted 2005) [#3]
	glReadPixels(0, 0, ScreenWidth, ScreenHeight, GL_RGB, GL_UNSIGNED_BYTE, PixmapPixelPtr(pm))
	pm = YFlipPixmap(pm)



PGF(Posted 2005) [#4]
That works. Ta.


ImaginaryHuman(Posted 2005) [#5]
You can now use:

Local PX:TPixmap=Grab Pixmap(0,0,640,480) 'whatever area you want to save
Print SavePixmapPNG(PX,"Screengrab.png",9) '0-9 compression value

I was delighted to find out that SavePixmapPNG is now a standard function as part of the PNG loader module. :-) No sign of SavePixmapJPG() or a generic SavePixmap() yet. ;-)


PGF(Posted 2005) [#6]
AngelDaniel - Perhaps you missed the all important bit of my request for something that works with OpenGL. GrabPixmap is a Max2D function.

Now if you know how to get the Max2D functions working with OpenGL then that would be wonderful.


Haramanai(Posted 2005) [#7]
Check out this topic.
http://www.blitzmax.com/Community/posts.php?topic=50419
SavePixMapJpg()? Intersting.


ImaginaryHuman(Posted 2005) [#8]
Oh, yeah, and I notice that SavePixmapPNG() was already mentioned in that code above, I missed it.

What you asked is how to save the backbuffer to an image file, so I presumed you didn't mind using a pixmap. Why wouldn't you want to use a pixmap if it's purpose is just to allow you to save an image?

Or are you thinking of some kind of custom-coded direct backbuffer-to-file image saver which bypasses any temporary storage altogether?

You have to have some kind of a buffer because the only way to get the backbuffer content is to use glReadPixels() which has to go into some area of main memory. You then can convert that to image data and write it to a file, but whether you have Max2D do that part for you or not is up to you how you want it to go.


PGF(Posted 2005) [#9]
AngelDaniel,

As you can see in the code, the solution that I came up with does use a TPixmap, glReadPixels and SavePixmapPNG. Its only problem was that the image was inverted which Suco-X solved by suggesting use of YFlipPixmap.

The result is a short and fast solution to the problem and I'm happy with that.

If you have a substantially different and perhaps better method then I'd be very appreciative if you post a working bit of code.

Failing that I don't see a lot of value from your posts. You seem to mis-read the question, point out things already in evidence and question why I want to do or not do things that were never raised by me.

Help and insight are appreciated but waffle is not.


ozak(Posted 2005) [#10]
IIRC the image is flipped because OpenGL image coords 0,0 is at the bottom-left of the image :)