12 Replies - 452 Views - Last Post: 07 October 2011 - 01:16 PM

#1 boops boops  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-September 11

making a sprite with Texture.SetData - colors all wrong

Posted 29 September 2011 - 03:38 AM

I'm just trying out XNA 4.0 on WinXP using VB2010. I want to build a sprite from my own pixel data, and I started by defining Texture2D (tx2) with a simple block of color in the LoadContent sub of a Game:
For i As Integer = 0 To pixels.Count - 1
	pixels(i) = &HFFFF
Next
tx2.SetData(Of Integer)(pixels)


Then I draw the texture in the Draw sub:
device.Clear(Color.Black)
spriteBatch.Begin()
spriteBatch.Draw(tx2, New Rectangle(100, 100, 200, 100), Color.White)
spriteBatch.End()



A 200*100 block of color appears on the window. I set the pixels to hex FFFF so it should be blue, shouldn't it? But no, it's yellow. In fact every color I try comes out wrong except White. What is more, the color of the block is affected by the background. Black results in a fully saturated color, but if I clear the background to White, nothing is visible at all. Incidentally, if I don't clear the device the background color is BlueViolet, which seems like an odd choice for a default. Can anyone see what I am doing wrong?

BB

This post has been edited by boops boops: 29 September 2011 - 03:42 AM


Is This A Good Question/Topic? 0
  • +

Replies To: making a sprite with Texture.SetData - colors all wrong

#2 ShadowsEdge19  Icon User is offline

  • D.I.C Addict

Reputation: 142
  • View blog
  • Posts: 664
  • Joined: 16-January 10

Re: making a sprite with Texture.SetData - colors all wrong

Posted 29 September 2011 - 03:58 AM

You could try adding a blank white texture behind your pixels and draw them on top of it to stop the background from bleeding through. Though why it would do that I'm not sure, have you accidently set the transparency values on the colour for the pixels?
Was This Post Helpful? 1
  • +
  • -

#3 boops boops  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-September 11

Re: making a sprite with Texture.SetData - colors all wrong

Posted 29 September 2011 - 05:46 AM

Thanks for your reply, which prompted me to try again. Painting one color block sprite on top of another had the same result as painting on the background: the color underneath changed the saturation of the color on top. But it wasn't a matter of a "wrong" color blend mode such as Add or Multiply, because color hex FF00FF, which ought to be pure green, came out as pure red. It was as if the bytes in each integer were being handled in a different order from what I expected for RGBA pixels. So I tried setting the color byte by byte using Texture2D.SetData(Of Byte) instead of (Of Integer) -- and it fixed the problem.

So the answer is clear: use (Of Byte). But I am left wondering why using(Of Integer) gives paradoxical results, and whether the default background is really meant to be BlueViolet. :blink:

cheers, BB
Was This Post Helpful? 0
  • +
  • -

#4 Kilorn  Icon User is offline

  • XNArchitect
  • member icon



Reputation: 1355
  • View blog
  • Posts: 3,528
  • Joined: 03-May 10

Re: making a sprite with Texture.SetData - colors all wrong

Posted 29 September 2011 - 06:12 AM

You've got that hex code backwards. FF00FF is actually full red and full blue which should've been purple. 00FF00 is full green.
Was This Post Helpful? 0
  • +
  • -

#5 boops boops  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-September 11

Re: making a sprite with Texture.SetData - colors all wrong

Posted 29 September 2011 - 07:20 AM

Perhaps I shouldn't have left out the leading zeros. I was using 32 bit RGBA format, so the final FF represents the Alpha and for example hex 00FF00FF represents Green. Regards, BB
Was This Post Helpful? 0
  • +
  • -

#6 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: making a sprite with Texture.SetData - colors all wrong

Posted 29 September 2011 - 02:05 PM

View Postboops boops, on 29 September 2011 - 08:46 AM, said:

and whether the default background is really meant to be BlueViolet. :blink:


When you get a BlueViolet background it is a warning from XNA that you are not rendering properly. It is basically XNA's way of saying: "You're drawing wrong!"

What I would also suggest is instead of trying to use (Of Integer), use (Of Color). It will, in the end, save you many headaches as you try and match integer values to color values, which isn't necessarily a good idea.
Was This Post Helpful? 0
  • +
  • -

#7 boops boops  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-September 11

Re: making a sprite with Texture.SetData - colors all wrong

Posted 29 September 2011 - 03:21 PM

View PostSixOfEleven, on 29 September 2011 - 02:05 PM, said:

When you get a BlueViolet background it is a warning from XNA that you are not rendering properly. It is basically XNA's way of saying: "You're drawing wrong!"

If only I knew what I was doing wrong...:dontgetit: Never mind, I'll find out sooner or later.

View PostSixOfEleven, on 29 September 2011 - 02:05 PM, said:

