internal void ReadBuffer(BinaryReaderEx br, List <BufferLayout> layouts, FLVER.Vertex[] vertices, int count, int dataOffset, FLVERHeader header)
            {
                BufferLayout layout = layouts[LayoutIndex];

                if (VertexSize != layout.Size)
                {
                    throw new InvalidDataException($"Mismatched vertex buffer and buffer layout sizes.");
                }

                br.StepIn(dataOffset + BufferOffset);
                {
                    float uvFactor = 1024;
                    if (header.Version >= 0x2000F)
                    {
                        uvFactor = 2048;
                    }

                    for (int i = 0; i < count; i++)
                    {
                        vertices[i].Read(br, layout, uvFactor);
                    }
                }
                br.StepOut();

                VertexSize   = -1;
                BufferIndex  = -1;
                VertexCount  = -1;
                BufferOffset = -1;
            }
        private void Update(EvaluationContext context)
        {
            var bufferContent = new BufferLayout(context.CameraToClipSpace, context.WorldToCamera, context.ObjectToWorld);

            ResourceManager.Instance().SetupConstBuffer(bufferContent, ref Buffer.Value);
            Buffer.Value.DebugName = nameof(TransformsConstBuffer);
        }
示例#3
0
        public override void OnAttach()
        {
            app = Application.GetApplication();
            var window = app.GetWindow();

            Renderer.SetClearColor(Color.White.ToVec4());

            orthoCamera = new OrthographicCamera(-16f, 16f, -9f, 9f);
            //persCamera = new PerspectiveCamera(45, 16f/9f, 0.01f, 1000);

            //selectedCamera = persCamera;
            //persCamera.Position = new OpenTK.Mathematics.Vector3(0, 0, -1);

            float[] verticies =
            {
                -0.5f, -0.5f,                                                        0.0f, /* Colors  0.0f, 0.0f, 0.0f, */ /* Tex Coords */ 0.0f, 0.0f,
                0.5f,   0.5f,                                                        0.0f, /* Colors  0.0f, 0.0f, 0.0f, */ /* Tex Coords */ 1.0f, 1.0f,
                -0.5f,  0.5f,                                                        0.0f, /* Colors  0.0f, 0.0f, 0.0f, */ /* Tex Coords */ 0.0f, 1.0f,
                0.5f,  -0.5f,                                                        0.0f, /* Colors  0.0f, 0.0f, 0.0f, */ /* Tex Coords */ 1.0f, 0.0f,
            };

            uint[] indices =
            {
                0, 1, 2,
                0, 3, 1
            };

            shader = new Shader("Assets/Shaders/vertex.glsl", "Assets/Shaders/fragment.glsl", true);

            vertexBuffer = new VertexBuffer(verticies, verticies.Length * sizeof(float));
            indexBuffer  = new IndexBuffer(indices, indices.Length * sizeof(uint));

            BufferLayout layout = new BufferLayout(
                new BufferElement("positions", ShaderDataType.Float3),
                new BufferElement("texCoords", ShaderDataType.Float2)
                //new BufferElement("colors", ShaderDataType.Float3)
                );

            vertexBuffer.SetLayout(layout);

            vertexArray = new VertexArray();
            vertexArray.AddVertexBuffer(vertexBuffer);
            vertexArray.SetIndexBuffer(indexBuffer);

            checkerboard = new Texture2D("Assets/Textures/Checkerboard.png");
            cherno       = new Texture2D("Assets/Textures/ChernoLogo.png");

            shader.SetInt("uTexture", 0);

            vendorString   = GL.GetString(StringName.Vendor);
            rendererString = GL.GetString(StringName.Renderer);
            versionString  = GL.GetString(StringName.Version);

            FramebufferData fbData = new FramebufferData(1280, 720);

            framebuffer = new Framebuffer(fbData);

            viewportSize = new Vector2(framebuffer.FramebufferData.Width, framebuffer.FramebufferData.Height);
        }
示例#4
0
 public static void Dispose()
 {
     if (BufferLayout != null)
     {
         BufferLayout.Dispose();
     }
     if (Shader != null)
     {
         Shader.Dispose();
     }
 }
示例#5
0
        public override void SetLayout(BufferLayout bufferLayout)
        {
            this.layout = bufferLayout;
            List <BufferElement> layout = bufferLayout.GetLayout();

            for (int i = 0; i < layout.Count; i++)
            {
                BufferElement element = layout[i];
                Gl.EnableVertexAttribArray(i);
                Gl.VertexAttribPointer((uint)i, (int)element.count, (VertexAttribPointerType)element.type, element.normalized, (int)bufferLayout.GetStride(), new IntPtr(element.offset));
            }
        }
示例#6
0
            internal Mesh(BinaryReaderEx br, List <Material> materials, int dataOffset)
            {
                Dynamic       = br.ReadBoolean();
                MaterialIndex = br.ReadByte();
                Unk02         = br.ReadBoolean();
                Unk03         = br.ReadByte();

                int vertexIndexCount = br.ReadInt32();
                int vertexCount      = br.ReadInt32();

                DefaultBoneIndex = br.ReadInt16();
                BoneIndices      = br.ReadInt16s(28);
                br.AssertInt16(0);
                br.AssertInt32(vertexIndexCount * 2);
                int vertexIndicesOffset = br.ReadInt32();
                int bufferSize          = br.ReadInt32();
                int bufferOffset        = br.ReadInt32();

                br.ReadInt32(); // Buffers header offset
                br.AssertInt32(0);
                br.AssertInt32(0);

                VertexIndices = br.GetUInt16s(dataOffset + vertexIndicesOffset, vertexIndexCount);

                br.StepIn(dataOffset + bufferOffset);
                {
                    BufferLayout layout = null;
                    foreach (var bl in materials[MaterialIndex].Layouts)
                    {
                        if (bl.Size * vertexCount == bufferSize)
                        {
                            layout = bl;
                        }
                    }

                    float uvFactor = 1024;
                    // NB hack
                    if (!br.BigEndian)
                    {
                        uvFactor = 2048;
                    }

                    Vertices = new List <FLVER.Vertex>(vertexCount);
                    for (int i = 0; i < vertexCount; i++)
                    {
                        var vert = new FLVER.Vertex();
                        vert.Read(br, layout, uvFactor);
                        Vertices.Add(vert);
                    }
                }
                br.StepOut();
            }
