teapot !
This commit is contained in:
parent
341dbe1023
commit
17d69ba547
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,7 @@
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import mat4 from 'gl-mat4';
|
import mat4 from 'gl-mat4';
|
||||||
|
// @ts-ignore
|
||||||
|
import convert from './objparser';
|
||||||
|
|
||||||
let squareRotation = 0.0;
|
let squareRotation = 0.0;
|
||||||
|
|
||||||
|
@ -23,27 +25,32 @@ function main() {
|
||||||
attribute vec4 aVertexPosition;
|
attribute vec4 aVertexPosition;
|
||||||
attribute vec4 aVertexColor;
|
attribute vec4 aVertexColor;
|
||||||
|
|
||||||
uniform mat4 uModelViewMatrix;
|
|
||||||
uniform mat4 uProjectionMatrix;
|
uniform mat4 uProjectionMatrix;
|
||||||
|
uniform mat4 uModelViewMatrix;
|
||||||
|
|
||||||
varying lowp vec4 vColor;
|
varying lowp vec4 vColor;
|
||||||
|
void main()
|
||||||
void main() {
|
{
|
||||||
gl_Position = uProjectionMatrix *
|
gl_Position = uProjectionMatrix *
|
||||||
uModelViewMatrix *
|
uModelViewMatrix *
|
||||||
aVertexPosition;
|
aVertexPosition;
|
||||||
vColor = aVertexColor;
|
vColor = aVertexColor;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const fsSource = `
|
const fsSource = `
|
||||||
varying lowp vec4 vColor;
|
varying lowp vec4 vColor;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_FragColor = vColor;
|
gl_FragColor = vColor;
|
||||||
}
|
}`;
|
||||||
`;
|
|
||||||
|
|
||||||
|
|
||||||
|
fetch('/static/objs/teapot.obj').then((response) => {
|
||||||
|
return response.text();
|
||||||
|
}).then((data: any) => {
|
||||||
|
const [positions, normals, uvs, indices] = convert(data);
|
||||||
|
console.log(normals);
|
||||||
|
console.log(uvs);
|
||||||
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
|
const shaderProgram = initShaderProgram(gl, vsSource, fsSource);
|
||||||
|
|
||||||
const programInfo: any = {
|
const programInfo: any = {
|
||||||
|
@ -51,7 +58,8 @@ function main() {
|
||||||
attribLocations: {
|
attribLocations: {
|
||||||
vertexPosition: gl.getAttribLocation(shaderProgram,
|
vertexPosition: gl.getAttribLocation(shaderProgram,
|
||||||
'aVertexPosition'),
|
'aVertexPosition'),
|
||||||
vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'),
|
vertexColor: gl.getAttribLocation(shaderProgram,
|
||||||
|
'aVertexColor'),
|
||||||
},
|
},
|
||||||
uniformLocations: {
|
uniformLocations: {
|
||||||
projectionMatrix: gl.getUniformLocation(
|
projectionMatrix: gl.getUniformLocation(
|
||||||
|
@ -61,7 +69,7 @@ function main() {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const buffers = initBuffers(gl);
|
const buffers = initBuffers(gl, positions, indices);
|
||||||
let then = 0;
|
let then = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,10 +80,11 @@ function main() {
|
||||||
now *= 0.001;
|
now *= 0.001;
|
||||||
const deltaTime = now - then;
|
const deltaTime = now - then;
|
||||||
then = now;
|
then = now;
|
||||||
drawScene(gl, programInfo, buffers, deltaTime);
|
drawScene(gl, programInfo, buffers, deltaTime, indices.length);
|
||||||
requestAnimationFrame(render);
|
requestAnimationFrame(render);
|
||||||
}
|
}
|
||||||
requestAnimationFrame(render);
|
requestAnimationFrame(render);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -130,92 +139,16 @@ function loadShader(gl: any, type: any, source: string) {
|
||||||
/**
|
/**
|
||||||
* init buffers to create a square
|
* init buffers to create a square
|
||||||
* @param {any} gl the web gl context
|
* @param {any} gl the web gl context
|
||||||
|
* @param {Array<number>} positions the position buffer to be loaded
|
||||||
|
* @param {Array<number>} indices the index buffer to be loaded
|
||||||
* @return {any} the buffer
|
* @return {any} the buffer
|
||||||
*/
|
*/
|
||||||
function initBuffers(gl: any) {
|
function initBuffers(
|
||||||
// Create a buffer for the square's positions.
|
gl: any,
|
||||||
|
positions: Array<number>,
|
||||||
|
indices: Array<number>) {
|
||||||
const positionBuffer = gl.createBuffer();
|
const positionBuffer = gl.createBuffer();
|
||||||
// Select the positionBuffer as the one to apply buffer
|
|
||||||
// operations to from here out.
|
|
||||||
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
||||||
// Now create an array of positions for the square.
|
|
||||||
const cube = [
|
|
||||||
// Front face
|
|
||||||
-1.0, -1.0, 1.0,
|
|
||||||
1.0, -1.0, 1.0,
|
|
||||||
1.0, 1.0, 1.0,
|
|
||||||
-1.0, 1.0, 1.0,
|
|
||||||
// Back face
|
|
||||||
-1.0, -1.0, -1.0,
|
|
||||||
-1.0, 1.0, -1.0,
|
|
||||||
1.0, 1.0, -1.0,
|
|
||||||
1.0, -1.0, -1.0,
|
|
||||||
// Top face
|
|
||||||
-1.0, 1.0, -1.0,
|
|
||||||
-1.0, 1.0, 1.0,
|
|
||||||
1.0, 1.0, 1.0,
|
|
||||||
1.0, 1.0, -1.0,
|
|
||||||
// Bottom face
|
|
||||||
-1.0, -1.0, -1.0,
|
|
||||||
1.0, -1.0, -1.0,
|
|
||||||
1.0, -1.0, 1.0,
|
|
||||||
-1.0, -1.0, 1.0,
|
|
||||||
// Right face
|
|
||||||
1.0, -1.0, -1.0,
|
|
||||||
1.0, 1.0, -1.0,
|
|
||||||
1.0, 1.0, 1.0,
|
|
||||||
1.0, -1.0, 1.0,
|
|
||||||
// Left face
|
|
||||||
-1.0, -1.0, -1.0,
|
|
||||||
-1.0, -1.0, 1.0,
|
|
||||||
-1.0, 1.0, 1.0,
|
|
||||||
-1.0, 1.0, -1.0,
|
|
||||||
];
|
|
||||||
|
|
||||||
const positions = [];
|
|
||||||
|
|
||||||
for (let j = -2; j < 3; j++) {
|
|
||||||
for (let i = 0; i < cube.length; i++) {
|
|
||||||
positions.push(cube[i] + j * 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let k = -1; k < 3; k++) {
|
|
||||||
for (let j = -2; j < 3; j++) {
|
|
||||||
if (j != 0) {
|
|
||||||
for (let i = 0; i < cube.length; i++) {
|
|
||||||
if (i % 3 != k) {
|
|
||||||
positions.push(cube[i] + j * 3);
|
|
||||||
} else {
|
|
||||||
positions.push(cube[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0; i < cube.length; i++) {
|
|
||||||
if (i % 3 == k) {
|
|
||||||
positions.push(cube[i] + j * 3);
|
|
||||||
} else {
|
|
||||||
positions.push(cube[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0; i < cube.length; i++) {
|
|
||||||
if (i % 3 == k) {
|
|
||||||
positions.push(cube[i] + j * 3);
|
|
||||||
} else {
|
|
||||||
positions.push(cube[i] - j * 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0; i < cube.length; i++) {
|
|
||||||
if (i % 3 == k) {
|
|
||||||
positions.push(cube[i] + j * 3);
|
|
||||||
} else {
|
|
||||||
positions.push(cube[i] - j * 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Now pass the list of positions into WebGL to build the
|
|
||||||
// shape. We do this by creating a Float32Array from the
|
|
||||||
// JavaScript array, then use it to fill the current buffer.
|
|
||||||
gl.bufferData(
|
gl.bufferData(
|
||||||
gl.ARRAY_BUFFER,
|
gl.ARRAY_BUFFER,
|
||||||
new Float32Array(positions),
|
new Float32Array(positions),
|
||||||
|
@ -239,17 +172,21 @@ function initBuffers(gl: any) {
|
||||||
}
|
}
|
||||||
// Convert the array of colors into a table for all the vertices.
|
// Convert the array of colors into a table for all the vertices.
|
||||||
|
|
||||||
let colors: any = [];
|
const colors: any = [];
|
||||||
|
|
||||||
for (let j = 0; j < faceColors.length; ++j) {
|
for (let j = 0; j < indices.length; ++j) {
|
||||||
const c = [
|
const c = [
|
||||||
faceColors[Math.floor(Math.random() * 8)],
|
myColors[Math.floor(Math.random() * 8)],
|
||||||
faceColors[Math.floor(Math.random() * 8)],
|
faceColors[Math.floor(Math.random() * 8)],
|
||||||
faceColors[Math.floor(Math.random() * 8)],
|
faceColors[Math.floor(Math.random() * 8)],
|
||||||
faceColors[Math.floor(Math.random() * 8)],
|
faceColors[Math.floor(Math.random() * 8)],
|
||||||
];
|
];
|
||||||
// Repeat each color four times for the four vertices of the face
|
// Repeat each color four times for the four vertices of the face
|
||||||
colors = colors.concat(c[0], c[1], c[2], c[3]);
|
// colors = colors.concat([1.0, 1.0, 1.0, 1.0]);
|
||||||
|
colors.push(c[0][0]);
|
||||||
|
colors.push(c[0][1]);
|
||||||
|
colors.push(c[0][2]);
|
||||||
|
colors.push(c[0][3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const colorBuffer = gl.createBuffer();
|
const colorBuffer = gl.createBuffer();
|
||||||
|
@ -258,32 +195,9 @@ function initBuffers(gl: any) {
|
||||||
|
|
||||||
const indexBuffer = gl.createBuffer();
|
const indexBuffer = gl.createBuffer();
|
||||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||||
|
|
||||||
// This array defines each face as two triangles, using the
|
|
||||||
// indices into the vertex array to specify each triangle's
|
|
||||||
// position.
|
|
||||||
|
|
||||||
const indicesTemplates = [
|
|
||||||
0, 1, 2, 0, 2, 3,
|
|
||||||
4, 5, 6, 4, 6, 7,
|
|
||||||
8, 9, 10, 8, 10, 11,
|
|
||||||
12, 13, 14, 12, 14, 15,
|
|
||||||
16, 17, 18, 16, 18, 19,
|
|
||||||
20, 21, 22, 20, 22, 23,
|
|
||||||
];
|
|
||||||
|
|
||||||
const indices = [];
|
|
||||||
|
|
||||||
for (let j = 0; j < 70; j++) {
|
|
||||||
for (let i = 0; i < indicesTemplates.length; i++) {
|
|
||||||
indices.push(indicesTemplates[i] + 24 * j);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now send the element array to GL
|
|
||||||
|
|
||||||
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
|
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,
|
||||||
new Uint16Array(indices), gl.STATIC_DRAW);
|
new Uint16Array(indices), gl.STATIC_DRAW);
|
||||||
|
// Now send the element array to GL
|
||||||
|
|
||||||
return {
|
return {
|
||||||
position: positionBuffer,
|
position: positionBuffer,
|
||||||
|
@ -298,8 +212,13 @@ function initBuffers(gl: any) {
|
||||||
* @param {any} programInfo WebGL program information
|
* @param {any} programInfo WebGL program information
|
||||||
* @param {any} buffers the buffers to draw
|
* @param {any} buffers the buffers to draw
|
||||||
* @param {number} deltaTime the difference in time since last call
|
* @param {number} deltaTime the difference in time since last call
|
||||||
|
* @param {number} length the index buffer length
|
||||||
*/
|
*/
|
||||||
function drawScene(gl: any, programInfo: any, buffers: any, deltaTime: number) {
|
function drawScene(gl: any,
|
||||||
|
programInfo: any,
|
||||||
|
buffers: any,
|
||||||
|
deltaTime: number,
|
||||||
|
length: number) {
|
||||||
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
gl.clearDepth(1.0);
|
gl.clearDepth(1.0);
|
||||||
gl.enable(gl.DEPTH_TEST);
|
gl.enable(gl.DEPTH_TEST);
|
||||||
|
@ -334,21 +253,26 @@ function drawScene(gl: any, programInfo: any, buffers: any, deltaTime: number) {
|
||||||
|
|
||||||
// Now move the drawing position a bit to where we want to
|
// Now move the drawing position a bit to where we want to
|
||||||
// start drawing the square.
|
// start drawing the square.
|
||||||
|
mat4.translate(
|
||||||
|
modelViewMatrix,
|
||||||
|
modelViewMatrix,
|
||||||
|
[0.0, -1.0, 0]);
|
||||||
mat4.rotate(modelViewMatrix,
|
mat4.rotate(modelViewMatrix,
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
Math.PI,
|
Math.PI,
|
||||||
[0, 1, 0]);
|
[0, 1, 0]);
|
||||||
|
|
||||||
mat4.translate(
|
mat4.translate(
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
[0.0, 0.0, 48]);
|
[0.0, -0.0, 10]);
|
||||||
|
|
||||||
|
|
||||||
mat4.rotate(modelViewMatrix,
|
mat4.rotate(modelViewMatrix,
|
||||||
modelViewMatrix,
|
modelViewMatrix,
|
||||||
squareRotation,
|
squareRotation,
|
||||||
[Math.abs(squareRotation % 1.0 - 0.5), 1, 1]);
|
[
|
||||||
|
squareRotation * 0.5,
|
||||||
|
squareRotation * 0.6,
|
||||||
|
0,
|
||||||
|
]);
|
||||||
|
|
||||||
// Tell WebGL how to pull out the positions from the position
|
// Tell WebGL how to pull out the positions from the position
|
||||||
// buffer into the vertexPosition attribute.
|
// buffer into the vertexPosition attribute.
|
||||||
|
@ -406,13 +330,7 @@ function drawScene(gl: any, programInfo: any, buffers: any, deltaTime: number) {
|
||||||
modelViewMatrix);
|
modelViewMatrix);
|
||||||
|
|
||||||
{
|
{
|
||||||
const offset = 0;
|
const vertexCount = length;
|
||||||
const vertexCount = 4;
|
|
||||||
gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const vertexCount = 36 * 69;
|
|
||||||
const type = gl.UNSIGNED_SHORT;
|
const type = gl.UNSIGNED_SHORT;
|
||||||
const offset = 0;
|
const offset = 0;
|
||||||
gl.drawElements(gl.TRIANGLES, vertexCount, type, offset);
|
gl.drawElements(gl.TRIANGLES, vertexCount, type, offset);
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
export default function convert (objText) {
|
||||||
|
const lines = objText.split("\n");
|
||||||
|
|
||||||
|
let smoothing = false;
|
||||||
|
|
||||||
|
const positions = [];
|
||||||
|
const uvs = [];
|
||||||
|
const normals = [];
|
||||||
|
|
||||||
|
const vertices = [];
|
||||||
|
const indices = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < lines.length; i++) {
|
||||||
|
const line = lines[i];
|
||||||
|
const chunks = line.split(" ").map(x => x.trim());
|
||||||
|
|
||||||
|
switch (chunks[0]) {
|
||||||
|
case "v": {
|
||||||
|
positions.push(chunks.splice(1).map(parseFloat));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "vt": {
|
||||||
|
const uv = chunks.splice(1);
|
||||||
|
uvs.push([parseFloat(uv[0]), parseFloat(uv[1])]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "vn": {
|
||||||
|
normals.push(chunks.splice(1).map(parseFloat));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "s": {
|
||||||
|
if (chunks[1] > 0) {
|
||||||
|
smoothing = true;
|
||||||
|
} else {
|
||||||
|
smoothing = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "f": {
|
||||||
|
const c1 = (smoothing ? "s" : "") + chunks[1];
|
||||||
|
const c2 = (smoothing ? "s" : "") + chunks[2];
|
||||||
|
const c3 = (smoothing ? "s" : "") + chunks[3];
|
||||||
|
|
||||||
|
|
||||||
|
let index1 = vertices.indexOf(c1);
|
||||||
|
if (index1 === -1) {
|
||||||
|
index1 = vertices.length;
|
||||||
|
vertices.push(c1);
|
||||||
|
}
|
||||||
|
|
||||||
|
let index2 = vertices.indexOf(c2);
|
||||||
|
if (index2 === -1) {
|
||||||
|
index2 = vertices.length;
|
||||||
|
vertices.push(c2);
|
||||||
|
}
|
||||||
|
|
||||||
|
let index3 = vertices.indexOf(c3);
|
||||||
|
if (index3 === -1) {
|
||||||
|
index3 = vertices.length;
|
||||||
|
vertices.push(c3);
|
||||||
|
}
|
||||||
|
|
||||||
|
indices.push(index1, index2, index3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const avgNormals = [];
|
||||||
|
for (let i = 0; i < vertices.length; i++) {
|
||||||
|
if (vertices[i].startsWith("s")) {
|
||||||
|
const d = vertices[i].substr(1).split("/");
|
||||||
|
const normal = normals[d[2] - 1];
|
||||||
|
const index = d[0] - 1;
|
||||||
|
|
||||||
|
if (avgNormals[index]) {
|
||||||
|
avgNormals[index][0] += normal[0];
|
||||||
|
avgNormals[index][1] += normal[1];
|
||||||
|
avgNormals[index][2] += normal[2];
|
||||||
|
} else {
|
||||||
|
avgNormals[index] = normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let n of avgNormals) {
|
||||||
|
const len = Math.hypot(...n);
|
||||||
|
avgNormals[avgNormals.indexOf(n)] = n.map(x => x / len);
|
||||||
|
}
|
||||||
|
|
||||||
|
const outPositions = [];
|
||||||
|
const outNormals = [];
|
||||||
|
const outUVs = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < vertices.length; i++) {
|
||||||
|
const d = (vertices[i].startsWith("s") ? vertices[i].substr(1) : vertices[i]).split("/");
|
||||||
|
|
||||||
|
outPositions.push(...positions[d[0] - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(indices);
|
||||||
|
|
||||||
|
return [outPositions, outNormals, outUVs, indices];
|
||||||
|
};
|
Loading…
Reference in New Issue