Pixel Shader Giving Black output
- by Yashwinder
I am coding in C# using Windows Forms and the SlimDX API to show the effect of a pixel shader. When I am setting the pixel shader, I am getting a black output screen but if I am not using the pixel shader then I am getting my image rendered on the screen. I have the following C# code
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;
}
}
}
And my pixel shader and vertex shader code are as following
// 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
}
// 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
}