Exploring the depths and potentials of ASP.NET RSS 2.0 or Subscribe to .BenRush by Email
 Sunday, April 08, 2007

Thanks to Sebastian and his source here for my direction on this topic. Cheers man; I owe you Guinness.



There seems to be a severe lack of writing on the internet about how to do just this very thing - slowly blending one image to another using DirectX. I'm not an expert at DirectX, I spend most of my time these days doing web-based development, but I am also a software consultant and so get picked up for different types of jobs from time to time, and obviously it makes no sense to turn a job down....



....well, I wanted to implement a system where one texture slowly blended into another texture; kind of like a slow fade effect. As it turns out it's pretty trivial, but again not something I was very good at....



To do this correctly, you really want to do it independent of the image format, so that whether you're using something that has an alpha layer in it or not is irrelevant (like, a JPG vs. a PNG). To do this, you fill in or interpolate the alpha value of an image acrossed it using the vertices in the vertex buffer. So - you need to make sure that your vertices have an alpha color component. Likewise, to change the degree by which something blends, you change the alpha components of each vertex in the buffer. This actually gives you great control over the blending because you can choose even more advanced scenarios than simply blending from one image to another - you can also choose where to start the blending (from a particular corner to another, etc.).

So, on to the code....in the drawing loop for the application (if you're implementing your DirectX application correctly, this should be the Paint method):

        private void Form1_Paint(object sender, PaintEventArgs e)
        {

            _device.Clear(ClearFlags.Target, Color.Black, 1.0f, 0);
            _device.BeginScene();

            if (_zoomIn)
            {
                _alphaValue++;

                if (_alphaValue == 255)
                    _zoomIn = false;
            }
            else
            {
                _alphaValue--;
                if (_alphaValue == 0)
                    _zoomIn = true;
            }
            _verts[0] = new CustomVertex.PositionColoredTextured(-1.0F, 1.0F, 0.0F, Color.FromArgb(_alphaValue, Color.White).ToArgb(), 0.0F, 0.0F);
            _verts[1] = new CustomVertex.PositionColoredTextured(1.0F, 1.0F, 0.0F, Color.FromArgb(_alphaValue, Color.White).ToArgb(), 1.0F, 0.0F);
            _verts[2] = new CustomVertex.PositionColoredTextured(-1.0F, -1.0F, 0.0F, Color.FromArgb(_alphaValue, Color.White).ToArgb(), 0.0F, 1.0F);
            _verts[3] = new CustomVertex.PositionColoredTextured(1.0F, -1.0F, 0.0F, Color.FromArgb(_alphaValue, Color.White).ToArgb(), 1.0F, 1.0F);
            _verts[4] = new CustomVertex.PositionColoredTextured(-1.0F, -1.0F, 0.0F, Color.FromArgb(_alphaValue, Color.White).ToArgb(), 0.0F, 0.0F);
            _verts[5] = new CustomVertex.PositionColoredTextured(1.0F, -1.0F, 0.0F, Color.FromArgb(_alphaValue, Color.White).ToArgb(), 1.0F, 0.0F);

            _buffer.SetData(_verts, 0, LockFlags.None);

            _device.VertexFormat = CustomVertex.PositionColoredTextured.Format;
            _device.SetStreamSource(0, _buffer, 0);

            _device.SetTexture(0, _texture);
            _device.SetTexture(1, _texture2);

            _device.TextureState[1].TextureCoordinateIndex = 0;

            _device.SamplerState[1].AddressU = TextureAddress.Wrap;
            _device.SamplerState[1].AddressV = TextureAddress.Wrap;


            _device.SetTextureStageState(0, TextureStageStates.ColorArgument1, (int)TextureArgument.TextureColor);
            _device.SetTextureStageState(0, TextureStageStates.ColorOperation, (int)TextureOperation.SelectArg1);
            _device.SetTextureStageState(1, TextureStageStates.ColorArgument1, (int)TextureArgument.Current);
            _device.SetTextureStageState(1, TextureStageStates.ColorArgument2, (int)TextureArgument.TextureColor);
            _device.SetTextureStageState(1, TextureStageStates.ColorOperation, (int)TextureOperation.BlendDiffuseAlpha);

            _device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);

            _device.EndScene();
            _device.Present();

            Invalidate();
            return;
        }

The effect is two textures that slowly blend back and forth to each other.


Recommended Reading

kick it on DotNetKicks.com
Sunday, April 08, 2007 2:07:54 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
DirectX and XNA | Programming

Computers Blogs - Blog Top Sites

Archive
<August 2008>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
31123456
Blogroll
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2008
Benjamin Rush
Sign In
Statistics
Total Posts: 444
This Year: 0
This Month: 0
This Week: 0
Comments: 127
Themes
Pick a theme:
All Content © 2008, Benjamin Rush
DasBlog theme 'Business' created by Christoph De Baene (delarou)