Primitive Types

[Previous] [Next]

The D3DPRIMITIVETYPE enumerated type used by the DrawPrimitive methods lists all the primitives that these methods support. Here's the definition for this type:

 typedef enum _D3DPRIMITIVETYPE {      D3DPT_POINTLIST     = 1,      D3DPT_LINELIST      = 2,      D3DPT_LINESTRIP     = 3,      D3DPT_TRIANGLELIST  = 4,      D3DPT_TRIANGLESTRIP = 5,      D3DPT_TRIANGLEFAN   = 6      D3DPT_FORCE_DWORD   = 0x7fffffff,  } D3DPRIMITIVETYPE; 

These are the members of the D3DPRIMITIVETYPE enumerated type:

  • D3DPT_POINTLIST Causes the DrawPrimitive methods to render the vertices as a collection of isolated points.
  • D3DPT_LINELIST Causes the DrawPrimitive methods to render the vertices as a list of isolated straight-line segments. You must specify an even number of vertices that is greater than or equal to 2.
  • D3DPT_LINESTRIP Causes the DrawPrimitive methods to render the vertices as a single polyline. You must specify at least two vertices.
  • D3DPT_TRIANGLELIST Causes the DrawPrimitive methods to render the vertices as a sequence of isolated triangles. Each group of three vertices defines a separate triangle. You must specify at least three vertices and ensure that the number of vertices is divisible by 3. The winding-order render state defines how backface culling (backface removal) is performed. (We'll discuss backface culling and the winding-order render state later in the chapter.)
  • D3DPT_TRIANGLESTRIP Causes the DrawPrimitive methods to render the vertices as a triangle strip. You must provide at least three vertices. The DrawPrimitive method will take the vertices of even-numbered triangles out of order, to ensure that the triangles are drawn in a clockwise orientation. (For more information, see the section "Culling State" later in the chapter.)
  • D3DPT_TRIANGLEFAN Causes the DrawPrimitive methods to render the vertices as a triangle fan. You must define at least three vertices.
  • D3DPT_FORCE_DWORD Forces this enumerated type into a 32bit type.

The following sections cover each of these primitive types, which you can use to create the 3D content for your applications.

Point Lists

You can use the first primitive type, the point list, to define a collection of vertices that are rendered as isolated points. You can use a point list in a 3D scene to represent objects such as dotted lines.

To create a point list, you need to fill an array of vertices. The code that follows shows an example of how to perform this task. Although I show a simple six-element list, you could use a point list to create a star field if you wanted; of course, your list would need many more points. I tend to create star fields using a texture-wrapped sphere surrounding the 3D world because it allows me to create a number of effects using texture animation.

 const DWORD TOTAL_VERTICES = 6; D3DVERTEX lpVertices[TOTAL_VERTICES];  D3DVECTOR v1(-1, 4, 0); D3DVECTOR v2( 2,-1, 0); D3DVECTOR v3( 1, 3, 0); D3DVECTOR v4(-3,-2, 0); D3DVECTOR v5( 3, 2, 0); D3DVECTOR v6( 2, 1, 0); D3DVECTOR vNormal(0, 0, -1); lpVertices[0] = D3DVERTEX(v1, vNormal, 0, 0); lpVertices[1] = D3DVERTEX(v2, vNormal, 0, 0); lpVertices[2] = D3DVERTEX(v3, vNormal, 0, 0); lpVertices[3] = D3DVERTEX(v4, vNormal, 0, 0); lpVertices[4] = D3DVERTEX(v5, vNormal, 0, 0); lpVertices[5] = D3DVERTEX(v6, vNormal, 0, 0); 

Once you've defined the point list, you can render it by using the IDirect3DDevice7::DrawPrimitive method discussed earlier. The code for rendering the point list follows. As you also learned earlier in the chapter, any call you make to IDirect3DDevice7::DrawPrimitive must occur between calls to IDirect3DDevice7::BeginScene and IDirect3DDevice7::EndScene.

 if (FAILED(lpDirect3DDevice7->BeginScene())) {     // Handle any error here. }  if (FAILED(lpDirect3DDevice7->DrawPrimitive(D3DPT_POINTLIST,     D3DFVF_VERTEX, lpVertices, TOTAL_VERTICES, 0))) {     // Handle any error here. }  if (FAILED(lpDirect3DDevice7->EndScene())) {     // Handle any error here. } 

You can apply materials and textures to a point list, but one tiny pixel on the screen probably won't represent a texture or a material very well. Also, be aware that these points are always 1 pixel in diameter regardless of their distance from the camera. To produce bigger points, you need to use small triangles to represent them. When the rendering is complete, you'll see a scene similar to that shown in Figure 6-2.

Figure 6-2 A rendered point list

Line Lists

You can use the second primitive type, the line list, to define a group of straight-line segments. You can use this type to define groups of simple single-line objects.

To create a line list, simply fill an array of vertices as shown in the next code snippet. Always remember that the amount of vertices defined in a line list must be an even number that is greater than or equal to 2. This example shows the code needed to define three lines:

 const DWORD TOTAL_VERTICES = 6; D3DVERTEX lpVertices[TOTAL_VERTICES];  D3DVECTOR v1(-10, 10, 0); D3DVECTOR v2( -8, -5, 0); D3DVECTOR v3( -4,  3, 0); D3DVECTOR v4(  1, -6, 0); D3DVECTOR v5(  2, -1, 0); D3DVECTOR v6( 12,  9, 0); D3DVECTOR vNormal(0, 0, -1); lpVertices[0] = D3DVERTEX(v1, vNormal, 0, 0); lpVertices[1] = D3DVERTEX(v2, vNormal, 0, 0); lpVertices[2] = D3DVERTEX(v3, vNormal, 0, 0); lpVertices[3] = D3DVERTEX(v4, vNormal, 0, 0); lpVertices[4] = D3DVERTEX(v5, vNormal, 0, 0); lpVertices[5] = D3DVERTEX(v6, vNormal, 0, 0); 

Once you've defined the line list, you can render it by using the IDirect3DDevice7::DrawPrimitive method as you did with the point list. The code for rendering the line list follows. When the rendering is complete, you'll see a scene similar to that shown in Figure 6-3.

 if (FAILED(lpDirect3DDevice7->BeginScene())) {     // Handle any error here. }  if (FAILED(lpDirect3DDevice7->DrawPrimitive(D3DPT_LINELIST,     D3DFVF_VERTEX, lpVertices, TOTAL_VERTICES, 0))) {     // Handle any error here. }  if (FAILED(lpDirect3DDevice7->EndScene())) {     // Handle any error here. } 

Figure 6-3 A rendered line list

As with point lists, you can apply materials and textures to line lists. And like points, which always remain 1 pixel in size, lines are always 1 pixel wide. If you need to render wider lines or if you want the width to vary according to a line's distance from the camera, you should instead use pairs of thin triangles to represent the lines.

Line Strips

You can use the third primitive type, the line strip, to describe a series of connected line segments. You can use line strips to create polygons that are open—in other words, polygons whose last vertex isn't connected to the first vertex with a line segment.

You can create a line strip by filling an array of vertices the same way you did for point and line lists. This next code segment presents an example of how to fill this list:

 const DWORD TOTAL_VERTICES = 5; D3DVERTEX lpVertices[TOTAL_VERTICES];  D3DVECTOR v1(-8, -8, 0); D3DVECTOR v2(-3, -9, 0); D3DVECTOR v3(-1,  0, 0); D3DVECTOR v4( 9, -2, 0); D3DVECTOR v5( 7, -6, 0); D3DVECTOR vNormal(0, 0, -1); lpVertices[0] = D3DVERTEX(v1, vNormal, 0, 0); lpVertices[1] = D3DVERTEX(v2, vNormal, 0, 0); lpVertices[2] = D3DVERTEX(v3, vNormal, 0, 0); lpVertices[3] = D3DVERTEX(v4, vNormal, 0, 0); lpVertices[4] = D3DVERTEX(v5, vNormal, 0, 0); 

Once you've defined the line strip, you can render it by using the IDirect3DDevice7::DrawPrimitive method as you did for the point and line lists. The code to render the line strip follows, and Figure 6-4 shows the line strip produced by this code.

 if (FAILED(lpDirect3DDevice7->BeginScene())) {     // Handle any error here. }  if (FAILED(lpDirect3DDevice7->DrawPrimitive(D3DPT_LINESTRIP,     D3DFVF_VERTEX, lpVertices, TOTAL_VERTICES, 0))) {     // Handle any error here. }  if (FAILED(lpDirect3DDevice7->EndScene())) {     // Handle any error here. } 

Figure 6-4 A rendered line strip

Triangle Lists

You can use the fourth primitive type, the triangle list, to create lists of isolated triangles. Always remember that the number of vertices defined in a triangle list must be divisible by 3. You can use these lists to create objects that are made up of unconnected pieces. A code example that defines a list of two triangles follows:

 const DWORD TOTAL_VERTICES = 6; D3DVERTEX lpVertices[TOTAL_VERTICES];  D3DVECTOR v1(-10, -5, 0); D3DVECTOR v2( -5,  5, 0); D3DVECTOR v3(  0, -5, 0); D3DVECTOR v4(  1, -5, 0); D3DVECTOR v5(  6,  5, 0); D3DVECTOR v6( 11, -5, 0); D3DVECTOR vNormal(0, 0, -1); lpVertices[0] = D3DVERTEX(v1, vNormal, 0, 0); lpVertices[1] = D3DVERTEX(v2, vNormal, 0, 0); lpVertices[2] = D3DVERTEX(v3, vNormal, 0, 0); lpVertices[3] = D3DVERTEX(v4, vNormal, 0, 0); lpVertices[4] = D3DVERTEX(v5, vNormal, 0, 0); lpVertices[5] = D3DVERTEX(v6, vNormal, 0, 0); 

As with the other primitive types, you can render the triangle list by using the IDirect3DDevice7::DrawPrimitive method. The following code shows an example of how to render a triangle list. Figure 6-5 shows the result.

 if (FAILED(lpDirect3DDevice7->BeginScene())) {     // Handle any error here. }  if (FAILED(lpDirect3DDevice7->DrawPrimitive(D3DPT_TRIANGLELIST,     D3DFVF_VERTEX, lpVertices, TOTAL_VERTICES, 0)))  {     // Handle error here. }  if (FAILED(lpDirect3DDevice7->EndScene())) {     // Handle any error here. } 

Figure 6-5 A rendered triangle list

Triangle Strips

You can use the fifth primitive type, the triangle strip, to create a series of connected triangles. When you use connected triangles, the code will have to specify shared vertices only once. For example, you need only six vertices to define the triangle strip illustrated in Figure 6-6, which is composed of four triangles.

click to view at full size.

Figure 6-6 A triangle strip

As Figure 6-6 shows, the first three triangles share v3, two of the triangles share v4, and so on. By default, Direct3D culls triangles that are specified in counterclockwise order. Therefore, when rendering triangle strips, Direct3D reads the vertices out of order for every even triangle in the strip. To render the triangle strip in Figure 6-6, Direct3D reads vertices from the vertex list as follows: v1, v2, and v3 for the first triangle; v2, v4, and v3 for the second triangle; v3, v4, and v5 for the third triangle; v4, v6, and v5 for the fourth triangle; and so on. That way, the front side of the strip is always shown when it faces the camera, and the back side of the strip is always culled.

Triangle strips make efficient use of memory and processing time, so it's a good idea to use them whenever possible. The following code segment produces the triangle strip illustrated in Figure 6-6 by filling an array of vertices, just as you did with the other primitive types:

 const DWORD TOTAL_VERTICES=6; D3DVERTEX lpVertices[TOTAL_VERTICES];  D3DVECTOR v1(-10, -5, 0); D3DVECTOR v2( -5,  7, 0); D3DVECTOR v3(  0, -1, 0); D3DVECTOR v4(  6,  4, 0); D3DVECTOR v5( 11, -7, 0); D3DVECTOR v6(  9,  9, 0); D3DVECTOR vNormal(0, 0, -1); lpVertices[0] = D3DVERTEX(v1, vNormal, 0, 0); lpVertices[1] = D3DVERTEX(v2, vNormal, 0, 0); lpVertices[2] = D3DVERTEX(v3, vNormal, 0, 0); lpVertices[3] = D3DVERTEX(v4, vNormal, 0, 0); lpVertices[4] = D3DVERTEX(v5, vNormal, 0, 0); lpVertices[5] = D3DVERTEX(v6, vNormal, 0, 0); 

This next code snippet shows how to render a triangle strip by using the IDirect3DDevice7::DrawPrimitive method, just as you've done with all the other primitive types. Figure 6-7 illustrates the rendered strip.

 if (FAILED(lpDirect3DDevice7->BeginScene())) {     // Handle any error here. }  if (FAILED(lpDirect3DDevice7->DrawPrimitive(D3DPT_TRIANGLESTRIP,     D3DFVF_VERTEX, lpVertices, TOTAL_VERTICES, 0))) {     // Handle error here. }  if (FAILED(lpDirect3DDevice7->EndScene())) {     // Handle any error here. } 

Figure 6-7 The rendered triangle strip

Triangle Fans

The sixth primitive type, the triangle fan, is a lot like a triangle strip. The difference is that all the triangles share one vertex, as Figure 6-8 shows.

Figure 6-8 A triangle fan

Here's an example of the code needed to fill an array that defines a triangle fan:

 const DWORD TOTAL_VERTICES = 6; D3DVERTEX lpVertices[TOTAL_VERTICES];  D3DVECTOR v1( -3,  0, 0); D3DVECTOR v2(  1,  4, 0); D3DVECTOR v3(1.5,  3, 0); D3DVECTOR v4(  2,  1, 0); D3DVECTOR v5(  2, -1, 0); D3DVECTOR v6(1.5, -3, 0); D3DVECTOR v7(  1, -4, 0); D3DVECTOR vNormal(0, 0, -1); lpVertices[0] = D3DVERTEX(v1, vNormal, 0, 0); lpVertices[1] = D3DVERTEX(v2, vNormal, 0, 0); lpVertices[2] = D3DVERTEX(v3, vNormal, 0, 0); lpVertices[3] = D3DVERTEX(v4, vNormal, 0, 0); lpVertices[4] = D3DVERTEX(v5, vNormal, 0, 0); lpVertices[5] = D3DVERTEX(v6, vNormal, 0, 0); lpVertices[6] = D3DVERTEX(v7, vNormal, 0, 0); 

The code can then render the triangle fan by using the IDirect3DDevice3::DrawPrimitive method you've been using, specifying D3DPT_TRIANGLEFAN as the first parameter. Figure 6-9 shows the rendered triangle fan.

 if (FAILED(lpDirect3DDevice7->BeginScene())) {     // Handle any error here. }  if (FAILED(lpDirect3DDevice3->DrawPrimitive(D3DPT_TRIANGLEFAN,     D3DFVF_VERTEX, lpVertices, TOTAL_VERTICES, 0))) {     // Handle any error here. }    if (FAILED(lpDirect3DDevice7->EndScene())) {     // Handle any error here. } 

Figure 6-9 A rendered triangle fan



Inside Direct3D
Inside Direct3D (Dv-Mps Inside)
ISBN: 0735606137
EAN: 2147483647
Year: 1999
Pages: 131

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net