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
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
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
@@ -17,6 +17,7 @@ Controls for using are
* ``↓`` rotate camera downwards
* ``→`` rotate camera right
* ``←`` 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;
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;
protected Shader shader;
protected final List<Triangle> faces;
protected final List<SubGeometry> subGeometry;
private final StopWatch stopWatch;
protected Shader shader;
protected final List<Triangle> faces;
protected final List<SubGeometry> subGeometry;
private Matrix4f transformation;
private Camera camera;
private Matrix4f transformation;
private Camera camera;
private float[] floatArray;
private int vaoId;
private float[] floatArray;
private int vaoId;
public GraphicalObject(final Shader shader, final Camera camera) {
this.shader = shader;
this.subGeometry = new LinkedList<>();
this.faces = new LinkedList<>();
this.floatArray = new float[0];
public GraphicalObject(final Shader shader, final Camera camera) {
this.shader = shader;
this.subGeometry = new LinkedList<>();
this.faces = new LinkedList<>();
this.floatArray = new float[0];
this.transformation = new Matrix4f();
this.camera = camera;
this.stopWatch = new StopWatch();
this.stopWatch.start();
}
this.transformation = new Matrix4f();
this.camera = camera;
this.stopWatch = new StopWatch();
this.stopWatch.start();
}
public void setPosition(final Vector3f pos) {
this.transformation = transformation.setTranslation(pos);
}
public Vector3f getPosition() {
return transformation.getTranslation(new Vector3f());
}
public void setRotation(final float angleX, final float angleY, final float angleZ) {
this.transformation.setRotationXYZ((float) Math.toRadians(angleX), (float) Math.toRadians(angleY),
(float) Math.toRadians(angleZ));
}
public void setPosition(final Vector3f pos) {
this.transformation = transformation.setTranslation(pos);
}
public void rotate(final float angleDeg, final Vector3f axis) {
this.transformation.rotate((float) Math.toRadians(angleDeg), axis.x, axis.y, axis.z);
}
public void setRotation(final float angleX, final float angleY, final float angleZ) {
this.transformation.setRotationXYZ((float) Math.toRadians(angleX), (float) Math.toRadians(angleY),
(float) Math.toRadians(angleZ));
}
public void scale(final Vector3f factor) {
this.transformation.scale(factor.x, factor.y, factor.z);
}
public void rotate(final float angleDeg, final Vector3f axis) {
this.transformation.rotate((float) Math.toRadians(angleDeg), axis.x, axis.y, axis.z);
}
public void translate(final Vector3f vec) {
this.transformation.translate(vec.x, vec.y, vec.z);
}
public void scale(final Vector3f factor) {
this.transformation.scale(factor.x, factor.y, factor.z);
}
public void generateFaces() {
faces.clear();
for (final SubGeometry sub : subGeometry) {
faces.addAll(sub.getTriangles());
}
}
public void translate(final Vector3f vec) {
this.transformation.translate(vec.x, vec.y, vec.z);
}
public void setCamera(final Camera cam) {
this.camera = cam;
}
public void generateFaces() {
faces.clear();
for (final SubGeometry sub : subGeometry) {
faces.addAll(sub.getTriangles());
}
}
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;
}
public void setCamera(final Camera cam) {
this.camera = cam;
}
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
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];
public void init(final GL3 gl) {
// A simple temporary integer buffer to exchange data with the GPU
final int vertexBufferObject[] = new int[1];
// Create a buffer object in the GPU memory
gl.glGenBuffers(1, IntBuffer.wrap(vertexBufferObject));
// A simple temporary integer buffer to exchange data with the GPU
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];
// Bind our VAO to make it the active VAO in the OpenGL context
gl.glBindVertexArray(vaoId);
{
// 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]);
{
// A simple temporary integer buffer to exchange data with the GPU
final int vertexBufferObject[] = new int[1];
// Create a buffer object in the GPU memory
gl.glGenBuffers(1, IntBuffer.wrap(vertexBufferObject));
final FloatBuffer buffer = GLBuffers.newDirectFloatBuffer(this.getFloatArray());
// allocate the required memory on the GPU and copy the data
// from our vertexData-buffer into that memory
// Bind our VAO to make it the active VAO in the OpenGL context
gl.glBindVertexArray(vaoId);
{
// 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,
GL3.GL_STATIC_DRAW);
final FloatBuffer buffer = GLBuffers.newDirectFloatBuffer(this.getFloatArray());
// 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);
}
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
}
gl.glBindVertexArray(vaoId);
intiVertexAttributes(gl);
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);
gl.glDrawArrays(GraphicalObject.DRAWING_MODE, 0, this.faces.size() * 3);
displayParametersANDUniforms(gl);
}
gl.glUseProgram(0);
gl.glFlush();
gl.glBindVertexArray(vaoId);
gl.glDrawArrays(GraphicalObject.DRAWING_MODE, 0, this.faces.size() * 3);
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) {
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 void preDisplay(final GL3 gl) {
}
public Camera getCamera() {
return camera;
}
public void displayParametersANDUniforms(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 Shader getShader() {
return shader;
}
public Camera getCamera() {
return camera;
}
public final void update() {
stopWatch.stop();
updateLogic(stopWatch);
stopWatch.reset();
stopWatch.start();
}
public Shader getShader() {
return shader;
}
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;
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) {
super(width, height, title);
camera.setPosition(new Vector3f(0.0f, 8.0f, 0.0f));
camera.lookAt(new Vector3f(0.0f, 0.0f, 0.0f));
final Universe uv = new Universe();
public SolarSystemScene(final int width, final int height, final String title) {
super(width, height, title);
camera.setPosition(new Vector3f(0.0f, 8.0f, 0.0f));
camera.lookAt(new Vector3f(0.0f, 0.0f, 0.0f));
final Universe uv = new Universe();
this.getCanvas().addKeyListener(new UniverseKeyListener(uv));
// Mercury
this.addGraphicalObject(new Planet(
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f),
0.467f,
0.308f),
uv,
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));
final UniverseKeyListener universeKeyListener = new UniverseKeyListener(uv, camera);
this.getCanvas().addKeyListener(universeKeyListener);
// Mercury
final Planet mercury = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 0.467f, 0.308f), uv, 0.38f,
"spheres/mercury.jpg", 115.88f, 57.94f);
this.addGraphicalObject(mercury);
universeKeyListener.setKeySphericalSpaceObject(mercury, 2);
// Earth
final Planet earth = new Planet(
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f),
0.98f,
1.02f),
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));
// Venus
final Planet venus = 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);
this.addGraphicalObject(venus);
universeKeyListener.setKeySphericalSpaceObject(venus, 3);
// Jupiter
this.addGraphicalObject(new Planet(
new Orbit(new Vector3f(0.0f, 0.0f, 0.0f),
5.2f - 3.3f,
4.9f - 3.3f),
uv,
12.0f / 12f,
"spheres/jupiter.jpg",
4330.0f,
0.4132f));
// Saturn
this.addGraphicalObject(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));
// 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"));
// Earth
final Planet earth = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 0.98f, 1.02f), uv, 1.0f,
"spheres/earth.jpg", 365.256f, 1.0f);
this.addGraphicalObject(earth);
universeKeyListener.setKeySphericalSpaceObject(earth, 4);
// 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
final Planet mars = 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);
this.addGraphicalObject(mars);
universeKeyListener.setKeySphericalSpaceObject(mars, 5);
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"});
}
// Jupiter
final Planet jupiter = new Planet(new Orbit(new Vector3f(0.0f, 0.0f, 0.0f), 5.2f - 3.3f, 4.9f - 3.3f), uv,
12.0f / 12f, "spheres/jupiter.jpg", 4330.0f, 0.4132f);
this.addGraphicalObject(jupiter);
universeKeyListener.setKeySphericalSpaceObject(jupiter, 6);
// 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.KeyListener;
import org.kuchelmeister.engine.camera.Camera;
import org.kuchelmeister.solarsystem.geometry.SphericalSpaceObject;
import org.kuchelmeister.solarsystem.geometry.Universe;
public class UniverseKeyListener implements KeyListener {
Universe universe;
Universe universe;
Camera camera;
SphericalSpaceObject[] spaceObjects;
public UniverseKeyListener(final Universe universe) {
this.universe = universe;
}
public UniverseKeyListener(final Universe universe, final Camera camera) {
this.universe = universe;
this.spaceObjects = new SphericalSpaceObject[10];
this.camera = camera;
}
@Override
public void keyPressed(final KeyEvent e) {
final float stepsPosition = 0.1f;
final float stepsRotation = 10.0f;
if (!universe.isPaused()) {
if (e.getKeyCode() == KeyEvent.VK_PLUS) {
// Faster time scale
universe.doubleTimeScale();
System.out.println("Time Scale Doubled to: " + universe.getTimeScale());
} else if (e.getKeyCode() == KeyEvent.VK_MINUS) {
// Slower timescale
universe.halfTimeScale();
System.out.println("Time scale halfed to: " + universe.getTimeScale());
} else if (e.getKeyCode() == KeyEvent.VK_R) {
// Reverse timescale
universe.reverseTime();
System.out.println("Time scale halfed to: " + universe.getTimeScale());
}
}
}
@Override
public void keyPressed(final KeyEvent e) {
final float stepsPosition = 0.1f;
final float stepsRotation = 10.0f;
if (!universe.isPaused()) {
if (e.getKeyCode() == KeyEvent.VK_PLUS) {
// Faster time scale
universe.doubleTimeScale();
System.out.println("Time Scale Doubled to: " + universe.getTimeScale());
} else if (e.getKeyCode() == KeyEvent.VK_MINUS) {
// Slower timescale
universe.halfTimeScale();
System.out.println("Time scale halfed to: " + universe.getTimeScale());
} else if (e.getKeyCode() == KeyEvent.VK_R) {
// Reverse timescale
universe.reverseTime();
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 keyReleased(final KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_SPACE) {
// Pause
universe.tooglePause();
System.out.println("Toggledpause:" + universe.getTimeScale());
}
}
public void setKeySphericalSpaceObject(final SphericalSpaceObject object, final int numberKey) {
assert 0 <= numberKey && numberKey <= 9;
spaceObjects[numberKey] = object;
}
@Override
public void keyTyped(final KeyEvent e) {
@Override
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) {
}
}