Skip to content

Instantly share code, notes, and snippets.

@eiennohito
Created April 18, 2012 17:46
Show Gist options
  • Save eiennohito/2415378 to your computer and use it in GitHub Desktop.
Save eiennohito/2415378 to your computer and use it in GitHub Desktop.
package org.eiennohito.ui;
import com.sun.opengl.util.j2d.TextRenderer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eiennohito.MouseUtils;
import static org.eiennohito.MouseUtils.isButton1Pressed;
import org.eiennohito.control.MouseToTransformation;
import org.eiennohito.control.TranslatorsService;
import org.eiennohito.drawing.GLRenderer;
import org.eiennohito.drawing.Scene;
import org.eiennohito.math.Matrix;
import org.eiennohito.model.GLFPSCounter;
import org.eiennohito.transformations.AbstractTransformation;
import org.eiennohito.transformations.FitToScreenTransformation;
import org.eiennohito.transformations.NullTransformation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.media.opengl.GL;
import static javax.media.opengl.GL.*;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCanvas;
import javax.media.opengl.GLEventListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
/**
* @author eiennohito
* @date 24.02.2008
*/
@Service
public class GLDrawer implements GLEventListener {
Log logger = LogFactory.getLog(GLDrawer.class);
private GLFPSCounter counter = null;
private Scene scene;
@Autowired
private GLRenderer renderer;
private Matrix projectionMatrix;
private Matrix modelMatrix;
private boolean enabled;
Robot robot;
private int winX;
private int winY;
private int winWidth;
private int winHeight;
private int screenX;
private int screenY;
private int wheelPos;
private int modePos = 0;
@Autowired
private TranslatorsService translators;
private final TextRenderer textRenderer = new TextRenderer(new Font("Meiryo", Font.PLAIN, 10));
public void init(final GLAutoDrawable drawable) {
final GL gl = drawable.getGL();
try {
robot = new Robot();
} catch (AWTException e) {
throw new RuntimeException(e);
}
gl.glShadeModel(GL.GL_SMOOTH);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
gl.glClearDepth(1.0f);
gl.glEnable(GL.GL_LIGHTING);
gl.glEnable(GL_LIGHT0);
gl.glLightModelf(GL_LIGHT_MODEL_AMBIENT, 0.f);
gl.glLightf(GL_LIGHT0, GL.GL_CONSTANT_ATTENUATION, 0.4f);
gl.glLightfv(GL_LIGHT0, GL.GL_SPECULAR, new float[] {1, 1, 1, 1}, 0);
gl.glLightfv(GL_LIGHT0, GL.GL_DIFFUSE, new float[] {1, 1, 1, 1}, 0);
//gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, new float[]{0, 0.5f, 0.5f, 1}, 0);
gl.glLightfv(GL_LIGHT0, GL.GL_DIFFUSE, new float[]{2, 0, 1, 1}, 0);
//gl.glLightf(GL.GL_LIGHT0, GL.GL_SPECULAR, 1.f);
gl.glLightModeli(GL.GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE, 1);
//gl.glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180f);
//gl.glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 15.0f);
gl.glLightModeli(GL.GL_LIGHT_MODEL_LOCAL_VIEWER, 0);
//gl.glEnable(GL.GL_COLOR_MATERIAL);
//gl.glDepthFunc(GL.GL_LEQUAL);
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT,
GL.GL_NICEST);
scene = new Scene();
final MouseAdapter listener = new MouseAdapter() {
public Cursor cursor;
@Override
public void mouseClicked(MouseEvent e) {
GLCanvas canvas = (GLCanvas) drawable;
if (isButton1Pressed(e)) {
enabled = !enabled;
if (enabled) {
screenX = e.getXOnScreen();
screenY = e.getYOnScreen();
centerMouse();
wheelPos = 0;
getTranslator().changeMode(0);
cursor = canvas.getCursor();
canvas.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
getTranslator().start();
} else {
robot.mouseMove(screenX, screenY);
canvas.setCursor(cursor);
scene.addTransformation(getTranslator().stop());
drawable.repaint();
}
}
if (MouseUtils.isButton3Pressed(e) && enabled) {
enabled = !enabled;
robot.mouseMove(screenX, screenY);
canvas.setCursor(cursor);
getTranslator().stop();
scene.applyTemporaryTransformation(new NullTransformation());
drawable.repaint();
}
if (!enabled && MouseUtils.isButton3Pressed(e) && e.getClickCount() == 2) {
scene.addTransformation(new FitToScreenTransformation(scene, getOrthoVals()));
drawable.repaint();
}
//logger.info("click count = " + e.getClickCount());
}
@Override
public void mouseMoved(MouseEvent e) {
if (enabled) {
final int dx = winX + winWidth / 2 - e.getXOnScreen();
final int dy = winY + winHeight / 2 - e.getYOnScreen();
centerMouse();
drawable.repaint();
scene.applyTemporaryTransformation(getTranslator().process(dx, dy));
}
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (enabled) {
wheelPos += e.getWheelRotation();
getTranslator().changeMode(wheelPos);
} else {
modePos += e.getWheelRotation();
translators.changeMode(modePos);
}
drawable.repaint();
}
};
drawable.addMouseMotionListener(listener);
drawable.addMouseListener(listener);
drawable.addMouseWheelListener(listener);
}
private void centerMouse() {
robot.mouseMove(winX + winWidth / 2, winY + winHeight / 2);
}
public void loadScene(Scene s) {
scene = s;
s.init();
s.setFPSCounter(counter);
}
public void display(GLAutoDrawable drawable) {
final GL gl = drawable.getGL();
scene.setRenderer(renderer.applyGL(gl));
scene.draw();
textRenderer.beginRendering(winWidth, winHeight);
textRenderer.draw(getTranslator().getHelpString(), 40, 30);
textRenderer.endRendering();
buildGLMatrix(gl);
}
public void buildGLMatrix(GL gl) {
final float[] projectionMatrix = new float[16];
gl.glGetFloatv(GL.GL_PROJECTION_MATRIX, projectionMatrix, 0);
this.projectionMatrix = new Matrix(projectionMatrix);
final float[] modelMatrix = new float[16];
gl.glGetFloatv(GL.GL_MODELVIEW_MATRIX, modelMatrix, 0);
this.modelMatrix = new Matrix(modelMatrix);
}
public Matrix getProjectionMatrix() {
return projectionMatrix;
}
public Matrix getModelMatrix() {
return modelMatrix;
}
protected Matrix createProjectionMatrix(GLAutoDrawable drawable) {
return Matrix.identity();
}
private float[] getOrthoVals() {
return new float[] {
-winWidth / 20,
winWidth / 20,
-winHeight / 20,
winHeight / 20
};
}
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
winX = x;
winY = y;
winWidth = width;
winHeight = height;
final GL gl = drawable.getGL();
gl.glMatrixMode(GL_PROJECTION);
gl.glLoadIdentity();
//createProjectionMatrix(drawable).fillGL(gl);
float[] vals = getOrthoVals();
gl.glOrtho(vals[0], vals[1], vals[2], vals[3], -1000, 1000);
gl.glMatrixMode(GL_MODELVIEW);
GLFPSCounter newCounter = new GLFPSCounter(10, height - 10, textRenderer, width, height);
counter = newCounter;
scene.setFPSCounter(counter);
}
public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
}
public void addTransformation(AbstractTransformation transformation) {
scene.addTransformation(transformation);
}
public MouseToTransformation getTranslator() {
return translators.current();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment