Compare commits

4 Commits
1.0 ... master

Author SHA1 Message Date
Hannes Kuchelmeister
dbc7fda722 Update README.md
added new keybindings to readme
2018-05-10 13:39:53 +02:00
Hannes
33acc16389 added keybindings to allow jumping to planets 2018-05-10 13:28:22 +02:00
Hannes
1ac7cbcefa converted to eclipse project 2018-05-10 13:23:35 +02:00
Hannes Kuchelmeister
78fc4f8cd7 Update README.md 2018-03-27 21:21:02 +02:00
7 changed files with 292 additions and 267 deletions

10
.classpath Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Apache commons-lan- 3.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/JOML"/>
<classpathentry kind="lib" path="C:/Users/Hannes/EclipseInstances/oxygen_hobby/lib/jogamp-all-platforms/jar/gluegen-rt.jar"/>
<classpathentry kind="lib" path="C:/Users/Hannes/EclipseInstances/oxygen_hobby/lib/jogamp-all-platforms/jar/jogl-all.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

12
.gitignore vendored
View File

@@ -20,3 +20,15 @@
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid* hs_err_pid*
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
.recommenders

17
.project Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>OpenGL-SolarSystem</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -1,7 +1,7 @@
# OpenGL: Solar System Visualization # OpenGL: Solar System Visualization
This project was created for an assignment in the course 3d-graphics at Linnaeus University. The visualization is written using directly OpenGL APIs which are exposed by JOGL. This project was created for an assignment in the course 3d-graphics at Linnaeus University. The visualization is written using directly OpenGL APIs which are exposed by JOGL.
The size of planets and their orbits is not to scale. The size of planets and their orbits is not to scale but the rotation and speed of planets is.
Controls for using are Controls for using are
@@ -17,6 +17,7 @@ Controls for using are
* ``↓`` rotate camera downwards * ``↓`` rotate camera downwards
* ``→`` rotate camera right * ``→`` rotate camera right
* ``←`` rotate camera left * ``←`` rotate camera left
* ``1`` to ``9`` jump to celestial body (``1`` - Sun, ``2`` - Mercury, ``9`` - Neptun)

View File

