Wrap Texture with TexturedMaterial

This commit is contained in:
2025-07-22 15:32:26 +02:00
parent 4fede6a0fc
commit a66b450203
19 changed files with 453 additions and 46 deletions

View File

@@ -1,5 +1,6 @@
package com.bartlomiejpluta.base.api.animation;
import com.bartlomiejpluta.base.api.color.Colorful;
import com.bartlomiejpluta.base.api.map.layer.base.Layer;
import com.bartlomiejpluta.base.api.move.Movable;
import com.bartlomiejpluta.base.internal.program.Updatable;
@@ -8,7 +9,7 @@ import com.bartlomiejpluta.base.util.path.Path;
import java.util.concurrent.CompletableFuture;
public interface Animation extends Movable, Animated, Renderable, Updatable {
public interface Animation extends Movable, Animated, Colorful, Renderable, Updatable {
Integer getRepeat();

View File

@@ -1,6 +1,7 @@
package com.bartlomiejpluta.base.api.character;
import com.bartlomiejpluta.base.api.animation.Animated;
import com.bartlomiejpluta.base.api.color.Colorful;
import com.bartlomiejpluta.base.api.entity.Entity;
import com.bartlomiejpluta.base.api.move.Direction;
import com.bartlomiejpluta.base.api.move.Movable;
@@ -26,10 +27,10 @@ import java.util.concurrent.CompletableFuture;
* damaged box).
*
* <p>This interface combines movement capabilities ({@link Movable}), animation features
* ({@link Animated}), and entity properties ({@link Entity}) to create a complete
* ({@link Animated}), coloring capabilities ({@link Colorful}), and entity properties ({@link Entity}) to create a complete
* character system for 2D games.
*/
public interface Character extends Movable, Animated, Entity {
public interface Character extends Movable, Animated, Colorful, Entity {
/**
* Initiates movement in the specified direction.

View File

@@ -0,0 +1,123 @@
package com.bartlomiejpluta.base.api.color;
import org.joml.Vector3fc;
import org.joml.Vector4fc;
/**
* Interface for objects that can be colored and have their color properties modified.
* This interface provides a comprehensive API for managing RGBA color values using
* various input formats including JOML vectors, individual float components, and
* packed integer values.
*
* <p>Color components are expected to be in the range [0.0, 1.0] for float values,
* where 0.0 represents no intensity and 1.0 represents full intensity.</p>
*/
public interface Colorful {
/**
* Returns the current color of this object.
*
* @return a Vector4fc containing the RGBA color components, where:
* x = red, y = green, z = blue, w = alpha.
* All components are in the range [0.0, 1.0].
*/
Vector4fc getColor();
/**
* Sets the color of this object using a 4D vector.
*
* @param color a Vector4fc containing the RGBA color components, where:
* x = red, y = green, z = blue, w = alpha.
* All components should be in the range [0.0, 1.0].
* @throws NullPointerException if color is null
*/
void setColor(Vector4fc color);
/**
* Sets the RGB color components of this object using a 3D vector.
* The alpha component will remain unchanged or be set to a default value.
*
* @param color a Vector3fc containing the RGB color components, where:
* x = red, y = green, z = blue.
* All components should be in the range [0.0, 1.0].
* @throws NullPointerException if color is null
*/
void setColor(Vector3fc color);
/**
* Sets the RGBA color components of this object using individual float values.
*
* @param red the red component in the range [0.0, 1.0]
* @param green the green component in the range [0.0, 1.0]
* @param blue the blue component in the range [0.0, 1.0]
* @param alpha the alpha component in the range [0.0, 1.0]
*/
void setColor(float red, float green, float blue, float alpha);
/**
* Sets the RGB color components of this object using individual float values.
* The alpha component will remain unchanged or be set to a default value.
*
* @param red the red component in the range [0.0, 1.0]
* @param green the green component in the range [0.0, 1.0]
* @param blue the blue component in the range [0.0, 1.0]
*/
void setColor(float red, float green, float blue);
/**
* Sets the color of this object using a packed RGBA integer value.
* The integer is expected to be in RGBA format where each component
* occupies 8 bits in the range [0, 255] and is automatically converted
* to the [0.0, 1.0] range by dividing by 255.
*
* <p>The bit layout is as follows:</p>
* <ul>
* <li>Bits 24-31: Red component</li>
* <li>Bits 16-23: Green component</li>
* <li>Bits 8-15: Blue component</li>
* <li>Bits 0-7: Alpha component</li>
* </ul>
*
* <p>For example, {@code 0xFF0000FF} represents full red with full alpha,
* while green and blue are zero.</p>
*
* @param rgba the packed RGBA color value
*/
default void setColor(int rgba) {
setColor(
((rgba >>> 24) & 0xFF) / 255f,
((rgba >>> 16) & 0xFF) / 255f,
((rgba >>> 8) & 0xFF) / 255f,
(rgba & 0xFF) / 255f
);
}
/**
* Sets only the red color component of this object.
*
* @param red the red component in the range [0.0, 1.0]
*/
void setRed(float red);
/**
* Sets only the green color component of this object.
*
* @param green the green component in the range [0.0, 1.0]
*/
void setGreen(float green);
/**
* Sets only the blue color component of this object.
*
* @param blue the blue component in the range [0.0, 1.0]
*/
void setBlue(float blue);
/**
* Sets only the alpha (transparency) component of this object.
*
* @param alpha the alpha component in the range [0.0, 1.0], where
* 0.0 is fully transparent and 1.0 is fully opaque
*/
void setAlpha(float alpha);
}

View File

@@ -1,8 +1,9 @@
package com.bartlomiejpluta.base.api.icon;
import com.bartlomiejpluta.base.api.color.Colorful;
import com.bartlomiejpluta.base.api.entity.Entity;
public interface Icon extends Entity {
public interface Icon extends Colorful, Entity {
void changeIcon(int row, int column);
void changeIcon(String iconSetUid, int row, int column);

View File

@@ -11,9 +11,7 @@ import com.bartlomiejpluta.base.api.screen.Screen;
import com.bartlomiejpluta.base.internal.object.Placeable;
import com.bartlomiejpluta.base.internal.render.ShaderManager;
import com.bartlomiejpluta.base.util.path.Path;
import org.joml.Matrix4fc;
import org.joml.Vector2fc;
import org.joml.Vector2ic;
import org.joml.*;
import java.util.concurrent.CompletableFuture;
@@ -294,6 +292,51 @@ public abstract class AnimationDelegate implements Animation {
return animation.getLayer();
}
@Override
public Vector4fc getColor() {
return animation.getColor();
}
@Override
public void setColor(Vector4fc color) {
animation.setColor(color);
}
@Override
public void setColor(Vector3fc color) {
animation.setColor(color);
}
@Override
public void setColor(float red, float green, float blue, float alpha) {
animation.setColor(red, green, blue, alpha);
}
@Override
public void setColor(float red, float green, float blue) {
animation.setColor(red, green, blue);
}
@Override
public void setRed(float red) {
animation.setRed(red);
}
@Override
public void setGreen(float green) {
animation.setGreen(green);
}
@Override
public void setBlue(float blue) {
animation.setBlue(blue);
}
@Override
public void setAlpha(float alpha) {
animation.setAlpha(alpha);
}
@Override
public void render(Screen screen, Camera camera, ShaderManager shaderManager) {
animation.render(screen, camera, shaderManager);

View File

@@ -12,9 +12,7 @@ import com.bartlomiejpluta.base.api.move.Movement;
import com.bartlomiejpluta.base.api.screen.Screen;
import com.bartlomiejpluta.base.internal.object.Placeable;
import com.bartlomiejpluta.base.internal.render.ShaderManager;
import org.joml.Matrix4fc;
import org.joml.Vector2fc;
import org.joml.Vector2ic;
import org.joml.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Consumer;
@@ -328,6 +326,51 @@ public abstract class CharacterDelegate implements Character {
character.abortMove();
}
@Override
public Vector4fc getColor() {
return character.getColor();
}
@Override
public void setColor(Vector4fc color) {
character.setColor(color);
}
@Override
public void setColor(Vector3fc color) {
character.setColor(color);
}
@Override
public void setColor(float red, float green, float blue, float alpha) {
character.setColor(red, green, blue, alpha);
}
@Override
public void setColor(float red, float green, float blue) {
character.setColor(red, green, blue);
}
@Override
public void setRed(float red) {
character.setRed(red);
}
@Override
public void setGreen(float green) {
character.setGreen(green);
}
@Override
public void setBlue(float blue) {
character.setBlue(blue);
}
@Override
public void setAlpha(float alpha) {
character.setAlpha(alpha);
}
@Override
public void update(float dt) {
character.update(dt);

View File

@@ -11,9 +11,7 @@ import com.bartlomiejpluta.base.api.screen.Screen;
import com.bartlomiejpluta.base.internal.object.Placeable;
import com.bartlomiejpluta.base.internal.render.ShaderManager;
import lombok.NonNull;
import org.joml.Matrix4fc;
import org.joml.Vector2fc;
import org.joml.Vector2ic;
import org.joml.*;
import java.util.function.Consumer;
@@ -249,6 +247,51 @@ public abstract class IconDelegate implements Icon {
icon.handleEvent(event);
}
@Override
public Vector4fc getColor() {
return icon.getColor();
}
@Override
public void setColor(Vector4fc color) {
icon.setColor(color);
}
@Override
public void setColor(Vector3fc color) {
icon.setColor(color);
}
@Override
public void setColor(float red, float green, float blue, float alpha) {
icon.setColor(red, green, blue, alpha);
}
@Override
public void setColor(float red, float green, float blue) {
icon.setColor(red, green, blue);
}
@Override
public void setRed(float red) {
icon.setRed(red);
}
@Override
public void setGreen(float green) {
icon.setGreen(green);
}
@Override
public void setBlue(float blue) {
icon.setBlue(blue);
}
@Override
public void setAlpha(float alpha) {
icon.setAlpha(alpha);
}
@Override
public void update(float dt) {
icon.update(dt);

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -0,0 +1,73 @@
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();
}
public float[] getTextureCoordinates(int id) {
return texture.getTextureCoordinates(id);
}
public float[] getTextureCoordinates(int x, int y) {
return texture.getTextureCoordinates(x, y);
}
public float[] getTextureCoordinates(int textureX, int textureY, int tileWidth, int tileHeight) {
return texture.getTextureCoordinates(textureX, textureY, tileWidth, tileHeight);
}
@Override
public void render(Screen screen, Camera camera, ShaderManager shaderManager) {
shaderManager.setUniform(UniformName.UNI_OBJECT_COLOR, color);
texture.render(screen, camera, shaderManager);
}
}

View File

@@ -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<Animation> 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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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));

View File

@@ -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));
}
}
}

View File

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

View File

@@ -2,12 +2,11 @@ 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.object.texture.TexturedMaterial;
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;
@@ -17,8 +16,10 @@ import com.bartlomiejpluta.base.internal.render.Renderable;
import com.bartlomiejpluta.base.internal.render.ShaderManager;
import lombok.NonNull;
import static com.bartlomiejpluta.base.engine.core.gl.object.material.Material.textured;
public class TileChunk extends Model implements Placeable, Renderable, Disposable, BoundingBox {
private final Texture tileSet;
private final TexturedMaterial tileSet;
private final Mesh mesh;
private final int chunkSize;
private final QuadTemplate template;
@@ -30,10 +31,10 @@ public class TileChunk extends Model implements Placeable, Renderable, Disposabl
}
public TileChunk(@NonNull MeshManager meshManager, @NonNull Texture tileSet, int chunkSize, float originX, float originY) {
this.tileSet = tileSet;
this.tileSet = textured(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 +83,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 +96,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;
}

View File

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