cwei
Senior Newbie 
Let the robots do.
|
 |
«
Posted
2005-05-06 15:13:33 » |
|
Hello together, here is an example to make screenshots from OpenGL context very quickly. The file is written in uncompressed TARGA (*.tga) format. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public static final int TARGA_HEADER_SIZE = 18;
void screenshot(GL gl, int width, int, height, File file) { try { RandomAccessFile out = new RandomAccessFile(file, "rw"); FileChannel ch = out.getChannel(); int fileLength = TARGA_HEADER_SIZE + width * height * 3; out.setLength(fileLength); MappedByteBuffer image = ch.map(FileChannel.MapMode.READ_WRITE, 0, fileLength);
image.put(0, (byte) 0).put(1, (byte) 0); image.put(2, (byte) 2); image.put(12, (byte) (width & 0xFF)); image.put(13, (byte) (width >> 8)); image.put(14, (byte) (height & 0xFF)); height image.put(15, (byte) (height >> 8)); height image.put(16, (byte) 24); image.position(TARGA_HEADER_SIZE); ByteBuffer bgr = image.slice(); gl.glReadPixels(0, 0, width, height, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, bgr);
ch.close(); } catch (Exception e) { e.printStackTrace(); } } |
I think it is useful. bye Carsten
|
|
|
|
|
Ken Russell
|
 |
«
Reply #1 - Posted
2005-05-06 15:30:32 » |
|
Thanks for the code. I've added it to JOGL Issue 131. We need to add a bunch of utility classes to JOGL to make it more useful.
|
|
|
|
|
ozak
Junior Member  
Java demon has no respect for bad code!!!
|
 |
«
Reply #2 - Posted
2005-05-08 08:53:14 » |
|
Why not use ImageIO instead? That way you can save to all supported formats from the bytebuffer. Or perhaps even print it too 
|
Want to do multiplayer? Why not try my free Socky socket server? It's scriptable through JavaScript! Check it out at http://www.furi.dk/socky
|
|
|
Games published by our own members! Check 'em out!
|
|
cwei
Senior Newbie 
Let the robots do.
|
 |
«
Reply #3 - Posted
2005-05-08 11:52:37 » |
|
Why not use ImageIO instead? That way you can save to all supported formats from the bytebuffer. Or perhaps even print it too  The ImageIO class is ok, but much slower. I've used this function to make screenshots on the fly in Jake2. I've tested ImageIO too and the Quake2 game loop hangs a little bit on saving an image. The trick in this example is to bypass the CPU for image writing. This function copies the graphics memory (AGP) to a memory mapped file. I think only the DMA contoller has a lot to do :-) An other fact is, that you don't need extra memory allocation like int[]. There is no extra runtime (dynamic) garbage. And the MappedByteBuffer will be collected by GC after closing the file channel. try it and you will see what I mean. bye Carsten
|
|
|
|
|
ryanm
« League of Dukes » Senior Member    Projects: 1
Used to be bleb
|
 |
«
Reply #4 - Posted
2005-05-11 12:31:39 » |
|
First of all, thanks for the amazing code snippet. Using ImageIO, i was getting pauses ~1 second for each snapshot, with this method there is no appreciable delay  Unfortunately, there seems to be a problem with the resultant images. What should look something like  comes out like  I'm calling it with 1
| screenshot( canvas.getGL(), canvas.getWidth(), canvas.getHeight(), imageFile ); |
where canvas is my GLCanvas. Where am i going wrong?
|
|
|
|
|
keving
Senior Newbie 
Java games rock!
|
 |
«
Reply #5 - Posted
2005-05-11 18:01:29 » |
|
Hi,
To fix this, either make sure your image width will always be a multiple of 4, or add the line
gl.glPixelStorei(GL.GL_PACK_ALIGNMENT, 1);
before your call to gl.glReadPixels()
Thanks for the tip on using file channels! I have just finished implementing code to capture directly to an AVI file (with sound). Anyone interested?
Kevin
|
|
|
|
|
ryanm
« League of Dukes » Senior Member    Projects: 1
Used to be bleb
|
 |
«
Reply #6 - Posted
2005-05-11 19:35:36 » |
|
Awesome, that's got it. 
|
|
|
|
|
cwei
Senior Newbie 
Let the robots do.
|
 |
«
Reply #7 - Posted
2005-05-11 20:52:46 » |
|
Thanks you for the test and for the hint with pixel alignment. I had forgotten this issue.
Keving, I'm interested in your AVI tool.
bye Carsten
|
|
|
|
|
ryanm
« League of Dukes » Senior Member    Projects: 1
Used to be bleb
|
 |
«
Reply #8 - Posted
2005-05-11 22:46:46 » |
|
I too am interested in encoding directly to a video file. Currently i'm using this screenshot code to capture a whole crapload of frames, which i then encode with other tools. Skipping this step and encoding directly would be ideal.
Incidentally -as I understand it- avi is a container for various video and audio formats. What video format would be used?
|
|
|
|
|
Vorax
Senior Member    Projects: 1
System shutting down in 5..4..3...
|
 |
«
Reply #9 - Posted
2005-05-12 01:27:47 » |
|
Me too please 
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Louis
Senior Newbie 
Dis-member
|
 |
«
Reply #10 - Posted
2005-05-18 12:56:24 » |
|
I noticed you do not specify which color buffer the glreadpixels should capture the pix info from. On prompting of a screengrab I usually render the final pass of my app into an Auxilary Buffer and then dump the color information from the Aux buffer to file. That way your app doesn't not have to be showing on the screen for the screendump to be successful.
|
|
|
|
|
jensall
Senior Newbie 
|
 |
«
Reply #11 - Posted
2006-04-28 11:20:55 » |
|
I suppose, the code resulted in the Screenshot Class of JSR-231. How about adding something like the AVI tool, too? I have just finished implementing code to capture directly to an AVI file (with sound). Anyone interested?
Could you send me the code for the AVI capturing, please? Jens
|
|
|
|
|
emzic
|
 |
«
Reply #12 - Posted
2006-05-02 10:03:41 » |
|
how do you get the GLCanvas outside one of the jogl functions (init,display,reshape) ?
|
|
|
|
Ken Russell
|
 |
«
Reply #13 - Posted
2006-05-02 18:17:33 » |
|
You shouldn't really need to. The work you need to do to capture the screen contents should typically be called from within your GLEventListener.display() method.
|
|
|
|
|
invictus
Senior Newbie 
|
 |
«
Reply #14 - Posted
2006-05-03 13:20:32 » |
|
I have just finished implementing code to capture directly to an AVI file (with sound). Anyone interested?
Kevin
I am 
|
|
|
|
|
|