package net.hvidtfeldts.meshia.engine3d;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLJPanel;
import javax.swing.SwingUtilities;
import net.hvidtfeldts.meshia.sunflow.SunflowRenderer;
import net.hvidtfeldts.meshia.sunflow.TestScene;
import net.hvidtfeldts.utils.Logger;
import org.sunflow.math.Point3;
import org.sunflow.math.Vector3;
import com.jogamp.opengl.util.Animator;
public final class OpenGlWindow extends GLJPanel implements MouseListener, MouseMotionListener, KeyListener {
public static final boolean MEASURE_FPS = false;
private static final long serialVersionUID = 1L;
private Animator animator;
private final Engine engine;
private int x;
private int y;
private OpenGlWindow(final GLCapabilities caps, Engine engine) {
super(caps);
this.engine = engine;
addGLEventListener(engine);
this.setBackground(Color.BLACK);
if (MEASURE_FPS) {
animator = new Animator();
animator.setRunAsFastAsPossible(true);
animator.add(this);
animator.start();
}
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
}
public static OpenGlWindow createOpenGlWindow(Engine engine) {
GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
final GLCapabilities caps = new GLCapabilities(glp);
caps.setSampleBuffers(true);
caps.setNumSamples(2);
OpenGlWindow oglw = new OpenGlWindow(caps, engine);
oglw.setMinimumSize(new Dimension(50, 50));
return oglw;
}
@Override
public void dispose() {
if (animator != null) {
animator.stop();
}
}
@Override
public void mouseClicked(MouseEvent e) {
requestFocus();
}
@Override
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e) && SwingUtilities.isRightMouseButton(e)) {
engine.moveCamera(0, 0, (e.getY() - y) / 2.0f);
engine.zoom((e.getX() - x) / 10.0f);
}
else if (SwingUtilities.isLeftMouseButton(e)) {
engine.rotate(x - e.getX(), y - e.getY());
}
else {
engine.moveCamera(-(x - e.getX()) / 10.f, (y - e.getY()) / 10.f, 0.0f);
}
x = e.getX();
y = e.getY();
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == 'a') {
engine.moveCamera(1, 0, 0);
}
else if (e.getKeyChar() == 'd') {
engine.moveCamera(-1, 0, 0);
}
else if (e.getKeyChar() == 'w') {
engine.moveCamera(0, 0, 1);
}
else if (e.getKeyChar() == 's') {
engine.moveCamera(0, 0, -1);
}
else if (e.getKeyChar() == '1') {
engine.takeSnapshot();
}
else if (e.getKeyChar() == '2') {
TestScene ts = new TestScene();
float[] pos = engine.getCamera().getPosInWorldCoords();
float[] cpos = engine.getCamera().getPosInCameraCoords();
float[] up = engine.getCamera().getUp();
float[] forward = engine.getCamera().getForward();
ts.up = new Vector3(up[0], up[1], up[2]);
ts.eye = new Point3(pos[0], pos[1], pos[2]);
ts.target = new Point3(pos[0] + forward[0], pos[1] + forward[1], pos[2] + forward[2]);
Logger.log(String.format("Forward: %s %s %s", forward[0], forward[1], forward[2]));
Logger.log(String.format("Pos: %s %s %s", pos[0], pos[1], pos[2]));
Logger.log(String.format("CPos: %s %s %s", cpos[0], cpos[1], cpos[2]));
ts.mesh = engine.getMesh();
ts.width = this.getWidth();
ts.height = this.getHeight();
SunflowRenderer.render(ts);
}
repaint();
}
@Override
public void keyReleased(KeyEvent e) {
}
}