What I would also suggest is instead of trying to use (Of Integer), use (Of Color). It will, in the end, save you many headaches as you try and match integer values to color values, which isn't necessarily a good idea.

The color blocks were just for debugging. My aim is to use GDI+ bitmaps in XNA to take advantage of the graphics acceleration. I found a working example in XNA 3.1 and converting that into 4.0 has been my first real clash with the mysteries of XNA. Using (Of Integer) was tempting because it is quick to convert a Bitmap to an array of integers. A pity it didn't work! But it turns out that reshuffling the bytes of each pixel from ARGB to RGBA and using (Of Byte) works fine. Converting the bytes into XNA Colors has no advantage here as far as I can see. I could post my VB.Net function if anyone's interested.

BB

This post has been edited by boops boops: 29 September 2011 - 03:26 PM

Was This Post Helpful? 0
  • +
  • -

#8 boops boops  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-September 11

Re: making a sprite with Texture.SetData - colors all wrong

Posted 30 September 2011 - 03:43 AM

I just discovered the real cause of the problem. In XNA 4.0, the default pixel format has changed to Premultiplied, as explained here. Now why didn't I think of that? In fact why didn't anyone think of that :wink:? Now I can get nicely alpha-blended sprites.

BB

This post has been edited by boops boops: 30 September 2011 - 03:44 AM

Was This Post Helpful? 0
  • +
  • -

#9 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: making a sprite with Texture.SetData - colors all wrong

Posted 30 September 2011 - 05:31 AM

View Postboops boops, on 29 September 2011 - 06:21 PM, said:

View PostSixOfEleven, on 29 September 2011 - 02:05 PM, said:

When you get a BlueViolet background it is a warning from XNA that you are not rendering properly. It is basically XNA's way of saying: "You're drawing wrong!"

If only I knew what I was doing wrong...:dontgetit: Never mind, I'll find out sooner or later.


Usually it has to do with rendering to an off surface area and not setting the render target back to the graphics device. It happens frequently to me when I'm working with XNA in Windows Forms projects for editors. Just make sure that you have a valid device and you clear it before trying to render.
Was This Post Helpful? 1
  • +
  • -

#10 racidon  Icon User is offline

  • D.I.C Head

Reputation: 59
  • View blog
  • Posts: 172
  • Joined: 27-August 11

Re: making a sprite with Texture.SetData - colors all wrong

Posted 06 October 2011 - 04:47 AM

You may find this class I made when working on the Tower Defence game.
It makes gradient images, it also can take a part image of an existing image.

Personally I find if you want to make a colour instead of calculating all those colours, just calculate the shade and you can overlap the shading.

