The VertexData class manages a raw list of vertex information, allowing direct upload to OpenGL vertex buffers. _You only have to work with this class if you create display objects with a custom render function. If you don't plan to do that, you can safely ignore it._ To render objects with OpenGL, you have to organize vertex data in so-called vertex buffers. Those buffers reside in graphics memory and can be accessed very efficiently by the GPU. Before you can move data into vertex buffers, you have to set it up in conventional memory - that is, in a byte array. That array contains all vertex information (the coordinates, color, and texture coordinates) - one vertex after the other. To simplify creating and working with such a bulky list, the VertexData class was created. It contains methods to specify and modify vertex data. The raw array managed by the class can then easily be uploaded to a vertex buffer. **Premultiplied Alpha** The color values of texture files may contain premultiplied alpha values, which means that the 'RGB' values were multiplied with the 'alpha' value before saving them. On rendering, it makes a difference in which way the alpha value is saved; for that reason, the VertexData class mimics this behavior. You can choose how the alpha values should be handled via the 'premultipliedAlpha' property.
예제 #1
0
        public void TestEmpty ()
        {
            VertexData vertexData = new VertexData();

            Assert.AreEqual(0, vertexData.NumVertices, "wrong number of vertices");
            Assert.True(vertexData.Vertices == null, "vertex array should be null");
        }
예제 #2
0
        public void TestSetAllAlphas()
        {
            VertexData vertexData = new VertexData(4);
            vertexData.SetAlpha(0.5f);

            for (int i = 0; i < vertexData.NumVertices; ++i)
            {
                AssertAreEqualWithSmallError(0.5f, vertexData.AlphaAt(i), "wrong alpha", 0.005f);
            }
        }
예제 #3
0
        public void TestSetAllColors()
        {
            uint color = 0xabcdef;
            VertexData vertexData = new VertexData(4);
            vertexData.SetColor(color);

            for (int i = 0; i < vertexData.NumVertices; ++i)
            {
                Assert.AreEqual(color, vertexData.ColorAt(i), "wrong color");
            }
        }
예제 #4
0
        public void TestSetAllColorsAndAlphas()
        {
            uint color = 0xabcdef;
            float alpha = 0.5f;
            VertexData vertexData = new VertexData(4);
            vertexData.SetColor(color);
            vertexData.SetAlpha(alpha);

            for (int i=0; i<vertexData.NumVertices; ++i)
            {
                Assert.AreEqual(color, vertexData.ColorAt(i), "wrong color");
                AssertAreEqualWithSmallError(alpha, vertexData.AlphaAt(i), "wrong alpha", 0.005f);
            }
        }
예제 #5
0
        public void TestBasicMethods ()
        {
            const int numVertices = 4;

            Vertex vertex = AnyVertex();
            Vertex defaultVertex = DefaultVertex();

            VertexData vertexData = new VertexData(numVertices);

            Assert.AreEqual(numVertices, vertexData.NumVertices, "wrong number of vertices");
            Assert.True(vertexData.Vertices != null, "vertex array not accessible");

            for (int i = 0; i < numVertices; ++i)
            {
                CompareVertex(defaultVertex, vertexData.Vertices[i]);
            }
        }
예제 #6
0
        protected void InitImage(Texture texture)
        {
            if (texture == null)
            {
                throw new Exception("texture cannot be null!");
            }

            Rectangle frame = texture.Frame;
            float width = (frame != null) ? frame.Width : texture.Width;
            float height = (frame != null) ? frame.Height : texture.Height;
            bool pma = texture.PremultipliedAlpha;

            Init(width, height, 0xFFFFFF, pma);

            _vertexData.Vertices[1].TexCoords.X = 1.0f;
            _vertexData.Vertices[2].TexCoords.Y = 1.0f;
            _vertexData.Vertices[3].TexCoords.X = 1.0f;
            _vertexData.Vertices[3].TexCoords.Y = 1.0f;

            _texture = texture;
            _vertexDataCache = new VertexData(4, pma);
            _vertexDataCacheInvalid = true;
        }
예제 #7
0
        public void TestTransformVertices()
        {
            VertexData vertexData = new VertexData(3, true);

            Vertex defaultVertex = DefaultVertex();
            Vertex secondVertex = DefaultVertex();
            secondVertex.Position.X = 1.0f;
            secondVertex.Position.Y = 2.0f;

            vertexData.Vertices[0] = defaultVertex;
            vertexData.Vertices[1] = secondVertex;
            vertexData.Vertices[2] = defaultVertex;

            Matrix matrix = Matrix.Create();
            matrix.Rotate((float)Math.PI);
           
            vertexData.TransformVertices(matrix, 1, 1);

            Vertex expected = DefaultVertex();
            expected.Position.X = -1.0f;
            expected.Position.Y = -2.0f;

            CompareVertex(vertexData.Vertices[0], DefaultVertex());
            CompareVertex(vertexData.Vertices[1], expected);
            CompareVertex(vertexData.Vertices[2], DefaultVertex());
        }
