Your first window
Describe an app with the app { } DSL, give it a render plan, and open it in a desktop window with the Vulkan backend.
Vulkan Desktop
This page uses awake-engine-bootstrap and awake-asset-shader-pack in commonMain, and awake-backend-vulkan in
desktopMain. See Installation.
Describe the app
In commonMain, the app { } DSL describes the window and the hooks the engine calls. render
runs once per frame.
import com.awakekt.awake.asset.shaderpack.PackShaderSets
import com.awakekt.awake.asset.shaders.RenderPlan
import com.awakekt.awake.asset.shaders.ScenePipeline
import com.awakekt.awake.core.geometry.VertexFormat
import com.awakekt.awake.engine.bootstrap.dsl.app
import com.awakekt.awake.engine.platform.lifecycle.AwakeAppLifecycle
import com.awakekt.awake.render.pipeline.GroupBindings
import com.awakekt.awake.render.pipeline.PipelineKey
/** The app: one window, and a hook that runs every frame. */
fun firstWindow(): AwakeAppLifecycle = app {
window {
title = "Hello AwakeKt"
size(1280, 720)
}
render { frame ->
// frame.delta is the seconds since the last frame.
}
}
The app does not name a backend, so the same app runs on Vulkan here and on WebGPU in Run in the browser.
Choose what it draws with
A RenderPlan lists the shaders the app renders with. Every app needs a primary pipeline: meshes
draw through it unless their vertex format asks for another. This plan uses the lit shader from the
shader pack, and turns on the depth pre-pass it samples for shadows. Add it to the same file:
/** What the app draws with: the lit, shadowed shader that ships in the shader pack. */
val GameRenderPlan = RenderPlan(
primary = ScenePipeline(
key = PipelineKey.Primary,
shaders = PackShaderSets.LitShadow,
vertexFormat = VertexFormat.PositionNormalColor,
materialBindings = GroupBindings.UniformOnlyMaterial,
),
depthPrePassShaderSet = PackShaderSets.ShadowDepth,
)
The plan lives in commonMain so that every backend reads the same one. A backend that cannot run
part of a plan leaves that part out and reports it, rather than failing.
Open the window
In desktopMain, hand the app and the plan to runVulkanDesktopGame:
import com.awakekt.awake.vulkan.application.runVulkanDesktopGame
fun main() = runVulkanDesktopGame(firstWindow(), GameRenderPlan)
Run main. A 1280 × 720 window titled "Hello AwakeKt" opens. Nothing has been added to
draw yet, so it shows only the clear colour. Closing the window ends the loop and disposes the app.
macOS needs -XstartOnFirstThread
GLFW only opens windows from the process's first thread on macOS. Add -XstartOnFirstThread to
the JVM options of whatever runs main, such as your IDE run configuration or Gradle JavaExec
task.
Window settings
Everything inside window { }:
| Property | Type | Default | What it does |
|---|---|---|---|
title |
String |
"Awake" |
The window title. |
size(width, height) |
function | 800 × 600 | The window size, in pixels. |
backend |
vulkan() · webGpu() · default() |
default() |
Which backend the app asks for. runVulkanDesktopGame accepts vulkan() or default(). |
frameRateMode |
FrameRateMode |
FrameRateMode.Auto |
Auto follows the display, Capped(fps) limits it, Unlimited never waits. |
presentMode |
PresentMode |
PresentMode.Auto |
How finished frames reach the display. A request: the surface may pick another. |
throttleCpuWhenNotForeground |
Boolean |
true |
Drops to backgroundFrameRate while the window is not focused. |
backgroundFrameRate |
Int |
15 |
The frame rate used while throttled. |
Besides render, the app DSL has ready, resize, pause, resume, and dispose hooks.
Next
Your first scene puts a camera, a light, and a spinning cube in this window.