An FP game engine for Scala.

Blank Entity

Blank Entities are the most basic form of scene node you can create, and reveal the relationship between the scene nodes and their materials.

Here we have a node without any frills or helpers, that does two things:

  1. Allows you to defined a space on the screen.
  2. Allows you to explain to Indigo how to fill that space.

When you're using any of the other fancier primitives, all they are doing is producing a particular flavor of those two things. Defining a space, and drawing something in it.

A placeholder for shaders

The purpose of a blank entity is to allow you to render whatever you like, but to do so, you need to know how to write shaders. So really, this primitive is for people who'd like to define their own effects.

Setting up a BlankEntity with a custom shader

First, we'll need a simple shader. This one renders pretty colours.

object CustomShader:

  val shader: ShaderProgram =
    UltravioletShader.entityFragment(
      ShaderId("custom shader"),
      EntityShader.fragment[FragmentEnv](fragment, FragmentEnv.reference)
    )

  inline def fragment: Shader[FragmentEnv, Unit] =
    Shader[FragmentEnv] { env =>
      def fragment(color: vec4): vec4 =
        val col: vec3 = 0.5f + 0.5f * cos(env.TIME + env.UV.xyx + vec3(0.0f, 2.0f, 4.0f))
        vec4(col, 1.0f)
    }

Then we need to register the shader. In an IndigoDemo/Game you'll need to do this on the boot result object.

val shaders: Set[ShaderProgram] = Set(CustomShader.shader)

Finally, we can use a blank entity to render the shader into a space on the screen.

def present(context: Context[Unit], model: Unit): Outcome[SceneUpdateFragment] =
  Outcome(
    SceneUpdateFragment(
      BlankEntity(Size(200, 200), ShaderData(CustomShader.shader.id))
        .moveTo(20, 20)
    )
  )