You will see this in my class, it creates a black/white gradient image, but by using a shade of blue when drawing to the screen it changes it to a black/blue gradient.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XNATowerDefenseLibrary.EngineComponents
{
    /// <summary>
    /// Used for creating textures to be used in drawing.
    /// </summary>
    public class TextureCreator
    {
        #region Field Region

        //Declare required fields
        static GraphicsDevice graphicsDevice;
        public static SpriteBatch spriteBatch;

        #endregion

        #region Constructor Region

        /// <summary>
        /// Initialises the Texture Creator class.
        /// </summary>
        /// <param name="graphicsDevice">Graphics Device used for creating textures.</param>
        /// <param name="spriteBatch">Sprite Batch used for drawing textures.</param>
        public static void Initialise(GraphicsDevice graphicsDevice,SpriteBatch spriteBatch)
        {
            TextureCreator.graphicsDevice = graphicsDevice;
            TextureCreator.spriteBatch = spriteBatch;
        }

        #endregion

        #region Static Method Region

        #region Get Horizontal Gradient Colors
        /// <summary>
        /// Gets an array of colors for a Horizontal Bar with a color gradient.
        /// </summary>
        /// <param name="width">The width of the bar.</param>
        /// <param name="length">Length of the bar.</param>
        /// <returns>Color Array.</returns>
        private static Color[] GetHorizontalGradientColors(uint width, uint length)
        {
            //Declare variables
            Color[] result;
            float
                increment;
            int color,
                index = 0,
                endPoint = (int)width;

            //Determine both width and length are greater than 0
            if (!(width > 0 && length > 0))
            //exit the function with a null color array
            { return null; }

            //Setup the result array
            result = new Color[width * length];

            //Calculate the increment
            increment = 255 / width * 2;

            //Loop through half the colors
            for (int y = 0; y < width/2; y++)
            {
                //Setup the color
                color = (int)(increment * y);

                //Loop through each pixel on the x axis
                for (int x = 0; x < length; x++)
                {
                    //Setup the current result
                    result[y*length + x] = new Color(
                        color,
                        color,
                        color);

                }

                //set the end point to the current index
                endPoint = y;
            }

            //Loop through the other half of the colors
            for (int y = (int)width-1; y > endPoint; y--)
            {
                //Setup the color
                color = (int)(increment * index);

                //Loop through each pixel on the x axis
                for (int x = 0; x < length; x++)
                {
                    //Set the current color
                    result[y * length + x] = new Color(
                        color,
                        color,
                        color);
                }

                //add to index
                index++;
            }

            //return the result
            return result;
        }
        #endregion
        #region Get Gradient Colors
        /// <summary>
        /// Gets an array of colors for a Top Down Gradient.
        /// </summary>
        /// <param name="width">The width of the color array.</param>
        /// <param name="height">The height of the color array.</param>
        /// <returns>Color Array.</returns>
        private static Color[] GetGradientColors(uint width, uint height)
        {
            //Declare variables
            Color[] result;
            float
                increment;
            int color;

            //Determine that both height and width are greater than 0
            if (!(width > 0 && height > 0))
            //exit the function with a null color array
            { return null; }

            //Setup the result array
            result = new Color[width * height];

            //Calculate the increment values
            increment = (float)255 / (result.Length);

            //Loop through each color
            for (int i = 0; i < result.Length; i++)
            {
                color = (int)(increment * i);

                result[i] = new Color(
                    color,
                    color,
                    color);
            }

            //return the color
            return result;
        }
        #endregion
        #region Get Gradient Corner
        /// <summary>
        /// Gets an array of colors for a Corner Bar with a color gradient.
        /// </summary>
        /// <param name="width">Width of the Bar.</param>
        /// <returns>2D Array of Colors.</returns>
        private static Color[,] GetGradientCorner(uint width)
        {
            //Declare variables
            Color[,] result;
            float increment;
            int
                color,
                x,
                y,
                endPoint = (int)width,
                count = 0;

            //Setup the result array
            result = new Color[width, width];

            //Calculate the increment
            increment = 255 / width * 2;

            //Loop through all the possible colours
            for (int i = 0; i < width/2; i++)
            {
                //Setup the colour
                color = (int)(increment * i);

                //Set the x and y values
                x = i;
                y = i;

                //Loop through each color on the X axis
                do
                {
                    //Set the current color
                    result[y, x] = new Color(
                        color,
                        color,
                        color);

                    //Increment the X value
                    x++;
                } while (x < width);

                //Set the X and Y values
                x = i;
                y = i;

                //Loop through each color on the Y axis
                do
                {
                    //Set the current color
                    result[y, x] = new Color(
                        color,
                        color,
                        color);

                    //Increment the Y value
                    y++;
                } while (y < width);

                endPoint = i;
            }

            //Setup color
            color = 0;

            //Loop through all the possible colours
            for (int i = (int)width-1; i > endPoint; i--)
            {
                //Set the X and Y values
                x = i;
                y = i;

                //Loop through each color on the X axis
                do
                {
                    //Set the current color
                    result[y, x] = new Color(
                        color,
                        color,
                        color);

                    //Increment the X value
                    x++;
                } while (x < width);

                //Set the X and Y values
                x = i;
                y = i;

                //Loop through each color on the Y axis
                do
                {
                    //Set the current color
                    result[y, x] = new Color(
                        color,
                        color,
                        color);

                    //Increment the Y value
                    y++;
                } while (y < width);

                //increment the count
                count++;

                //Setup the color
                color = (int)(increment * count);
            }

            //return the result
            return result;
        }
        #endregion
        #region Get Gradient Image
        /// <summary>
        /// Gets an Image filled with a gray scale gradient.
        /// </summary>
        /// <param name="width">Width of the Texture.</param>
        /// <param name="height">Height of the Texture.</param>
        /// <returns>Texture.</returns>
        public static Texture2D GetGradientImage(uint width, uint height)
        {
            //Declare and setup the result texture
            Texture2D result =
                new Texture2D(graphicsDevice, (int)width, (int)height);

            //Set the color data
            result.SetData<Color>(GetGradientColors(width,height));

            //return the result
            return result;
        }
        #endregion
        #region Get Horizontal Border Image
        /// <summary>
        /// Gets an Image filled with a horizontal bar gray scale gradient.
        /// </summary>
        /// <param name="width">Width (in pixels) of the bar being created.</param>
        /// <param name="length">Length (in pixels) of the bar being created.</param>
        /// <returns>Texture2D.</returns>
        public static Texture2D GetHorizontalBorderImage(uint width, uint length)
        {
            //Declare and setup the result texture
            Texture2D result =
                new Texture2D(graphicsDevice, (int)length, (int)width);

            //Set the color data
            result.SetData<Color>(GetHorizontalGradientColors(width, length));

            //return the result
            return result;
        }
        #endregion
        #region Get Corner Border Image
        /// <summary>
        /// Gets an Image filled with a corner bar gray scale gradient.
        /// </summary>
        /// <param name="width">Width (in pixels) of the corner being created.</param>
        /// <returns>Texture2D.</returns>
        public static Texture2D GetCornerBorderImage(uint width)
        {
            //Declare and setup the result texture
            Texture2D result =
                new Texture2D(graphicsDevice, (int)width, (int)width);
            Color[] colors =
                new Color[width * width];
            Color[,] colorArray = GetGradientCorner(width);

            //Loop through each color on the y axis
            for (int y = 0; y < width; y++)
            {
                //Loop through each color on the x axis
                for (int x = 0; x < width; x++)
                {
                    //Set the current color
                    colors[width * y + x] = colorArray[y, x];

                    if (colors[width * y + x].A == 0)
                    { colors[width * y + x] = new Color(255, 255, 255, 255); }
                }
            }

            //Setup the result texture
            result.SetData<Color>(colors);

            //return the texture
            return result;
        }
        #endregion
        /*
        #region Create Window Texture
        /// <summary>
        /// Creates a texture for a window component.
        /// </summary>
        /// <param name="window">Window used for creating the texture.</param>
        /// <returns>Texture2D.</returns>
        public static Texture2D CreateWindowTexture(Window window)
        {
            //Declare variables
            Texture2D result;
            RenderTarget2D render;
            PresentationParameters presPara;

            //Setup the presentation parameters
            presPara = graphicsDevice.PresentationParameters;

            //Setup the render target
            render = new RenderTarget2D(graphicsDevice, presPara.BackBufferWidth, presPara.BackBufferHeight, true, presPara.BackBufferFormat, presPara.DepthStencilFormat);

            //Set the render target
            graphicsDevice.SetRenderTarget(render);

            graphicsDevice.Clear(Color.Red);

            //Begin the draw
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);

            #region Draw

            //Begin by drawing the gradient fill
            spriteBatch.Draw(
                GetGradientImage((uint)window.Size.X, (uint)window.Size.Y),
                new Vector2(window.BorderSize),
                window.BackgroundColour);

            //Draw the top border
            spriteBatch.Draw(
                GetHorizontalBorderImage((uint)window.BorderSize,(uint)window.Size.X),
                new Vector2(window.BorderSize,0),
                    window.BorderColor);

            //Draw the bottom border
            spriteBatch.Draw(
                GetHorizontalBorderImage((uint)window.BorderSize, (uint)window.Size.X),
                new Vector2(window.BorderSize,window.Size.Y+window.BorderSize),
                    window.BorderColor);

            //Draw the top left corner
            spriteBatch.Draw(
                GetCornerBorderImage((uint)window.BorderSize),
                new Vector2(),
                window.BorderColor);

            //Draw the left border
            spriteBatch.Draw(
                GetHorizontalBorderImage((uint)window.BorderSize,(uint)window.Size.Y),
                new Vector2(window.BorderSize,window.BorderSize),
                null,
                window.BorderColor,
                1.57f,
                new Vector2(),
                1f,
                SpriteEffects.None,
                0);

            //Draw the right border
            spriteBatch.Draw(
                GetHorizontalBorderImage((uint)window.BorderSize, (uint)window.Size.Y),
                new Vector2(window.Size.X+window.BorderSize*2, window.BorderSize),
                null,
                window.BorderColor,
                1.57f,
                new Vector2(),
                1f,
                SpriteEffects.None,
                0);

            //Draw the top right corner
            spriteBatch.Draw(
                GetCornerBorderImage((uint)window.BorderSize),
                new Vector2(window.Size.X+window.BorderSize*2,0),
                null,
                window.BorderColor,
                1.57f,
                new Vector2(),
                1f,
                SpriteEffects.None,
                0);

            //Draw the bottom left corner
            spriteBatch.Draw(
                GetCornerBorderImage((uint)window.BorderSize),
                new Vector2(0,window.Size.Y+window.BorderSize),
                null,
                window.BorderColor,
                0f,
                new Vector2(),
                1f,
                SpriteEffects.FlipVertically,
                0);

            //Draw the bottom right corner
            spriteBatch.Draw(
                GetCornerBorderImage((uint)window.BorderSize),
                window.Size + new Vector2(window.BorderSize*2,window.BorderSize),
                null,
                window.BorderColor,
                1.57f,
                new Vector2(),
                1f,
                SpriteEffects.FlipHorizontally,
                0);

            #endregion

            //End the draw
            spriteBatch.End();

            //remove the render target
            graphicsDevice.SetRenderTarget(null);

            //Set the result texture
            result = new Texture2D(graphicsDevice, (int)(window.Size.X + window.BorderSize * 2), (int)(window.Size.Y + window.BorderSize * 2));
            result = (Texture2D)render;

            //Return the result
            return result;
        }
        #endregion
        */
        #region Create Part Image
        /// <summary>
        /// Creates a new image from an existing image.
        /// </summary>
        /// <param name="bounds">Area to use as the new image.</param>
        /// <param name="source">Source image used for getting a part image.</param>
        /// <returns>Texture2D.</returns>
        public static Texture2D CreatePartImage(Rectangle bounds, Texture2D source)
        {
            //Declare variables
            Texture2D result;
            Color[]
                sourceColors,
                resultColors;

            //Setup the result texture
            result = new Texture2D(graphicsDevice, bounds.Width, bounds.Height);

            //Setup the color arrays
            sourceColors = new Color[source.Height * source.Width];
            resultColors = new Color[bounds.Height * bounds.Width];

            //Get the source colors
            source.GetData<Color>(sourceColors);

            //Loop through colors on the y axis
            for (int y = bounds.Y; y < bounds.Height; y++)
            {
                //Loop through colors on the x axis
                for (int x = bounds.X; x < bounds.Width; x++)
                {
                    //Get the current color
                    resultColors[x - bounds.X + (y - bounds.Y) * bounds.Width] =
                        sourceColors[x + y * source.Width];
                }
            }

            //Set the color data of the result image
            result.SetData<Color>(resultColors);

            //return the result
            return result;
        }
        #endregion
        #region Create Pixel
        public static Texture2D CreatePixel()
        {
            //Declare variables
            Texture2D result;
            Color[] colors;

            //Setup the colors array
            colors = new Color[] { Color.White };

            //Setup the result texture
            result = new Texture2D(graphicsDevice, 1, 1);

            //Set the color data
            result.SetData<Color>(colors);

            //return the result image
            return result;
        }
        #endregion
        #region Create Rectangle
        public static Texture2D CreateRectangle(uint width, uint height)
        {
            //Declare variables
            Texture2D result;
            Color[] colors;

            //Setup the color array
            colors = new Color[width * height];

            //Draw the outline
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    //If the current color is on the outline
                    if (y == 0 || y == height - 1 || x == 0 || x == width - 1)
                    {
                        //Set the current color
                        colors[x + y * width] = Color.White;
                    }
                }
            }

            //Setup the result texture
            result = new Texture2D(graphicsDevice, (int)width, (int)height);

            //Set the result color data
            result.SetData<Color>(colors);

            //return the result texture
            return result;
        }
        #endregion

        #endregion
    }
}