示例#7
0
            internal Mesh(BinaryReaderEx br, List <Material> materials, int dataOffset)
            {
                Dynamic       = br.ReadBoolean();
                MaterialIndex = br.ReadByte();
                Unk02         = br.ReadBoolean();
                Unk03         = br.ReadByte();

                int vertexIndexCount = br.ReadInt32();
                int vertexCount      = br.ReadInt32();

                BoneIndices = br.ReadInt16s(29);
                br.AssertInt16(0);
                br.AssertInt32(vertexIndexCount * 2);
                int vertexIndicesOffset = br.ReadInt32();
                int bufferSize          = br.ReadInt32();
                int bufferOffset        = br.ReadInt32();
                int bufferHeaderOffset  = br.ReadInt32();

                br.AssertInt32(0);
                br.AssertInt32(0);

                VertexIndices = br.GetUInt16s(dataOffset + vertexIndicesOffset, vertexIndexCount);

                br.StepIn(dataOffset + bufferOffset);
                {
                    BufferLayout layout = null;
                    foreach (var bl in materials[MaterialIndex].Layouts)
                    {
                        if (bl.Size * vertexCount == bufferSize)
                        {
                            layout = bl;
                        }
                    }

                    Vertices = new List <Vertex>(vertexCount);
                    for (int i = 0; i < vertexCount; i++)
                    {
                        long pos = br.Position;
                        Vertices.Add(new Vertex(br, layout));
                        if (br.Position != pos + layout.Size)
                        {
                            throw null;
                        }

                        if (Vertices.Last().Position.X == float.MinValue)
                        {
                            throw null;
                        }
                    }
                }
                br.StepOut();
            }
示例#8
0
        public BatchRenderer2D()
        {
            m_Shader = ResourceLoader.LoadShader("Renderer2D", "/Assets/Shaders/");
            m_Shader.Bind();

            foreach (ShaderUniformBufferDeclaration bufferDecl in m_Shader.VSSystemUniforms)
            {
                if (bufferDecl.Name == "VSUniforms")
                {
                    m_R2DUniformMatricesBufferSlot = bufferDecl.Register;
                }
            }

            BufferLayout layout = new BufferLayout();

            layout.Push <Vector2>("POSITION", 1);
            layout.Push <Vector2>("TEXCOORD", 1);
            layout.Push <float>("ID", 1);
            layout.Push <byte>("COLOR", 4);

            m_VertexBuffer = new VertexBuffer();
            m_VertexBuffer.Resize(layout.Size * MaxSprites * 4);
            m_VertexBuffer.SetLayout(layout);

            uint[] indices = new uint[IndicesSize];

            uint offset = 0;

            for (uint i = 0; i < IndicesSize; i += 6)
            {
                indices[i]     = offset;
                indices[i + 1] = offset + 1;
                indices[i + 2] = offset + 2;

                indices[i + 3] = offset + 2;
                indices[i + 4] = offset + 3;
                indices[i + 5] = offset;

                offset += 4;
            }
            m_IndexBuffer = new IndexBuffer(indices);

            Matrix.OrthoOffCenterLH(0, Application.Instance.Info.Width, Application.Instance.Info.Height,
                                    0, -1, 1, out Matrix ProjectionMatrix);
            Camera = new Camera
            {
                ProjectionMatrix = ProjectionMatrix,
                ViewMatrix       = new Matrix(),
                Position         = new Vector3(),
                Rotation         = new Vector3()
            };
        }
