Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scene-graph: rework rendering & canvas coordinates calculations for CanvasLayer nodes #254

Merged
merged 3 commits into from
Jul 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import com.littlekt.graphics.g2d.use
import com.littlekt.graphics.webgpu.*
import com.littlekt.resources.Fonts
import com.littlekt.util.viewport.ExtendViewport
import com.littlekt.util.viewport.setViewport

/**
* @author Colton Daily
Expand Down Expand Up @@ -89,7 +88,6 @@ class FontExample(context: Context) : ContextListener(context) {
)
)
)
renderPassEncoder.setViewport(viewport)
camera.update()

batch.use(renderPassEncoder, camera.viewProjection) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.littlekt.graph.node.ui.centerContainer
import com.littlekt.graph.node.ui.label
import com.littlekt.graph.sceneGraph
import com.littlekt.graphics.g2d.SpriteBatch
import com.littlekt.graphics.g2d.use
import com.littlekt.graphics.webgpu.*
import com.littlekt.util.viewport.ExtendViewport

Expand Down Expand Up @@ -46,7 +45,7 @@ class GameWorldAndUIViewports(context: Context) : ContextListener(context) {
if (preferredFormat.srgb) world.defaultLevelBackgroundColor.toLinear()
else world.defaultLevelBackgroundColor
val graph =
sceneGraph(this, viewport = ExtendViewport(960, 540)) {
sceneGraph(this, viewport = ExtendViewport(960, 540), batch = batch) {
centerContainer {
anchorRight = 1f
anchorTop = 1f
Expand Down Expand Up @@ -107,11 +106,10 @@ class GameWorldAndUIViewports(context: Context) : ContextListener(context) {
)
)
)
// worldRenderPass.setViewport(worldViewport)
worldCamera.update()
batch.use(worldRenderPass, worldCamera.viewProjection) {
world.render(batch, worldCamera, scale = 1f)
}
batch.begin(worldCamera.viewProjection)
world.render(batch, worldCamera, scale = 1f)
batch.flush(worldRenderPass)
worldRenderPass.end()
worldRenderPass.release()

Expand All @@ -129,6 +127,7 @@ class GameWorldAndUIViewports(context: Context) : ContextListener(context) {

graph.update(dt)
graph.render(commandEncoder, uiRenderPassDescriptor)
batch.end()

val commandBuffer = commandEncoder.finish()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import com.littlekt.input.Key
import com.littlekt.math.geom.Angle
import com.littlekt.math.geom.degrees
import com.littlekt.math.geom.radians
import com.littlekt.util.viewport.ExtendViewport

/**
* An example using a [sceneGraph]
Expand All @@ -42,7 +43,7 @@ class HelloSceneGraphExample(context: Context) : ContextListener(context) {
)

val graph =
sceneGraph(this) {
sceneGraph(this, ExtendViewport(960, 540)) {
canvasLayerContainer {
stretch = true
shrink = 2
Expand All @@ -59,7 +60,6 @@ class HelloSceneGraphExample(context: Context) : ContextListener(context) {
}
}
}
// button { text = "test" }
node2d {
rotation = 45.degrees
onReady += { println("$name: $canvas") }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.littlekt.file.vfs.readLDtkMapLoader
import com.littlekt.graphics.g2d.SpriteCache
import com.littlekt.graphics.webgpu.*
import com.littlekt.util.viewport.ExtendViewport
import com.littlekt.util.viewport.setViewport

/**
* Load and render an entire world of LDtk.
Expand Down Expand Up @@ -97,7 +96,6 @@ class LDtkTileMapCacheExample(context: Context) : ContextListener(context) {
)
)

renderPassEncoder.setViewport(viewport)
camera.update()

cache.render(renderPassEncoder, camera.viewProjection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.littlekt.graphics.g2d.SpriteBatch
import com.littlekt.graphics.g2d.use
import com.littlekt.graphics.webgpu.*
import com.littlekt.util.viewport.ExtendViewport
import com.littlekt.util.viewport.setViewport

/**
* Load and render an LDtk map.
Expand Down Expand Up @@ -93,7 +92,6 @@ class LDtkTileMapExample(context: Context) : ContextListener(context) {
)
)
)
renderPassEncoder.setViewport(viewport)
camera.update()

batch.use(renderPassEncoder, camera.viewProjection) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.littlekt.graphics.Color
import com.littlekt.graphics.g2d.SpriteBatch
import com.littlekt.graphics.webgpu.*
import com.littlekt.util.viewport.ExtendViewport
import com.littlekt.util.viewport.setViewport

/**
* An example using a simple Orthographic camera to move around a texture.
Expand Down Expand Up @@ -88,7 +87,6 @@ class SimpleCameraExample(context: Context) : ContextListener(context) {
)
)
)
renderPassEncoder.setViewport(viewport)
camera.update()
batch.begin()
batch.draw(logoTexture, 0f, 0f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.littlekt.graphics.Color
import com.littlekt.graphics.g2d.SpriteCache
import com.littlekt.graphics.webgpu.*
import com.littlekt.util.viewport.ExtendViewport
import com.littlekt.util.viewport.setViewport

/**
* Load and render a Tiled map using a [SpriteCache].
Expand Down Expand Up @@ -91,7 +90,6 @@ class TiledTileMapCacheExample(context: Context) : ContextListener(context) {
)
)
)
renderPassEncoder.setViewport(viewport)
camera.update()
map.updateCachedAnimationTiles(cache)
cache.render(renderPassEncoder, camera.viewProjection)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import com.littlekt.graphics.g2d.shape.ShapeRenderer
import com.littlekt.graphics.g2d.use
import com.littlekt.graphics.webgpu.*
import com.littlekt.util.viewport.ExtendViewport
import com.littlekt.util.viewport.setViewport

/**
* Load and render a Tiled map.
Expand Down Expand Up @@ -93,7 +92,6 @@ class TiledTileMapExample(context: Context) : ContextListener(context) {
)
)
)
renderPassEncoder.setViewport(viewport)
camera.update()

batch.use(renderPassEncoder, camera.viewProjection) {
Expand Down
51 changes: 22 additions & 29 deletions scene-graph/src/commonMain/kotlin/com/littlekt/graph/SceneGraph.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import kotlin.time.Duration.Companion.milliseconds
*
* @param context the current context
* @param viewport the viewport that the camera of the scene graph will own
* @param batch an option sprite batch. If omitted, the scene graph will create and manage its own.
* @param callback the callback that is invoked with a [SceneGraph] context in order to initialize
* any values and create nodes
* @return the newly created [SceneGraph]
Expand All @@ -41,6 +42,7 @@ import kotlin.time.Duration.Companion.milliseconds
inline fun sceneGraph(
context: Context,
viewport: Viewport = ScreenViewport(context.graphics.width, context.graphics.height),
batch: Batch? = null,
controller: InputMapController<String>? = null,
whitePixel: TextureSlice = Textures.white,
callback: @SceneGraphDslMarker SceneGraph<String>.() -> Unit = {},
Expand All @@ -63,6 +65,7 @@ inline fun sceneGraph(
return SceneGraph(
context,
viewport,
batch,
signals,
controller ?: createDefaultSceneGraphController(context.input, signals),
whitePixel
Expand All @@ -75,6 +78,7 @@ inline fun sceneGraph(
*
* @param context the current context
* @param viewport the viewport that the camera of the scene graph will own
* @param batch an option sprite batch. If omitted, the scene graph will create and manage its own.
* @param callback the callback that is invoked with a [SceneGraph] context in order to initialize
* any values and create nodes
* @return the newly created [SceneGraph]
Expand All @@ -83,13 +87,15 @@ inline fun sceneGraph(
inline fun <InputSignal> sceneGraph(
context: Context,
viewport: Viewport = ScreenViewport(context.graphics.width, context.graphics.height),
batch: Batch? = null,
uiInputSignals: SceneGraph.UiInputSignals<InputSignal> = SceneGraph.UiInputSignals(),
controller: InputMapController<InputSignal> = InputMapController(context.input),
whitePixel: TextureSlice = Textures.white,
callback: @SceneGraphDslMarker SceneGraph<InputSignal>.() -> Unit = {},
): SceneGraph<InputSignal> {
contract { callsInPlace(callback, InvocationKind.EXACTLY_ONCE) }
return SceneGraph(context, viewport, uiInputSignals, controller, whitePixel).also(callback)
return SceneGraph(context, viewport, batch, uiInputSignals, controller, whitePixel)
.also(callback)
}

/**
Expand Down Expand Up @@ -146,11 +152,11 @@ fun <InputSignal> createDefaultSceneGraphController(
InputMapController<InputSignal>(input).also { it.addDefaultUiInput(uiInputSignals) }

/**
* A class for creating a scene graph of nodes. The scene graph manages its own [Batch] and handles
* creating, ending, and releasing [RenderPassEncoder].
* A class for creating a scene graph of nodes.
*
* @param context the current context
* @param viewport the viewport that the camera of the scene graph will own
* @param batch an option sprite batch. If omitted, the scene graph will create and manage its own.
* @param uiInputSignals the input signals mapped to the UI input of type [InputType].
* @param controller the input map controller for the scene graph
* @param whitePixel a white 1x1 pixel [TextureSlice] that is used for rendering with
Expand All @@ -161,18 +167,25 @@ fun <InputSignal> createDefaultSceneGraphController(
open class SceneGraph<InputType>(
val context: Context,
viewport: Viewport = ScreenViewport(context.graphics.width, context.graphics.height),
batch: Batch? = null,
val uiInputSignals: UiInputSignals<InputType> = UiInputSignals(),
val controller: InputMapController<InputType> =
createDefaultSceneGraphController(context.input, uiInputSignals),
whitePixel: TextureSlice = Textures.white,
) : InputMapProcessor<InputType>, Releasable {

private var ownsBatch = true
/**
* The [Batch] being used by the scene graph. This batch may be managed by the scene graph or
* could be optional passed in via the constructor.
*/
val batch: Batch =
SpriteBatch(context.graphics.device, context.graphics, context.graphics.preferredFormat)
batch?.also { ownsBatch = false }
?: SpriteBatch(
context.graphics.device,
context.graphics,
context.graphics.preferredFormat
)

