예제 #1
0
        private void SetupTextureCoordArray(SepdChunk sepd)
        {
            if (!texCoordBufferObjects.ContainsKey(sepd))
            {
                return;
            }

            GL.EnableClientState(ArrayCap.TextureCoordArray);
            GL.BindBuffer(BufferTarget.ArrayBuffer, texCoordBufferObjects[sepd]);
            GL.TexCoordPointer(2, sepd.TexCoordPointerType, 0, IntPtr.Zero);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
예제 #2
0
        private void SetupVertexArray(SepdChunk sepd)
        {
            if (!vertexBufferObjects.ContainsKey(sepd))
            {
                return;
            }

            GL.EnableClientState(ArrayCap.VertexArray);
            GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBufferObjects[sepd]);
            GL.VertexPointer(3, sepd.VertexPointerType, 0, IntPtr.Zero);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
예제 #3
0
        private void SetupNormalArray(SepdChunk sepd)
        {
            if (!normalBufferObjects.ContainsKey(sepd))
            {
                return;
            }

            GL.EnableClientState(ArrayCap.NormalArray);
            GL.BindBuffer(BufferTarget.ArrayBuffer, normalBufferObjects[sepd]);
            GL.NormalPointer(sepd.NormalPointerType, 0, IntPtr.Zero);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
예제 #4
0
        private void SetupColorArray(SepdChunk sepd)
        {
            if (!colorBufferObjects.ContainsKey(sepd))
            {
                return;
            }

            GL.EnableClientState(ArrayCap.ColorArray);
            GL.BindBuffer(BufferTarget.ArrayBuffer, colorBufferObjects[sepd]);
            GL.ColorPointer(4, sepd.ColorPointerType, 0, IntPtr.Zero);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
예제 #5
0
        public ShpChunk(byte[] data, int offset, BaseCTRChunk parent)
            : base(data, offset, parent)
        {
            SepdCount = BitConverter.ToUInt32(ChunkData, 0x8);
            Unknown1  = BitConverter.ToUInt32(ChunkData, 0xC);

            SepdOffsets = new ushort[SepdCount];
            for (int i = 0; i < SepdOffsets.Length; i++)
            {
                SepdOffsets[i] = BitConverter.ToUInt16(ChunkData, 0x10 + (i * 2));
            }

            SepdChunks = new SepdChunk[SepdCount];
            for (int i = 0; i < SepdChunks.Length; i++)
            {
                SepdChunks[i] = new SepdChunk(ChunkData, SepdOffsets[i], this);
            }
        }
예제 #6
0
        public CmbChunk(byte[] data, int offset, BaseCTRChunk parent)
            : base(data, offset, parent)
        {
            FileSize        = BitConverter.ToUInt32(ChunkData, 0x4);
            NumberOfChunks  = BitConverter.ToUInt32(ChunkData, 0x8);
            Unknown2        = BitConverter.ToUInt32(ChunkData, 0xC);
            CmbName         = Encoding.ASCII.GetString(ChunkData, 0x10, 16).TrimEnd('\0');
            NumberOfIndices = BitConverter.ToUInt32(ChunkData, 0x20);

            BaseCTRChunk.IsMajora3D = (NumberOfChunks == 0x0A);

            if (!BaseCTRChunk.IsMajora3D)
            {
                SklChunk  = new SklChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, SklChunkPointer_OoT), this);
                MatsChunk = new MatsChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, MatsChunkPointer_OoT), this);
                TexChunk  = new TexChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, TexChunkPointer_OoT), this);
                SklmChunk = new SklmChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, SklmChunkPointer_OoT), this);
                VatrChunk = new VatrChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, VatrChunkPointer_OoT), this);

                vtxIdxOffset  = (int)BitConverter.ToUInt32(ChunkData, VertexIndicesPointer_OoT);
                texDataOffset = (int)BitConverter.ToUInt32(ChunkData, TextureDataPointer_OoT);
            }
            else
            {
                SklChunk  = new SklChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, SklChunkPointer_MM), this);
                MatsChunk = new MatsChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, MatsChunkPointer_MM), this);
                TexChunk  = new TexChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, TexChunkPointer_MM), this);
                SklmChunk = new SklmChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, SklmChunkPointer_MM), this);
                VatrChunk = new VatrChunk(ChunkData, (int)BitConverter.ToUInt32(ChunkData, VatrChunkPointer_MM), this);

                vtxIdxOffset  = (int)BitConverter.ToUInt32(ChunkData, VertexIndicesPointer_MM);
                texDataOffset = (int)BitConverter.ToUInt32(ChunkData, TextureDataPointer_MM);
            }

            Indices = new byte[NumberOfIndices * sizeof(ushort)];
            Buffer.BlockCopy(ChunkData, vtxIdxOffset, Indices, 0, Indices.Length);

            TextureData = new byte[ChunkData.Length - texDataOffset];
            Buffer.BlockCopy(ChunkData, texDataOffset, TextureData, 0, TextureData.Length);

            /* For information purposes, tho inexact if (probably) one array type isn't used by sepd (or smth) */
            TotalPrimitives = 0;
            foreach (SepdChunk sepd in SklmChunk.ShpChunk.SepdChunks)
            {
                TotalPrimitives += sepd.TotalPrimitives;
            }

            TotalVertices = TotalTexCoords = TotalColors = TotalNormals = 0;
            for (int i = 0; i < SklmChunk.ShpChunk.SepdChunks.Length; i++)
            {
                if (i == SklmChunk.ShpChunk.SepdChunks.Length - 1)
                {
                    SepdChunk sepdCurrent = SklmChunk.ShpChunk.SepdChunks[i];

                    if (VatrChunk.Sizes[VatrChunk.VertexArray_OoT] != 0)
                    {
                        TotalVertices += (int)((VatrChunk.Sizes[VatrChunk.VertexArray_OoT] - sepdCurrent.VertexArrayOffset) / sepdCurrent.VertexSize);
                    }
                    if (VatrChunk.Sizes[VatrChunk.TextureCoordArray_OoT] != 0)
                    {
                        TotalTexCoords += (int)((VatrChunk.Sizes[VatrChunk.TextureCoordArray_OoT] - sepdCurrent.TextureCoordArrayOffset) / sepdCurrent.TexCoordSize);
                    }
                    if (VatrChunk.Sizes[VatrChunk.ColorArray_OoT] != 0)
                    {
                        TotalColors += (int)((VatrChunk.Sizes[VatrChunk.ColorArray_OoT] - sepdCurrent.ColorArrayOffset) / sepdCurrent.ColorSize);
                    }
                    if (VatrChunk.Sizes[VatrChunk.NormalArray_OoT] != 0)
                    {
                        TotalNormals += (int)((VatrChunk.Sizes[VatrChunk.NormalArray_OoT] - sepdCurrent.NormalArrayOffset) / sepdCurrent.NormalSize);
                    }
                }
                else
                {
                    SepdChunk sepdCurrent = SklmChunk.ShpChunk.SepdChunks[i];
                    SepdChunk sepdNext    = SklmChunk.ShpChunk.SepdChunks[i + 1];

                    if (VatrChunk.Sizes[VatrChunk.VertexArray_OoT] != 0)
                    {
                        TotalVertices += (int)((sepdNext.VertexArrayOffset - sepdCurrent.VertexArrayOffset) / sepdCurrent.VertexSize);
                    }
                    if (VatrChunk.Sizes[VatrChunk.TextureCoordArray_OoT] != 0)
                    {
                        TotalTexCoords += (int)((sepdNext.TextureCoordArrayOffset - sepdCurrent.TextureCoordArrayOffset) / sepdCurrent.TexCoordSize);
                    }
                    if (VatrChunk.Sizes[VatrChunk.ColorArray_OoT] != 0)
                    {
                        TotalColors += (int)((sepdNext.ColorArrayOffset - sepdCurrent.ColorArrayOffset) / sepdCurrent.ColorSize);
                    }
                    if (VatrChunk.Sizes[VatrChunk.NormalArray_OoT] != 0)
                    {
                        TotalNormals += (int)((sepdNext.NormalArrayOffset - sepdCurrent.NormalArrayOffset) / sepdCurrent.NormalSize);
                    }
                }
            }
        }
