package com.framsticks.net.client3D; import java.awt.BorderLayout; import java.awt.Container; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.util.HashMap; import java.util.Set; import javax.media.opengl.GLCanvas; import javax.swing.JFrame; import javax.swing.JPanel; /** * A window rendering the whole scene using OpenGL. * * @author vorg */ public class Viewer extends JPanel implements MouseListener, MouseMotionListener { static final long serialVersionUID = 1; private Renderer renderer; private HashMap styles; private Creature[] creatures; private int clickX; private int clickY; private float clickRotY; private float clickRotX; private App app = null; /** * Constructor. * * @param app * An application instance. */ public Viewer(App app) throws IOException { this.app = app; init(); } /** * Constructor. */ public Viewer() throws IOException { init(); } /** * Creates a rendering window. * * @return A window's handler. */ public JFrame showInFrame() { JFrame frame = new JFrame("Framsticks 3D View"); JFrame.setDefaultLookAndFeelDecorated(true); frame.setSize(500, 500); if (app != null) { frame.setLocationRelativeTo(app); frame.setLocation(app.getX() - frame.getSize().width, app.getY()); } frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); Container contentPane = frame.getContentPane(); contentPane.setLayout(new BorderLayout()); contentPane.add(this, BorderLayout.CENTER); return frame; } private void init() throws IOException { styles = new HashMap(); createCanvas(); MouseWheelListener listener = new MouseWheelListener() { // float zoomFactor = 0.1f; public void mouseWheelMoved(MouseWheelEvent e) { renderer.setTranslation(renderer.getTranslation() * (float) (e.getWheelRotation() * 0.1 + 1.0)); } }; this.addMouseWheelListener(listener); // Log.getInstance().addLoggerListener(new ILogListener() { // public void onMesssage(String category, String text) { // System.out.println(category + " > " + text ); // } // }); } /** * Creates a surface object for OpenGL rendering. */ private void createCanvas() throws IOException { GLCanvas canvas = new GLCanvas(); renderer = new Renderer(); canvas.addGLEventListener(renderer); canvas.addMouseListener(this); canvas.addMouseMotionListener(this); canvas.setVisible(true); this.setOpaque(true); this.setLayout(new BorderLayout()); this.add(canvas, BorderLayout.CENTER); this.setVisible(true); final String shadersPath = "res/shaders"; File dir = new File(shadersPath); if (!dir.canRead()) { throw new IOException("Cannot access " + shadersPath); } if (!dir.isDirectory()) { throw new IOException(shadersPath + " is not a directory."); } // It is also possible to filter the list of returned files. // This example does not return any files that start with `.'. FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String name) { return name.matches(".*[cC][gG][fF][xX]$"); } }; String[] children = dir.list(filter); dir = new File("../.."); for (int i = 0; i < children.length; i++) { String name = children[i].substring(0, children[i].length() - 5); cgfxEffect effect = new cgfxEffect(name); styles.put(name, effect); if (app != null) { app.AddStyle(name); } // effect.LoadByName(name, context) // children[i]; Log.getInstance().log("dbg", name); } setStyle("basic"); //seems even simpler (and thus supported) than "default" } /** * Sets creatures to render. * * @param creatures * Creatures to render. */ public void setCreatures(Creature[] creatures) { this.creatures = creatures; renderer.setCreatures(creatures); } /** * Sets a world to render. * * @param world * A world to render. */ public void setWorld(World world) { renderer.setWorld(world); } /** * Gets a set of style names. * * @return A set of style names. */ public Set getStyleNames() { return styles.keySet(); } /** * Sets a currently activated style. If a style doesn't exist, it prints a * warning and a list of available styles. * * @param styleName * Name of a style to turn on. */ public void setStyle(String styleName) { if (styles.containsKey(styleName)) { renderer.setStyle(styles.get(styleName)); } else { Log.getInstance().log("wrn", "Style: " + styleName + " not found"); Log.getInstance().log("dbg", "Available styles:"); for (String key : styles.keySet()) { Log.getInstance().log("dbg", key); } } } /** * Switches the view to a creature from a specified group, with a specified * index. Passing value 1 in both parameters turns on the * general view of the whole world. * * @param group * Number of a group. * @param index * Index of a creature. */ public void setView(int group, int index) { if (creatures == null) { return; } renderer.resetTranslation(); if ((group == -1) || (index == -1)) { // if ((creatures != null) && creatures.length > 0) renderer.setCreatures(creatures); renderer.setModelType(Creature.ModelType.MechParts); } else { Creature creature = null; for (Creature c : creatures) { if ((c.getGroup() == group) && (c.getIndex() == index)) { creature = c; break; } } if (creature != null) { renderer.setCreatures(new Creature[] { creature }); renderer.setModelType(Creature.ModelType.Parts); } else { renderer.setCreatures(creatures); renderer.setModelType(Creature.ModelType.MechParts); } } } /* (non-Javadoc) * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) */ public void mouseClicked(MouseEvent e) { } /* (non-Javadoc) * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent) */ public void mouseEntered(MouseEvent e) { } /* (non-Javadoc) * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent) */ public void mouseExited(MouseEvent e) { } /* (non-Javadoc) * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) */ public void mousePressed(MouseEvent e) { clickX = e.getX(); clickY = e.getY(); clickRotY = renderer.getRotationY(); clickRotX = renderer.getRotationX(); } /* (non-Javadoc) * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent) */ public void mouseReleased(MouseEvent e) { } /* (non-Javadoc) * @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent) */ public void mouseDragged(MouseEvent e) { float difX = (e.getX() - clickX) / (float) getWidth(); float difY = (e.getY() - clickY) / (float) getHeight(); renderer.setRotationY(clickRotY + 180 * difX); renderer.setRotationX(clickRotX + 180 * difY); } /* (non-Javadoc) * @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent) */ public void mouseMoved(MouseEvent e) { } }