Skip to main content
GameDev.net gamedev.net
🔒 Locked

Grayscale Image Transitions Using SlimDX

Started by Yashwinder Jun 1, 2011 at 5:28 AM 28 replies 7.8k views
Original Post
Yashwinder
Yashwinder
I am making an image slide show. Till now I have done transitions using the matrix transformation but now I am trying to make transitions using some gray scale background image.
Can any body please give me an idea how can i perform that or can post some code to give me an idea.

Thanks
Michael Tanczos
Michael Tanczos
Use a pixel shader for this. You can use some of the shaders in this library to get you started.. they just require that you add the technique to the shader but that's about it. Granted, this is for WPF.. but the concepts are going to be similar in that you have to load the shader, load two textures (texture0, texture1), set the two texture sampler registers to use those textures for the effect, and then set a register for "progress" that is a simple float between 0 and 1 to represent how much the transition has progressed.. then just render out all the passes.

I've actually done this in SlimDX, but my code is a little elaborate to post here.

http://wpffx.codeplex.com/

Here's a list of transitions they have available:
BandedSwirl, Blings, Blood, CircleReveal, CircleStretch, CircularBlur, CloudReveral, Cloudy, Crumble, Dissolve, DropFade, Fade, LeastBright, LineReveal, MostBright, PixelateIn, PixelateOut, Pixelate, RadialBlur, RadialWiggle, RandomCircleReveal, Ripple, Rotate, Saturate, Shrink, SlideIn, SmoothSwirl, Swirl, Water, Wave.
Yashwinder
Yashwinder
Can you please post a little bit of the main working code. I will be grateful to you
DJTN
DJTN

Can you please post a little bit of the main working code. I will be grateful to you


Are you familiar with HLSL and how to set that up on the CPU side? If not, it's too much to go into in a thread post. If you do know how- then obtaining your greyscale would be easy:

Color.rgb = (Color.r+Color.g+Color.b)/3.0f;
Yashwinder
Yashwinder
I have learned to code for HLSL but i dont know how to use it in slimdx code for rendering an image file by the help of a texture and sprite to create various effects. can you please post a small code for just giving a hint, so that I can proceed further. I will be grateful to you.
Postie
Postie

[quote name='Yash14' timestamp='1307459102' post='4820537']
Can you please post a little bit of the main working code. I will be grateful to you


Are you familiar with HLSL and how to set that up on the CPU side? If not, it's too much to go into in a thread post. If you do know how- then obtaining your greyscale would be easy:

Color.rgb = (Color.r+Color.g+Color.b)/3.0f;
[/quote]

A better formula to use would be:

[font="Courier New"]Color.rgb = (Color.r * 0.299f + Color.g * 0.587f + Color.b * 0.114f);[/font]

The reason is that in terms of luminance (which is what the grayscale value is a representation of), the three colour primaries are not equally weighted. Use of those coefficients is fairly standard in image processing.
[size="2"]Currently working on an open world survival RPG - For info check out my Development blog:[size="2"] ByteWrangler
Yashwinder
Yashwinder
How can I use my HLSL .fx File in my slimDx code
Yashwinder
Yashwinder
I have understood making pixel shader file and vertex shader file for doing image transition. But what should be the extension of the file when i am saving it for the pixel shader and the vertex shader.
How can I use these shader files in my slimdx c# code. I have gone through the examples of the pixel shader and vertex shader but they are not clear enough to show the use of pixel shader and vertex shader. please help me out to show the use of pixel shader and the vertex shader in slimdx or directx using c#.
Yashwinder
Yashwinder
sampler inputImage;
sampler productImage;
float4 Timers;
struct PS_INPUT
{
float2 texCoord:TEXCOORD0;
};

float4 main(PS_INPUT In):COLOR
{

float xPosition=Timers.w*1.1;
float2 newCoords;
float4 c=.5;
xPosition=In.texCoord.x-xPosition;
if((xPosition<0)||(xPosition>1))
{
c=tex2D(productImage,In.texCoord);
}
else
{
newCoords.y=In.texCoord.y;
newCoords.x=xPosition;
c=tex2D(inputImage,newCoords);
}
return c;
}


This is an hlsl code for transition between two images , can any body tell me that how can i use it in the real implementation in slimdx
Yashwinder
Yashwinder
Can anybody please help me out in doing this
DJTN
DJTN

Can anybody please help me out in doing this



Pixel Shader files end in ".fx". I did a google search for wpf pixel shaders and returned over 200,000 results. Here's a link to the first tutorial who is doing the exact same thing as you.


http://bursjootech.blogspot.com/2008/06/grayscale-effect-pixel-shader-effect-in.html



DirectX - SlimDx - XNA, thery're all based off the same platform pretty much so the only different is the language used to access them and who is resonsible for memory clean up. In other words, you can take C++ directx code and easily turn it into XNA or SlimDX assembly. Just keep in mind that the XNA platform uses the right handed cordinate system.



Good luck!
Yashwinder
Yashwinder
Thank you very much for your reply. But I am looking for something that can guide me through making the pixel shader effects in windows form application. I will be very thankful to you if you can help me out in this context.
Yashwinder
Yashwinder
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using SlimDX.Direct3D9;
using SlimDX;
using SlimDX.Windows;
using System.Drawing;
using System.Threading;