@@ -19,175 +19,179 @@ import com.jogamp.opengl.util.GLBuffers;
import shader.Shader; import shader.Shader;
public abstract class GraphicalObject { public abstract class GraphicalObject {
public static final int DRAWING_MODE = GL3.GL_TRIANGLES; public static final int DRAWING_MODE = GL3.GL_TRIANGLES;
private final StopWatch stopWatch; private final StopWatch stopWatch;
protected Shader shader; protected Shader shader;
protected final List<Triangle> faces; protected final List<Triangle> faces;
protected final List<SubGeometry> subGeometry; protected final List<SubGeometry> subGeometry;
private Matrix4f transformation; private Matrix4f transformation;
private Camera camera; private Camera camera;
private float[] floatArray; private float[] floatArray;
private int vaoId; private int vaoId;
public GraphicalObject(final Shader shader, final Camera camera) { public GraphicalObject(final Shader shader, final Camera camera) {
this.shader = shader; this.shader = shader;
this.subGeometry = new LinkedList<>(); this.subGeometry = new LinkedList<>();
this.faces = new LinkedList<>(); this.faces = new LinkedList<>();
this.floatArray = new float[0]; this.floatArray = new float[0];
this.transformation = new Matrix4f(); this.transformation = new Matrix4f();
this.camera = camera; this.camera = camera;
this.stopWatch = new StopWatch(); this.stopWatch = new StopWatch();
this.stopWatch.start(); this.stopWatch.start();
} }
public void setPosition(final Vector3f pos) { public Vector3f getPosition() {
this.transformation = transformation.setTranslation(pos); return transformation.getTranslation(new Vector3f());
} }
public void setRotation(final float angleX, final float angleY, final float angleZ) { public void setPosition(final Vector3f pos) {
this.transformation.setRotationXYZ((float) Math.toRadians(angleX), (float) Math.toRadians(angleY), this.transformation = transformation.setTranslation(pos);
(float) Math.toRadians(angleZ)); }
}
public void rotate(final float angleDeg, final Vector3f axis) { public void setRotation(final float angleX, final float angleY, final float angleZ) {
this.transformation.rotate((float) Math.toRadians(angleDeg), axis.x, axis.y, axis.z); this.transformation.setRotationXYZ((float) Math.toRadians(angleX), (float) Math.toRadians(angleY),
} (float) Math.toRadians(angleZ));
}
public void scale(final Vector3f factor) { public void rotate(final float angleDeg, final Vector3f axis) {
this.transformation.scale(factor.x, factor.y, factor.z); this.transformation.rotate((float) Math.toRadians(angleDeg), axis.x, axis.y, axis.z);
} }
public void translate(final Vector3f vec) { public void scale(final Vector3f factor) {
this.transformation.translate(vec.x, vec.y, vec.z); this.transformation.scale(factor.x, factor.y, factor.z);
} }
public void generateFaces() { public void translate(final Vector3f vec) {
faces.clear(); this.transformation.translate(vec.x, vec.y, vec.z);
for (final SubGeometry sub : subGeometry) { }
faces.addAll(sub.getTriangles());
}
}
public void setCamera(final Camera cam) { public void generateFaces() {
this.camera = cam; faces.clear();
} for (final SubGeometry sub : subGeometry) {
faces.addAll(sub.getTriangles());
}
}
public float[] getFloatArray() { public void setCamera(final Camera cam) {
if (this.floatArray.length <= 0) { this.camera = cam;
generateFaces(); }
floatArray = new float[0];
for (final Triangle triangle : faces) {
floatArray = ArrayUtils.addAll(floatArray, triangle.getVertices());
}
}
return floatArray;
}
public void init(final GL3 gl) { public float[] getFloatArray() {
if (this.floatArray.length <= 0) {
generateFaces();
floatArray = new float[0];
for (final Triangle triangle : faces) {
floatArray = ArrayUtils.addAll(floatArray, triangle.getVertices());
}
}
return floatArray;
}
// A simple temporary integer buffer to exchange data with the GPU public void init(final GL3 gl) {
final int vertexArrayObject[] = new int[1];
// Create a VAO -- Vertex Array Object -- in the GPU's memory
gl.glGenVertexArrays(1, IntBuffer.wrap(vertexArrayObject));
vaoId = vertexArrayObject[0];
// A simple temporary integer buffer to exchange data with the GPU // A simple temporary integer buffer to exchange data with the GPU
final int vertexBufferObject[] = new int[1]; final int vertexArrayObject[] = new int[1];
// Create a buffer object in the GPU memory // Create a VAO -- Vertex Array Object -- in the GPU's memory
gl.glGenBuffers(1, IntBuffer.wrap(vertexBufferObject)); gl.glGenVertexArrays(1, IntBuffer.wrap(vertexArrayObject));
vaoId = vertexArrayObject[0];
// Bind our VAO to make it the active VAO in the OpenGL context // A simple temporary integer buffer to exchange data with the GPU
gl.glBindVertexArray(vaoId); final int vertexBufferObject[] = new int[1];
{ // Create a buffer object in the GPU memory
// Make the buffer the active array buffer: gl.glGenBuffers(1, IntBuffer.wrap(vertexBufferObject));
// e.g. bind the newly created buffer object to the GL_ARRAY_BUFFER
// context
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vertexBufferObject[0]);
{
final FloatBuffer buffer = GLBuffers.newDirectFloatBuffer(this.getFloatArray()); // Bind our VAO to make it the active VAO in the OpenGL context
// allocate the required memory on the GPU and copy the data gl.glBindVertexArray(vaoId);
// from our vertexData-buffer into that memory {
// Make the buffer the active array buffer:
// e.g. bind the newly created buffer object to the GL_ARRAY_BUFFER
// context
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, vertexBufferObject[0]);
{
gl.glBufferData(GL3.GL_ARRAY_BUFFER, this.getFloatArray().length * Buffers.SIZEOF_FLOAT, buffer, final FloatBuffer buffer = GLBuffers.newDirectFloatBuffer(this.getFloatArray());
GL3.GL_STATIC_DRAW); // allocate the required memory on the GPU and copy the data
// from our vertexData-buffer into that memory
intiVertexAttributes(gl); gl.glBufferData(GL3.GL_ARRAY_BUFFER, this.getFloatArray().length * Buffers.SIZEOF_FLOAT, buffer,
GL3.GL_STATIC_DRAW);
} intiVertexAttributes(gl);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
}
gl.glBindVertexArray(vaoId);
shader.compile(gl); }
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
}
gl.glBindVertexArray(vaoId);
} shader.compile(gl);
public void setShader() { }
} public void setShader() {
public abstract void intiVertexAttributes(final GL3 gl); }
public void display(final GL3 gl) { public abstract void intiVertexAttributes(final GL3 gl);
preDisplay(gl); public void display(final GL3 gl) {
gl.glUseProgram(shader.getProgramId()); preDisplay(gl);
{
displayParametersANDUniforms(gl); gl.glUseProgram(shader.getProgramId());
{
gl.glBindVertexArray(vaoId); displayParametersANDUniforms(gl);
gl.glDrawArrays(GraphicalObject.DRAWING_MODE, 0, this.faces.size() * 3);
} gl.glBindVertexArray(vaoId);
gl.glUseProgram(0); gl.glDrawArrays(GraphicalObject.DRAWING_MODE, 0, this.faces.size() * 3);
gl.glFlush();
afterDisplay(gl); }
} gl.glUseProgram(0);
gl.glFlush();
public void afterDisplay(final GL3 gl) { afterDisplay(gl);
} }
public void preDisplay(final GL3 gl) { public void afterDisplay(final GL3 gl) {
} }
public void displayParametersANDUniforms(final GL3 gl) { public void preDisplay(final GL3 gl) {
final int transformationLocation = gl.glGetUniformLocation(this.getShader().getProgramId(), "ModelMatrix"); }
if (transformationLocation != -1) {
final float[] mat = new float[16];
gl.glUniformMatrix4fv(transformationLocation, 1, false, transformation.get(mat), 0);
}
final int cameraLocation = gl.glGetUniformLocation(this.getShader().getProgramId(), "CameraMatrix");
if (transformationLocation != -1) {
final float[] mat = new float[16];
gl.glUniformMatrix4fv(cameraLocation, 1, false, getCamera().getMatrix().get(mat), 0);
}
}
public Camera getCamera() { public void displayParametersANDUniforms(final GL3 gl) {
return camera; final int transformationLocation = gl.glGetUniformLocation(this.getShader().getProgramId(), "ModelMatrix");
} if (transformationLocation != -1) {
final float[] mat = new float[16];
gl.glUniformMatrix4fv(transformationLocation, 1, false, transformation.get(mat), 0);
}
final int cameraLocation = gl.glGetUniformLocation(this.getShader().getProgramId(), "CameraMatrix");
if (transformationLocation != -1) {
final float[] mat = new float[16];
gl.glUniformMatrix4fv(cameraLocation, 1, false, getCamera().getMatrix().get(mat), 0);
}
}
public Shader getShader() { public Camera getCamera() {
return shader; return camera;
} }
public final void update() { public Shader getShader() {
stopWatch.stop(); return shader;
updateLogic(stopWatch); }
stopWatch.reset();
stopWatch.start();
}
public void updateLogic(final StopWatch sWatch) { public final void update() {
stopWatch.stop();
updateLogic(stopWatch);
stopWatch.reset();
stopWatch.start();
}
} public void updateLogic(final StopWatch sWatch) {
}
} }