예제 #7
0
        private void PrepareBoneInformation(SepdChunk sepd, PrmsChunk prms)
        {
            /* TODO!! B/C HURR DURR, DON'T KNOW  https://www.the-gcn.com/topic/2859-oot-3d-3ds-model-format-discussion/page-3#entry46121 */
            if (prms.SkinningMode == PrmsChunk.SkinningModes.PerVertex)
            {
                uint[] lookupInts = new uint[(int)(Root.VatrChunk.BoneIndexLookup.Length - sepd.BoneIndexLookupArrayOffset) / sepd.BoneIndexLookupSize];
                for (int i = 0; i < lookupInts.Length; i++)
                {
                    switch (sepd.BoneIndexLookupArrayDataType)
                    {
                    case Constants.PicaDataType.Byte:
                    case Constants.PicaDataType.UnsignedByte:
                        lookupInts[i] = (uint)Root.VatrChunk.BoneIndexLookup[sepd.BoneIndexLookupArrayOffset + (i * sizeof(byte))];
                        break;

                    case Constants.PicaDataType.Short:
                    case Constants.PicaDataType.UnsignedShort:
                        lookupInts[i] = (uint)BitConverter.ToUInt16(Root.VatrChunk.BoneIndexLookup, (int)(sepd.BoneIndexLookupArrayOffset + (i * sizeof(ushort))));
                        break;

                    case Constants.PicaDataType.Int:
                    case Constants.PicaDataType.UnsignedInt:
                        lookupInts[i] = (uint)BitConverter.ToUInt32(Root.VatrChunk.BoneIndexLookup, (int)(sepd.BoneIndexLookupArrayOffset + (i * sizeof(uint))));
                        break;

                    case Constants.PicaDataType.Float:
                        lookupInts[i] = (uint)BitConverter.ToSingle(Root.VatrChunk.BoneIndexLookup, (int)(sepd.BoneIndexLookupArrayOffset + (i * sizeof(float))));
                        break;
                    }
                }

                GL.ActiveTexture(TextureUnit.Texture0 + vertBoneTexUnit);
                GL.BindTexture(TextureTarget.TextureBuffer, vertBoneTexId);

                GL.BindBuffer(BufferTarget.TextureBuffer, vertBoneBufferId);
                GL.BufferData <uint>(BufferTarget.TextureBuffer, new IntPtr(lookupInts.Length * sizeof(uint)), lookupInts, BufferUsageHint.StaticDraw);
                GL.BindBuffer(BufferTarget.TextureBuffer, 0);
            }

            /* Maaaaaaybe? I dunno... not using this yet either */
            Vector2[] weights = new Vector2[(int)(Root.VatrChunk.BoneWeights.Length - sepd.BoneWeightArrayOffset) / 2];
            for (int i = 0, j = 0; i < weights.Length; i++, j += 2)
            {
                weights[i] = new Vector2(
                    Root.VatrChunk.BoneWeights[sepd.BoneWeightArrayOffset + j],
                    Root.VatrChunk.BoneWeights[sepd.BoneWeightArrayOffset + (j + 1)]);
            }

            for (int i = 0; i < prms.BoneIndexCount; i++)
            {
                Matrix4 matrix = Matrix4.Identity;

                SklChunk.Bone bone = Root.SklChunk.Bones.FirstOrDefault(x => x.BoneID == prms.BoneIndices[i]);
                if (bone != null)
                {
                    matrix = bone.GetMatrix(prms.SkinningMode != PrmsChunk.SkinningModes.PerVertexNoTrans);
                }

                GL.UniformMatrix4(GL.GetUniformLocation(program, string.Format("boneMatrix[{0}]", i)), false, ref matrix);
            }
        }