namespace WindowsFormsApplication1
{
// Vertex structure.
[StructLayout(LayoutKind.Sequential)]
struct Vertex
{
public Vector3 Position;
public float Tu;
public float Tv;

public static int SizeBytes
{
get { return Marshal.SizeOf(typeof(Vertex)); }
}

public static VertexFormat Format
{
get { return VertexFormat.Position | VertexFormat.Texture1; }
}
}


static class Program
{
public static Device D3DDevice; // Direct3D device.
public static VertexBuffer Vertices; // Vertex buffer object used to hold vertices.
public static Texture Image; // Texture object to hold the image loaded from a file.
public static int time; // Used for rotation caculations.
public static float angle; // Angle of rottaion.
public static Form1 Window =new Form1();
public static string filepath;
static VertexShader vertexShader = null;
static ConstantTable constantTable = null;
static ImageInformation info;
[STAThread]
static void Main()
{

filepath = "C:\\Users\\Public\\Pictures\\Sample Pictures\\Garden.jpg";




info = new ImageInformation();
info = ImageInformation.FromFile(filepath);

PresentParameters presentParams = new PresentParameters();

// Below are the required bare mininum, needed to initialize the D3D device.
presentParams.BackBufferHeight = info.Height; // BackBufferHeight, set to the Window's height.
presentParams.BackBufferWidth = info.Width+200; // BackBufferWidth, set to the Window's width.




presentParams.Windowed =true;
presentParams.DeviceWindowHandle = Window.panel2 .Handle; // DeviceWindowHandle, set to the Window's handle.

// Create the device.
D3DDevice = new Device(new Direct3D (), 0, DeviceType.Hardware, Window.Handle, CreateFlags.HardwareVertexProcessing, presentParams);

// Create the vertex buffer and fill with the triangle vertices. (Non-indexed)
// Remember 3 vetices for a triangle, 2 tris per quad = 6.
Vertices = new VertexBuffer(D3DDevice, 6 * Vertex.SizeBytes, Usage.WriteOnly, VertexFormat.None, Pool.Managed);
DataStream stream = Vertices.Lock(0, 0, LockFlags.None);
stream.WriteRange(BuildVertexData());
Vertices.Unlock();

// Create the texture.

Image = Texture.FromFile(D3DDevice,filepath );

// Turn off culling, so we see the front and back of the triangle
D3DDevice.SetRenderState(RenderState.CullMode, Cull.None);

// Turn off lighting
D3DDevice.SetRenderState(RenderState.Lighting, false);


ShaderBytecode sbcv = ShaderBytecode.CompileFromFile("C:\\Users\\yashwinder singh\\Desktop\\vertexShader.vs", "vs_main", "vs_1_1", ShaderFlags.None);
constantTable = sbcv.ConstantTable;
vertexShader = new VertexShader(D3DDevice, sbcv);


ShaderBytecode sbc = ShaderBytecode.CompileFromFile("C:\\Users\\yashwinder singh\\Desktop\\pixelShader.txt", "ps_main", "ps_3_0", ShaderFlags.None);
PixelShader ps = new PixelShader(D3DDevice, sbc);

VertexDeclaration vertexDecl = new VertexDeclaration(D3DDevice, new[] {
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.PositionTransformed, 0),
new VertexElement(0, 12, DeclarationType.Float2 , DeclarationMethod.Default, DeclarationUsage.TextureCoordinate , 0),
VertexElement.VertexDeclarationEnd
});

Application.EnableVisualStyles();

MessagePump.Run(Window, () =>
{
// Clear the backbuffer to a black color.
D3DDevice.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);

// Begin the scene.
D3DDevice.BeginScene();



// Setup the world, view and projection matrices.



//D3DDevice.VertexShader = vertexShader;
//D3DDevice.PixelShader = ps;

// Render the vertex buffer.
D3DDevice.SetStreamSource(0, Vertices, 0, Vertex.SizeBytes);
D3DDevice.VertexFormat = Vertex.Format;

// Setup our texture. Using Textures introduces the texture stage states,
// which govern how Textures get blended together (in the case of multiple
// Textures) and lighting information.
D3DDevice.SetTexture(0, Image);


// Now drawing 2 triangles, for a quad.
D3DDevice.DrawPrimitives(PrimitiveType.TriangleList , 0, 2);

// End the scene.
D3DDevice.EndScene();

// Present the backbuffer contents to the screen.
D3DDevice.Present();

});
if (Image != null)
Image.Dispose();

if (Vertices != null)
Vertices.Dispose();

if (D3DDevice != null)
D3DDevice.Dispose();


}
private static Vertex[] BuildVertexData()
{
Vertex[] vertexData = new Vertex[6];

vertexData[0].Position = new Vector3(-1.0f, 1.0f, 0.0f);
vertexData[0].Tu = 0.0f;
vertexData[0].Tv = 0.0f;

vertexData[1].Position = new Vector3(-1.0f, -1.0f, 0.0f);
vertexData[1].Tu = 0.0f;
vertexData[1].Tv = 1.0f;

vertexData[2].Position = new Vector3(1.0f, 1.0f, 0.0f);
vertexData[2].Tu = 1.0f;
vertexData[2].Tv = 0.0f;

vertexData[3].Position = new Vector3(-1.0f, -1.0f, 0.0f);
vertexData[3].Tu = 0.0f;
vertexData[3].Tv = 1.0f;

vertexData[4].Position = new Vector3(1.0f, -1.0f, 0.0f);
vertexData[4].Tu = 1.0f;
vertexData[4].Tv = 1.0f;

vertexData[5].Position = new Vector3(1.0f, 1.0f, 0.0f);
vertexData[5].Tu = 1.0f;
vertexData[5].Tv = 0.0f;

return vertexData;
}


}
}





