EOS 2  1.1.0
Einfache Objektbasierte Sprache
WorldPanelOpenGLNoShader.java
gehe zur Dokumentation dieser Datei
1 package de.lathanda.eos.robot.gui;
2 
3 import java.awt.Color;
4 import java.awt.Dimension;
5 import java.awt.Toolkit;
6 import java.awt.event.MouseEvent;
7 import java.awt.event.MouseListener;
8 import java.awt.event.MouseMotionListener;
9 import java.awt.event.MouseWheelEvent;
10 import java.awt.event.MouseWheelListener;
11 import java.util.Map.Entry;
12 import com.jogamp.opengl.GL;
13 import com.jogamp.opengl.GL2;
14 import com.jogamp.opengl.GLAutoDrawable;
15 import com.jogamp.opengl.GLCapabilities;
16 import com.jogamp.opengl.GLEventListener;
17 import com.jogamp.opengl.GLProfile;
18 import com.jogamp.opengl.awt.GLCanvas;
19 import com.jogamp.opengl.glu.GLU;
20 import com.jogamp.opengl.util.FPSAnimator;
21 import de.lathanda.eos.robot.Column;
22 import de.lathanda.eos.robot.Coordinate;
23 import de.lathanda.eos.robot.Cube;
24 import de.lathanda.eos.robot.Entrance;
25 import de.lathanda.eos.robot.Robot;
26 import de.lathanda.eos.robot.World;
27 import de.lathanda.eos.robot.World.IntRange;
28 import de.lathanda.eos.robot.exceptions.RobotException;
29 import de.lathanda.eos.robot.geom3d.Polyhedron;
30 import static de.lathanda.eos.robot.obj.Models.*;
31 
39 public class WorldPanelOpenGLNoShader extends GLCanvas
40  implements GLEventListener, MouseListener, MouseMotionListener, MouseWheelListener {
41  private static final long serialVersionUID = -7254900679929645124L;
42  private GLU glu;
43  private FPSAnimator animator;
44 
45  private Camera cam;
46 
47  private int lastMouseX, lastMouseY;
48  private int lastButton;
49  private World world;
50 
52  super(new GLCapabilities(GLProfile.get(GLProfile.GL2)));
53  this.world = world;
54  cam = world.getCamera();
55  Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
56  setPreferredSize(new Dimension(screen.width / 2, screen.height / 2));
57 
58  init();
59  }
60 
61  private void init() {
62  glu = new GLU();
63 
64  // link controller
65  addMouseListener(this);
66  addMouseMotionListener(this);
67  addMouseWheelListener(this);
68  addGLEventListener(this);
69 
70  // start animation
71  animator = new FPSAnimator(this, 30, true);
72  animator.start();
73 
74  }
75 
76  @Override
77  public void display(GLAutoDrawable glad) {
78  GL2 gl = glad.getGL().getGL2();
79 
80  // prepare rendering
81  gl.glClearColor(0.25f, 0.6f, 1f, 0f);
82 
83  // store status
84  gl.glPushMatrix();
85  gl.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
86 
87  // apply camera position
88  gl.glRotated(cam.getCameraRotationX(), 1d, 0d, 0d);
89  gl.glRotated(cam.getCameraRotationZ(), 0d, 0d, 1d);
90 
91  // setup rendering parameters
92  gl.glEnable(GL.GL_BLEND);
93  gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
94  gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
95  // light
96  gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, new float[] { 0.2f, 0.2f, 0.2f, 1f }, 0);
97  gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, new float[] { 0.2f, 0.2f, 0.2f, 1f }, 0);
98  gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, new float[] { 0.8f, 0.8f, 0.8f, 1f }, 0);
99  gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, new float[] { -0.5f, -0.3f, 1f, 0f }, 0);
100 
101  renderSkybox(gl);
102 
103  gl.glTranslated(-cam.getCameraPositionX(), -cam.getCameraPositionY(), -cam.getCameraPositionZ());
104  gl.glEnable(GL.GL_DEPTH_TEST);
105  gl.glDepthFunc(GL.GL_LEQUAL);
106 
107  // render world
108  renderWorld(gl);
109 
110  // render cursor
111  if (world.isShowCursor()) {
112  renderCursor(gl);
113  }
114  // end rendering
115  gl.glPopAttrib();
116  gl.glPopMatrix();
117  }
118 
119  @Override
120  public void dispose(GLAutoDrawable glad) {
121  GLObjectBuffer.clear(glad.getGL());
122  GLTextureBuffer.clear(glad.getGL());
123  }
124 
125  @Override
126  public void init(GLAutoDrawable glad) {
127  }
128 
129  @Override
130  public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
131  GL2 gl = glad.getGL().getGL2();
132  double ratio = (double) width / (double) height;
133 
134  // lighting
135  gl.glEnable(GL2.GL_LIGHTING);
136  gl.glEnable(GL2.GL_LIGHT0);
137 
138  // projection
139  gl.glViewport(0, 0, width, height);
140  gl.glMatrixMode(GL2.GL_PROJECTION);
141  gl.glLoadIdentity();
142  glu.gluPerspective(60, ratio, 0.1d, 200d);
143 
144  gl.glMatrixMode(GL2.GL_MODELVIEW);
145 
146  }
147 
148  // Mouse routines
149  private static final double ROTATION_SPEED_SIDE = 0.15d;
150  private static final double ROTATION_SPEED_UP_DOWN = 0.4d;
151  private static final double MOVE_SPEED_SIDE = 0.14d;
152  private static final double MOVE_SPEED_UP_DOWN = 0.07d;
153  private static final double MOVE_SPEED = 2d;
154 
155  @Override
156  public void mouseDragged(MouseEvent e) {
157  int dX = e.getX() - lastMouseX;
158  int dY = e.getY() - lastMouseY;
159  switch (lastButton) {
160  case MouseEvent.BUTTON1: // Left
161  cam.moveCamera(-(dX * cos(cam.getCameraRotationZ()) - dY * sin(cam.getCameraRotationZ())) * MOVE_SPEED_SIDE,
162  (dX * sin(cam.getCameraRotationZ()) + dY * cos(cam.getCameraRotationZ())) * MOVE_SPEED_SIDE, 0d);
163  break;
164  case MouseEvent.BUTTON2: // middle
165  cam.moveCamera(-dX * cos(cam.getCameraRotationZ()) * MOVE_SPEED_SIDE,
166  dX * sin(cam.getCameraRotationZ()) * MOVE_SPEED_SIDE, dY * MOVE_SPEED_UP_DOWN);
167  break;
168  case MouseEvent.BUTTON3: // right
169  cam.rotateCamera(dY * ROTATION_SPEED_UP_DOWN, dX * ROTATION_SPEED_SIDE);
170  break;
171  }
172  restrictCamera();
173  lastMouseX = e.getX();
174  lastMouseY = e.getY();
175  }
176 
177  private void restrictCamera() {
178  if (cam.getCameraPositionZ() < 0.1) {
179  cam.setCameraRotationZ(0.1);
180  }
181  }
182 
183  @Override
184  public void mouseMoved(MouseEvent e) {
185  }
186 
187  @Override
188  public void mouseClicked(MouseEvent e) {
189  }
190 
191  @Override
192  public void mousePressed(MouseEvent e) {
193  lastButton = e.getButton();
194  lastMouseX = e.getX();
195  lastMouseY = e.getY();
196  }
197 
198  @Override
199  public void mouseReleased(MouseEvent e) {
200  lastMouseX = e.getX();
201  lastMouseY = e.getY();
202  }
203 
204  @Override
205  public void mouseEntered(MouseEvent e) {
206  }
207 
208  @Override
209  public void mouseExited(MouseEvent e) {
210  }
211 
212  @Override
213  public void mouseWheelMoved(MouseWheelEvent e) {
214  double mouseRotation = e.getPreciseWheelRotation();
215  moveCamera(MOVE_SPEED * mouseRotation);
216  }
217 
218  private void moveCamera(double distance) {
219  cam.moveCamera(sin(cam.getCameraRotationZ()) * sin(cam.getCameraRotationX()) * distance,
220  cos(cam.getCameraRotationZ()) * sin(cam.getCameraRotationX()) * distance,
221  cos(cam.getCameraRotationX()) * distance);
222  restrictCamera();
223  }
224 
225  private static double sin(double degree) {
226  return Math.sin(degree / 180 * Math.PI);
227  }
228 
229  private static double cos(double degree) {
230  return Math.cos(degree / 180 * Math.PI);
231  }
232 
233  // rendering routines
234  private static Color CURSOR_COLOR = new Color(1f, 1f, 0f, .5f);
235  public static double WIDTH = 1d;
236  public static double HEIGHT = 0.707117d;
237  public static double DEPTH = 1d;
238 
239  private void renderSkybox(GL2 gl) {
240  renderPolyhedron(SKYBOX, Color.BLACK, gl);
241  }
242 
243  public void renderWorld(GL2 gl) {
244  // floor
245  GLTextureBuffer floor = GLTextureBuffer.get(FLOOR_MATERIAL, gl);
246  floor.openMaterial(Color.GREEN, gl);
247  gl.glBegin(GL2.GL_QUADS);
248  gl.glNormal3f(0f, 0f, 1f);
249  IntRange rangeX = world.getxRange();
250  IntRange rangeY = world.getyRange();
251  double left = rangeX.getMin() - 0.5d;
252  double width = rangeX.size();
253  double bottom = rangeY.getMin() - 0.5d;
254  double height = rangeY.size();
255  gl.glTexCoord2d(0, 0);
256  gl.glVertex3d(left * WIDTH, bottom * DEPTH, 0);
257  gl.glTexCoord2d(0, height);
258  gl.glVertex3d(left * WIDTH, (bottom + height) * DEPTH, 0);
259  gl.glTexCoord2d(width, height);
260  gl.glVertex3d((left + width) * WIDTH, (bottom + height) * DEPTH, 0);
261  gl.glTexCoord2d(width, 0);
262  gl.glVertex3d((left + width) * WIDTH, bottom * DEPTH, 0);
263  gl.glEnd();
264  floor.closeMaterial(gl);
265 
266  // render columns with stones
267  synchronized (world.getColumns()) {
268  for (Entry<Coordinate, Column> col : world.getColumns().entrySet()) {
269  Coordinate co = col.getKey();
270  gl.glPushMatrix();
271  gl.glTranslated(co.getX() * WIDTH, co.getY() * DEPTH, 0d);
272  renderColumn(col.getValue(), gl);
273  gl.glPopMatrix();
274  }
275  }
276 
277  // render robots
278  synchronized (world.getRobots()) {
279  for (Robot r : world.getRobots()) {
280  renderRobot(r, gl);
281  }
282  }
283  // render entrances
284  synchronized (world.getEntrances()) {
285  for (Entrance e : world.getEntrances()) {
286  renderEntrance(e, gl);
287  }
288  }
289  }
290 
291  private void renderCursor(GL2 gl) {
292  gl.glPushMatrix();
293  gl.glTranslated(world.getCursorX() * WIDTH, world.getCursorY() * DEPTH, world.getCursorZ() * HEIGHT);
294  renderPolyhedron(CURSOR, CURSOR_COLOR, gl);
295  gl.glPopMatrix();
296  }
297 
298  private void renderEntrance(Entrance e, GL2 gl) {
299  gl.glPushMatrix();
300  gl.glTranslated(e.x * WIDTH, e.y * DEPTH, e.z * HEIGHT);
301  gl.glRotatef(e.d.getAngle(), 0f, 0f, 1f);
302  renderPolyhedron(ROBOT, new Color(0.5f, 0.5f, 0.5f, 0.5f), gl);
303  gl.glPopMatrix();
304  }
305 
306  private void renderRobot(Robot r, GL2 gl) {
307  gl.glPushMatrix();
308  gl.glTranslated(r.getX() * WIDTH, r.getY() * DEPTH, r.getZ() * HEIGHT);
309  gl.glRotatef(r.getDirection().getAngle(), 0f, 0f, 1f);
310  renderPolyhedron(ROBOT, r.getRobotColor().getColor(), gl);
311  gl.glPopMatrix();
312  }
313 
314  private void renderColumn(Column column, GL2 gl) {
315  gl.glPushMatrix();
316  boolean doMark = true;
317  Cube[] cubes;
318  try {
319  cubes = column.getCubes();
320  for (int i = 0; i < cubes.length; i++) {
321  if (!cubes[i].isEmpty()) {
322  renderCube(cubes[i], gl);
323  doMark = true;
324  } else if (column.isMarked() && doMark) {
325  renderPolyhedron(MARK, column.getMark().getColor(), gl);
326  doMark = false;
327  }
328  gl.glTranslated(0d, 0d, HEIGHT);
329  }
330  if (column.isMarked() && doMark) {
331  renderPolyhedron(MARK, column.getMark().getColor(), gl);
332  }
333  } catch (RobotException e) {
334  }
335  gl.glPopMatrix();
336  }
337 
338  private void renderCube(Cube cube, GL2 gl) {
339  switch (cube.getType()) {
340  case 0: // empty
341  break;
342  case 1: // ground
343  break;
344  case 2: // stone
345  renderPolyhedron(CUBE, cube.getColor().getColor(), gl);
346  break;
347  case 3: // rock
348  renderPolyhedron(ROCK, cube.getColor().getColor(), gl);
349  break;
350  }
351  }
352 
353  private void renderPolyhedron(Polyhedron poly, Color base, GL2 gl) {
354  GLObjectBuffer.get(poly).render(base, gl);
355  }
356 }
LinkedList< Entrance > getEntrances()
Definition: World.java:697
LinkedList< Robot > getRobots()
Definition: World.java:701
TreeMap< Coordinate, Column > getColumns()
Definition: World.java:693
void moveCamera(double dx, double dy, double dz)
Definition: Camera.java:37
void rotateCamera(double rx, double rz)
Definition: Camera.java:42
void setCameraRotationZ(double cameraRotationZ)
Definition: Camera.java:34
static synchronized void clear(GL gl)
static synchronized GLTextureBuffer get(Material m, GL gl)
static synchronized void clear(GL gl)
void reshape(GLAutoDrawable glad, int x, int y, int width, int height)
Impressum