示例#9
0
        public ExampleLayer()
        {
            //Create camera
            cameraController = new OrthographicCameraController(1280.0f / 720.0f);

            //Shader library
            shaderLibrary = new ShaderLibrary();

            // ----------
            //Square
            // ----------
            squareVertexArray = IVertexArray.Create();

            float[] squareVertices =
            {
                -0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
                0.5f,  -0.5f, 0.0f, 1.0f, 0.0f,
                0.5f,   0.5f, 0.0f, 1.0f, 1.0f,
                -0.5f,  0.5f, 0.0f, 0.0f, 1.0f
            };

            IVertexBuffer squareVertexBuffer = IVertexBuffer.Create(squareVertices, squareVertices.GetBytes());

            BufferLayout squareBufferLayout = new BufferLayout(new[]
            {
                new BufferElement("a_Position", ShaderDataType.Float3),
                new BufferElement("a_TexCoord", ShaderDataType.Float2)
            });

            squareVertexBuffer.SetLayout(squareBufferLayout);
            squareVertexArray.AddVertexBuffer(squareVertexBuffer);

            uint[]       squareIndices     = { 0, 1, 2, 2, 3, 0 };
            IIndexBuffer squareIndexBuffer =
                IIndexBuffer.Create(squareIndices, squareIndices.GetBytes() / sizeof(uint));

            squareVertexArray.SetIndexBuffer(squareIndexBuffer);

            //Square shader
            shaderLibrary.LoadAndAddShader("Shaders/Square.glsl");

            //Texture shader
            IShader textureShader = IShader.Create("Shaders/Texture.glsl");

            shaderLibrary.AddShader(textureShader);

            birdiTexture = I2DTexture.Create("Textures/Birdi.png");
            faceTexture  = I2DTexture.Create("Textures/Face.png");

            textureShader.Bind();
            textureShader.SetInt("u_Texture", 0);
        }
            internal void Write(BinaryWriterEx bw, FLVERHeader header, int index, int bufferIndex, List <BufferLayout> layouts, int vertexCount)
            {
                BufferLayout layout = layouts[LayoutIndex];

                bw.WriteInt32(bufferIndex);
                bw.WriteInt32(LayoutIndex);
                bw.WriteInt32(layout.Size);
                bw.WriteInt32(vertexCount);
                bw.WriteInt32(0);
                bw.WriteInt32(0);
                bw.WriteInt32(header.Version > 0x20005 ? layout.Size * vertexCount : 0);
                bw.ReserveInt32($"VertexBufferOffset{index}");
            }
            internal void ReadXML(XmlNode node)
            {
                var bufferLayoutNodes = node.SelectNodes("vertex_buffer");
                int bufferIndex       = 0;

                Buffers.Clear();
                foreach (XmlNode bln in bufferLayoutNodes)
                {
                    var bufferLayout = new BufferLayout();
                    foreach (XmlNode memberNode in bln.ChildNodes)
                    {
                        FLVER.LayoutType     memberType     = (FLVER.LayoutType)Enum.Parse(typeof(FLVER.LayoutType), memberNode.Name);
                        FLVER.LayoutSemantic memberSemantic = FLVER.LayoutSemantic.Position;
                        var memberIndex       = 0;
                        var memberBufferIndex = bufferIndex;



                        // Try to parse Semantic[Index] lol
                        int memberSemanticLeftBracketIndex  = memberNode.InnerText.IndexOf('[');
                        int memberSemanticRightBracketIndex = memberNode.InnerText.IndexOf(']');
                        int memberSemanticIndexStrLength    = memberSemanticRightBracketIndex - memberSemanticLeftBracketIndex - 1;
                        // If it has [] brackets with text inbetween them, parse index from within brackets and semantic from before brackets.
                        if (memberSemanticLeftBracketIndex >= 0 && memberSemanticRightBracketIndex >= 0 && memberSemanticIndexStrLength > 0)
                        {
                            memberIndex    = int.Parse(memberNode.InnerText.Substring(memberSemanticLeftBracketIndex + 1, memberSemanticIndexStrLength));
                            memberSemantic = (FLVER.LayoutSemantic)Enum.Parse(typeof(FLVER.LayoutSemantic),
                                                                              memberNode.InnerText.Substring(0, memberSemanticLeftBracketIndex));
                        }
                        // Otherwise entire string parsed as semantic and index is 0.
                        else
                        {
                            memberIndex    = 0;
                            memberSemantic = (FLVER.LayoutSemantic)Enum.Parse(typeof(FLVER.LayoutSemantic), memberNode.InnerText);
                        }


                        var bufferIndexText = memberNode.Attributes["from_buffer_index"]?.InnerText;
                        if (bufferIndexText != null && int.TryParse(bufferIndexText, out int specifiedBufferIndex))
                        {
                            memberBufferIndex = specifiedBufferIndex;
                        }


                        bufferLayout.Add(new FLVER.LayoutMember(memberType, memberSemantic, memberIndex, memberBufferIndex));
                    }
                    Buffers.Add(bufferLayout);
                    bufferIndex++;
                }
            }
            internal void WriteBuffer(BinaryWriterEx bw, int index, List <BufferLayout> layouts, FLVER.Vertex[] Vertices, int dataStart, FLVERHeader header)
            {
                BufferLayout layout = layouts[LayoutIndex];

                bw.FillInt32($"VertexBufferOffset{index}", (int)bw.Position - dataStart);

                float uvFactor = 1024;

                if (header.Version >= 0x2000F)
                {
                    uvFactor = 2048;
                }

                foreach (FLVER.Vertex vertex in Vertices)
                {
                    vertex.Write(bw, layout, uvFactor);
                }
            }
示例#13
0
        /// <summary>
        /// Initializes the 2D rendering system
        /// </summary>
        internal static void Init()
        {
            ProfilerTimer.Profile(() =>
            {
                rendererData = new Renderer2DStorage
                {
                    QuadVertexArray = IVertexArray.Create()
                };

                float[] squareVertices =
                {
                    -0.5f, -0.5f, 0.0f, 0.0f, 0.0f,
                    0.5f,  -0.5f, 0.0f, 1.0f, 0.0f,
                    0.5f,   0.5f, 0.0f, 1.0f, 1.0f,
                    -0.5f,  0.5f, 0.0f, 0.0f, 1.0f
                };

                IVertexBuffer squareVertexBuffer = IVertexBuffer.Create(squareVertices, squareVertices.GetBytes());

                BufferLayout squareBufferLayout = new BufferLayout(new[]
                {
                    new BufferElement("a_Position", ShaderDataType.Float3),
                    new BufferElement("a_TexCoord", ShaderDataType.Float2)
                });
                squareVertexBuffer.SetLayout(squareBufferLayout);
                rendererData.QuadVertexArray.AddVertexBuffer(squareVertexBuffer);

                uint[] squareIndices           = { 0, 1, 2, 2, 3, 0 };
                IIndexBuffer squareIndexBuffer =
                    IIndexBuffer.Create(squareIndices, squareIndices.GetBytes() / sizeof(uint));
                rendererData.QuadVertexArray.SetIndexBuffer(squareIndexBuffer);

                rendererData.WhiteTexture = I2DTexture.Create(1, 1);
                uint whiteTextureData     = 0xffffffff;
                rendererData.WhiteTexture.SetData(whiteTextureData, sizeof(uint));

                rendererData.TextureShader = IShader.Create("Shaders/Texture.glsl");
                rendererData.TextureShader.Bind();
                rendererData.TextureShader.SetInt("u_Texture", 0);
            });
        }