예제 #8
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();
        }
예제 #9
0
        private void PrepareBuffers()
        {
            vertexBufferObjects   = new Dictionary <SepdChunk, int>();
            normalBufferObjects   = new Dictionary <SepdChunk, int>();
            colorBufferObjects    = new Dictionary <SepdChunk, int>();
            texCoordBufferObjects = new Dictionary <SepdChunk, int>();
            elementBufferObjects  = new Dictionary <PrmsChunk, int>();

            foreach (MshsChunk.Mesh mesh in Root.SklmChunk.MshsChunk.Meshes)
            {
                int size, expectedSize;

                SepdChunk sepd = Root.SklmChunk.ShpChunk.SepdChunks[mesh.SepdID];

                if (Root.VatrChunk.Vertices.Length > 0)
                {
                    int newVertexBuffer = GL.GenBuffer();

                    GL.BindBuffer(BufferTarget.ArrayBuffer, newVertexBuffer);
                    if (sepd.VertexArrayDataType == Constants.PicaDataType.Byte || sepd.VertexArrayDataType == Constants.PicaDataType.UnsignedByte)
                    {
                        short[] converted = new short[Root.VatrChunk.Vertices.Length];
                        expectedSize = (converted.Length * sizeof(ushort));
                        for (int i = 0; i < Root.VatrChunk.Vertices.Length; i++)
                        {
                            converted[i] = Root.VatrChunk.Vertices[i];
                        }
                        GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(expectedSize), ref converted[sepd.VertexArrayOffset], BufferUsageHint.StaticDraw);
                    }
                    else
                    {
                        expectedSize = (int)(Root.VatrChunk.Vertices.Length - sepd.VertexArrayOffset);
                        GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(expectedSize), ref Root.VatrChunk.Vertices[sepd.VertexArrayOffset], BufferUsageHint.StaticDraw);
                    }

                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
                    if (size != expectedSize)
                    {
                        throw new ApplicationException(string.Format("Problem uploading vertices to VBO; tried {0} bytes, uploaded {1}", expectedSize, size));
                    }

                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

                    vertexBufferObjects.Add(sepd, newVertexBuffer);
                }

                if (Root.VatrChunk.Normals.Length > 0)
                {
                    int newNormalBuffer = GL.GenBuffer();

                    expectedSize = (int)(Root.VatrChunk.Normals.Length - sepd.NormalArrayOffset);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, newNormalBuffer);
                    GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(expectedSize), ref Root.VatrChunk.Normals[sepd.NormalArrayOffset], BufferUsageHint.StaticDraw);

                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
                    if (size != expectedSize)
                    {
                        throw new ApplicationException(string.Format("Problem uploading normals to VBO; tried {0} bytes, uploaded {1}", expectedSize, size));
                    }

                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

                    normalBufferObjects.Add(sepd, newNormalBuffer);
                }

                if (Root.VatrChunk.Colors.Length > 0)
                {
                    int newColorBuffer = GL.GenBuffer();

                    expectedSize = (int)(Root.VatrChunk.Colors.Length - sepd.ColorArrayOffset);
                    GL.BindBuffer(BufferTarget.ArrayBuffer, newColorBuffer);
                    GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(expectedSize), ref Root.VatrChunk.Colors[sepd.ColorArrayOffset], BufferUsageHint.StaticDraw);

                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
                    if (size != expectedSize)
                    {
                        throw new ApplicationException(string.Format("Problem uploading colors to VBO; tried {0} bytes, uploaded {1}", expectedSize, size));
                    }

                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

                    colorBufferObjects.Add(sepd, newColorBuffer);
                }

                if (Root.VatrChunk.TextureCoords.Length > 0)
                {
                    int newTexCoordBuffer = GL.GenBuffer();

                    GL.BindBuffer(BufferTarget.ArrayBuffer, newTexCoordBuffer);
                    if (sepd.TextureCoordArrayDataType == Constants.PicaDataType.Byte || sepd.TextureCoordArrayDataType == Constants.PicaDataType.UnsignedByte)
                    {
                        short[] converted = new short[Root.VatrChunk.TextureCoords.Length];
                        expectedSize = (converted.Length * sizeof(ushort));
                        for (int i = 0; i < Root.VatrChunk.TextureCoords.Length; i++)
                        {
                            converted[i] = Root.VatrChunk.TextureCoords[i];
                        }
                        GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(expectedSize), ref converted[sepd.TextureCoordArrayOffset], BufferUsageHint.StaticDraw);
                    }
                    else
                    {
                        expectedSize = (int)(Root.VatrChunk.TextureCoords.Length - sepd.TextureCoordArrayOffset);
                        GL.BufferData(BufferTarget.ArrayBuffer, new IntPtr(expectedSize), ref Root.VatrChunk.TextureCoords[sepd.TextureCoordArrayOffset], BufferUsageHint.StaticDraw);
                    }

                    GL.GetBufferParameter(BufferTarget.ArrayBuffer, BufferParameterName.BufferSize, out size);
                    if (size != expectedSize)
                    {
                        throw new ApplicationException(string.Format("Problem uploading texcoords to VBO; tried {0} bytes, uploaded {1}", expectedSize, size));
                    }

                    GL.BindBuffer(BufferTarget.ArrayBuffer, 0);

                    texCoordBufferObjects.Add(sepd, newTexCoordBuffer);
                }

                foreach (PrmsChunk prms in sepd.PrmsChunks)
                {
                    int newElementBuffer = GL.GenBuffer();

                    expectedSize = (prms.PrmChunk.NumberOfIndices * prms.PrmChunk.ElementSize);
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, newElementBuffer);
                    GL.BufferData(BufferTarget.ElementArrayBuffer, new IntPtr(expectedSize), ref Root.Indices[prms.PrmChunk.FirstIndex * sizeof(ushort)], BufferUsageHint.StaticDraw);

                    GL.GetBufferParameter(BufferTarget.ElementArrayBuffer, BufferParameterName.BufferSize, out size);
                    if (size != expectedSize)
                    {
                        throw new ApplicationException(string.Format("Problem uploading indices to VBO; tried {0} bytes, uploaded {1}", expectedSize, size));
                    }

                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

                    elementBufferObjects.Add(prms, newElementBuffer);
                }
            }
        }
예제 #10
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();
        }
예제 #11
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();
        }