ASP.NET
  Home arrow ASP.NET arrow Page 6 - 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+ - Drawing Primitives and Texture


    (Page 6 of 14 )

    You’re ready to start working now: You know what adapters and devices are, you understand what display modes are, you know the basic Direct3D program structure, and you know all you need to know (for now) about projections, cameras, and transformations. The stage is all ready for the play. All you need now is to meet the actors: the drawing primitives.

    Drawing primitives, or 3-D primitives, are vertex collections that define single 3-D objects. Direct3D uses the simplest polygon—a triangle—as a base to create all other 3-D objects. This is done because a primitive defined with only three points is guaranteed to be in a single plane and to be convex, and these characteristics are the key to performing the fastest rendering possible.

    So, for example, if you want to draw a square on screen, you’ll have to use two triangles. If you want to create a cube, you’ll use 12 triangles (2 for each facet), as shown in Figure 3-10.


    Figure 3-10.  A cube made with triangles

    Along with triangles, Direct3D allows you to define lists of lines and lists of points, which are useful mainly for debugging purposes in that they help you to see the wireframe image for your objects and check the hidden surfaces when you use triangles.

    The steps for creating a simple set of triangles in Direct3D are as follows:

    1. Create a vertex buffer.

    2. Fill the buffer with each of the vertices of the object, according to the defined vertex type.

    3. Draw the buffer on the device, using the desired primitive type.

    You can see an example of this simple set of steps in tutorial #2 in the DirectX SDK (“Rendering Vertices”). For now, let’s just consider that all the vertices are defined only by x, y, and z coordinates (you’ll see more details about this later), so you can concentrate on the drawing primitive types.

    A primitive type can be one of the following values of the PrimitiveType enumeration:

    • PointList: Each vertex is rendered isolated from the others, so you can see a list of floating points. Figure 3-11 presents a set of vertices rendered as a point list. 

                  Figure 3-11. Vertices rendered as a point list

    • LineList: The vertices are rendered in pairs, with lines connecting each pair. This call fails if you pass in a vertex buffer with an odd number of vertices. Figure 3-12 illustrates the use of a line list primitive type.



        Figure 3-12.  The same vertices rendered as a line list
    • LineStrip: All the vertices in the buffer are rendered as a single polyline. This is useful when debugging, because this primitive type allows you to see a wireframe image of your objects, regardless of the number of vertices. Figure 3-13 presents a line strip primitive type sample.
        


      Figure 3-13. The same rendered as a line strip           

    • TriangleList: The vertices are rendered in groups of three, as isolated triangles. This provides you the greatest flexibility when rendering complex scenes, but there’s the drawback of having duplicated vertices if you want to draw connected triangles. Figure 3-14 shows the use of the triangle list primitive type to render vertices. 


    Figure 3-14. The same vertices rendered as a triangle list

    • TriangleStrip: You’ll use this primitive type when drawing connected triangles. It’s the usual choice for rendering scenes, because it’s more efficient, since you don’t have to repeat the duplicated vertices. Every new vertex (after the first two) added to the buffer creates a new triangle, using the last two defined vertices. Figure 3-15 presents a triangle strip primitive type example. 

      

    Figure 3-15. A complex polygon created with a triangle strip 

    • TriangleFan: In this primitive, all the triangles share a common vertex— the first one in the buffer—and each new vertex added creates a new triangle, using the first vertex and the last defined one. Figure 3-16 illustrates the last of the primitive types, the triangle fan.  

     

    Figure 3-16.  A triangle fan example 

    Conceptually, everything rendered in the graphics pipeline ultimately is a triangle. Not only that, but the way the triangle is drawn determines which side of the triangle is the front and which is the back. This is particularly important when you begin to add effects such as coloring or texturing to a triangle. Imagine if you had a collection of triangles that represented a sphere. Then imagine you wanted to apply some kind of shaded coloring to the triangle, perhaps as if you were painting the sphere with a shiny color. It wouldn’t make sense to paint the same color on the inside of the sphere, would it? Well, that same concept applies to rendering the triangles. The system removes triangles that aren’t seen in a process called culling. The process of removing triangles that can’t be seen is called back-face culling (because you can’t see the backs of the triangles facing you).

    In DirectX, you actually have control over the culling mode. You could, for instance, tell DirectX to not cull backface triangles. This ability to turn on/off backface culling is important for some applications. To see an example of this, look at example 3 in the DirectX SDK tutorials (“Using Matrices”) and comment out this line:

    dev.RenderState.CullMode = Cull.None;

    You’ll then see that the triangle appears and disappears, because the back-face of the triangle is being culled (DirectX culls back-facing triangles by default).

    When drawing triangles, you also need to take special care about the triangle vertex ordering when you want Direct3D to draw only the front part of a triangle. You must define whether you want the front face to be the clockwise-ordered one or the counterclockwise one; so you must draw all triangles using the same ordering for the vertices.

    Okay, you’re probably thinking, “These primitive types are interesting, but what if I just want to draw a single image, say, a bitmap file on disk, to the screen? Can’t I just draw it directly on screen?”

    The answer is not quite. You can create a square (composed with two triangles) and apply the image on it as a texture. You can even state that a specific color must be treated as transparent, so it appears that you’re dealing with non-rectangular objects. That’s what you’ll see in the next section. However, there is a simpler way to draw a square and put a bitmap in it, using a special Sprite class, which you’ll get a chance to investigate in later chapters.

    Coloring and Texturing with Flexible Vertex Formats

    Direct3D gives you the power to choose how you can define the vertices that will compose your drawing primitives, using the so-called flexible vertex formats (FVF).

    Before creating a vertex buffer (explained in the previous section), you must specify which kind of information each vertex will hold, creating a custom vertex structure and using it when creating a new VertexBuffer object, as presented in the next code sample:

    vertBuffer = new VertexBuffer(typeof(CustomVertex),
       numVerts, device, Usage.WriteOnly, customVertexFlags,
         Pool.Default);

    The parameters for this code line are as follows:

    • CustomVertex is the actual description of your custom vertex buffer, and the typeof keyword passes along the type information about the CustomVertex type. You’ll see what this type looks like shortly.

    • numVerts is the number of vertices you’ll want the buffer to hold.

    • device is the Direct3D reference to the current display device.

    • Usage defines the purpose of the vertex buffer, allowing Direct3D to perform any extra control it needs. You’ll usually use WriteOnly for this, meaning that you’re only writing to the buffer and passing it later to the device, and won’t read from it. This flag allows Direct3D to choose the best memory allocation for fast writing and rendering.

    • customVertexFlags is a collection of flags that describes the type of information contained in the custom vertex structure. These flags are defined in the VertexFormat enumerated type.

    • Pool provides extra information to Direct3D, defining where the resource must be placed (system memory or managed memory, for example). Usually you’ll use the Default enumeration member for this parameter.

    The VertexFormat parameter is a combination of flags that will tell Direct3D what information you’re using in your vertices, allowing you to include special information on how to create lighting effects or texture information on each vertex. Among the many possible values on the VertexFormat enumeration, the ones you’ll be using in this book are as follows:

    • Diffuse: You’ll include information for a diffuse color in the vertex. A diffuse color is the kind of color an object gives when white light shines on it—the kind of color an object would have in “real world” lighting.

    • Position: Your vertex coordinates need transformation (remember the matrices?) from world coordinates to screen coordinates before being displayed. This flag can’t be used with the VertexFormat.Transformed flag.

    • Transformed: Your vertices are already in screen coordinates, so you won’t need any projection information. This enumeration member can’t be combined with the Position one.

    • VertexFormat.Texture0 through VertexFormat.Texture8: Your vertices include from zero to eight different texture coordinates. Texture coordinates are used to tell the rendering engine how to display a texture (instead of a plain color) relative to the vertices. You’ll get a chance to investigate texture coordinates shortly.

    There is one additional technique to note at this point. The best time to create various buffers and objects is just after the DirectX device gets created. Once again, the event handling system of the .NET Framework gives you a convenient event just for this situation, called the DeviceReset event. Every time the DirectX device gets resized or toggled to/from full-screen mode, the device gets reset. When this happens, you need to re-create your vertex buffers. The best way to do this is by registering an event handler for the DeviceReset event like this:

    device.DeviceReset += new System.EventHandler
       (this.OnCreateDevice);

    The following code sample shows a complete example, from defining the vertex structure to creating the vertex buffer. Note that Managed DirectX also contains definitions for many common custom vertex formats. The custom vertex struct that follows, in fact, is defined as CustomVertex.TransformedTextured. You’re going to continue using your own special struct for these examples, so that you can get used to how to manually create custom vertex structures.


    // Your Custom vertex format will need to be transformed,
        and
    // has information about texturing and diffuse colors. private VertexBuffer vertexBuffer;
    private const VertexFormats customVertexFormat =
        VertexFormats.Transformed |
       VertexFormats.Texture1;
    private const int numVerts = 36; //need to hold 36 vertices public struct CustomVertex {
       public float X;
       public float Y;
       public float Z;
       public float rhw;
       public float tu;
       public float tv;
    }

    public void OnCreateDevice(object sender, EventArgs e) {
       Device device = (Device)sender;
       vertexBuffer = new VertexBuffer(typeof(CustomVertex),
        numVerts, device,
          Usage.WriteOnly, customVertexFlags, Pool.Default); 
       vertexBuffer.Created += new System.EventHandler
        (this.OnCreateVertexBuffer); this.OnCreateVertexBuffer(vertexBuffer, null); //force the call
    }

    The color parameter specifies a color for each vertex. The vertex colors generate gradients between each vertex, as shown in the square in Figure 3-17. The upper-left corner will be rendered with blue, the upper-right with red, the lower-left with yellow, and the lower-right with green.


    Figure 3-17.  Applying colors to square vertices

    You must specify the colors through their RGB components using the Color.FromARGB function. The color codes are the same ones defined in the System.Drawing.Color component. You can’t use the old GDI’s RGB function to specify such color, because it’s intrinsically different from the new Color.FromARGB function, and you can have unexpected results, like the blue and red components being inverted.

    Now let’s look at texturing. As you would imagine, texturing is a way of applying an appearance to a polygon, usually by means of a separate image. Two-dimensional textures are generally described in tu and tv coordinates (sometimes you’ll simply see u and v as the coordinate system). All textures have rectangular shapes, and these values range from (0, 0) for the upper-left corner of the texture to (1, 1) for the lower-right corner. The texture is applied to the object according to the values set to all vertices. In Figure 3-18, you see three vertices with valid tu and tv values, the texture loaded, and the result rendered by the device.


    Figure 3-18.  Texture mapping with (tu, tv) pairs of values

    The Device object needs to have the information about which texture it must use for each call of the DrawPrimitives function (explained in the previous section), which will receive the vertex buffer with the vertex and texture coordinates. For this, you must pass a previously loaded texture to the SetTexture method of the device.

    You can load the texture from a file using the FromFile method of the TextureLoader helper object, which can receive different parameters depending on the need of the program. To load opaque textures, it will simply receive the filename and the device to which the texture will be rendered. When calling the method to load transparent textures, the functions receive many other parameters, allowing greater control over the loaded texture, including a color key that will specify the transparent color for the texture loaded.

    You’ll see the details about how to implement texture features on your program in the next sections. In the following section, we’ll outline the proposal for the sample application of this chapter.

    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 3 Hosted by Hostway
    For more Enterprise Application Development news, visit eWeek