summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/src/main/java/org/snoopdesigns/endless/screen/main/MainScreen.java7
-rw-r--r--core/src/main/java/org/snoopdesigns/endless/screen/main/StarFieldDebug.java199
2 files changed, 204 insertions, 2 deletions
diff --git a/core/src/main/java/org/snoopdesigns/endless/screen/main/MainScreen.java b/core/src/main/java/org/snoopdesigns/endless/screen/main/MainScreen.java
index ed26ef6..a219b32 100644
--- a/core/src/main/java/org/snoopdesigns/endless/screen/main/MainScreen.java
+++ b/core/src/main/java/org/snoopdesigns/endless/screen/main/MainScreen.java
@@ -19,6 +19,7 @@ public class MainScreen implements Screen {
private float screenHeight;
private Renderable starField;
+ private Renderable starFieldDebug;
private Renderable cameraDebug;
private Renderable playerShip;
private OrthographicCamera camera;
@@ -44,7 +45,7 @@ public class MainScreen implements Screen {
camera.viewportWidth *= scale;
camera.viewportHeight = camera.viewportWidth *
(screenHeight / screenWidth);
- normalizeCamera();
+ //normalizeCamera();
return true;
}
@@ -58,6 +59,7 @@ public class MainScreen implements Screen {
});
starField = new StarField();
+ starFieldDebug = new StarFieldDebug();
cameraDebug = new CameraDebug();
playerShip = new PlayerShip();
@@ -71,7 +73,8 @@ public class MainScreen implements Screen {
ScreenUtils.clear(Color.BLACK);
- starField.render(delta, renderContext);
+ //starField.render(delta, renderContext);
+ starFieldDebug.render(delta, renderContext);
cameraDebug.render(delta, renderContext);
playerShip.render(delta, renderContext);
}
diff --git a/core/src/main/java/org/snoopdesigns/endless/screen/main/StarFieldDebug.java b/core/src/main/java/org/snoopdesigns/endless/screen/main/StarFieldDebug.java
new file mode 100644
index 0000000..a79e591
--- /dev/null
+++ b/core/src/main/java/org/snoopdesigns/endless/screen/main/StarFieldDebug.java
@@ -0,0 +1,199 @@
+package org.snoopdesigns.endless.screen.main;
+
+import com.badlogic.gdx.graphics.GL30;
+import com.badlogic.gdx.graphics.Mesh;
+import com.badlogic.gdx.graphics.VertexAttribute;
+import com.badlogic.gdx.graphics.VertexAttributes;
+import com.badlogic.gdx.graphics.glutils.ShaderProgram;
+import com.badlogic.gdx.math.Vector2;
+import org.snoopdesigns.endless.render.RenderContext;
+import org.snoopdesigns.endless.render.Renderable;
+
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.IntStream;
+
+public class StarFieldDebug implements Renderable {
+
+ private static final Random rand = new SecureRandom();
+ private static final double PI = Math.PI;
+ private static final int TILE_SIZE = 256;
+ private static final int MAX_OFFSET = 50;
+ private static final int MAX_OFFSET_DISTANCE = MAX_OFFSET * MAX_OFFSET;
+ private static final int MIN_OFFSET_DISTANCE = MAX_OFFSET_DISTANCE / 4;
+ private static final float[] STAR_CORNERS = {
+ 0.0f * (float) PI,
+ 0.5f * (float) PI,
+ 1.5f * (float) PI,
+ 0.5f * (float) PI,
+ 1.5f * (float) PI,
+ 1.0f * (float) PI
+ };
+
+ private final ShaderProgram shader;
+ private final Mesh mesh;
+
+ private static final String VERTEX_SHADER = """
+ #version 130
+ in vec2 offset;
+ in float size;
+ in float corner;
+ uniform mat4 u_projTrans;
+ void main() {
+ vec2 coord = vec2(sin(corner), cos(corner));
+ vec4 pos = vec4(offset.x + coord.x, offset.y + coord.y, 0, 1);
+ gl_Position = u_projTrans * pos;
+ }
+ """;
+ private static final String FRAGMENT_SHADER = """
+ void main() {
+ gl_FragColor = vec4(1, 1, 1, 1);
+ }
+ """;
+
+ public StarFieldDebug() {
+ shader = new ShaderProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+ System.out.println("Shader compiled: " + shader.isCompiled());
+ System.out.println(shader.getLog());
+
+ final var vertices = createStarVertices();
+
+ mesh = new Mesh(true, 6 * 16384, 0,
+ new VertexAttribute(VertexAttributes.Usage.Generic, 2, "offset"),
+ new VertexAttribute(VertexAttributes.Usage.Generic, 1, "size"),
+ new VertexAttribute(VertexAttributes.Usage.Generic, 1, "corner"));
+ final var mul = 100;
+ mesh.setVertices(vertices);
+ /*mesh.setVertices(new float[] {
+ mul * -0.5f, mul * -0.5f, 0f, 1f,
+ mul * 0.5f, mul * -0.5f, 0f, 1f,
+ mul * 0.5f, mul * 0.5f, 0f, 1f,
+ mul * -0.5f, mul * 0.5f, 0f, 1f
+ });*/
+ //mesh.setIndices(new short[] {0, 1, 2, 2, 3, 0});
+ }
+
+ @Override
+ public void render(float delta, RenderContext renderContext) {
+ shader.bind();
+ shader.setUniformMatrix("u_projTrans", renderContext.getCamera().combined);
+ mesh.render(shader, GL30.GL_TRIANGLES);
+ }
+
+ public static void main(String[] args) {
+ final var starVertices = createStarVertices();
+ }
+
+ public static float[] createStarVertices() {
+ // Input values
+ final int width = 4096;
+ final int stars = 16384;
+
+ final int widthMod = width - 1;
+ final int tileCols = width / TILE_SIZE;
+ final List<Integer> tileIndex = new ArrayList<>();
+ IntStream.range(0, tileCols * tileCols)
+ .forEach(i -> tileIndex.add(0));
+
+ // Generate offset vector
+ // Offset is used to later generate a random point X,Y
+ // Looks like a booblik with small ring of MAX_OFFSET * MAX_OFFSET / 4 till MAX_OFFSET * MAX_OFFSET
+ final List<Vector2> offsets = new ArrayList<>();
+ for (int x = -MAX_OFFSET; x <= MAX_OFFSET; x++) {
+ for (int y = -MAX_OFFSET; y <= MAX_OFFSET; y++) {
+ int d = x * x + y * y;
+ if (d < MIN_OFFSET_DISTANCE || d > MAX_OFFSET_DISTANCE) {
+ continue;
+ }
+ offsets.add(new Vector2(x, y));
+ }
+ }
+
+ // Generate random points in a temporary list
+ final List<Vector2> temp = new ArrayList<>();
+
+ int x = rand.nextInt(width);
+ int y = rand.nextInt(width);
+
+ for (int i = 0; i < stars; i++) {
+ for (int j = 0; j < 10; j++) { // shake original random coordinates 10 times with random offsets up to 50 in any direction
+ int index = rand.nextInt(offsets.size());
+ final Vector2 offset = offsets.get(index);
+ final int incrementX = (int) offset.x;
+ final int incrementY = (int) offset.y;
+ x += incrementX;
+ y += incrementY;
+ x &= widthMod;
+ y &= widthMod;
+ }
+ temp.add(new Vector2(x, y));
+
+ // Increment counter in tile index to which generated point ended
+ int index = (x / TILE_SIZE) + (y / TILE_SIZE) * tileCols;
+ tileIndex.set(index, tileIndex.get(index) + 1);
+ }
+
+ // Accumulate item counts in tileIndex
+ tileIndex.add(0, 0);
+ tileIndex.remove(tileIndex.size() - 1);
+ for (int i = 1; i < tileIndex.size(); i++) {
+ tileIndex.set(i, tileIndex.get(i) + tileIndex.get(i - 1));
+ }
+
+ class StarPoint {
+ float x;
+ float y;
+ float size;
+ float corner;
+ }
+ // Each star consists of six vertices, each with four data elements
+ final List<StarPoint> data = new ArrayList<>(6 * stars);
+ IntStream.range(0, 6 * stars)
+ .forEach(i -> data.add(null));
+ final Iterator<Vector2> tempIterator = temp.iterator();
+
+ while (tempIterator.hasNext()) {
+ // Get the x and y coordinates
+ final var randomPoint = tempIterator.next();
+ x = (int) randomPoint.x;
+ y = (int) randomPoint.y;
+ int index = (x / TILE_SIZE) + (y / TILE_SIZE) * tileCols;
+
+ // Randomize sub-pixel position, size, and brightness
+ int randomValue = rand.nextInt(4096);
+ float fx = (x & (TILE_SIZE - 1)) + (randomValue & 15) * 0.0625f;
+ float fy = (y & (TILE_SIZE - 1)) + (randomValue >> 8) * 0.0625f;
+ float size = (((randomValue >> 4) & 15) + 20) * 0.0625f;
+
+ // Fill in the data array
+ int tileStartIndex = tileIndex.get(index);
+ int dataIndex = 6 * tileStartIndex;
+ tileIndex.set(index, tileStartIndex + 1);
+
+ for (final float corner : STAR_CORNERS) {
+ final var star = new StarPoint();
+ star.x = fx;
+ star.y = fy;
+ star.size = size;
+ star.corner = corner;
+ data.set(dataIndex++, star);
+ }
+ }
+
+ // Adjust tile indices for proper referencing
+ tileIndex.add(0, 0);
+
+ float[] result = new float[6 * 4 * stars];
+ for (int i = 0; i < data.size(); i++) {
+ final var star = data.get(i);
+ result[4 * i] = star.x;
+ result[4 * i + 1] = star.y;
+ result[4 * i + 2] = star.size;
+ result[4 * i + 3] = star.corner;
+ }
+ return result;
+ }
+}