Your First Cube
This tutorial shows the absolute minimum needed to get a 3D cube on screen. We’ll cover:
- Creating an application class
- Setting up a camera
- Adding a cube entity to the scene
- Running the engine
The init() method
init() is called once after the engine starts. This is where you set up
your scene — create entities, configure the camera, load assets.
Every jGibbonEngine app extends BaseApplication and overrides init().
1
2
@Override
protected void init() {
Set up the camera
The camera determines what you see. lookAt positions the camera
and points it at a target. Without a camera, nothing is visible.
1
2
3
4
5
camera().lookAt(
new Vec3(0, 2, 5), // camera position: slightly above and in front
Vec3.ZERO, // look at the origin
Vec3.UNIT_Y // "up" direction is +Y
);
Create an entity
Everything in the scene is an entity with components. An entity needs at least:
- A mesh — the shape (cube, sphere, custom model)
- A material — the appearance (color, texture, PBR properties)
- A transform — the position, rotation, scale
1
var cube = scene().createEntity();
Add a cube mesh. PrimitiveMeshes provides built-in shapes.
1
cube.add(PrimitiveMeshes.cube());
Add an unlit material with a blue color. Unlit means no lighting calculations — the color is shown as-is. Great for debugging.
1
cube.add(MaterialData.unlit(new Vec3(0.2f, 0.6f, 1.0f)));
Place the cube at the origin. Transform.IDENTITY means
no translation, no rotation, scale = 1.
1
2
cube.add(Transform.IDENTITY);
}
The update() method
update() is called every frame. Use it for game logic, animation,
or anything that changes over time. Here we just update the camera
aspect ratio to match the window size.
1
2
3
4
5
6
7
8
9
10
@Override
protected void update(float deltaTime) {
float aspect = (float) window().width() / Math.max(window().height(), 1);
camera().setPerspective(
(float) Math.toRadians(60), // 60° field of view
aspect, // match window aspect ratio
0.1f, // near clip plane
100f // far clip plane
);
}
The main() method
This is the entry point. We configure the engine and launch the app.
EngineConfig bundles everything:
- Platform — how assets are loaded and shaders compiled
- GraphicsBackend — which GPU API to use (OpenGL, Vulkan, WebGPU)
- Window settings — title, size
1
2
3
4
5
6
7
8
public static void main(String[] args) {
var config = EngineConfig.builder()
.window(WindowDescriptor.builder("Tutorial 01 — Hello Cube").size(1280, 720).build())
.platform(DesktopPlatform.builder().build())
.graphicsBackend(OpenGlBackend.factory(
new dev.engine.windowing.glfw.GlfwWindowToolkit(dev.engine.windowing.glfw.GlfwWindowToolkit.OPENGL_HINTS),
new dev.engine.providers.lwjgl.graphics.opengl.LwjglGlBindings()))
.build();
Launch! This opens the window, calls init(), then runs the update loop until the window is closed.
1
2
new T01_HelloCube().launch(config);
}