View File

@@ -10,112 +10,72 @@ import org.kuchelmeister.solarsystem.geometry.Universe;
import org.kuchelmeister.solarsystem.input.UniverseKeyListener; import org.kuchelmeister.solarsystem.input.UniverseKeyListener;
public class SolarSystemScene extends Scene { public class SolarSystemScene extends Scene {
private static final long serialVersionUID = 3875025579198640196L; private static final long serialVersionUID = 3875025579198640196L;
public SolarSystemScene(final int width, final int height, final String title) { public SolarSystemScene(final int width, final int height, final String title) {
super(width, height, title); super(width, height, title);
camera.setPosition(new Vector3f(0.0f, 8.0f, 0.0f)); camera.setPosition(new Vector3f(0.0f, 8.0f, 0.0f));
camera.lookAt(new Vector3f(0.0f, 0.0f, 0.0f)); camera.lookAt(new Vector3f(0.0f, 0.0f, 0.0f));
final Universe uv = new Universe(); final Universe uv = new Universe();
this.getCanvas().addKeyListener(new UniverseKeyListener(uv)); final UniverseKeyListener universeKeyListener = new UniverseKeyListener(uv, camera);
// Mercury this.getCanvas().addKeyListener(universeKeyListener);
this.addGraphicalObject(new Planet( // Mercury
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), final Planet mercury = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 0.467f, 0.308f), uv, 0.38f,
0.467f, "spheres/mercury.jpg", 115.88f, 57.94f);
0.308f), this.addGraphicalObject(mercury);
uv, universeKeyListener.setKeySphericalSpaceObject(mercury, 2);
0.38f,
"spheres/mercury.jpg", 115.88f, 57.94f));
// Venus
this.addGraphicalObject(new Planet(
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f),
0.723f,
0.718f),
uv,
0.38f,
"spheres/venus.jpg", 224.701f, 243.0f));
// Earth // Venus
final Planet earth = new Planet( final Planet venus = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 0.723f, 0.718f), uv, 0.38f,
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), "spheres/venus.jpg", 224.701f, 243.0f);
0.98f, this.addGraphicalObject(venus);
1.02f), universeKeyListener.setKeySphericalSpaceObject(venus, 3);
uv,
1.0f,
"spheres/earth.jpg", 365.256f, 1.0f);
this.addGraphicalObject(earth);
// Moon
this.addGraphicalObject(new Moon(
earth,
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f),
2 * Universe.EARTH_RADIUS,
2 * Universe.EARTH_RADIUS),
uv,
0.3f,
"spheres/moon.jpg",
29.530589f,
29.530589f));
// Mars
this.addGraphicalObject(new Planet(
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f),
1.5f,
1.4f),
uv,
0.2657f * 2,
"spheres/mars.jpg",
686.971f,
1.0275f));
// Jupiter // Earth
this.addGraphicalObject(new Planet( final Planet earth = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 0.98f, 1.02f), uv, 1.0f,
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), "spheres/earth.jpg", 365.256f, 1.0f);
5.2f - 3.3f, this.addGraphicalObject(earth);
4.9f - 3.3f), universeKeyListener.setKeySphericalSpaceObject(earth, 4);
uv, // Moon
12.0f / 12f, this.addGraphicalObject(new Moon(earth,
"spheres/jupiter.jpg", new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 2 * Universe.EARTH_RADIUS, 2 * Universe.EARTH_RADIUS), uv,
4330.0f, 0.3f, "spheres/moon.jpg", 29.530589f, 29.530589f));
0.4132f)); // Mars
// Saturn final Planet mars = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 1.5f, 1.4f), uv, 0.2657f * 2,
this.addGraphicalObject(new Planet( "spheres/mars.jpg", 686.971f, 1.0275f);
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), this.addGraphicalObject(mars);
9.5f - 7f, universeKeyListener.setKeySphericalSpaceObject(mars, 5);
9f - 7f),
uv,
10.0f / 10f,
"spheres/saturn.jpg",
10751.805f,
0.45f));
// Uranus
this.addGraphicalObject(new Planet(
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f),
19f - 16f,
18f - 16f),
uv,
4.0f / 6,
"spheres/uranus.jpg",
30660.0f,
0.72f));
// Neptun
this.addGraphicalObject(new Planet(
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f),
30f - 26.0f,
29f - 26.0f),
uv,
3.88f / 6,
"spheres/neptune.jpg",
30660.0f,
0.673f));
this.addGraphicalObject(new Sun(new Vector3f(0.0f, 0.0f, 0.0f), 3.0f, "spheres/sun.jpg"));
this.setSkybox(new String[] { // Jupiter
"skybox/space_left_0.png", final Planet jupiter = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 5.2f - 3.3f, 4.9f - 3.3f), uv,
"skybox/space_right_1.png", 12.0f / 12f, "spheres/jupiter.jpg", 4330.0f, 0.4132f);
"skybox/space_down_2.png", this.addGraphicalObject(jupiter);
"skybox/space_up_3.png", universeKeyListener.setKeySphericalSpaceObject(jupiter, 6);
"skybox/space_front_4.png",
"skybox/space_back_5.png"});
}
// Saturn
final Planet saturn = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 9.5f - 7f, 9f - 7f), uv, 10.0f / 10f,
"spheres/saturn.jpg", 10751.805f, 0.45f);
this.addGraphicalObject(saturn);
universeKeyListener.setKeySphericalSpaceObject(saturn, 7);
// Uranus
final Planet uranus = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 19f - 16f, 18f - 16f), uv, 4.0f / 6,
"spheres/uranus.jpg", 30660.0f, 0.72f);
this.addGraphicalObject(uranus);
universeKeyListener.setKeySphericalSpaceObject(uranus, 8);
// Neptun
final Planet neptun = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 30f - 26.0f, 29f - 26.0f), uv,
3.88f / 6, "spheres/neptune.jpg", 30660.0f, 0.673f);
this.addGraphicalObject(neptun);
universeKeyListener.setKeySphericalSpaceObject(neptun, 9);
final Sun sun = new Sun(new Vector3f(0.0f, 0.0f, 0.0f), 3.0f, "spheres/sun.jpg");
this.addGraphicalObject(sun);
universeKeyListener.setKeySphericalSpaceObject(sun, 1);
this.setSkybox(new String[] { "skybox/space_left_0.png", "skybox/space_right_1.png", "skybox/space_down_2.png",
"skybox/space_up_3.png", "skybox/space_front_4.png", "skybox/space_back_5.png" });
}
} }

