diff options
Diffstat (limited to 'src/net/java/games/util/DxTex.java')
-rw-r--r-- | src/net/java/games/util/DxTex.java | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/src/net/java/games/util/DxTex.java b/src/net/java/games/util/DxTex.java new file mode 100644 index 000000000..fc7410314 --- /dev/null +++ b/src/net/java/games/util/DxTex.java @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MIDROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + * + * Sun gratefully acknowledges that this software was originally authored + * and developed by Kenneth Bradley Russell and Christopher John Kline. + */ + +package net.java.games.util; + +import java.io.*; +import java.nio.*; +import java.awt.image.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.event.*; +import javax.swing.filechooser.*; + +/** Simplified clone of DxTex tool from the DirectX SDK, written in + Java using the DDSReader; tests fetching of texture data */ + +public class DxTex { + private InternalFrameListener frameListener; + private File defaultDirectory; + private JDesktopPane desktop; + private static String endl = System.getProperty("line.separator"); + private JMenu mipMapMenu; + + public static void main(String[] args) { + new DxTex().run(args); + } + + private void run(String[] args) { + defaultDirectory = new File(System.getProperty("user.dir")); + JFrame frame = new JFrame("DirectX Texture Tool"); + frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + JMenuBar menuBar = new JMenuBar(); + JMenu menu = createMenu("File", 'F', 0); + JMenuItem item = + createMenuItem("Open...", + new ActionListener() { + public void actionPerformed(ActionEvent e) { + openFile(); + } + }, + KeyEvent.VK_O, InputEvent.CTRL_MASK, + 'O', 0); + menu.add(item); + item = + createMenuItem("Exit", + new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.exit(0); + } + }, + KeyEvent.VK_Q, InputEvent.CTRL_MASK, + 'x', 1); + menu.add(item); + menuBar.add(menu); + + menu = createMenu("MipMap", 'M', 0); + menu.setEnabled(false); + mipMapMenu = menu; + menuBar.add(menu); + + frame.setJMenuBar(menuBar); + + desktop = new JDesktopPane(); + frame.getContentPane().add(desktop); + frame.setSize(640, 480); + frame.show(); + + frameListener = new InternalFrameAdapter() { + public void internalFrameActivated(InternalFrameEvent e) { + JInternalFrame ifr = e.getInternalFrame(); + if (ifr instanceof ImageFrame) { + // Recompute entries in mip map menu + final ImageFrame frame = (ImageFrame) ifr; + if (frame.getNumMipMaps() > 0) { + mipMapMenu.removeAll(); + // Add entries + for (int i = 0; i < frame.getNumMipMaps(); i++) { + final int map = i; + JMenuItem item; + String title = "Level " + (i + 1); + ActionListener listener = new ActionListener() { + public void actionPerformed(ActionEvent e) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + frame.setMipMapLevel(map); + } + }); + } + }; + if (i < 9) { + char c = (char) ('0' + i + 1); + item = createMenuItem(title, listener, c, 6); + } else { + item = createMenuItem(title, listener); + } + mipMapMenu.add(item); + } + mipMapMenu.setEnabled(true); + } else { + mipMapMenu.setEnabled(false); + } + } else { + mipMapMenu.setEnabled(false); + } + } + + public void internalFrameClosing(InternalFrameEvent e) { + desktop.remove(e.getInternalFrame()); + desktop.invalidate(); + desktop.validate(); + desktop.repaint(); + // THIS SHOULD NOT BE NECESSARY + desktop.requestFocus(); + } + + public void internalFrameClosed(InternalFrameEvent e) { + JInternalFrame ifr = e.getInternalFrame(); + if (ifr instanceof ImageFrame) { + ((ImageFrame) ifr).close(); + } + } + }; + + for (int i = 0; i < args.length; i++) { + final File file = new File(args[i]); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + openFile(file); + } + }); + } + } + + //---------------------------------------------------------------------- + // Actions + // + + private void openFile() { + JFileChooser chooser = new JFileChooser(defaultDirectory); + chooser.setMultiSelectionEnabled(false); + chooser.addChoosableFileFilter(new javax.swing.filechooser.FileFilter() { + public boolean accept(File f) { + return (f.isDirectory() || + f.getName().endsWith(".dds")); + } + + public String getDescription() { + return "Texture files (*.dds)"; + } + }); + + int res = chooser.showOpenDialog(null); + if (res == JFileChooser.APPROVE_OPTION) { + final File file = chooser.getSelectedFile(); + defaultDirectory = file.getParentFile(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + openFile(file); + } + }); + } + } + + private void openFile(File file) { + try { + DDSReader reader = new DDSReader(); + reader.loadFile(file.getAbsolutePath()); + showImage(file.getName(), reader, 0); + } catch (IOException e) { + showMessageDialog("Error while opening file:" + endl + + exceptionToString(e), + "Error opening file", + JOptionPane.WARNING_MESSAGE); + } + } + + //---------------------------------------------------------------------- + // Image display + // + + private void showImage(String filename, DDSReader reader, int mipMapLevel) { + try { + ImageFrame fr = new ImageFrame(filename, reader, mipMapLevel); + desktop.add(fr); + fr.show(); + } catch (Exception e) { + showMessageDialog("Error while loading file:" + endl + + exceptionToString(e), + "Error loading file", + JOptionPane.WARNING_MESSAGE); + } + } + + class ImageFrame extends JInternalFrame { + private String filename; + private DDSReader reader; + private int mipMapLevel; + private int curWidth; + private int curHeight; + private JLabel label; + + ImageFrame(String filename, DDSReader reader, int mipMapLevel) { + super(); + this.filename = filename; + this.reader = reader; + + addInternalFrameListener(frameListener); + label = new JLabel(); + JScrollPane scroller = new JScrollPane(label); + getContentPane().add(scroller); + setSize(400, 400); + setResizable(true); + setIconifiable(true); + setClosable(true); + setMipMapLevel(mipMapLevel); + } + + int getNumMipMaps() { + return reader.getNumMipMaps(); + } + + void setMipMapLevel(int level) { + mipMapLevel = level; + computeImage(); + resetTitle(); + } + + void close() { + System.err.println("Closing files"); + reader.close(); + } + + private void computeImage() { + // Get image data + reader.getNumMipMaps(); + DDSReader.ImageInfo info = reader.getMipMap(mipMapLevel); + int width = info.getWidth(); + int height = info.getHeight(); + curWidth = width; + curHeight = height; + ByteBuffer data = info.getData(); + + // Build ImageIcon out of image data + BufferedImage img = new BufferedImage(width, height, + BufferedImage.TYPE_3BYTE_BGR); + WritableRaster dst = img.getRaster(); + + int skipSize; + if (reader.getPixelFormat() == DDSReader.D3DFMT_A8R8G8B8) { + skipSize = 4; + } else if (reader.getPixelFormat() == DDSReader.D3DFMT_R8G8B8) { + skipSize = 3; + } else { + reader.close(); + throw new RuntimeException("Unsupported pixel format " + reader.getPixelFormat()); + } + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + // NOTE: highly suspicious that A comes fourth in + // A8R8G8B8...not really ARGB, but RGBA (like OpenGL) + dst.setSample(x, y, 0, data.get(skipSize * (width * y + x) + 2) & 0xFF); + dst.setSample(x, y, 1, data.get(skipSize * (width * y + x) + 1) & 0xFF); + dst.setSample(x, y, 2, data.get(skipSize * (width * y + x) + 0) & 0xFF); + } + } + + label.setIcon(new ImageIcon(img)); + } + + private void resetTitle() { + setTitle(filename + " (" + curWidth + "x" + curHeight + + ", mipmap " + (1 + mipMapLevel) + " of " + + reader.getNumMipMaps() + ")"); + } + } + + + //---------------------------------------------------------------------- + // Menu and menu item creation + // + + private static JMenu createMenu(String name, char mnemonic, int mnemonicPos) { + JMenu menu = new JMenu(name); + menu.setMnemonic(mnemonic); + menu.setDisplayedMnemonicIndex(mnemonicPos); + return menu; + } + + private static JMenuItem createMenuItem(String name, ActionListener l) { + JMenuItem item = new JMenuItem(name); + item.addActionListener(l); + return item; + } + + private static JMenuItem createMenuItemInternal(String name, ActionListener l, int accelerator, int modifiers) { + JMenuItem item = createMenuItem(name, l); + item.setAccelerator(KeyStroke.getKeyStroke(accelerator, modifiers)); + return item; + } + + private static JMenuItem createMenuItem(String name, ActionListener l, int accelerator) { + return createMenuItemInternal(name, l, accelerator, 0); + } + + private static JMenuItem createMenuItem(String name, ActionListener l, char mnemonic, int mnemonicPos) { + JMenuItem item = createMenuItem(name, l); + item.setMnemonic(mnemonic); + item.setDisplayedMnemonicIndex(mnemonicPos); + return item; + } + + private static JMenuItem createMenuItem(String name, + ActionListener l, + int accelerator, + int acceleratorMods, + char mnemonic, + int mnemonicPos) { + JMenuItem item = createMenuItemInternal(name, l, accelerator, acceleratorMods); + item.setMnemonic(mnemonic); + item.setDisplayedMnemonicIndex(mnemonicPos); + return item; + } + + private void showMessageDialog(final String message, final String title, final int jOptionPaneKind) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + JOptionPane.showInternalMessageDialog(desktop, message, title, jOptionPaneKind); + } + }); + } + + private static String exceptionToString(Exception e) { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + PrintStream s = new PrintStream(bos); + e.printStackTrace(s); + return bos.toString(); + } +} |