示例#14
0
        private void Update(EvaluationContext context)
        {
            System.Numerics.Vector2 size = Size.GetValue(context);
            System.Numerics.Vector2 clip = NearFarClip.GetValue(context);
            Matrix cameraToClipSpace     = Matrix.OrthoRH(size.X, size.Y, clip.X, clip.Y);

            var     pos     = Position.GetValue(context);
            Vector3 eye     = new Vector3(pos.X, pos.Y, pos.Z);
            var     t       = Target.GetValue(context);
            Vector3 target  = new Vector3(t.X, t.Y, t.Z);
            Vector3 viewDir = target - eye;

            viewDir.Normalize();
            Vector3 upRef         = (Math.Abs(Vector3.Dot(viewDir, Vector3.Up)) > 0.9) ? Vector3.Left : Vector3.Up;
            Vector3 up            = Vector3.Cross(upRef, target - eye);
            Matrix  worldToCamera = Matrix.LookAtRH(eye, target, up);

            var bufferContent = new BufferLayout(cameraToClipSpace, worldToCamera, context.ObjectToWorld);

            ResourceManager.Instance().SetupConstBuffer(bufferContent, ref Buffer.Value);
            Buffer.Value.DebugName = nameof(ShadowMapTransformsConstBuffer);
        }
示例#15
0
 public void SetLayout(BufferLayout layout)
 {
     bufferLayout = layout;
 }
示例#16
0
 public override void SetLayout(BufferLayout layout)
 {
     _layout = layout;
 }
示例#17
0
        private static void CreateDeviceResources()
        {
            vertexArray = new VertexArray();

            vertexBufferSize = 10000;
            indexBufferSize  = 2000;

            //GL.CreateBuffers(1, out vertexBuffer);

            vertexBuffer = new VertexBuffer(vertexBufferSize);

            indexBuffer = new IndexBuffer(indexBufferSize);

            //GL.CreateBuffers(1, out indexBuffer);

            //GL.NamedBufferData(vertexBuffer, vertexBufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);
            //GL.NamedBufferData(indexBuffer, indexBufferSize, IntPtr.Zero, BufferUsageHint.DynamicDraw);

            RecreateFontDeviceTexture();

            string VertexSource = @"

                #version 330 core
                uniform mat4 projection_matrix;
                layout(location = 0) in vec2 in_position;
                layout(location = 1) in vec2 in_texCoord;
                layout(location = 2) in vec4 in_color;
                out vec4 color;
                out vec2 texCoord;
                void main()
                {
                    gl_Position = projection_matrix * vec4(in_position, 0, 1);
                    color = in_color;
                    texCoord = in_texCoord;
                }
            ";

            string FragmentSource = @"

                #version 330 core
                uniform sampler2D in_fontTexture;
                in vec4 color;
                in vec2 texCoord;
                out vec4 outputColor;
                void main()
                {
                    outputColor = color * texture(in_fontTexture, texCoord);
                }
            ";

            shader = new Shader(VertexSource, FragmentSource, false);

            // Old Code

            //GL.VertexArrayVertexBuffer(vertexArray, 0, vertexBuffer, IntPtr.Zero, Unsafe.SizeOf<ImDrawVert>());
            //GL.VertexArrayElementBuffer(vertexArray, indexBuffer);

            //GL.EnableVertexArrayAttrib(vertexArray, 0);
            //GL.VertexArrayAttribBinding(vertexArray, 0, 0);
            //GL.VertexArrayAttribFormat(vertexArray, 0, 2, VertexAttribType.Float, false, 0);

            //GL.EnableVertexArrayAttrib(vertexArray, 1);
            //GL.VertexArrayAttribBinding(vertexArray, 1, 0);
            //GL.VertexArrayAttribFormat(vertexArray, 1, 2, VertexAttribType.Float, false, 8);

            //GL.EnableVertexArrayAttrib(vertexArray, 2);
            //GL.VertexArrayAttribBinding(vertexArray, 2, 0);
            //GL.VertexArrayAttribFormat(vertexArray, 2, 4, VertexAttribType.UnsignedByte, true, 16);


            // New Code

            vertexArray.Bind();

            //vertexBuffer.Bind();
            //indexBuffer.Bind();

            BufferLayout layout = new BufferLayout(
                new BufferElement("position", ShaderDataType.Float2, false),
                new BufferElement("texCoords", ShaderDataType.Float2, false),
                new BufferElement("color", ShaderDataType.UnsignedByte4, true)
                );

            vertexBuffer.SetLayout(layout);

            vertexArray.AddVertexBuffer(vertexBuffer);
            vertexArray.SetIndexBuffer(indexBuffer);

            //GL.EnableVertexAttribArray(0);
            //GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, Unsafe.SizeOf<ImDrawVert>(), 0);
            //
            //GL.EnableVertexAttribArray(1);
            //GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, Unsafe.SizeOf<ImDrawVert>(), 8);
            //
            //GL.EnableVertexAttribArray(2);
            //GL.VertexAttribPointer(2, 4, VertexAttribPointerType.UnsignedByte, true, Unsafe.SizeOf<ImDrawVert>(), 16);
        }
