private void LoadSkins(BinaryReader reader) { mSkin = new M2SkinFile(ModelRoot, mModelName, 0); if (mSkin.Load() == false) { throw new InvalidOperationException("Unable to load skin file"); } Indices = mSkin.Indices; mSubMeshes = mSkin.SubMeshes.Select(sm => new M2SubMeshInfo { BoundingSphere = new BoundingSphere(sm.centerBoundingBox, sm.radius), NumIndices = sm.nTriangles, StartIndex = sm.startTriangle + (((sm.unk1 & 1) != 0) ? (ushort.MaxValue + 1) : 0) }).ToArray(); var texLookup = ReadArrayOf <ushort>(reader, mHeader.OfsTexLookup, mHeader.NTexLookup); var renderFlags = ReadArrayOf <uint>(reader, mHeader.OfsRenderFlags, mHeader.NRenderFlags); var uvAnimLookup = ReadArrayOf <short>(reader, mHeader.OfsUvAnimLookup, mHeader.NUvAnimLookup); foreach (var texUnit in mSkin.TexUnits) { var mesh = mSkin.SubMeshes[texUnit.submeshIndex]; int uvIndex; if (texUnit.textureAnimIndex >= uvAnimLookup.Length || uvAnimLookup[texUnit.textureAnimIndex] < 0) { uvIndex = -1; } else { uvIndex = uvAnimLookup[texUnit.textureAnimIndex]; } var startTriangle = (int)mesh.startTriangle; if ((mesh.unk1 & 1) != 0) { startTriangle += ushort.MaxValue + 1; } var textures = new List <Graphics.Texture>(); var texIndices = new List <int>(); switch (texUnit.op_count) { case 2: textures.Add(mTextures[texLookup[texUnit.texture]]); textures.Add(mTextures[texLookup[texUnit.texture + 1]]); texIndices.Add(texLookup[texUnit.texture]); texIndices.Add(texLookup[texUnit.texture + 1]); break; case 3: textures.Add(mTextures[texLookup[texUnit.texture]]); textures.Add(mTextures[texLookup[texUnit.texture + 1]]); textures.Add(mTextures[texLookup[texUnit.texture + 2]]); texIndices.Add(texLookup[texUnit.texture]); texIndices.Add(texLookup[texUnit.texture + 1]); texIndices.Add(texLookup[texUnit.texture + 2]); break; default: textures.Add(mTextures[texLookup[texUnit.texture]]); texIndices.Add(texLookup[texUnit.texture]); break; } var flags = renderFlags[texUnit.renderFlags]; var blendMode = flags >> 16; var flag = flags & 0xFFFF; if (mRemapBlend && texUnit.shaderId < mBlendMap.Length) { blendMode = mBlendMap[texUnit.shaderId]; } blendMode %= 7; if (blendMode != 0 && blendMode != 1) { HasBlendPass = true; } else { HasOpaquePass = true; } Passes.Add(new M2RenderPass { TextureIndices = texIndices, Textures = textures, AlphaAnimIndex = texUnit.transparencyIndex, ColorAnimIndex = texUnit.colorIndex, IndexCount = mesh.nTriangles, RenderFlag = flag, BlendMode = blendMode, StartIndex = startTriangle, TexAnimIndex = uvIndex, TexUnitNumber = texUnit.texUnitNumber, OpCount = texUnit.op_count, VertexShaderType = M2ShadersClass.GetVertexShaderType(texUnit.shaderId, texUnit.op_count), PixelShaderType = M2ShadersClass.GetPixelShaderType(texUnit.shaderId, texUnit.op_count), }); } SortPasses(); }
public void InitShaders() { // TODO: should they all go here? mM2Shaders = new M2ShadersClass(); mM2Shaders.Initialize(Context); }