import java.awt.Font; import java.awt.Color; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import keel.runtime.Application; import keel.runtime.KeelRuntime; import keel.runtime.event.KeyEvent; import keel.runtime.event.KeyAdapter; import keel.gfx.GLGraphics; import keel.gfx.GLConstants; import keelx.gfx.image.BufferedGLImage; public class Move implements Application { private int width = 640; private int height = 480; private Cube cube1 = new Cube(); private Cube cube2 = new Cube(); private Material[] materials = { cube1, cube2, }; private BufferedGLImage image; private Camera camera; private int fontSize = Math.min(height, width) / 16; public Move() { camera = new Camera(width / (double) height, 10, cube1); image = new BufferedGLImage(width, height); } public void keelMain(KeelRuntime runtime,String argv[]) { runtime.createWindow("", width, height); runtime.createGraphicsWithDefaultPixelFormat(); runtime.addKeyListener(new Controller()); runtime.run(); } public void initGraphics(GLGraphics g) { g.glViewport(0, 0, width, height); g.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); g.glEnable(GLConstants.GL_BLEND); g.glBlendFunc(GLConstants.GL_SRC_ALPHA, GLConstants.GL_ONE_MINUS_SRC_ALPHA); } public void update(GLGraphics g) { g.glClear(GLConstants.GL_COLOR_BUFFER_BIT); g.glPushMatrix(); g.glMatrixMode(GLConstants.GL_PROJECTION); g.glLoadIdentity(); camera.update(g); g.glMatrixMode(GLConstants.GL_MODELVIEW); g.glLoadIdentity(); for (int i = 0; i < materials.length; i++) { g.glPushMatrix(); materials[i].update(g); g.glPopMatrix(); } g.glPopMatrix(); printMessage(g, new String[] { camera.toString(), "Cube1: " + cube1.toString(), "Cube2: " + cube2.toString(), }); } public void quitRequested() { KeelRuntime.getRuntime().disposeDisplay(); System.exit(0); } private void printMessage(GLGraphics g, String[] messages) { Graphics2D g2d = image.getBufferedImage().createGraphics(); g2d.setTransform(new AffineTransform(1, 0, 0, -1, 0, height)); g2d.setBackground(new Color(0, 0, 0, 0)); g2d.clearRect(0, 0, width, height); g2d.setFont(g2d.getFont().deriveFont(Font.PLAIN, (float) fontSize)); g2d.setColor(Color.blue); int margin = fontSize / 2; int x = margin; int y = height - (fontSize + margin) * (messages.length - 1) - margin; for (int i = 0; i < messages.length; i++) { g2d.drawString(messages[i], x, y); y += fontSize + margin; } g.glPushMatrix(); g.glMatrixMode(GLConstants.GL_PROJECTION); g.glLoadIdentity(); image.draw(g); g.glPopMatrix(); } class Controller extends KeyAdapter { Material material = cube1; public void keyPressed(KeyEvent ev) { switch (ev.getKeyCode()) { case KeyEvent.VK_LEFT: material.left(); break; case KeyEvent.VK_RIGHT: material.right(); break; case KeyEvent.VK_UP: material.forward(); break; case KeyEvent.VK_DOWN: material.backward(); break; case KeyEvent.VK_PAGE_UP: material.up(); break; case KeyEvent.VK_PAGE_DOWN: material.down(); break; case KeyEvent.VK_SPACE: if (material == camera) { material = cube1; } else { material = camera; } break; case KeyEvent.VK_ADD: camera.narrower(); break; case KeyEvent.VK_SUBTRACT: camera.wider(); break; case KeyEvent.VK_Q: System.exit(0); break; default: break; } } } } class Camera extends Material { public Camera(double anAspectRatio, int aViewAngle, Material aTarget) { super(-20, 100, 100); target = aTarget; aspectRatio = anAspectRatio; viewAngle = aViewAngle; } private Material target; private double aspectRatio; private int viewAngle; public void setTarget(Material aTarget) { target = aTarget; } public void update(GLGraphics g) { g.gluPerspective(viewAngle, aspectRatio, 1.0d, 1600.0d); g.gluLookAt( getX(), getY(), getZ(), target.getX(), target.getY(), target.getZ(), 0, 0, 1); } public void narrower() { viewAngle--; } public void wider() { viewAngle++; } public String toString() { return "View angle:" + viewAngle + " at: (" + getX() + "," + getY() + "," + getZ() + ") target: (" + target.getX() + "," + target.getY() + "," + target.getZ() + ")"; } } class Cube extends Material { public Cube() { super(0, 0, 0); } private double width = 2d; private int[][] faceList = { {0, 3, 2, 1}, {1, 2, 6, 5}, {5, 6, 7, 4}, {4, 7, 3, 0}, {4, 0, 1, 5}, {3, 7, 6, 2}, }; public void update(GLGraphics g) { double[][] vertexList = { {getX() - width, getY() - width, getZ() - width}, {getX() + width, getY() - width, getZ() - width}, {getX() + width, getY() + width, getZ() - width}, {getX() - width, getY() + width, getZ() - width}, {getX() - width, getY() - width, getZ() + width}, {getX() + width, getY() - width, getZ() + width}, {getX() + width, getY() + width, getZ() + width}, {getX() - width, getY() + width, getZ() + width}, }; g.glColor3f(1.0f, 1.0f, 1.0f); for (int i = 0; i < faceList.length; i++) { g.glBegin(GLConstants.GL_LINE_LOOP); int[] face = faceList[i]; for (int j = 0; j < face.length; j++) { int vertexIndex = face[j]; g.glVertex3dv(vertexList[vertexIndex]); } g.glEnd(); } } public String toString() { return "Cube at: (" + getX() + "," + getY() + "," + getZ() + ") width: " + width; } } class Material { public Material(int aX, int aY, int aZ) { this(aX, aY, aZ, 2); } public Material(int aX, int aY, int aZ, int aSpeed) { x = aX; y = aY; z = aZ; speed = aSpeed; } private int x = 0; private int y = 0; private int z = 0; private int speed = 2; public int getX() { return x; } public int getY() { return y; } public int getZ() { return z; } public int getSpeed() { return speed; } public void right() { x += speed; } public void left() { x -= speed; } public void forward() { y += speed; } public void backward() { y -= speed; } public void up() { z += speed; } public void down() { z -= speed; } public void update(GLGraphics g) { } }