/// DrawParts 内の、mesh を DrawOrder ごとに並び替える /** * note : DrawPart をまたぐようなソートは行わない点に注意すること. */ public void SortDrawParts() { foreach (var bone in Bones) { List <Part> partList = new List <Part>(); foreach (var index in bone.DrawParts) { BasicPart part = Parts[index]; foreach (var mesh in part.Meshes) { BasicMaterial material = Materials[mesh.Material]; partList.Add(new Part(mesh, material.DrawOrder)); } // パーツを DrawOrder 順にソート partList.Sort(delegate(Part lhs, Part rhs){ return(lhs.drawOrder - rhs.drawOrder); }); int i = 0; foreach (var sortedPart in partList) { part.Meshes[i] = sortedPart.mesh; i++; } } } }
void LoadPart(Chunk chunk, BasicPart part) { int nMeshes = CountChild(chunk, ChunkType.Mesh); part.Meshes = new BasicMesh[nMeshes]; for (int i = 0; i < nMeshes; i++) { part.Meshes[i] = new BasicMesh(); } int iMesh = 0; Chunk child; for (int pos = chunk.Child; pos < chunk.Next; pos = child.Next) { child = ReadChunk(pos); switch (child.Type) { case ChunkType.Mesh: LoadMesh(child, chunk, part.Meshes[iMesh++]); break; } } }
/// BasicMaterial に設定された ShaderName から、ShaderProgram を探して描画する public void Draw( GraphicsContext graphics, ShaderContainer shaderContainer, Matrix4 viewProj, Vector4 eye, float Brightness ) { foreach (var bone in Bones) { int worldCount = 0; // sky00_nami; // bone.Name = "sky00_nami"; int[] blendBones = bone.BlendBones; if (blendBones == null) { worldCount = 1; matrixBuffer = new Matrix4[1]; matrixBuffer[0] = bone.WorldMatrix; } else { int blendCount = blendBones.Length; if (blendCount > matrixBuffer.Length) { matrixBuffer = new Matrix4[blendCount]; } for (int i = 0; i < blendCount; i++) { matrixBuffer[i] = Bones[blendBones[i]].WorldMatrix * bone.BlendOffsets[i]; } } int[] blendSubset = defaultBlendSubset; foreach (var index in bone.DrawParts) { BasicPart part = Parts[index]; foreach (var mesh in part.Meshes) { if (blendBones != null && blendSubset != mesh.BlendSubset) { blendSubset = (mesh.BlendSubset != null) ? mesh.BlendSubset : defaultBlendSubset; worldCount = blendSubset.Length; if (worldCount > blendBones.Length) { worldCount = blendBones.Length; } } BasicMaterial material = Materials[mesh.Material]; if (material != null) { setPolygonMode(graphics, material); BasicProgram program = findBasicProgram(shaderContainer, material, worldCount, this.lightCount); graphics.SetShaderProgram(program); program.SetViewProj(viewProj); program.SetMaterial(ref material); if (material.LightEnable != 0) { program.SetLightCount(lightCount); program.SetLights(ref matrixBuffer[0], ref eye, ref lights); } else { program.SetLightCount(0); } program.SetRateLight(Brightness); setLayers(graphics, program, material); program.SetWorldCount(worldCount); for (int i = 0; i < worldCount; i++) { program.SetMatrixPalette(i, ref matrixBuffer[blendSubset[i]]); } program.Update(); } graphics.SetVertexBuffer(0, mesh.VertexBuffer); graphics.DrawArrays(mesh.Primitives); } } } }
/// DrawOrder の実装のため、 SubMesn を LocalPart としてリストに積みなおす private List <LocalPart> updateLocalPart() { List <LocalPart> localPartList = new List <LocalPart>(); foreach (var bone in Bones) { int worldCount = 0; int[] blendBones = bone.BlendBones; if (blendBones == null) { worldCount = 1; matrixBuffer = new Matrix4[1]; matrixBuffer[0] = bone.WorldMatrix; } else { int blendCount = blendBones.Length; if (blendCount > matrixBuffer.Length) { matrixBuffer = new Matrix4[blendCount]; } for (int i = 0; i < blendCount; i++) { matrixBuffer[i] = Bones[blendBones[i]].WorldMatrix * bone.BlendOffsets[i]; } } int[] blendSubset = defaultBlendSubset; foreach (var index in bone.DrawParts) { BasicPart part = Parts[index]; foreach (var mesh in part.Meshes) { if (blendBones != null && blendSubset != mesh.BlendSubset) { blendSubset = (mesh.BlendSubset != null) ? mesh.BlendSubset : defaultBlendSubset; worldCount = blendSubset.Length; if (worldCount > blendBones.Length) { worldCount = blendBones.Length; } } // パーツの保存 LocalPart localPart = new LocalPart(); if (mesh.Material >= 0) { localPart.material = Materials[mesh.Material]; } else { localPart.material = null; } localPart.worldCount = worldCount; localPart.vertexBuffer = mesh.VertexBuffer; localPart.primitives = mesh.Primitives; for (int i = 0; i < worldCount; i++) { localPart.matrixPalette[i] = matrixBuffer[blendSubset[i]]; } localPartList.Add(localPart); } } } return(localPartList); }
void LoadPart( Chunk chunk, BasicPart part ) { int nMeshes = CountChild( chunk, ChunkType.Mesh ) ; part.Meshes = new BasicMesh[ nMeshes ] ; for ( int i = 0 ; i < nMeshes ; i ++ ) part.Meshes[ i ] = new BasicMesh() ; int iMesh = 0 ; Chunk child ; for ( int pos = chunk.Child ; pos < chunk.Next ; pos = child.Next ) { child = ReadChunk( pos ) ; switch ( child.Type ) { case ChunkType.Mesh : LoadMesh( child, chunk, part.Meshes[ iMesh ++ ] ) ; break ; } } }