Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - DevMike

Pages: [1]
1
General discussions / Re: VertexArray transformations
« on: November 17, 2023, 12:08:12 am »
And here is refactored compact version if someone needs that kind of function.

        public static VertexArray CreateMappedVertices(Vector2f position, IntRect textureRect, Transform transform)
        {
            VertexArray vertices = new VertexArray(PrimitiveType.Quads);

            for (int i = 0; i < 4; ++i)
            {
                Vector2f point = transform.TransformPoint(new Vector2f(
                    (i == 1 || i == 2) ? textureRect.Width : 0,
                    (i == 2 || i == 3) ? textureRect.Height : 0
                )) - position;

                Vertex vertex = new Vertex(new Vector2f(position.X + point.X, position.Y + point.Y),
                                           new Vector2f(textureRect.Left + ((i == 1 || i == 2) ? textureRect.Width : 0),
                                                        textureRect.Top + ((i == 2 || i == 3) ? textureRect.Height : 0)));

                vertices.Append(vertex);
            }

            return vertices;
        }
 

2
General discussions / Re: VertexArray transformations
« on: November 16, 2023, 10:56:36 pm »
Ok, I forgot I have to move vertices of my object to point (0,0) before I apply transformation, and then I have to translate transformed vertices back to position. Now with this code my sprites behaves extacly the same like those I draw with Draw method.

        public static VertexArray CreateMappedVertices(Vector2f position, IntRect textureRect, Transform transform)
        {
            Vector2f[] transformedVertices = new Vector2f[4];

            transformedVertices[0] = transform.TransformPoint(new Vector2f(0, 0)) - position;
            transformedVertices[1] = transform.TransformPoint(new Vector2f(textureRect.Width, 0)) - position;
            transformedVertices[2] = transform.TransformPoint(new Vector2f(textureRect.Width, textureRect.Height)) - position;
            transformedVertices[3] = transform.TransformPoint(new Vector2f(0, textureRect.Height)) - position;

            VertexArray vertices = new(PrimitiveType.Quads);

            Vertex[] quad = new Vertex[4];

            quad[0] = new Vertex(new Vector2f(position.X, position.Y),
                                 new Vector2f(textureRect.Left, textureRect.Top));
            quad[1] = new Vertex(new Vector2f(position.X + transformedVertices[1].X, position.Y + transformedVertices[1].Y),
                                 new Vector2f(textureRect.Left + textureRect.Width, textureRect.Top));
            quad[2] = new Vertex(new Vector2f(position.X + transformedVertices[2].X, position.Y + transformedVertices[2].Y),
                                 new Vector2f(textureRect.Left + textureRect.Width, textureRect.Top + textureRect.Height));
            quad[3] = new Vertex(new Vector2f(position.X + transformedVertices[3].X, position.Y + transformedVertices[3].Y),
                                 new Vector2f(textureRect.Left, textureRect.Top + textureRect.Height));

            vertices.Append(quad[0]);
            vertices.Append(quad[1]);
            vertices.Append(quad[2]);
            vertices.Append(quad[3]);

            return vertices;
        }
 

3
General discussions / VertexArray transformations
« on: November 16, 2023, 02:08:40 am »
I am writing sprite batching based on VertexArray. Idea is, that every sprite instead of being drawn with Draw method is converted to VertexArray and merged with global VertexArray assigned to sprites atlas texture.
With this technique, I've got only one Draw call per sprites atlas texture.

I want my resulting VertexArray to support sprite Rotation and Scale. I know that there is Sprite.TransformPoint method, but it includes also Sprite position, so I cant use it.

Here is my approach to do this task manualy. Is my approach good or it can be done simplier?


        public static VertexArray CreateVertexArrayFromSprite(this Sprite sprite)
        {
            VertexArray vertices = new VertexArray(PrimitiveType.Quads);

            IntRect currentRect = sprite.TextureRect;
            Vector2f currentPos = sprite.Position;
            float rotation = sprite.Rotation;
            Vector2f scale = sprite.Scale;

            // Calculate the rotated and scaled vertices of the quad manually
            Vertex[] quad = new Vertex[4];
            quad[0] = new Vertex(new Vector2f(currentPos.X, currentPos.Y),
                                 new Vector2f(currentRect.Left, currentRect.Top));
            quad[1] = new Vertex(new Vector2f(currentPos.X + currentRect.Width, currentPos.Y),
                                 new Vector2f(currentRect.Left + currentRect.Width, currentRect.Top));
            quad[2] = new Vertex(new Vector2f(currentPos.X + currentRect.Width, currentPos.Y + currentRect.Height),
                                 new Vector2f(currentRect.Left + currentRect.Width, currentRect.Top + currentRect.Height));
            quad[3] = new Vertex(new Vector2f(currentPos.X, currentPos.Y + currentRect.Height),
                                 new Vector2f(currentRect.Left, currentRect.Top + currentRect.Height));

            // Apply rotation and scale manually
            Vector2f rotationCenter = new Vector2f(currentPos.X + currentRect.Width / 2, currentPos.Y + currentRect.Height / 2);
            for (int i = 0; i < 4; i++)
            {
                quad[i].Position = RotateAndScalePoint(quad[i].Position, rotationCenter, rotation);
                quad[i].Position = new Vector2f(quad[i].Position.X * scale.X, quad[i].Position.Y * scale.Y);
            }

            // Add the quad to the VertexArray
            vertices.Append(quad[0]);
            vertices.Append(quad[1]);
            vertices.Append(quad[2]);
            vertices.Append(quad[3]);

            return vertices;
        }

        // Helper method to rotate and scale a point around a center
        private static Vector2f RotateAndScalePoint(Vector2f point, Vector2f center, float rotation)
        {
            float cosTheta = (float)Math.Cos(Math.PI * rotation / 180.0);
            float sinTheta = (float)Math.Sin(Math.PI * rotation / 180.0);

            float translatedX = point.X - center.X;
            float translatedY = point.Y - center.Y;

            float rotatedX = translatedX * cosTheta - translatedY * sinTheta;
            float rotatedY = translatedX * sinTheta + translatedY * cosTheta;

            return new Vector2f(rotatedX + center.X, rotatedY + center.Y);
        }
 

Pages: [1]