XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   July 19: Series4 - 2 Pass Renderstates
My Book: Out Now!
      
       Go to section on this site

Additional info


Latest Forum posts

 WinForm not found
  Posted by: riemer
  When: 20/07/2008 at 14:30:03

 Bounding Boxes for Maya Data
  Posted by: riemer
  When: 20/07/2008 at 14:27:31

 QuadTree
  Posted by: riemer
  When: 20/07/2008 at 14:23:48

 Bounding Boxes for Maya Data
  Posted by: vijay
  When: 20/07/2008 at 12:25:40

 Error on compiling
  Posted by: libia
  When: 20/07/2008 at 02:36:16

 Terrain From RAW
  Posted by: reiko
  When: 19/07/2008 at 20:36:39

 WinForm not found
  Posted by: kapil.rajak
  When: 19/07/2008 at 16:24:52

 human skin colors
  Posted by: aguacate
  When: 19/07/2008 at 13:34:55

 Bounding Boxes for Maya Data
  Posted by: Archenon
  When: 19/07/2008 at 09:19:16

 Volunteer to write VB.net tutorial
  Posted by: riemer
  When: 19/07/2008 at 07:00:19


Ads

Creating our first light

This chapter we’ll create a point light. This is a point in 3D space, that shines light in every direction. Every object is lit by an amount of light, which is the dot product between that object’s normal and the direction of the incoming light. If you want a picture to illustrate this, have a look at ‘DirectX light basics’ in Series 1.

At this moment we have normal data included in our vertex stream, so we can go straight to the HLSL code. First, let’s have a look at how we can light our quads:



In the left quad, the dot product for every vertex is calculated by the vertex shader. Imagine our light is exactly above the center of the quad. In that case, the angle between the direction (the thin blue lines) of the light and the plane is 45 degrees in every vertex. In that case, the dot product between this light direction and the normal is 0.5 for all four vertices. So 0.5 would be the output of the vertex shader for each of the 4 vertices.

Now the interpolator comes into play. For each pixel of our quad, it interpolates this value, and sends the interpolated value to the pixel shader. In this case, it’s very easy: the interpolated value is 0.5 for each pixel! This means it will seem as if every pixel in our quad is lit the same way, which is wrong.

The right quad illustrates what should happen. For each pixel, the dot product has to be calculated separately: each pixel will get its correct value. For example, the corner points will still get value 0.5, whereas the pixel exactly below the light will get value 1.0, as the direction of the normal is exactly the same as the direction of the light.

So now you’re completely convinced the pixel shader is the way to go, let’s start by creating a method that calculates the dot product, if you give it the 3D position of the light, the 3D position of the pixel and the normal in that pixel:

float DotProduct(float4 LightPos, float3 Pos3D, float3 Normal)
{
    float3 LightDir = normalize(LightPos - Pos3D);
    return dot(LightDir, Normal);
}

First the direction of the light is calculated, this is the vector between the 3D position of the light and the 3D position of the pixel. Then we calculate the dot product between this light direction and the normal in the pixel, which is what the method returns.

When you try to compile this code, FX Composer will warn you that the HLSL normalize method will only work in Pixel Shader version 2.0 code. So let’s hope your card supports HLSL 2.0 code (if it doesn’t, you can always code your own normalization method) and change your technique definition like this:

technique Simplest
{
    pass Pass0
    {
        VertexShader = compile vs_2_0 SimplestVertexShader();
        PixelShader = compile ps_2_0 OurFirstPixelShader();
    }
}

We will call the DotProduct from within our pixel shader, as discussed above. You can see this method requires the 3D position as well as the normal to be available to the pixel shader, so we need to update our VertexToPixel structure:

struct VertexToPixel
{
    float4 Position     : POSITION;    
    float2 TexCoords    : TEXCOORD0;
    float3 Normal        : TEXCOORD1;
    float3 Position3D    : TEXCOORD2;
};

Once again, we’re using the TEXCOORDn semantic to pass floatn values from our vertex shader to our pixel shader. Now it’s time to fill these values in the vertex shader, so add these lines to your vertex shader:

Output.Normal = mul(inNormal, xRot);
Output.Position3D = inPos;

I guess the second line requires no explanation, as the 3D position of the vertices is passed straight on to the interpolator, which interpolates the 3D position for each pixel.

