ASP.NET
  Home arrow ASP.NET arrow Page 9 - Managed DirectX First Steps: Direct 3D Bas...
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Silverlight  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
ASP Web Hosting  
ASP.NET Web Hosting 
Windows Web Hosting
 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
ASP.NET

Managed DirectX First Steps: Direct 3D Basics and DirectX vs. GDI+
By: Apress Publishing
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 65
    2005-01-26

    Table of Contents:
  • Managed DirectX First Steps: Direct 3D Basics and DirectX vs. GDI+
  • DirectX Overview
  • Referencing DirectX Libraries
  • Put That in Your Pipeline and Shade It
  • 3-D Coordinate Systems and Projections
  • Drawing Primitives and Texture
  • The Application Proposal
  • The Coding Phase
  • Second Step: Coding Your First Windowed Test
  • Code the Render Procedure
  • Fourth Step: Using Transparent Textures
  • Fifth Step: Changing Diffuse Colors
  • Sixth Step: Testing Matrix Transformations
  • Adding the Final Touches

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Managed DirectX First Steps: Direct 3D Basics and DirectX vs. GDI+ - Second Step: Coding Your First Windowed Test


    (Page 9 of 14 )

    This first test is very important, because it will establish the base of all future tests and programs. So you’ll make it very simple: Just initialize the Direct3D, create the device, draw a simple image, and count the frame rate. In order to allow you to see something happening, you’ll load an array of images (loaded as textures) and render them one at a time, over a square (composed of two triangles), so you’ll see the illusion of a walking guy.

    You’ll use the basic Direct3D program structure, explained in the “Creating a Simple Direct3D Program” section, dividing the code into two groups:

    • In your main window (coded in the click event for the corresponding button): The code that simply creates (and destroys) the test window and call to the initialization, finalization, and rendering routines defined in the test window

    • In the test window: All the Direct3D routines—initialization, finalization, and rendering

    The code for the main window, which will be very similar to other tests, is show here:

    using (WindowTest windowTest = new WindowTest()) {
       int desiredFrameRate = 10;
       int lastTick = 0;
       windowTest.Show();
       // Initialize Direct3D and the Device object.
       if(!windowTest.InitD3D(windowTest.Handle)) {   
          MessageBox.Show("Could not initialize Direct3D."); 
          windowTest.Dispose();
          return;
       }
       else {
           // Load the textures and create the square to show
             them.
           if(!windowTest.CreateTextures()) {
              MessageBox.Show("Could not initialize vertices
             and textures.");
              return;
           }
       }
       // Uncomment the lines below to see a smooth walking
           man.
       //desiredFrameRate = 10;
       if(System.Environment.TickCount - lastTick >= 1000 /
           desiredFrameRate) {
         
    windowTest.Render();
          // Frame rate calculation.
          
    windowTest.Text = "Window Test. Frame rate: " +  
             DirectXLists.CalcFrameRate().ToString();
          
    lastTick = System.Environment.TickCount;
        }
        Application.DoEvents();
       
    // If you have no errors, then enter the rendering 
               loop.
       
    while(!windowTest.EndTest) {
            // Uncomment the lines below to see a smooth 
               walking man.
            // Force a Frame rate of 10 frames to second on
          maximum
            //if(System.Environment.TickCount - lastTick >=
              1000 / desiredFrameRate)
    {
           windowTest.Render();
           // Frame rate calculation.
           windowTest.Text = "Window Test. Frame rate: " +
             
    DirectXLists.CalcFrameRate().ToString();
          //lastTick = System.Environment.TickCount;
         //}
         Application.DoEvents();
       }
    }

    In the rendering procedure you use a helper function, CalcFrameRate, that you create in order to make your code cleaner. In this function (shown in the next code listing), you use System.Environment. Tick Count to retrieve the current tick of the processor clock (with the precision rate of about 15 milliseconds), so you can calculate the frame rate. Note that this function isn’t very accurate, but since you’ll only use frame rate calculations to give you an idea of the speed at which you’re drawing the scene, and won’t include it in your final games, we think that using it is a valid approach.

    private static int FrameRate, LastFrameRate, LastTick;
    public static int CalcFrameRate() {
        // Frame rate calculation.
        if(System.Environment.TickCount - LastTick >= 1000) {
           LastFrameRate = FrameRate;
           FrameRate = 0;
           LastTick = System.Environment.TickCount;
        }
        FrameRate++;
        return LastFrameRate;
    }

    Following the sequence of the code just shown, let’s see the initialization routines for the WindowTest class. The InitD3D procedure will create the Direct3D object, define the presentation parameters for the window creation based on the current display mode, and create the Device object. If you don’t understand any part of the following code, refer to the first sections of this chapter for detailed explanations.

    private Device device;
    public bool InitD3D(IntPtr winHandle) {
       DisplayMode dispMode =
          Manager.Adapters[Manager.Adapters.Default. Adapter].
            CurrentDisplayMode;
       PresentParameters presentParams= new PresentParameters
            ();
       // Define the presentation parameters.  
       presentParams.Windowed = true;
       presentParams.SwapEffect = SwapEffect.Discard;  
       presentParams.BackBufferFormat = dispMode.Format;
       // Try to create the device.
    try {
       
    device = new Device(
           Manager.Adapters.Default.Adapter, 
           DeviceType.Hardware,
           winHandle,
           CreateFlags.SoftwareVertexProcessing,
           presentParams);
       device.VertexFormat = customVertexFlags;
       return true;
       }
       catch {
          
    return false;
       }
    }

    The most important part in the preceding code is the definition of the presentation parameters, which will rule the device creation. Let’s analyze this one line at a time.

    In the first line of the code listing, you create the presentation parameters as an object of the PresentParameters type:

     PresentParameters presentParams = new PresentParameters();

    Then you state that you want to run in windowed mode. Because you didn’t specify the window size, the device will use the whole client area of the target window (defined by the handle used when creating Device).

     presentParams.Windowed = true;

    In the next line, you instruct the device to choose the best memory allocation when doing the screen flips, even if your back buffer got discarded. Note that this option doesn’t force the back buffer to be discarded, it just tells the device that you are re-creating the whole scene in the Render procedure, so it doesn’t need to preserve the contents of the back buffer when flipping.

     presentParams.SwapEffect = SwapEffect.Discard;

    The last line specifies the format of your back buffer. Because you’re running in windowed mode, it’s a must for you to use the current display mode format, because the window will be rendered using the same resolution and colors of the rest of the screen.

     presentParams.BackBufferFormat = DispMode.Format;

    The next function, following the main program sequence, is the one that will load the textures from disk and create a square in which to display them. To create such a function, first refer to the flexible vertices format (FVF) definition in the “Coloring and Texturing with Flexible Vertex Formats” section. You see that you’ll need to create a custom vertex type that will hold texture information in addition to the x, y, and z coordinates. And because you don’t want to make any 3-D transformations, you’ll create the vertex with an extra flag (rhw, which stands for “reciprocal of homogeneous w”) that informs the device that the coordinates are already transformed (they are screen coordinates). The definition of your VertexFormat is made using a constant value and creating the corresponding structure.

    // Simple textured vertices constant and structure.
    private const VertexFormats customVertexFlags =
          VertexFormats.Transformed |
            VertexFormats.Texture1;
    private struct CustomVertex {
       public float X;
       public float Y;
       public float Z;
       public float rhw;
       public float tu;
       public float tv;
    }

    In order to help you fill the VertexFormat structure for each new vertex, it’s a good idea to create a helper function that fills the structure members and returns the vertex, as show in the following code snippet:

    private CustomVertex CreateFlexVertex(float X, float Y,
          float Z,
            float rhw, float tu, float tv) {
       CustomVertex cv = new CustomVertex();
      
    cv.X = X;
      
    cv.Y = Y;
       cv.Z = Z;
       cv.rhw = rhw;
       cv.tu = tu;
       cv.tv = tv;
       return cv;
    }

    Now you can start thinking about the CreateTextures routine. Based on the basic concepts shown earlier, you can create a draft for the function as follows:

    1. Define the array of textures (must be public to the form, because it’ll be used in the Render procedure).

    2. Create the textures for each array element.

    3. Create and open the vertex buffer.

    4. Define the vertices.

    5. Close the buffer.

    The textures you’ll be using show a draft of the walking man, and are numbered from walk1.bmp to walk10.bmp, as shown in Figure 3-24.

    The code for the previous steps is shown next.


    NOTE  Notice that you create a separate function to generate the vertices, so the code becomes more readable and more easy to expand with different vertices.


    Figure 3-24.  Walking man textures, from walk1.bmp to walk 10.bmp (courtesy of Igor Sinkovec) 

    private const int numVerts = 4;
    private VertexBuffer vertBuffer = null;
    private Texture[] Textures = new Texture[10];
    public bool CreateTextures() {
       CustomVertex[] verts;
      
    try {
           string textureFile;
           // Load the textures, named from walk1.bmp to
               walk10.bmp.
           for(int i=1; i<=10; i++) {
              
    textureFile = Application.StartupPath
               +@"\walk"+i.ToString() +".bmp";
               textures[i-1] = TextureLoader.FromFile(device,
                 textureFile);
       }
       // Define the vertex buffer to hold your custom   
               vertices.
       vertBuffer = new VertexBuffer(typeof(CustomVertex),
       numVerts, device, Usage.WriteOnly, customVertexFlags,
               Pool.Default);
       // Locks the memory, which will return the array to
               be filled.
       verts = vertBuffer.Lock(0, 0) as CustomVertex[];
       // Defines the vertices.
       SquareVertices(verts);
       // Unlocks the buffer, which saves your vertex
               information to the device.
       vertBuffer.Unlock();
       return true;
    }
    catch {
       return false;
       }
    }
    private void SquareVertices(CustomVertex[] vertices) {
       // Create a square, composed of 2 triangles.
       vertices[0] = CreateFlexVertex(60, 60, 0, 1, 0, 0);  
       vertices[1] = CreateFlexVertex(240, 60, 0, 1, 1, 0);
       vertices[2] = CreateFlexVertex(60, 240, 0, 1, 0, 1);
       vertices[3] = CreateFlexVertex(240, 240, 0, 1, 1, 1);
    }

    This chapter is from Beginning .NET Game Programming in C# by David Weller et. al.(Apress, 2004, ISBN: 1590593197). Check it out at your favorite bookstore today. Buy this book now.

    More ASP.NET Articles
    More By Apress Publishing


     

    ASP.NET ARTICLES

    - Adding Content to a Static ASP.NET Website
    - Building a Static ASP.NET Website in a Basic...
    - Develop Your First ASP.NET Website with Visu...
    - Run ASP.NET in Windows XP Home with Cassini ...
    - How to Test a Web Application
    - How to Add Code and Validation Controls to a...
    - Working in Source and Split Views to Build a...
    - How to Build a Web Form for a One-Page Web A...
    - How to Develop a One-Page Web Application
    - An ASP.NET Web Application in Action
    - Developing ASP.NET Web Applications
    - An Introduction to ASP.NET Web Programming
    - Introduction to the ADO.NET Entity Framework...
    - Completing an In-Text Advertising System und...
    - Programming an In-Text Advertising System un...





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 6 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek