XNA for C#
DirectX 9 for C#
DirectX 9 for C++
DirectX 9 for VB
Forum
   
My XNA Book
      
       Go to section on this site

Additional info


Latest Forum posts

 No download link for 2d series: shooter
  Posted by: zaboleq
  When: 07/05/2013 at 15:46:28

 Collision Class?
  Posted by: Anonymous
  When: 05/05/2013 at 19:03:59

 stack overflow
  Posted by: cityguy
  When: 07/04/2013 at 01:58:38

 Meshes looks strange.
  Posted by: ab_saratov
  When: 01/04/2013 at 04:31:08

 Lamppost Not loaded
  Posted by: Anonymous
  When: 22/03/2013 at 06:43:52

 Collision Class?
  Posted by: Da_Boom
  When: 21/03/2013 at 01:23:09

 Math boggles me
  Posted by: cityguy
  When: 17/03/2013 at 03:44:48

 Collision Class?
  Posted by: Da_Boom
  When: 16/03/2013 at 03:44:42

 Tree update
  Posted by: Anonymous
  When: 15/03/2013 at 21:11:22

 XNA 4.0
  Posted by: Anonymous
  When: 15/03/2013 at 19:43:57


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:
  • Compilant error for setting normals
          Hi i am going thru your tutorials one after anothe...
  • 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 - 2011 Riemer Grootjans
  • Translations

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

    Microsoft MVP Award



    2007 - 2011 MVP Award
    DirectX - XNA

    Contents

    News
    Home
    Forum
    XNA 2.0 Recipes Book (8)
    Chapter 1
    Chapter 2
    Chapter 3
    Chapter 4
    Chapter 5
    Chapter 6
    Chapter 7
    Chapter 8
    XNA 3.0 Recipes Book (8)
    Chapter 1
    Chapter 2
    Chapter 3
    Chapter 4
    Chapter 5
    Chapter 6
    Chapter 7
    Chapter 8
    Downloads
    Extra Reading (3)
    Matrices: geometrical
    Matrix Mathematics
    Homogenous matrices
    Community Projects (1)
    Team Project (1)
    News
    Tutorials (160)
    XNA 4.0 using C# (89)
    2D Series: Shooters (22)
    Starting a project
    Drawing fullscreen images
    Positioning images
    SpriteBatch.Draw()
    Rotation
    Keyboard input
    Writing text
    Angle to Direction
    Direction to Angle
    Smoke trail
    Manual texture creation
    Random terrain
    Texture to Colors
    Coll Detection Overview
    Coll Detection Matrices
    Putting CD into practice
    Particles
    Additive alpha blending
    Particle engine
    Adding craters
    Sound in XNA
    Resolution independency
    3D Series 1: Terrain (13)
    Starting a project
    The effect file
    The first triangle
    World space
    Rotation - translation
    Indices
    Terrain basics
    Terrain from file
    Keyboard
    Adding colors
    Lighting basics
    Terrain lighting
    VertexBuffer & IndexBuffer
    3D Series 2: Flightsim (14)
    Starting point
    Textures
    Loading the floorplan
    Creating the 3D city
    Loading a Model
    Ambient and diffuse
    Quaternion camera
    Flight kinematics
    Collision detection
    Adding targets
    Point sprites
    Alpha blending
    Skybox
    Camera delay
    3D Series 3: HLSL (18)
    Starting point
    HLSL introduction
    Vertex format
    Vertex shader
    Pixel shader
    Per-pixel colors
    Textured triangle
    Triangle strip
    World transform
    World normals
    Per-pixel lighting
    Shadow map
    Render to texture
    Projective texturing
    Real shadow
    Shaping the light
    Preshaders
    3D Series 4: Adv. terrain (19)
    Starting code
    Mouse camera
    Textured terrain
    Multitexturing
    Adding detail
    Skydome
    The water technique
    Refraction map
    Reflection map
    Perfect mirror
    Ripples
    The Fresnel term
    Moving water
    Specular highlights
    Billboarding
    Region growing
    Billboarding renderstates
    Perlin noise
    Gradient skybox
    Short Tuts (3)
    Run XNA on older pcs
    MessageBox in XNA
    Normal generation
    DirectX using C# (54)
    Series 1:Terrain (14)
    Opening a window
    Linking to the Device
    Drawing a triangle
    Camera
    Rotation - Translation
    Indices
    Terrain creation
    Terrain from file
    DirectInput
    Importing bmp files
    Colored vertices
    DirectX Light basics
    Mesh creation
    Mesh lighting
    Series 2: Flightsim (19)
    Starting code
    Textures
    The floorplan
    Creating the 3D City
    Meshloading from file
    Ambient light
    Action
    Flight kinematics
    Collision detection
    Skybox
    Texture filtering
    Adding targets
    Point sprites
    Alpha blending
    DirectSound
    Sounds in 3D
    Playing MP3 files
    Displaying text
    Going fullscreen
    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)
    Resizing problem
    Checking Device caps
    DirectX using C++ (15)
    Series 1: Terrain (15)
    Opening a window
    Ending the game loop
    Linking to the Device
    Clearing your window
    Drawing a triangle
    Culling
    Camera
    Rotation - Translation
    Indices
    Terrain creation
    Terrain from file
    DirectInput
    Importing .bmp files
    Adding colors
    DirectX Light basics
    DirectX using VB (2)
    Series 1: Intro (2)
    The first triangle
    Rotation - translation
    -- Tree view --


    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!