@giraphics/grpkggfx
Version:
164 lines (163 loc) • 5.58 kB
JavaScript
import UUID from './objid';
import { PRIMITIVE_TYPE } from './../renderer/constants';
import { mat4, vec3 } from 'gl-matrix';
export class AbstractShape extends UUID {
}
export class BaseShape extends AbstractShape {
constructor(primitiveType, typeInfo) {
super();
this.isPrimtiveTypeStrip = false;
this.vertexSize = 0;
this.elementCount = 0;
// Model
this.rotX = 0;
this.rotY = 0;
this.rotZ = 0;
this.rotation = [0, 0, 0];
this.translate = [0, 0, 0];
// - Host
this.modelViewProjectionMatrix = mat4.create();
// Uniforms
// - Device
this.matrixSize = 4 * 16; // 4x4 matrix
this.offset = 256; // uniformBindGroup offset must be 256-byte aligned
this.uniformBufferSize = this.offset + this.matrixSize;
this.posOffset = 0;
this.colOffset = 4 * 4;
for (let i of typeInfo) {
this.vertexSize += i;
this.elementCount += i / Float32Array.BYTES_PER_ELEMENT;
}
console.log(this.vertexSize);
console.log(this.elementCount);
switch (primitiveType) {
case PRIMITIVE_TYPE.POINT_LIST: {
this.primitiveType = "point-list";
break;
}
case PRIMITIVE_TYPE.LINE_LIST: {
this.primitiveType = "line-list";
break;
}
case PRIMITIVE_TYPE.LINE_STRIP: {
this.primitiveType = "line-strip";
break;
}
case PRIMITIVE_TYPE.TRIANGLE_LIST: {
this.primitiveType = "triangle-list";
break;
}
case PRIMITIVE_TYPE.TRIANGLE_STRIP: {
this.primitiveType = "triangle-strip";
break;
}
}
this.isPrimtiveTypeStrip = (primitiveType > PRIMITIVE_TYPE.TRIANGLE_LIST);
}
initialize() {
// Uniform
this.uniformBuffer = this.device.createBuffer({
size: this.uniformBufferSize,
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
});
}
createDefaultPipeline(vertShaderCode, fragShaderCode) {
// Shaders
const vsmDesc = {
code: vertShaderCode
};
this.vertModule = this.device.createShaderModule(vsmDesc);
const fsmDesc = {
code: fragShaderCode
};
this.fragModule = this.device.createShaderModule(fsmDesc);
// Defauft pipeline comprises of vertex4, color4, uv2
// Input Assembly
const positionAttribDesc = [
{
shaderLocation: 0,
offset: this.posOffset,
format: 'float32x4'
},
{
shaderLocation: 1,
offset: this.colOffset,
format: 'float32x4'
}
];
const geometryBufferDesc = {
attributes: positionAttribDesc,
arrayStride: this.vertexSize,
stepMode: 'vertex'
};
// Depth
const depthStencil = {
depthWriteEnabled: true,
depthCompare: 'less',
format: 'depth24plus-stencil8'
};
// Uniform Data
const pipelineLayoutDesc = { bindGroupLayouts: [] };
const layout = this.device.createPipelineLayout(pipelineLayoutDesc);
// Shader Stages
const vertex = {
module: this.vertModule,
entryPoint: 'main',
buffers: [geometryBufferDesc]
};
// Color/Blend State
const colorState = {
format: 'bgra8unorm',
blend: {
color: {
srcFactor: "src-alpha",
dstFactor: "one-minus-src-alpha",
operation: "add"
},
alpha: {
srcFactor: "src-alpha",
dstFactor: "one" /*"one-minus-src-alpha"*/,
operation: "add"
}
}
};
const fragment = {
module: this.fragModule,
entryPoint: 'main',
targets: [colorState]
};
// Rasterization
const primitive = this.isPrimtiveTypeStrip ? {
frontFace: 'cw',
cullMode: 'none',
topology: this.primitiveType,
stripIndexFormat: 'uint16', // Parminder: for triangle string this field is must
} :
{
frontFace: 'cw',
cullMode: 'none',
topology: this.primitiveType,
};
const pipelineDesc = {
vertex,
fragment,
primitive,
depthStencil
};
this.pipeline = this.device.createRenderPipeline(pipelineDesc);
}
draw(passEncoder, camera) {
// MOVE / TRANSLATE OBJECT
const modelMatrix = mat4.create();
mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(this.translate[0], this.translate[1], this.translate[2]));
mat4.rotateX(modelMatrix, modelMatrix, this.rotation[0]);
mat4.rotateY(modelMatrix, modelMatrix, this.rotation[1]);
mat4.rotateZ(modelMatrix, modelMatrix, this.rotation[2]);
this.rotation[1] += 0.01;
if (this.rotation[1] > 6.14) {
this.rotation[1] = 0.0;
}
// PROJECT ON CAMERA
mat4.multiply(this.modelViewProjectionMatrix, camera.getCameraViewProjMatrix(), modelMatrix);
}
}