예제 #8
0
        public void TestScaleAlphaWithoutPMA()
        {
            VertexData vertexData = new VertexData(1);

            vertexData.SetColor(ColorUtil.GetRGB(80, 60, 40), 128/255.0f);

            vertexData.ScaleAlphaBy(0.5f);

            CompareVertexColor(VertexColorHelper.CreateVertexColor(80, 60, 40, 64), vertexData.VertexColors[0]);
        }
예제 #9
0
        public void TestScaleAlphaWithPMA()
        {
            VertexData vertexData = new VertexData(1, true);

            vertexData.SetColor(ColorUtil.GetRGB(80, 60, 40), 204/255.0f);

            vertexData.ScaleAlphaBy(0.8f);

            CompareVertexColor(VertexColorHelper.CreateVertexColor(
                (byte)(80 * 0.64f + 0.5f), 
                (byte)(60 * 0.64f + 0.5f), 
                (byte)(40 * 0.64f + 0.5f), 
                (byte)(204 * 0.8f + 0.5f)), vertexData.VertexColors[0]);
        }
예제 #10
0
        override public void AdjustPositions(VertexData vertexData, uint startIndex, uint count)
        {
            if (_frame != null)
            {
                if (count != 4)
                    throw new InvalidOperationException(@"Textures with a frame can only be used on quads");

                float deltaRight = _frame.Width + _frame.X - _width;
                float deltaBottom = _frame.Height + _frame.Top - _height;

                // top left
                vertexData.Vertices[startIndex].Position.X -= _frame.X;
                vertexData.Vertices[startIndex].Position.Y -= _frame.Top;

                // top right
                vertexData.Vertices[startIndex + 1].Position.X -= deltaRight;
                vertexData.Vertices[startIndex + 1].Position.Y -= _frame.Top;

                // bottom left
                vertexData.Vertices[startIndex + 2].Position.X -= _frame.X;
                vertexData.Vertices[startIndex + 2].Position.Y -= deltaBottom;

                // bottom right
                vertexData.Vertices[startIndex + 3].Position.X -= deltaRight;
                vertexData.Vertices[startIndex + 3].Position.Y -= deltaBottom;
            }
        }
예제 #11
0
        public void TestPremultipliedAlpha()
        {
            VertexData vertexData = new VertexData(1);
          
            vertexData.SetColor(ColorUtil.GetRGB(80, 60, 40), 204/255.0f);

            vertexData.SetPremultipliedAlpha(true, true);

            CompareVertexColor(VertexColorHelper.CreateVertexColor(64, 48, 32, 204), vertexData.VertexColors[0]);

            vertexData.SetPremultipliedAlpha(false, true);

            CompareVertexColor(VertexColorHelper.CreateVertexColor(80, 60, 40, 204), vertexData.VertexColors[0]);
        }
예제 #12
0
        /// <summary>
        /// Initializes a fragment filter with the specified number of passes and resolution.
        /// </summary>
        protected FragmentFilter(int numPasses = 1, float resolution = 1.0f)
        {
            NumPasses = numPasses;
            Resolution = resolution;
            Mode = FragmentFilterMode.Replace;
            _passTextures = new List<Texture>(numPasses);
            _projMatrix = Matrix.Create(0, 0, 0, 0, 0, 0);

            _vertexData = new VertexData(4, true);
            _vertexData.Vertices[1].TexCoords.X = 1.0f;
            _vertexData.Vertices[2].TexCoords.Y = 1.0f;
            _vertexData.Vertices[3].TexCoords.X = 1.0f;
            _vertexData.Vertices[3].TexCoords.Y = 1.0f;

            _indexData[0] = 0;
            _indexData[1] = 1;
            _indexData[2] = 2;
            _indexData[3] = 1;
            _indexData[4] = 3;
            _indexData[5] = 2;

            CreatePrograms();
        }
예제 #13
0
 /// <summary>
 /// Converts texture coordinates and vertex positions of raw vertex data into the format
 /// required for rendering.
 /// </summary>
 virtual public void AdjustVertexData(VertexData vertexData, uint startIndex, uint count)
 {
 }
예제 #14
0
        virtual internal void CopyVertexDataTo(VertexData targetData, int atIndex, bool copyColor)
        {
            copyColor = copyColor || Tinted;

            _vertexData.CopyToVertexData(targetData, copyColor, atIndex);
        }
예제 #15
0
 /// <summary>
 /// Copies the vertex data of this instance to another vertex data object, starting at a certain index.
 /// </summary>
 public void CopyToVertexData(VertexData target, bool copyColor, int atIndex = 0)
 {
     CopyToVertexData(target, copyColor, atIndex, _numVertices);
 }
예제 #16
0
        protected void Init(float width = 32, float height = 32, uint color = 0xffffff, bool premultipliedAlpha = false)
        {
            if (width <= MIN_SIZE)
            {
                width = MIN_SIZE;
            }
            if (height <= MIN_SIZE)
            {
                height = MIN_SIZE;
            }
            _color = color;
            _vertexData = new VertexData(4, premultipliedAlpha);
            _vertexData.Vertices[1].Position.X = width;
            _vertexData.Vertices[2].Position.Y = height;
            _vertexData.Vertices[3].Position.X = width;
            _vertexData.Vertices[3].Position.Y = height;

            for (int i = 0; i < 4; ++i)
            {
                _vertexData.VertexColors[i] = VertexColorHelper.CreateVertexColor(color, 1.0f);
            }

            VertexDataDidChange();
        }
