mirror of
https://github.com/visgl/luma.gl.git
synced 2025-12-08 17:36:19 +00:00
113 lines
2.4 KiB
TypeScript
113 lines
2.4 KiB
TypeScript
// luma.gl, MIT license
|
|
import {glsl, UniformStore, NumberArray, ShaderUniformType} from '@luma.gl/core';
|
|
import {AnimationLoopTemplate, AnimationProps, Model, CubeGeometry} from '@luma.gl/engine';
|
|
import {Matrix4} from '@math.gl/core';
|
|
|
|
const INFO_HTML = `\
|
|
<p>
|
|
Drawing a textured cube
|
|
</p>
|
|
`;
|
|
|
|
type AppUniforms = {
|
|
uMVP: NumberArray;
|
|
};
|
|
|
|
const appUniforms: {uniformTypes: Record<keyof AppUniforms, ShaderUniformType>} = {
|
|
uniformTypes: {
|
|
uMVP: 'mat4x4<f32>'
|
|
}
|
|
};
|
|
|
|
const vs = glsl`\
|
|
#version 300 es
|
|
attribute vec3 positions;
|
|
attribute vec2 texCoords;
|
|
|
|
uniform AppUniforms {
|
|
uniform mat4 uMVP;
|
|
} app;
|
|
|
|
varying vec2 vUV;
|
|
|
|
void main(void) {
|
|
gl_Position = app.uMVP * vec4(positions, 1.0);
|
|
vUV = texCoords;
|
|
}
|
|
`;
|
|
|
|
const fs = glsl`\
|
|
#version 300 es
|
|
precision highp float;
|
|
|
|
uniform sampler2D uTexture;
|
|
varying vec2 vUV;
|
|
|
|
void main(void) {
|
|
gl_FragColor = texture2D(uTexture, vec2(vUV.x, 1.0 - vUV.y));
|
|
}
|
|
`;
|
|
|
|
const eyePosition = [0, 0, 5];
|
|
|
|
export default class AppAnimationLoopTemplate extends AnimationLoopTemplate {
|
|
static info = INFO_HTML;
|
|
|
|
uniformStore = new UniformStore<{app: AppUniforms}>({
|
|
app: appUniforms
|
|
});
|
|
|
|
mvpMatrix = new Matrix4();
|
|
viewMatrix = new Matrix4().lookAt({eye: eyePosition});
|
|
model: Model;
|
|
|
|
constructor({device}: AnimationProps) {
|
|
super();
|
|
|
|
const texture = device.createTexture({
|
|
data: 'vis-logo.png',
|
|
mipmaps: true,
|
|
sampler: device.createSampler({
|
|
minFilter: 'linear',
|
|
magFilter: 'linear',
|
|
mipmapFilter: 'linear'
|
|
})
|
|
});
|
|
|
|
this.model = new Model(device, {
|
|
vs,
|
|
fs,
|
|
geometry: new CubeGeometry(),
|
|
bindings: {
|
|
uTexture: texture,
|
|
AppUniforms: this.uniformStore.getManagedUniformBuffer(device, 'app')
|
|
},
|
|
parameters: {
|
|
depthWriteEnabled: true,
|
|
depthCompare: 'less-equal'
|
|
}
|
|
});
|
|
}
|
|
|
|
onFinalize() {
|
|
this.model.destroy();
|
|
this.uniformStore.destroy();
|
|
}
|
|
|
|
onRender({device, aspect, tick}: AnimationProps) {
|
|
this.mvpMatrix
|
|
.perspective({fovy: Math.PI / 3, aspect})
|
|
.multiplyRight(this.viewMatrix)
|
|
.rotateX(tick * 0.01)
|
|
.rotateY(tick * 0.013);
|
|
|
|
this.uniformStore.setUniforms({
|
|
app: {uMVP: this.mvpMatrix}
|
|
});
|
|
|
|
const renderPass = device.beginRenderPass({clearColor: [0, 0, 0, 1]});
|
|
this.model.draw(renderPass);
|
|
renderPass.end();
|
|
}
|
|
}
|