View File

@@ -3,48 +3,69 @@ package org.kuchelmeister.solarsystem.input;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.KeyListener; import java.awt.event.KeyListener;
import org.kuchelmeister.engine.camera.Camera;
import org.kuchelmeister.solarsystem.geometry.SphericalSpaceObject;
import org.kuchelmeister.solarsystem.geometry.Universe; import org.kuchelmeister.solarsystem.geometry.Universe;
public class UniverseKeyListener implements KeyListener { public class UniverseKeyListener implements KeyListener {
Universe universe; Universe universe;
Camera camera;
SphericalSpaceObject[] spaceObjects;
public UniverseKeyListener(final Universe universe) { public UniverseKeyListener(final Universe universe, final Camera camera) {
this.universe = universe; this.universe = universe;
} this.spaceObjects = new SphericalSpaceObject[10];
this.camera = camera;
}
@Override @Override
public void keyPressed(final KeyEvent e) { public void keyPressed(final KeyEvent e) {
final float stepsPosition = 0.1f; final float stepsPosition = 0.1f;
final float stepsRotation = 10.0f; final float stepsRotation = 10.0f;
if (!universe.isPaused()) { if (!universe.isPaused()) {
if (e.getKeyCode() == KeyEvent.VK_PLUS) { if (e.getKeyCode() == KeyEvent.VK_PLUS) {
// Faster time scale // Faster time scale
universe.doubleTimeScale(); universe.doubleTimeScale();
System.out.println("Time Scale Doubled to: " + universe.getTimeScale()); System.out.println("Time Scale Doubled to: " + universe.getTimeScale());
} else if (e.getKeyCode() == KeyEvent.VK_MINUS) { } else if (e.getKeyCode() == KeyEvent.VK_MINUS) {
// Slower timescale // Slower timescale
universe.halfTimeScale(); universe.halfTimeScale();
System.out.println("Time scale halfed to: " + universe.getTimeScale()); System.out.println("Time scale halfed to: " + universe.getTimeScale());
} else if (e.getKeyCode() == KeyEvent.VK_R) { } else if (e.getKeyCode() == KeyEvent.VK_R) {
// Reverse timescale // Reverse timescale
universe.reverseTime(); universe.reverseTime();
System.out.println("Time scale halfed to: " + universe.getTimeScale()); System.out.println("Time scale halfed to: " + universe.getTimeScale());
} }
} }
} // Jumping to the position
if (KeyEvent.VK_0 <= e.getKeyCode() && e.getKeyCode() <= KeyEvent.VK_9) {
final int position = e.getKeyCode() - KeyEvent.VK_0;
final SphericalSpaceObject sObject = spaceObjects[position];
if (sObject != null) {
// TODO: get position and move camera to that position
// lookingDirection * radius + sObject.getPosition()
this.camera.setPosition(sObject.getPosition());
}
}
}
@Override public void setKeySphericalSpaceObject(final SphericalSpaceObject object, final int numberKey) {
public void keyReleased(final KeyEvent e) { assert 0 <= numberKey && numberKey <= 9;
if (e.getKeyCode() == KeyEvent.VK_SPACE) { spaceObjects[numberKey] = object;
// Pause }
universe.tooglePause();
System.out.println("Toggledpause:" + universe.getTimeScale());
}
}
@Override @Override
public void keyTyped(final KeyEvent e) { public void keyReleased(final KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
// Pause
universe.tooglePause();
System.out.println("Toggledpause:" + universe.getTimeScale());
}
}
} @Override
public void keyTyped(final KeyEvent e) {
}
} }