Example #1
0
        private void ApplyTextures(MatsChunk.Material mat)
        {
            /* Texture stages */
            for (int i = 0; i < 3; i++)
            {
                GL.ActiveTexture(TextureUnit.Texture0 + i);
                if (Properties.Settings.Default.DisableAllShaders)
                {
                    GL.Enable(EnableCap.Texture2D);
                }
                else
                {
                    GL.Disable(EnableCap.Texture2D);
                }

                if (Properties.Settings.Default.EnableTextures && Root.TexChunk.Textures.Length > 0 && mat.TextureIDs[i] != -1)
                {
                    /* Bind texture & set parameters */
                    GL.BindTexture(TextureTarget.Texture2D, Root.TexChunk.Textures[mat.TextureIDs[i]].GLID);

                    if (mat.TextureMinFilters[i] != TextureMinFilter.Linear && mat.TextureMinFilters[i] != TextureMinFilter.Nearest)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
                    }
                    else
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)mat.TextureMinFilters[i]);
                    }

                    if (mat.TextureMagFilters[i] != TextureMagFilter.Linear && mat.TextureMagFilters[i] != TextureMagFilter.Nearest)
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)mat.TextureMagFilters[i]);
                    }
                    else
                    {
                        GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)mat.TextureMagFilters[i]);
                    }

                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)mat.TextureWrapModeSs[i]);
                    GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)mat.TextureWrapModeTs[i]);
                }
                else
                {
                    GL.BindTexture(TextureTarget.Texture2D, emptyTexture);
                }
            }
        }
Example #2
0
        private static void WriteSectionLibraryVisualScenes(XmlTextWriter xw, CmbChunk cmbRoot)
        {
            xw.WriteStartElement("library_visual_scenes");
            {
                xw.WriteStartElement("visual_scene");
                xw.WriteAttributeString("id", "default");
                {
                    foreach (MshsChunk.Mesh mesh in cmbRoot.SklmChunk.MshsChunk.Meshes)
                    {
                        SepdChunk          sepd = cmbRoot.SklmChunk.ShpChunk.SepdChunks[mesh.SepdID];
                        MatsChunk.Material mat  = cmbRoot.MatsChunk.Materials[mesh.MaterialID];

                        string nodeId = string.Format("node-{0:X8}", mesh.GetHashCode());
                        xw.WriteStartElement("node");
                        xw.WriteAttributeString("id", nodeId);
                        xw.WriteAttributeString("name", nodeId);
                        {
                            xw.WriteStartElement("translate");
                            xw.WriteString("0.0 0.0 0.0");
                            xw.WriteEndElement();

                            xw.WriteStartElement("rotate");
                            xw.WriteString("0.0 0.0 1.0 0.0");
                            xw.WriteEndElement();

                            xw.WriteStartElement("rotate");
                            xw.WriteString("0.0 1.0 0.0 0.0");
                            xw.WriteEndElement();

                            xw.WriteStartElement("rotate");
                            xw.WriteString("1.0 0.0 0.0 0.0");
                            xw.WriteEndElement();

                            xw.WriteStartElement("scale");
                            xw.WriteString("1.0 1.0 1.0");
                            xw.WriteEndElement();

                            xw.WriteStartElement("instance_geometry");
                            xw.WriteAttributeString("url", string.Format("#geom-{0:X8}", mesh.GetHashCode()));
                            {
                                xw.WriteStartElement("bind_material");
                                {
                                    xw.WriteStartElement("technique_common");
                                    {
                                        xw.WriteStartElement("instance_material");
                                        xw.WriteAttributeString("symbol", string.Format("material-{0:X8}-symbol", mat.GetHashCode()));
                                        xw.WriteAttributeString("target", string.Format("#material-{0:X8}", mat.GetHashCode()));
                                        xw.WriteEndElement();
                                    }
                                    xw.WriteEndElement();
                                }
                                xw.WriteEndElement();
                            }
                            xw.WriteEndElement();
                        }
                        xw.WriteEndElement();
                    }
                }
                xw.WriteEndElement();
            }
            xw.WriteEndElement();
        }