This is my code for the pixel shader use. The image is being displayed properly if I don't set the pixel shader but as and when I give the pixel shader to device then nothing is displayed.
Please help me out to resolve this problem.
DJTN
DJTN
I'm not familar with slimDX but shouldnt you have an EFFECT file that loads the pixel shader (.fx) and use that handle to set the textures, colors, and other varables in the shader? Then you'd render with Device.DrawPrimitive() like you're currently doing. I dont' see where you are setting any vars in the pixelshader.

I've never used SlimDX, sorry
Yashwinder
Yashwinder
// Pixel shader input structure
struct PS_INPUT
{
float4 Position : POSITION;
float2 Texture : TEXCOORD0;
};


// Pixel shader output structure
struct PS_OUTPUT
{
float4 Color : COLOR0;
};


// Global variables
sampler2D Tex0;


// Name: Simple Pixel Shader
// Type: Pixel shader
// Desc: Fetch texture and blend with constant color
//
PS_OUTPUT ps_main( in PS_INPUT In )
{
PS_OUTPUT Out; //create an output pixel

Out.Color = tex2D(Tex0, In.Texture); //do a texture lookup

Out.Color *= float4(0.9f, 0.8f, 0.0f, 1); //do a simple effect

return Out; //return output pixel
}




this is my pixel shader file that i am importing and there is no use of importing the effect file in this program. the vertex shader and pixel shader does required things. And below is my vertex shader code.


// Vertex shader input structure
struct VS_INPUT
{
float4 Position : POSITION;
float2 Texture : TEXCOORD0;
};


// Vertex shader output structure
struct VS_OUTPUT
{
float4 Position : POSITION;
float2 Texture : TEXCOORD0;
};


// Global variables
float4x4 WorldViewProj;


// Name: Simple Vertex Shader
// Type: Vertex shader
// Desc: Vertex transformation and texture coord pass-through
//
VS_OUTPUT vs_main( in VS_INPUT In )
{
VS_OUTPUT Out; //create an output vertex

Out.Position = mul(In.Position,
WorldViewProj); //apply vertex transformation
Out.Texture = In.Texture; //copy original texcoords

return Out; //return output vertex
}
Yashwinder
Yashwinder
can any body please reply me something to help me out
Postie
Postie
I'm using SlimDX on DX9 with shaders in my current project, and the way I setup and use my shaders is different to what you've posted.

In my code I do something like this:

To load the shader file:


Effect shader = Effect.FromFile(device, "shader.fx", ShaderFlags.None);

EffectHandle paramWorldViewProj = new EffectHandle("matWorldViewProj");


.. then at render time:...


// here is an example of setting a shader parameter...
shader.SetValue(paramWorldViewProj , worldViewProjection);

shader.Begin();
shader.BeginPass(0);

// primitives render call goes here
// model.Render();

shader.EndPass();
shader.End();
[size="2"]Currently working on an open world survival RPG - For info check out my Development blog:[size="2"] ByteWrangler
DJTN
DJTN
Postie -what you posted makes sense to me too but it looks like Yash14 is using pre-compiled shaders. Regardless, he'll still need to set vars and render using the same technique as your code. Currently he's using Device.SetTexture() which is a fixed function pipeline code. He needs to pass the texture into the shader as a varable. The code he posted is both a Progammable Pipeline and a Fixed Function Pipeleine.
Postie
Postie

Postie -what you posted makes sense to me too but it looks like Yash14 is using pre-compiled shaders. Regardless, he'll still need to set vars and render using the same technique as your code. Currently he's using Device.SetTexture() which is a fixed function pipeline code. He needs to pass the texture into the shader as a varable. The code he posted is both a Progammable Pipeline and a Fixed Function Pipeleine.


Yeah, it seemed like he was mixing shaders and the fixed function pipeline. I haven't used pre-compiled shaders myself, so that didn't make sense to me. Though I noted that the link you mentioned earlier is a link to a SlimDX tutorial for DirectX11, and he's trying to use DX9 (from his inclusion of "using SlimDX.Direct3D9"), so I didn't know if the bytecode stuff was how you handle shaders under dx11 and wouldn't work correctly with dx9, but I haven't used dx11 yet, so I wasn't sure and decided to post what I knew works for me.
[size="2"]Currently working on an open world survival RPG - For info check out my Development blog:[size="2"] ByteWrangler

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.