Was This Post Helpful? 0
  • +
  • -

#11 boops boops  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-September 11

Re: making a sprite with Texture.SetData - colors all wrong

Posted 06 October 2011 - 12:27 PM

Hi racidon. I should have made it clearer in my thread title that my purpose is for now just to convert System.Drawing.Images into XNA textures; and it turns out that using Texture2D.SetData(Of Integer) works perfectly as long as the input data is in 32bppPArgb (premultiplied) format. I think I can learn something by studying your code (as soon as I get over my allergy to curly braces -- now where's that smiley for a VB.Net programmer...?). So thanks.

BB

View Postracidon, on 06 October 2011 - 04:47 AM, said:

You may find this class I made when working on the Tower Defence game.
It makes gradient images, it also can take a part image of an existing image.

Personally I find if you want to make a colour instead of calculating all those colours, just calculate the shade and you can overlap the shading.

You will see this in my class, it creates a black/white gradient image, but by using a shade of blue when drawing to the screen it changes it to a black/blue gradient.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace XNATowerDefenseLibrary.EngineComponents
{
    /// <summary>
    /// Used for creating textures to be used in drawing.
    /// </summary>
    public class TextureCreator
    {
        #region Field Region

        //Declare required fields
        static GraphicsDevice graphicsDevice;
        public static SpriteBatch spriteBatch;

        #endregion

        #region Constructor Region

        /// <summary>
        /// Initialises the Texture Creator class.
        /// </summary>
        /// <param name="graphicsDevice">Graphics Device used for creating textures.</param>
        /// <param name="spriteBatch">Sprite Batch used for drawing textures.</param>
        public static void Initialise(GraphicsDevice graphicsDevice,SpriteBatch spriteBatch)
        {
            TextureCreator.graphicsDevice = graphicsDevice;
            TextureCreator.spriteBatch = spriteBatch;
        }

        #endregion

        #region Static Method Region

        #region Get Horizontal Gradient Colors
        /// <summary>
        /// Gets an array of colors for a Horizontal Bar with a color gradient.
        /// </summary>
        /// <param name="width">The width of the bar.</param>
        /// <param name="length">Length of the bar.</param>
        /// <returns>Color Array.</returns>
        private static Color[] GetHorizontalGradientColors(uint width, uint length)
        {
            //Declare variables
            Color[] result;
            float
                increment;
            int color,
                index = 0,
                endPoint = (int)width;

            //Determine both width and length are greater than 0
            if (!(width > 0 && length > 0))
            //exit the function with a null color array
            { return null; }

            //Setup the result array
            result = new Color[width * length];

            //Calculate the increment
            increment = 255 / width * 2;

            //Loop through half the colors
            for (int y = 0; y < width/2; y++)
            {
                //Setup the color
                color = (int)(increment * y);

                //Loop through each pixel on the x axis
                for (int x = 0; x < length; x++)
                {
                    //Setup the current result
                    result[y*length + x] = new Color(
                        color,
                        color,
                        color);

                }

                //set the end point to the current index
                endPoint = y;
            }

            //Loop through the other half of the colors
            for (int y = (int)width-1; y > endPoint; y--)
            {
                //Setup the color
                color = (int)(increment * index);

                //Loop through each pixel on the x axis
                for (int x = 0; x < length; x++)
                {
                    //Set the current color
                    result[y * length + x] = new Color(
                        color,
                        color,
                        color);
                }

                //add to index
                index++;
            }

            //return the result
            return result;
        }
        #endregion
        #region Get Gradient Colors
        /// <summary>
        /// Gets an array of colors for a Top Down Gradient.
        /// </summary>
        /// <param name="width">The width of the color array.</param>
        /// <param name="height">The height of the color array.</param>
        /// <returns>Color Array.</returns>
        private static Color[] GetGradientColors(uint width, uint height)
        {
            //Declare variables
            Color[] result;
            float
                increment;
            int color;

            //Determine that both height and width are greater than 0
            if (!(width > 0 && height > 0))
            //exit the function with a null color array
            { return null; }

            //Setup the result array
            result = new Color[width * height];

            //Calculate the increment values
            increment = (float)255 / (result.Length);

            //Loop through each color
            for (int i = 0; i < result.Length; i++)
            {
                color = (int)(increment * i);

                result[i] = new Color(
                    color,
                    color,
                    color);
            }

            //return the color
            return result;
        }
        #endregion
        #region Get Gradient Corner
        /// <summary>
        /// Gets an array of colors for a Corner Bar with a color gradient.
        /// </summary>
        /// <param name="width">Width of the Bar.</param>
        /// <returns>2D Array of Colors.</returns>
        private static Color[,] GetGradientCorner(uint width)
        {
            //Declare variables
            Color[,] result;
            float increment;
            int
                color,
                x,
                y,
                endPoint = (int)width,
                count = 0;

            //Setup the result array
            result = new Color[width, width];

            //Calculate the increment
            increment = 255 / width * 2;

            //Loop through all the possible colours
            for (int i = 0; i < width/2; i++)
            {
                //Setup the colour
                color = (int)(increment * i);

                //Set the x and y values
                x = i;
                y = i;

                //Loop through each color on the X axis
                do
                {
                    //Set the current color
                    result[y, x] = new Color(
                        color,
                        color,
                        color);

                    //Increment the X value
                    x++;
                } while (x < width);

                //Set the X and Y values
                x = i;
                y = i;

                //Loop through each color on the Y axis
                do
                {
                    //Set the current color
                    result[y, x] = new Color(
                        color,
                        color,
                        color);

                    //Increment the Y value
                    y++;
                } while (y < width);

                endPoint = i;
            }

            //Setup color
            color = 0;

            //Loop through all the possible colours
            for (int i = (int)width-1; i > endPoint; i--)
            {
                //Set the X and Y values
                x = i;
                y = i;

                //Loop through each color on the X axis
                do
                {
                    //Set the current color
                    result[y, x] = new Color(
                        color,
                        color,
                        color);

                    //Increment the X value
                    x++;
                } while (x < width);

                //Set the X and Y values
                x = i;
                y = i;

                //Loop through each color on the Y axis
                do
                {
                    //Set the current color
                    result[y, x] = new Color(
                        color,
                        color,
                        color);

                    //Increment the Y value
                    y++;
                } while (y < width);

                //increment the count
                count++;

                //Setup the color
                color = (int)(increment * count);
            }

            //return the result
            return result;
        }
        #endregion
        #region Get Gradient Image
        /// <summary>
        /// Gets an Image filled with a gray scale gradient.
        /// </summary>
        /// <param name="width">Width of the Texture.</param>
        /// <param name="height">Height of the Texture.</param>
        /// <returns>Texture.</returns>
        public static Texture2D GetGradientImage(uint width, uint height)
        {
            //Declare and setup the result texture
            Texture2D result =
                new Texture2D(graphicsDevice, (int)width, (int)height);

            //Set the color data
            result.SetData<Color>(GetGradientColors(width,height));

            //return the result
            return result;
        }
        #endregion
        #region Get Horizontal Border Image
        /// <summary>
        /// Gets an Image filled with a horizontal bar gray scale gradient.
        /// </summary>
        /// <param name="width">Width (in pixels) of the bar being created.</param>
        /// <param name="length">Length (in pixels) of the bar being created.</param>
        /// <returns>Texture2D.</returns>
        public static Texture2D GetHorizontalBorderImage(uint width, uint length)
        {
            //Declare and setup the result texture
            Texture2D result =
                new Texture2D(graphicsDevice, (int)length, (int)width);

            //Set the color data
            result.SetData<Color>(GetHorizontalGradientColors(width, length));

            //return the result
            return result;
        }
        #endregion
        #region Get Corner Border Image
        /// <summary>
        /// Gets an Image filled with a corner bar gray scale gradient.
        /// </summary>
        /// <param name="width">Width (in pixels) of the corner being created.</param>
        /// <returns>Texture2D.</returns>
        public static Texture2D GetCornerBorderImage(uint width)
        {
            //Declare and setup the result texture
            Texture2D result =
                new Texture2D(graphicsDevice, (int)width, (int)width);
            Color[] colors =
                new Color[width * width];
            Color[,] colorArray = GetGradientCorner(width);

            //Loop through each color on the y axis
            for (int y = 0; y < width; y++)
            {
                //Loop through each color on the x axis
                for (int x = 0; x < width; x++)
                {
                    //Set the current color
                    colors[width * y + x] = colorArray[y, x];

                    if (colors[width * y + x].A == 0)
                    { colors[width * y + x] = new Color(255, 255, 255, 255); }
                }
            }

            //Setup the result texture
            result.SetData<Color>(colors);

            //return the texture
            return result;
        }
        #endregion
        /*
        #region Create Window Texture
        /// <summary>
        /// Creates a texture for a window component.
        /// </summary>
        /// <param name="window">Window used for creating the texture.</param>
        /// <returns>Texture2D.</returns>
        public static Texture2D CreateWindowTexture(Window window)
        {
            //Declare variables
            Texture2D result;
            RenderTarget2D render;
            PresentationParameters presPara;

            //Setup the presentation parameters
            presPara = graphicsDevice.PresentationParameters;

            //Setup the render target
            render = new RenderTarget2D(graphicsDevice, presPara.BackBufferWidth, presPara.BackBufferHeight, true, presPara.BackBufferFormat, presPara.DepthStencilFormat);

            //Set the render target
            graphicsDevice.SetRenderTarget(render);

            graphicsDevice.Clear(Color.Red);

            //Begin the draw
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);

            #region Draw

            //Begin by drawing the gradient fill
            spriteBatch.Draw(
                GetGradientImage((uint)window.Size.X, (uint)window.Size.Y),
                new Vector2(window.BorderSize),
                window.BackgroundColour);

            //Draw the top border
            spriteBatch.Draw(
                GetHorizontalBorderImage((uint)window.BorderSize,(uint)window.Size.X),
                new Vector2(window.BorderSize,0),
                    window.BorderColor);

            //Draw the bottom border
            spriteBatch.Draw(
                GetHorizontalBorderImage((uint)window.BorderSize, (uint)window.Size.X),
                new Vector2(window.BorderSize,window.Size.Y+window.BorderSize),
                    window.BorderColor);

            //Draw the top left corner
            spriteBatch.Draw(
                GetCornerBorderImage((uint)window.BorderSize),
                new Vector2(),
                window.BorderColor);

            //Draw the left border
            spriteBatch.Draw(
                GetHorizontalBorderImage((uint)window.BorderSize,(uint)window.Size.Y),
                new Vector2(window.BorderSize,window.BorderSize),
                null,
                window.BorderColor,
                1.57f,
                new Vector2(),
                1f,
                SpriteEffects.None,
                0);

            //Draw the right border
            spriteBatch.Draw(
                GetHorizontalBorderImage((uint)window.BorderSize, (uint)window.Size.Y),
                new Vector2(window.Size.X+window.BorderSize*2, window.BorderSize),
                null,
                window.BorderColor,
                1.57f,
                new Vector2(),
                1f,
                SpriteEffects.None,
                0);

            //Draw the top right corner
            spriteBatch.Draw(
                GetCornerBorderImage((uint)window.BorderSize),
                new Vector2(window.Size.X+window.BorderSize*2,0),
                null,
                window.BorderColor,
                1.57f,
                new Vector2(),
                1f,
                SpriteEffects.None,
                0);

            //Draw the bottom left corner
            spriteBatch.Draw(
                GetCornerBorderImage((uint)window.BorderSize),
                new Vector2(0,window.Size.Y+window.BorderSize),
                null,
                window.BorderColor,
                0f,
                new Vector2(),
                1f,
                SpriteEffects.FlipVertically,
                0);

            //Draw the bottom right corner
            spriteBatch.Draw(
                GetCornerBorderImage((uint)window.BorderSize),
                window.Size + new Vector2(window.BorderSize*2,window.BorderSize),
                null,
                window.BorderColor,
                1.57f,
                new Vector2(),
                1f,
                SpriteEffects.FlipHorizontally,
                0);

            #endregion

            //End the draw
            spriteBatch.End();

            //remove the render target
            graphicsDevice.SetRenderTarget(null);

            //Set the result texture
            result = new Texture2D(graphicsDevice, (int)(window.Size.X + window.BorderSize * 2), (int)(window.Size.Y + window.BorderSize * 2));
            result = (Texture2D)render;

            //Return the result
            return result;
        }
        #endregion
        */
        #region Create Part Image
        /// <summary>
        /// Creates a new image from an existing image.
        /// </summary>
        /// <param name="bounds">Area to use as the new image.</param>
        /// <param name="source">Source image used for getting a part image.</param>
        /// <returns>Texture2D.</returns>
        public static Texture2D CreatePartImage(Rectangle bounds, Texture2D source)
        {
            //Declare variables
            Texture2D result;
            Color[]
                sourceColors,
                resultColors;

            //Setup the result texture
            result = new Texture2D(graphicsDevice, bounds.Width, bounds.Height);

            //Setup the color arrays
            sourceColors = new Color[source.Height * source.Width];
            resultColors = new Color[bounds.Height * bounds.Width];

            //Get the source colors
            source.GetData<Color>(sourceColors);

            //Loop through colors on the y axis
            for (int y = bounds.Y; y < bounds.Height; y++)
            {
                //Loop through colors on the x axis
                for (int x = bounds.X; x < bounds.Width; x++)
                {
                    //Get the current color
                    resultColors[x - bounds.X + (y - bounds.Y) * bounds.Width] =
                        sourceColors[x + y * source.Width];
                }
            }

            //Set the color data of the result image
            result.SetData<Color>(resultColors);

            //return the result
            return result;
        }
        #endregion
        #region Create Pixel
        public static Texture2D CreatePixel()
        {
            //Declare variables
            Texture2D result;
            Color[] colors;

            //Setup the colors array
            colors = new Color[] { Color.White };

            //Setup the result texture
            result = new Texture2D(graphicsDevice, 1, 1);

            //Set the color data
            result.SetData<Color>(colors);

            //return the result image
            return result;
        }
        #endregion
        #region Create Rectangle
        public static Texture2D CreateRectangle(uint width, uint height)
        {
            //Declare variables
            Texture2D result;
            Color[] colors;

            //Setup the color array
            colors = new Color[width * height];

            //Draw the outline
            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    //If the current color is on the outline
                    if (y == 0 || y == height - 1 || x == 0 || x == width - 1)
                    {
                        //Set the current color
                        colors[x + y * width] = Color.White;
                    }
                }
            }

            //Setup the result texture
            result = new Texture2D(graphicsDevice, (int)width, (int)height);

            //Set the result color data
            result.SetData<Color>(colors);

            //return the result texture
            return result;
        }
        #endregion

        #endregion
    }
}