示例#18
0
        private void UpdateMesh(EvaluationContext context)
        {
            var text = Text.GetValue(context);

            if (string.IsNullOrEmpty(text) || _font == null)
            {
                text = " ";
            }

            var horizontalAlign  = HorizontalAlign.GetValue(context);
            var verticalAlign    = VerticalAlign.GetValue(context);
            var characterSpacing = Spacing.GetValue(context);
            var lineHeight       = LineHeight.GetValue(context);
            var commonScaleH     = (512.0 / _font.Font.Common.ScaleH);
            var scaleFactor      = 1.0 / _font.Font.Info.Size * 0.00185;
            var size             = (float)(Size.GetValue(context) * scaleFactor); // Scaling to match 1080p 72DPI pt font sizes
            var position         = Position.GetValue(context);

            var numLinesInText = text.Split('\n').Length;

            var         color         = Color.GetValue(context);
            float       textureWidth  = _font.Font.Common.ScaleW;
            float       textureHeight = _font.Font.Common.ScaleH;
            float       cursorX       = 0;
            float       cursorY       = 0;
            const float SdfWidth      = 5f; // assumption after some experiments

            switch (verticalAlign)
            {
            // Top
            case 0:
                //cursorY = _font.Font.Common.LineHeight * lineHeight * 1;
                //cursorY = 40;// _font.Font.Common.LineHeight - _font.Font.Common.Base;// -_font.Font.Common.LineHeight;
                cursorY = _font.Font.Common.Base * (1 + SdfWidth / _font.Font.Info.Size);
                break;

            // Middle
            case 1:
                //var evenLineNumber = numLinesInText + numLinesInText % 2;
                cursorY = _font.Font.Common.LineHeight * lineHeight * (numLinesInText - 1) / 2
                          + _font.Font.Common.LineHeight / 2f
                          + _font.Font.Common.Base * (SdfWidth / _font.Font.Info.Size);
                break;

            // Bottom
            case 2:
                cursorY = _font.Font.Common.LineHeight * lineHeight * numLinesInText;
                break;
            }



            //cursorY += (_font.Font.Common.LineHeight - _font.Font.Common.Base) * lineHeight;
            //cursorY += ( _font.Font.Common.Base) * lineHeight / 6;
            //cursorY += _font.Font.Common.LineHeight * lineHeight/6;
            if (_bufferContent == null || _bufferContent.Length != text.Length)
            {
                _bufferContent = new BufferLayout[text.Length];
            }

            var outputIndex = 0;
            var currentLineCharacterCount = 0;
            var lastChar = 0;

            for (var index = 0; index < text.Length; index++)
            {
                var c = text[index];

                if (c == '\n')
                {
                    AdjustLineAlignment();

                    cursorY -= _font.Font.Common.LineHeight * lineHeight;
                    cursorX  = 0;
                    currentLineCharacterCount = 0;
                    lastChar = 0;
                    continue;
                }

                if (!_font.InfoForCharacter.TryGetValue(c, out var charInfo))
                {
                    lastChar = 0;
                    continue;
                }



                if (lastChar != 0)
                {
                    int key = lastChar | c;
                    if (_font.KerningForPairs.TryGetValue(key, out var kerning2))
                    {
                        cursorX += kerning2;
                    }
                }

                var sizeWidth  = charInfo.Width * size;
                var sizeHeight = charInfo.Height * size;
                var x          = position.X + (cursorX + charInfo.XOffset) * size;
                var y          = position.Y + ((cursorY - charInfo.YOffset)) * size;

                if (charInfo.Width != 1 || charInfo.Height != 1)
                {
                    _bufferContent[outputIndex]
                        = new BufferLayout
                        {
                        Position    = new Vector3(x, y, 0),
                        Size        = sizeHeight,
                        Orientation = new Vector3(0, 1, 0),
                        AspectRatio = sizeWidth / sizeHeight,
                        Color       = color,
                        UvMinMax    = new Vector4(
                            charInfo.X / textureWidth,                              // uLeft
                            charInfo.Y / textureHeight,                             // vTop
                            (charInfo.X + charInfo.Width) / textureWidth,           // uRight
                            (charInfo.Y + charInfo.Height) / textureHeight          // vBottom
                            ),
                        BirthTime = (float)context.LocalTime,
                        Speed     = 0,
                        Id        = (uint)outputIndex,
                        };

                    outputIndex++;
                }

                currentLineCharacterCount++;
                cursorX += charInfo.XAdvance;
                cursorX += characterSpacing;
                lastChar = c;
            }
            AdjustLineAlignment();

            ResourceManager.Instance().SetupStructuredBuffer(_bufferContent, ref Buffer.Value);
            Buffer.Value.DebugName = nameof(_RenderFontBuffer);
            VertexCount.Value      = outputIndex * 6;

            void AdjustLineAlignment()
            {
                switch (horizontalAlign)
                {
                case 1:
                    OffsetLineCharacters((cursorX / 2 - characterSpacing / 2) * size, currentLineCharacterCount, outputIndex);
                    break;

                case 2:
                    OffsetLineCharacters(cursorX * size, currentLineCharacterCount, outputIndex);
                    break;
                }
            }
        }
