Added texture generation system
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -11,6 +11,7 @@
|
|||||||
/core/lib/
|
/core/lib/
|
||||||
/annotations/build/
|
/annotations/build/
|
||||||
/kryonet/build/
|
/kryonet/build/
|
||||||
|
/packer/build/
|
||||||
/server/build/
|
/server/build/
|
||||||
/annotations/build/
|
/annotations/build/
|
||||||
/android/assets/mindustry-maps/
|
/android/assets/mindustry-maps/
|
||||||
|
|||||||
@@ -198,6 +198,14 @@ project(":server") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
project(":packer") {
|
||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compile project(":core")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
project(":annotations") {
|
project(":annotations") {
|
||||||
apply plugin: "java"
|
apply plugin: "java"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 118 KiB |
@@ -3,25 +3,6 @@ sourceCompatibility = 1.8
|
|||||||
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
|
||||||
sourceSets.main.java.srcDirs = ["src/"]
|
sourceSets.main.java.srcDirs = ["src/"]
|
||||||
|
|
||||||
import com.badlogic.gdx.tools.texturepacker.TexturePacker
|
|
||||||
|
|
||||||
task packSprites(){
|
|
||||||
doLast {
|
|
||||||
TexturePacker.process("core/assets-raw/sprites/", "core/assets/sprites/", "sprites.atlas")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task packUI(){
|
|
||||||
doLast {
|
|
||||||
TexturePacker.process("core/assets-raw/ui/", "core/assets/ui/", "uiskin.atlas")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task pack(){
|
|
||||||
dependsOn 'packSprites'
|
|
||||||
dependsOn 'packUI'
|
|
||||||
}
|
|
||||||
|
|
||||||
eclipse.project {
|
eclipse.project {
|
||||||
name = appName + "-core"
|
name = appName + "-core"
|
||||||
}
|
}
|
||||||
@@ -1,31 +1,20 @@
|
|||||||
package io.anuke.mindustry.editor;
|
package io.anuke.mindustry.editor;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
|
||||||
import com.badlogic.gdx.graphics.Pixmap.Format;
|
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
|
||||||
import com.badlogic.gdx.graphics.Texture.TextureFilter;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.PixmapPacker;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.PixmapPacker.Page;
|
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
import com.badlogic.gdx.math.GridPoint2;
|
import com.badlogic.gdx.math.GridPoint2;
|
||||||
import com.badlogic.gdx.math.Rectangle;
|
|
||||||
import com.badlogic.gdx.utils.Disposable;
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
import com.badlogic.gdx.utils.IntSet;
|
import com.badlogic.gdx.utils.IntSet;
|
||||||
import com.badlogic.gdx.utils.IntSet.IntSetIterator;
|
import com.badlogic.gdx.utils.IntSet.IntSetIterator;
|
||||||
import com.badlogic.gdx.utils.ObjectMap;
|
|
||||||
import io.anuke.mindustry.game.Team;
|
import io.anuke.mindustry.game.Team;
|
||||||
import io.anuke.mindustry.io.MapTileData.DataPosition;
|
import io.anuke.mindustry.io.MapTileData.DataPosition;
|
||||||
import io.anuke.mindustry.world.Block;
|
import io.anuke.mindustry.world.Block;
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.core.Graphics;
|
import io.anuke.ucore.core.Graphics;
|
||||||
import io.anuke.ucore.core.Timers;
|
|
||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.graphics.IndexedRenderer;
|
import io.anuke.ucore.graphics.IndexedRenderer;
|
||||||
import io.anuke.ucore.util.Bits;
|
import io.anuke.ucore.util.Bits;
|
||||||
import io.anuke.ucore.util.Geometry;
|
import io.anuke.ucore.util.Geometry;
|
||||||
import io.anuke.ucore.util.Log;
|
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.tilesize;
|
import static io.anuke.mindustry.Vars.tilesize;
|
||||||
@@ -39,69 +28,8 @@ public class MapRenderer implements Disposable{
|
|||||||
private int width, height;
|
private int width, height;
|
||||||
private Color tmpColor = Color.WHITE.cpy();
|
private Color tmpColor = Color.WHITE.cpy();
|
||||||
|
|
||||||
private ObjectMap<Block, TextureRegion> blockIcons = new ObjectMap<>();
|
|
||||||
private ObjectMap<String, TextureRegion> regions = new ObjectMap<>();
|
|
||||||
private Texture blockTexture;
|
|
||||||
|
|
||||||
public MapRenderer(MapEditor editor){
|
public MapRenderer(MapEditor editor){
|
||||||
this.editor = editor;
|
this.editor = editor;
|
||||||
createTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void createTexture(){
|
|
||||||
Timers.mark();
|
|
||||||
|
|
||||||
PixmapPacker packer = new PixmapPacker(512, 512, Format.RGBA8888, 2, true);
|
|
||||||
Pixmap pixmap = Core.atlas.getPixmapOf("blank");
|
|
||||||
|
|
||||||
for(Block block : Block.all()){
|
|
||||||
TextureRegion[] regions = block.getBlockIcon();
|
|
||||||
if(regions.length > 0){
|
|
||||||
Pixmap result = new Pixmap(regions[0].getRegionWidth(), regions[0].getRegionHeight(), Format.RGBA8888);
|
|
||||||
for(TextureRegion region : regions){
|
|
||||||
result.drawPixmap(pixmap, 0, 0, region.getRegionX(), region.getRegionY(), region.getRegionWidth(), region.getRegionHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
packer.pack(block.name, result);
|
|
||||||
result.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
add("clear", packer);
|
|
||||||
add("block-border", packer);
|
|
||||||
add("block-elevation", packer);
|
|
||||||
add("block-slope", packer);
|
|
||||||
|
|
||||||
if(packer.getPages().size > 1){
|
|
||||||
throw new IllegalArgumentException("Pixmap packer may not have more than 1 page!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Page page = packer.getPages().first();
|
|
||||||
page.updateTexture(TextureFilter.Nearest, TextureFilter.Nearest, false);
|
|
||||||
blockTexture = page.getTexture();
|
|
||||||
for(String str : page.getRects().keys()){
|
|
||||||
if(Block.getByName(str) == null) continue;
|
|
||||||
Rectangle rect = page.getRects().get(str);
|
|
||||||
blockIcons.put(Block.getByName(str),
|
|
||||||
new TextureRegion(blockTexture,
|
|
||||||
(int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height));
|
|
||||||
}
|
|
||||||
|
|
||||||
packer.dispose();
|
|
||||||
|
|
||||||
Core.atlas.disposePixmaps();
|
|
||||||
|
|
||||||
Log.info("Packing elapsed: {0}", Timers.elapsed());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void add(String name, PixmapPacker packer){
|
|
||||||
TextureRegion region = Draw.region(name);
|
|
||||||
Pixmap result = new Pixmap(region.getRegionWidth(), region.getRegionHeight(), Format.RGBA8888);
|
|
||||||
result.drawPixmap(Core.atlas.getPixmapOf(region), 0, 0, region.getRegionX(), region.getRegionY(), region.getRegionWidth(), region.getRegionHeight());
|
|
||||||
Rectangle rect = packer.pack(name, result);
|
|
||||||
result.dispose();
|
|
||||||
Gdx.app.postRunnable(() -> regions.put(name, new TextureRegion(packer.getPages().first().getTexture(), (int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resize(int width, int height){
|
public void resize(int width, int height){
|
||||||
@@ -149,7 +77,7 @@ public class MapRenderer implements Disposable{
|
|||||||
th / (height * tilesize), 1f);
|
th / (height * tilesize), 1f);
|
||||||
mesh.setProjectionMatrix(Core.batch.getProjectionMatrix());
|
mesh.setProjectionMatrix(Core.batch.getProjectionMatrix());
|
||||||
|
|
||||||
mesh.render(blockTexture);
|
mesh.render(Core.atlas.getTextures().first());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +117,7 @@ public class MapRenderer implements Disposable{
|
|||||||
TextureRegion region;
|
TextureRegion region;
|
||||||
|
|
||||||
if(bw != 0) {
|
if(bw != 0) {
|
||||||
region = blockIcons.get(wall, regions.get("clear"));
|
region = Draw.region("block-icon-" + wall.name, Draw.region("clear"));
|
||||||
|
|
||||||
if (wall.rotate) {
|
if (wall.rotate) {
|
||||||
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region,
|
mesh.draw((wx % chunksize) + (wy % chunksize) * chunksize, region,
|
||||||
@@ -201,7 +129,7 @@ public class MapRenderer implements Disposable{
|
|||||||
region.getRegionWidth(), region.getRegionHeight());
|
region.getRegionWidth(), region.getRegionHeight());
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
region = blockIcons.get(floor, regions.get("clear"));
|
region = Draw.region("block-icon-" + floor.name, Draw.region("clear"));
|
||||||
|
|
||||||
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize, region, wx * tilesize, wy * tilesize, 8, 8);
|
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize, region, wx * tilesize, wy * tilesize, 8, 8);
|
||||||
}
|
}
|
||||||
@@ -210,14 +138,14 @@ public class MapRenderer implements Disposable{
|
|||||||
|
|
||||||
if(wall.update || wall.destructible) {
|
if(wall.update || wall.destructible) {
|
||||||
mesh.setColor(team.color);
|
mesh.setColor(team.color);
|
||||||
region = regions.get("block-border");
|
region = Draw.region("block-border");
|
||||||
}else if(elev > 0 && check){
|
}else if(elev > 0 && check){
|
||||||
mesh.setColor(tmpColor.fromHsv((360f * elev/127f * 4f) % 360f, 0.5f + (elev / 4f) % 0.5f, 1f));
|
mesh.setColor(tmpColor.fromHsv((360f * elev/127f * 4f) % 360f, 0.5f + (elev / 4f) % 0.5f, 1f));
|
||||||
region = regions.get("block-elevation");
|
region = Draw.region("block-elevation");
|
||||||
}else if(elev == -1){
|
}else if(elev == -1){
|
||||||
region = regions.get("block-slope");
|
region = Draw.region("block-slope");
|
||||||
}else{
|
}else{
|
||||||
region = regions.get("clear");
|
region = Draw.region("clear");
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region,
|
mesh.draw((wx % chunksize) + (wy % chunksize)*chunksize + chunksize*chunksize, region,
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package io.anuke.mindustry.graphics;
|
|
||||||
|
|
||||||
/**Used for generating extra textures before packing.*/
|
|
||||||
public class TextureGenerator {
|
|
||||||
|
|
||||||
public static void main(String[] args){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,7 +16,7 @@ public abstract class Upgrade implements UnlockableContent{
|
|||||||
public Upgrade(String name){
|
public Upgrade(String name){
|
||||||
this.id = lastid ++;
|
this.id = lastid ++;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.description = Bundles.getNotNull("upgrade."+name+".description");
|
this.description = Bundles.get("upgrade."+name+".description");
|
||||||
|
|
||||||
upgrades.add(this);
|
upgrades.add(this);
|
||||||
}
|
}
|
||||||
|
|||||||
45
packer/build.gradle
Normal file
45
packer/build.gradle
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
apply plugin: "java"
|
||||||
|
|
||||||
|
sourceCompatibility = 1.8
|
||||||
|
sourceSets.main.java.srcDirs = [ "src/" ]
|
||||||
|
|
||||||
|
import com.badlogic.gdx.tools.texturepacker.TexturePacker
|
||||||
|
|
||||||
|
def textureFolder = "../core/assets-raw/sprites/generated/"
|
||||||
|
|
||||||
|
task pack(){
|
||||||
|
dependsOn 'prePack'
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
TexturePacker.process("core/assets-raw/sprites/", "core/assets/sprites/", "sprites.atlas")
|
||||||
|
|
||||||
|
delete{
|
||||||
|
delete textureFolder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task prePack(){
|
||||||
|
dependsOn "cleanup"
|
||||||
|
|
||||||
|
doLast{
|
||||||
|
TexturePacker.process("core/assets-raw/sprites/", "core/assets/sprites/", "sprites.atlas")
|
||||||
|
}
|
||||||
|
|
||||||
|
finalizedBy 'generateSprites'
|
||||||
|
}
|
||||||
|
|
||||||
|
task cleanup(){
|
||||||
|
delete{
|
||||||
|
delete textureFolder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task generateSprites(dependsOn: classes, type: JavaExec) {
|
||||||
|
file(textureFolder).mkdirs()
|
||||||
|
|
||||||
|
main = "io.anuke.mindustry.TextureGenerator"
|
||||||
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
|
standardInput = System.in
|
||||||
|
workingDir = textureFolder
|
||||||
|
}
|
||||||
113
packer/src/io/anuke/mindustry/TextureGenerator.java
Normal file
113
packer/src/io/anuke/mindustry/TextureGenerator.java
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
package io.anuke.mindustry;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureAtlas.TextureAtlasData.Region;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
|
import io.anuke.mindustry.core.ContentLoader;
|
||||||
|
import io.anuke.mindustry.world.Block;
|
||||||
|
import io.anuke.ucore.core.Core;
|
||||||
|
import io.anuke.ucore.util.Atlas;
|
||||||
|
import io.anuke.ucore.util.Log;
|
||||||
|
import io.anuke.ucore.util.Log.NoopLogHandler;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**Used for generating extra textures before packing.*/
|
||||||
|
public class TextureGenerator {
|
||||||
|
static BufferedImage image;
|
||||||
|
static Graphics2D graphics;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception{
|
||||||
|
Log.setLogger(new NoopLogHandler());
|
||||||
|
|
||||||
|
ContentLoader.load();
|
||||||
|
|
||||||
|
String spritesFolder = new File("../../../assets/sprites").getAbsolutePath();
|
||||||
|
|
||||||
|
TextureAtlasData data = new TextureAtlasData(new FileHandle(spritesFolder + "/sprites.atlas"),
|
||||||
|
new FileHandle(spritesFolder), false);
|
||||||
|
|
||||||
|
ObjectMap<String, TextureRegion> regionCache = new ObjectMap<>();
|
||||||
|
|
||||||
|
for(Region region : data.getRegions()){
|
||||||
|
int x = region.left, y = region.top, width = region.width, height = region.height;
|
||||||
|
|
||||||
|
regionCache.put(region.name, new TextureRegion(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRegionX(){
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRegionY(){
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRegionWidth(){
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRegionHeight(){
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Core.atlas = new Atlas(){
|
||||||
|
@Override
|
||||||
|
public TextureRegion getRegion(String name){
|
||||||
|
return regionCache.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasRegion(String s) {
|
||||||
|
return regionCache.containsKey(s);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
image = ImageIO.read(new File(spritesFolder + "/sprites.png"));
|
||||||
|
graphics = image.createGraphics();
|
||||||
|
|
||||||
|
generateBlocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void generateBlocks() throws IOException {
|
||||||
|
|
||||||
|
for(Block block : Block.all()){
|
||||||
|
TextureRegion[] regions = block.getBlockIcon();
|
||||||
|
|
||||||
|
if(regions.length == 0){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BufferedImage target = new BufferedImage(regions[0].getRegionWidth(), regions[0].getRegionHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||||
|
Graphics2D tg = target.createGraphics();
|
||||||
|
|
||||||
|
for(TextureRegion region : regions){
|
||||||
|
|
||||||
|
tg.drawImage(image,
|
||||||
|
0, 0,
|
||||||
|
region.getRegionWidth(),
|
||||||
|
region.getRegionHeight(),
|
||||||
|
region.getRegionX(),
|
||||||
|
region.getRegionY(),
|
||||||
|
region.getRegionX() + region.getRegionWidth(),
|
||||||
|
region.getRegionY() + region.getRegionHeight(),
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
tg.dispose();
|
||||||
|
|
||||||
|
ImageIO.write(target, "png", new File("block-icon-" + block.name + ".png"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
include 'desktop', 'html', 'core', 'android', 'kryonet', 'server', 'ios', 'annotations'
|
include 'desktop', 'html', 'core', 'android', 'kryonet', 'server', 'ios', 'annotations', 'packer'
|
||||||
|
|
||||||
if(System.properties["release"] == null || System.properties["release"].equals("false")){
|
if(System.properties["release"] == null || System.properties["release"].equals("false")){
|
||||||
if (new File(settingsDir, '../uCore').exists()) {
|
if (new File(settingsDir, '../uCore').exists()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user