computer-graphics-study/src/model.ts
2021-10-10 02:07:34 +09:00

70 lines
2.3 KiB
TypeScript

import { createIndexBuffer, createVertexArray, createVertexBuffer, GLProgram, IndexBuffer, VertexArray, VertexBuffer } from "./glWrapper";
import {OBJ} from "webgl-obj-loader";
import { assertBoolean } from "./util";
type VertexType = "position" | "normal" | "textureUV";
type Vertexes = {[key in VertexType]:VertexBuffer};
export class Model{
vertexes : Vertexes;
ibo :IndexBuffer;
vao :VertexArray;
constructor(gl:WebGL2RenderingContext,vertex:Vertexes,index :IndexBuffer){
this.vertexes = vertex;
this.vao = createVertexArray(gl);
this.ibo = index;
}
ready(gl:WebGL2RenderingContext,p : GLProgram){
const VertexLayouts = {
"position":{
count:3,
type:gl.FLOAT,
normalize:false,
stride:0,
offset:0
},
"normal":{
count:3,
type:gl.FLOAT,
normalize:false,
stride:0,
offset:0
},
"textureUV":{
count:2,
type:gl.FLOAT,
normalize:false,
stride:0,
offset:0
}
}
this.vao.bind(gl);
for(const [name,buf] of Object.entries(this.vertexes)){
const loc = p.getAttribLocation(gl,name);
assertBoolean(loc >= 0,"there is no",name,"attribute");
this.vao.addBuffer(gl,buf,loc,VertexLayouts[name]);
}
this.ibo.bind(gl);
this.vao.unbind(gl);
}
draw(gl:WebGL2RenderingContext){
this.vao.bind(gl);
gl.drawElements(gl.TRIANGLES,this.ibo.count,gl.UNSIGNED_SHORT,0);
this.vao.unbind(gl);
}
static async loadFromOBJ(gl:WebGL2RenderingContext,src:RequestInfo,init?:RequestInit){
const response = await fetch(src,init);
const text = await response.text();
const mesh = new OBJ.Mesh(text);
const position = createVertexBuffer(gl,mesh.vertices);
const normal = createVertexBuffer(gl,mesh.vertexNormals);
const texture = createVertexBuffer(gl,mesh.textures);
const index = createIndexBuffer(gl,mesh.indices);
return new Model(gl,{
position: position,
normal: normal,
textureUV: texture
}, index);
}
}