diff --git a/core/src/ru/mclord/classic/Block.java b/core/src/ru/mclord/classic/Block.java
index d565945..bb2e6ce 100644
--- a/core/src/ru/mclord/classic/Block.java
+++ b/core/src/ru/mclord/classic/Block.java
@@ -1,21 +1,8 @@
package ru.mclord.classic;
-import com.badlogic.gdx.graphics.GL20;
-import com.badlogic.gdx.graphics.Pixmap;
-import com.badlogic.gdx.graphics.Texture;
-import com.badlogic.gdx.graphics.g3d.Material;
import com.badlogic.gdx.graphics.g3d.Model;
-import com.badlogic.gdx.graphics.g3d.ModelInstance;
-import com.badlogic.gdx.graphics.g3d.attributes.BlendingAttribute;
-import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
-import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.utils.Disposable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
public class Block implements Disposable {
public interface PermissionChecker {
boolean doIHaveThisPermission();
@@ -45,9 +32,6 @@ public boolean doIHaveThisPermission() {
}
}
- private static final BlendingAttribute ALPHA =
- new BlendingAttribute(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
-
// All of these fields can be directly used by the
// game while plugins will be required to use getters
/* package-private */ final short id;
@@ -129,90 +113,15 @@ public void initGraphics() {
if (model != null) return;
TextureManager manager = TextureManager.getInstance();
- ModelBuilder modelBuilder = new ModelBuilder();
- modelBuilder.begin();
- modelBuilder.node();
-
- modelBuilder.part(
- Helper.FRONT_SIDE_NAME,
- GL20.GL_TRIANGLES,
- Helper.ATTR,
- new Material(TextureAttribute.createDiffuse(manager
- .rotate90Texture(manager.getTexture(frontTextureId), false)))
- ).rect(-0.5f, -0.5f, -0.5f,
- -0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- 0f, 0f, -0.5f
- );
- modelBuilder.part(
- Helper.BACK_SIDE_NAME,
- GL20.GL_TRIANGLES,
- Helper.ATTR,
- new Material(TextureAttribute.createDiffuse(manager
- .rotate90Texture(manager.getTexture(backTextureId), true)))
- ).rect(-0.5f, 0.5f, 0.5f,
- -0.5f, -0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- 0f, 0f, 0.5f
+ model = Helper.constructBlock(0.5f,
+ manager.getTexture(frontTextureId),
+ manager.getTexture(backTextureId),
+ manager.getTexture(bottomTextureId),
+ manager.getTexture(topTextureId),
+ manager.getTexture(leftTextureId),
+ manager.getTexture(rightTextureId)
);
-
- modelBuilder.part(
- Helper.BOTTOM_SIDE_NAME,
- GL20.GL_TRIANGLES,
- Helper.ATTR,
- new Material(TextureAttribute
- .createDiffuse(manager.getTexture(bottomTextureId)))
- ).rect(-0.5f, -0.5f, 0.5f,
- -0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, -0.5f,
- 0.5f, -0.5f, 0.5f,
- 0f, -0.5f, 0f
- );
-
- modelBuilder.part(
- Helper.TOP_SIDE_NAME,
- GL20.GL_TRIANGLES,
- Helper.ATTR,
- new Material(TextureAttribute
- .createDiffuse(manager.getTexture(topTextureId)))
- ).rect(-0.5f, 0.5f, -0.5f,
- -0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, 0.5f, -0.5f,
- 0f, 0.5f, 0f
- );
-
- modelBuilder.part(
- Helper.LEFT_SIDE_NAME,
- GL20.GL_TRIANGLES,
- Helper.ATTR,
- new Material(TextureAttribute.createDiffuse(manager
- .rotate90Texture(manager.getTexture(leftTextureId), false)))
- ).rect(-0.5f, -0.5f, 0.5f,
- -0.5f, 0.5f, 0.5f,
- -0.5f, 0.5f, -0.5f,
- -0.5f, -0.5f, -0.5f,
- -0.5f, 0f, 0f
- );
-
- modelBuilder.part(
- Helper.RIGHT_SIDE_NAME,
- GL20.GL_TRIANGLES,
- Helper.ATTR,
- new Material(TextureAttribute.createDiffuse(manager
- .rotate90Texture(manager.getTexture(rightTextureId), false)))
- ).rect(0.5f, -0.5f, -0.5f,
- 0.5f, 0.5f, -0.5f,
- 0.5f, 0.5f, 0.5f,
- 0.5f, -0.5f, 0.5f,
- 0.5f, 0f, 0f
- );
- model = modelBuilder.end();
-
- for (Material material : model.materials) material.set(ALPHA);
}
public final Model getModel() {
diff --git a/core/src/ru/mclord/classic/Helper.java b/core/src/ru/mclord/classic/Helper.java
index 70cfa42..63f2907 100644
--- a/core/src/ru/mclord/classic/Helper.java
+++ b/core/src/ru/mclord/classic/Helper.java
@@ -1,6 +1,13 @@
package ru.mclord.classic;
+import com.badlogic.gdx.graphics.GL20;
+import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.VertexAttributes;
+import com.badlogic.gdx.graphics.g3d.Material;
+import com.badlogic.gdx.graphics.g3d.Model;
+import com.badlogic.gdx.graphics.g3d.attributes.BlendingAttribute;
+import com.badlogic.gdx.graphics.g3d.attributes.TextureAttribute;
+import com.badlogic.gdx.graphics.g3d.utils.ModelBuilder;
import com.badlogic.gdx.utils.Disposable;
import com.badlogic.gdx.utils.ScreenUtils;
@@ -12,6 +19,9 @@ public class Helper {
public static final int ATTR = VertexAttributes.Usage.Position |
VertexAttributes.Usage.Normal | VertexAttributes.Usage.TextureCoordinates;
+ private static final BlendingAttribute ALPHA =
+ new BlendingAttribute(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
+
public static final String RIGHT_SIDE_NAME = "right";
public static final String LEFT_SIDE_NAME = "left";
public static final String TOP_SIDE_NAME = "top";
@@ -26,6 +36,112 @@ public static void clearDepthRGB(int r, int g, int b) {
ScreenUtils.clear(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f, true);
}
+ public static boolean containsIgnoreCase(String str, String[] array) {
+ // System.out.println("Searching for \"" + str + "\" in " + Arrays.toString(array));
+ for (String element : array) {
+ if (str.equalsIgnoreCase(element)) return true;
+ }
+
+ return false;
+ }
+
+ public static Model constructBlock(
+ float size,
+ Texture front,
+ Texture back,
+ Texture bottom,
+ Texture top,
+ Texture left,
+ Texture right
+ ) {
+ TextureManager manager = TextureManager.getInstance();
+ ModelBuilder modelBuilder = new ModelBuilder();
+ modelBuilder.begin();
+ modelBuilder.node();
+
+ modelBuilder.part(
+ FRONT_SIDE_NAME,
+ GL20.GL_TRIANGLES,
+ ATTR,
+ new Material(TextureAttribute.createDiffuse(manager
+ .rotate90Texture(front, false)))
+ ).rect(-size, -size, -size,
+ -size, size, -size,
+ size, size, -size,
+ size, -size, -size,
+ 0.0f, 0.0f, -size
+ );
+
+ modelBuilder.part(
+ BACK_SIDE_NAME,
+ GL20.GL_TRIANGLES,
+ ATTR,
+ new Material(TextureAttribute.createDiffuse(manager
+ .rotate90Texture(back, true)))
+ ).rect(-size, size, size,
+ -size, -size, size,
+ size, -size, size,
+ size, size, size,
+ 0.0f, 0.0f, size
+ );
+
+ modelBuilder.part(
+ BOTTOM_SIDE_NAME,
+ GL20.GL_TRIANGLES,
+ ATTR,
+ new Material(TextureAttribute.createDiffuse(bottom))
+ ).rect(-size, -size, size,
+ -size, -size, -size,
+ size, -size, -size,
+ size, -size, size,
+ 0.0f, -size, 0.0f
+ );
+
+ modelBuilder.part(
+ TOP_SIDE_NAME,
+ GL20.GL_TRIANGLES,
+ ATTR,
+ new Material(TextureAttribute.createDiffuse(manager
+ .rotate90Texture(top, false)))
+ ).rect(-size, size, -size,
+ -size, size, size,
+ size, size, size,
+ size, size, -size,
+ 0.0f, size, 0.0f
+ );
+
+ modelBuilder.part(
+ LEFT_SIDE_NAME,
+ GL20.GL_TRIANGLES,
+ ATTR,
+ new Material(TextureAttribute.createDiffuse(manager
+ .rotate90Texture(left, false)))
+ ).rect(-size, -size, size,
+ -size, size, size,
+ -size, size, -size,
+ -size, -size, -size,
+ -size, 0.0f, 0.0f
+ );
+
+ modelBuilder.part(
+ RIGHT_SIDE_NAME,
+ GL20.GL_TRIANGLES,
+ ATTR,
+ new Material(TextureAttribute.createDiffuse(manager
+ .rotate90Texture(right, false)))
+ ).rect(size, -size, -size,
+ size, size, -size,
+ size, size, size,
+ size, -size, size,
+ size, 0.0f, 0.0f
+ );
+ Model model = modelBuilder.end();
+
+ for (Material material : model.materials) material.set(ALPHA);
+
+ return model;
+ }
+
public static String getStacktrace(Throwable t) {
StringWriter writer0 = new StringWriter();
PrintWriter writer = new PrintWriter(writer0);
diff --git a/core/src/ru/mclord/classic/InGameScreen.java b/core/src/ru/mclord/classic/InGameScreen.java
index d799a80..0ac1cc1 100644
--- a/core/src/ru/mclord/classic/InGameScreen.java
+++ b/core/src/ru/mclord/classic/InGameScreen.java
@@ -7,8 +7,6 @@
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
-import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
-import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import ru.mclord.classic.events.CustomizeEnvironmentEvent;
public class InGameScreen implements Screen {
@@ -19,14 +17,14 @@ public class InGameScreen implements Screen {
private ModelBatch modelBatch;
private McLordFirstPersonCameraController cameraController;
private Level level;
+ private final Skybox skybox;
private Environment environment;
private PerspectiveCamera camera;
private final float fov;
- private final float cameraFar;
private InGameScreen() {
fov = Float.parseFloat(McLordClassic.getProperty("fov"));
- cameraFar = Float.parseFloat(McLordClassic.getProperty("cameraFar"));
+ skybox = new Skybox();
}
public static InGameScreen getInstance() {
@@ -65,12 +63,17 @@ public void show() {
// camera.position.set(player.spawnLocation.x, player.spawnLocation.y, player.spawnLocation.z);
camera.position.set(-1.0f, -1.0f, -1.0f);
camera.near = 0.35f; // todo might be not the best value
- camera.far = cameraFar;
+ camera.far = 1000000000.0f;
camera.update();
level.initGraphics();
-
+ if (TextureManager.getInstance().skyboxPresented) {
+ float size = Math.max(Math.max(level.sizeX, level.sizeY), level.sizeZ);
+ skybox.setSize(size);
+ skybox.initGraphics();
+ }
cameraController = new McLordFirstPersonCameraController(camera);
+
Gdx.input.setInputProcessor(cameraController);
Gdx.input.setCursorCatched(true);
}
@@ -82,6 +85,9 @@ public void render(float delta) {
Helper.clearDepthRGB(17, 137, 217);
modelBatch.begin(camera);
+ if (skybox.isReady()) {
+ skybox.render(modelBatch, camera);
+ }
level.render(modelBatch, environment);
modelBatch.end();
}
diff --git a/core/src/ru/mclord/classic/McLordClassic.java b/core/src/ru/mclord/classic/McLordClassic.java
index 18b0d38..d35a167 100644
--- a/core/src/ru/mclord/classic/McLordClassic.java
+++ b/core/src/ru/mclord/classic/McLordClassic.java
@@ -1,6 +1,7 @@
package ru.mclord.classic;
import com.badlogic.gdx.Game;
+import com.badlogic.gdx.graphics.g3d.shaders.DefaultShader;
import ru.mclord.classic.events.DisconnectEvent;
import ru.mclord.classic.events.LevelDownloadingFinishedEvent;
import ru.mclord.classic.events.PlayerSpawnEvent;
@@ -127,6 +128,7 @@ public Object addTask(Runnable task, boolean subscribe) {
}
@Override
+ @SuppressWarnings("deprecation")
public void create() {
System.out.println("Loading texture pack");
String configTexturePack = gameProperties.getProperty("texturePack");
@@ -142,6 +144,8 @@ public void create() {
networkingThread = new NetworkingThread();
networkingThread.start();
+ DefaultShader.defaultCullFace = 0; // make it possible to render skybox
+
setScreen(LoadingScreen.getInstance());
}
diff --git a/core/src/ru/mclord/classic/McLordFirstPersonCameraController.java b/core/src/ru/mclord/classic/McLordFirstPersonCameraController.java
index e89fef2..97fac21 100644
--- a/core/src/ru/mclord/classic/McLordFirstPersonCameraController.java
+++ b/core/src/ru/mclord/classic/McLordFirstPersonCameraController.java
@@ -70,7 +70,6 @@ public void update(float deltaTime) {
private boolean collision() {
if (xRay) return false;
- // too bad, fixme at some point
int x = (int) (camera.position.x);
int y = (int) (camera.position.y);
int z = (int) (camera.position.z);
diff --git a/core/src/ru/mclord/classic/Pair.java b/core/src/ru/mclord/classic/Pair.java
new file mode 100644
index 0000000..a90c61c
--- /dev/null
+++ b/core/src/ru/mclord/classic/Pair.java
@@ -0,0 +1,23 @@
+package ru.mclord.classic;
+
+public class Pair {
+ private final A first;
+ private final B second;
+
+ private Pair(A first, B second) {
+ this.first = first;
+ this.second = second;
+ }
+
+ public static Pair of(A first, B second) {
+ return new Pair<>(first, second);
+ }
+
+ public A getFirst() {
+ return first;
+ }
+
+ public B getSecond() {
+ return second;
+ }
+}
diff --git a/core/src/ru/mclord/classic/Skybox.java b/core/src/ru/mclord/classic/Skybox.java
new file mode 100644
index 0000000..5500707
--- /dev/null
+++ b/core/src/ru/mclord/classic/Skybox.java
@@ -0,0 +1,52 @@
+package ru.mclord.classic;
+
+import com.badlogic.gdx.graphics.Camera;
+import com.badlogic.gdx.graphics.g3d.ModelBatch;
+import com.badlogic.gdx.graphics.g3d.ModelInstance;
+import com.badlogic.gdx.math.Matrix4;
+import com.badlogic.gdx.utils.Disposable;
+
+public class Skybox implements Disposable {
+ private float size;
+ private ModelInstance modelInstance;
+
+ public Skybox() {
+ }
+
+ public void setSize(float size) {
+ this.size = size;
+ }
+
+ public void initGraphics() {
+ if (isReady()) return;
+
+ if (size == 0.0f) throw new IllegalStateException("Size not set");
+
+ TextureManager manager = TextureManager.getInstance();
+
+ modelInstance = new ModelInstance(Helper.constructBlock(size,
+ manager.getSkyboxTexture(3),
+ manager.getSkyboxTexture(5),
+ manager.getSkyboxTexture(1),
+ manager.getSkyboxTexture(0),
+ manager.getSkyboxTexture(4),
+ manager.getSkyboxTexture(2)
+ ));
+ }
+
+ public boolean isReady() {
+ return modelInstance != null;
+ }
+
+ public void render(ModelBatch batch, Camera camera) {
+ modelInstance.transform.set((new Matrix4()).translate(camera.position));
+
+ batch.render(modelInstance);
+ }
+
+ @Override
+ public void dispose() {
+ Helper.dispose(modelInstance.model);
+ modelInstance = null;
+ }
+}
diff --git a/core/src/ru/mclord/classic/TextureManager.java b/core/src/ru/mclord/classic/TextureManager.java
index 69fd64d..96f8322 100644
--- a/core/src/ru/mclord/classic/TextureManager.java
+++ b/core/src/ru/mclord/classic/TextureManager.java
@@ -6,18 +6,22 @@
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class TextureManager implements Disposable {
+ public interface Handler {
+ void handle(Pixmap pixmap, int xOffset, int yOffset, int x, int y);
+
+ default boolean shouldWalk(int i) {
+ return true;
+ }
+ }
+
public static final int TEXTURE_SIZE = 16;
public static final int IMAGE_WIDTH = 256;
public static final int IMAGE_HEIGHT = 512;
@@ -38,11 +42,16 @@ public class TextureManager implements Disposable {
private static final TextureManager INSTANCE = new TextureManager();
private final Texture[] textures = new Texture[TEXTURE_COUNT];
- private final Pixmap[] temporaryPixmaps = new Pixmap[TEXTURE_COUNT + 1];
+ private final boolean searchForSkybox;
+ private final Texture[] skyboxTextures = new Texture[6];
+ /* package-private */ boolean skyboxPresented;
+ private final List temporaryPixmaps = new ArrayList<>();
private final List temporaryTextures;
private Texture emptyTexture;
private TextureManager() {
+ this.searchForSkybox = Boolean.parseBoolean(
+ McLordClassic.getProperty("searchForSkybox"));
this.temporaryTextures = new ArrayList<>();
}
@@ -50,11 +59,41 @@ public static TextureManager getInstance() {
return INSTANCE;
}
+ @SuppressWarnings("unchecked")
@ShouldBeCalledBy(thread = "main")
public void load(String path, boolean allowNet, boolean allowFileSystem) {
BufferedImage image;
- try (InputStream inputStream = createInputStream(path, allowNet, allowFileSystem)) {
- image = ImageIO.read(inputStream);
+ BufferedImage skybox = null;
+ try {
+ String[] query;
+ if (searchForSkybox) {
+ query = new String[]{"terrain.png", "skybox.png"};
+ } else {
+ query = new String[]{"terrain.png"};
+ }
+ Object result = createInputStreams(path, allowNet, allowFileSystem, query);
+ if (result instanceof InputStream) { // no skybox for sure :(
+ try (InputStream inputStream = (InputStream) result){
+ image = ImageIO.read(inputStream);
+ }
+ } else {
+ Map streams = (Map) result;
+
+ InputStream terrainStream = streams.get("terrain.png");
+ if (terrainStream == null) {
+ throw new FileNotFoundException("Could not load terrain textures");
+ }
+ image = ImageIO.read(terrainStream);
+ if (searchForSkybox) {
+ InputStream skyboxStream = streams.get("skybox.png");
+
+ if (skyboxStream != null) {
+ skybox = ImageIO.read(skyboxStream);
+ } else {
+ System.err.println("Could not load skybox textures");
+ }
+ }
+ }
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -74,37 +113,104 @@ public void load(String path, boolean allowNet, boolean allowFileSystem) {
// }
//}
emptyTexture = new Texture(emptyPixmap);
- temporaryPixmaps[temporaryPixmaps.length - 1] = emptyPixmap;
- for (int i = 0; i < TEXTURE_COUNT; i++) {
- Pixmap pixmap = new Pixmap(TEXTURE_SIZE, TEXTURE_SIZE, Pixmap.Format.RGBA8888);
-
- int xOffset = (i % 16) * TEXTURE_SIZE;
- int yOffset = (i / 16) * TEXTURE_SIZE;
- for (int x = 0; x < TEXTURE_SIZE; x++) {
- for (int y = 0; y < TEXTURE_SIZE; y++) {
- int color;
+ temporaryPixmaps.add(emptyPixmap);
+
+ walk(textures, temporaryPixmaps, textures.length, TEXTURE_SIZE,
+ TEXTURE_SIZE, 16, (pixmap, xOffset, yOffset, x, y) -> {
+
+ int color;
+ int realX = xOffset + x;
+ int realY = yOffset + y;
+ if (realX >= width || realY >= height) color = 0;
+ else color = image.getRGB(realX, realY);
+
+ pixmap.drawPixel(x, y, textureColorFrom(color));
+ });
+
+ if (skybox != null) {
+ int skyboxWidth = skybox.getWidth();
+ int skyboxHeight = skybox.getHeight();
+ if (skyboxHeight % 2 != 0) {
+ System.err.println("skybox.png height should be even");
+
+ return;
+ }
+ int skyboxTextureSize = skyboxHeight / 2;
+ if (skyboxTextureSize * 4 != skyboxWidth) {
+ System.err.println("Unexpected width of skybox.png");
+
+ return;
+ }
+ BufferedImage finalSkybox = skybox;
+ walk(skyboxTextures, temporaryPixmaps, 8, skyboxTextureSize,
+ skyboxTextureSize, 4, new Handler() {
+
+ @Override
+ public void handle(Pixmap pixmap, int xOffset, int yOffset, int x, int y) {
int realX = xOffset + x;
int realY = yOffset + y;
- if (realX >= width || realY >= height) color = 0;
- else color = image.getRGB(realX, realY);
-
- // The highest byte here represents the alpha
- // value. We need to move it to the lowest byte
- byte alpha = (byte) ((color >> 24) & 0xFF);
- color <<= 8;
- color += alpha;
- pixmap.drawPixel(x, y, color);
+ int color = finalSkybox.getRGB(realX, realY);
+
+ pixmap.drawPixel(x, y, textureColorFrom(color));
+ }
+
+ @Override
+ public boolean shouldWalk(int i) {
+ return (i != 0 && i != 3);
+ }
+ });
+
+ skyboxPresented = true;
+ }
+ }
+
+ /*
+ * Turns a BufferedImage pixel color into a Texture color by
+ * moving the alpha value (the highest byte) to the lowest byte. For example
+ * fixColor(0xFFFF0000) returns 0xFF0000FF (nontransparent red)
+ * fixColor(0xFF888888) returns 0x888888FF (nontransparent grey)
+ * fixColor(0x01888888) returns 0x88888801 (transparent grey)
+ */
+ public static int textureColorFrom(int bufferedImageColor) {
+ byte alpha = (byte) ((bufferedImageColor >> 24) & 0xFF);
+ bufferedImageColor <<= 8;
+ bufferedImageColor += alpha;
+ // might be it's possible to optimize this?
+
+ return bufferedImageColor;
+ }
+
+ public void walk(
+ Texture[] textures,
+ List temporaryPixmaps,
+ int textureCountInImage,
+ int textureWidth,
+ int textureHeight,
+ int textureCountInARow,
+ Handler handler
+ ) {
+ int texturesI = 0;
+ for (int i = 0; i < textureCountInImage; i++) {
+ if (!handler.shouldWalk(i)) continue;
+
+ Pixmap pixmap = new Pixmap(textureWidth, textureHeight, Pixmap.Format.RGBA8888);
+
+ int xOffset = (i % textureCountInARow) * textureWidth;
+ int yOffset = (i / textureCountInARow) * textureHeight;
+ for (int x = 0; x < textureWidth; x++) {
+ for (int y = 0; y < textureHeight; y++) {
+ handler.handle(pixmap, xOffset, yOffset, x, y);
}
}
- textures[i] = new Texture(pixmap);
+ textures[texturesI++] = new Texture(pixmap);
- temporaryPixmaps[i] = pixmap;
+ temporaryPixmaps.add(pixmap);
}
}
@SuppressWarnings("IOStreamConstructor")
- private static InputStream createInputStream(
- String path, boolean allowNet, boolean allowFileSystem
+ public static Object createInputStreams(
+ String path, boolean allowNet, boolean allowFileSystem, String... objects
) throws IOException {
String lowercasePath = path.toLowerCase();
boolean isZIP = lowercasePath.endsWith(".zip");
@@ -128,17 +234,26 @@ private static InputStream createInputStream(
inputStream = new FileInputStream(path);
}
if (isZIP) {
- inputStream = new ZipInputStream(inputStream);
- ZipEntry entry;
- while ((entry = ((ZipInputStream) inputStream).getNextEntry()) != null) {
- if (entry.isDirectory()) continue;
- if (entry.getName().equalsIgnoreCase("terrain.png")) {
- return inputStream;
+ Map inputStreams = new HashMap<>();
+ try (ZipInputStream zipStream = new ZipInputStream(inputStream)) {
+ DataInputStream wrapper = new DataInputStream(zipStream);
+
+ ZipEntry entry;
+ while ((entry = zipStream.getNextEntry()) != null) {
+ if (entry.isDirectory()) continue;
+
+ String name = entry.getName();
+ if (Helper.containsIgnoreCase(name, objects)) {
+ byte[] bytes = new byte[(int) entry.getSize()];
+ wrapper.readFully(bytes);
+ inputStreams.put(name, new ByteArrayInputStream(bytes));
+ System.out.println("Added " + name);
+ if (inputStreams.size() == objects.length) break;
+ }
}
}
- inputStream.close();
- throw new FileNotFoundException("Could not find terrain.png file in the ZIP");
+ return inputStreams;
}
return inputStream;
@@ -151,6 +266,19 @@ public Texture getTexture(int i) {
return textures[i];
}
+ public boolean isSkyboxPresented() {
+ return skyboxPresented;
+ }
+
+ @ShouldBeCalledBy(thread = "main")
+ public Texture getSkyboxTexture(int i) {
+ return skyboxTextures[i];
+ }
+
+ public Texture getEmptyTexture() {
+ return emptyTexture;
+ }
+
public Texture rotate90Texture(Texture texture, boolean clockwise) {
if (texture == emptyTexture) return texture;
@@ -218,12 +346,16 @@ public void dispose() {
for (Texture texture : textures) {
Helper.dispose(texture);
}
+ for (Texture texture : skyboxTextures) {
+ Helper.dispose(texture);
+ }
for (Pixmap pixmap : temporaryPixmaps) {
- Helper.dispose(pixmap);
+ pixmap.dispose();
}
for (Texture texture : temporaryTextures) {
texture.dispose();
}
+ temporaryPixmaps.clear();
temporaryTextures.clear();
}
}
diff --git a/desktop/src/ru/mclord/classic/DesktopLauncher.java b/desktop/src/ru/mclord/classic/DesktopLauncher.java
index 85e1ec3..2aba7b0 100644
--- a/desktop/src/ru/mclord/classic/DesktopLauncher.java
+++ b/desktop/src/ru/mclord/classic/DesktopLauncher.java
@@ -21,8 +21,8 @@ public static void main(String[] arg) throws IOException {
props.setProperty("hdpiMode", "Logical");
props.setProperty("texturePack", TextureManager.DEFAULT_TEXTURE_PACK);
props.setProperty("fov", "90.0");
- props.setProperty("cameraFar", "300.0");
props.setProperty("xRay", "true");
+ props.setProperty("searchForSkybox", "true");
File propertiesFile = new File("game.properties");
if (propertiesFile.exists()) {