Was This Post Helpful? 0
  • +
  • -

#12 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Re: making a sprite with Texture.SetData - colors all wrong

Posted 07 October 2011 - 07:56 AM

View Postboops boops, on 29 September 2011 - 06:21 PM, said:

My aim is to use GDI+ bitmaps in XNA to take advantage of the graphics acceleration.


Just noticed that line. If I'm reading it right you want to use GDI+ to take advantage of graphics acceleration. GDI+ does not use graphics acceleration. GDI+ is actually painfully slow compared to XNA. If I misunderstood what you are trying to do then feel free to ignore me because using XNA to make GDI+ faster is an excellent idea as XNA does use graphics acceleration. I see why you would be using SetData(Of Integer) rather than SetData(Of Color).
Was This Post Helpful? 0
  • +
  • -

#13 boops boops  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 29-September 11

Re: making a sprite with Texture.SetData - colors all wrong

Posted 07 October 2011 - 01:16 PM

View PostSixOfEleven, on 07 October 2011 - 07:56 AM, said:

View Postboops boops, on 29 September 2011 - 06:21 PM, said:

My aim is to use GDI+ bitmaps in XNA to take advantage of the graphics acceleration.


Just noticed that line. If I'm reading it right you want to use GDI+ to take advantage of graphics acceleration. GDI+ does not use graphics acceleration. GDI+ is actually painfully slow compared to XNA. If I misunderstood what you are trying to do then feel free to ignore me because using XNA to make GDI+ faster is an excellent idea as XNA does use graphics acceleration. I see why you would be using SetData(Of Integer) rather than SetData(Of Color).

Your understanding is wholly correct. To put it into context, I am mainly interested in creating software for 2d art, animation and photography. GDI+ offers some good tools for that purpose but it performs poorly especially with large images. Perhaps I could have gone for Win32 or DirectX pure, but it seemed easier to take an existing package. Someone gave me code for an XNA Viewport for WinForms (using an inherited Panel) which performed extremely well. It was in XNA 2 (I think) and only worked with .Net Framework 2 or less. I decided to try porting it to XNA 4.0/Net Framework 4, and learn something about XNA at the same time. But I ran into all kinds of problems including this color one. Meanwhile I have also been looking using WPF instead as a DirectX package and I think I will go with that for the while. XNA is games oriented and WPF is UI oriented so that's Hobson's Choice. I expect I will take another look at XNA later to see how they compare.

Thanks again to everyone for their help on this forum.

regards, BB
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1