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
 | ||||
| import mat4 from 'gl-mat4'; | ||||
| // @ts-ignore
 | ||||
| import convert from './objparser'; | ||||
| 
 | ||||
| let squareRotation = 0.0; | ||||
| 
 | ||||
|  | @ -23,59 +25,66 @@ function main() { | |||
| 		attribute vec4 aVertexPosition; | ||||
| 		attribute vec4 aVertexColor; | ||||
| 
 | ||||
| 		uniform mat4 uModelViewMatrix; | ||||
| 		uniform mat4 uProjectionMatrix; | ||||
| 		uniform mat4 uModelViewMatrix; | ||||
| 
 | ||||
| 		varying lowp vec4 vColor; | ||||
| 
 | ||||
| 		void main() { | ||||
| 		void main() | ||||
| 		{ | ||||
| 			gl_Position = uProjectionMatrix * | ||||
| 				uModelViewMatrix * | ||||
| 				aVertexPosition; | ||||
| 			vColor = aVertexColor; | ||||
| 		} | ||||
| 	`;
 | ||||
| 
 | ||||
| 	const fsSource = ` | ||||
| 		varying lowp vec4 vColor; | ||||
| 	varying lowp vec4 vColor; | ||||
| 
 | ||||
| 		void main() { | ||||
| 			gl_FragColor = vColor; | ||||
| 	void main() { | ||||
| 		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 programInfo: any = { | ||||
| 			program: shaderProgram, | ||||
| 			attribLocations: { | ||||
| 				vertexPosition: gl.getAttribLocation(shaderProgram, | ||||
| 					'aVertexPosition'), | ||||
| 				vertexColor: gl.getAttribLocation(shaderProgram, | ||||
| 					'aVertexColor'), | ||||
| 			}, | ||||
| 			uniformLocations: { | ||||
| 				projectionMatrix: gl.getUniformLocation( | ||||
| 					shaderProgram, 'uProjectionMatrix'), | ||||
| 				modelViewMatrix: gl.getUniformLocation( | ||||
| 					shaderProgram, 'uModelViewMatrix'), | ||||
| 			}, | ||||
| 		}; | ||||
| 
 | ||||
| 		const buffers = initBuffers(gl, positions, indices); | ||||
| 		let then = 0; | ||||
| 
 | ||||
| 		/** | ||||
| 		 * Draws the scene repeatedly | ||||
| 		 * @param {number} now the current time | ||||
| 		 */ | ||||
| 		function render(now: any) { | ||||
| 			now *= 0.001; | ||||
| 			const deltaTime = now - then; | ||||
| 			then = now; | ||||
| 			drawScene(gl, programInfo, buffers, deltaTime, indices.length); | ||||
| 			requestAnimationFrame(render); | ||||
| 		} | ||||
| 	`;
 | ||||
| 
 | ||||
| 
 | ||||
| 	const shaderProgram = initShaderProgram(gl, vsSource, fsSource); | ||||
| 
 | ||||
| 	const programInfo: any = { | ||||
| 		program: shaderProgram, | ||||
| 		attribLocations: { | ||||
| 			vertexPosition: gl.getAttribLocation(shaderProgram, | ||||
| 				'aVertexPosition'), | ||||
| 			vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'), | ||||
| 		}, | ||||
| 		uniformLocations: { | ||||
| 			projectionMatrix: gl.getUniformLocation( | ||||
| 				shaderProgram, 'uProjectionMatrix'), | ||||
| 			modelViewMatrix: gl.getUniformLocation( | ||||
| 				shaderProgram, 'uModelViewMatrix'), | ||||
| 		}, | ||||
| 	}; | ||||
| 
 | ||||
| 	const buffers = initBuffers(gl); | ||||
| 	let then = 0; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Draws the scene repeatedly | ||||
| 	 * @param {number} now the current time | ||||
| 	 */ | ||||
| 	function render(now: any) { | ||||
| 		now *= 0.001; | ||||
| 		const deltaTime = now - then; | ||||
| 		then = now; | ||||
| 		drawScene(gl, programInfo, buffers, deltaTime); | ||||
| 		requestAnimationFrame(render); | ||||
| 	} | ||||
| 	requestAnimationFrame(render); | ||||
| 	}); | ||||
| } | ||||
| 
 | ||||
| /** | ||||
|  | @ -130,92 +139,16 @@ function loadShader(gl: any, type: any, source: string) { | |||
| /** | ||||
|  * init buffers to create a square | ||||
|  * @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 | ||||
|  */ | ||||
| function initBuffers(gl: any) { | ||||
| 	// Create a buffer for the square's positions.
 | ||||
| function initBuffers( | ||||
| 	gl: any, | ||||
| 	positions: Array<number>, | ||||
| 	indices: Array<number>) { | ||||
| 	const positionBuffer = gl.createBuffer(); | ||||
| 	// Select the positionBuffer as the one to apply buffer
 | ||||
| 	// operations to from here out.
 | ||||
| 	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.ARRAY_BUFFER, | ||||
| 		new Float32Array(positions), | ||||
|  | @ -239,17 +172,21 @@ function initBuffers(gl: any) { | |||
| 	} | ||||
| 	// 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 = [ | ||||
| 			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)], | ||||
| 		]; | ||||
| 		// 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(); | ||||
|  | @ -258,32 +195,9 @@ function initBuffers(gl: any) { | |||
| 
 | ||||
| 	const indexBuffer = gl.createBuffer(); | ||||
| 	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, | ||||
| 		new Uint16Array(indices), gl.STATIC_DRAW); | ||||
| 	// Now send the element array to GL
 | ||||
| 
 | ||||
| 	return { | ||||
| 		position: positionBuffer, | ||||
|  | @ -298,8 +212,13 @@ function initBuffers(gl: any) { | |||
|  * @param {any} programInfo WebGL program information | ||||
|  * @param {any} buffers the buffers to draw | ||||
|  * @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.clearDepth(1.0); | ||||
| 	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
 | ||||
| 	// start drawing the square.
 | ||||
| 	mat4.translate( | ||||
| 		modelViewMatrix, | ||||
| 		modelViewMatrix, | ||||
| 		[0.0, -1.0, 0]); | ||||
| 	mat4.rotate(modelViewMatrix, | ||||
| 		modelViewMatrix, | ||||
| 		Math.PI, | ||||
| 		[0, 1, 0]); | ||||
| 
 | ||||
| 	mat4.translate( | ||||
| 		modelViewMatrix, | ||||
| 		modelViewMatrix, | ||||
| 		[0.0, 0.0, 48]); | ||||
| 
 | ||||
| 
 | ||||
| 		[0.0, -0.0, 10]); | ||||
| 	mat4.rotate(modelViewMatrix, | ||||
| 		modelViewMatrix, | ||||
| 		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
 | ||||
| 	// buffer into the vertexPosition attribute.
 | ||||
|  | @ -406,13 +330,7 @@ function drawScene(gl: any, programInfo: any, buffers: any, deltaTime: number) { | |||
| 		modelViewMatrix); | ||||
| 
 | ||||
| 	{ | ||||
| 		const offset = 0; | ||||
| 		const vertexCount = 4; | ||||
| 		gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount); | ||||
| 	} | ||||
| 
 | ||||
| 	{ | ||||
| 		const vertexCount = 36 * 69; | ||||
| 		const vertexCount = length; | ||||
| 		const type = gl.UNSIGNED_SHORT; | ||||
| 		const offset = 0; | ||||
| 		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