/** The [ShapeRenderer] managed by the scene graph. This uses the [batch] for drawing. */
val shapeRenderer: ShapeRenderer = ShapeRenderer(this.batch, whitePixel)
Expand All @@ -185,7 +198,6 @@ open class SceneGraph<InputType>(
CanvasLayer().apply {
name = "Scene Viewport"
this.viewport = viewport
spriteShader = this@SceneGraph.batch.defaultShader
resizeAutomatically = false
}
}
Expand Down Expand Up @@ -337,29 +349,8 @@ open class SceneGraph<InputType>(
}

this.commandEncoder = commandEncoder
if (dirty) {
sceneCanvas.resizeFbo(width.toInt(), height.toInt())
dirty = false
}
sceneCanvas.canvasRenderPassDescriptor = renderPassDescriptor
sceneCanvas.render(batch, shapeRenderer) { node, _, _, _, _ -> checkNodeMaterial(node) }

if (batch.drawing) {
batch.setBlendState(BlendState.NonPreMultiplied)
batch.useDefaultShader()
val graphPass = commandEncoder.beginRenderPass(desc = renderPassDescriptor)
batch.viewProjection = sceneCanvas.canvasCamera.viewProjection
batch.draw(
texture = sceneCanvas.target,
x = 0f,
y = 0f,
width = sceneCanvas.width.toFloat(),
height = sceneCanvas.height.toFloat()
)
batch.flush(graphPass)
graphPass.end()
graphPass.release()
}

flush()

if (debugInfoDirty) {
Expand All @@ -384,7 +375,7 @@ open class SceneGraph<InputType>(

commandEncoder = null

if (batch.drawing) {
if (ownsBatch && batch.drawing) {
batch.end()
}
}
Expand Down Expand Up @@ -1092,7 +1083,9 @@ open class SceneGraph<InputType>(
*/
override fun release() {
sceneCanvas.destroy()
batch.release()
if (ownsBatch) {
batch.release()
}

controller.removeInputMapProcessor(this)
context.input.removeInputProcessor(this)
Expand Down
Loading
Loading