Skip to content

Commit

Permalink
Batch OverlayPack data
Browse files Browse the repository at this point in the history
  • Loading branch information
ultraq committed Aug 3, 2024
1 parent 354678f commit c967654
Showing 1 changed file with 107 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ import nz.net.ultraq.redhorizon.engine.scenegraph.nodes.Primitive
import nz.net.ultraq.redhorizon.filetypes.ColourFormat
import nz.net.ultraq.redhorizon.filetypes.ImagesFile

import org.joml.Matrix4f
import org.joml.Vector2f
import org.joml.primitives.Rectanglef
import org.slf4j.Logger
Expand Down Expand Up @@ -83,9 +82,6 @@ class Map extends Node<Map> {
final Rectanglef boundary
final Vector2f initialPosition

protected final Matrix4f transformCopy = new Matrix4f()
protected final PalettedSpriteMaterial materialCopy = new PalettedSpriteMaterial()

private final ResourceManager resourceManager
private final RulesFile rules

Expand Down Expand Up @@ -268,8 +264,8 @@ class Map extends Node<Map> {
final PartitionHint partitionHint = PartitionHint.LARGE_AREA
final UpdateHint updateHint = UpdateHint.NEVER

private final TileSet tileSet = new TileSet()
private final List<MapTile> mapTiles = []
private final TileSet tileSet = new TileSet()
private Mesh fullMesh
private Shader shader
private PalettedSpriteMaterial material = new PalettedSpriteMaterial()
Expand Down Expand Up @@ -332,11 +328,7 @@ class Map extends Node<Map> {
return CompletableFuture.allOf(
CompletableFuture.supplyAsync { ->
return tileSet.tileFileList
.collect { tileFile ->
return tileFile.imagesData.collect { imageData ->
return imageData.center(tileFile.width, tileFile.height, TILE_WIDTH, TILE_HEIGHT)
}
}
.collect { tileFile -> tileFile.imagesData }
.flatten() as ByteBuffer[]
}
.thenComposeAsync { allTileImageData ->
Expand Down Expand Up @@ -395,12 +387,9 @@ class Map extends Node<Map> {
@Override
RenderCommand renderCommand() {

transformCopy.set(globalTransform)
materialCopy.copy(material)

return { renderer ->
if (fullMesh && shader && materialCopy.texture) {
renderer.draw(fullMesh, transformCopy, shader, materialCopy)
if (fullMesh && shader && material.texture) {
renderer.draw(fullMesh, transform, shader, material)
}
}
}
Expand All @@ -409,13 +398,17 @@ class Map extends Node<Map> {
/**
* The "OverlayPack" layer of a Red Alert map.
*/
private class OverlayPack extends Node<OverlayPack> {
private class OverlayPack extends Node<OverlayPack> implements GraphicsElement {

final PartitionHint partitionHint = PartitionHint.DO_NOT_PARTICIPATE
final PartitionHint partitionHint = PartitionHint.LARGE_AREA
final NodeListDisplayHint nodeListDisplayHint = NodeListDisplayHint.START_COLLAPSED
final UpdateHint updateHint = UpdateHint.NEVER

private int numTiles = 0
private final List<MapTile> mapTiles = []
private final TileSet tileSet = new TileSet()
private Mesh fullMesh
private Shader shader
private PalettedSpriteMaterial material = new PalettedSpriteMaterial()

OverlayPack() {

Expand Down Expand Up @@ -481,22 +474,108 @@ class Map extends Node<Map> {
3 + adjacent
}

var overlay = new PalettedSprite(tileFile)
overlay.name = "${tile.name} - Variant ${imageVariant}"
overlay.frame = imageVariant
overlay.position = new Vector2f(tilePos).asWorldCoords(1)
overlay.partitionHint = PartitionHint.SMALL_AREA

addChild(overlay)

numTiles++
tileSet.addTiles(tileFile)
// var overlay = new PalettedSprite(tileFile)
// overlay.name = "${tile.name} - Variant ${imageVariant}"
// overlay.frame = imageVariant
// overlay.position = new Vector2f(tilePos).asWorldCoords(1)
// overlay.partitionHint = PartitionHint.SMALL_AREA
//
// addChild(overlay)
var mapTile = new MapTile(new Vector2f(tilePos).asWorldCoords(1), tileSet.getFrame(tileFile, imageVariant))
mapTiles << mapTile

bounds { ->
expand(
mapTile.position().x,
mapTile.position().y,
mapTile.position().x + TILE_WIDTH as float,
mapTile.position().y + TILE_HEIGHT as float
)
}
}
}

@Override
String getName() {

return "OverlayPack - ${numTiles} tiles"
return "OverlayPack - ${mapTiles.size()} tiles"
}

@Override
CompletableFuture<Void> onSceneAddedAsync(Scene scene) {

return CompletableFuture.allOf(
CompletableFuture.supplyAsync { ->
return tileSet.tileFileList
.collect { tileFile ->
return tileFile.imagesData.collect { imageData ->
return imageData.center(tileFile.width, tileFile.height, TILE_WIDTH, TILE_HEIGHT)
}
}
.flatten() as ByteBuffer[]
}
.thenComposeAsync { allTileImageData ->
return scene.requestCreateOrGet(new SpriteSheetRequest(TILE_WIDTH, TILE_HEIGHT, ColourFormat.FORMAT_INDEXED, allTileImageData))
}
.thenApplyAsync { newSpriteSheet ->
tileSet.spriteSheet = newSpriteSheet
material.with {
texture = newSpriteSheet.texture
frame = 0
frameStepX = newSpriteSheet.frameStepX
frameStepY = newSpriteSheet.frameStepY
framesHorizontal = newSpriteSheet.framesHorizontal
framesVertical = newSpriteSheet.framesVertical
}
return newSpriteSheet
}
// TODO: This can be some batching request method
.thenApplyAsync { spriteSheet ->
List<Vector2f> allVertices = []
List<Vector2f> allTextureUVs = []
List<Integer> allIndices = []
var indexOffset = 0
mapTiles.each { mapTile ->
allVertices.addAll(new Rectanglef(0, 0, TILE_WIDTH, TILE_HEIGHT).translate(mapTile.position()) as Vector2f[])
allTextureUVs.addAll(spriteSheet[mapTile.frameInTileSet()] as Vector2f[])
allIndices.addAll([0, 1, 2, 0, 2, 3].collect { index -> index + indexOffset })
indexOffset += 4
}
return new Tuple3<Vector2f[], Vector2f[], int[]>(allVertices as Vector2f[], allTextureUVs as Vector2f[], allIndices as int[])
}
.thenComposeAsync { meshData ->
def (allVertices, allTextureUVs, allIndices) = meshData
return scene
.requestCreateOrGet(new MeshRequest(MeshType.TRIANGLES,
new VertexBufferLayout(Attribute.POSITION, Attribute.COLOUR, Attribute.TEXTURE_UVS),
allVertices, Colour.WHITE, allTextureUVs, allIndices))
.thenAcceptAsync { newMesh ->
fullMesh = newMesh
}
},
scene
.requestCreateOrGet(new ShaderRequest(Shaders.palettedSpriteShader))
.thenAcceptAsync { requestedShader ->
shader = requestedShader
}
)
}

@Override
CompletableFuture<Void> onSceneRemovedAsync(Scene scene) {

return scene.requestDelete(fullMesh, tileSet.spriteSheet)
}

@Override
RenderCommand renderCommand() {

return { renderer ->
if (fullMesh && shader && material.texture) {
renderer.draw(fullMesh, transform, shader, material)
}
}
}
}

Expand Down

0 comments on commit c967654

Please sign in to comment.