Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (512)
Games in Android Showcase (119)
games submitted by our members
Games in WIP (576)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  a fast screenshot function  (Read 4674 times)
0 Members and 1 Guest are viewing this topic.
Offline cwei

Senior Newbie




Let the robots do.


« Posted 2005-05-06 13: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);

    // write the TARGA header
   image.put(0, (byte) 0).put(1, (byte) 0);
   image.put(2, (byte) 2); // uncompressed type
   image.put(12, (byte) (width & 0xFF)); // width
   image.put(13, (byte) (width >> 8)); // width
   image.put(14, (byte) (height & 0xFF)); height
   image.put(15, (byte) (height >> 8)); height
   image.put(16, (byte) 24); // pixel size
             
   // go to image data position
   image.position(TARGA_HEADER_SIZE);
   // jogl needs a sliced buffer
   ByteBuffer bgr = image.slice();
   // read the BGR values into the image buffer
   gl.glReadPixels(0, 0, width, height, GL.GL_BGR,
                      GL.GL_UNSIGNED_BYTE, bgr);

   // close the file channel
   ch.close();
  } catch (Exception e) {
     e.printStackTrace();
  }
}


I think it is useful.

bye
Carsten
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #1 - Posted 2005-05-06 13: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.
Offline ozak

Junior Duke




Java demon has no respect for bad code!!!


« Reply #2 - Posted 2005-05-08 06: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 Smiley

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!
Legends of Yore - The Casual Retro Roguelike
Offline cwei

Senior Newbie




Let the robots do.


« Reply #3 - Posted 2005-05-08 09:52:37 »

Quote
Why not use ImageIO instead? That way you can save to all supported formats from the bytebuffer. Or perhaps even print it too Smiley


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
Offline ryanm

Senior Duke


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #4 - Posted 2005-05-11 10: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 Cheesy

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?

Offline keving

Senior Newbie




Java games rock!


« Reply #5 - Posted 2005-05-11 16: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
Offline ryanm

Senior Duke


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #6 - Posted 2005-05-11 17:35:36 »

Awesome, that's got it. Grin
Offline cwei

Senior Newbie




Let the robots do.


« Reply #7 - Posted 2005-05-11 18: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
Offline ryanm

Senior Duke


Projects: 1
Exp: 15 years


Used to be bleb


« Reply #8 - Posted 2005-05-11 20: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?
Offline Vorax

Senior Duke


Projects: 1


System shutting down in 5..4..3...


« Reply #9 - Posted 2005-05-11 23:27:47 »

Me too please Smiley

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Louis

Senior Newbie




Dis-member


« Reply #10 - Posted 2005-05-18 10: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.
Offline jensall

Senior Newbie





« Reply #11 - Posted 2006-04-28 09: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
Offline emzic

Senior Duke





« Reply #12 - Posted 2006-05-02 08:03:41 »

how do you get the GLCanvas outside one of the jogl functions (init,display,reshape) ?

www.embege.com - personal website
webstart blendinspect - OpenGL BlendingModes visualization.
Offline Ken Russell

JGO Coder




Java games rock!


« Reply #13 - Posted 2006-05-02 16: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.
Offline invictus

Senior Newbie





« Reply #14 - Posted 2006-05-03 11:20:32 »

I have just finished implementing code to capture directly to an AVI file (with sound). Anyone interested?

Kevin

I am Smiley
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

Longarmx (49 views)
2014-10-17 03:59:02

Norakomi (39 views)
2014-10-16 15:22:06

Norakomi (31 views)
2014-10-16 15:20:20

lcass (35 views)
2014-10-15 16:18:58

TehJavaDev (65 views)
2014-10-14 00:39:48

TehJavaDev (65 views)
2014-10-14 00:35:47

TehJavaDev (55 views)
2014-10-14 00:32:37

BurntPizza (72 views)
2014-10-11 23:24:42

BurntPizza (43 views)
2014-10-11 23:10:45

BurntPizza (84 views)
2014-10-11 22:30:10
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!