1. 程式人生 > 實用技巧 >LayaAir2.x 動態建立網格(二) 多個材質貼圖

LayaAir2.x 動態建立網格(二) 多個材質貼圖

export default class Test extends Laya.Script{
	
	protected onAwake():void{
		//建立3d場景
		let scene = Laya.stage.addChild(new Laya.Scene3D());
		//建立相機
		let camera = new Laya.Camera(0, 0.1, 100);
		scene.addChild(camera);
		camera.transform.translate(new Laya.Vector3(0, 0, 5));
		camera.transform.rotate(new Laya.Vector3(0, 0, 0), true, false);
		//建立燈光
		let directionLight = new Laya.DirectionLight();
		scene.addChild(directionLight);
		let mat = directionLight.transform.worldMatrix;
		mat.setForward(new Laya.Vector3(1.0, -1.0, -1.0));
		directionLight.transform.worldMatrix = mat;	
		
		//建立網格
		//let mesh=this.createTriangle();
		let mesh=this.createQuad2();
		let meshSprite3d = new Laya.MeshSprite3D(mesh);
		scene.addChild(meshSprite3d);
		meshSprite3d.transform.position = new Laya.Vector3(0, 0, 0);
		meshSprite3d.transform.rotate(new Laya.Vector3(0, 0, 0), false, false);
		
		//設定材質、貼圖
		let textureUrls=["res/atlas/comp.png","res/flower.jpg"];
		Laya.loader.create(textureUrls.slice(),Laya.Handler.create(null,()=>{//注意此處的 textureUrls.slice() 對陣列進行淺拷貝,因為 Laya.loader.create() 內部會對陣列進行修改
			let materials=[];
			for(let i=0;i<textureUrls.length;i++){
				let texture:Laya.Texture2D=Laya.loader.getRes(textureUrls[i]);
				//在U方向上使用WARPMODE_CLAMP
				texture.wrapModeU = Laya.WarpMode.Clamp;
				//在V方向使用WARPMODE_REPEAT
				texture.wrapModeV = Laya.WarpMode.Repeat;
				//設定過濾方式
				texture.filterMode = Laya.FilterMode.Bilinear;
				//設定各向異性等級
				texture.anisoLevel = 2;
				//設定材質
				let material=new Laya.BlinnPhongMaterial();
				material.albedoTexture=texture;
				materials[i]=material;
			}
			meshSprite3d.meshRenderer.materials=materials;
		}));
		
	}
	
	/*private createQuad():Laya.Mesh{
		const long=2;
		const width=1;
		let vertexDeclaration = Laya.VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
		let halfLong = long / 2;
		let halfWidth = width / 2;
		let vertices = new Float32Array([
			-halfLong, halfWidth, 0, 0, 0, 1, 0, 0, 
			halfLong, halfWidth, 0, 0, 0, 1, 1, 0, 
			-halfLong, -halfWidth, 0, 0, 0, 1, 0, 1, 
			halfLong, -halfWidth, 0, 0, 0, 1, 1, 1
		]);
		let indices = new Uint16Array([0, 1, 2, 3, 2, 1]);
		return this.createMesh(vertexDeclaration, vertices, indices);
	}*/
	
	/*private createTriangle():Laya.Mesh{
		const w=2;
		const h=1;
		
		let vertexDeclaration = Laya.VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
		let vertices = new Float32Array([
			-w, h,0, 0,0,1, 0,0,
			 w, h,0, 0,0,1, 1,0,
			-w,-h,0, 0,0,1, 0,1,
		]);
		let indices = new Uint16Array([
			0,1,2
		]);
		return this.createMesh(vertexDeclaration, vertices, indices);
	}*/
	
	private createQuad2():Laya.Mesh{
		const w=2;
		const h=1;
		
		let vertexDeclaration = Laya.VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
		let vertices = new Float32Array([
			-w, h,0, 0,0,1, 0,0,
			 w, h,0, 0,0,1, 1,0,
			-w,-h,0, 0,0,1, 0,1,
			 w,-h,0, 0,0,1, 1,1
		]);
		let indices = new Uint16Array([
			0,1,2,
			3,2,1
		]);
		let subMeshIndexRangeList=new Uint16Array([
			0,3,
			3,3
		])
		return this.createMesh(vertexDeclaration, vertices, indices,subMeshIndexRangeList);
	}
	
