diff options
author | Dmitrii Morozov <snoopdesigns@gmail.com> | 2025-01-07 01:10:37 +0100 |
---|---|---|
committer | Dmitrii Morozov <snoopdesigns@gmail.com> | 2025-01-07 01:10:37 +0100 |
commit | 62687c67eae8c2f26ca31d2bfac4296b61f57e7f (patch) | |
tree | 3608e3cce524d8a292ad6f52b2ed980012e07f0c /core/src/main/java/org/snoopdesigns | |
parent | 783631a87294d126b5c96549d7674682c926ed39 (diff) |
Diffstat (limited to 'core/src/main/java/org/snoopdesigns')
-rw-r--r-- | core/src/main/java/org/snoopdesigns/endless/screen/main/MainScreen.java | 7 | ||||
-rw-r--r-- | core/src/main/java/org/snoopdesigns/endless/screen/main/StarFieldDebug.java | 199 |
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; + } +} |