diff options
author | Carsten Weisse <[email protected]> | 2005-04-25 09:23:14 +0000 |
---|---|---|
committer | Carsten Weisse <[email protected]> | 2005-04-25 09:23:14 +0000 |
commit | 7e6cd3a615ab0743fbe01798c438a766dc8610b4 (patch) | |
tree | 15b7d8b5dc9dff3417ec6dbb8a920b49a58245de /src/jake2/render | |
parent | f5bac8b0a570ba6fad3a1847399caa32df669a58 (diff) |
screenshot function for (fast)jogl drivers.
Needs a callback mechanism and a sliced buffer.
Diffstat (limited to 'src/jake2/render')
-rw-r--r-- | src/jake2/render/fastjogl/Misc.java | 146 | ||||
-rw-r--r-- | src/jake2/render/jogl/Misc.java | 150 |
2 files changed, 165 insertions, 131 deletions
diff --git a/src/jake2/render/fastjogl/Misc.java b/src/jake2/render/fastjogl/Misc.java index 68e4ea4..5b0e146 100644 --- a/src/jake2/render/fastjogl/Misc.java +++ b/src/jake2/render/fastjogl/Misc.java @@ -2,7 +2,7 @@ * Misc.java * Copyright (C) 2003 * - * $Id: Misc.java,v 1.3 2004-09-22 19:22:10 salomo Exp $ + * $Id: Misc.java,v 1.4 2005-04-25 09:23:14 cawe Exp $ */ /* Copyright (C) 1997-2001 Id Software, Inc. @@ -25,8 +25,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package jake2.render.fastjogl; +import java.io.File; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +import org.lwjgl.opengl.GL11; + import jake2.Defines; import jake2.client.VID; +import jake2.qcommon.FS; +import jake2.qcommon.xcommand_t; import net.java.games.jogl.GL; import net.java.games.jogl.WGL; @@ -98,73 +108,81 @@ public abstract class Misc extends Mesh { // unsigned short x_origin, y_origin, width, height; // unsigned char pixel_size, attributes; // } TargaHeader; + + private final static int TGA_HEADER_SIZE = 18; - /* - ================== - GL_ScreenShot_f - ================== - */ + /** + * GL_ScreenShot_f + */ void GL_ScreenShot_f() { - // byte *buffer; - // char picname[80]; - // char checkname[MAX_OSPATH]; - // int i, c, temp; - // FILE *f; - // - // // create the scrnshots directory if it doesn't exist - // Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir()); - // Sys_Mkdir (checkname); - // - //// - //// find a file name to save it to - //// - // strcpy(picname,"quake00.tga"); - // - // for (i=0 ; i<=99 ; i++) - // { - // picname[5] = i/10 + '0'; - // picname[6] = i%10 + '0'; - // Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), picname); - // f = fopen (checkname, "r"); - // if (!f) - // break; // file doesn't exist - // fclose (f); - // } - // if (i==100) - // { - // VID.Printf (PRINT_ALL, "SCR_ScreenShot_f: Couldn't create a file\n"); - // return; - // } - // - // - // buffer = malloc(vid.width*vid.height*3 + 18); - // memset (buffer, 0, 18); - // buffer[2] = 2; // uncompressed type - // buffer[12] = vid.width&255; - // buffer[13] = vid.width>>8; - // buffer[14] = vid.height&255; - // buffer[15] = vid.height>>8; - // buffer[16] = 24; // pixel size - // - // qglReadPixels (0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); - // - // // swap rgb to bgr - // c = 18+vid.width*vid.height*3; - // for (i=18 ; i<c ; i+=3) - // { - // temp = buffer[i]; - // buffer[i] = buffer[i+2]; - // buffer[i+2] = temp; - // } - // - // f = fopen (checkname, "rw"); - // fwrite (buffer, 1, c, f); - // fclose (f); - // - // free (buffer); - // VID.Printf (PRINT_ALL, "Wrote %s\n", picname); + if (contextInUse) { + screenshot_f(); + } else { + updateScreen(screenshotCall); + } } + private xcommand_t screenshotCall = new xcommand_t() { + public void execute() { + screenshot_f(); + } + }; + + private void screenshot_f() { + FS.CreatePath(FS.Gamedir() + "/scrshot/jake00.tga"); + File file = new File(FS.Gamedir() + "/scrshot/jake00.tga"); + // find a valid file name + int i = 0; + while (file.exists() && i++ < 100) { + file = new File(FS.Gamedir() + "/scrshot/jake" + (i/10) + (i%10) + ".tga"); + } + if (i == 100) { + VID.Printf(Defines.PRINT_ALL, "Couldn't create a new screenshot file\n"); + return; + } + + try { + RandomAccessFile out = new RandomAccessFile(file, "rw"); + FileChannel ch = out.getChannel(); + int fileLength = TGA_HEADER_SIZE + vid.width * vid.height * 3; + out.setLength(fileLength); + MappedByteBuffer image = ch.map(FileChannel.MapMode.READ_WRITE, 0, + fileLength); + + // write the TGA header + image.put(0, (byte) 0).put(1, (byte) 0); + image.put(2, (byte) 2); // uncompressed type + image.put(12, (byte) (vid.width & 0xFF)); // vid.width + image.put(13, (byte) (vid.width >> 8)); // vid.width + image.put(14, (byte) (vid.height & 0xFF)); // vid.height + image.put(15, (byte) (vid.height >> 8)); // vid.height + image.put(16, (byte) 24); // pixel size + + // go to image data position + image.position(TGA_HEADER_SIZE); + // jogl needs a sliced buffer + ByteBuffer rgb = image.slice(); + // read the RGB values into the image buffer + gl.glReadPixels(0, 0, vid.width, vid.height, GL11.GL_RGB, + GL11.GL_UNSIGNED_BYTE, rgb); + + // flip RGB to BGR + byte tmp; + for (i = TGA_HEADER_SIZE; i < fileLength; i += 3) { + tmp = image.get(i); + image.put(i, image.get(i + 2)); + image.put(i + 2, tmp); + } + // close the file channel + ch.close(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + VID.Printf(Defines.PRINT_ALL, "Wrote " + file + '\n'); + } + /* ** GL_Strings_f */ diff --git a/src/jake2/render/jogl/Misc.java b/src/jake2/render/jogl/Misc.java index 256e0cf..e161d9d 100644 --- a/src/jake2/render/jogl/Misc.java +++ b/src/jake2/render/jogl/Misc.java @@ -2,7 +2,7 @@ * Misc.java * Copyright (C) 2003 * - * $Id: Misc.java,v 1.3 2004-07-16 10:11:35 cawe Exp $ + * $Id: Misc.java,v 1.4 2005-04-25 09:23:13 cawe Exp $ */ /* Copyright (C) 1997-2001 Id Software, Inc. @@ -25,8 +25,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package jake2.render.jogl; +import java.io.File; +import java.io.RandomAccessFile; +import java.nio.ByteBuffer; +import java.nio.MappedByteBuffer; +import java.nio.channels.FileChannel; + +import org.lwjgl.opengl.GL11; + import jake2.Defines; import jake2.client.VID; +import jake2.qcommon.FS; +import jake2.qcommon.xcommand_t; import net.java.games.jogl.GL; import net.java.games.jogl.WGL; @@ -111,73 +121,79 @@ public abstract class Misc extends Mesh { // unsigned char pixel_size, attributes; // } TargaHeader; + private final static int TGA_HEADER_SIZE = 18; - /* - ================== - GL_ScreenShot_f - ================== - */ - void GL_ScreenShot_f() - { -// byte *buffer; -// char picname[80]; -// char checkname[MAX_OSPATH]; -// int i, c, temp; -// FILE *f; -// -// // create the scrnshots directory if it doesn't exist -// Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir()); -// Sys_Mkdir (checkname); -// -//// -//// find a file name to save it to -//// -// strcpy(picname,"quake00.tga"); -// -// for (i=0 ; i<=99 ; i++) -// { -// picname[5] = i/10 + '0'; -// picname[6] = i%10 + '0'; -// Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), picname); -// f = fopen (checkname, "r"); -// if (!f) -// break; // file doesn't exist -// fclose (f); -// } -// if (i==100) -// { -// VID.Printf (PRINT_ALL, "SCR_ScreenShot_f: Couldn't create a file\n"); -// return; -// } -// -// -// buffer = malloc(vid.width*vid.height*3 + 18); -// memset (buffer, 0, 18); -// buffer[2] = 2; // uncompressed type -// buffer[12] = vid.width&255; -// buffer[13] = vid.width>>8; -// buffer[14] = vid.height&255; -// buffer[15] = vid.height>>8; -// buffer[16] = 24; // pixel size -// -// qglReadPixels (0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); -// -// // swap rgb to bgr -// c = 18+vid.width*vid.height*3; -// for (i=18 ; i<c ; i+=3) -// { -// temp = buffer[i]; -// buffer[i] = buffer[i+2]; -// buffer[i+2] = temp; -// } -// -// f = fopen (checkname, "rw"); -// fwrite (buffer, 1, c, f); -// fclose (f); -// -// free (buffer); -// VID.Printf (PRINT_ALL, "Wrote %s\n", picname); - } + /** + * GL_ScreenShot_f + */ + void GL_ScreenShot_f() { + if (contextInUse) { + screenshot_f(); + } else { + updateScreen(screenshotCall); + } + } + + private xcommand_t screenshotCall = new xcommand_t() { + public void execute() { + screenshot_f(); + } + }; + + private void screenshot_f() { + FS.CreatePath(FS.Gamedir() + "/scrshot/jake00.tga"); + File file = new File(FS.Gamedir() + "/scrshot/jake00.tga"); + // find a valid file name + int i = 0; + while (file.exists() && i++ < 100) { + file = new File(FS.Gamedir() + "/scrshot/jake" + (i/10) + (i%10) + ".tga"); + } + if (i == 100) { + VID.Printf(Defines.PRINT_ALL, "Couldn't create a new screenshot file\n"); + return; + } + + try { + RandomAccessFile out = new RandomAccessFile(file, "rw"); + FileChannel ch = out.getChannel(); + int fileLength = TGA_HEADER_SIZE + vid.width * vid.height * 3; + out.setLength(fileLength); + MappedByteBuffer image = ch.map(FileChannel.MapMode.READ_WRITE, 0, + fileLength); + + // write the TGA header + image.put(0, (byte) 0).put(1, (byte) 0); + image.put(2, (byte) 2); // uncompressed type + image.put(12, (byte) (vid.width & 0xFF)); // vid.width + image.put(13, (byte) (vid.width >> 8)); // vid.width + image.put(14, (byte) (vid.height & 0xFF)); // vid.height + image.put(15, (byte) (vid.height >> 8)); // vid.height + image.put(16, (byte) 24); // pixel size + + // go to image data position + image.position(TGA_HEADER_SIZE); + // jogl needs a sliced buffer + ByteBuffer rgb = image.slice(); + // read the RGB values into the image buffer + gl.glReadPixels(0, 0, vid.width, vid.height, GL11.GL_RGB, + GL11.GL_UNSIGNED_BYTE, rgb); + + // flip RGB to BGR + byte tmp; + for (i = TGA_HEADER_SIZE; i < fileLength; i += 3) { + tmp = image.get(i); + image.put(i, image.get(i + 2)); + image.put(i + 2, tmp); + } + // close the file channel + ch.close(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + VID.Printf(Defines.PRINT_ALL, "Wrote " + file + '\n'); + } /* ** GL_Strings_f |