示例#19
0
            internal void Write(BinaryWriterEx bw, BufferLayout layout, int vertexSize, int version)
            {
                var tangentQueue = new Queue <Vector4>(Tangents);
                var colorQueue   = new Queue <Color>(Colors);
                var uvQueue      = new Queue <Vector3>(UVs);

                float uvFactor = 1024;

                foreach (BufferLayout.Member member in layout)
                {
                    switch (member.Semantic)
                    {
                    case BufferLayout.MemberSemantic.Position:
                        if (member.Type == BufferLayout.MemberType.Float3)
                        {
                            bw.WriteVector3(Position);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.BoneWeights:
                        if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteSByte((sbyte)(BoneWeights[i] * sbyte.MaxValue));
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4A)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteInt16((short)(BoneWeights[i] * short.MaxValue));
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.BoneIndices:
                        if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.ShortBoneIndices)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteUInt16((ushort)BoneIndices[i]);
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4E)
                        {
                            for (int i = 0; i < 4; i++)
                            {
                                bw.WriteByte((byte)BoneIndices[i]);
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.Normal:
                        if (member.Type == BufferLayout.MemberType.Float4)
                        {
                            bw.WriteVector4(Normal);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteByte((byte)(Normal.X * 127 + 127));
                            bw.WriteByte((byte)(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)(Normal.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteByte((byte)(Normal.X * 127 + 127));
                            bw.WriteByte((byte)(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)(Normal.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteByte((byte)(Normal.X * 127 + 127));
                            bw.WriteByte((byte)(Normal.Y * 127 + 127));
                            bw.WriteByte((byte)(Normal.Z * 127 + 127));
                            bw.WriteByte((byte)(Normal.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4B)
                        {
                            bw.WriteInt16((short)(Normal.X * 32767 + 32767));
                            bw.WriteInt16((short)(Normal.Y * 32767 + 32767));
                            bw.WriteInt16((short)(Normal.Z * 32767 + 32767));
                            bw.WriteInt16((short)(Normal.W * 32767 + 32767));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.UV:
                        Vector3 uv = uvQueue.Dequeue() * uvFactor;
                        if (member.Type == BufferLayout.MemberType.Float2)
                        {
                            bw.WriteSingle(uv.X);
                            bw.WriteSingle(uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.Float3)
                        {
                            bw.WriteVector3(uv);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.Short2toFloat2)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.UV)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else if (member.Type == BufferLayout.MemberType.UVPair)
                        {
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);

                            uv = uvQueue.Dequeue() * uvFactor;
                            bw.WriteInt16((short)uv.X);
                            bw.WriteInt16((short)uv.Y);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.Tangent:
                        Vector4 tangent = tangentQueue.Dequeue();
                        if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteByte((byte)(tangent.X * 127 + 127));
                            bw.WriteByte((byte)(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)(tangent.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteByte((byte)(tangent.X * 127 + 127));
                            bw.WriteByte((byte)(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)(tangent.W * 127 + 127));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteByte((byte)(tangent.X * 127 + 127));
                            bw.WriteByte((byte)(tangent.Y * 127 + 127));
                            bw.WriteByte((byte)(tangent.Z * 127 + 127));
                            bw.WriteByte((byte)(tangent.W * 127 + 127));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.UnknownVector4A:
                        if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            bw.WriteBytes(UnknownVector4);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteBytes(UnknownVector4);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.VertexColor:
                        Color color = colorQueue.Dequeue();
                        if (member.Type == BufferLayout.MemberType.Float4)
                        {
                            bw.WriteSingle(color.R);
                            bw.WriteSingle(color.G);
                            bw.WriteSingle(color.B);
                            bw.WriteSingle(color.A);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            bw.WriteByte((byte)(color.A * 255));
                            bw.WriteByte((byte)(color.R * 255));
                            bw.WriteByte((byte)(color.G * 255));
                            bw.WriteByte((byte)(color.B * 255));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            bw.WriteByte((byte)(color.R * 255));
                            bw.WriteByte((byte)(color.G * 255));
                            bw.WriteByte((byte)(color.B * 255));
                            bw.WriteByte((byte)(color.A * 255));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
示例#20
0
            internal Mesh(BinaryReaderEx br, FLVER0 flv, int dataOffset)
            {
                Dynamic       = br.ReadByte();
                MaterialIndex = br.ReadByte();
                Unk02         = br.ReadBoolean();
                Unk03         = br.ReadByte();

                int vertexIndexCount = br.ReadInt32();
                int vertexCount      = br.ReadInt32();

                DefaultBoneIndex = br.ReadInt16();
                BoneIndices      = br.ReadInt16s(28);
                Unk46            = br.ReadInt16();
                br.ReadInt32(); // Vertex indices length
                int vertexIndicesOffset  = br.ReadInt32();
                int bufferDataLength     = br.ReadInt32();
                int bufferDataOffset     = br.ReadInt32();
                int vertexBuffersOffset1 = br.ReadInt32();
                int vertexBuffersOffset2 = br.ReadInt32();

                br.AssertInt32(0);

                if (flv.VertexIndexSize == 16)
                {
                    VertexIndices = new List <int>(vertexCount);
                    foreach (ushort index in br.GetUInt16s(dataOffset + vertexIndicesOffset, vertexIndexCount))
                    {
                        VertexIndices.Add(index);
                    }
                }
                else if (flv.VertexIndexSize == 32)
                {
                    VertexIndices = new List <int>(br.GetInt32s(dataOffset + vertexIndicesOffset, vertexIndexCount));
                }

                VertexBuffer buffer;

                // Stupid hack for old (version F?) flvers; for example DeS o9993.
                if (vertexBuffersOffset1 == 0)
                {
                    buffer = new VertexBuffer()
                    {
                        BufferLength = bufferDataLength,
                        BufferOffset = bufferDataOffset,
                        LayoutIndex  = 0,
                    };
                }
                else
                {
                    br.StepIn(vertexBuffersOffset1);
                    {
                        List <VertexBuffer> vertexBuffers1 = VertexBuffer.ReadVertexBuffers(br);
                        if (vertexBuffers1.Count == 0)
                        {
                            throw new NotSupportedException("First vertex buffer list is expected to contain at least 1 buffer.");
                        }
                        for (int i = 1; i < vertexBuffers1.Count; i++)
                        {
                            if (vertexBuffers1[i].BufferLength != 0)
                            {
                                throw new NotSupportedException("Vertex buffers after the first one in the first buffer list are expected to be empty.");
                            }
                        }
                        buffer = vertexBuffers1[0];
                    }
                    br.StepOut();
                }

                if (vertexBuffersOffset2 != 0)
                {
                    br.StepIn(vertexBuffersOffset2);
                    {
                        List <VertexBuffer> vertexBuffers2 = VertexBuffer.ReadVertexBuffers(br);
                        if (vertexBuffers2.Count != 0)
                        {
                            throw new NotSupportedException("Second vertex buffer list is expected to contain exactly 0 buffers.");
                        }
                    }
                    br.StepOut();
                }

                br.StepIn(dataOffset + buffer.BufferOffset);
                {
                    LayoutIndex = buffer.LayoutIndex;
                    BufferLayout layout = flv.Materials[MaterialIndex].Layouts[LayoutIndex];

                    float uvFactor = 1024;
                    // NB hack
                    if (!br.BigEndian)
                    {
                        uvFactor = 2048;
                    }

                    Vertices = new List <FLVER.Vertex>(vertexCount);
                    for (int i = 0; i < vertexCount; i++)
                    {
                        var vert = new FLVER.Vertex();
                        vert.Read(br, layout, uvFactor);
                        Vertices.Add(vert);
                    }
                }
                br.StepOut();
            }
示例#21
0
        private void init(DisposableI parent, BufferLayoutDescI bufferLayoutDesc, BufferUsages bufferUsage, VertexBufferTopologys vertexBufferTopology, float[] vertices, int[] indices)
        {
            try
            {
                video = parent.FindParentOrSelfWithException<Video>();
                Topology = vertexBufferTopology;
                bufferLayout = new BufferLayout(this, null, bufferLayoutDesc, true);

                vertexBuffer = new X.VertexBuffer(video.Device, bufferLayout.layout, vertexCount, X.BufferUsage.WriteOnly);
                Update(vertices, vertexCount);

                if (indices != null && indices.Length != 0) indexBuffer = new IndexBuffer(this, usage, indices);
            }
            catch (Exception e)
            {
                Dispose();
                throw e;
            }
        }
示例#22
0
        private void Update(EvaluationContext context)
        {
            var text       = Text.GetValue(context);
            var bufferSize = BufferSize.GetValue(context);
            var wrapText   = WrapText.GetValue(context);
            var textOffset = TextOffset.GetValue(context);

            var columns = bufferSize.Width;
            var rows    = bufferSize.Height;

            if (columns <= 0 || rows <= 0)
            {
                return;
            }

            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            var textCycle = (int)textOffset.X + (int)(textOffset.Y) * columns;

            var size = rows * columns;

            if (_bufferContent == null || _bufferContent.Length != size)
            {
                _bufferContent = new BufferLayout[size];
            }

            var index = 0;

            char c;
            var  highlightChars = HighlightCharacters.GetValue(context);

            for (var rowIndex = 0; rowIndex < rows; rowIndex++)
            {
                for (var columnIndex = 0; columnIndex < columns; columnIndex++)
                {
                    if (wrapText)
                    {
                        var i = (index + textCycle) % text.Length;
                        if (i < 0)
                        {
                            i += text.Length;
                        }

                        c = text[i];
                    }
                    else
                    {
                        var i            = index + textCycle;
                        var indexIsValid = i >= 0 && i < text.Length;
                        c = indexIsValid ? text[i] : ' ';
                    }

                    var highlight = highlightChars.IndexOf(c) > -1 ? 1f : 0;      // oh, that's slow!

                    _bufferContent[index] = new BufferLayout(
                        pos: new Vector2((float)columnIndex / columns, 1 - (float)rowIndex / rows),
                        uv: new Vector2(c % 16, (c >> 4)),
                        highlight: highlight);

                    index++;
                }
            }

            ResourceManager.Instance().SetupStructuredBuffer(_bufferContent, ref Buffer.Value);
            Buffer.Value.DebugName = nameof(TypoGridBuffer);

            VertexCount.Value = size * 6;
        }
示例#23
0
 public void Enable()
 {
     BufferLayout.Enable();
 }
示例#24
0
            /// <summary>
            /// Create a new Vertex with null or empty values.
            /// </summary>
            public Vertex(BinaryReaderEx br, BufferLayout layout)
            {
                Position       = Vector3.Zero;
                BoneIndices    = null;
                BoneWeights    = null;
                UVs            = new List <Vector3>();
                Normal         = Vector4.Zero;
                Tangents       = new List <Vector4>();
                Colors         = new List <Color>();
                UnknownVector4 = null;

                float uvFactor = 1024;

                // NB hack
                if (!br.BigEndian)
                {
                    uvFactor = 2048;
                }

                foreach (BufferLayout.Member member in layout)
                {
                    switch (member.Semantic)
                    {
                    case BufferLayout.MemberSemantic.Position:
                        if (member.Type == BufferLayout.MemberType.Float3)
                        {
                            Position = br.ReadVector3();
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.BoneWeights:
                        if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            BoneWeights = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                BoneWeights[i] = br.ReadSByte() / (float)sbyte.MaxValue;
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.UVPair)
                        {
                            BoneWeights = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                BoneWeights[i] = br.ReadInt16() / (float)short.MaxValue;
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4A)
                        {
                            BoneWeights = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                BoneWeights[i] = br.ReadInt16() / (float)short.MaxValue;
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.BoneIndices:
                        if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            BoneIndices = new int[4];
                            for (int i = 0; i < 4; i++)
                            {
                                BoneIndices[i] = br.ReadByte();
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.ShortBoneIndices)
                        {
                            BoneIndices = new int[4];
                            for (int i = 0; i < 4; i++)
                            {
                                BoneIndices[i] = br.ReadUInt16();
                            }
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4E)
                        {
                            BoneIndices = new int[4];
                            for (int i = 0; i < 4; i++)
                            {
                                BoneIndices[i] = br.ReadByte();
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.Normal:
                        if (member.Type == BufferLayout.MemberType.Float3)
                        {
                            Normal = new Vector4(br.ReadVector3(), 0);
                        }
                        else if (member.Type == BufferLayout.MemberType.Float4)
                        {
                            Normal = br.ReadVector4();
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            float[] floats = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                floats[i] = (br.ReadByte() - 127) / 127f;
                            }
                            Normal = new Vector4(floats[0], floats[1], floats[2], floats[3]);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            float[] floats = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                floats[i] = (br.ReadByte() - 127) / 127f;
                            }
                            Normal = new Vector4(floats[0], floats[1], floats[2], floats[3]);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            float[] floats = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                floats[i] = (br.ReadByte() - 127) / 127f;
                            }
                            Normal = new Vector4(floats[0], floats[1], floats[2], floats[3]);
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4A)
                        {
                            float[] floats = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                floats[i] = br.ReadInt16() / 32767f;
                            }
                            Normal = new Vector4(floats[0], floats[1], floats[2], floats[3]);
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4B)
                        {
                            float[] floats = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                floats[i] = (br.ReadUInt16() - 32767) / 32767f;
                            }
                            Normal = new Vector4(floats[0], floats[1], floats[2], floats[3]);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.UV:
                        if (member.Type == BufferLayout.MemberType.Float2)
                        {
                            UVs.Add(new Vector3(br.ReadVector2() / uvFactor, 0));
                        }
                        else if (member.Type == BufferLayout.MemberType.Float3)
                        {
                            UVs.Add(br.ReadVector3() / uvFactor);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            UVs.Add(new Vector3(br.ReadInt16() / uvFactor, br.ReadInt16() / uvFactor, 0));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            UVs.Add(new Vector3(br.ReadInt16() / uvFactor, br.ReadInt16() / uvFactor, 0));
                        }
                        else if (member.Type == BufferLayout.MemberType.Short2toFloat2)
                        {
                            UVs.Add(new Vector3(br.ReadInt16() / uvFactor, br.ReadInt16() / uvFactor, 0));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            UVs.Add(new Vector3(br.ReadInt16() / uvFactor, br.ReadInt16() / uvFactor, 0));
                        }
                        else if (member.Type == BufferLayout.MemberType.UV)
                        {
                            UVs.Add(new Vector3(br.ReadInt16() / uvFactor, br.ReadInt16() / uvFactor, 0));
                        }
                        else if (member.Type == BufferLayout.MemberType.UVPair)
                        {
                            UVs.Add(new Vector3(br.ReadInt16() / uvFactor, br.ReadInt16() / uvFactor, 0));
                            UVs.Add(new Vector3(br.ReadInt16() / uvFactor, br.ReadInt16() / uvFactor, 0));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.Tangent:
                        if (member.Type == BufferLayout.MemberType.Float4)
                        {
                            Tangents.Add(br.ReadVector4());
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            float[] floats = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                floats[i] = (br.ReadByte() - 127) / 127f;
                            }
                            Tangents.Add(new Vector4(floats[0], floats[1], floats[2], floats[3]));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            float[] floats = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                floats[i] = (br.ReadByte() - 127) / 127f;
                            }
                            Tangents.Add(new Vector4(floats[0], floats[1], floats[2], floats[3]));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            float[] floats = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                floats[i] = (br.ReadByte() - 127) / 127f;
                            }
                            Tangents.Add(new Vector4(floats[0], floats[1], floats[2], floats[3]));
                        }
                        else if (member.Type == BufferLayout.MemberType.Short4toFloat4A)
                        {
                            float[] floats = new float[4];
                            for (int i = 0; i < 4; i++)
                            {
                                floats[i] = br.ReadInt16() / 32767f;
                            }
                            Tangents.Add(new Vector4(floats[0], floats[1], floats[2], floats[3]));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.UnknownVector4A:
                        if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            UnknownVector4 = br.ReadBytes(4);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4B)
                        {
                            UnknownVector4 = br.ReadBytes(4);
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            UnknownVector4 = br.ReadBytes(4);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    case BufferLayout.MemberSemantic.VertexColor:
                        if (member.Type == BufferLayout.MemberType.Float4)
                        {
                            float[] floats = br.ReadSingles(4);
                            Colors.Add(new Color(floats[3], floats[0], floats[1], floats[2]));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4A)
                        {
                            byte[] bytes = br.ReadBytes(4);
                            Colors.Add(new Color(bytes[0], bytes[1], bytes[2], bytes[3]));
                        }
                        else if (member.Type == BufferLayout.MemberType.Byte4C)
                        {
                            byte[] bytes = br.ReadBytes(4);
                            Colors.Add(new Color(bytes[3], bytes[0], bytes[1], bytes[2]));
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }