/******************************************************************************* * Copyright (c) 2015 * * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *******************************************************************************/ package jsettlers.graphics.debug; import go.graphics.GLDrawContext; import go.graphics.area.Area; import go.graphics.event.GOEvent; import go.graphics.event.GOKeyEvent; import go.graphics.region.Region; import go.graphics.region.RegionContent; import go.graphics.swing.AreaContainer; import go.graphics.text.EFontSize; import go.graphics.text.TextDrawer; import java.awt.Dimension; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFileChooser; import javax.swing.JFrame; import jsettlers.common.Color; import jsettlers.graphics.image.GuiImage; import jsettlers.graphics.image.Image; import jsettlers.graphics.image.LandscapeImage; import jsettlers.graphics.image.SettlerImage; import jsettlers.graphics.image.SingleImage; import jsettlers.graphics.reader.AdvancedDatFileReader; import jsettlers.graphics.reader.DatFileType; import jsettlers.graphics.reader.SequenceList; import jsettlers.graphics.sequence.Sequence; import jsettlers.graphics.swing.utils.ImageUtils; public class DatFileTester { private static final DatFileType TYPE = DatFileType.RGB555; private static final String FILE = "/home/michael/.jsettlers/GFX/siedler3_%" + TYPE.getFileSuffix(); private static final Color[] colors = new Color[] { Color.WHITE }; // private static final String FILE = // "D:/Games/Siedler3/GFX/siedler3_%.f8007e01f.dat"; private static int datFileIndex = 14; private AdvancedDatFileReader reader; private Region region; private DatFileTester() { reloadDatFile(); region = new Region(Region.POSITION_CENTER); region.setContent(new Content()); Area area = new Area(); area.add(region); AreaContainer glcanvas = new AreaContainer(area); JFrame frame = new JFrame("Opengl image test: " + datFileIndex); frame.getContentPane().add(glcanvas); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(new Dimension(400, 400)); frame.setVisible(true); } /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { new DatFileTester(); // // long intime = System.nanoTime(); // int images = 0; // // int y = offsetY; // int seqIndex = 0; // for (Sequence<SettlerImage> seq : reader.getSettlers()) { // int x = offsetX; // System.out.println("next sequence: " + seqIndex); // // for (SettlerImage image : seq) { // gl.glEnable(GL.GL_TEXTURE_2D); // gl.glColor3f(1, 1, 1); // image.drawAt(gl, x - image.getOffsetX(), // y + image.getHeight() + image.getOffsetY(), // colors[images % colors.length]); // // gl.glDisable(GL.GL_TEXTURE_2D); // gl.glColor3f(1, 0, 0); // gl.glBegin(GL.GL_LINE_STRIP); // gl.glVertex2i(x, y); // gl.glVertex2i(x, // y + image.getHeight() + image.getOffsetY()); // gl.glVertex2i(x - image.getOffsetX(), // y + image.getHeight() + image.getOffsetY()); // gl.glEnd(); // drawPoint(gl, x, y); // drawPoint(gl, x + image.getWidth(), y); // drawPoint(gl, x + image.getWidth(), // y + image.getHeight()); // drawPoint(gl, x, y + image.getHeight()); // // System.out.println("image sizes: " + image.getWidth() // + "x" + image.getHeight()); // // x += 100; // images++; // } // // gl.glColor3f(0, 0, 0); // gl.glRasterPos2i(20, y + 20); // glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, seqIndex // + ":"); // // seqIndex++; // y -= 200; // } // // y = offsetY; // int landImageIndex = 0; // for (Sequence<LandscapeImage> seq : reader.getLandscapes()) { // LandscapeImage image = seq.getImage(0); // gl.glEnable(GL.GL_TEXTURE_2D); // image.bind(gl); // gl.glColor3f(1, 1, 1); // gl.glBegin(GL2.GL_QUADS); // gl.glTexCoord2f(0, 0); // gl.glVertex2f(50, y); // gl.glTexCoord2f(0, 1); // gl.glVertex2f(50, y + 32); // gl.glTexCoord2f(1, 1); // gl.glVertex2f(82, y + 32); // gl.glTexCoord2f(1, 0); // gl.glVertex2f(82, y); // gl.glEnd(); // gl.glDisable(GL.GL_TEXTURE_2D); // // gl.glColor3f(0, 0, 0); // gl.glRasterPos2i(20, y + 20); // glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, // landImageIndex + ":"); // // if (image.isContinuous()) { // gl.glRasterPos2i(100, y + 20); // glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, "big"); // } // images++; // landImageIndex++; // y -= 40; // } // // y = offsetY; // int guiImageIndex = 0; // for (Sequence<GuiImage> seq : reader.getGuis()) { // GuiImage image = seq.getImage(0); // System.out.println("next gui image: " + guiImageIndex + " " // + image.getWidth() + "x" + image.getHeight() // + " px"); // gl.glEnable(GL.GL_TEXTURE_2D); // image.drawAt(gl, 100, y); // gl.glDisable(GL.GL_TEXTURE_2D); // // gl.glColor3f(0, 0, 0); // gl.glRasterPos2i(20, y + 20); // glut.glutBitmapString(GLUT.BITMAP_HELVETICA_12, // guiImageIndex + ":"); // // images++; // guiImageIndex++; // y -= image.getHeight() + 20; // } // // System.out.println("Nanotime: " + (System.nanoTime() - intime) // + " for " + images + " images"); // gl.glFlush(); // // } // // private void drawPoint(GL2 gl, int x, int y) { // gl.glColor3f(0, 0, 1); // gl.glBegin(GL2.GL_QUADS); // gl.glVertex2i(x + 2, y + 2); // gl.glVertex2i(x + 2, y - 2); // gl.glVertex2i(x - 2, y - 2); // gl.glVertex2i(x - 2, y + 2); // gl.glEnd(); // gl.glColor3f(1, 1, 1); // } // }); } private class Content implements RegionContent { private static final int SETTLERS = 1; private static final int GUI = 2; private static final int LANDSCAPE = 2; private int offsetY = 400; private int offsetX = 200; private int mode = SETTLERS; public Content() { printHelp(); } @Override public void handleEvent(GOEvent event) { if (event instanceof GOKeyEvent) { String keyCode = ((GOKeyEvent) event).getKeyCode(); if ("UP".equalsIgnoreCase(keyCode)) { offsetY -= 400; } else if ("DOWN".equalsIgnoreCase(keyCode)) { offsetY += 400; } else if ("LEFT".equalsIgnoreCase(keyCode)) { offsetX += 100; } else if ("RIGHT".equalsIgnoreCase(keyCode)) { offsetX -= 100; } else if ("L".equalsIgnoreCase(keyCode)) { mode = LANDSCAPE; } else if ("S".equalsIgnoreCase(keyCode)) { mode = SETTLERS; } else if ("G".equalsIgnoreCase(keyCode)) { mode = GUI; } else if ("E".equalsIgnoreCase(keyCode)) { export(); } else if ("W".equalsIgnoreCase(keyCode)) { exportAll(); } region.requestRedraw(); } } @Override public void drawContent(GLDrawContext gl2, int width, int height) { if (mode == SETTLERS) { SequenceList<Image> sequences = reader.getSettlers(); drawSequences(gl2, width, height, sequences); } else if (mode == GUI) { Sequence<GuiImage> sequences = reader.getGuis(); drawSequence(gl2, width, height, 0, sequences); } else { Sequence<LandscapeImage> sequences = reader.getLandscapes(); drawSequence(gl2, width, height, 0, sequences); } } private <T extends Image> void drawSequences(GLDrawContext gl2, int width, int height, SequenceList<T> sequences) { gl2.glTranslatef(offsetX, offsetY, 0); int y = 0; int seqIndex = 0; TextDrawer drawer = gl2.getTextDrawer(EFontSize.NORMAL); for (int i = 0; i < sequences.size(); i++) { Sequence<T> seq = sequences.get(i); int maxheight; maxheight = drawSequence(gl2, width, height, y, seq); gl2.color(0, 0, 0, 1); drawer.drawString(20, y + 20, seqIndex + ":"); seqIndex++; y -= maxheight + 40; } } private <T extends Image> int drawSequence(GLDrawContext gl2, int width, int height, int y, Sequence<T> seq) { int maxheight = 0; int x = 0; for (int index = 0; index < seq.length(); index++) { T image = seq.getImage(index); maxheight = Math.max(maxheight, image.getHeight()); if (x > -offsetX - 100 && x < -offsetX + width + 100 && y > -offsetY - 100 && y < -offsetY + height + 100) { drawImage(gl2, y, index, x, (SingleImage) image); } x += 100; } return maxheight; } private void drawImage(GLDrawContext gl2, int y, int index, int x, SingleImage image) { image.drawAt(gl2, x - image.getOffsetX(), y + image.getHeight() + image.getOffsetY(), colors[index % colors.length]); gl2.color(1, 0, 0, 1); float[] line = new float[] { x, y, 0, x, y + image.getHeight() + image.getOffsetY(), 0, x - image.getOffsetX(), y + image.getHeight() + image.getOffsetY(), 0 }; gl2.drawLine(line, false); drawPoint(gl2, x, y); drawPoint(gl2, x + image.getWidth(), y); drawPoint(gl2, x + image.getWidth(), y + image.getHeight()); drawPoint(gl2, x, y + image.getHeight()); } private void drawPoint(GLDrawContext gl2, int x, int y) { } private void printHelp() { System.out .println("HELP:\nUse arrow keys to navigate.\nS shows settlers. \nG shows gui images. \nB shows Background. \nE exports as png"); } } private void reloadDatFile() { File file = new File(FILE.replace("%", String.format("%02d", datFileIndex))); reader = new AdvancedDatFileReader(file, TYPE); } protected void export() { final JFileChooser fc = new JFileChooser(); fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int returnVal = fc.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { File dir = fc.getSelectedFile(); exportTo(dir, reader); } } private static void exportAll() { final JFileChooser fc = new JFileChooser(); fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); int returnVal = fc.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { File dir = fc.getSelectedFile(); for (int i = 0; i <= 99; i++) { File file = new File(FILE.replace("%", String.format("%02d", i))); if (file.exists()) { AdvancedDatFileReader reader = new AdvancedDatFileReader(file, TYPE); exportTo(new File(dir, "" + i), reader); } } } } private static void exportTo(File dir, AdvancedDatFileReader reader) { export(reader.getSettlers(), new File(dir, "settlers")); Sequence<GuiImage> guis = reader.getGuis(); if (guis.length() > 0) { exportSequence(new File(dir, "gui"), 0, guis); } Sequence<LandscapeImage> landscapes = reader.getLandscapes(); if (landscapes.length() > 0) { exportSequence(new File(dir, "landscape"), 1, landscapes); } } private static <T extends Image> void export(SequenceList<T> sequences, File dir) { for (int index = 0; index < sequences.size(); index++) { Sequence<T> seq = sequences.get(index); exportSequence(dir, index, seq); } } private static <T extends Image> void exportSequence(File dir, int index, Sequence<T> seq) { File seqdir = new File(dir, index + ""); seqdir.mkdirs(); for (int j = 0; j < seq.length(); j++) { T image = seq.getImage(j); export((SingleImage) image, new File(seqdir, j + ".png")); if (image instanceof SettlerImage && ((SettlerImage) image).getTorso() != null) { export((SingleImage) ((SettlerImage) image).getTorso(), new File(seqdir, j + "_torso.png")); } } } private static void export(SingleImage image, File file) { // does not work if gpu does not support non-power-of-two BufferedImage rendered = ImageUtils.convertToBufferedImage(image); if (rendered == null) { return; } try { ImageIO.write(rendered, "png", file); } catch (IOException e) { e.printStackTrace(); } } }