Example #3
0
        public void Render(short meshToRender, Csab.AnimHandler animHandler = null)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException(string.Format("{0} was disposed", this.GetType().Name));
            }

            GL.PushAttrib(AttribMask.AllAttribBits);
            GL.PushClientAttrib(ClientAttribMask.ClientAllAttribBits);

            /* If we haven't yet, prepare some OGL stuff (shaders etc) */
            if (!ready)
            {
                PrepareGL();
            }

            /* Shaders or no shaders? */
            if (Properties.Settings.Default.DisableAllShaders)
            {
                GL.UseProgram(0);
            }
            else
            {
                GL.UseProgram(program);
            }

            /* Some setup if we want the wireframe overlay... */
            if (Properties.Settings.Default.AddWireframeOverlay)
            {
                GL.Enable(EnableCap.PolygonOffsetFill);
                GL.PolygonOffset(2.0f, 2.0f);
            }
            else
            {
                GL.Disable(EnableCap.PolygonOffsetFill);
            }

            /* Determine what to render... */
            List <MshsChunk.Mesh> renderList = new List <MshsChunk.Mesh>();

            if (meshToRender != -1)
            {
                renderList.Add(Root.SklmChunk.MshsChunk.Meshes[meshToRender]);
            }
            else
            {
                renderList.AddRange(Root.SklmChunk.MshsChunk.Meshes);
                renderList = renderList.OrderBy(x => x.Unknown).ToList();
            }

            /* Render meshes normally */
            foreach (MshsChunk.Mesh mesh in renderList)
            {
                if (mesh.SepdID > Root.SklmChunk.ShpChunk.SepdChunks.Length)
                {
                    continue;
                }
                if (mesh.MaterialID > Root.MatsChunk.Materials.Length)
                {
                    continue;
                }
                if (mesh.MaterialID > Root.MatsChunk.TextureEnvSettings.Length)
                {
                    continue;
                }

                SepdChunk                   sepd = Root.SklmChunk.ShpChunk.SepdChunks[mesh.SepdID];
                MatsChunk.Material          mat  = Root.MatsChunk.Materials[mesh.MaterialID];
                MatsChunk.TextureEnvSetting tenv = Root.MatsChunk.TextureEnvSettings[mesh.MaterialID];

                /* Blend, Alphatest, etc (likely incorrect) */
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(mat.BlendingFactorSrc, mat.BlendingFactorDest);
                GL.BlendColor(1.0f, 1.0f, 1.0f, mat.BlendColorA);
                if (mat.AlphaTestEnable)
                {
                    GL.Enable(EnableCap.AlphaTest);
                }
                else
                {
                    GL.Disable(EnableCap.AlphaTest);
                }
                GL.AlphaFunc(mat.AlphaFunction, mat.AlphaReference);

                /* Texenv stuff testing, tho it doesn't work w/ shaders anyway, I dunno */
                /* Probably needs seperate shader per material, where the texenv stuff gets simulated... */
                /* And yes, I know this doesn't map 100% to standard OpenGL anyway */
                if (false)
                {
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Combine);

                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.CombineRgb, (int)tenv.CombineRgb);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Source0Rgb, (int)tenv.SourceRgb[0]); // OpenTK, Y U name this one differently?
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Src1Rgb, (int)tenv.SourceRgb[1]);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Src2Rgb, (int)tenv.SourceRgb[2]);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Operand0Rgb, (int)tenv.OperandRgb[0]);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Operand1Rgb, (int)tenv.OperandRgb[1]);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Operand2Rgb, (int)tenv.OperandRgb[2]);

                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.CombineAlpha, (int)tenv.CombineAlpha);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Src0Alpha, (int)tenv.SourceAlpha[0]);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Src1Alpha, (int)tenv.SourceAlpha[1]);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Src2Alpha, (int)tenv.SourceAlpha[2]);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Operand0Alpha, (int)tenv.OperandAlpha[0]);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Operand1Alpha, (int)tenv.OperandAlpha[1]);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.Operand2Alpha, (int)tenv.OperandAlpha[2]);
                }

                /* Apply textures :P */
                ApplyTextures(mat);

                /* Setup component arrays */
                GL.DisableClientState(ArrayCap.NormalArray);
                GL.DisableClientState(ArrayCap.ColorArray);
                GL.DisableClientState(ArrayCap.TextureCoordArray);
                GL.DisableClientState(ArrayCap.VertexArray);

                SetupNormalArray(sepd);
                SetupColorArray(sepd);
                SetupTextureCoordArray(sepd);
                SetupVertexArray(sepd);

                /* Send stuff to shader */
                GL.Uniform1(boneIdLocation, 0);

                GL.Uniform1(vertBoneSamplerLocation, vertBoneTexUnit);

                GL.Uniform1(tex0Location, 0);
                GL.Uniform1(tex1Location, 1);
                GL.Uniform1(tex2Location, 2);

                //GL.Uniform4(materialColorLocation, 1.0f, 1.0f, 1.0f, mat.Float158);
                GL.Uniform4(materialColorLocation, 1.0f, 1.0f, 1.0f, 1.0f);

                GL.Uniform1(vertexScaleLocation, sepd.VertexArrayScale);
                GL.Uniform1(texCoordScaleLocation, sepd.TextureCoordArrayScale);
                GL.Uniform1(normalScaleLocation, sepd.NormalArrayScale);

                GL.Uniform1(disableAlphaLocation, Convert.ToInt16(Properties.Settings.Default.DisableAlpha));
                GL.Uniform1(enableLightingLocation, Convert.ToInt16(Properties.Settings.Default.EnableLighting));
                GL.Uniform1(enableSkeletalStuffLocation, Convert.ToInt16(Properties.Settings.Default.EnableSkeletalStuff));

                /* Render each prms chunk */
                foreach (PrmsChunk prms in sepd.PrmsChunks)
                {
                    PrepareBoneInformation(sepd, prms);
                    GL.Uniform1(skinningModeLocation, Convert.ToInt16(prms.SkinningMode));
                    RenderBuffer(prms);
                }

                /* Clean up arrays */
                GL.DisableClientState(ArrayCap.NormalArray);
                GL.DisableClientState(ArrayCap.ColorArray);
                GL.DisableClientState(ArrayCap.TextureCoordArray);
                GL.DisableClientState(ArrayCap.VertexArray);
            }

            /* Render wireframe overlay */
            if (Properties.Settings.Default.AddWireframeOverlay && !Properties.Settings.Default.DisableAllShaders)
            {
                GL.UseProgram(programOverlay);

                foreach (MshsChunk.Mesh mesh in renderList)
                {
                    GL.Disable(EnableCap.PolygonOffsetFill);
                    GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);

                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

                    SepdChunk sepd = Root.SklmChunk.ShpChunk.SepdChunks[mesh.SepdID];
                    GL.Uniform1(vertexScaleLocationOverlay, sepd.VertexArrayScale);
                    GL.Uniform1(enableSkeletalStuffLocationOverlay, Convert.ToInt16(Properties.Settings.Default.EnableSkeletalStuff));

                    SetupVertexArray(sepd);

                    GL.Uniform1(boneIdLocationOverlay, 0);
                    GL.Uniform1(vertBoneSamplerLocationOverlay, vertBoneTexUnit);

                    foreach (PrmsChunk prms in sepd.PrmsChunks)
                    {
                        PrepareBoneInformation(sepd, prms);
                        GL.Uniform1(skinningModeLocationOverlay, Convert.ToInt16(prms.SkinningMode));
                        RenderBuffer(prms);
                    }

                    GL.DisableClientState(ArrayCap.NormalArray);
                    GL.DisableClientState(ArrayCap.ColorArray);
                    GL.DisableClientState(ArrayCap.TextureCoordArray);
                    GL.DisableClientState(ArrayCap.VertexArray);
                }
            }

            /* Reset stuff */
            GL.Disable(EnableCap.AlphaTest);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);

            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

            /* Render skeleton */
            //if (false)
            {
                // TODO  get rid of immediate mode
                GL.PushAttrib(AttribMask.AllAttribBits);
                GL.Disable(EnableCap.Texture2D);
                GL.Disable(EnableCap.DepthTest);
                GL.Disable(EnableCap.Lighting);
                GL.PointSize(10.0f);
                GL.LineWidth(5.0f);
                GL.UseProgram(0);
                GL.Color4(Color4.Red);
                GL.Begin(PrimitiveType.Points);
                foreach (SklChunk.Bone bone in Root.SklChunk.Bones)
                {
                    GL.Vertex3(Vector3.Transform(Vector3.One, bone.GetMatrix(true)));
                }
                GL.End();
                GL.Color4(Color4.Blue);
                GL.Begin(PrimitiveType.Lines);
                foreach (SklChunk.Bone bone in Root.SklChunk.Bones.Where(x => x.ParentBone != null))
                {
                    GL.Vertex3(Vector3.Transform(Vector3.One, bone.GetMatrix(true)));
                    GL.Vertex3(Vector3.Transform(Vector3.One, bone.ParentBone.GetMatrix(true)));
                }
                GL.End();
                GL.PopAttrib();
                // END TODO
            }

            GL.PopClientAttrib();
            GL.PopAttrib();
        }