The normal, however, needs some more explanation. Think of our meshes: they contain normal data. However, before we actually draw the meshes, we have rotated them and translated them. This means we also need to rotate the normals (try to think why we mustn’t also translate them), so we multiply them by the xRot matrix, which we will fill in our DirectX app. Remember, to do so, you need to first declare this variable in your HLSL file:

float4x4 xRot;
float xLightPower;

We’ll be using the second line to control the power of our light. Let’s not forget to fill those later on in this chapter. First let’s move on to our pixel shader. This is the contents of the PSIn structure your pixel shader receives from the interpolator:

  • PSIn.Position : the 2D position of the current pixel in screen coordinates; remember our pixel shader can NOT use this
  • PSIn.TexCoords : the 2D coordinates indicating the position in the texture image that has to be sampled from
  • PSIn.Normal : the direction of the normal in the current pixel
  • PSIn.Position3D : the 3D coordinate of the current pixel

    It’s time to start updating our pixel shader. These should be your first 2 lines:

    PixelToFrame Output = (PixelToFrame)0;

    float DiffuseLightingFactor = DotProduct(xLightPos, PSIn.Position3D, PSIn.Normal);

    The new line calls our DotProduct method for the current pixel. As a result, we obtain a value which indicates the amount of light that is caught, and thus reflected by the object the current pixel represents. Because the result of a dot product is always within the [-1, 1] range, we can safely multiply this with the color:

    Output.Color = tex2D(ColoredTextureSampler, PSIn.TexCoords)*DiffuseLightingFactor*xLightPower;

    So the original color of the pixel is multiplied by this dot product, as well as by a factor xLightPower we can set from within our DirectX app.

    That’s it for the HLSL code! When you hit Ctrl+S, you shouldn’t get any errors. Of course we still have to set all the xSomething variables from within DirectX. So go to your DirectX code, and put these additional lines at the beginning of your OnPaint method:

     effect.SetValue("xLightPos", new Vector4(10,0,4,1));
     effect.SetValue("xLightPower", 2.0f);

    At the end of the chapter, try changing these values to see what they do. Next, we need to update the xRot value for every object we draw using our technique:

     effect.SetValue("xWorldViewProjection", Matrix.Identity * matView * matProjection);
     effect.SetValue("xRot", Matrix.Identity);
     device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 16);
     
     Matrix LamppostWorld = Matrix.Scaling(0.05f, 0.05f, 0.05f) * Matrix.RotationX((float)Math.PI / 2) * Matrix.Translation(-4.0f, 5, 1);
     effect.SetValue("xWorldViewProjection", LamppostWorld * matView * matProjection);
     effect.SetValue("xRot", Matrix.RotationX((float)Math.PI / 2));
     DrawMesh(Lamppost, LamppostMaterials, LamppostTextures);
     
     LamppostWorld = Matrix.Scaling(0.05f, 0.05f, 0.05f) * Matrix.RotationX((float)Math.PI / 2) * Matrix.Translation(-4.0f, 35, 1);
     effect.SetValue("xWorldViewProjection", LamppostWorld * matView * matProjection);
     effect.SetValue("xRot", Matrix.RotationX((float)Math.PI / 2));
     DrawMesh(Lamppost, LamppostMaterials, LamppostTextures);
     
     Matrix CarWorld = Matrix.Scaling(4f, 4f, 4f) * Matrix.RotationYawPitchRoll((float)Math.PI / 2, (float)Math.PI / 2, (float)Math.PI / 2) * Matrix.Translation(3, 15, 0f);
     effect.SetValue("xWorldViewProjection", CarWorld * matView * matProjection);
     effect.SetValue("xRot", Matrix.RotationYawPitchRoll((float)Math.PI / 2, (float)Math.PI / 2, (float)Math.PI / 2) * Matrix.Translation(3, 15, 0f));
     DrawMesh(Car, CarMaterials, CarTextures);
     
     CarWorld = Matrix.Scaling(4f, 4f, 4f) * Matrix.RotationYawPitchRoll((float)Math.PI / 2, (float)Math.PI / 8, (float)Math.PI / 2) * Matrix.Translation(28, -1.9f, 0f);
     effect.SetValue("xWorldViewProjection", CarWorld * matView * matProjection);
     effect.SetValue("xRot", Matrix.RotationYawPitchRoll((float)Math.PI / 2, (float)Math.PI / 2, (float)Math.PI / 2) * Matrix.Translation(3, 15, 0f));
     DrawMesh(Car, CarMaterials, CarTextures);

    Now when you run this code, you should see the image below. Can you see where the light is positioned ?




    DirectX Tutorial 10 - The first light

    If you appreciate the amount of time I spend creating and updating
    these pages, feel free to donate -- any amount is welcome !



    Click here to go to the forum on this chapter!

    Or click on one of the topics on this chapter to go there:
  • FX Composer - Gone?
          Hi, I went to the ATI web site to download the ...
  • A normal problem
          Have been playing around with the code in these tu...
  • A normal problem
          Have been playing around with the code in these tu...


    So now we have the basics of lighting in our HLSL code, what’s next? This is where things get interesting: we’ll be starting our shadowing code.

    Our HLSL code:

    struct VertexToPixel
    {
        float4 Position     : POSITION;    
        float2 TexCoords    : TEXCOORD0;

         float3 Normal        : TEXCOORD1;
         float3 Position3D    : TEXCOORD2;

    };

    struct PixelToFrame
    {
        float4 Color : COLOR0;
    };

    float4x4 xWorldViewProjection;

     float4x4 xRot;
     float4 xLightPos;
     float xLightPower;


    Texture xColoredTexture;

    sampler ColoredTextureSampler = sampler_state { texture = <xColoredTexture> ; magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};

     VertexToPixel SimplestVertexShader( float4 inPos : POSITION, float2 inTexCoords : TEXCOORD0, float3 inNormal : NORMAL)

    {
        VertexToPixel Output = (VertexToPixel)0;
        
        Output.Position = mul(inPos, xWorldViewProjection);
        Output.TexCoords = inTexCoords;

         Output.Normal = mul(inNormal, xRot);
         Output.Position3D = inPos;

        
        return Output;    
    }


     float DotProduct(float4 LightPos, float3 Pos3D, float3 Normal)
     {
         float3 LightDir = normalize(LightPos - Pos3D);
         return dot(LightDir, Normal);
     }


    PixelToFrame OurFirstPixelShader(VertexToPixel PSIn)
    {
        PixelToFrame Output = (PixelToFrame)0;


         float DiffuseLightingFactor = DotProduct(xLightPos, PSIn.Position3D, PSIn.Normal);
         Output.Color = tex2D(ColoredTextureSampler, PSIn.TexCoords)*DiffuseLightingFactor*xLightPower;


        return Output;
    }

    technique Simplest
    {
        pass Pass0
        {

             VertexShader = compile vs_2_0 SimplestVertexShader();
             PixelShader = compile ps_2_0 OurFirstPixelShader();

        }
    }

    And the DirectX code:

     using System;
     using System.Drawing;
     using System.Collections;
     using System.ComponentModel;
     using System.Windows.Forms;
     using System.Data;
     using Microsoft.DirectX;
     using Microsoft.DirectX.Direct3D;
     using D3D = Microsoft.DirectX.Direct3D;
     
     namespace DirectX_Tutorial
     {
         struct myownvertexformat
         {
             public Vector3 Pos;
             public Vector3 Normal;
             public Vector2 TexCoord;
     
             public myownvertexformat(Vector3 _Pos, Vector3 _Normal, float texx, float texy)
             {
                 Pos = _Pos;
                 Normal = _Normal;
                 TexCoord.X = texx;
                 TexCoord.Y = texy;
             }
         }
     
         public class WinForm : System.Windows.Forms.Form
         {        
             private System.ComponentModel.Container components = null;
             private D3D.Device device;        
             private VertexBuffer vb;
             private Vector3 CameraPos;
             private VertexDeclaration vd;
             private Effect effect;
     
             private Texture StreetTexture;
             private Mesh Lamppost;
             private Material[] LamppostMaterials;
             private Texture[] LamppostTextures;
             private Mesh Car;
             private Material[] CarMaterials;
             private Texture[] CarTextures;
     
             private Matrix matView;
             private Matrix matProjection;
     
             private int LastTickCount = 1;
             private int Frames = 0;
             private float LastFrameRate = 0;
             private D3D.Font text;
     
             public WinForm()
             {
                 InitializeComponent();
                 this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
             }
     
             public void InitializeDevice()
             {
                 PresentParameters presentParams = new PresentParameters();
                 presentParams.Windowed = true;
                 presentParams.SwapEffect = SwapEffect.Discard;
                 presentParams.AutoDepthStencilFormat = DepthFormat.D16;
                 presentParams.EnableAutoDepthStencil = true;
     
                 Caps DevCaps = D3D.Manager.GetDeviceCaps(0, D3D.DeviceType.Hardware);
                 D3D.DeviceType DevType = D3D.DeviceType.Reference;
                 CreateFlags DevFlags = CreateFlags.SoftwareVertexProcessing;
                 if ((DevCaps.VertexShaderVersion >= new Version(2, 0)) && (DevCaps.PixelShaderVersion >= new Version(2, 0)))
                 {
                     DevType = D3D.DeviceType.Hardware;                
                     if (DevCaps.DeviceCaps.SupportsHardwareTransformAndLight)
                     {
                         DevFlags = CreateFlags.HardwareVertexProcessing;
                         if (DevCaps.DeviceCaps.SupportsPureDevice)
                         {
                             DevFlags |= CreateFlags.PureDevice;
                         }
                     }                
                 }
     
                 device = new D3D.Device(0, DevType, this, DevFlags, presentParams);
                 device.DeviceReset += new EventHandler(this.HandleDeviceReset);            
             }
     
             private void HandleDeviceReset(object sender, EventArgs e)
             {
                 FillResources();        
             }
     
             private void AllocateResources()
             {
                 vb = new VertexBuffer(typeof(myownvertexformat), 18, device, Usage.WriteOnly, VertexFormats.Position | VertexFormats.Normal | VertexFormats.Texture0, Pool.Managed);                        
                 InitializeFont();
                 effect = D3D.Effect.FromFile(device, @"../../OurHLSLFile.fx", null, null, ShaderFlags.None, null);
             }
     
             private void FillResources()
             {
                 myownvertexformat[] vertices = new myownvertexformat[18];
     
                 vertices[0] = new myownvertexformat(new Vector3(20, -10, 0), new Vector3(0, 0, 1), -0.25f, 25.0f);
                 vertices[1] = new myownvertexformat(new Vector3(20, 100, 0), new Vector3(0, 0, 1), -0.25f, 0.0f);
                 vertices[2] = new myownvertexformat(new Vector3(-2, -10, 0), new Vector3(0, 0, 1), 0.25f, 25.0f);                        
                 vertices[3] = new myownvertexformat(new Vector3(-2, 100, 0), new Vector3(0, 0, 1), 0.25f, 0.0f);
                 vertices[4] = new myownvertexformat(new Vector3(-2, -10, 0), new Vector3(1, 0, 0), 0.25f, 25.0f);                        
                 vertices[5] = new myownvertexformat(new Vector3(-2, 100, 0), new Vector3(1, 0, 0), 0.25f, 0.0f);
                 vertices[6] = new myownvertexformat(new Vector3(-2, -10, 1), new Vector3(1, 0, 0), 0.375f, 25.0f);
                 vertices[7] = new myownvertexformat(new Vector3(-2, 100, 1), new Vector3(1, 0, 0), 0.375f, 0.0f);
                 vertices[8] = new myownvertexformat(new Vector3(-2, -10, 1), new Vector3(0, 0, 1), 0.375f, 25.0f);
                 vertices[9] = new myownvertexformat(new Vector3(-2, 100, 1), new Vector3(0, 0, 1), 0.375f, 0.0f);
                 vertices[10] = new myownvertexformat(new Vector3(-3, -10, 1), new Vector3(0, 0, 1), 0.5f, 25.0f);
                 vertices[11] = new myownvertexformat(new Vector3(-3, 100, 1), new Vector3(0, 0, 1), 0.5f, 0.0f);
                 vertices[12] = new myownvertexformat(new Vector3(-13, -10, 1), new Vector3(0, 0, 1), 0.75f, 25.0f);
                 vertices[13] = new myownvertexformat(new Vector3(-13, 100, 1), new Vector3(0, 0, 1), 0.75f, 0.0f);
                 vertices[14] = new myownvertexformat(new Vector3(-13, -10, 1), new Vector3(1, 0, 0), 0.75f, 25.0f);
                 vertices[15] = new myownvertexformat(new Vector3(-13, 100, 1), new Vector3(1, 0, 0), 0.75f, 0.0f);
                 vertices[16] = new myownvertexformat(new Vector3(-13, -10, 21), new Vector3(1, 0, 0), 1.25f, 25.0f);
                 vertices[17] = new myownvertexformat(new Vector3(-13, 100, 21), new Vector3(1, 0, 0), 1.25f, 0.0f);
                 
                 vb.SetData(vertices, 0, LockFlags.None);
     
                 SetUpCamera();
     
                 VertexElement[] velements = new VertexElement[]
                 {
                     new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
                     new VertexElement(0, 12, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Normal, 0),
                     new VertexElement(0, 24, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
                     VertexElement.VertexDeclarationEnd
                 };
                 vd = new VertexDeclaration(device, velements);
     
                 StreetTexture = TextureLoader.FromFile(device, "streettexture.jpg");
     
                 LoadMesh("lamppost.x", ref Lamppost, ref LamppostMaterials, ref LamppostTextures);
                 LoadMesh("car.x", ref Car, ref CarMaterials, ref CarTextures);
             }
     
             private void InitializeFont()
             {
                 System.Drawing.Font systemfont = new System.Drawing.Font("Arial", 12f, FontStyle.Regular);
                 text = new D3D.Font(device, systemfont);
             }
     
             private void DrawMesh(Mesh mesh, Material[] meshmaterials, Texture[] meshtextures)
             {
                 for (int i = 0; i < meshmaterials.Length; i++)
                 {
                     if (meshtextures.Length > 3) effect.SetValue("xColoredTexture", meshtextures[i]);
                     effect.CommitChanges();
                     mesh.DrawSubset(i);
                 }
             }
     
             protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
             {
                 device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
                 device.BeginScene();
     
                 device.SetStreamSource(0, vb, 0);            
                 device.VertexDeclaration = vd;
                 effect.Technique = "Simplest";            
                 effect.SetValue("xColoredTexture", StreetTexture);
                 effect.SetValue("xLightPos", new Vector4(10,0,4,1));
                 effect.SetValue("xLightPower", 2.0f);
                 int numpasses = effect.Begin(0);
                 for (int i = 0; i < numpasses; i++)
                 {
                     effect.BeginPass(i);
     
                     effect.SetValue("xWorldViewProjection", Matrix.Identity * matView * matProjection);
                     effect.SetValue("xRot", Matrix.Identity);
                     effect.CommitChanges();
                     device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 16);                
     
                     Matrix LamppostWorld = Matrix.Scaling(0.05f, 0.05f, 0.05f) * Matrix.RotationX((float)Math.PI / 2) * Matrix.Translation(-4.0f, 5, 1);
                     effect.SetValue("xWorldViewProjection", LamppostWorld * matView * matProjection);
                     effect.SetValue("xRot", Matrix.RotationX((float)Math.PI / 2));
                     DrawMesh(Lamppost, LamppostMaterials, LamppostTextures);
     
                     LamppostWorld = Matrix.Scaling(0.05f, 0.05f, 0.05f) * Matrix.RotationX((float)Math.PI / 2) * Matrix.Translation(-4.0f, 35, 1);
                     effect.SetValue("xWorldViewProjection", LamppostWorld * matView * matProjection);
                     effect.SetValue("xRot", Matrix.RotationX((float)Math.PI / 2));
                     DrawMesh(Lamppost, LamppostMaterials, LamppostTextures);
     
                     Matrix CarWorld = Matrix.Scaling(4f, 4f, 4f) *                 Matrix.RotationYawPitchRoll((float)Math.PI / 2, (float)Math.PI / 2, (float)Math.PI / 2) * Matrix.Translation(3, 15, 0f);
                     effect.SetValue("xWorldViewProjection", CarWorld * matView * matProjection);
                     effect.SetValue("xRot", Matrix.RotationYawPitchRoll((float)Math.PI / 2, (float)Math.PI / 2, (float)Math.PI / 2) * Matrix.Translation(3, 15, 0f));
                     DrawMesh(Car, CarMaterials, CarTextures);
     
                     CarWorld = Matrix.Scaling(4f, 4f, 4f) * Matrix.RotationYawPitchRoll((float)Math.PI / 2, (float)Math.PI / 8, (float)Math.PI / 2) * Matrix.Translation(28, -1.9f, 0f);
                     effect.SetValue("xWorldViewProjection", CarWorld * matView * matProjection);
                     effect.SetValue("xRot", Matrix.RotationYawPitchRoll((float)Math.PI / 2, (float)Math.PI / 2, (float)Math.PI / 2) * Matrix.Translation(3, 15, 0f));
                     DrawMesh(Car, CarMaterials, CarTextures);
     
                     effect.EndPass();
                 }
                 effect.End();
     
                 UpdateFramerate();
     
                 device.EndScene();
                 device.Present();
                 this.Invalidate();    
             }
     
             private void UpdateFramerate()
             {
                 Frames++;
                 if (Math.Abs(Environment.TickCount - LastTickCount) > 1000)
                 {
                     LastFrameRate = (float)Frames * 1000 / Math.Abs(Environment.TickCount - LastTickCount);
                     LastTickCount = Environment.TickCount;
                     Frames = 0;
                 }
                 text.DrawText(null, string.Format("Framerate : {0:0.00} fps", LastFrameRate), new Point(10, 430), Color.Red);
             }
     
             private void SetUpCamera()
             {
                 CameraPos = new Vector3(25, -18, 13);
                 matProjection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 0.3f, 200f);
                 matView = Matrix.LookAtLH(CameraPos, new Vector3(0, 12, 2), new Vector3(0, 0, 1));
             }
     
             private void LoadMesh(string filename, ref Mesh mesh, ref Material[] meshmaterials, ref Texture[] meshtextures)
             {
                 ExtendedMaterial[] materialarray;
                 GraphicsStream adj = null;
     
                 mesh = Mesh.FromFile(filename, MeshFlags.Managed, device, out adj, out materialarray);
     
                 if ((materialarray != null) && (materialarray.Length > 0))
                 {
                     meshmaterials = new Material[materialarray.Length];
                     meshtextures = new Texture[materialarray.Length];
     
                     for (int i = 0; i < materialarray.Length; i++)
                     {
                         meshmaterials[i] = materialarray[i].Material3D;
                         meshmaterials[i].Ambient = meshmaterials[i].Diffuse;
     
                         if ((materialarray[i].TextureFilename != null) && (materialarray[i].TextureFilename != string.Empty))
                         {
                             meshtextures[i] = TextureLoader.FromFile(device, materialarray[i].TextureFilename);
                         }
                     }                
                 }
     
                 mesh = mesh.Clone(mesh.Options.Value, CustomVertex.PositionNormalTextured.Format, device);
                 mesh.ComputeNormals();
             }
     
             protected override void Dispose(bool disposing)
             {
                 if (disposing)
                 {
                     if (components != null)
                     {
                         components.Dispose();
                     }
                 }
                 base.Dispose(disposing);
             }
     
             private void InitializeComponent()
             {
                 this.components = new System.ComponentModel.Container();
                 this.Size = new System.Drawing.Size(500, 500);
                 this.Text = "Riemer's DirectX & HLSL Tutorial using C# -- Season 3";
             }
     
             static void Main()
             {
                 using (WinForm our_directx_form = new WinForm())
                 {
                     our_directx_form.InitializeDevice();                
                     our_directx_form.AllocateResources();
                     our_directx_form.FillResources();
                     Application.Run(our_directx_form);
                 }
             }
         }
     }


    Google
     
    Webwww.riemers.net


    If you appreciate the amount of time I spend creating and updating
    these pages, feel free to donate -- any amount is welcome !



    - Website design & XNA + DirectX code : Riemer Grootjans -
    ©2003 - 2008 Riemer Grootjans
  • Translations

    This site in English
    This site in Korean
    This site in Czech

    Microsoft MVP Award



    2007 - 2008 MVP Award
    DirectX - XNA

    Contents

    News
    Home
    Forum
    XNA 2.0 Recipes Book (8)
    Downloads
    Extra Reading (3)
    Matrices: geometrical
    Matrix Mathematics
    Homogenous matrices
    Tutorials (136)
    XNA 2.0 using C# (65)
    DirectX using C# (54)
    Series 1:Terrain (14)
    Series 2: Flightsim (19)
    Series 3: HLSL (19)
    Starting point
    HLSL Introduction
    Vertex Shader
    Shaded triangle
    Pixel Shader
    Textured Triangle
    Triangle Strip
    World transform
    Adding normals
    The first light
    Shadow mapping
    Render To Texture
    Projective texturing
    The first shadow
    Shaping the light
    Preshaders
    Multiple lights
    Adjusting Z values
    Finishing touch
    Short Tuts (2)
    DirectX using C++ (15)
    DirectX using VB (2)
    -- Expand all --


    Thank you!

    Support this site --
    any amount is welcome !

    Stay up-to-date

    I don't have the time to keep a News section, so stay informed about the updates by clicking on this RSS file!