Hello Triangle
This tutorial will demonstrate how to draw a triangle using luma.gl's high-level APIs.
The tutorial pages have not yet been updated for luma.gl v9.
Hello Triangle
Have to start somewhere...
It is assumed you've set up your development environment as described in
Getting Started. Your index.js
file should look like the following:
import {AnimationLoop} from '@luma.gl/engine';
import {clear} from '@luma.gl/webgl';
class AppAnimationLoop extends AnimationLoop ({
override onInitialize({device}) {
// Setup logic goes here
},
override onRender({device}) {
// Drawing logic goes here
clear(device, {color: [0, 0, 0, 1]});
}
});
const loop = new AppAnimationLoop();
loop.start();
First, we'll need to update our imports with the classes we'll be using, Buffer
and Model
:
import {AnimationLoop, Model} from '@luma.gl/engine';
import {clear} from '@luma.gl/webgl';
Now let's create some buffers in the onInitialize
method to hold our attribute data:
override onInitialize({device}) {
// Setup logic goes here
const positionBuffer = device.createBuffer(new Float32Array([
-0.5, -0.5,
0.5, -0.5,
0.0, 0.5
]));
const colorBuffer = device.createBuffer(new Float32Array([
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0
]));
}
Next let's add the vertex and fragment shader code we'll be using to draw:
override onInitialize({device}) {
// Setup logic goes here
// Buffers...
const vs = `
attribute vec2 position;
attribute vec3 color;
out vec3 vColor;
void main() {
vColor = color;
gl_Position = vec4(position, 0.0, 1.0);
}
`;
const fs = `
in vec3 vColor;
void main() {
gl_FragColor = vec4(vColor, 1.0);
}
`;
}
As a final step in our initialization, we'll create a Model
in onInitialize
:
override onInitialize({device}) {
// Setup logic goes here
// Buffers...
// Shaders...
this.model = new Model(device, {
vs,
fs,
attributes: {
position: positionBuffer,
color: colorBuffer
},
vertexCount: 3
});
return {model};
}
A Model
can be thought of as gathering all the WebGL pieces necessary for a single draw call: programs, attributes, uniforms. Also note that we return the Model
instance we created. This will make it available to the onRender
method.
Our onRender
method is comparitavely much simpler:
override onRender({device}) {
clear(device, {color: [0, 0, 0, 1]});
this.model.draw();
}
This clears the canvas and draws the Model
. If all went well, you should see a tri-color triangle on a black background.
The entire application should look like the following:
import {AnimationLoop, Model} from '@luma.gl/engine';
import {clear} from '@luma.gl/webgl';
class AppAnimationLoop extends AnimationLoop {
override onInitialize({device}) {
const positionBuffer = device.createBuffer(new Float32Array([-0.5, -0.5, 0.5, -0.5, 0.0, 0.5]));
const colorBuffer = device.createBuffer(new Float32Array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]));
const vs = `
attribute vec2 position;
attribute vec3 color;
out vec3 vColor;
void main() {
vColor = color;
gl_Position = vec4(position, 0.0, 1.0);
}
`;
const fs = `
in vec3 vColor;
void main() {
gl_FragColor = vec4(vColor, 1.0);
}
`;
const model = new Model(device, {
vs,
fs,
attributes: {
position: positionBuffer,
color: colorBuffer
},
vertexCount: 3
});
return {model};
},
override onRender({device, model}) {
clear(device, {color: [0, 0, 0, 1]});
model.draw();
}
};
const loop = new AppAnimationLoop();
loop.start();