	/**
	 * 建立網格
	 * @param vertexDeclaration 頂點宣告,如:let vertexDeclaration = Laya.VertexMesh.getVertexDeclaration("POSITION,NORMAL,UV");
	 * @param vertices 頂點列表
	 * @param indices 三角形索引列表
	 * @param subMeshIndexRangeList 各子網格的三角形索引起始點和計數,長度必須是2的倍數且大於等於2,如:[0,3, 3,3]
	 */
	private createMesh(vertexDeclaration:Laya.VertexDeclaration, vertices:Float32Array, indices:Uint16Array,subMeshIndexRangeList:Uint16Array=null):Laya.Mesh{
		let gl = Laya["LayaGL"].instance;
		let mesh = new Laya.Mesh();
		
		let vertexBuffer = new Laya.VertexBuffer3D(vertices.length * 4, gl.STATIC_DRAW, true);
		vertexBuffer.vertexDeclaration = vertexDeclaration;
		vertexBuffer.setData(vertices.buffer);
		mesh["_vertexBuffer"] = vertexBuffer;
		mesh["_vertexCount"] = vertexBuffer._byteLength / vertexDeclaration.vertexStride;
		
		let indexBuffer = new Laya.IndexBuffer3D(Laya.IndexFormat.UInt16, indices.length, gl.STATIC_DRAW, true);
		indexBuffer.setData(indices);
		mesh["_indexBuffer"] = indexBuffer;
		mesh["_setBuffer"](vertexBuffer, indexBuffer);
		
		mesh["_setInstanceBuffer"](mesh["_instanceBufferStateType"]);
		
		let subMeshes = [];
		if(subMeshIndexRangeList && subMeshIndexRangeList.length>0){
			for(let i=0,len=subMeshIndexRangeList.length/2;i<len;i++){
				let subMeshIndexStart=subMeshIndexRangeList[i*2+0];
				let subMeshIndexCount=subMeshIndexRangeList[i*2+1];
				
				let subMesh = new Laya.SubMesh(mesh);
				subMesh["_vertexBuffer"] = vertexBuffer;
				subMesh["_indexBuffer"] = indexBuffer;
				subMesh["_setIndexRange"](subMeshIndexStart, subMeshIndexCount);
				let subIndexBufferStart = subMesh["_subIndexBufferStart"];
				let subIndexBufferCount = subMesh["_subIndexBufferCount"];
				let boneIndicesList = subMesh["_boneIndicesList"];
				subIndexBufferStart.length = 1;
				subIndexBufferCount.length = 1;
				boneIndicesList.length = 1;
				subIndexBufferStart[0] = subMeshIndexStart;
				subIndexBufferCount[0] = subMeshIndexCount;
				subMeshes.push(subMesh);
			}
		}else{
			let subMesh = new Laya.SubMesh(mesh);
			subMesh["_vertexBuffer"] = vertexBuffer;
			subMesh["_indexBuffer"] = indexBuffer;
			subMesh["_setIndexRange"](0, indexBuffer.indexCount);
			let subIndexBufferStart = subMesh["_subIndexBufferStart"];
			let subIndexBufferCount = subMesh["_subIndexBufferCount"];
			let boneIndicesList = subMesh["_boneIndicesList"];
			subIndexBufferStart.length = 1;
			subIndexBufferCount.length = 1;
			boneIndicesList.length = 1;
			subIndexBufferStart[0] = 0;
			subIndexBufferCount[0] = indexBuffer.indexCount;
			subMeshes.push(subMesh);
		}
		mesh["_setSubMeshes"](subMeshes);
		
		mesh.calculateBounds();
		let memorySize = vertexBuffer._byteLength + indexBuffer._byteLength;
		mesh["_setCPUMemory"](memorySize);
		mesh["_setGPUMemory"](memorySize);
		return mesh;
	}
	
}