예제 #17
0
 /// <summary>
 /// Moves the position coordinates stored at the given memory region into the format required for
 /// rendering. This happens for SubTextures that contain a 'frame'.
 /// </summary>
 virtual public void AdjustPositions(VertexData vertexData, uint startIndex, uint count)
 {
 }
예제 #18
0
 /// <summary>
 /// Converts texture coordinates stored at the given memory region into the format required for
 /// rendering. While the texture coordinates of an image always use the range [0, 1], the actual
 /// coordinates could be different: you might be working with a SubTexture. This method adjusts
 /// the coordinates accordingly.
 /// </summary>
 virtual public void AdjustTexCoords(VertexData vertexData, uint startIndex, uint count)
 {
 }
예제 #19
0
        public void TestCopy()
        {
            VertexData sourceData = new VertexData(3);

            Vertex defaultVertex = DefaultVertex();
            Vertex vertex = AnyVertex();

            sourceData.Vertices[0] = vertex;
            sourceData.Vertices[1] = defaultVertex;
            sourceData.Vertices[2] = vertex;

            VertexData targetData = new VertexData(5, false);

            sourceData.CopyToVertexData(targetData, true, 2);

            CompareVertex(defaultVertex, targetData.Vertices[0]);
            CompareVertex(defaultVertex, targetData.Vertices[1]);
            CompareVertex(vertex, targetData.Vertices[2]);
            CompareVertex(defaultVertex, targetData.Vertices[3]);
            CompareVertex(vertex, targetData.Vertices[4]);
        }
예제 #20
0
        override internal void CopyVertexDataTo(VertexData targetData, int atIndex, bool copyColor)
        {
            copyColor = copyColor || Tinted;

            if (_vertexDataCacheInvalid)
            {
                _vertexDataCacheInvalid = false;
                _vertexData.CopyToVertexData(_vertexDataCache, copyColor);
                _texture.AdjustVertexData(_vertexDataCache, 0, 4);
            }
            _vertexDataCache.CopyToVertexData(targetData, copyColor, atIndex, 4);
        }
예제 #21
0
 public QuadBatch()
 {
     _numQuads = 0;
     _syncRequired = false;
     _vertexData = new VertexData();
     _baseEffect = new BaseEffect();
 }
예제 #22
0
        /// <summary>
        /// Copies a range of vertices of this instance to another vertex data object.
        /// </summary>
        public void CopyToVertexData(VertexData target, bool copyColor, int atIndex, int numVertices)
        {
            Vertex.Copy(_vertices, 0, target.Vertices, atIndex, numVertices);

            if (copyColor)
            {
                Array.Copy(_vertexColors, 0, target.VertexColors, atIndex, numVertices);
            }
        }
예제 #23
0
 override public void AdjustVertexData(VertexData vertexData, uint startIndex, uint count)
 {
     AdjustPositions(vertexData, startIndex, count);
     AdjustTexCoords(vertexData, startIndex, count);
 }
예제 #24
0
        override public void AdjustTexCoords(VertexData vertexData, uint startIndex, uint count)
        {
            Texture texture = this;
            Matrix matrix = Matrix.Create();

            do
            {
                SubTexture subTexture = (SubTexture)texture;
                matrix.AppendMatrix(subTexture.TransformationMatrix);
                texture = subTexture._parent;
            } while (texture.GetType().IsEquivalentTo(typeof(SubTexture)));

            uint endIndex = startIndex + count;
            for (uint i = startIndex; i < endIndex; ++i)
            {
                Vector2 currentCoord = vertexData.Vertices[i].TexCoords;
                vertexData.Vertices[i].TexCoords = TransformVector2(matrix, currentCoord);
            }
        }
예제 #25
0
        public void TestResize()
        {
            Vertex vertex = AnyVertex();
            Vertex defaultVertex = DefaultVertex();
            VertexData vertexData = new VertexData(4);

            Assert.AreEqual(4, vertexData.NumVertices, "wrong number of vertices");

            vertexData.Vertices[1] = vertex;
            vertexData.Vertices[2] = vertex;
            vertexData.Vertices[3] = vertex;

            vertexData.NumVertices = 2;

            Assert.AreEqual(2, vertexData.NumVertices, "wrong number of vertices");

            CompareVertex(defaultVertex, vertexData.Vertices[0]);
            CompareVertex(vertex, vertexData.Vertices[1]);

            vertexData.NumVertices = 4;

            CompareVertex(defaultVertex, vertexData.Vertices[2]);
            CompareVertex(defaultVertex, vertexData.Vertices[3]);
        }
예제 #26
0
 /// <summary>
 /// Copies the vertex data of this instance to another vertex data object, starting at a certain index.
 /// </summary>
 public void CopyToVertexData(VertexData target, bool copyColor, int atIndex = 0)
 {
     CopyToVertexData(target, copyColor, atIndex, _numVertices);
 }