From 9fe8ab7fbe4f983a8fc450f3d15a7e9c7a0c53fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Pluta?= Date: Tue, 22 Jul 2025 15:32:26 +0200 Subject: [PATCH] Wrap Texture with TexturedMaterial --- .../core/gl/object/material/Material.java | 17 ++++++ .../core/gl/object/texture/Texture.java | 17 +++--- .../gl/object/texture/TexturedMaterial.java | 61 +++++++++++++++++++ .../animation/model/DefaultAnimation.java | 6 +- .../character/model/DefaultCharacter.java | 10 +-- .../engine/world/icon/model/DefaultIcon.java | 10 +-- .../world/image/model/DefaultImage.java | 7 ++- .../map/layer/autotile/BaseAutoTileLayer.java | 2 +- .../map/layer/color/DefaultColorLayer.java | 5 +- .../world/map/layer/util/ChunkManager.java | 2 +- .../world/map/layer/util/TileChunk.java | 8 +-- .../base/engine/world/object/Sprite.java | 54 ++++++++++++++++ 12 files changed, 168 insertions(+), 31 deletions(-) create mode 100644 engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/texture/TexturedMaterial.java diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/material/Material.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/material/Material.java index a3ce75c2..a222627b 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/material/Material.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/material/Material.java @@ -1,5 +1,8 @@ package com.bartlomiejpluta.base.engine.core.gl.object.material; +import com.bartlomiejpluta.base.engine.core.gl.object.color.Color; +import com.bartlomiejpluta.base.engine.core.gl.object.texture.Texture; +import com.bartlomiejpluta.base.engine.core.gl.object.texture.TexturedMaterial; import com.bartlomiejpluta.base.internal.render.Renderable; import org.joml.Vector3fc; import org.joml.Vector4fc; @@ -28,4 +31,18 @@ public interface Material extends Renderable { int getRows(); float[][] getTextureCoordinatesForAllFrames(); + + /** + * Creates a material with single, uniform color. + */ + static Material unicolor(float red, float green, float blue, float alpha) { + return new Color(red, green, blue, alpha); + } + + /** + * Creates a textured material + */ + static TexturedMaterial textured(Texture texture) { + return new TexturedMaterial(texture); + } } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/texture/Texture.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/texture/Texture.java index aa5870dc..38cbe8b3 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/texture/Texture.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/texture/Texture.java @@ -2,11 +2,10 @@ package com.bartlomiejpluta.base.engine.core.gl.object.texture; import com.bartlomiejpluta.base.api.camera.Camera; import com.bartlomiejpluta.base.api.screen.Screen; -import com.bartlomiejpluta.base.engine.core.gl.object.color.Color; -import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; import com.bartlomiejpluta.base.engine.core.gl.shader.constant.UniformName; import com.bartlomiejpluta.base.engine.error.AppException; import com.bartlomiejpluta.base.internal.gc.Disposable; +import com.bartlomiejpluta.base.internal.render.Renderable; import com.bartlomiejpluta.base.internal.render.ShaderManager; import lombok.Getter; import org.joml.Vector2f; @@ -21,7 +20,7 @@ import static org.lwjgl.opengl.GL13.glActiveTexture; import static org.lwjgl.stb.STBImage.stbi_failure_reason; import static org.lwjgl.stb.STBImage.stbi_load_from_memory; -public class Texture extends Color implements Material, Disposable { +public class Texture implements Renderable, Disposable { private static final int DESIRED_CHANNELS = 4; private final int textureId; @@ -42,10 +41,10 @@ public class Texture extends Color implements Material, Disposable { private final int columns; @Getter - private final Vector2fc spriteFragment; + private final Vector2fc frameFragment; @Getter - private final Vector2fc spriteSize; + private final Vector2fc frameSize; Texture(String textureFilename, ByteBuffer buffer, int rows, int columns) { try (var stack = MemoryStack.stackPush()) { @@ -74,12 +73,11 @@ public class Texture extends Color implements Material, Disposable { this.rows = rows; this.columns = columns; - this.spriteFragment = new Vector2f(1 / (float) columns, 1 / (float) rows); - this.spriteSize = new Vector2f(width, height).mul(spriteFragment); + this.frameFragment = new Vector2f(1 / (float) columns, 1 / (float) rows); + this.frameSize = new Vector2f(width, height).mul(frameFragment); } } - @Override public float[][] getTextureCoordinatesForAllFrames() { var array = new float[rows * columns][]; @@ -95,7 +93,7 @@ public class Texture extends Color implements Material, Disposable { } public float[] getTextureCoordinates(int x, int y) { - return getTextureCoordinates(x * (int) spriteSize.x(), y * (int) spriteSize.y(), (int) spriteSize.x(), (int) spriteSize.y()); + return getTextureCoordinates(x * (int) frameSize.x(), y * (int) frameSize.y(), (int) frameSize.x(), (int) frameSize.y()); } public float[] getTextureCoordinates(int textureX, int textureY, int tileWidth, int tileHeight) { @@ -118,7 +116,6 @@ public class Texture extends Color implements Material, Disposable { @Override public void render(Screen screen, Camera camera, ShaderManager shaderManager) { shaderManager.setUniform(UniformName.UNI_HAS_OBJECT_TEXTURE, true); - shaderManager.setUniform(UniformName.UNI_OBJECT_COLOR, color); shaderManager.setUniform(UniformName.UNI_TEXTURE_SAMPLER, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, textureId); diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/texture/TexturedMaterial.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/texture/TexturedMaterial.java new file mode 100644 index 00000000..8eaf1b93 --- /dev/null +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/core/gl/object/texture/TexturedMaterial.java @@ -0,0 +1,61 @@ +package com.bartlomiejpluta.base.engine.core.gl.object.texture; + +import com.bartlomiejpluta.base.api.camera.Camera; +import com.bartlomiejpluta.base.api.screen.Screen; +import com.bartlomiejpluta.base.engine.core.gl.object.color.Color; +import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; +import com.bartlomiejpluta.base.engine.core.gl.shader.constant.UniformName; +import com.bartlomiejpluta.base.internal.render.ShaderManager; +import lombok.Getter; +import lombok.NonNull; +import org.joml.Vector2fc; + +@Getter +public class TexturedMaterial extends Color implements Material { + private final Texture texture; + + public TexturedMaterial(@NonNull Texture texture) { + this.texture = texture; + } + + @Override + public float[][] getTextureCoordinatesForAllFrames() { + return texture.getTextureCoordinatesForAllFrames(); + } + + @Override + public int getColumns() { + return texture.getColumns(); + } + + @Override + public int getRows() { + return texture.getRows(); + } + + public String getFileName() { + return texture.getFileName(); + } + + public int getHeight() { + return texture.getHeight(); + } + + public int getWidth() { + return texture.getWidth(); + } + + public Vector2fc getFrameFragment() { + return texture.getFrameFragment(); + } + + public Vector2fc getFrameSize() { + return texture.getFrameSize(); + } + + @Override + public void render(Screen screen, Camera camera, ShaderManager shaderManager) { + shaderManager.setUniform(UniformName.UNI_OBJECT_COLOR, color); + texture.render(screen, camera, shaderManager); + } +} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/animation/model/DefaultAnimation.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/animation/model/DefaultAnimation.java index 2b27089d..fe152144 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/animation/model/DefaultAnimation.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/animation/model/DefaultAnimation.java @@ -6,6 +6,7 @@ import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer; import com.bartlomiejpluta.base.api.move.AnimationMovement; import com.bartlomiejpluta.base.api.move.Direction; import com.bartlomiejpluta.base.api.move.Movement; +import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.QuadMesh; import com.bartlomiejpluta.base.engine.core.gl.object.texture.Texture; import com.bartlomiejpluta.base.engine.world.movement.MovableSprite; @@ -19,6 +20,7 @@ import org.joml.Vector2fc; import java.util.concurrent.CompletableFuture; +import static com.bartlomiejpluta.base.engine.core.gl.object.material.Material.textured; import static com.bartlomiejpluta.base.util.path.PathProgress.DONE; import static com.bartlomiejpluta.base.util.path.PathProgress.SEGMENT_FAILED; @@ -52,11 +54,11 @@ public class DefaultAnimation extends MovableSprite implements Animation { private final CompletableFuture future = new CompletableFuture<>(); public DefaultAnimation(QuadMesh mesh, Texture texture, @NonNull Vector2fc[] frames) { - super(mesh, texture); + super(mesh, textured(texture)); this.frames = frames; this.lastFrameIndex = frames.length - 1; - this.animationSpriteSize = texture.getSpriteSize(); + this.animationSpriteSize = texture.getFrameSize(); super.setScale(animationSpriteSize.x() * animationScale.x, animationSpriteSize.y() * animationScale.y); } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/character/model/DefaultCharacter.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/character/model/DefaultCharacter.java index e6aba496..5de5e8d5 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/character/model/DefaultCharacter.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/character/model/DefaultCharacter.java @@ -7,6 +7,7 @@ import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer; import com.bartlomiejpluta.base.api.move.CharacterMovement; import com.bartlomiejpluta.base.api.move.Direction; import com.bartlomiejpluta.base.api.move.Movement; +import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.QuadMesh; import com.bartlomiejpluta.base.engine.error.AppException; import com.bartlomiejpluta.base.engine.world.character.manager.CharacterSetManager; @@ -24,6 +25,7 @@ import java.util.Queue; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; +import static com.bartlomiejpluta.base.engine.core.gl.object.material.Material.textured; import static java.util.Objects.requireNonNull; @EqualsAndHashCode(callSuper = true) @@ -59,13 +61,13 @@ public class DefaultCharacter extends MovableSprite implements Character { } private DefaultCharacter(QuadMesh mesh, @NonNull CharacterSet characterSet, @NonNull CharacterSetManager characterSetManager, int defaultSpriteColumn) { - super(mesh, characterSet.getTexture()); + super(mesh, textured(characterSet.getTexture())); this.defaultSpriteColumn = defaultSpriteColumn; this.characterSetManager = characterSetManager; this.faceDirection = Direction.DOWN; this.characterSet = characterSet; - this.characterSetSize = characterSet.getTexture().getSpriteSize(); + this.characterSetSize = characterSet.getTexture().getFrameSize(); super.setScale(characterSetSize.x() * characterScale.x, characterSetSize.y() * characterScale.y); @@ -115,9 +117,9 @@ public class DefaultCharacter extends MovableSprite implements Character { @Override public void changeCharacterSet(String characterSetUid) { this.characterSet = characterSetManager.loadObject(characterSetUid); - this.characterSetSize = characterSet.getTexture().getSpriteSize(); + this.characterSetSize = characterSet.getTexture().getFrameSize(); super.setScale(characterSetSize.x() * characterScale.x, characterSetSize.y() * characterScale.y); - setMaterial(characterSet.getTexture()); + applyTextureAndPreserveCurrentColor(characterSet.getTexture()); } @Override diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/icon/model/DefaultIcon.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/icon/model/DefaultIcon.java index 947ef80c..29a792c7 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/icon/model/DefaultIcon.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/icon/model/DefaultIcon.java @@ -18,6 +18,8 @@ import org.joml.Vector2fc; import java.util.function.Consumer; +import static com.bartlomiejpluta.base.engine.core.gl.object.material.Material.textured; + public class DefaultIcon extends Sprite implements Icon { private final EventHandler eventHandler = new EventHandler(); private final IconSetManager iconSetManager; @@ -49,11 +51,11 @@ public class DefaultIcon extends Sprite implements Icon { } private DefaultIcon(@NonNull IconSetManager iconSetManager, QuadMesh mesh, @NonNull Texture texture, @NonNull String iconSetUid, int row, int column) { - super(mesh, texture); + super(mesh, textured(texture)); this.iconSetManager = iconSetManager; setFrame(row, column); - this.iconSetSize = texture.getSpriteSize(); + this.iconSetSize = texture.getFrameSize(); super.setScale(iconSetSize.x() * iconScale.x, iconSetSize.y() * iconScale.y); this.iconSetUid = iconSetUid; @@ -81,14 +83,14 @@ public class DefaultIcon extends Sprite implements Icon { @Override public void changeIcon(String iconSetUid, int row, int column) { var texture = iconSetManager.loadObject(iconSetUid); - setMaterial(texture); + applyTextureAndPreserveCurrentColor(texture); setFrame(row, column); this.iconSetUid = iconSetUid; this.iconSetRow = row; this.iconSetColumn = column; - this.iconSetSize = texture.getSpriteSize(); + this.iconSetSize = texture.getFrameSize(); super.setScale(iconSetSize.x() * iconScale.x, iconSetSize.y() * iconScale.y); } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/image/model/DefaultImage.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/image/model/DefaultImage.java index 44af96a1..bc325bd2 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/image/model/DefaultImage.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/image/model/DefaultImage.java @@ -3,11 +3,14 @@ package com.bartlomiejpluta.base.engine.world.image.model; import com.bartlomiejpluta.base.api.image.Image; import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.QuadMesh; +import com.bartlomiejpluta.base.engine.core.gl.object.texture.Texture; import com.bartlomiejpluta.base.engine.world.object.Sprite; import lombok.Getter; import lombok.NonNull; import org.joml.Vector2f; +import static com.bartlomiejpluta.base.engine.core.gl.object.material.Material.textured; + @Getter public class DefaultImage extends Sprite implements Image { private final Vector2f imageScale = new Vector2f(1, 1); @@ -17,8 +20,8 @@ public class DefaultImage extends Sprite implements Image { private final int width; private final int height; - public DefaultImage(QuadMesh mesh, @NonNull Material texture, int primaryWidth, int primaryHeight, int factor) { - super(mesh, texture); + public DefaultImage(QuadMesh mesh, @NonNull Texture texture, int primaryWidth, int primaryHeight, int factor) { + super(mesh, textured(texture)); this.primaryWidth = primaryWidth; this.primaryHeight = primaryHeight; this.factor = factor; diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/autotile/BaseAutoTileLayer.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/autotile/BaseAutoTileLayer.java index a3bf3ad7..3da75e49 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/autotile/BaseAutoTileLayer.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/autotile/BaseAutoTileLayer.java @@ -41,7 +41,7 @@ public abstract class BaseAutoTileLayer extends BaseLayer { tileSet.getTexture(), rows * 4, columns * 4, - new Vector2f(tileSet.getTexture().getSpriteSize()).div(2) + new Vector2f(tileSet.getTexture().getFrameSize()).div(2) ); stream(layer).forEach(tiles -> fill(tiles, EMPTY_TILE)); diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/color/DefaultColorLayer.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/color/DefaultColorLayer.java index 6f55f335..0229580c 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/color/DefaultColorLayer.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/color/DefaultColorLayer.java @@ -4,7 +4,6 @@ import com.bartlomiejpluta.base.api.camera.Camera; import com.bartlomiejpluta.base.api.map.layer.color.ColorLayer; import com.bartlomiejpluta.base.api.map.model.GameMap; import com.bartlomiejpluta.base.api.screen.Screen; -import com.bartlomiejpluta.base.engine.core.gl.object.color.Color; import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.MeshManager; import com.bartlomiejpluta.base.engine.world.map.layer.base.BaseLayer; @@ -15,6 +14,8 @@ import lombok.NonNull; import org.joml.Matrix4fc; import org.joml.Vector2fc; +import static com.bartlomiejpluta.base.engine.core.gl.object.material.Material.unicolor; + public class DefaultColorLayer extends BaseLayer implements ColorLayer { private static final float QUAD_WIDTH = 1; private static final float QUAD_HEIGHT = 1; @@ -150,7 +151,7 @@ public class DefaultColorLayer extends BaseLayer implements ColorLayer { private static class ColorPlane extends Sprite { public ColorPlane(@NonNull MeshManager meshManager, float red, float green, float blue, float alpha) { - super(meshManager.createQuad(QUAD_WIDTH, QUAD_HEIGHT, QUAD_ORIGIN_X, QUAD_ORIGIN_Y), new Color(red, green, blue, alpha)); + super(meshManager.createQuad(QUAD_WIDTH, QUAD_HEIGHT, QUAD_ORIGIN_X, QUAD_ORIGIN_Y), unicolor(red, green, blue, alpha)); } } } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/util/ChunkManager.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/util/ChunkManager.java index 41892dd9..362877f2 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/util/ChunkManager.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/util/ChunkManager.java @@ -34,7 +34,7 @@ public class ChunkManager implements Renderable, Disposable { } public ChunkManager(MeshManager meshManager, Texture tileSet, int rows, int columns, int chunkSize) { - this(meshManager, tileSet, rows, columns, tileSet.getSpriteSize(), chunkSize); + this(meshManager, tileSet, rows, columns, tileSet.getFrameSize(), chunkSize); } public ChunkManager(MeshManager meshManager, @NonNull Texture tileSet, int rows, int columns, @NonNull Vector2fc tileSize, int chunkSize) { diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/util/TileChunk.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/util/TileChunk.java index 8d80e436..4444a593 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/util/TileChunk.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/util/TileChunk.java @@ -2,12 +2,10 @@ package com.bartlomiejpluta.base.engine.world.map.layer.util; import com.bartlomiejpluta.base.api.camera.Camera; import com.bartlomiejpluta.base.api.screen.Screen; -import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.MeshManager; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.QuadTemplate; import com.bartlomiejpluta.base.engine.core.gl.object.texture.Texture; -import com.bartlomiejpluta.base.engine.core.gl.shader.constant.Shader; import com.bartlomiejpluta.base.engine.core.gl.shader.constant.UniformName; import com.bartlomiejpluta.base.engine.world.object.Model; import com.bartlomiejpluta.base.internal.gc.Disposable; @@ -33,7 +31,7 @@ public class TileChunk extends Model implements Placeable, Renderable, Disposabl this.tileSet = tileSet; this.chunkSize = chunkSize; this.mesh = meshManager.createMesh(chunkSize * chunkSize); - this.template = new QuadTemplate(tileSet.getSpriteSize().x(), tileSet.getSpriteSize().y(), originX, originY); + this.template = new QuadTemplate(tileSet.getFrameSize().x(), tileSet.getFrameSize().y(), originX, originY); this.originX = originX; this.originY = originY; } @@ -82,7 +80,7 @@ public class TileChunk extends Model implements Placeable, Renderable, Disposabl @Override public float getMaxX() { float scaledOriginX = originX * scaleX; - float scaledChunkWidth = chunkSize * tileSet.getSpriteSize().x() * scaleX; + float scaledChunkWidth = chunkSize * tileSet.getFrameSize().x() * scaleX; return getPosition().x() + scaledChunkWidth - scaledOriginX; } @@ -95,7 +93,7 @@ public class TileChunk extends Model implements Placeable, Renderable, Disposabl @Override public float getMaxY() { float scaledOriginY = originY * scaleY; - float scaledChunkHeight = chunkSize * tileSet.getSpriteSize().y() * scaleY; + float scaledChunkHeight = chunkSize * tileSet.getFrameSize().y() * scaleY; return getPosition().y() + scaledChunkHeight - scaledOriginY; } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/object/Sprite.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/object/Sprite.java index bf7efb42..1dab7c96 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/object/Sprite.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/object/Sprite.java @@ -4,6 +4,7 @@ import com.bartlomiejpluta.base.api.camera.Camera; import com.bartlomiejpluta.base.api.screen.Screen; import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.QuadMesh; +import com.bartlomiejpluta.base.engine.core.gl.object.texture.Texture; import com.bartlomiejpluta.base.engine.core.gl.shader.constant.UniformName; import com.bartlomiejpluta.base.engine.world.location.LocationableModel; import com.bartlomiejpluta.base.internal.render.BoundingBox; @@ -12,6 +13,10 @@ import com.bartlomiejpluta.base.internal.render.ShaderManager; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NonNull; +import org.joml.Vector3fc; +import org.joml.Vector4fc; + +import static com.bartlomiejpluta.base.engine.core.gl.object.material.Material.textured; @EqualsAndHashCode(callSuper = true) public abstract class Sprite extends LocationableModel implements Renderable, BoundingBox { @@ -49,6 +54,19 @@ public abstract class Sprite extends LocationableModel implements Renderable, Bo updateTextureCoordinates(); } + /** + * Replaces current material with textured one but preserves the color. + * For example if some sprite is 0.4 opaque but needs to change its texture, + * this function will apply new texture keeping the 0.4 opacity in opposite to {@link #setMaterial(Material)}, + * which completely replaces the material including its color. + * @param texture - desired texture to be applied + */ + protected void applyTextureAndPreserveCurrentColor(@NonNull Texture texture) { + var currentColor = material.getColor(); + setMaterial(textured(texture)); + material.setColor(currentColor); + } + public void setFrame(int row, int column) { setFrame(row * material.getColumns() + column); } @@ -83,6 +101,42 @@ public abstract class Sprite extends LocationableModel implements Renderable, Bo return getPosition().y() + scaledChunkHeight - scaledOriginY; } + public Vector4fc getColor() { + return material.getColor(); + } + + public void setColor(Vector4fc color) { + material.setColor(color); + } + + public void setColor(Vector3fc color) { + material.setColor(color); + } + + public void setColor(float red, float green, float blue, float alpha) { + material.setColor(red, green, blue, alpha); + } + + public void setColor(float red, float green, float blue) { + material.setColor(red, green, blue); + } + + public void setRed(float red) { + material.setRed(red); + } + + public void setGreen(float green) { + material.setGreen(green); + } + + public void setBlue(float blue) { + material.setBlue(blue); + } + + public void setAlpha(float alpha) { + material.setAlpha(alpha); + } + @Override public void render(Screen screen, Camera camera, ShaderManager shaderManager) { if (!camera.containsBox(this)) {