TPL refactor, unified line endings, JavaDoc and full switch to SmartSeverity
This commit is contained in:
parent
60fae86237
commit
2b065249ee
|
@ -51,6 +51,7 @@ version numbers.*
|
||||||
|
|
||||||
### Normal priority
|
### Normal priority
|
||||||
* The collision system for PlutoStatic
|
* The collision system for PlutoStatic
|
||||||
|
* Improve image loading capabilities, possibly rewrite PlutoLib#TPL
|
||||||
|
|
||||||
### Low priority
|
### Low priority
|
||||||
* Polishing PlutoLib
|
* Polishing PlutoLib
|
||||||
|
|
|
@ -7,5 +7,21 @@
|
||||||
* `Logger`'s output filenames now look cleaner with `log--YYYY-MM-DD--HH-MM-SS.txt`
|
* `Logger`'s output filenames now look cleaner with `log--YYYY-MM-DD--HH-MM-SS.txt`
|
||||||
* `[Logger#setup]` can now throw `IOException`
|
* `[Logger#setup]` can now throw `IOException`
|
||||||
* `[PlutoCore]` As a result, `[PlutoApplication#run]` can now throw `Exception`
|
* `[PlutoCore]` As a result, `[PlutoApplication#run]` can now throw `Exception`
|
||||||
|
* `[PlutoLib]` Updated JavaDoc in `ResourceAddress`, `TPL`, `TPNImage`
|
||||||
|
* `[PlutoLib]` Added `ResourceAddress#openRead` and `ResourceAddress#openWrite`
|
||||||
|
* `[PlutoLib]` Code cleanup in `MiniTime`, `TPL`
|
||||||
|
* `[PlutoLib]` Deprecated `TPL#load(String)` in favor of `TPL#load(ResourceAddress)`,
|
||||||
|
`TPL#load(File)` and `TPL#load(Path)`
|
||||||
|
* `[PlutoTexturing]` Deprecated the `String` variant of `Texture#load`
|
||||||
|
to reflect this change
|
||||||
|
* `[PlutoSpritesheet]` Removed the usage of this method
|
||||||
|
in `DisposablePlaceholderSprite`
|
||||||
|
* `[PlutoLib]` Added an option to flip loaded images with `TPL#loadImageSpecial`
|
||||||
|
and added respective `TPL#loadSpecial` for every `TPL#load`
|
||||||
|
* `[PlutoLib]` *Removed* `TPJImage`
|
||||||
|
* `[PlutoLib]` Removed `TPL#loadPixels`
|
||||||
|
* `[PlutoCore]` Updated `GLFWImageUtil` to remove the usage of `TPJImage`
|
||||||
* `[PlutoCore]` `[PlutoApplication]` now properly closes the `Logger` on exit
|
* `[PlutoCore]` `[PlutoApplication]` now properly closes the `Logger` on exit
|
||||||
* `[PlutoLib]` Various typo fixes
|
* `[PlutoLib]` Various typo fixes
|
||||||
|
* `[Pluto*]` Deprecated `Severity` for `SmartSeverity` and replaced all usages
|
||||||
|
* `[Pluto*]` Deprecated `CRLF` with `LF` in all Java source files
|
|
@ -48,8 +48,6 @@ public class CursorPositionCallback extends GLFWCursorPosCallback
|
||||||
|
|
||||||
public boolean isInside(int x, int y, int x2, int y2)
|
public boolean isInside(int x, int y, int x2, int y2)
|
||||||
{
|
{
|
||||||
boolean inside = this.getX() > x && this.getX() < x2 && this.getY() > y && this.getY() < y2;
|
return this.getX() > x && this.getX() < x2 && this.getY() > y && this.getY() < y2;
|
||||||
|
|
||||||
return inside;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
package cz.tefek.pluto;
|
package cz.tefek.pluto;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constants shared by all Pluto libraries.
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
|
*
|
||||||
|
* @author 493msi
|
||||||
|
*/
|
||||||
public class Pluto
|
public class Pluto
|
||||||
{
|
{
|
||||||
public static final boolean DEBUG_MODE = Boolean.valueOf(System.getProperty("cz.tefek.pluto.debug"));
|
public static final boolean DEBUG_MODE = Boolean.valueOf(System.getProperty("cz.tefek.pluto.debug"));
|
||||||
|
@ -8,41 +15,57 @@ public class Pluto
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The year version number, changes with breaking API changes.
|
* The year version number, changes with breaking API changes.
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
* */
|
* */
|
||||||
public static final int VERSION_YEAR = 20;
|
public static final int VERSION_YEAR = 20;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The major version number, changes with breaking API changes.
|
* The major version number, changes with breaking API changes.
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
* */
|
* */
|
||||||
public static final int VERSION_MAJOR = 2;
|
public static final int VERSION_MAJOR = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The minor version number, changes with backwards-compatible API changes.
|
* The minor version number, changes with backwards-compatible API changes.
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
* */
|
* */
|
||||||
public static final int VERSION_MINOR = 0;
|
public static final int VERSION_MINOR = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The patch number, changes with backwards-compatible fixes and patches.
|
* The patch number, changes with backwards-compatible fixes and patches.
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
* */
|
* */
|
||||||
public static final int VERSION_PATCH = 0;
|
public static final int VERSION_PATCH = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Denotes whether this build is a pre-release build.
|
* Denotes whether this build is a pre-release build.
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
* */
|
* */
|
||||||
public static final boolean PRERELEASE = true;
|
public static final boolean PRERELEASE = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of this pre-release, e.g. alpha, beta, RC and similar.
|
* The name of this pre-release, e.g. alpha, beta, RC and similar.
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
* */
|
* */
|
||||||
public static final String PRERELEASE_NAME = "alpha";
|
public static final String PRERELEASE_NAME = "alpha";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The pre-release patch number, incremented by 1 with *any* pre-release change.
|
* The pre-release patch number, incremented by 1 with *any* pre-release update.
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
* */
|
* */
|
||||||
public static final int PRERELEASE_PATCH = 1;
|
public static final int PRERELEASE_PATCH = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The combined version string.
|
* The combined version string.
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
* */
|
* */
|
||||||
public static final String VERSION = VERSION_YEAR + "." + VERSION_MAJOR + "." + VERSION_MINOR + "." + VERSION_PATCH + (PRERELEASE ? "-" + PRERELEASE_NAME + "." + PRERELEASE_PATCH : "");
|
public static final String VERSION = VERSION_YEAR + "." + VERSION_MAJOR + "." + VERSION_MINOR + "." + VERSION_PATCH + (PRERELEASE ? "-" + PRERELEASE_NAME + "." + PRERELEASE_PATCH : "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ public class MiniTime
|
||||||
for (int i = 1; i < nrs.length; i++)
|
for (int i = 1; i < nrs.length; i++)
|
||||||
{
|
{
|
||||||
var type = letters[i - 1];
|
var type = letters[i - 1];
|
||||||
int number = 0;
|
int number;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -196,10 +196,12 @@ public class MiniTime
|
||||||
/**
|
/**
|
||||||
* Converts a time span between two Unix-epoch millisecond time points to a
|
* Converts a time span between two Unix-epoch millisecond time points to a
|
||||||
* MiniTime string. <i>Note ALL time spans larger or equal than
|
* MiniTime string. <i>Note ALL time spans larger or equal than
|
||||||
* {@link Integer#MAX_VALUE} will be permanently converted to "forever".</i>
|
* {@link Integer#MAX_VALUE} weeks will be permanently converted to "forever".
|
||||||
|
* Inputting {@link Long#MAX_VALUE} for the future time point has the same effect.</i>
|
||||||
*
|
*
|
||||||
* @param before The first time point in Unix-time milliseconds
|
* @param before The first time point in Unix-time milliseconds
|
||||||
* @param after The first time point in Unix-time milliseconds
|
* @param after The first time point in Unix-time milliseconds
|
||||||
|
*
|
||||||
* @return The resulting MiniTime string
|
* @return The resulting MiniTime string
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException on a negative time duration
|
* @throws IllegalArgumentException on a negative time duration
|
||||||
|
@ -220,10 +222,12 @@ public class MiniTime
|
||||||
/**
|
/**
|
||||||
* Converts a time span between now and a future time point in Unix-epoch
|
* Converts a time span between now and a future time point in Unix-epoch
|
||||||
* milliseconds to a MiniTime string. <i>Note ALL time spans larger or equal
|
* milliseconds to a MiniTime string. <i>Note ALL time spans larger or equal
|
||||||
* than {@link Integer#MAX_VALUE} will be permanently converted to
|
* than {@link Integer#MAX_VALUE} weeks will be permanently converted to
|
||||||
* "forever".</i>
|
* "forever". Inputting {@link Long#MAX_VALUE} for the future time point
|
||||||
|
* has the same effect.</i>
|
||||||
|
*
|
||||||
|
* @param future The future time point in Unix time milliseconds
|
||||||
*
|
*
|
||||||
* @param future The source time span in milliseconds
|
|
||||||
* @return The resulting MiniTime string
|
* @return The resulting MiniTime string
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException on a negative time duration
|
* @throws IllegalArgumentException on a negative time duration
|
||||||
|
@ -245,7 +249,7 @@ public class MiniTime
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a time span milliseconds to a MiniTime string. <i>Note ALL time
|
* Converts a time span milliseconds to a MiniTime string. <i>Note ALL time
|
||||||
* spans larger or equal than {@link Integer#MAX_VALUE} will be permanently
|
* spans larger or equal than {@link Integer#MAX_VALUE} weeks will be permanently
|
||||||
* converted to "forever".</i>
|
* converted to "forever".</i>
|
||||||
*
|
*
|
||||||
* @param diff The source time span in milliseconds
|
* @param diff The source time span in milliseconds
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
package cz.tefek.pluto.io.asl.resource;
|
package cz.tefek.pluto.io.asl.resource;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.nio.file.FileSystems;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import java.nio.file.FileSystems;
|
|
||||||
import java.nio.file.Path;
|
|
||||||
|
|
||||||
import cz.tefek.pluto.io.logger.Logger;
|
import cz.tefek.pluto.io.logger.Logger;
|
||||||
import cz.tefek.pluto.io.logger.Severity;
|
import cz.tefek.pluto.io.logger.SmartSeverity;
|
||||||
import cz.tefek.pluto.modloader.ModLoaderCore;
|
import cz.tefek.pluto.modloader.ModLoaderCore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,13 +93,11 @@ public class ResourceAddress
|
||||||
|
|
||||||
if (as.length == 1)
|
if (as.length == 1)
|
||||||
{
|
{
|
||||||
Logger.log(Severity.WARNING, "Please do not use tier 1 addresses, so it doesn't conflict with core assets.");
|
Logger.log(SmartSeverity.WARNING, "Please do not use tier 1 addresses, so it doesn't conflict with core assets.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < as.length; i++)
|
for (String branch : as)
|
||||||
{
|
{
|
||||||
var branch = as[i];
|
|
||||||
|
|
||||||
if (branch.length() < 1 || branch.length() > MAX_BRANCH_STRING_LENGTH)
|
if (branch.length() < 1 || branch.length() > MAX_BRANCH_STRING_LENGTH)
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Length of branch must be higher than 0 and lower than 33, this is not an essay.");
|
throw new IllegalArgumentException("Length of branch must be higher than 0 and lower than 33, this is not an essay.");
|
||||||
|
@ -151,9 +148,9 @@ public class ResourceAddress
|
||||||
return raddress;
|
return raddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceAddress fileExtension(String ext)
|
public ResourceAddress fileExtension(@Nullable String ext)
|
||||||
{
|
{
|
||||||
if (ext == null || ext == "")
|
if (ext == null || "".equals(ext))
|
||||||
{
|
{
|
||||||
this.fileExtension = null;
|
this.fileExtension = null;
|
||||||
return this;
|
return this;
|
||||||
|
@ -213,15 +210,7 @@ public class ResourceAddress
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
StringBuilder sbPath = new StringBuilder(this.resSubscriber.getMod().getModID());
|
return this.resSubscriber.getMod().getModID() + "$" + this.subAddressToString();
|
||||||
|
|
||||||
sbPath.append("$");
|
|
||||||
|
|
||||||
sbPath.append(this.subAddressToString());
|
|
||||||
|
|
||||||
String path = sbPath.toString();
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceAddress copy()
|
public ResourceAddress copy()
|
||||||
|
@ -246,12 +235,10 @@ public class ResourceAddress
|
||||||
|
|
||||||
if (this.hasFileExtension())
|
if (this.hasFileExtension())
|
||||||
{
|
{
|
||||||
sbPath.append("." + this.fileExtension);
|
sbPath.append(".").append(this.fileExtension);
|
||||||
}
|
}
|
||||||
|
|
||||||
String path = sbPath.toString();
|
return sbPath.toString();
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String subAddressToString()
|
public String subAddressToString()
|
||||||
|
@ -293,7 +280,7 @@ public class ResourceAddress
|
||||||
var pathBuilder = new StringBuilder(this.resSubscriber.getRootPath());
|
var pathBuilder = new StringBuilder(this.resSubscriber.getRootPath());
|
||||||
final var separator = FileSystems.getDefault().getSeparator();
|
final var separator = FileSystems.getDefault().getSeparator();
|
||||||
pathBuilder.append(separator);
|
pathBuilder.append(separator);
|
||||||
pathBuilder.append(this.subAddress.stream().collect(Collectors.joining(separator)));
|
pathBuilder.append(String.join(separator, this.subAddress));
|
||||||
|
|
||||||
if (this.hasFileExtension())
|
if (this.hasFileExtension())
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
package cz.tefek.pluto.io.asl.resource.type;
|
package cz.tefek.pluto.io.asl.resource.type;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
|
|
||||||
import cz.tefek.pluto.io.asl.resource.Resource;
|
import cz.tefek.pluto.io.asl.resource.Resource;
|
||||||
import cz.tefek.pluto.io.asl.resource.ResourceAddress;
|
import cz.tefek.pluto.io.asl.resource.ResourceAddress;
|
||||||
import cz.tefek.pluto.io.asl.resource.ResourceHelper;
|
import cz.tefek.pluto.io.asl.resource.ResourceHelper;
|
||||||
import cz.tefek.pluto.io.logger.Logger;
|
import cz.tefek.pluto.io.logger.Logger;
|
||||||
import cz.tefek.pluto.io.logger.Severity;
|
import cz.tefek.pluto.io.logger.SmartSeverity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ResourceAddress} in, {@link BufferedImage} out.
|
* {@link ResourceAddress} in, {@link BufferedImage} out.
|
||||||
|
@ -38,7 +37,7 @@ public class ResourceImage extends Resource<BufferedImage>
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
Logger.log(Severity.ERROR, "Could not load BufferedImage: " + this.address.toString() + ", will load placeholder.");
|
Logger.log(SmartSeverity.ERROR, "Could not load BufferedImage: " + this.address.toString() + ", will load placeholder.");
|
||||||
Logger.log(e);
|
Logger.log(e);
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -47,7 +46,7 @@ public class ResourceImage extends Resource<BufferedImage>
|
||||||
}
|
}
|
||||||
catch (IOException e1)
|
catch (IOException e1)
|
||||||
{
|
{
|
||||||
Logger.log(Severity.ERROR, "Placeholder BufferedImage not found: " + ResourceHelper.GLOBAL_ROOT + "data/assets/err/missingTex.png");
|
Logger.log(SmartSeverity.ERROR, "Placeholder BufferedImage not found: " + ResourceHelper.GLOBAL_ROOT + "data/assets/err/missingTex.png");
|
||||||
Logger.log("This is not good! :C");
|
Logger.log("This is not good! :C");
|
||||||
|
|
||||||
Logger.log(e1);
|
Logger.log(e1);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package cz.tefek.pluto.io.asl.resource.type;
|
package cz.tefek.pluto.io.asl.resource.type;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
import cz.tefek.pluto.io.asl.resource.Resource;
|
import cz.tefek.pluto.io.asl.resource.Resource;
|
||||||
import cz.tefek.pluto.io.asl.resource.ResourceAddress;
|
import cz.tefek.pluto.io.asl.resource.ResourceAddress;
|
||||||
import cz.tefek.pluto.io.logger.Logger;
|
import cz.tefek.pluto.io.logger.Logger;
|
||||||
import cz.tefek.pluto.io.logger.Severity;
|
import cz.tefek.pluto.io.logger.SmartSeverity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ResourceAddress} in, {@link InputStream} out.
|
* {@link ResourceAddress} in, {@link InputStream} out.
|
||||||
|
@ -26,12 +26,12 @@ public class ResourceInputStream extends Resource<InputStream>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return new FileInputStream(this.address.toPath());
|
return Files.newInputStream(this.address.toNIOPath());
|
||||||
}
|
}
|
||||||
catch (IOException e)
|
catch (IOException e)
|
||||||
{
|
{
|
||||||
Logger.log(Severity.EXCEPTION, "Failed to open " + this.address + "!");
|
Logger.log(SmartSeverity.ERROR, "Failed to open " + this.address + "!");
|
||||||
Logger.log(Severity.EXCEPTION, e);
|
Logger.log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class Logger
|
||||||
private static OutputStream fileLog = null;
|
private static OutputStream fileLog = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes up the logger and replaces the standard output and standard error output with the logger methods.
|
* Initializes the logger and replaces the standard output and standard error output with the logger methods.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* <em>
|
* <em>
|
||||||
|
|
|
@ -4,7 +4,10 @@ package cz.tefek.pluto.io.logger;
|
||||||
* Message severity.
|
* Message severity.
|
||||||
*
|
*
|
||||||
* @author 493msi
|
* @author 493msi
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link SmartSeverity} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public enum Severity implements ISeverity
|
public enum Severity implements ISeverity
|
||||||
{
|
{
|
||||||
INFO("[INFO] ", false),
|
INFO("[INFO] ", false),
|
||||||
|
@ -19,6 +22,7 @@ public enum Severity implements ISeverity
|
||||||
Severity(String name, boolean usesStdErr)
|
Severity(String name, boolean usesStdErr)
|
||||||
{
|
{
|
||||||
this.displayName = name;
|
this.displayName = name;
|
||||||
|
this.usesStdErr = usesStdErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
package cz.tefek.pluto.tpl;
|
|
||||||
|
|
||||||
public class TPJImage
|
|
||||||
{
|
|
||||||
int[] data;
|
|
||||||
int width;
|
|
||||||
int height;
|
|
||||||
|
|
||||||
public TPJImage(int[] pixels, int width, int height)
|
|
||||||
{
|
|
||||||
this.data = pixels;
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getWidth()
|
|
||||||
{
|
|
||||||
return this.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getHeight()
|
|
||||||
{
|
|
||||||
return this.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getData()
|
|
||||||
{
|
|
||||||
return this.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int pixelAt(int x, int y)
|
|
||||||
{
|
|
||||||
return this.data[x + y * this.width];
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,14 +1,17 @@
|
||||||
package cz.tefek.pluto.tpl;
|
package cz.tefek.pluto.tpl;
|
||||||
|
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.*;
|
||||||
import java.awt.image.DataBuffer;
|
|
||||||
import java.awt.image.DataBufferByte;
|
|
||||||
import java.awt.image.Raster;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
|
||||||
import cz.tefek.pluto.io.asl.resource.ResourceAddress;
|
import cz.tefek.pluto.io.asl.resource.ResourceAddress;
|
||||||
|
@ -16,172 +19,294 @@ import cz.tefek.pluto.io.logger.Logger;
|
||||||
import cz.tefek.pluto.io.logger.SmartSeverity;
|
import cz.tefek.pluto.io.logger.SmartSeverity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Quick ABGR (8-bit per channel, 32 bits per pixel) texture loader for OpenGL
|
* Quick ABGR (8-bit per channel, 32 bits per pixel) image loader for OpenGL textures.
|
||||||
* use. Color component swizzling may be needed.
|
* Color component swizzling may be needed.
|
||||||
|
*
|
||||||
|
* FIXME: Refactor {@link TPL#loadBufferedImage}
|
||||||
*
|
*
|
||||||
* @author 493msi
|
* @author 493msi
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
*/
|
*/
|
||||||
public class TPL
|
public class TPL
|
||||||
{
|
{
|
||||||
private static final int PLACEHOLDER_SIZE = 16;
|
private static final int PLACEHOLDER_SIZE = 16;
|
||||||
|
|
||||||
private static final int PLACEHOLDER_CHECKEDBOARD = 8;
|
private static final int PLACEHOLDER_CHECKEDBOARD = 8;
|
||||||
private static final int PLACEHOLDER_CHECKEDBOARD_SQUARE_SIZE = PLACEHOLDER_SIZE / PLACEHOLDER_CHECKEDBOARD;
|
private static final int PLACEHOLDER_CHECKEDBOARD_SQUARE_SIZE = PLACEHOLDER_SIZE / PLACEHOLDER_CHECKEDBOARD;
|
||||||
|
|
||||||
public static TPNImage load(ResourceAddress file)
|
private static final BufferedImage placeholder;
|
||||||
|
|
||||||
|
static
|
||||||
{
|
{
|
||||||
return file == null ? loadImage(null) : load(file.toPath());
|
placeholder = new BufferedImage(PLACEHOLDER_SIZE, PLACEHOLDER_SIZE, BufferedImage.TYPE_INT_ARGB);
|
||||||
|
var data = placeholder.getData();
|
||||||
|
var dataBuffer = (DataBufferInt) data.getDataBuffer();
|
||||||
|
|
||||||
|
for (int i = 0; i < PLACEHOLDER_SIZE * PLACEHOLDER_SIZE; i++)
|
||||||
|
{
|
||||||
|
int x = i % PLACEHOLDER_SIZE;
|
||||||
|
int y = i / PLACEHOLDER_SIZE;
|
||||||
|
boolean checker = x / PLACEHOLDER_CHECKEDBOARD_SQUARE_SIZE % 2 == y / PLACEHOLDER_CHECKEDBOARD_SQUARE_SIZE % 2;
|
||||||
|
|
||||||
|
dataBuffer.setElem(i, checker ? 0xFFFF0000 : 0xFF000000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TPNImage load(String file)
|
// TODO: Fix this mess
|
||||||
|
private static BufferedImage loadBufferedImage(@Nullable Object source)
|
||||||
{
|
{
|
||||||
if (file == null)
|
var inputStream = (InputStream) null;
|
||||||
{
|
|
||||||
return loadImage(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return loadImage(ImageIO.read(new File(file)));
|
if (source instanceof ResourceAddress)
|
||||||
|
{
|
||||||
|
inputStream = Files.newInputStream(((ResourceAddress) source).toNIOPath());
|
||||||
|
}
|
||||||
|
else if (source instanceof String)
|
||||||
|
{
|
||||||
|
inputStream = new FileInputStream((String) source);
|
||||||
|
}
|
||||||
|
else if (source instanceof File)
|
||||||
|
{
|
||||||
|
inputStream = new FileInputStream((File) source);
|
||||||
|
}
|
||||||
|
else if (source instanceof Path)
|
||||||
|
{
|
||||||
|
inputStream = Files.newInputStream((Path) source);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputStream != null)
|
||||||
|
{
|
||||||
|
return ImageIO.read(inputStream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.log(SmartSeverity.ERROR, "[TPL] Image could not be loaded: " + file);
|
Logger.log(SmartSeverity.ERROR, "[TPL] Image could not be loaded: " + source);
|
||||||
Logger.log(e);
|
Logger.log(e);
|
||||||
|
|
||||||
return loadImage(null);
|
|
||||||
}
|
}
|
||||||
}
|
finally
|
||||||
|
|
||||||
public static TPNImage loadImage(BufferedImage image)
|
|
||||||
{
|
{
|
||||||
boolean remake = false;
|
try
|
||||||
int width = 0;
|
{
|
||||||
int height = 0;
|
if (inputStream != null)
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
Logger.log(SmartSeverity.ERROR, "[TPL] Failed to close: " + source);
|
||||||
|
Logger.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an image from a file the denoted by the input {@link ResourceAddress} into a {@link TPNImage} buffer.
|
||||||
|
*
|
||||||
|
* If the input {@link ResourceAddress} is null, a placeholder will be generated.
|
||||||
|
*
|
||||||
|
* @param address The source {@link ResourceAddress}, from which the image will be loaded
|
||||||
|
*
|
||||||
|
* @return The output {@link TPNImage}, never null
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
|
* */
|
||||||
|
public static TPNImage load(@Nullable ResourceAddress address)
|
||||||
|
{
|
||||||
|
return loadImage(loadBufferedImage(address));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an image from the denoted filename to a {@link TPNImage} buffer.
|
||||||
|
*
|
||||||
|
* If the input filename is null, a placeholder will be generated.
|
||||||
|
*
|
||||||
|
* @deprecated Use the {@link TPL#load(ResourceAddress)} or {@link TPL#load(File)} variants.
|
||||||
|
*
|
||||||
|
* @param filename The source filename, from which the image will be loaded
|
||||||
|
*
|
||||||
|
* @return The output {@link TPNImage}, never null
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
|
* */
|
||||||
|
@Deprecated
|
||||||
|
public static TPNImage load(@Nullable String filename)
|
||||||
|
{
|
||||||
|
return loadImage(loadBufferedImage(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an image from the input {@link File} into a {@link TPNImage} buffer.
|
||||||
|
*
|
||||||
|
* If the input {@link File} is null, a placeholder will be generated.
|
||||||
|
*
|
||||||
|
* @param file The source {@link File}, from which the image will be loaded
|
||||||
|
*
|
||||||
|
* @return The output {@link TPNImage}, never null
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since 20.2.0.0-alpha.1
|
||||||
|
* */
|
||||||
|
public static TPNImage load(@Nullable File file)
|
||||||
|
{
|
||||||
|
return loadImage(loadBufferedImage(file));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an image from a file the denoted by the input {@link Path} into a {@link TPNImage} buffer.
|
||||||
|
*
|
||||||
|
* If the input {@link Path} is null, a placeholder will be generated.
|
||||||
|
*
|
||||||
|
* @param path The source {@link Path}, from which the image will be loaded
|
||||||
|
*
|
||||||
|
* @return The output {@link TPNImage}, never null
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since 20.2.0.0-alpha.1
|
||||||
|
* */
|
||||||
|
public static TPNImage load(@Nullable Path path)
|
||||||
|
{
|
||||||
|
return loadImage(loadBufferedImage(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an image from a file the denoted by the input {@link ResourceAddress} into a {@link TPNImage} buffer.
|
||||||
|
*
|
||||||
|
* If the input {@link ResourceAddress} is null, a placeholder will be generated.
|
||||||
|
*
|
||||||
|
* @param address The source {@link ResourceAddress}, from which the image will be loaded
|
||||||
|
* @param flipY Whether the image should flipped vertically (for OpenGL uses)
|
||||||
|
*
|
||||||
|
* @return The output {@link TPNImage}, never null
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since 20.2.0.0-alpha.1
|
||||||
|
* */
|
||||||
|
public static TPNImage loadSpecial(@Nullable ResourceAddress address, boolean flipY)
|
||||||
|
{
|
||||||
|
return loadImageSpecial(loadBufferedImage(address), flipY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an image from the input {@link File} into a {@link TPNImage} buffer.
|
||||||
|
*
|
||||||
|
* If the input {@link File} is null, a placeholder will be generated.
|
||||||
|
*
|
||||||
|
* @param file The source {@link File}, from which the image will be loaded
|
||||||
|
* @param flipY Whether the image should flipped vertically (for OpenGL uses)
|
||||||
|
*
|
||||||
|
* @return The output {@link TPNImage}, never null
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since 20.2.0.0-alpha.1
|
||||||
|
* */
|
||||||
|
public static TPNImage load(@Nullable File file, boolean flipY)
|
||||||
|
{
|
||||||
|
return loadImageSpecial(loadBufferedImage(file), flipY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads an image from a file the denoted by the input {@link Path} into a {@link TPNImage} buffer.
|
||||||
|
*
|
||||||
|
* If the input {@link Path} is null, a placeholder will be generated.
|
||||||
|
*
|
||||||
|
* @param path The source {@link Path}, from which the image will be loaded
|
||||||
|
* @param flipY Whether the image should flipped vertically (for OpenGL uses)
|
||||||
|
*
|
||||||
|
* @return The output {@link TPNImage}, never null
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since 20.2.0.0-alpha.1
|
||||||
|
* */
|
||||||
|
public static TPNImage loadSpecial(@Nullable Path path, boolean flipY)
|
||||||
|
{
|
||||||
|
return loadImageSpecial(loadBufferedImage(path), flipY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a {@link BufferedImage} into a {@link TPNImage} buffer.
|
||||||
|
*
|
||||||
|
* If the input {@link Path} is null, a placeholder will be generated.
|
||||||
|
*
|
||||||
|
* @param image The source {@link BufferedImage}
|
||||||
|
* @param flipY Whether the image should flipped vertically (for OpenGL uses)
|
||||||
|
*
|
||||||
|
* @return The output {@link TPNImage}, never null
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since 20.2.0.0-alpha.1
|
||||||
|
* */
|
||||||
|
public static TPNImage loadImageSpecial(@Nullable BufferedImage image, boolean flipY)
|
||||||
|
{
|
||||||
if (image == null)
|
if (image == null)
|
||||||
{
|
{
|
||||||
Logger.log(SmartSeverity.WARNING, "[TPL] Null BufferedImage supplied, generating a placeholder.");
|
Logger.log(SmartSeverity.WARNING, "[TPL] Null BufferedImage supplied, generating a placeholder.");
|
||||||
|
|
||||||
remake = true;
|
return loadImageSpecial(placeholder, flipY);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
int width = image.getWidth();
|
||||||
width = image.getWidth();
|
int height = image.getHeight();
|
||||||
height = image.getHeight();
|
|
||||||
|
|
||||||
if (width > 16384 || height > 16384 || width < 1 || height < 1)
|
if (width > 16384 || height > 16384 || width < 1 || height < 1)
|
||||||
{
|
{
|
||||||
Logger.log(SmartSeverity.ERROR, "[TPL] BufferedImage size is invalid (< 1 or > 16384), generating a placeholder.");
|
Logger.log(SmartSeverity.ERROR, "[TPL] BufferedImage size is invalid (< 1 or > 16384), generating a placeholder.");
|
||||||
|
|
||||||
remake = true;
|
return loadImageSpecial(placeholder, flipY);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (remake)
|
|
||||||
{
|
|
||||||
width = PLACEHOLDER_SIZE;
|
|
||||||
height = PLACEHOLDER_SIZE;
|
|
||||||
|
|
||||||
Logger.log(SmartSeverity.INFO, "[TPL] Generating a substitute image...");
|
|
||||||
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect(width * height * 4);
|
|
||||||
buffer.order(ByteOrder.nativeOrder());
|
|
||||||
|
|
||||||
for (int i = 0; i < width * height; i++)
|
|
||||||
{
|
|
||||||
int x = i % width;
|
|
||||||
int y = i / width;
|
|
||||||
boolean checker = x / PLACEHOLDER_CHECKEDBOARD_SQUARE_SIZE % 2 == y / PLACEHOLDER_CHECKEDBOARD_SQUARE_SIZE % 2;
|
|
||||||
|
|
||||||
buffer.put((byte) 0xff); // A
|
|
||||||
buffer.put((byte) 0x00); // B
|
|
||||||
buffer.put((byte) 0x00); // G
|
|
||||||
buffer.put((byte) (checker ? 0xff : 0x00)); // R
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer.flip();
|
|
||||||
return new TPNImage(buffer, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.nativeOrder());
|
|
||||||
|
|
||||||
BufferedImage copy = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
|
BufferedImage copy = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
|
||||||
Graphics2D imgGraphics = copy.createGraphics();
|
Graphics2D imgGraphics = copy.createGraphics();
|
||||||
imgGraphics.drawImage(image, 0, copy.getHeight(), copy.getWidth(), 0, 0, 0, image.getWidth(), image.getHeight(), null); // I wonder if this is pixel-perfect
|
imgGraphics.drawImage(image,
|
||||||
|
0, flipY ? copy.getHeight() : 0, copy.getWidth(), flipY ? 0 : copy.getHeight(),
|
||||||
|
0, 0, image.getWidth(), image.getHeight(),
|
||||||
|
null); // I wonder if this is pixel-perfect
|
||||||
imgGraphics.dispose();
|
imgGraphics.dispose();
|
||||||
|
|
||||||
Raster data = copy.getData();
|
Raster data = copy.getRaster();
|
||||||
DataBuffer dataBuffer = data.getDataBuffer();
|
DataBuffer dataBuffer = data.getDataBuffer();
|
||||||
DataBufferByte byteBuffer = (DataBufferByte) dataBuffer;
|
DataBufferByte byteBuffer = (DataBufferByte) dataBuffer;
|
||||||
byte[] byteData = byteBuffer.getData();
|
byte[] byteData = byteBuffer.getData();
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocateDirect(width * height * 4).order(ByteOrder.nativeOrder());
|
||||||
buffer.put(byteData);
|
buffer.put(byteData);
|
||||||
buffer.flip();
|
buffer.flip();
|
||||||
|
|
||||||
return new TPNImage(buffer, width, height);
|
return new TPNImage(buffer, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TPJImage loadPixels(String file)
|
|
||||||
|
/**
|
||||||
|
* Writes a {@link BufferedImage} into a {@link TPNImage} buffer.
|
||||||
|
*
|
||||||
|
* If the input {@link Path} is null, a placeholder will be generated.
|
||||||
|
*
|
||||||
|
* @param image The source {@link BufferedImage}
|
||||||
|
*
|
||||||
|
* @return The output {@link TPNImage}, never null
|
||||||
|
*
|
||||||
|
* @see TPNImage
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
|
* */
|
||||||
|
public static TPNImage loadImage(@Nullable BufferedImage image)
|
||||||
{
|
{
|
||||||
TPJImage tImg = null;
|
return loadImageSpecial(image, true);
|
||||||
BufferedImage image = null;
|
|
||||||
|
|
||||||
boolean remake = false;
|
|
||||||
|
|
||||||
int width = 0;
|
|
||||||
int height = 0;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
image = ImageIO.read(new File(file));
|
|
||||||
width = image.getWidth();
|
|
||||||
height = image.getHeight();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Logger.log(SmartSeverity.ERROR, "[TPL] Image could not be loaded: " + file);
|
|
||||||
Logger.log(e);
|
|
||||||
|
|
||||||
remake = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width > 16384 || height > 16384 || width < 1 || height < 1)
|
|
||||||
{
|
|
||||||
Logger.log(SmartSeverity.ERROR, "[TPL] Image size is invalid (< 1 or > 16384): " + file);
|
|
||||||
Logger.log(SmartSeverity.ERROR, "[TPL] A replacement will be generated.");
|
|
||||||
|
|
||||||
remake = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remake)
|
|
||||||
{
|
|
||||||
width = PLACEHOLDER_SIZE;
|
|
||||||
height = PLACEHOLDER_SIZE;
|
|
||||||
|
|
||||||
tImg = new TPJImage(new int[width * height], width, height);
|
|
||||||
|
|
||||||
Logger.log(SmartSeverity.INFO, "[TPL] Generating a substitute image...");
|
|
||||||
|
|
||||||
for (int i = 0; i < width * height; i++)
|
|
||||||
{
|
|
||||||
int x = i % width;
|
|
||||||
int y = i / width;
|
|
||||||
boolean checker = x / PLACEHOLDER_CHECKEDBOARD_SQUARE_SIZE % 2 == y / PLACEHOLDER_CHECKEDBOARD_SQUARE_SIZE % 2;
|
|
||||||
|
|
||||||
tImg.data[i] = checker ? 0xffff0000 : 0xff000000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tImg;
|
|
||||||
}
|
|
||||||
|
|
||||||
tImg = new TPJImage(new int[width * height], width, height);
|
|
||||||
|
|
||||||
for (int i = 0; i < width * height; i++)
|
|
||||||
{
|
|
||||||
int pixel = image.getRGB(i % width, i / width);
|
|
||||||
|
|
||||||
tImg.data[i] = pixel;
|
|
||||||
}
|
|
||||||
|
|
||||||
return tImg;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,32 @@ package cz.tefek.pluto.tpl;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A wrapper around a native color buffer for easier handling
|
||||||
|
* by various APIs, such as OpenGL and GLFW.
|
||||||
|
*
|
||||||
|
* @implNote TPNImage is <em>always</em> ABGR due to image format
|
||||||
|
* limitations of {@link java.awt.image.BufferedImage}
|
||||||
|
*
|
||||||
|
* @author 493msi
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
|
*/
|
||||||
public class TPNImage
|
public class TPNImage
|
||||||
{
|
{
|
||||||
ByteBuffer data;
|
private final ByteBuffer data;
|
||||||
int width;
|
private final int width;
|
||||||
int height;
|
private final int height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link TPNImage} from the specified buffer, width and height.
|
||||||
|
*
|
||||||
|
* @param bfr The input {@link ByteBuffer}
|
||||||
|
* @param width This image's width
|
||||||
|
* @param height This image's height
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
|
* */
|
||||||
public TPNImage(ByteBuffer bfr, int width, int height)
|
public TPNImage(ByteBuffer bfr, int width, int height)
|
||||||
{
|
{
|
||||||
this.data = bfr;
|
this.data = bfr;
|
||||||
|
@ -15,18 +35,39 @@ public class TPNImage
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the width of the color buffer.
|
||||||
|
*
|
||||||
|
* @return The width of this {@link TPNImage}
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
|
* */
|
||||||
public int getWidth()
|
public int getWidth()
|
||||||
{
|
{
|
||||||
return this.width;
|
return this.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the height of the color buffer.
|
||||||
|
*
|
||||||
|
* @return The height of this {@link TPNImage}
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
|
* */
|
||||||
public int getHeight()
|
public int getHeight()
|
||||||
{
|
{
|
||||||
return this.height;
|
return this.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a read-only view of the color buffer.
|
||||||
|
*
|
||||||
|
* @return This image's color {@link ByteBuffer}
|
||||||
|
*
|
||||||
|
* @since pre-alpha
|
||||||
|
* */
|
||||||
public ByteBuffer getData()
|
public ByteBuffer getData()
|
||||||
{
|
{
|
||||||
return this.data;
|
return this.data.asReadOnlyBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package cz.tefek.pluto.engine.graphics.sprite;
|
package cz.tefek.pluto.engine.graphics.sprite;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
import cz.tefek.pluto.engine.graphics.texture.MagFilter;
|
import cz.tefek.pluto.engine.graphics.texture.MagFilter;
|
||||||
import cz.tefek.pluto.engine.graphics.texture.MinFilter;
|
import cz.tefek.pluto.engine.graphics.texture.MinFilter;
|
||||||
import cz.tefek.pluto.engine.graphics.texture.WrapMode;
|
import cz.tefek.pluto.engine.graphics.texture.WrapMode;
|
||||||
|
@ -11,7 +13,7 @@ public class DisposablePlaceholderSprite extends DisposableTextureSprite
|
||||||
{
|
{
|
||||||
super(new RectangleTexture());
|
super(new RectangleTexture());
|
||||||
|
|
||||||
this.spriteTexture.load((String) null, MagFilter.NEAREST, MinFilter.NEAREST, WrapMode.CLAMP_TO_EDGE, WrapMode.CLAMP_TO_EDGE);
|
this.spriteTexture.load((BufferedImage) null, MagFilter.NEAREST, MinFilter.NEAREST, WrapMode.CLAMP_TO_EDGE, WrapMode.CLAMP_TO_EDGE);
|
||||||
this.width = this.spriteTexture.getWidth();
|
this.width = this.spriteTexture.getWidth();
|
||||||
this.height = this.spriteTexture.getHeight();
|
this.height = this.spriteTexture.getHeight();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import cz.tefek.pluto.engine.graphics.sprite.Sprite;
|
||||||
import cz.tefek.pluto.engine.graphics.sprite.SpriteDisposable;
|
import cz.tefek.pluto.engine.graphics.sprite.SpriteDisposable;
|
||||||
import cz.tefek.pluto.engine.graphics.sprite.TileSprite;
|
import cz.tefek.pluto.engine.graphics.sprite.TileSprite;
|
||||||
import cz.tefek.pluto.io.logger.Logger;
|
import cz.tefek.pluto.io.logger.Logger;
|
||||||
import cz.tefek.pluto.io.logger.Severity;
|
import cz.tefek.pluto.io.logger.SmartSeverity;
|
||||||
|
|
||||||
public abstract class TiledSpriteSheet<T> extends SpriteSheet<T>
|
public abstract class TiledSpriteSheet<T> extends SpriteSheet<T>
|
||||||
{
|
{
|
||||||
|
@ -65,7 +65,7 @@ public abstract class TiledSpriteSheet<T> extends SpriteSheet<T>
|
||||||
|
|
||||||
protected void expand()
|
protected void expand()
|
||||||
{
|
{
|
||||||
Logger.logf(Severity.INFO, "Spritesheet #%d: Expanding from %dx%d to ", this.id, this.spriteSheetWidth, this.spriteSheetHeight);
|
Logger.logf(SmartSeverity.INFO, "Spritesheet #%d: Expanding from %dx%d to ", this.id, this.spriteSheetWidth, this.spriteSheetHeight);
|
||||||
|
|
||||||
this.spriteSheetWidth *= 2;
|
this.spriteSheetWidth *= 2;
|
||||||
this.spriteSheetHeight *= 2;
|
this.spriteSheetHeight *= 2;
|
||||||
|
@ -79,7 +79,7 @@ public abstract class TiledSpriteSheet<T> extends SpriteSheet<T>
|
||||||
|
|
||||||
protected void upscale(int factor)
|
protected void upscale(int factor)
|
||||||
{
|
{
|
||||||
Logger.logf(Severity.INFO, "Spritesheet #%d: Upscaling from %dx%d to ", this.id, this.tileWidth, this.tileHeight);
|
Logger.logf(SmartSeverity.INFO, "Spritesheet #%d: Upscaling from %dx%d to ", this.id, this.tileWidth, this.tileHeight);
|
||||||
|
|
||||||
this.tileWidth *= factor;
|
this.tileWidth *= factor;
|
||||||
this.tileHeight *= factor;
|
this.tileHeight *= factor;
|
||||||
|
|
|
@ -3,6 +3,8 @@ package cz.tefek.pluto.engine.buffer;
|
||||||
import org.lwjgl.BufferUtils;
|
import org.lwjgl.BufferUtils;
|
||||||
import org.lwjgl.glfw.GLFWImage;
|
import org.lwjgl.glfw.GLFWImage;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import cz.tefek.pluto.tpl.TPL;
|
import cz.tefek.pluto.tpl.TPL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,23 +30,27 @@ public class GLFWImageUtil
|
||||||
{
|
{
|
||||||
var icon = GLFWImage.create(icons.length);
|
var icon = GLFWImage.create(icons.length);
|
||||||
|
|
||||||
for (int iconIndex = 0; iconIndex < icons.length; iconIndex++)
|
for (String iconPath : icons)
|
||||||
{
|
{
|
||||||
var img = TPL.loadPixels(icons[iconIndex]);
|
var img = TPL.loadSpecial(Path.of(iconPath), false);
|
||||||
var imgData = img.getData();
|
var imgData = img.getData();
|
||||||
var imgWidth = img.getWidth();
|
int imgWidth = img.getWidth();
|
||||||
var imgHeight = img.getHeight();
|
int imgHeight = img.getHeight();
|
||||||
|
|
||||||
var byteBuf = BufferUtils.createByteBuffer(imgWidth * imgHeight * 4);
|
int pixelCount = imgWidth * imgHeight;
|
||||||
|
int bytesPerPixel = 4;
|
||||||
|
var byteBuf = BufferUtils.createByteBuffer(pixelCount * bytesPerPixel);
|
||||||
|
|
||||||
for (int i = 0; i < imgHeight * imgWidth; i++)
|
byte[] px = new byte[bytesPerPixel];
|
||||||
|
|
||||||
|
for (int i = 0; i < pixelCount; i++)
|
||||||
{
|
{
|
||||||
var data = imgData[i];
|
px[3] = imgData.get(); // A
|
||||||
|
px[2] = imgData.get(); // B
|
||||||
|
px[1] = imgData.get(); // G
|
||||||
|
px[0] = imgData.get(); // R
|
||||||
|
|
||||||
byteBuf.put((byte) ((data & 0x00ff0000) >> 16));
|
byteBuf.put(px);
|
||||||
byteBuf.put((byte) ((data & 0x0000ff00) >> 8));
|
|
||||||
byteBuf.put((byte) (data & 0x000000ff));
|
|
||||||
byteBuf.put((byte) ((data & 0xff000000) >> 24));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
byteBuf.flip();
|
byteBuf.flip();
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
package cz.tefek.pluto.engine.display;
|
package cz.tefek.pluto.engine.display;
|
||||||
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.*;
|
||||||
import org.lwjgl.glfw.GLFWErrorCallback;
|
|
||||||
import org.lwjgl.glfw.GLFWImage;
|
|
||||||
import org.lwjgl.glfw.GLFWVidMode;
|
|
||||||
import org.lwjgl.glfw.GLFWWindowSizeCallback;
|
|
||||||
import org.lwjgl.opengl.ARBDebugOutput;
|
import org.lwjgl.opengl.ARBDebugOutput;
|
||||||
import org.lwjgl.opengl.GL;
|
import org.lwjgl.opengl.GL;
|
||||||
import org.lwjgl.opengl.GL33;
|
import org.lwjgl.opengl.GL33;
|
||||||
|
@ -13,7 +9,6 @@ import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import cz.tefek.pluto.engine.gl.GLDebugInfo;
|
import cz.tefek.pluto.engine.gl.GLDebugInfo;
|
||||||
import cz.tefek.pluto.io.logger.Logger;
|
import cz.tefek.pluto.io.logger.Logger;
|
||||||
import cz.tefek.pluto.io.logger.Severity;
|
|
||||||
import cz.tefek.pluto.io.logger.SmartSeverity;
|
import cz.tefek.pluto.io.logger.SmartSeverity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,7 +67,7 @@ public class Display
|
||||||
{
|
{
|
||||||
if (Display.this.debugMode)
|
if (Display.this.debugMode)
|
||||||
{
|
{
|
||||||
Logger.logf(Severity.INFO, "Resized to %dx%d.\n", width, height);
|
Logger.logf(SmartSeverity.INFO, "Resized to %dx%d.\n", width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
Display.this.width = width;
|
Display.this.width = width;
|
||||||
|
|
|
@ -1,23 +1,21 @@
|
||||||
package cz.tefek.pluto.engine.graphics.texture;
|
package cz.tefek.pluto.engine.graphics.texture;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL33;
|
import org.lwjgl.opengl.GL33;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import cz.tefek.pluto.io.asl.resource.ResourceAddress;
|
import cz.tefek.pluto.io.asl.resource.ResourceAddress;
|
||||||
import cz.tefek.pluto.io.logger.Logger;
|
import cz.tefek.pluto.io.logger.Logger;
|
||||||
import cz.tefek.pluto.io.logger.Severity;
|
|
||||||
import cz.tefek.pluto.io.logger.SmartSeverity;
|
import cz.tefek.pluto.io.logger.SmartSeverity;
|
||||||
import cz.tefek.pluto.tpl.TPL;
|
import cz.tefek.pluto.tpl.TPL;
|
||||||
import cz.tefek.pluto.tpl.TPNImage;
|
import cz.tefek.pluto.tpl.TPNImage;
|
||||||
|
|
||||||
public abstract class Texture
|
public abstract class Texture
|
||||||
{
|
{
|
||||||
protected int glID = 0;
|
protected int glID;
|
||||||
protected final int type;
|
protected final int type;
|
||||||
protected final int dimensions;
|
protected final int dimensions;
|
||||||
|
|
||||||
|
@ -138,7 +136,7 @@ public abstract class Texture
|
||||||
{
|
{
|
||||||
if (wrapOptions.length != this.dimensions)
|
if (wrapOptions.length != this.dimensions)
|
||||||
{
|
{
|
||||||
Logger.log(Severity.ERROR, "Error: WrapMode option count does not match texture's dimensions.");
|
Logger.log(SmartSeverity.ERROR, "Error: WrapMode option count does not match texture's dimensions.");
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,6 +196,7 @@ public abstract class Texture
|
||||||
this.load(file.toPath(), magFilter, minFilter, wrap);
|
this.load(file.toPath(), magFilter, minFilter, wrap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public void load(String file, MagFilter magFilter, MinFilter minFilter, WrapMode... wrap)
|
public void load(String file, MagFilter magFilter, MinFilter minFilter, WrapMode... wrap)
|
||||||
{
|
{
|
||||||
TPNImage image = TPL.load(file);
|
TPNImage image = TPL.load(file);
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
package cz.tefek.pluto.engine.graphics.texture.texture2d;
|
package cz.tefek.pluto.engine.graphics.texture.texture2d;
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL33;
|
import org.lwjgl.opengl.GL33;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import cz.tefek.pluto.engine.graphics.texture.Texture;
|
import cz.tefek.pluto.engine.graphics.texture.Texture;
|
||||||
import cz.tefek.pluto.engine.graphics.texture.WrapMode;
|
import cz.tefek.pluto.engine.graphics.texture.WrapMode;
|
||||||
import cz.tefek.pluto.io.logger.Logger;
|
import cz.tefek.pluto.io.logger.Logger;
|
||||||
import cz.tefek.pluto.io.logger.Severity;
|
import cz.tefek.pluto.io.logger.SmartSeverity;
|
||||||
|
|
||||||
public class RectangleTexture extends Texture
|
public class RectangleTexture extends Texture
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ public class RectangleTexture extends Texture
|
||||||
{
|
{
|
||||||
if (Arrays.stream(wrapOptions).anyMatch(WrapMode.repeatModes::contains))
|
if (Arrays.stream(wrapOptions).anyMatch(WrapMode.repeatModes::contains))
|
||||||
{
|
{
|
||||||
Logger.log(Severity.ERROR, "Error: Rectangle textures do not support repeat wrap modes!");
|
Logger.log(SmartSeverity.ERROR, "Error: Rectangle textures do not support repeat wrap modes!");
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue