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()) {