Example #4
0
        private static void WriteSectionLibraryGeometry(XmlTextWriter xw, CmbChunk cmbRoot)
        {
            xw.WriteStartElement("library_geometries");
            {
                foreach (MshsChunk.Mesh mesh in cmbRoot.SklmChunk.MshsChunk.Meshes)
                {
                    SepdChunk          sepd = cmbRoot.SklmChunk.ShpChunk.SepdChunks[mesh.SepdID];
                    MatsChunk.Material mat  = cmbRoot.MatsChunk.Materials[mesh.MaterialID];

                    string meshId = string.Format("geom-{0:X8}", mesh.GetHashCode());
                    xw.WriteStartElement("geometry");
                    xw.WriteAttributeString("id", meshId);
                    xw.WriteAttributeString("name", meshId);
                    {
                        xw.WriteStartElement("mesh");
                        {
                            /* Vertices */
                            xw.WriteStartElement("source");
                            xw.WriteAttributeString("id", string.Format("{0}-pos", meshId));
                            {
                                float[] vtxData = ConvertToFloatArray(sepd.VertexArrayDataType, cmbRoot.VatrChunk.Vertices, sepd.VertexArrayOffset, sepd.VertexArrayScale);

                                xw.WriteStartElement("float_array");
                                xw.WriteAttributeString("id", string.Format("{0}-pos-array", meshId));
                                xw.WriteAttributeString("count", string.Format("{0}", vtxData.Length));
                                {
                                    for (int i = 0; i < vtxData.Length; i++)
                                    {
                                        xw.WriteString(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00} ", vtxData[i]));
                                    }
                                }
                                xw.WriteEndElement();

                                xw.WriteStartElement("technique_common");
                                {
                                    xw.WriteStartElement("accessor");
                                    xw.WriteAttributeString("source", string.Format("#{0}-pos-array", meshId));
                                    xw.WriteAttributeString("count", string.Format("{0}", vtxData.Length / 3));
                                    xw.WriteAttributeString("stride", "3");
                                    {
                                        xw.WriteStartElement("param");
                                        xw.WriteAttributeString("name", "X");
                                        xw.WriteAttributeString("type", "float");
                                        xw.WriteEndElement();

                                        xw.WriteStartElement("param");
                                        xw.WriteAttributeString("name", "Y");
                                        xw.WriteAttributeString("type", "float");
                                        xw.WriteEndElement();

                                        xw.WriteStartElement("param");
                                        xw.WriteAttributeString("name", "Z");
                                        xw.WriteAttributeString("type", "float");
                                        xw.WriteEndElement();
                                    }
                                    xw.WriteEndElement();
                                }
                                xw.WriteEndElement();
                            }
                            xw.WriteEndElement();

                            /* Texcoords */
                            xw.WriteStartElement("source");
                            xw.WriteAttributeString("id", string.Format("{0}-texcoord", meshId));
                            {
                                float[] texCoordData = ConvertToFloatArray(sepd.TextureCoordArrayDataType, cmbRoot.VatrChunk.TextureCoords, sepd.TextureCoordArrayOffset, sepd.TextureCoordArrayScale);

                                xw.WriteStartElement("float_array");
                                xw.WriteAttributeString("id", string.Format("{0}-texcoord-array", meshId));
                                xw.WriteAttributeString("count", string.Format("{0}", texCoordData.Length));
                                {
                                    for (int i = 0; i < texCoordData.Length; i++)
                                    {
                                        xw.WriteString(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00} ", texCoordData[i]));
                                    }
                                }
                                xw.WriteEndElement();

                                xw.WriteStartElement("technique_common");
                                {
                                    xw.WriteStartElement("accessor");
                                    xw.WriteAttributeString("source", string.Format("#{0}-texcoord-array", meshId));
                                    xw.WriteAttributeString("count", string.Format("{0}", texCoordData.Length / 2));
                                    xw.WriteAttributeString("stride", "2");
                                    {
                                        xw.WriteStartElement("param");
                                        xw.WriteAttributeString("name", "S");
                                        xw.WriteAttributeString("type", "float");
                                        xw.WriteEndElement();

                                        xw.WriteStartElement("param");
                                        xw.WriteAttributeString("name", "T");
                                        xw.WriteAttributeString("type", "float");
                                        xw.WriteEndElement();
                                    }
                                    xw.WriteEndElement();
                                }
                                xw.WriteEndElement();
                            }
                            xw.WriteEndElement();

                            /* Colors */
                            xw.WriteStartElement("source");
                            xw.WriteAttributeString("id", string.Format("{0}-colors", meshId));
                            {
                                float[] colorData = ConvertToFloatArray(sepd.ColorArrayDataType, cmbRoot.VatrChunk.Colors, sepd.ColorArrayOffset, sepd.ColorArrayScale);

                                xw.WriteStartElement("float_array");
                                xw.WriteAttributeString("id", string.Format("{0}-colors-array", meshId));
                                xw.WriteAttributeString("count", string.Format("{0}", colorData.Length));
                                {
                                    for (int i = 0; i < colorData.Length; i++)
                                    {
                                        xw.WriteString(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00} ", colorData[i]));
                                    }
                                }
                                xw.WriteEndElement();

                                xw.WriteStartElement("technique_common");
                                {
                                    xw.WriteStartElement("accessor");
                                    xw.WriteAttributeString("source", string.Format("#{0}-colors-array", meshId));
                                    xw.WriteAttributeString("count", string.Format("{0}", colorData.Length / 4));
                                    xw.WriteAttributeString("stride", "4");
                                    {
                                        xw.WriteStartElement("param");
                                        xw.WriteAttributeString("name", "R");
                                        xw.WriteAttributeString("type", "float");
                                        xw.WriteEndElement();

                                        xw.WriteStartElement("param");
                                        xw.WriteAttributeString("name", "G");
                                        xw.WriteAttributeString("type", "float");
                                        xw.WriteEndElement();

                                        xw.WriteStartElement("param");
                                        xw.WriteAttributeString("name", "B");
                                        xw.WriteAttributeString("type", "float");
                                        xw.WriteEndElement();

                                        xw.WriteStartElement("param");
                                        xw.WriteAttributeString("name", "A");
                                        xw.WriteAttributeString("type", "float");
                                        xw.WriteEndElement();
                                    }
                                    xw.WriteEndElement();
                                }
                                xw.WriteEndElement();
                            }
                            xw.WriteEndElement();

                            /* Normals */

                            /*xw.WriteStartElement("source");
                             * xw.WriteAttributeString("id", string.Format("{0}-norm", meshId));
                             * {
                             *  float[] normData = ConvertToFloatArray(sepd.NormalArrayFormat, cmbRoot.VatrChunk.Normals, sepd.NormalArrayDisplacement, sepd.NormalArrayScale);
                             *
                             *  xw.WriteStartElement("float_array");
                             *  xw.WriteAttributeString("id", string.Format("{0}-norm-array", meshId));
                             *  xw.WriteAttributeString("count", string.Format("{0}", normData.Length));
                             *  {
                             *      for (int i = 0; i < normData.Length; i += 3)
                             *      {
                             *          xw.WriteString(string.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:0.00} {1:0.00} {2:0.00} ", normData[i], normData[i + 1], normData[i + 2]));
                             *      }
                             *  }
                             *  xw.WriteEndElement();
                             *
                             *  xw.WriteStartElement("technique_common");
                             *  {
                             *      xw.WriteStartElement("accessor");
                             *      xw.WriteAttributeString("source", string.Format("#{0}-norm-array", meshId));
                             *      xw.WriteAttributeString("count", string.Format("{0}", normData.Length / 3));
                             *      xw.WriteAttributeString("stride", "3");
                             *      {
                             *          xw.WriteStartElement("param");
                             *          xw.WriteAttributeString("name", "X");
                             *          xw.WriteAttributeString("type", "float");
                             *          xw.WriteEndElement();
                             *
                             *          xw.WriteStartElement("param");
                             *          xw.WriteAttributeString("name", "Y");
                             *          xw.WriteAttributeString("type", "float");
                             *          xw.WriteEndElement();
                             *
                             *          xw.WriteStartElement("param");
                             *          xw.WriteAttributeString("name", "Z");
                             *          xw.WriteAttributeString("type", "float");
                             *          xw.WriteEndElement();
                             *      }
                             *      xw.WriteEndElement();
                             *  }
                             *  xw.WriteEndElement();
                             * }
                             * xw.WriteEndElement();
                             */
                            xw.WriteStartElement("vertices");
                            xw.WriteAttributeString("id", string.Format("{0}-vtx", meshId));
                            {
                                xw.WriteStartElement("input");
                                xw.WriteAttributeString("semantic", "POSITION");
                                xw.WriteAttributeString("source", string.Format("#{0}-pos", meshId));
                                xw.WriteEndElement();
                            }
                            xw.WriteEndElement();

                            foreach (PrmsChunk prms in sepd.PrmsChunks)
                            {
                                xw.WriteStartElement("triangles");
                                xw.WriteAttributeString("count", string.Format("{0}", prms.PrmChunk.NumberOfIndices));
                                xw.WriteAttributeString("material", string.Format("material-{0:X8}-symbol", mat.GetHashCode()));
                                {
                                    xw.WriteStartElement("input");
                                    xw.WriteAttributeString("semantic", "VERTEX");
                                    xw.WriteAttributeString("source", string.Format("#{0}-vtx", meshId));
                                    xw.WriteAttributeString("offset", "0");
                                    xw.WriteEndElement();

                                    xw.WriteStartElement("input");
                                    xw.WriteAttributeString("semantic", "TEXCOORD");
                                    xw.WriteAttributeString("source", string.Format("#{0}-texcoord", meshId));
                                    xw.WriteAttributeString("offset", "0");
                                    xw.WriteEndElement();

                                    xw.WriteStartElement("input");
                                    xw.WriteAttributeString("semantic", "COLOR");
                                    xw.WriteAttributeString("source", string.Format("#{0}-colors", meshId));
                                    xw.WriteAttributeString("offset", "0");
                                    xw.WriteEndElement();

                                    /*
                                     * xw.WriteStartElement("input");
                                     * xw.WriteAttributeString("semantic", "NORMAL");
                                     * xw.WriteAttributeString("source", string.Format("#{0}-norm", meshId));
                                     * xw.WriteAttributeString("offset", "0");
                                     * xw.WriteEndElement();
                                     */
                                    uint[] idx = new uint[prms.PrmChunk.NumberOfIndices];
                                    switch (prms.PrmChunk.DataType)
                                    {
                                    case Constants.PicaDataType.UnsignedByte:
                                        for (int i = 0; i < prms.PrmChunk.NumberOfIndices; i++)
                                        {
                                            idx[i] = (uint)cmbRoot.Indices[(prms.PrmChunk.FirstIndex * sizeof(ushort)) + (i * prms.PrmChunk.ElementSize)];
                                        }
                                        break;

                                    case Constants.PicaDataType.UnsignedShort:
                                        for (int i = 0; i < prms.PrmChunk.NumberOfIndices; i++)
                                        {
                                            idx[i] = (uint)BitConverter.ToUInt16(cmbRoot.Indices, (prms.PrmChunk.FirstIndex * sizeof(ushort)) + (i * prms.PrmChunk.ElementSize));
                                        }
                                        break;

                                    case Constants.PicaDataType.UnsignedInt:
                                        for (int i = 0; i < prms.PrmChunk.NumberOfIndices; i++)
                                        {
                                            idx[i] = BitConverter.ToUInt32(cmbRoot.Indices, (prms.PrmChunk.FirstIndex * sizeof(ushort)) + (i * prms.PrmChunk.ElementSize));
                                        }
                                        break;
                                    }

                                    xw.WriteStartElement("p");
                                    {
                                        for (int i = 0; i < idx.Length; i++)
                                        {
                                            xw.WriteString(string.Format("{0} ", idx[i]));
                                        }
                                    }
                                    xw.WriteEndElement();
                                }
                                xw.WriteEndElement();
                            }
                        }
                        xw.WriteEndElement();
                    }
                    xw.WriteEndElement();
                }
            }
            xw.WriteEndElement();
        }