This page uses frames, but your browser doesn't support them.
DirectX Graphics This section provides information about using the Microsoft®
DirectX® Graphics application programming interfaces (APIs). As with other
components of DirectX, DirectX Graphics can be used with C, C++, and Microsoft
Visual Basic®. For an overview of the organization of the DirectX Graphics
Help, see Error! Bookmark not defined.. Roadmap Information on Microsoft®
DirectX® Graphics is presented in the following sections. What's New in DirectX
Graphics. New features and functionality of this component in DirectX 8.0. If
you've used Microsoft Direct3D® or Microsoft DirectDraw® before, read this
section first, because much has changed since DirectX 7.0. Introduction to
DirectX Graphics. An overview of what DirectX Graphics is and what it can do
for your application, together with a look at some key principles and necessary
background information. Understanding DirectX Graphics. A deeper look at the
underlying structure. This section won't teach you how to implement vertex
lighting or texture mapping in your application, but it will help you
understand the mechanics of the API when you get into the details. Using
DirectX Graphics. A guide to using the API. You'll probably want to familiarize
yourself with the table of contents for this section and then refer to parts of
it as you need specific information. Use it in conjunction with the reference
section. Advanced Topics in DirectX Graphics. Information of interest for
creating applications that take full advantage of the power of DirectX
Graphics. Programming Tips and Tools. Miscellaneous information about
compiling, debugging, and optimizing DirectX Graphics applications. In
addition, this section contains information on issues that may be encountered
when using pre-DirectX 8.0 drivers. [C++] DirectX Graphics C/C++ Tutorials.
Step-by-step implementation of basic functionality. If you learn best by doing,
this is a good place to start. DirectX Graphics C/C++ Samples. A guide to the
sample applications in the SDK to point you to the sample code you need.
Direct3D C/C++ Reference. Detailed information for all the API elements
declared in the Microsoft Direct3D® header files. Direct3DX C/C++ Reference.
Detailed information for all the API elements declared in the Direct3DX utility
library header files. Direct3DX Shader Assemblers Reference. Detailed reference
information on the Direct3DX vertex and pixel shader assemblers. Effect File
Format. Information on the format of effect files, which consist of a set of
parameter declarations, followed by descriptions of various techniques X File
C/C++ Reference. Detailed information for all the API elements declared in
Dxfile.h. X File Format Reference. Detailed information on the DirectX (.x)
file format. [Visual Basic] DirectX Graphics Visual Basic Tutorials.
Step-by-step implementation of basic functionality. If you learn best by doing,
this is a good place to start. DirectX Graphics Visual Basic Samples. A guide
to the sample applications in the SDK to point you to the sample code you need.
Direct3D Visual Basic Reference. Detailed information on the Direct3D® API
elements in the DirectX for Visual Basic type library. Direct3DX Visual Basic
Reference. Detailed information on the Direct3DX API elements in the DirectX
for Visual Basic type library. Direct3DX Shader Assemblers Reference. Detailed
reference information on the Direct3DX vertex and pixel shader assemblers.
Effect File Format. Information on the format of effect files, which consist of
a set of parameter declarations, followed by descriptions of various techniques
X File Visual Basic Reference. Detailed information on the DirectX (.x) API
elements in the DirectX for Visual Basic type library. X File Format Reference.
Detailed information on the .x file format. What's New in DirectX Graphics
Microsoft® DirectX® 8.0 maintains backward compatibility by exposing and
supporting objects and interfaces offered by previous releases of DirectX.
However, many new features and performance enhancements have been added as part
of the DirectX 8.0 new Microsoft Direct3D® API interfaces. Complete integration
of DirectDraw and Direct3D Simplifies application initialization and improves
data allocation and management performance, which reduces the memory footprint.
Also, the integration of the graphics APIs enable parallel vertex input streams
for more flexible rendering. Programmable vertex processing language Enables
you to write custom shaders for morphing and tweening animation, matrix palette
skinning, user-defined lighting models, general environment mapping, procedural
geometry, or any other developer-defined algorithm. Programmable pixel
processing language Enables you to write custom hardware shaders for general
texture combining expressions, per-pixel lighting (bump mapping), per-pixel
environment mapping for photoreal specular effects, or any other
developer-defined algorithm. Multisampling rendering support Enables full-scene
anti-aliasing and multisampling effects, such as motion blur and
depth-of-field. Point sprites Enables high-performance rendering of particle
systems for sparks, explosions, rain, snow, and so on. 3-D volumetric textures
Enables range-attenuation in per-pixel lighting and volumetric atmospheric
effects, and can be applied to more intricate geometry. Higher-order primitive
support Enhances the appearance of 3-D content and facilitates the mapping of
content from major 3-D authoring tools. Higher-level technologies Includes 3-D
content creation tool plug-ins for export to Direct3D of skinned meshes using a
variety of Direct3D techniques, multiresolution level-of-detail (LOD) geometry,
and higher-order surface data. Indexed vertex blending Extends geometry
blending support to allow the matrices used for vertex blending to be referred
to using a matrix index. Expansion of the Direct3DX Utility Library Contains a
wealth of new functionality. The Direct3DX utility library is a helper layer
that sits on top of Direct3D to simplify common tasks encountered by 3-D
graphics developers. Includes a skinning library, support for working with
meshes, and functions to assemble vertex and pixel shaders. Note that the
functionality supplied by D3D_OVERLOADS, first introduced with Microsoft
DirectX? 5.0, has been moved to the Direct3DX utility library. Introduction to
DirectX Graphics This section introduces the Microsoft® DirectX® Graphics APIs,
providing a high- level overview of technology and services. * The Power of
DirectX Graphics * Getting Started with DirectX Graphics The Power of DirectX
Graphics Microsoft® Direct3D® is designed to enable world-class game and
interactive three- dimensional (3-D) graphics on a computer running Microsoft
Windows®. It is a drawing interface that provides device-dependent access to
3-D video-display hardware in a device-independent manner. Direct3D is a
low-level 3-D API that is ideal for developers who need to port games and other
high-performance multimedia applications to the Windows operating system.
Direct3D provides a device-independent way for applications to communicate with
accelerator hardware at a low level. Direct3D is a software interface that
provides direct access to display devices while maintaining compatibility with
the Windows graphics device interface (GDI), providing a device-independent way
for games and Windows subsystem software, such as three-dimensional (3-D)
graphics packages, to gain access to the features of specific display devices.
Direct3D provides excellent game graphics on computers running Windows 95 or
later, or Windows 2000. Some of the advanced features of Direct3D are: *
Switchable depth buffering (using z-buffers or w-buffers). * Flat and Gouraud
shading. * Multiple light sources and types. * Full material and texture
support, including mipmapping. * Robust software emulation drivers. *
Transformation and clipping. * Hardware independence. * Full support on Windows
95, Windows 98, Windows ME, and Windows 2000. * Support for the Intel MMX
architecture, Intel Streaming Single-Instruction, Multiple-Data (SIMD)
Extensions (SSE)®, and AMD's® 3DNow® architecture. * Support for a Hardware
Abstraction Layer (HAL). This provides a consistent interface through which to
work directly with the display hardware, getting maximum performance. * Support
for page flipping with multiple back buffers in full-screen applications. For
more information, see Page Flipping and Back Buffering. * Support for clipping
in windowed or full-screen applications. * Support for 3-D z-buffers. * Access
to image-stretching hardware. * Simultaneous access to standard and enhanced
display-device memory areas. * Other features, including exclusive hardware
access and resolution switching. These features combine to enable you to write
applications that easily outperform standard Windows GDI-based applications and
even MS-DOS applications. The world management of Direct3D is based on
vertices, polygons, and commands that control them. It enables immediate access
to the transformation, lighting, and rasterization 3-D graphics pipeline. If
hardware isn't present to accelerate rendering, Direct3D offers robust software
emulation. Direct3D provides simple and straightforward methods to set up and
render a 3-D scene. The key set of rendering methods is referred to as
DrawPrimitive methods. They enable applications to render one or more objects
in a scene with a single method call. For more information about these methods,
see Rendering Primitives. Direct3D enables a low-overhead connection to 3-D
hardware. This comes at a price, however. You must provide explicit calls for
transformations and lighting, you must provide all the necessary matrices, and
you must determine what kind of hardware is present and its capabilities.
Getting Started with DirectX Graphics This section provides an overview of
graphics programming with Microsoft® Direct3D®. Each concept discussed here
begins with a nontechnical overview, followed by specific information about how
Direct3D supports it. You don't need to be a graphics guru to benefit from this
overview. In fact, if you are one, you might want to skip this section entirely
and move on to the more detailed information in the Using DirectX Graphics
section. When you finish reading these topics, you will have a solid
understanding of basic Direct3D graphics programming concepts. The following
topics are discussed. * 3-D Coordinate Systems and Geometry * Shading
Techniques * Matrices and Transformations * Vectors, Vertices, and Quaternions
* Copying Surfaces * Page Flipping and Back Buffering * Rectangles 3-D
Coordinate Systems and Geometry Programming Microsoft® Direct3D® applications
requires a working familiarity with 3-D geometric principles. This section
introduces the most important geometric concepts for creating 3-D scenes. The
following topics are covered. * 3-D Coordinate Systems * 3-D Primitives *
Triangle Rasterization Rules These topics provide you with a high-level
understanding of the basic concepts employed by a Direct3D application. For
more information about these topics, see Further Information. 3-D Coordinate
Systems Typically 3-D graphics applications use two types of Cartesian
coordinate systems: left-handed and right-handed. In both coordinate systems,
the positive x-axis points to the right, and the positive y-axis points up. You
can remember which direction the positive z-axis points by pointing the fingers
of either your left or right hand in the positive x-direction and curling them
into the positive y-direction. The direction your thumb points, either toward
or away from you, is the direction that the positive z-axis points for that
coordinate system. The following illustration shows these two coordinate
systems. [C++] Microsoft® Direct3D® uses a left-handed coordinate system. If
you are porting an application that is based on a right-handed coordinate
system, you must make two changes to the data passed to Direct3D. * Flip the
order of triangle vertices so that the system traverses them clockwise from the
front. In other words, if the vertices are v0, v1, v2, pass them to Direct3D as
v0, v2, v1. * Use the view matrix to scale world space by –1 in the
z-direction. To do this, flip the sign of the _31, _32, _33, and _34 member of
the D3DMATRIX structure that you use for your view matrix. To obtain what
amounts to a right-handed world, use the D3DXMatrixPerspectiveRH and
D3DXMatrixOrthoRH functions to define the projection transform. However, be
careful to use the corresponding D3DXMatrixLookAtRH function, reverse the
backface-culling order, and lay out the cube maps accordingly. [Visual Basic]
Microsoft® Direct3D® uses a left-handed coordinate system. If you are porting
an application that is based on a right-handed coordinate system, you must make
two changes to the data passed to Direct3D. * Flip the order of triangle
vertices so that the system traverses them clockwise from the front. In other
words, if the vertices are v0, v1, v2, pass them to Direct3D as v0, v2, v1. *
Use the view matrix to scale world space by –1 in the z-direction. To do this,
flip the sign of the _31, _32, _33, and _34 member of the D3DMATRIX type that
you use for your view matrix. To obtain what amounts to a right-handed world,
use the D3DXMatrixPerspectiveRH and D3DXMatrixOrthoRH functions to define the
projection transform. However, be careful to use the corresponding
D3DXMatrixLookAtRH function, reverse the backface-culling order, and lay out
the cube maps accordingly. Although left-handed and right-handed coordinates
are the most common systems, there is a variety of other coordinate systems
used in 3-D software. For example, it is not unusual for 3-D modeling
applications to use a coordinate system in which the y- axis points toward or
away from the viewer, and the z-axis points up. In this case, right-handedness
is defined as any positive axis (x, y, or z) pointing toward the viewer.
Left-handedness is defined as any positive axis (x, y, or z) pointing away from
the viewer. If you are porting a left-handed modeling application where the z-
axis points up, you must do a rotation on all the vertex data in addition to
the previous steps. The essential operations performed on objects defined in a
3-D coordinate system are translation, rotation, and scaling. You can combine
these basic transformations to create a transform matrix. For details, see 3-D
Transformations. When you combine these operations, the results are not
commutative—the order in which you multiply matrices is important. 3-D
Primitives A 3-D primitive is a collection of vertices that form a single 3-D
entity. The simplest primitive is a collection of points in a 3-D coordinate
system, which is called a point list. Often, 3-D primitives are polygons. A
polygon is a closed 3-D figure delineated by at least three vertices. The
simplest polygon is a triangle. Microsoft® Direct3D® uses triangles to compose
most of its polygons because all three vertices in a triangle are guaranteed to
be coplanar. Rendering nonplanar vertices is inefficient. You can combine
triangles to form large, complex polygons and meshes. The following
illustration shows a cube. Two triangles form each face of the cube. The entire
set of triangles forms one cubic primitive. You can apply textures and
materials to the surfaces of primitives to make them appear to be a single
solid form. For details, see Materials and Textures. You can also use triangles
to create primitives whose surfaces appear to be smooth curves. The following
illustration shows how a sphere can be simulated with triangles. After a
material is applied, the sphere looks curved when it is rendered. This is
especially true if you use Gouraud shading. For details, see Gouraud Shading.
Triangle Rasterization Rules Often, the points specified for vertices do not
precisely match the pixels on the screen. When this happens, Microsoft®
Direct3D® applies triangle rasterization rules to decide which pixels apply to
a given triangle. Direct3D uses a top-left filling convention for filling
geometry. This is the same convention that is used for rectangles in GDI and
OpenGL. In Direct3D, the center of the pixel is the decisive point. If the
center is inside a triangle, the pixel is part of the triangle. Pixel centers
are at integer coordinates. This description of triangle-rasterization rules
used by Direct3D does not necessarily apply to all available hardware. Your
testing may uncover minor variations in the implementation of these rules. The
following illustration shows a rectangle whose upper-left corner is at (0, 0)
and whose lower-right corner is at (5, 5). This rectangle fills 25 pixels, just
as you would expect. The width of the rectangle is defined as right minus left.
The height is defined as bottom minus top. In the top-left filling convention,
top refers to the vertical location of horizontal spans, and left refers to the
horizontal location of pixels within a span. An edge cannot be a top edge
unless it is horizontal—in general, most triangles have only left and right
edges. The top-left filling convention determines the action taken by Direct3D
when a triangle passes through the center of a pixel. The following
illustration shows two triangles, one at (0, 0), (5, 0), and (5, 5), and the
other at (0, 5), (0, 0), and (5, 5). The first triangle in this case gets 15
pixels (shown in black), whereas the second gets only 10 pixels (shown in gray)
because the shared edge is the left edge of the first triangle. If you define a
rectangle with its upper-left corner at (0.5, 0.5) and its lower-right corner
at (2.5, 4.5), the center point of this rectangle is at (1.5, 2.5). When the
Direct3D rasterizer tessellates this rectangle, the center of each pixel is
unambiguously inside each of the four triangles, and the top-left filling
convention is not needed. The following illustration shows this. The pixels in
the rectangle are labeled according to the triangle in which Direct3D includes
them. If you move the rectangle in the previous example so that its upper-left
corner is at (1.0, 1.0), its lower-right corner at (3.0, 5.0), and its center
point at (2.0, 3.0), Direct3D applies the top-left filling convention. Most
pixels in this rectangle straddle the border between two or more triangles, as
the next illustration shows. For both rectangles, the same pixels are affected.
Shading Techniques This section describes techniques used in Microsoft®
Direct3D® to control the shading of 3-D polygons. * Shading Modes * Comparing
Shading Modes * Setting the Shading Mode * Face and Vertex Normal Vectors *
Triangle Interpolants Shading Modes The shading mode used to render a polygon
has a profound effect on its appearance. Shading modes determine the intensity
of color and lighting at any point on a polygon face. Microsoft® Direct3D®
supports two shading modes: * Flat Shading * Gouraud Shading Flat Shading In
the flat shading mode, the Direct3D rendering pipeline renders a polygon, using
the color of the polygon material at its first vertex as the color for the
entire polygon. 3-D objects that are rendered with flat shading have visibly
sharp edges between polygons if they are not coplanar. The following figure
shows a teapot rendered with flat shading. The outline of each polygon is
clearly visible. Flat shading is computationally the least expensive form of
shading. Gouraud Shading When Microsoft® Direct3D® renders a polygon using
Gouraud shading, it computes a color for each vertex by using the vertex normal
and lighting parameters. Then, it interpolates the color across the face of the
polygons The interpolation is done linearly. For example, if the red component
of the color of vertex 1 is 0.8 and the red component of vertex 2 is 0.4, using
the Gouraud shading mode and the RGB color model, the Direct3D lighting module
assigns a red component of 0.6 to the pixel at the midpoint of the line between
these vertices. The following figure demonstrates Gouraud shading. This teapot
is composed of many flat, triangular polygons. However, Gouraud shading makes
the surface of the object appear curved and smooth. Gouraud shading can also be
used to display objects with sharp edges. For more information, see Face and
Vertex Normal Vectors. Comparing Shading Modes In flat shading mode, the
pyramid below is displayed with a sharp edge between adjoining faces. In
Gouraud shading mode, however, shading values are interpolated across the edge,
and the final appearance is of a curved surface. Gouraud shading lights flat
surfaces more realistically than flat shading. A face in the flat shading mode
is a uniform color, but Gouraud shading enables light to fall across a face
more correctly. This effect is particularly obvious if there is a nearby point
source. Gouraud shading smoothes the sharp edges between polygons that are
visible with flat shading. However, it can result in Mach bands, which are
bands of color or light that are not smoothly blended across adjacent polygons.
Your application can reduce the appearance of Mach bands by increasing the
number of polygons in an object, increasing screen resolution, or increasing
the color depth of the application. Gouraud shading can miss some details. One
example is the case shown by the following illustration, in which a spotlight
is completely contained within a polygon face. In this case, Gouraud shading,
which interpolates between vertices, would miss the spotlight altogether; the
face would be rendered as though the spotlight did not exist. Setting the
Shading Mode [C++] Microsoft® Direct3D® enables one shading mode to be selected
at a time. By default, Gouraud shading is selected. In C++, you can change the
shading mode by calling the IDirect3DDevice8::SetRenderState method. Set the
State parameter to D3DRS_SHADEMODE. The State parameter must be set to a member
of the D3DSHADEMODE enumeration. The following sample code examples illustrate
how the current shading mode of a Direct3D application can be set to flat or
Gouraud shading mode. // Set to flat shading. // This code example assumes that
pDev is a valid pointer to // an IDirect3DDevice8 interface. hr =
pDev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); if(FAILED(hr)) { // Code
to handle the error goes here. } // Set to Gouraud shading. This is the default
for Direct3D. hr = pDev->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
if(FAILED(hr)) { // Code to handle the error goes here. } [Visual Basic]
Microsoft® Direct3D® enables one shading mode to be selected at a time. By
default, Gouraud shading is selected. In Microsoft Visual Basic®, you can
change the shading mode by calling the Direct3DDevice8.SetRenderState method.
Set the State parameter to D3DRS_SHADEMODE. The State parameter must be set to
a member of the CONST_D3DSHADEMODE enumeration. The following code example
illustrates how the current shading mode of a Direct3D application can be set
to flat or Gouraud shading mode. ' Set to flat shading. ' This code example
assumes that d3dDev is a valid reference to ' a Direct3DDevice8 object. On
Local Error Resume Next Call d3dDev.SetRenderState(D3DRS_SHADEMODE, _
D3DSHADE_FLAT) ' Check for an error. If Err.Number <> D3D_OK Then ' Handle the
error. End If ' Set to Gouraud shading. this is the default for Direct3D. Call
d3dDev.SetRenderState(D3DRS_SHADEMODE, _ D3DSHADE_GOURAUD) If Err.Number <>
D3D_OK Then ' Handle the error. End If Face and Vertex Normal Vectors Each face
in a mesh has a perpendicular normal vector. The vector's direction is
determined by the order in which the vertices are defined and by whether the
coordinate system is right- or left-handed. The face normal points away from
the front side of the face. In Microsoft® Direct3D®, only the front of a face
is visible. A front face is one in which vertices are defined in clockwise
order. Any face that is not a front face is a back face. Direct3D does not
always render back faces; therefore, back faces are said to be culled. You can
change the culling mode to render back faces if you want. See Culling State for
more information. Direct3D applications do not need to specify face normals;
the system calculates them automatically when they are needed. The system uses
face normals in the flat shading mode. In the Gouraud shading mode, Direct3D
uses the vertex normal. It also uses the vertex normal for controlling lighting
and texturing effects. When applying Gouraud shading to a polygon, Direct3D
uses the vertex normals to calculate the angle between the light source and the
surface. It calculates the color and intensity values for the vertices and
interpolates them for every point across all the primitive's surfaces. Direct3D
calculates the light intensity value by using the angle. The greater the angle,
the less light is shining on the surface. If you are creating an object that is
flat, set the vertex normals to point perpendicular to the surface, as shown in
the following illustration. A flat surface composed of two triangles is
defined. It is more likely, however, that your object is made up of triangle
strips and the triangles are not coplanar. One simple way to achieve smooth
shading across all the triangles in the strip is to first calculate the surface
normal vector for each polygonal face with which the vertex is associated. The
vertex normal can be set to make an equal angle with each surface normal.
However, this method might not be efficient enough for complex primitives. This
method is illustrated by the following figure, which shows two surfaces, S1 and
S2 seen edge-on from above. The normal vectors for S1 and S2 are shown in blue.
The vertex normal vector is shown in red. The angle that the vertex normal
vector makes with the surface normal of S1 is the same as the angle between the
vertex normal and the surface normal of S2. When these two surfaces are lit and
shaded with Gouraud shading, the result is a smoothly shaded, smoothly rounded
edge between them. If the vertex normal leans toward one of the faces with
which it is associated, it causes the light intensity to increase or decrease
for points on that surface, depending on the angle it makes with the light
source. An example is shown in the following figure. Again, these surfaces are
seen edge-on. The vertex normal leans toward S1, causing it to have a smaller
angle with the light source than if the vertex normal had equal angles with the
surface normals. You can use Gouraud shading to display some objects in a 3-D
scene with sharp edges. To do so, duplicate the vertex normal vectors at any
intersection of faces where a sharp edge is required, as shown in the following
illustration. If you use the DrawPrimitive methods to render your scene, define
the object with sharp edges as a triangle list, rather than a triangle strip.
When you define an object as a triangle strip, Direct3D treats it as a single
polygon composed of multiple triangular faces. Gouraud shading is applied both
across each face of the polygon and between adjacent faces. The result is an
object that is smoothly shaded from face to face. Because a triangle list is a
polygon composed of a series of disjoint triangular faces, Direct3D applies
Gouraud shading across each face of the polygon. However, it is not applied
from face to face. If two or more triangles of a triangle list are adjacent,
they appear to have a sharp edge between them. Another alternative is to change
to flat shading when rendering objects with sharp edges. This is
computationally the most efficient method, but it may result in objects in the
scene that are not rendered as realistically as the objects that are Gouraud-
shaded. Triangle Interpolants The system interpolates the characteristics of a
triangle's vertices across the triangle when it renders a face. These are the
triangle interpolants: * Color * Specular * Alpha All the triangle interpolants
are modified by the current shading mode, as shown in the following table.
Shading mode Description Flat No interpolation is done. Instead, the color of
the first vertex in the triangle is applied across the entire face. Gouraud
Linear interpolation is performed between all three vertices. The color and
specular interpolants are treated differently, depending on the color model. In
the RGB color model, the system uses the red, green, and blue color components
in the interpolation. In the monochromatic or ramp model, the system uses only
the blue component of the vertex color. The alpha component of a color is
treated as a separate interpolant because device drivers can implement
transparency in two different ways: by using texture blending or by using
stippling. [C++] Use the ShadeCaps member of the D3DCAPS8 structure to
determine what forms of interpolation the current device driver supports.
[Visual Basic] Use the ShadeCaps member of the D3DCAPS8 type to determine what
forms of interpolation the current device driver supports. Matrices and
Transformations Use matrices in Microsoft® Direct3D® to define world, view, and
projection transformations. If you haven't programmed for 3-D graphics before,
this section will help you familiarize yourself with the key concepts you need
to understand in order to get started. If you have prior experience in 3-D
programming, skip this section, or skim the following topics. * Matrices * 3-D
Transformations Matrices [C++] Matrices in Microsoft® Direct3D® are represented
by a 4´4 homogeneous matrix, defined by the D3DMATRIX structure. [Visual Basic]
Matrices in Microsoft® Direct3D® are represented by a 4?4 homogeneous matrix,
defined by the D3DMATRIX type. [C++] The Direct3DX utility library
implementation of the D3DMATRIX structure (D3DXMATRIX) implements a parentheses
("()") operator. This operator offers convenient access to values in the matrix
for C++ programmers. Instead of having to refer to the structure members by
name, you can refer to them by row and column number and index the numbers as
needed. These indices are zero-based, so, for example, the element in the third
row, second column would be M(2, 1). You need a basic knowledge of matrices to
work with Direct3D. For more information, see 3-D Transformations. 3-D
Transformations Microsoft® Direct3D® uses matrices to perform 3-D
transformations. This section explains how matrices create 3-D transformations,
describes some common uses for transformations, and details how you can combine
matrices to produce a single matrix that encompasses multiple transformations.
Information is divided into the following topics. * About 3-D Transformations *
Translation * Rotation * Scaling * Matrix Concatenation For more information
about transformations in Direct3D, see the Direct3D Rendering Pipeline. About
3-D Transformations In applications that work with 3-D graphics, you can use
geometrical transformations to do the following: * Express the location of an
object relative to another object. * Rotate and size objects. * Change viewing
positions, directions, and perspectives. You can transform any point into
another point by using a 4?4 matrix. In the following example, a matrix is
reinterprets the point (x, y, z), producing the new point (x', y', z'). Perform
the following operations on (x, y, z) and the matrix to produce the point (x',
y', z'). The most common transformations are translation, rotation, and
scaling. You can combine the matrices that produce these effects into a single
matrix to calculate several transformations at once. For example, you can build
a single matrix to translate and rotate a series of points. For more
information, see Matrix Concatenation. Matrices are written in row-column
order. A matrix that evenly scales vertices along each axis, known as uniform
scaling, is represented by the following matrix using mathematical notation.
[C++] In C++, Microsoft® Direct3D® declares matrices as a two-dimensional
array, using the D3DMATRIX structure. The following example shows how to
initialize a D3DMATRIX structure to act as a uniform scaling matrix. // In this
example, s is a variable of type float. D3DMATRIX scale = { s, 0.0f, 0.0f,
0.0f, 0.0f, s, 0.0f, 0.0f, 0.0f, 0.0f, s, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f };
[Visual Basic] In Microsoft® Visual Basic®, Microsoft Direct3D® uses matrices
declared as a two- dimensional array, using the D3DMATRIX type. The following
example shows how to initialize a variable of type D3DMATRIX to act as a
uniform scaling matrix. ' In this example, s is a variable of type Single. Dim
ScaleMatrix As D3DMATRIX With ScaleMatrix .m11 = s .m22 = s .m33 = s .m44 = 1
End With Translation The following transformation translates the point (x, y,
z) to a new point (x', y', z'). [C++] You can create a translation matrix by
hand in C++. The following example shows the source code for a function that
creates a matrix to translate vertices. D3DXMATRIX Translate(const float dx,
const float dy, const float dz) { D3DXMATRIX ret; D3DXMatrixIdentity(&ret); //
Implemented by Direct3DX ret(3, 0) = dx; ret(3, 1) = dy; ret(3, 2) = dz; return
ret; } // End of Translate For convenience, the Direct3DX utility library
supplies the D3DXMatrixTranslation function. [Visual Basic] You can create a
translation matrix by hand in Microsoft® Visual Basic®. The following example
shows the source code for a function that creates a matrix to translate
vertices. Sub TranslateMatrix(m As D3DMATRIX, v As D3DVECTOR)
D3DXMatrixIdentity m ' Implemented by Direct3DX. m.m41 = v.x m.m42 = v.y m.m43
= v.z End Sub For convenience, the Direct3DX utility library supplies the
D3DXMatrixTranslation function. Rotation The transformations described here are
for left-handed coordinate systems, and so may be different from transformation
matrices that you have seen elsewhere. For more information, see 3-D Coordinate
Systems. The following transformation rotates the point (x, y, z) around the
x-axis, producing a new point (x', y', z'). The following transformation
rotates the point around the y-axis. The following transformation rotates the
point around the z-axis. In these example matrices, the Greek letter theta (?)
stands for the angle of rotation, in radians. Angles are measured clockwise
when looking along the rotation axis toward the origin. [C++] In a C++
application, use the D3DXMatrixRotationX, D3DXMatrixRotationY, and
D3DXMatrixRotationZ functions supplied by the Direct3DX utility library to
create rotation matrices. The following is the code for the D3DXMatrixRotationX
function. D3DXMATRIX* WINAPI D3DXMatrixRotationX ( D3DXMATRIX *pOut, float
angle ) { #if DBG if(!pOut) return NULL; #endif float sin, cos; sincosf(angle,
&sin, &cos); // Determine sin and cos of angle. pOut->_11 = 1.0f; pOut->_12 =
0.0f; pOut->_13 = 0.0f; pOut->_14 = 0.0f; pOut->_21 = 0.0f; pOut->_22 = cos;
pOut->_23 = sin; pOut->_24 = 0.0f; pOut->_31 = 0.0f; pOut->_32 = -sin;
pOut->_33 = cos; pOut->_34 = 0.0f; pOut->_41 = 0.0f; pOut->_42 = 0.0f;
pOut->_43 = 0.0f; pOut->_44 = 1.0f; return pOut; } [Visual Basic] In a
Microsoft® Visual Basic® application, use the D3DXMatrixRotationX,
D3DXMatrixRotationY, and D3DXMatrixRotationZ functions supplied by the
Direct3DX utility library to create rotation matrices. If you manually create a
matrix for rotation about an axis—in this case, the x-axis— the source code
looks something like the following: Sub CreateXRotation(ret As D3DMATRIX, rads
As Single) Dim cosine As Single Dim sine As Single cosine = Cos(rads) sine =
Sin(rads) D3DXMatrixIdentity ret ' Implemented by Direct3DX. ret.m22 = cosine
ret.m23 = sine ret.m32 = -sine ret.m33 = cosine End Sub Scaling The following
transformation scales the point (x, y, z) by arbitrary values in the x-, y- ,
and z-directions to a new point (x', y', z'). Matrix Concatenation One
advantage of using matrices is that you can combine the effects of two or more
matrices by multiplying them. This means that, to rotate a model and then
translate it to some location, you don't need to apply two matrices. Instead,
you multiply the rotation and translation matrices to produce a composite
matrix that contains all their effects. This process, called matrix
concatenation, can be written with the following formula. In this formula, C is
the composite matrix being created, and M1 through Mn are the individual
transformations that matrix C contains. In most cases, only two or three
matrices are concatenated, but there is no limit. [C++] Use the
D3DXMatrixMultiply function to perform matrix multiplication. [Visual Basic]
Use the D3DXMatrixMultiply function to perform matrix multiplication. The order
in which the matrix multiplication is performed is crucial. The preceding
formula reflects the left-to-right rule of matrix concatenation. That is, the
visible effects of the matrices that you use to create a composite matrix occur
in left-to-right order. A typical world transformation matrix is shown the
following example. Imagine that you are creating the world transformation
matrix for a stereotypical flying saucer. You would probably want to spin the
flying saucer around its center— the y-axis of model space—and translate it to
some other location in your scene. To accomplish this effect, you first create
a rotation matrix, and then multiply it by a translation matrix, as shown in
the following formula. In this formula, Ry is a matrix for rotation about the
y-axis, and Tw is a translation to some position in world coordinates. The
order in which you multiply the matrices is important because, unlike
multiplying two scalar values, matrix multiplication is not commutative.
Multiplying the matrices in the opposite order has the visual effect of
translating the flying saucer to its world space position, and then rotating it
around the world origin. No matter what type of matrix you are creating,
remember the left-to-right rule to ensure that you achieve the expected
effects. Vectors, Vertices, and Quaternions Throughout Microsoft® Direct3D®,
vertices describe position and orientation. Each vertex in a primitive is
described by a vector that gives its position, color, texture coordinates, and
a normal vector that gives its orientation. Quaternions add a fourth element to
the [x, y, z] values that define a three- component-vector. Quaternions are an
alternative to the matrix methods that are typically used for 3-D rotations. A
quaternion represents an axis in 3-D space and a rotation around that axis. For
example, a quaternion might represent a (1,1,2) axis and a rotation of 1
radian. Quaternions carry valuable information, but their true power comes from
the two operations that you can perform on them: composition and interpolation.
Performing composition on quaternions is similar to combining them. The
composition of two quaternions is notated as follows: The composition of two
quaternions applied to a geometry means "rotate the geometry around axis2 by
rotation2, then rotate it around axis1 by rotation1." In this case, Q
represents a rotation around a single axis that is the result of applying q2,
then q1 to the geometry. Using quaternion interpolation, an application can
calculate a smooth and reasonable path from one axis and orientation to
another. Therefore, interpolation between q1 and q2 provides a simple way to
animate from one orientation to another. When you use composition and
interpolation together, they provide you with a simple way to manipulate a
geometry in a manner that appears complex. For example, imagine that you have a
geometry that you want to rotate to a given orientation. You know that you want
to rotate it r2 degrees around axis2, then rotate it r1 degrees around axis1,
but you don't know the final quaternion. By using composition, you could
combine the two rotations on the geometry to get a single quaternion that is
the result. Then, you could interpolate from the original to the composed
quaternion to achieve a smooth transition from one to the other. [C++] The
Direct3DX utility library includes functions that help you work with
quaternions. For example, the D3DXQuaternionRotationAxis function adds a
rotation value to a vector that defines an axis of rotation, and returns the
result in a quaternion defined by a D3DXQUATERNION structure. Additionally, the
D3DXQuaternionMultiply function composes quaternions and the
D3DXQuaternionSlerp performs spherical linear interpolation between two
quaternions. Direct3D applications can use the following functions to simplify
the task of working with quaternions. * D3DXQuaternionBaryCentric *
D3DXQuaternionConjugate * D3DXQuaternionDot * D3DXQuaternionExp *
D3DXQuaternionIdentity * D3DXQuaternionInverse * D3DXQuaternionIsIdentity *
D3DXQuaternionLength * D3DXQuaternionLengthSq * D3DXQuaternionLn *
D3DXQuaternionMultiply * D3DXQuaternionNormalize * D3DXQuaternionRotationAxis *
D3DXQuaternionRotationMatrix * D3DXQuaternionRotationYawPitchRoll *
D3DXQuaternionSlerp * D3DXQuaternionSquad * D3DXQuaternionToAxisAngle Direct3D
applications can use the following functions to simplify the task of working
with three-component-vectors. * D3DXVec3Add * D3DXVec3BaryCentric *
D3DXVec3CatmullRom * D3DXVec3Cross * D3DXVec3Dot * D3DXVec3Hermite *
D3DXVec3Length * D3DXVec3LengthSq * D3DXVec3Lerp * D3DXVec3Maximize *
D3DXVec3Minimize * D3DXVec3Normalize * D3DXVec3Project * D3DXVec3Scale *
D3DXVec3Subtract * D3DXVec3Transform * D3DXVec3TransformCoord *
D3DXVec3TransformNormal * D3DXVec3Unproject Many additional functions that
simplify tasks using two- and four-component-vectors are included among the
math functions supplied by the Direct3DX utility library. [Visual Basic] The
Direct3DX utility library includes functions that help you work with
quaternions. For example, the D3DXQuaternionRotationAxis function adds a
rotation value to a vector that defines an axis of rotation, and returns the
result in a quaternion defined by a D3DQUATERNION type. Additionally, the
D3DXQuaternionMultiply function composes quaternions and the
D3DXQuaternionSlerp performs spherical linear interpolation between two
quaternions. Direct3D applications can use the following functions to simplify
the task of working with quaternions. * D3DXQuaternionBaryCentric *
D3DXQuaternionConjugate * D3DXQuaternionExp * D3DXQuaternionIdentity *
D3DXQuaternionInverse * D3DXQuaternionIsIdentity * D3DXQuaternionLength *
D3DXQuaternionLengthSq * D3DXQuaternionLn * D3DXQuaternionMultiply *
D3DXQuaternionNormalize * D3DXQuaternionRotationAxis *
D3DXQuaternionRotationMatrix * D3DXQuaternionRotationYawPitchRoll *
D3DXQuaternionSlerp * D3DXQuaternionSquad * D3DXQuaternionToAxisAngle Direct3D
applications can use the following functions to simplify the task of working
with three-component-vectors. * D3DXVec3Add * D3DXVec3BaryCentric *
D3DXVec3CatmullRom * D3DXVec3Cross * D3DXVec3Dot * D3DXVec3Hermite *
D3DXVec3Length * D3DXVec3LengthSq * D3DXVec3Lerp * D3DXVec3Maximize *
D3DXVec3Minimize * D3DXVec3Normalize * D3DXVec3Project * D3DXVec3Scale *
D3DXVec3Subtract * D3DXVec3Transform * D3DXVec3TransformCoord *
D3DXVec3TransformNormal * D3DXVec3Unproject Many additional functions that
simplify tasks using two- and four-component-vectors are included with the math
functions supplied by the Direct3DX utility library. Copying Surfaces [C++] The
term blit is shorthand for "bit block transfer," which is the process of
transferring blocks of data from one place in memory to another. The blitting
device driver interface (DDI) continues to be used in Microsoft® DirectX® 8.0
as the primary mechanism for moving large rectangles of pixels on a per-frame
basis, the mechanism behind the copy-oriented IDirect3DDevice8::Present method.
The transportation of artwork in the blit operation is performed by the
IDirect3DDevice8::UpdateTexture method. Artwork can also be copied in DirectX
8.0 by using the IDirect3DDevice8::CopyRects method, which copies a rectangular
subset of pixels. Note DirectX 8.0 provides D3DX functions that enable you to
load artwork from files, apply color conversion, and resize artwork. For more
information on the available functions see Texturing Functions. [Visual Basic]
The term blit is shorthand for "bit block transfer," which is the process of
transferring blocks of data from one place in memory to another. The blitting
device driver interface (DDI) continues to be used in Microsoft® DirectX® 8.0
as the primary mechanism for moving large rectangles of pixels on a per-frame
basis, the mechanism behind the copy-oriented Direct3DDevice8.Present method.
The transportation of artwork in the blit operation is performed by the
Direct3DDevice8.UpdateTexture method. Artwork can also be copied in DirectX 8.0
by using the Direct3DDevice8.CopyRects method, which copies a rectangular
subset of pixels. Note DirectX 8.0 provides D3DX functions that enable you to
load artwork from files, apply color conversion, and resize artwork. For more
information on the available functions see the D3DX8.class and look under
methods for textures. Page Flipping and Back Buffering Page flipping is key in
multimedia, animation, and game software. Software page flipping is analogous
to the way you can do animation with a pad of paper. On each page the artist
changes the figure slightly, so that when you flip rapidly between sheets, the
drawing appears animated. Page flipping in software is very similar to this
process. Microsoft® Direct3D® implements page flipping functionality through a
swap chain which is a property of the device. Initially, you set up a series of
Direct3D buffers that are designed to flip to the screen the way the artist's
paper flips to the next page. The first buffer is referred to as the color
front buffer and the buffers behind it are called back buffers. Your
application writes to a back buffer, and then flips the color front buffer so
that the back buffer appears on screen. While the system displays the image,
your software is again writing to a back buffer. The process continues as long
as you are animating, enabling you to animate images quickly and efficiently.
Direct3D makes it easy to set up page flipping schemes, from a relatively
simple double-buffered scheme—a color front buffer with one back buffer—to more
sophisticated schemes that add additional back buffers. Rectangles Throughout
Microsoft® Direct3D® and Microsoft Windows® programming, objects on the screen
are referred to in terms of bounding rectangles. The sides of a bounding
rectangle are always parallel to the sides of the screen, so the rectangle can
be described by two points, the top-left corner and bottom-right corner. Most
applications use the RECT structure to carry information about a bounding
rectangle to use when blitting to the screen or performing hit detection. [C++]
In C++, the RECT structure has the following definition. typedef struct tagRECT
{ LONG left; // This is the top-left corner x-coordinate. LONG top; // The
top-left corner y-coordinate. LONG right; // The bottom-right corner
x-coordinate. LONG bottom; // The bottom-right corner y-coordinate. } RECT,
*PRECT, NEAR *NPRECT, FAR *LPRECT; [Visual Basic] In Microsoft Visual Basic®,
the RECT type has the following definition. Type RECT Left As Long ' This is
the top-left corner x-coordinate. Top As Long ' The top-left corner
y-coordinate. Right As Long ' The bottom-right corner x-coordinate. Bottom As
Long ' The bottom-right corner y-coordinate. End Type In the preceding example,
the left and top members are the x- and y-coordinates of a bounding rectangle's
top-left corner. Similarly, the right and bottom members make up the
coordinates of the bottom-right corner. The following diagram illustrates how
you can visualize these values. In the interest of efficiency, consistency, and
ease of use, all Direct3D presentation functions work with rectangles.
Understanding DirectX Graphics This section describes the underlying workings
of Microsoft® DirectX® Graphics. * Direct3D Architecture * Direct3D Rendering
Pipeline Direct3D Architecture This section contains general information about
the relationship between the Microsoft® Direct3D® component and the rest of
Microsoft DirectX®, the operating system, and the system hardware. The
following topics are discussed. * Architectural Overview for Direct3D *
Hardware Abstraction Layer * System Integration Architectural Overview for
Direct3D There are two programmable sections of the Microsoft® Direct3D®
architecture: vertex shaders and pixel shaders. Vertex shaders are invoked
prior to vertex assembly and operate on vectors. Pixel shaders are invoked
after any DrawPrimitive calls and operate on pixels. The following simplified
diagram illustrates the Direct3D architecture. It is a subset of the
architecture, as Direct3D supports eight sets of textures and texture
coordinates. As shown in this diagram, vertex buffers stream vertex data into
the vertex shader. The vertex shader performs geometry operations using the
instructions defined by the Direct3DX vertex shader assembler. The data
streamed to the vertex shader does not have to be contained in vertex buffers,
but this is the ideal case. After vertex assembly, the assembled vertex data is
drawn using DrawPrimitive methods. At this point, each pixel of the drawn
primitive is routed to the pixel shader, including its position, color,
texture, and texture coordinate. The pixel shader performs pixel operations
using the instructions defined by the Direct3DX pixel shader assembler. The
inputs to the pixel processing pixel shader stage include texture surfaces and
the associated texture coordinates controlling the sampling of surfaces. The
output pixel is routed to the frame buffer. For more information on the
architecture of the programmable sections of the Direct3D, see Vertex Shader
Architecture and Pixel Shader Architecture. For more information on how vertex
and pixel shaders fit into the rendering pipeline, see the Direct3D Rendering
Pipeline. Vertex Shader Architecture The following diagram illustrates the
vertex shader architecture. The incoming data to the vertex data is taken from
vertex data streams, and the constant data is loaded by the vertex shader
declarator. For details, see the Vertex Shader Assembler Reference. Pixel
Shader Architecture The following diagram illustrates the pixel shader
architecture. The incoming data to the pixel shader is the clip space vertex
(homogeneous coordinates). The diffuse and specular color comes from the values
in the color registers (v0 and v1). The texture coordinates and set textures
come from the values in the texture registers (t0, t1, t2, and t3) from the
texture setup stage and vertex data. For details, see the Pixel Shader
Assembler Reference. Hardware Abstraction Layer Microsoft® Direct3D® provides
device independence through the hardware abstraction layer (HAL). The HAL is a
device-specific interface, provided by the device manufacturer, that Direct3D
uses to work directly with the display hardware. Applications never interact
with the HAL. Rather, with the infrastructure that the HAL provides, Direct3D
exposes a consistent set of interfaces and methods that an application uses to
display graphics. The device manufacturer implements the HAL in a combination
of 16-bit and 32-bit code under Microsoft Windows®. Under Windows NT® and
Windows 2000, the HAL is always implemented in 32-bit code. The HAL can be part
of the display driver or a separate dynamic-link library (DLL) that
communicates with the display driver through a private interface that driver's
creator defines. The Direct3D HAL is implemented by the chip manufacturer,
board producer, or original equipment manufacturer (OEM). The HAL implements
only device- dependent code and performs no emulation. If a function is not
performed by the hardware, the HAL does not report it as a hardware capability.
Additionally, the HAL does not validate parameters; Direct3D does this before
the HAL is invoked. In DirectX 8.0, the HAL can have three different vertex
processing modes: software vertex processing, hardware vertex processing, and
mixed vertex processing on the same device. The pure device mode is a variant
of the HAL device. The pure device type supports hardware vertex processing
only, and allows only a small subset of the device state to be queried by the
application. Additionally, the pure device is available only on adapters that
have a minimum level of capabilities. System Integration The following diagram
shows the relationships between Microsoft® Direct3D®, the graphics device
interface (GDI), the hardware abstraction layer (HAL), and the hardware. As the
preceding diagram shows, Direct3D applications exist alongside GDI applications
and both have access to the graphics hardware through the device driver for the
graphics card. Unlike GDI, Direct3D can take advantage of hardware features
when a HAL device is selected. HAL devices provide hardware acceleration based
on the feature set supported by the graphics card. You are provided with a
Direct3D method to determine at run time if a device is capable of the task.
The software device, although not supporting the entire DirectX 8.0 feature
set, is intended to ensure that applications can always find a working device
on any system. However, in many cases an application running on a software
device must be prepared to run with a downgraded set of functionality. The
capabilities of the software device can be determined in the same fashion as
the capabilities of a hardware device. For more information on devices
supported by Direct3D, see Device Types. Direct3D Rendering Pipeline The
Microsoft® Direct3D® rendering pipeline is a series of processing stages that
specify the behavior of the vertex transform and lighting pipeline, and the
pixel and texture blending pipeline. When you design a 3-D application, you can
define the world in any units you find convenient, from microns to parsecs.
Your application passes a description of that world to Direct3D. This
description includes the sizes and relative positions of all the objects in
your world and the position and orientation of the viewer. Direct3D transforms
these descriptions (vertices) into a series of pixels on the screen. The first
step of this process—the transformation of the geometry that you supply into a
two- dimensional image—is the geometry pipeline, sometimes called the
transformation pipeline. After vertex processing, pixel data is used to perform
multitexturing and fog blending. Then alpha, stencil, and depth tests are
performed. Finally, frame-buffer blending is done by the rasterizer. The
following topics provide a Direct3D-centered approach to the complete rendering
pipeline. The topics introduce key concepts and make parallels from those
concepts to their counterparts in the Direct3D API. The fixed-function
processing section discusses techniques familiar to developers who have used
earlier versions of Microsoft DirectX®, whereas the section on programmable
(procedural) processing explains the new procedural model used for vertex and
pixel processing in Microsoft DirectX 8.0. * Fixed Function Vertex and Pixel
Processing * Programmable Vertex and Pixel Processing * Presenting Vertex Data
to the Vertex Processor Fixed Function Vertex and Pixel Processing The part of
Microsoft® Direct3D® that pushes geometry through the fixed function geometry
pipeline is the transformation engine. It locates the model and viewer in the
world, projects vertices for display on the screen, and clips vertices to the
viewport. The transformation engine also performs lighting computations to
determine diffuse and specular components at each vertex. The geometry pipeline
takes vertices as input. The transformation engine applies three
transformations—the world, view, and projection transformations—to the
vertices, clips the result, and passes everything to the rasterizer. The
following image illustrates the sequence of steps. At the head of the pipeline,
no transformations have been applied, so all of a model's vertices are declared
relative to a local coordinate system—this is a local origin and an
orientation. This orientation of coordinates is often referred to as model
space, and individual coordinates are called model coordinates. The first stage
of the geometry pipeline transforms a model's vertices from their local
coordinate system to a coordinate system that is used by all the objects in a
scene. The process of reorienting the vertices is called the world
transformation. This new orientation is commonly referred to as world space,
and each vertex in world space is declared using world coordinates. In the next
stage, the vertices that describe your 3-D world are oriented with respect to a
camera. That is, your application chooses a point-of-view for the scene, and
world space coordinates are relocated and rotated around the camera's view,
turning world space into camera space. This is the view transformation. The
next stage is the projection transformation. In this part of the pipeline,
objects are usually scaled with relation to their distance from the viewer in
order to give the illusion of depth to a scene; close objects are made to
appear larger than distant objects, and so on. For simplicity, this
documentation refers to the space in which vertices exist after the projection
transformation as projection space. Some graphics books might refer to
projection space as post-perspective homogeneous space. Not all projection
transformations scale the size of objects in a scene. A projection such as this
is sometimes called an affine or orthogonal projection. In the final part of
the pipeline, any vertices that will not be visible on the screen are removed,
so that the rasterizer doesn't take the time to calculate the colors and
shading for something that will never be seen. This process is called clipping.
After clipping, the remaining vertices are scaled according to the viewport
parameters and converted into screen coordinates. The resulting vertices—seen
on the screen when the scene is rasterized—exist in screen space. Information
on the fixed vertex and pixel processing pipeline is organized into the
following topics. * Transformation and Lighting Engine * Viewports and Clipping
* Rasterization Transformation and Lighting Engine The following topics explain
the mechanics behind each component of the fixed function transformation and
lighting engine in detail. * The World Transformation * The View Transformation
* The Projection Transformation * The Lighting Engine * Mathematics of Direct3D
Lighting The World Transformation The discussion of the world transformation
introduces basic concepts and provides details on how to set up a world
transformation matrix in a Microsoft® Direct3D® application. This information
is organized into the following topics. * What Is the World Transformation? *
Setting Up a World Matrix What Is the World Transformation? The world
transformation changes coordinates from model space, where vertices are defined
relative to a model's local origin, to world space, where vertices are defined
relative to an origin common to all the objects in a scene. In essence, the
world transformation places a model into the world; hence its name. The
following diagram illustrates the relationship between the world coordinate
system and a model's local coordinate system. The world transformation can
include any combination of translations, rotations, and scalings. For a
discussion of the mathematics of transformations, see 3-D Transformations.
Setting Up a World Matrix As with any other transformation, you create the
world transformation by concatenating a series of transformation matrices into
a single matrix that contains the sum total of their effects. In the simplest
case, when a model is at the world origin and its local coordinate axes are
oriented the same as world space, the world matrix is the identity matrix. More
commonly, the world matrix is a combination of a translation into world space
and possibly one or more rotations to turn the model as needed. [C++] The
following example, from a fictitious 3-D model class written in C++, uses the
helper functions included in the Direct3DX utility library to create a world
matrix that includes three rotations to orient a model and a translation to
relocate it relative to its position in world space. /* * For the purposes of
this example, the following variables * are assumed to be valid and
initialized. * * The m_xPos, m_yPos, m_zPos variables contain the model's *
location in world coordinates. * * The m_fPitch, m_fYaw, and m_fRoll variables
are floats that * contain the model's orientation in terms of pitch, yaw, and
roll * angles, in radians. */ void C3DModel::MakeWorldMatrix( D3DXMATRIX*
pMatWorld ) { D3DXMATRIX MatTemp; // Temp matrix for rotations. D3DXMATRIX
MatRot; // Final rotation matrix, applied to // pMatWorld. // Using the
left-to-right order of matrix concatenation, // apply the translation to the
object's world position // before applying the rotations.
D3DXMatrixTranslation(pMatWorld, m_xPos, m_yPos, m_zPos);
D3DXMatrixIdentity(&MatRot); // Now, apply the orientation variables to the
world matrix if(m_fPitch || m_fYaw || m_fRoll) { // Produce and combine the
rotation matrices. D3DXMatrixRotationX(&MatTemp, m_fPitch); // Pitch
D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp); D3DXMatrixRotationY(&MatTemp,
m_fYaw); // Yaw D3DXMatrixMultiply(&MatRot, &MatRot, &MatTemp);
D3DXMatrixRotationZ(&MatTemp, m_fRoll); // Roll D3DXMatrixMultiply(&MatRot,
&MatRot, &MatTemp); // Apply the rotation matrices to complete the world
matrix. D3DXMatrixMultiply(pMatWorld, &MatRot, pMatWorld); } } After you
prepare the world transformation matrix, call the
IDirect3DDevice8::SetTransform method to set it, specifying the D3DTS_WORLD
macro for the first parameter. For more information, see Setting
Transformations. [Visual Basic] The following example, from a fictitious 3-D
model class written in Microsoft ® Visual Basic® uses the helper functions
included in the Direct3DX utility library to create a world matrix that
includes three rotations to orient a model and a translation to relocate it
relative to its position in world space. ' ' For the purposes of this example,
the following variables ' are assumed to be valid and initialized. ' ' The
m_xPos, m_yPos, m_zPos variables contain the model's ' location in world
coordinates. ' ' The m_sPitch, m_sYaw, and m_sRoll variables are Singles that '
contain the model's orientation in terms of pitch, yaw, and roll ' angles, in
radians. ' Public Function MakeWorldMatrix() As D3DMATRIX Dim matWorld As
D3DMATRIX ' World matrix to return. Dim matTemp As D3DMATRIX ' Temp matrix to
hold rotations. Dim matRot As D3DMATRIX ' Temp rotation matrix. ' Modify
matWorld to create a translation matrix. D3DXMatrixIdentity matWorld
matWorld.m41 = m_xPos matWorld.m42 = m_yPos matWorld.m43 = m_zPos
D3DXMatrixIdentity matRot ' Sets up the rotation matrix. ' ' Using the
left-to-right order of matrix concatenation, ' apply the translation to the
object's world position ' before applying the rotations. ' ' Produce and
combine the rotation matrices. If (m_sPitch <> 0) Or (m_sYaw <> 0) Or (m_sRoll
<> 0) Then ' First, pitch. D3DXMatrixRotationX matTemp, m_sPitch
D3DXMatrixMultiply matRot, matRot, matTemp ' Then, yaw. D3DXMatrixRotationY
matTemp, m_sYaw D3DXMatrixMultiply matRot, matRot, matTemp ' Finally, roll.
D3DXMatrixRotationZ matTemp, m_sRoll D3DXMatrixMultiply matRot, matRot, matTemp
' Apply the rotation matrices to the translation already in ' matWorld to
complete the world matrix. D3DXMatrixMultiply matWorld, matRot, matWorld End If
MakeWorldMatrix = matWorld End Function After you prepare the world
transformation matrix, call the Direct3DDevice8.SetTransform method to set it,
specifying the D3DTS_WORLD flag in the first parameter. For more information,
see Setting Transformations. Note Microsoft® Direct3D® uses the world and view
matrices that you set to configure several internal data structures. Each time
you set a new world or view matrix, the system recalculates the associated
internal structures. Setting these matrices frequently—for example, thousands
of times per frame—is computationally expensive. You can minimize the number of
required calculations by concatenating your world and view matrices into a
world-view matrix that you set as the world matrix, and then setting the view
matrix to the identity. Keep cached copies of individual world and view
matrices so that you can modify, concatenate, and reset the world matrix as
needed. For clarity, in this documentation Direct3D samples rarely employ this
optimization. The View Transformation This section introduces the basic
concepts of the view transformation and provides details on how to set up a
view transformation matrix in a Microsoft® Direct3D® application. This
information is organized into the following topics. * What Is the View
Transformation? * Setting Up a View Matrix What Is the View Transformation? The
view transformation locates the viewer in world space, transforming vertices
into camera space. In camera space, the camera, or viewer, is at the origin,
looking in the positive z-direction. Recall that Microsoft® Direct3D® uses a
left-handed coordinate system, so z is positive into a scene. The view matrix
relocates the objects in the world around a camera's position—the origin of
camera space—and orientation. There are many ways to create a view matrix. In
all cases, the camera has some logical position and orientation in world space
that is used as a starting point to create a view matrix that will be applied
to the models in a scene. The view matrix translates and rotates objects to
place them in camera space, where the camera is at the origin. One way to
create a view matrix is to combine a translation matrix with rotation matrices
for each axis. In this approach, the following general matrix formula applies.
In this formula, V is the view matrix being created, T is a translation matrix
that repositions objects in the world, and Rx through Rz are rotation matrices
that rotate objects along the x-, y-, and z-axis. The translation and rotation
matrices are based on the camera's logical position and orientation in world
space. So, if the camera's logical position in the world is <10,20,100>, the
aim of the translation matrix is to move objects -10 units along the x-axis,
-20 units along the y-axis, and -100 units along the z-axis. The rotation
matrices in the formula are based on the camera's orientation, in terms of how
the much the axes of camera space are rotated out of alignment with world
space. For example, if the camera mentioned earlier is pointing straight down,
its z-axis is 90 degrees (pi/2 radians) out of alignment with the z-axis of
world space, as shown in the following illustration. The rotation matrices
apply rotations of equal, but opposite, magnitude to the models in the scene.
The view matrix for this camera includes a rotation of -90 degrees around the
x-axis. The rotation matrix is combined with the translation matrix to create a
view matrix that adjusts the position and orientation of the objects in the
scene so that their top is facing the camera, giving the appearance that the
camera is above the model. [C++] Another approach involves creating the
composite view matrix directly. The D3DXMatrixLookAtLH and D3DXMatrixLookAtRH
helper functions use this technique. This approach uses the camera's world
space position and a look-at point in the scene to derive vectors that describe
the orientation of the camera space coordinate axes. The camera position is
subtracted from the look-at point to produce a vector for the camera's
direction vector (vector n). Then the cross product of the vector n and the
y-axis of world space is taken and normalized to produce a right vector (vector
u). Next, the cross product of the vectors u and n is taken to determine an up
vector (vector v). The right (u), up (v), and view-direction (n) vectors
describe the orientation of the coordinate axes for camera space in terms of
world space. The x, y, and z translation factors are computed by taking the
negative of the dot product between the camera position and the u, v, and n
vectors. [Visual Basic] Another approach involves creating the composite view
matrix directly. The D3DXMatrixLookAtRH and D3DXMatrixLookAtRH methods use this
technique. This approach uses the camera's world space position and a look-at
point in the scene to derive vectors that describe the orientation of the
camera space coordinate axes. The camera position is subtracted from the
look-at point to produce a vector for the camera's direction vector (vector n).
Then the cross product of the vector n and the y- axis of world space is taken
and normalized to produce a right vector (vector u). Next, the cross product of
the vectors u and n is taken to determine an up vector (vector v). The right
(u), up (v), and view-direction (n) vectors describe the orientation of the
coordinate axes for camera space in terms of world space. The x, y, and z
translation factors are computed by taking the negative of the dot product
between the camera position and the u, v, and n vectors. These values are put
into the following matrix to produce the view matrix. In this matrix, u, v, and
n are the up, right, and view-direction vectors, and c is the camera's world
space position. This matrix contains all the elements needed to translate and
rotate vertices from world space to camera space. After creating this matrix,
you can also apply a matrix for rotation around the z-axis to allow the camera
to roll. For information on implementing this technique, see Setting Up a View
Matrix. Setting Up a View Matrix [C++] The D3DXMatrixLookAtLH and
D3DXMatrixLookAtRH helper functions create a view matrix based on the camera
location and a look-at point. They use the D3DXVec3Cross, D3DXVec3Dot,
D3DXVec3Normalize, and D3DXVec3Subtract helper functions. The following code
example, illustrates the D3DXMatrixLookAtLH function. D3DXMATRIX* WINAPI
D3DXMatrixLookAtLH ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const
D3DXVECTOR3 *pAt, const D3DXVECTOR3 *pUp ) { #if DBG if(!pOut || !pEye || !pAt
|| !pUp) return NULL; #endif D3DXVECTOR3 XAxis, YAxis, ZAxis; // Get the z
basis vector, which points straight ahead; the // difference from the eye point
to the look-at point. This is the // direction of the gaze (+z).
D3DXVec3Subtract(&ZAxis, pAt, pEye); // Normalize the z basis vector.
D3DXVec3Normalize(&ZAxis, &ZAxis); // Compute the orthogonal axes from the
cross product of the gaze // and the pUp vector. D3DXVec3Cross(&XAxis, pUp,
&ZAxis); D3DXVec3Normalize(&XAxis, &XAxis); D3DXVec3Cross(&YAxis, &ZAxis,
&XAxis); // Start building the matrix. The first three rows contain the //
basis vectors used to rotate the view to point at the look-at // point. The
fourth row contains the translation values. // Rotations are still about the
eyepoint. pOut->_11 = XAxis.x; pOut->_21 = XAxis.y; pOut->_31 = XAxis.z;
pOut->_41 = -D3DXVec3Dot(&XAxis, pEye); pOut->_12 = YAxis.x; pOut->_22 =
YAxis.y; pOut->_32 = YAxis.z; pOut->_42 = -D3DXVec3Dot(&YAxis, pEye); pOut->_13
= ZAxis.x; pOut->_23 = ZAxis.y; pOut->_33 = ZAxis.z; pOut->_43 =
-D3DXVec3Dot(&ZAxis, pEye); pOut->_14 = 0.0f; pOut->_24 = 0.0f; pOut->_34 =
0.0f; pOut->_44 = 1.0f; return pOut; } As with the world transformation, you
call the IDirect3DDevice8::SetTransform method to set the view transformation,
specifying the D3DTS_VIEW flag in the first parameter. For more information,
see Setting Transformations. [Visual Basic] Microsoft® Visual Basic®
applications use the D3DXMatrixLookAtLH and D3DXMatrixLookAtRH helper functions
to create a view matrix based on the camera location, a look-at point, and an
up vector (usually 0,1,0). The following example code, written in Visual Basic,
shows how you can use the D3DXMatrixLookAtLH function. ' This example assumes
that g_D3DDevice is a valid reference ' to a Direct3DDevice8 object. Dim
matView As D3DMATRIX ' Set the eyepoint five units back along the z-axis ' and
up three units. D3DXMatrixLookAtLH matView, vec3(0#, 3#, -5#), _ vec3(0#, 0#,
0#), _ vec3(0#, 1#, 0#) g_D3DDevice.SetTransform D3DTS_VIEW, matView As with
the world transformation, you call the Direct3DDevice8.SetTransform method to
set the view transformation, specifying the D3DTS_VIEW flag in the first
parameter. See Setting Transformations, for more information. Performance
Optimization Note Microsoft® Direct3D® uses the world and view matrices that
you set to configure several internal data structures. Each time you set a new
world or view matrix, the system recalculates the associated internal
structures. Setting these matrices frequently—for example, 20,000 times per
frame—is computationally expensive. You can minimize the number of required
calculations by concatenating your world and view matrices into a world-view
matrix that you set as the world matrix, and then setting the view matrix to
the identity. Keep cached copies of individual world and view matrices that you
can modify, concatenate, and reset the world matrix as needed. For clarity,
Direct3D samples rarely employ this optimization. The Projection Transformation
You can think of the projection transformation as controlling the camera's
internals; it is analogous to choosing a lens for the camera. This is the most
complicated of the three transformation types. This discussion of the
projection transformation is organized into the following topics. * The Viewing
Frustum * What Is the Projection Transformation? * Setting Up a Projection
Matrix * A W-Friendly Projection Matrix The Viewing Frustum A viewing frustum
is 3-D volume in a scene positioned relative to the viewport's camera. The
shape of the volume affects how models are projected from camera space onto the
screen. The most common type of projection, a perspective projection, is
responsible for making objects near the camera appear bigger than objects in
the distance. For perspective viewing, the viewing frustum can be visualized as
a pyramid, with the camera positioned at the tip. This pyramid is intersected
by a front and back clipping plane. The volume within the pyramid between the
front and back clipping planes is the viewing frustum. Objects are visible only
when they are in this volume. If you imagine that you are standing in a dark
room and looking through a square window, you are visualizing a viewing
frustum. In this analogy, the near clipping plane is the window, and the back
clipping plane is whatever finally interrupts your view—the skyscraper across
the street, the mountains in the distance, or nothing at all. You can see
everything inside the truncated pyramid that starts at the window and ends with
whatever interrupts your view, and you can see nothing else. The viewing
frustum is defined by fov (field of view) and by the distances of the front and
back clipping planes, specified in z-coordinates. In this illustration, the
variable D is the distance from the camera to the origin of the space that was
defined in the last part of the geometry pipeline—the viewing transformation.
This is the space around which you arrange the limits of your viewing frustum.
For information about how this D variable is used to build the projection
matrix, see What Is the Projection Transformation? What Is the Projection
Transformation? The projection matrix is typically a scale and perspective
projection. The projection transformation converts the viewing frustum into a
cuboid shape. Because the near end of the viewing frustum is smaller than the
far end, this has the effect of expanding objects that are near to the camera;
this is how perspective is applied to the scene. In The Viewing Frustum, the
distance between the camera required by the projection transformation and the
origin of the space defined by the viewing transformation is defined as D. A
beginning for a matrix defining the perspective projection might use this D
variable like this: The viewing matrix puts the camera at the origin of the
scene. Because the projection matrix needs to have the camera at (0, 0, -D), it
translates the vector by -D in the z- direction, by using the following matrix.
Multiplying these two matrices gives the following composite matrix. The
following illustration shows how the perspective transformation converts a
viewing frustum into a new coordinate space. Notice that the frustum becomes
cuboid and also that the origin moves from the upper-right corner of the scene
to the center. In the perspective transformation, the limits of the x- and
y-directions are -1 and 1. The limits of the z-direction are 0 for the front
plane and 1 for the back plane. This matrix translates and scales objects based
on a specified distance from the camera to the near clipping plane, but it
doesn't consider the field of view (fov), and the z-values that it produces for
objects in the distance can be nearly identical, making depth comparisons
difficult. The following matrix addresses these issues, and it adjusts vertices
to account for the aspect ratio of the viewport, making it a good choice for
the perspective projection. In this matrix, Zn is the z-value of the near
clipping plane. The variables w, h, and Q have the following meanings. Note
that fovw and fovh represent the viewport's horizontal and vertical fields of
view, in radians. For your application, using field-of-view angles to define
the x and y scaling coefficients might not be as convenient as using the
viewport's horizontal and vertical dimensions (in camera space). As the math
works out, the following two formulas for w and h use the viewport's
dimensions, and are equivalent to the preceding formulas. In these formulas, Zn
represents the position of the near clipping plane, and the Vw and Vh variables
represent the width and height of the viewport, in camera space. [C++] For a
C++ application, these two dimensions correspond directly to the Width and
Height members of the D3DVIEWPORT8 structure. Whatever formula you decide to
use, it's important that you set Zn to as large a value as possible, as
z-values extremely close to the camera don't vary by much. This makes depth
comparisons using 16-bit z-buffers somewhat complicated. As with the world and
view transformations, you call the IDirect3DDevice8::SetTransform method to set
the projection transformation; for more information, see Setting
Transformations. [Visual Basic] For a Microsoft® Visual Basic® application,
these two dimensions correspond directly to the Width and Height members of the
D3DVIEWPORT8 type. Whatever formula you decide to use, it's important that you
set Zn to as large a value as possible, as z-values extremely close to the
camera don't vary by much, making depth comparisons using 16-bit z-buffers
tricky. As with the world and view transformations, you call the
Direct3DDevice8.SetTransform method to set the projection transformation; for
more information, see Setting Transformations. Setting Up a Projection Matrix
[C++] The following ProjectionMatrix sample function—written in C++—takes four
input parameters that set the front and back clipping planes, as well as the
horizontal and vertical field of view angles. This code parallels the approach
discussed in the What Is the Projection Transformation? topic. The fields of
view should be less than pi radians. D3DMATRIX ProjectionMatrix(const float
near_plane, // Distance to near clipping // plane const float far_plane, //
Distance to far clipping // plane const float fov_horiz, // Horizontal field of
view // angle, in radians const float fov_vert) // Vertical field of view //
angle, in radians { float h, w, Q; w = (float)1/tan(fov_horiz*0.5); // 1/tan(x)
== cot(x) h = (float)1/tan(fov_vert*0.5); // 1/tan(x) == cot(x) Q =
far_plane/(far_plane - near_plane); D3DMATRIX ret; ZeroMemory(&ret,
sizeof(ret)); ret(0, 0) = w; ret(1, 1) = h; ret(2, 2) = Q; ret(3, 2) =
-Q*near_plane; ret(2, 3) = 1; return ret; } // End of ProjectionMatrix After
you create the matrix, you must set it in a call to the
IDirect3DDevice8::SetTransform method, specifying D3DTRANSFORMSTATE_PROJECTION
in the first parameter. For details, see Setting Transformations. The Direct3DX
utility library provides the following functions to help you set up your
projections matrix. * D3DXMatrixPerspectiveLH * D3DXMatrixPerspectiveRH *
D3DXMatrixPerspectiveFovLH * D3DXMatrixPerspectiveFovRH *
D3DXMatrixPerspectiveOffCenterLH * D3DXMatrixPerspectiveOffCenterRH [Visual
Basic] Applications written in Microsoft® Visual Basic® can create a projection
matrix as described in the What Is the Projection Transformation? topic.
However, the Direct3DX utility library provides the following functions to help
you set up your projections matrix. * D3DXMatrixPerspectiveLH *
D3DXMatrixPerspectiveRH * D3DXMatrixPerspectiveFovLH *
D3DXMatrixPerspectiveFovRH * D3DXMatrixPerspectiveOffCenterLH *
D3DXMatrixPerspectiveOffCenterRH The following Visual Basic code example shows
how D3DXMatrixPerspectiveLH is commonly used. ' This example assumes that
g_D3DDevice is a valid reference ' to a Direct3DDevice8 object. ' For the
projection matrix, set up a perspective transform, which ' transforms geometry
from 3-D view space to 2-D viewport space, ' with a perspective divide that
makes objects smaller in the ' distance. To build a perspective transform, you
need the field ' of view (1/4 pi is common), the aspect ratio, and the near and
' far clipping planes, which define the distances at which ' geometry should be
no longer be rendered. Dim matProj As D3DMATRIX D3DXMatrixPerspectiveFovLH
matProj, g_pi / 4, 1, 1, 1000 g_D3DDevice.SetTransform D3DTS_PROJECTION,
matProj After you create the matrix, you must set it in a call to the
Direct3DDevice8.SetTransform method, specifying D3DTRANSFORMSTATE_PROJECTION in
the first parameter. For details, see Setting Transformations. A W-Friendly
Projection Matrix Microsoft® Direct3D® can use the W component of a vertex that
has been transformed by the world, view, and projection matrices to perform
depth-based calculations in depth-buffer or fog effects. Computations such as
these require that your projection matrix normalize W to be equivalent to
world-space Z. In short, if your projection matrix includes a (3,4) coefficient
that is not 1, you must scale all the coefficients by the inverse of the (3,4)
coefficient to make a proper matrix. If you don't provide a compliant matrix,
fog effects and depth buffering are not applied correctly. The projection
matrix recommended in What Is the Projection Transformation? is compliant with
w-based calculations. The following illustration shows a non-compliant
projection matrix, and the same matrix scaled so that eye-relative fog will be
enabled. In the preceding matrices, all variables are assumed to be nonzero.
For more information about eye-relative fog, see Eye-Relative vs. Z-based
Depth. For information about w-based depth buffering, see What Are Depth
Buffers? Note Direct3D uses the currently set projection matrix in its w-based
depth calculations. As a result, applications must set a compliant projection
matrix to receive the desired w-based features, even if they do not use the
Direct3D transformation pipeline. The Lighting Engine This section introduces
the general concepts behind the Microsoft® Direct3D® lighting engine. The
following topics are discussed. * Enabling and Disabling the Lighting Engine *
Light Color Types and Sources * Fog Effects For detailed information on the
inner working of the lighting engine, see Mathematics of Direct3D Lighting.
Enabling and Disabling the Lighting Engine [C++] By default, Microsoft®
Direct3D® performs lighting calculations on all vertices, even those without
vertex normals. This is different from the behavior in previous releases of
Microsoft DirectX®, where lighting was performed only on vertices that
contained a vertex normal. However, you can disable lighting through the
D3DRS_LIGHTING render state. Call the IDirect3DDevice8::SetRenderState method,
passing D3DRS_LIGHTING as the first parameter, and TRUE or FALSE as the second
parameter. Setting the state to TRUE enables lighting (the default), and
setting it to FALSE disables lighting operations. [Visual Basic] By default,
Microsoft® Direct3D® performs lighting calculations on all vertices, even those
without vertex normals. However, you can disable lighting through the
D3DRS_LIGHTING render state. Call the Direct3DDevice8.SetRenderState method,
passing D3DRS_LIGHTING as the first parameter, and True or False as the second
parameter. Setting the state to True enables lighting (the default), and
setting it to False disables lighting operations. Light Color Types and Sources
Light sources in Microsoft® Direct3D® emit diffuse, ambient, and specular
colors as distinct light components that factor into lighting computations
independently of each other. Similarly, the vertices that the system renders
can use discrete diffuse, ambient, specular, and emissive colors, as defined by
their vertex format. [C++] For a C++ application, these vertex colors are used
by the system only when you set the D3DRS_COLORVERTEX render state to TRUE.
Vertex color sources are selectable; that is, you can configure the system to
select the source for the vertex- color portions of lighting formulas at run
time. The D3DRS_AMBIENTMATERIALSOURCE, D3DRS_DIFFUSEMATERIALSOURCE, and
D3DRS_SPECULARMATERIALSOURCE render states control the source from which the
system draws the associated colors during lighting calculations. You can set
each render state to a member of the D3DMATERIALCOLORSOURCE enumerated type,
which defines values that cause the system to use the current material, or a
color from the vertex, as the color source. [Visual Basic] From Microsoft®
Visual Basic®, vertex colors are used by the system only when you set the
D3DRS_COLORVERTEX render state to True. Vertex color sources are selectable;
that is, you can configure the system to select the source for the vertex-
color portions of lighting formulas at run time. The
D3DRS_AMBIENTMATERIALSOURCE, D3DRS_DIFFUSEMATERIALSOURCE, and
D3DRS_SPECULARMATERIALSOURCE render states control the source from which the
system draws the associated colors during lighting calculations. You can set
each render state to a member of the CONST_D3DMATERIALCOLORSOURCE enumeration,
which defines values that cause the system to use the current material, or a
color from the vertex, as the color source. Fog Effects The Microsoft®
Direct3D® transformation and lighting engine can create fog effects during
lighting. This type of fog is usually referred to as vertex fog because fog
information is placed in the alpha component of the vertex to be rasterized.
For more information see Fog and Vertex Fog. Mathematics of Direct3D Lighting
This section describes the mechanics and implementation details behind the
Microsoft® Direct3D® lighting engine. Direct3D models illumination by
estimating how light behaves in nature. The Direct3D light model keeps track of
light color, the direction and distance that light travels, the position of the
viewer, and the characteristics of the current material to compute two color
components for each vertex in a face. Direct3D uses these color components to
compute the color it draws while rasterizing the pixels of a face. Note All
computations are made in model space by transforming the light source's
position and direction, along with the camera position to model space using the
inverse of the world matrix, then they are back transformed. As a result, if
the world or view matrices introduce nonuniform scaling, the resultant lighting
might be inaccurate. This section presents a technical look at the formulas
that Direct3D uses to come up with diffuse and specular components. By
understanding the approach of Direct3D, you will be better equipped to decide
if the Direct3D light model suits your needs. The Direct3D light model was
designed to be accurate, efficient, and easy to use. However, if the formulas
used by Direct3D don't suit your needs, you can implement your own light model,
bypassing the Direct3D lighting module altogether. The following topics are
discussed. * Lighting Notation * Camera Space Transformation * Basic Lighting
Formula * Diffuse Formula * Specular Formula * Light Attenuation Over Distance
* Reflectance Model * Spotlight Falloff Model The parameters used for these
formulas are listed in the tables below. Each table has its corresponding
default value, type, and a range of accepted values. The following table lists
the position parameters. Parameter Default value Type Description Pe (0,0,0)
D3DVECTOR Camera position in camera space. Po N/A D3DVECTOR Position of current
model origin (0,0,0,1) in the camera space. This is the fourth row of the Mw*Mv
matrix. Mw N/A D3DMATRIX World matrix, set by D3DTRANSFORMSTATE_VIEW. Mv N/A
D3DMATRIX View matrix, set by D3DTRANSFORMSTATE_VIEW. Mwv N/A D3DMATRIX Mw*Mv.
Halfway N/A D3DVECTOR Normalized vector, used to compute specular reflection.
La (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE Ambient color in the light state. Set by
D3DRENDERSTATE_AMBIENT. V N/A D3DVECTOR Vertex position in camera space. N N/A
D3DVECTOR Normalized vertex normal in camera space. Vcd N/A D3DCOLORVALUE
Vertex diffuse color. Vcs N/A D3DCOLORVALUE Vertex specular color. The
following table lists the material parameters. Parameter Default value Type
Description Ma (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE Ambient color. Md (255, 255,
255, 255) D3DCOLORVALUE Diffuse color. Ms (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE
Specular color. Me (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE Emissive color. Mp 0.0
D3DVALUE Specular exponent. Range: (-?,+?) The following table lists the light
source i parameters. Parameter Default value Type Description LpI (0.0, 0.0,
0.0) D3DVECTOR Position in camera space. LdI (0.0, 0.0, 1.0) D3DVECTOR
Direction to the light in the camera space. LrI 0.0 D3DVALUE Distance range.
Range: [0.0, D3DLIGHT_RANGE_MAX] LcaI (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE
Ambient color. LcsI (0.0, 0.0, 0.0, 0.0) D3DCOLORVALUE Specular color. LcI
(1.0, 1.0, 1.0, 0.0) D3DCOLORVALUE Diffuse color. att0I 0.0 D3DVALUE Constant
attenuation factor. Range: (0, +?) att1I 0.0 D3DVALUE Linear attenuation
factor. Range: (0, +?) att2I 0.0 D3DVALUE Quadratic attenuation factor. Range:
(0, +?) falloffI 0.0 D3DVALUE Falloff factor. Range: (-?, +?) thetaI 0.0
D3DVALUE Umbra angle of spotlight in radians. Range: [0, ?) phiI 0.0 D3DVALUE
Penumbra angle of spotlight in radians. Range: [thetaI, ?) Lighting Notation
[C++] The following notations are used in the lighting formulas. The range of a
D3DCOLORVALUE component is (-?, +?). • - dot product is defined as d1 • d2 =
max{d1•d2, 0} norm(P) - normalized vector V1V2 - vector from point V1 to point
V2 M-1- inverse matrix MT- transposed matrix V1 / V2 , where V1 and V2 are of
D3DVECTOR type, equals to the vector: (V1.x / V2.x, V1.y / V2.y , V1.z / V2.z).
V1 * V2 , where V1 and V2 are of D3DVECTOR type, equals to the vector: (V1.x *
V2.x, V1.y * V2.y , V1.z * V2.z). [Visual Basic] The following notations are
used in the lighting formulas. The range of a D3DCOLORVALUE component is (-?,
+?). • - dot product is defined as d1 • d2 = max{d1•d2, 0} norm(P) - normalized
vector V1V2 - vector from point V1 to point V2 M-1- inverse matrix MT-
transposed matrix V1 / V2 , where V1 and V2 are of D3DVECTOR type, equals to
the vector: (V1.x / V2.x, V1.y / V2.y , V1.z / V2.z). V1 * V2 , where V1 and V2
are of D3DVECTOR type, equals to the vector: (V1.x * V2.x, V1.y * V2.y , V1.z *
V2.z). Camera Space Transformation Vertices in the camera space are computed by
multiplying the object vertices by Mwv matrix. v = Vobject * Mwv Normals in the
camera space are computed by multiplying the object normals by inverse
transposed Mwv matrix and normalizing the result. N = Nobject * (Mwv-1)T If
D3DRENDERSTATE_NORMALIZENORMALS is set to TRUE, normals are normalized after
transformation to the camera space: N = norm(N) Light position in the camera
space (Lpi) is computed by multiplying the light source position by Mv. Lpi =
Lporiginal * Mv Direction to light in the camera space for D3DLIGHT_DIRECTIONAL
lights is computed by multiplying the light source position by Mv matrix,
normalizing and negating the result. Ldi = -norm(Ldi original * Mv) For the
D3DLIGHT_POINT and D3DLIGHT_SPOT the direction to light is computed as: Ldi =
norm(VLpi) Basic Lighting Formula The output of the lighting stage is diffuse
(D) and specular (S) colors in RGBA format. Lighting may be in one of two
states: 1. Lighting Off (D3DRENDERSTATE_LIGHTING is set to FALSE). In this
state the vertex color is computed as follows: D3DRENDERSTATE_COLORVETEX is
ignored. If the diffuse vertex color is present, the output diffuse color is
equal to the vertex diffuse color. Otherwise, the diffuse color is equal to the
default diffuse color (255,255,255,255). Output diffuse color is scaled and
clamped to the range [0, 255]. If the specular vertex color is present, the
output specular color is equal to the vertex specular color. Otherwise, the
specular color is equal to the default specular (0,0,0,0). Output specular
color is scaled and clamped to the range [0, 255]. 2. Lighting On
(D3DRENDERSTATE_LIGHTING is set to TRUE). In this state, Direct3D computes
vertex colors according to the formulas below. If normals are not present in
the vertices, the part of the lighting equations that depends on dot product is
set to zero. Lighting is still computed. Lighting is done in the camera space.
alpha component is not used in the following lighting equations. Diffuse
Formula The following explains the formula for diffuse lighting. The specular
component is set to (0, 0, 0, 0) if D3DRENDERSTATE_SPECULARENABLE is set to
FALSE, otherwise it is computed as follows: where Specular Formula The
following explains the formula for specular lighting. hi are half way vectors
between the normal and the direction to light. hi = norm(norm(Vpe) + Ldi)), if
D3DRENDERSTATE_LOCALVIEWER = TRUE hi = norm((0,0,-1) + Ldi)), if
D3DRENDERSTATE_LOCALVIEWER = FALSE rhoi = norm(Ldi) ? norm(VLpi) di is a
distance from a vertex to the light i and is computed as follows: Diffuse and
specular components are clamped to be from 0 to 255, after all lights are
processed and interpolated separately. Light Attenuation Over Distance [C++]
Microsoft® Direct3D® determines the distance between a light source and a
vertex being lit by taking the magnitude of the vector that exists between the
light's position and the vertex. This is represented by the following formula.
In the preceding formula, D is the distance being calculated, V is the position
of the vertex being lit, and L is the light source's position. If D is greater
than the light's range, that is, the Range member of a D3DLIGHT8 structure,
Direct3D makes no further attenuation calculations and applies no effects from
the light to the vertex. If the distance is within the light's range, Direct3D
then applies the following formula to calculate light attenuation over distance
for point lights and spotlights; directional lights don't attenuate. In this
attenuation formula, A is the calculated total attenuation and D is the
distance from the light source to the vertex. The dvAttenuation0,
dvAttenuation1, and dvAttenuation2 values are the light's attenuation constants
as specified by the members of a light object's D3DLIGHT8 structure. The
corresponding structure members are Attenuation0, Attenuation1, and
Attenuation2. The attenuation constants act as coefficients in the formula—you
can produce a variety of attenuation curves by making simple adjustments to
them. You can set Attenuation0 to 1.0 to create a light that doesn't attenuate
but is still limited by range, or you can experiment with different values to
achieve various attenuation effects. The attenuation at the maximum range of
the light is not 0.0. To prevent lights from suddenly appearing when they are
at the light range, an application can increase the light range. Or, the
application can set up attenuation constants so that the attenuation factor is
close to 0.0 at the light range. The attenuation value is multiplied by the
red, green, and blue components of the light's color to scale the light's
intensity as a factor of the distance light travels to a vertex. After
computing the light attenuation, Direct3D also considers spotlight effects if
applicable, the angle that the light reflects from a surface, and the
reflectance of the current material to calculate the diffuse and specular
components for that vertex. For more information, see Spotlight Falloff Model
and Reflectance Model. [Visual Basic] Microsoft® Direct3D® determines the
distance between a light source and a vertex being lit by taking the magnitude
of the vector that exists between the light's position and the vertex. This is
represented by the following formula. In the preceding formula, D is the
distance being calculated, V is the position of the vertex being lit, and L is
the light source's position. If D is greater than the light's range—the Range
member of a D3DLIGHT8 type—Direct3D makes no further attenuation calculations
and applies no effects from the light to the vertex. If the distance is within
the light's range, Direct3D then applies the following formula to calculate
light attenuation over distance for point lights and spotlights; directional
lights don't attenuate. In this attenuation formula, A is the calculated total
attenuation and D is the distance from the light source to the vertex. The
attenuation0, attenuation1, and attenuation2 values are the light's attenuation
constants as specified by the members of a light object's D3DLIGHT8 type. The
corresponding structure members are Attenuation0, Attenuation1, and
Attenuation2. The attenuation constants act as coefficients in the formula—you
can produce a variety of attenuation curves by making simple adjustments to
them. You can set Attenuation0 to 1.0 to create a light that doesn't attenuate
but is still limited by range, or you can experiment with different values to
achieve various attenuation effects. The attenuation at the maximum range of
the light is not 0.0. To prevent lights from suddenly appearing when they are
at the light range, an application can increase the light range. Or, the
application can set up attenuation constants so that the attenuation factor is
close to 0.0 at the light range. The attenuation value is multiplied by the
red, green, and blue components of the light's color to scale the light's
intensity as a factor of the distance light travels to a vertex. After
computing the light attenuation, Direct3D also considers spotlight effects if
applicable, the angle that the light reflects from a surface, and the
reflectance of the current material to calculate the diffuse and specular
components for that vertex. For more information, see Spotlight Falloff Model
and Reflectance Model. Reflectance Model After adjusting the light intensity
for any attenuation effects, Microsoft® Direct3D® computes how much of the
remaining light reflects from a vertex given the angle of the vertex normal and
the direction of the incident light. Direct3D skips to this step for
directional lights because they don't attenuate over distance. The system
considers two reflection types, diffuse and specular, and uses a different
formula to determine how much light is reflected for each. After calculating
the amounts of light reflected, Direct3D applies these new values to the
diffuse and specular reflectance properties of the current material. The
resulting color values are the diffuse and specular components that the
rasterizer uses to produce Gouraud shading and specular highlighting. Diffuse
Reflection Model [C++] Microsoft Direct3D uses the following formula to compute
diffuse reflection factors. In this formula, Rd is the diffuse reflectance
factor, D is the direction that the light travels to the vertex, and N is the
vertex normal. Vector D is normalized; vector N is normalized only if the
D3DRS_NORMALIZENORMALS render state is enabled. The light's direction vector is
reversed by multiplying it by -1 to create the proper association between the
direction vector and the vertex normal. This formula produces values that range
from -1.0 to 1.0, which are clamped to the range of 0.0 to 1.0 and used to
scale the intensity of the light reflecting from the vertex. After the diffuse
reflection formula is applied, the scaled light is then applied to the diffuse
reflectance formula to determine the diffuse component at that vertex. The
formula that combines ambient and diffuse reflection to create the diffuse
component for the vertex looks like this: In the preceding formula, Dv is the
diffuse component being calculated for the vertex, Ia is the ambient light
level in the scene, and A is the light intensity for a light source that has
been attenuated for distance and spotlight effects (attenuation from Light
Attenuation Over Distance multiplied by Spotlight Falloff Model). The L
variables represent the light's properties, and the V entries represent the
vertex color, where the subscripts a, d, and e applied to each denote the type
of color—ambient, diffuse, or emissive. As the formula notation states, the
system computes IaVa + Ve once, adding A(RdVdLd ? VaLa) for every active light.
If the D3DRS_COLORVERTEX render state is enabled, the system selects colors for
V based on the values set for the D3DRS_AMBIENTMATERIALSOURCE and
D3DRS_DIFFUSEMATERIALSOURCE render states. Set these render states to a member
of the D3DMATERIALCOLORSOURCE enumerated type to cause the system to use the
current material, or a color from the vertex, as the color source. For more
information, see Specular Reflection Model. [Visual Basic] Microsoft Direct3D
uses the following formula to compute diffuse reflection factors. In this
formula, Rd is the diffuse reflectance factor, D is the direction that the
light travels to the vertex, and N is the vertex normal. Vector D is
normalized; vector N is normalized only if the D3DRS_NORMALIZENORMALS render
state is enabled. The light's direction vector is reversed by multiplying it by
-1 to create the proper association between the direction vector and the vertex
normal. This formula produces values that range from -1.0 to 1.0, which are
clamped to the range of 0.0 to 1.0 and used to scale the intensity of the light
reflecting from the vertex. After the diffuse reflection formula is applied,
the scaled light is then applied to the diffuse reflectance formula to
determine the diffuse component at that vertex. The formula that combines
ambient and diffuse reflection to create the diffuse component for the vertex
looks like this: In the preceding formula, Dv is the diffuse component being
calculated for the vertex, Ia is the ambient light level in the scene, and A is
the light intensity for a light source that has been attenuated for distance
and spotlight effects—attenuation from Light Attenuation Over Distance
multiplied by Spotlight Falloff Model. The L variables represent the light's
properties, and the V entries represent the vertex color, where the subscripts
a, d, and e applied to each denote the type of color—ambient, diffuse, or
emissive. As the formula notation states, the system computes IaVa + Ve once,
adding A(RdVdLd ? VaLa) for every active light. If the D3DRS_COLORVERTEX render
state is enabled, the system selects colors for V based on the values set for
the D3DRS_AMBIENTMATERIALSOURCE and D3DRS_DIFFUSEMATERIALSOURCE render states.
Set these render states to a member of the CONST_D3DMATERIALCOLORSOURCE
enumeration to cause the system to use the current material, or a color from
the vertex, as the color source. For more information, see Specular Reflection
Model. Specular Reflection Model [C++] Modeling specular reflection requires
that the system not only know the direction that light is traveling, but also
the direction to the viewer's eye. The system uses a simplified version of the
Phong specular-reflection model, which employs a halfway vector to approximate
the intensity of specular reflection. This halfway vector exists midway between
the vector to the light source and the vector to the eye. Microsoft Direct3D
provides applications with two ways to compute the halfway vector, which is
controlled by the D3DRS_LOCALVIEWER render state. If D3DRS_LOCALVIEWER is set
to TRUE, the system calculates the halfway vector using the position of the
camera and the position of the vertex, along with the light's direction vector.
The following formula illustrates this. In the preceding formula, norm is an
operator that normalizes an input vector, VC is the vector that exists from the
position of the vertex to the position of the viewpoint or eye, and Ld is the
light's direction vector. Determining the halfway vector in this manner can be
computationally expensive. As an alternative, you can set D3DRS_LOCALVIEWER to
FALSE. This instructs the system to act as though the viewpoint is infinitely
distant on the z-axis. This setting is less computationally expensive, but much
less accurate, so it is best used by applications that use orthogonal
projection. When D3DRS_LOCALVIEWER is set to FALSE, Direct3D determines the
halfway vector by the following formula. This formula is similar to the first
formula, but substitutes the vector I (0, 0, -1)— which points at a viewpoint
infinitely distant on the z-axis—instead of computing the vector VC. After
determining the halfway vector, H, the system uses the following formula to
compute specular reflection. In the preceding formula, Rs is the specular
reflectance, N in the vertex normal, H is the halfway vector, and p is the
specular reflection power of the current material, as specified by the Power
member of the material's D3DMATERIAL8 structure. Vector H is normalized, and
vector N is normalized only if the D3DRS_NORMALIZENORMALS render state is
enabled. As with the diffuse reflectance formula, this formula produces values
that range from -1.0 to 1.0, which are clamped to the range of 0.0 to 1.0 and
used to scale the light reflecting from the vertex. Also similar to the diffuse
reflection model, the remaining light is applied to a formula that derives the
specular component at that vertex: In this formula, Sv is the specular color
being computed. A is the light from a single light source that has been
attenuated for distance and spotlight effects; for more information, see Light
Attenuation Over Distance and Spotlight Falloff Model. The Rs variable is the
previously calculated specular reflectance, Vs is the specular component for
the vertex, and Ls is the specular light color output by the light. If the
D3DRS_COLORVERTEX render state is enabled, the system selects the color source
for V based on the value of the D3DRS_SPECULARMATERIALSOURCE render state. This
render state can be set to a member of the D3DMATERIALCOLORSOURCE enumerated
type to cause the system to use the current material or one of the color
components for the vertex as the color source. For more information, see
Diffuse Reflection Model. [Visual Basic] Modeling specular reflection requires
that the system not only know the direction that light is traveling, but also
the direction to the viewer's eye. The system uses a simplified version of the
Phong specular-reflection model, which employs a halfway vector to approximate
the intensity of specular reflection. This halfway vector exists midway between
the vector to the light source and the vector to the eye. Microsoft® Direct3D®
provides applications with two ways to compute the halfway vector, which is
controlled by the D3DRS_LOCALVIEWER render state. If D3DRS_LOCALVIEWER is set
to True, the system calculates the halfway vector using the position of the
camera and the position of the vertex, along with the light's direction vector.
The following formula illustrates this. In the preceding formula, norm is an
operator that normalizes an input vector, VC is the vector that exists from the
position of the vertex to the position of the viewpoint or eye, and Ld is the
light's direction vector. Determining the halfway vector in this manner can be
computationally intensive. As an alternative, you can set D3DRS_LOCALVIEWER to
FALSE. This instructs the system to act as though the viewpoint is infinitely
distant on the z-axis. This setting is less computationally expensive, but much
less accurate, so it is best used by applications that use orthogonal
projection. When D3DS_LOCALVIEWER is set to False, Direct3D determines the
halfway vector by the following formula. This formula is similar to the first
formula, but substitutes the vector I (0, 0, -1)— which points at a viewpoint
infinitely distant on the z-axis—instead of computing the vector VC. After
determining the halfway vector, H, the system uses the following formula to
compute specular reflection. In the preceding formula, Rs is the specular
reflectance, N in the vertex normal, H is the halfway vector, and p is the
specular reflection power of the current material as specified by the power
member of the material's D3DMATERIAL8 type. Vector H is normalized, and vector
N is normalized only if the D3DRS_NORMALIZENORMALS render state is enabled. As
with the diffuse reflectance formula, this formula produces values that range
from -1.0 to 1.0, which are clamped to the range of 0.0 to 1.0 and used to
scale the light reflecting from the vertex. Also similar to the diffuse
reflection model, the remaining light is applied to a formula that derives the
specular component at that vertex: In the preceding formula, Sv is the specular
color being computed. A is the light from a single light source that has been
attenuated for distance and spotlight effects; for more information, see Light
Attenuation Over Distance and Spotlight Falloff Model. The Rs variable is the
previously calculated specular reflectance, Vs is the selected specular
component for the vertex, and Ls is the specular light color output by the
light. If the D3DRS_COLORVERTEX render state is enabled, the system selects the
color source for V based on the value of the D3DRS_SPECULARMATERIALSOURCE
render state. This render state can be set to a member of the
CONST_D3DMATERIALCOLORSOURCE enumerated type to cause the system to use the
current material or one of the color components for the vertex as the color
source. For more information, see Diffuse Reflection Model. Spotlight Falloff
Model [C++] Spotlights emit a cone of light that has two parts: a bright inner
cone and an outer cone. Light is brightest in the inner cone and isn't present
outside the outer cone, with light intensity attenuating between the two areas.
This type of attenuation is commonly referred to as falloff. How much light a
vertex receives is based on the vertex's location in the inner or outer cones.
Microsoft® Direct3D® computes the dot product of the spotlight's direction
vector (L) and the vector from the vertex to the light (D). This value is equal
to the cosine of the angle between the two vectors, and serves as an indicator
of the vertex's position that can be compared to the light's cone angles to
determine where the vertex might lie in the inner or outer cones. The following
illustration provides a graphical representation of the association between
these two vectors. Next, the system compares this value to the cosine of the
spotlight's inner and outer cone angles. In the light's D3DLIGHT8 structure,
the Theta and Phi members represent the total cone angles for the inner and
outer cones. Because the attenuation occurs as the vertex becomes more distant
from the center of illumination, rather than across the total cone angle,
Direct3D halves these cone angles before calculating their cosines. If the dot
product of vectors L and D is less than or equal to the cosine of the outer
cone angle, the vertex lies beyond the outer cone and receives no light. If the
dot product of L and D is greater than the cosine of the inner cone angle, then
the vertex is within the inner cone and receives the maximum amount of light,
still considering attenuation over distance. If the vertex is somewhere between
the two regions, Direct3D calculates falloff for the vertex by using the
following formula. In the formula, If is light intensity, after falloff, for
the vertex being lit, ? is the angle between vectors L and D, ? is half of the
outer cone angle, ? is half of the inner cone angle, and p is the spotlight's
falloff property—Falloff in the D3DLIGHT8 structure. This formula generates a
value between 0.0 and 1.0 that scales the light's intensity at the vertex to
account for falloff. Attenuation as a factor of the vertex's distance from the
light is also applied. The p value corresponds to the Falloff member of the
D3DLIGHT8 structure and controls the shape of the falloff curve. The following
illustration shows how different Falloff values can affect the falloff curve.
The effect of various Falloff values on the actual lighting is subtle, and a
small performance penalty is incurred by shaping the falloff curve with Falloff
values other than 1.0. For these reasons, this value is typically set to 1.0.
For more information, see Light Attenuation Over Distance. [Visual Basic]
Spotlights emit a cone of light that has two parts: a bright inner cone and an
outer cone. Light is brightest in the inner cone and isn't present outside the
outer cone, with light intensity attenuating between the two areas. This type
of attenuation is commonly referred to as falloff. How much light a vertex
receives is based on the vertex's location in the inner or outer cones.
Microsoft® Direct3D® computes the dot product of the spotlight's direction
vector (L) and the vector from the vertex to the light (D). This value is equal
to the cosine of the angle between the two vectors, and serves as an indicator
of the vertex's position that can be compared to the light's cone angles to
determine where the vertex might lie in the inner or outer cones. The following
illustration provides a graphical representation of the association between
these two vectors. Next, the system compares this value to the cosine of the
spotlight's inner and outer cone angles. In the light's D3DLIGHT8 type, the
Theta and Phi members represent the total cone angles for the inner and outer
cones. Because the attenuation occurs as the vertex becomes more distant from
the center of illumination, rather than across the total cone angle, Direct3D
halves these cone angles before calculating their cosines. If the dot product
of vectors L and D is less than or equal to the cosine of the outer cone angle,
the vertex lies beyond the outer cone and receives no light. If the dot product
of L and D is greater than the cosine of the inner cone angle, then the vertex
is within the inner cone and receives the maximum amount of light, still
considering attenuation over distance. If the vertex is somewhere between the
two regions, Direct3D calculates falloff for the vertex by using the following
formula. In the formula, If is light intensity, after falloff, for the vertex
being lit, ? is the angle between vectors L and D, ? is half of the outer cone
angle, ? is half of the inner cone angle, and p is the spotlight's falloff
property—Falloff in the D3DLIGHT8 type. This formula generates a value between
0.0 and 1.0 that scales the light's intensity at the vertex to account for
falloff. Attenuation as a factor of the vertex's distance from the light is
also applied. The p value corresponds to the Falloff member of the D3DLIGHT8
type and controls the shape of the falloff curve. The following illustration
shows how different Falloff values can affect the falloff curve. The effect of
various Falloff values on the actual lighting is subtle, and a small
performance penalty is incurred by shaping the falloff curve with values other
than 1.0. For these reasons, this value is typically set to 1.0. For more
information, see Light Attenuation Over Distance. Viewports and Clipping This
section discusses clipping, the last stage of the geometry pipeline. The
discussion is organized into the following topics. * What Is a Viewport? *
Viewport Rectangle * Clipping Volumes * Viewport Scaling * Using Viewports
Microsoft® Direct3D® implements clipping by way of a set of viewport parameters
set in the device. What Is a Viewport? Conceptually, a viewport is a 2-D
rectangle into which a three-dimensional scene is projected. In Microsoft®
Direct3D®, the rectangle exists as coordinates within a Direct3D surface that
the system uses as a rendering target. The projection transformation converts
vertices into the coordinate system used for the viewport. You use a viewport
in Direct3D to specify the following features in your application. * The
screen-space viewport to which the rendering will be confined. * The range of
depth values on a render-target surface into which a scene will be rendered
(usually 0.0 to 1.0). Viewport Rectangle [C++] You define the viewport
rectangle in C++ by using the D3DVIEWPORT8 structure. The D3DVIEWPORT8
structure is used with the following viewport manipulation methods exposed by
the IDirect3DDevice8 interface. * IDirect3DDevice8::GetViewport *
IDirect3DDevice8::SetViewport The D3DVIEWPORT8 structure contains four
members—X, Y, Width, and Height—that define the area of the render-target
surface into which a scene will be rendered. These values correspond to the
destination rectangle, or viewport rectangle, as shown in the following
illustration. The values you specify for the X, Y, Width, and Height members of
the D3DVIEWPORT8 structure are screen coordinates relative to the upper-left
corner of the render-target surface. The structure defines two additional
members (MinZ and MaxZ) that indicate the depth-ranges into which the scene
will be rendered. Microsoft® Direct3D® assumes that the viewport clipping
volume ranges from -1.0 to 1.0 in X, and from 1.0 to -1.0 in Y. These were the
settings used most often by applications in the past. During the projection
transformation, you can adjust for viewport aspect ratio before clipping. This
task is covered by topics in The Projection Transformation section. Note The
D3DVIEWPORT8 structure members MinZ and MaxZ indicate the depth- ranges into
which the scene will be rendered and are not used for clipping. Most
applications will set these members to 0.0 and 1.0 to enable the system to
render to the entire range of depth values in the depth buffer. In some cases,
you can achieve special effects by using other depth ranges. For instance, to
render a heads-up display in a game, you can set both values to 0.0 to force
the system to render objects in a scene in the foreground, or you might set
them both to 1.0 to render an object that should always be in the background.
[Visual Basic] You define the viewport rectangle in a Microsoft® Visual Basic®
application by using the D3DVIEWPORT8 type. The D3DVIEWPORT8 type is used with
the following viewport manipulation methods offered by the Direct3DDevice8
class. * Direct3DDevice8.GetViewport * Direct3DDevice8.SetViewport The
D3DVIEWPORT8 type contains four members—x, y, Width, and Height— that define
the area of the render-target surface into which a scene will be rendered,
called the viewport rectangle. These values correspond to the destination
rectangle, or viewport rectangle, as shown in the following illustration. The
values you specify for the x, y, Width, and Height members of the D3DVIEWPORT8
type are screen coordinates relative to the upper-left corner of the
render-target surface. The type defines two additional members (MinZ and MaxZ)
indicate the depth-ranges into which the scene will be rendered. Microsoft®
Direct3D® assumes that the viewport clipping volume ranges from -1.0 to 1.0 in
x, and from 1.0 to -1.0 in y. These were the settings used most often by
applications in the past. In Microsoft DirectX® 8.0, as in previous releases of
DirectX, you can adjust for viewport aspect ratio before clipping, during the
projection transformation. This task is covered by topics in The Projection
Transformation. Clipping Volumes The results of the projection matrix determine
the clipping volume in projection space. Microsoft® Direct3D® defines the
clipping volume in projection space as: In the preceding formulas, Xc, Yc, Zc,
and Wc represent the vertex coordinates after the projection transformation is
applied. Any vertices that have an x, y, or z component outside these ranges
are clipped, if clipping is enabled (the default behavior). [C++] With the
exception of vertex buffers, applications enable or disable clipping by way of
the D3DRS_CLIPPING render state. Clipping information for vertex buffers is
generated during processing, for more information see Processing Vertices.
Direct3D does not clip transformed vertices of a primitive from a vertex buffer
unless it comes from IDirect3DDevice8::ProcessVertices. If you are doing your
own transforms and need Direct3D to do the clipping you should not use vertex
buffers; in this case, the application traverses the data to transform it,
Direct3D traverses the data a second time to clip it, and then the driver
renders the data which is inefficient. So, if the application transforms the
data is should also clip the data. [Visual Basic] With the exception of vertex
buffers, applications enable or disable clipping by way of the D3DRS_CLIPPING
render state. Clipping information for vertex buffers is generated during
processing, for more information see Processing Vertices. Direct3D does not
clip transformed vertices of a primitive from a vertex buffer unless it comes
from Direct3DDevice8.ProcessVertices. If you are doing your own transforms and
need Direct3D to do the clipping you should not use vertex buffers; in this
case, the application traverses the data to transform it, Direct3D traverses
the data a second time to clip it, and then the driver renders the data which
is inefficient. So, if the application transforms the data is should also clip
the data. Viewport Scaling [C++] The dimensions used in the X, Y, Width, and
Height members of the D3DVIEWPORT8 structure for a viewport define the location
and dimensions of the viewport on the render-target surface. These values are
in screen coordinates, relative to the upper-left corner of the surface.
Microsoft® Direct3D® uses the viewport location and dimensions to scale the
vertices to fit a rendered scene into the appropriate location on the target
surface. Internally, Direct3D inserts these values into a matrix that is
applied to each vertex: This matrix simply scales vertices according to the
viewport dimensions and desired depth range and translates them to the
appropriate location on the render-target surface. The matrix also flips the
y-coordinate to reflect a screen origin at the top-left corner with y
increasing downward. After this matrix is applied, vertices are still
homogeneous—that is, they still exist as [x,y,z,w] vertices—and they must be
converted to non-homogeneous coordinates before being sent to the rasterizer.
This is performed by way of simple division, as discussed in Rasterization.
Note The viewport scaling matrix incorporates the MinZ and MaxZ members of the
D3DVIEWPORT8 structure to scale vertices to fit the depth range [MinZ, MaxZ].
This represents different semantics from previous releases of Microsoft
DirectX, in which these members were used for clipping. For more information,
see Viewport Rectangle and Clipping Volumes. Applications typically set MinZ
and MaxZ to 0.0 and 1.0 to cause the system to render to the entire depth
range. However, you can use other values to achieve certain affects. You might
set both values to 0.0 to force all objects into the foreground, or set both to
1.0 to render all objects into the background. [Visual Basic] The dimensions
used in the x, y, Width, and Height members of the D3DVIEWPORT8 type for a
viewport define the location and dimensions of the viewport on the
render-target surface. These values are in screen coordinates, relative to the
upper-left corner of the surface. Microsoft® Direct3D® uses the viewport
location and dimensions to scale the vertices to fit a rendered scene into the
appropriate location on the target surface. Internally, Direct3D inserts these
values into a matrix that is applied to each vertex: This matrix simply scales
vertices according to the viewport dimensions and desired depth range and
translates them to the appropriate location on the render-target surface. The
matrix also flips the y-coordinate to reflect a screen origin at the top-left
corner with y increasing downward. After this matrix is applied, vertices are
still homogeneous—that is, they still exist as [x,y,z,w] vertices—and they must
be converted to non-homogeneous coordinates before being sent to the
rasterizer. This is performed by way of simple division, as discussed in
Rasterization. Using Viewports This section provides details about working with
viewports. Information is divided into the following topics. * Setting the
Viewport Clipping Volume * Clearing a Viewport * Manually Transforming Vertices
Setting the Viewport Clipping Volume The only requirement for configuring the
viewport parameters for a rendering device is to set the viewport's clipping
volume. To do this, you initialize and set clipping values for the clipping
volume and for the render-target surface. Viewports are commonly set up to
render to the full area of the render-target surface, but this isn't a
requirement. [C++] You can use the following settings for the members of the
D3DVIEWPORT8 structure to achieve this in C++. D3DVIEWPORT8 viewData = { 0, 0,
width, height, 0.0f, 1.0f }; After setting values in the D3DVIEWPORT8
structure, apply the viewport parameters to the device by calling its
IDirect3DDevice8::SetViewport method. The following code example shows what
this call might look like. HRESULT hr; hr = pd3dDevice->SetViewport(&viewData);
if(FAILED(hr)) return hr; If the call succeeds, the viewport parameters are set
and will take effect the next time a rendering method is called. To make
changes to the viewport parameters, just update the values in the D3DVIEWPORT8
structure and call SetViewport again. Note The D3DVIEWPORT8 structure members
MinZ and MaxZ indicate the depth- ranges into which the scene will be rendered
and are not used for clipping. Most applications set these members to 0.0 and
1.0 to enable the system to render to the entire range of depth values in the
depth buffer. In some cases, you can achieve special effects by using other
depth ranges. For instance, to render a heads-up display in a game, you can set
both values to 0.0 to force the system to render objects in a scene in the
foreground, or you might set them both to 1.0 to render an object that should
always be in the background. [Visual Basic] The following Microsoft® Visual
Basic® code creates settings in a D3DVIEWPORT8 type to achieve this. Dim
viewData As D3DVIEWPORT8 With viewData .x = 0: .y = 0 .Width = Width: .Height =
Height .MinZ = 0#: .MaxZ = 1# End With After setting values in the D3DVIEWPORT8
type, apply the viewport parameters to the device by calling its
Direct3DDevice8.SetViewport method. ' The d3dDevice variable contains a valid
reference to a ' Direct3DDevice8 object. Call d3dDevice.SetViewport(viewData)
After the call, the viewport parameters are set and will take effect the next
time a rendering method is called. To make changes to the viewport parameters,
just update the values in the D3DVIEWPORT8 type and call SetViewport again.
Clearing a Viewport Clearing the viewport resets the contents of the viewport
rectangle on the render- target surface as well as the rectangle in the depth
and stencil buffer surfaces, if specified. Typically, you clear the viewport
before rendering a new frame to ensure that graphics and other data is ready to
accept new rendered objects without displaying artifacts. [C++] The
IDirect3DDevice8 interface offers C++ developers the IDirect3DDevice8::Clear
method to clear the viewport. The method accepts one or more rectangles that
define the areas on the surfaces being cleared. In cases where the scene being
rendered includes motion throughout the entire viewport rectangle— in a
first-person perspective game, for example—you might want to clear the entire
viewport each frame. In this situation, you set the Count parameter to 1, and
the pRects parameter to the address of a single rectangle that covers the
entire viewport area. If it is more convenient, you can set the pRects
parameter to NULL and the Count parameter to 0 to indicate that the entire
viewport rectangle should be cleared. The Clear method is flexible, and it
provides support for clearing stencil bits within a depth buffer. The Flags
parameter accepts three flags that determine how it clears the render target
and any associated depth or stencil buffers. If you include the D3DCLEAR_TARGET
flag, the method clears the viewport using an arbitrary RGBA color that you
provide in the Color parameter (not the material color). If you include the
D3DCLEAR_ZBUFFER flag, the method clears the depth buffer to an arbitrary depth
you specify in Z:. 0.0 is the closest distance, and 1.0 is the farthest.
Including the D3DCLEAR_STENCIL flag causes the method to reset the stencil bits
to the value you provide in the Stencil parameter. You can use integers that
range from 0 to 2n-1, where n is the stencil buffer bit depth. Note Microsoft®
DirectX® 5.0 allowed background materials to have associated textures, making
it possible to clear the viewport to a texture rather than a simple color. This
feature was little used, and not particularly efficient. Interfaces for DirectX
6.0 and later do not accept texture handles, meaning that you can no longer
clear the viewport to a texture. Rather, applications must now draw backgrounds
manually. As a result, there is rarely a need to clear the viewport on the
render-target surface. As long as your application clears the depth buffer, all
pixels on the render-target surface will be overwritten anyway. In some
situations, you might be rendering only to small portions of the render target
and depth buffer surfaces. The clear methods also enable you to clear multiple
areas of your surfaces in a single call. Do this by setting the Count parameter
to the number of rectangles you want cleared, and specify the address of the
first rectangle in an array of rectangles in the pRects parameter. [Visual
Basic] The Direct3DDevice8 Microsoft® Visual Basic® class offers the
Direct3DDevice8.Clear method to clear the viewport. The method accepts one or
more rectangles that define the area or areas on the surfaces being cleared. In
cases where the scene being rendered includes motion throughout the entire
viewport rectangle—in a first-person perspective game, for example—you might
want to clear the entire viewport each frame. In this situation, you set the
Count parameter to 1, and the ClearD3DRect parameter to a single-element array
of D3DRECT variables, where the first and only element describes a rectangle
that covers the entire area of the render-target surface. The Clear method is
flexible, and it provides support for clearing stencil bits in a depth buffer.
The Flags parameter accepts three flags that determine how it clears the render
target and any associated depth or stencil buffers. If you include the
D3DCLEAR_TARGET flag, the method clears the viewport using an arbitrary RGBA
color that you provide in the Color parameter (not the material color). If you
include the D3DCLEAR_ZBUFFER flag, the method clears the depth buffer to an
arbitrary depth you specify in Z:. 0.0 is the closest distance, and 1.0 is the
farthest. Including the D3DCLEAR_STENCIL flag causes the method to reset the
stencil bits to the value you provide in the Stencil parameter. You can use
integers that range from 0 to 2n-1, where n is the stencil buffer bit depth. In
some situations, you might only be rendering to small portions of the render
target and depth buffer surfaces. The clear methods also enable you to clear
multiple areas of your surfaces in a single call. Do this by setting the Count
parameter to the number of rectangles you want cleared, and an array of
rectangles in the ClearD3DRect parameter. Manually Transforming Vertices You
can use three kinds of vertices in your Microsoft® Direct3D® application. Read
Vertex Formats for more details on the vertex formats. [C++] Untransformed and
Unlit Vertices Vertices that your application doesn't light or transform.
Although you specify lighting parameters and transformation matrices, Direct3D
computes these values. Untransformed and Lit Vertices Vertices that your
application lights but does not transform. Transformed and Lit Vertices
Vertices that your application both lights and transforms. You can change from
simple to complex vertex types by using vertex buffers. Vertex buffers are
objects used to efficiently contain and process batches of vertices for rapid
rendering, and are optimized to exploit processor-specific features. Use the
IDirect3DDevice8::ProcessVertices method to perform vertex transformations.
ProcessVertices accepts only untransformed vertices and can optionally light
and clip vertices as well. Lighting is performed at the time you call the
ProcessVertices methods, but clipping is performed at render time. After
processing the vertices, you can use special rendering methods to render the
vertices, or you can access them directly by locking the vertex buffer memory.
For more information about using vertex buffers, see Vertex Buffers. [Visual
Basic] Untransformed and Unlit Vertices Vertices that your application doesn't
light or transform. Although you specify lighting parameters and transformation
matrices, Direct3D computes these values. Untransformed and Lit Vertices
Vertices that your application lights but does not transform. Transformed and
Lit Vertices Vertices that your application both lights and transforms. You can
change from simple to complex vertex types by using vertex buffers. Vertex
buffers are objects used to efficiently contain and process batches of vertices
for rapid rendering, and are optimized to exploit processor-specific features.
Use the Direct3DDevice8.ProcessVertices method to perform vertex
transformations for you. ProcessVertices accepts only untransformed vertices
and can optionally light and clip vertices as well. Lighting is performed at
the time you call the ProcessVertices methods, but clipping is performed at
render time. After processing the vertices, you can use special rendering
methods to render the vertices, or you can access them directly by locking the
vertex buffer memory. For more information about using vertex buffers, see
Vertex Buffers. Rasterization After passing through the Microsoft® Direct3D®
geometry pipeline, vertices have been transformed, clipped, and scaled to fit
in the viewport on the render-target surface, making them almost ready to send
to the rasterizer to paint on the screen. However, the vertices are still
homogeneous, and the rasterizer expects to receive vertices in terms of their
x-, y-, and z-locations, as well as the reciprocal-of- homogeneous-w (RHW).
Direct3D converts the homogeneous vertices to non- homogeneous vertices by
dividing the x-, y-, and z-coordinates by the w-coordinate. Direct3D then
produces an RHW value by inverting the w-coordinate, as in the following
formulas. The resulting values are passed to the rasterizer for display. The
rasterizer uses the x- and y-coordinates as the screen coordinates for the
vertex, and it uses the z- coordinate for depth comparisons in the depth buffer
when z-buffering is enabled. The RHW value is used in multiple ways: for
calculating fog, for performing perspective-correct texture mapping, and for
w-buffering—an alternate form of depth buffering. Programmable Vertex and Pixel
Processing Microsoft® DirectX® 8.0 features a new kind of graphics pipeline,
featuring a high degree of programmability. The following diagram illustrates
the major components and data flow in the programmable vertex and pixel
pipeline. The transformation and lighting engine and DirectX 6.0 and 7.0
multitexturing modules have been replaced in the programmable pipeline by
vertex and pixel shaders. The first new part of the pipeline is the high-order
primitive module, which works to tessellate high-order primitives such as
bézier and B-splines. The vertex shader is a programmable module used to
execute geometric operations on the vertex data. The vertex shader can perform
a variety of functions which includes standard transformation and lighting. The
pixel shader module is a programmable pixel processor. Pixel shaders control
the color and alpha blending operations and the texture addressing operations.
For general information on programmable shaders, see Introduction to Procedural
Shaders. For information on how the Microsoft Direct3D® pipeline for DirectX
8.0 compares to previous versions, see Integration of Vertex Shaders into the
Geometry Pipeline. For information on the nonprogrammable sections of the
pipeline, which have remained unchanged from DirectX 6.0 and 7.0, see Viewports
and Clipping and Rasterization. Introduction to Procedural Shaders In
Microsoft® Direct3D® for Microsoft DirectX® 8.0, procedural models are used for
specifying the behavior of the vertex transformation and lighting pipeline and
the pixel texture blending pipeline. There are many advantages to a program
model- based syntax for specifying the behavior of the hardware. First, a
procedural model allows a more general syntax for specifying common operations.
Fixed-function, as opposed to programmable, APIs must define modes, flags, and
so on for an increasing number of operations that need to be expressed.
Further, with the increasing power of the hardware—more colors, more textures,
more vertex streams, an so on—the token space for the operations multiplied by
the data inputs becomes complex. A programmability model, on the other hand,
enables even simple operations such as getting the right color and right
texture into the right part of the lighting model in a more direct fashion. You
do not have to search through all the possible modes; you just have to learn
the machine architecture and specify the desired algorithm to be performed. For
example, the following well-known features can be supported. * Basic geometry
transformations * Simple lighting models * Vertex blending for skinning *
Vertex morphing (tweening) * Texture transforms * Texture generation *
Environment mapping Second, a procedural model provides an easy mechanism for
developing new operations. There are many operations that developers find they
need that are not supported in current APIs. In most cases, this is not due to
limitations in the capabilities of the hardware but rather to restrictions in
the APIs. In general, these operations are also simpler and therefore faster
than trying to extract the same behavior by contorting a fixed function API to
an extent beyond its designer's expectations. Examples of new features expected
to be commonly implemented include the following: * Matrix Palette Skinning.
Character animation with 8-10 bones per mesh. * Anisotropic Lighting. Lighting
that currently can be done only at the cost of textures for look-up tables. *
Membrane Shaders. Shaders for balloons, skin, and so on (1/cos(eye DOT normal).
* Kubelka-Munk Shaders. Shaders that take into account light that penetrates
the surface. * Procedural Geometry. Compositing meshes with procedural ones
(spheres) to simulate muscles moving under the skin. * Displacement Mapping.
Modifying a mesh with a wave pattern or hump that can be tiled/repeated. Third,
a procedural model provides for scalability and evolvability. Hardware
capabilities are continuing to evolve rapidly, and programmatic representations
can help adapt the API because they scale very well. New features and
capabilities can be easily exposed in an incremental way by the following
operations. * Adding new instructions * Adding new data inputs * Adding new
capabilities from the fixed-function to the programmable portion of the
pipeline Code is the representation that has the best scaling properties for
representing complexity. Further, the amount of code that must change inside
Direct3D is very small for new features added to the programmable shaders.
Fourth, a procedural model offers familiarity. Software developers understand
programming better than they do hardware. An API that truly caters to software
developers should map hardware functionality into a code paradigm. Fifth, a
procedural model follows in the footsteps of a photo-real rendering heritage.
There has been a tradition of using programmable shaders in high-end photo-real
rendering for many years. In general, this area is unconstrained by
performance, so programmable shaders represent the ultimate no-compromise goal
for rendering technologies. Lastly, a procedural model enables direct mapping
to the hardware. Most current 3-D hardware, at the vertex processing stage at
least, is actually fairly programmable. The programmability through the API
enables the application to map directly to this hardware. This enables an you
to manage the hardware resources according to their requirements. With a
limited set of registers or instructions that can be executed, it is difficult
to make a fixed-function implementation that can have all its features enabled
independently. If you turn on too many features that require a shared resource,
they can stop working in unexpected ways. The programmable API model follows in
the DirectX tradition of eliminating this problem by letting the application
developer talk directly to the hardware, making any such limitations
transparent. Integration of Vertex Shaders into the Geometry Pipeline When in
operation, a programmable vertex shader replaces the transformation and
lighting module in the Microsoft® Direct3D® geometry pipeline. In effect, state
information regarding transformation and lighting operations are ignored.
However, when the vertex shader is disabled and fixed function processing is
returned, all current state settings apply. Any tessellation of high-order
primitives should be done before execution of the vertex shader.
Implementations that perform surface tessellation after the shader processing
must do so in a way that is not apparent to the application and shader code.
Because no semantic information is normally provided before the shader, a
special token is used to identify which input stream component represents the
base position relative to which all other components are interpolated. No
non-interpolable data channels are supported. On output, the vertex shader must
generate vertex positions in homogeneous clip space. Additional data that can
be generated includes texture coordinates, colors, fog factors and so on. The
standard graphics pipeline processes the vertices output by the shader,
including the following tasks. * Primitive assembly * Clipping against the
frustum and user clipping planes * Homogeneous divide * Viewport scaling *
Backface and viewport culling * Triangle setup * Rasterization Note that the
clipping space for DirectX 8.0 vertex shaders is the same as for DirectX 7.0
and DirectX 8.0 fixed function vertex processing. For details, see Clipping
Volumes. Programmable geometry is a mode within the Direct3D application
programming interface (API). When it is enabled, it partially replaces the
vertex pipeline. When it is disabled, the API has normal control—operating as
in DirectX 6.0 and 7.0. Execution of vertex shaders does not change the
internal Direct3D state, and no Direct3D state is available for shaders. [C++]
Calling IDirect3DDevice8::CreateVertexShader with the pFunction parameter equal
to NULL is used to create a shader for the fixed-function pipeline. When
pFunction is not NULL, the shader is programmable. A call to
IDirect3DDevice8::SetVertexShader sets the current active shader, which defines
whether the rendering pipeline should use programmable or fixed-function vertex
processing. [Visual Basic] Calling Direct3DDevice8.CreateVertexShader with the
FunctionTokenArray parameter equal to ByVal 0, is used to create a shader for
the fixed-function pipeline. When FunctionTokenArray is not ByVal 0, the shader
is programmable. A call to Direct3DDevice8.SetVertexShader sets the current
active shader, which defines whether the rendering pipeline should use
programmable or fixed-function vertex processing. Presenting Vertex Data to the
Vertex Processor Vertex data can be presented to the vertex processor using one
of the following formats. * Legacy FVF Format * Programmable Stream Model Note
The vertex data format that you choose is independent of and orthogonal to the
vertex processing method used (fixed function vs. programmable) For example,
you can use streams with fixed function transformation and lighting pipelines
and you can use FVF vertices with programmable vertex shaders. Legacy FVF
Format [C++] To use legacy FVF formats, use an FVF instead of a handle when
calling the IDirect3DDevice8::SetVertexShader method as shown in the code
example below. g_d3dDevice->SetVertexShader( CUSTOM_FVF ); [Visual Basic] To
use legacy FVF formats, use an FVF instead of a handle when calling the
Direct3DDevice8.SetVertexShader method as shown in the code example below. Call
m_D3DDevice.SetVertexShader(CUSTOM_FVF) This following topics cover legacy FVF
format types. * Vertex Legacy Type * LVertex Legacy Type * TLVertex Legacy Type
Vertex Legacy Type This topic shows the steps necessary to initialize and use
vertices that have a position, a normal, and texture coordinates. [C++] The
first step is to define the custom vertex type and FVF as shown in the code
example below. struct Vertex { FLOAT x, y, z; FLOAT nx, ny, nz; FLOAT tu, tv;
}; const DWORD VertexFVF = ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 ); The
next step is to create a vertex buffer with enough room for four vertices by
using the IDirect3DDevice8::CreateVertexBuffer method as shown in the code
example below. g_d3dDevice->CreateVertexBuffer( 4*sizeof(Vertex), VertexFVF,
D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT, &pBigSquareVB); The next step is to
manipulate the values for each vertex as shown in the code example below.
Vertex * v; pBigSquareVB->Lock( 0, 0, (BYTE**)&v, 0 ); v[0].x = 0.0f; v[0].y =
10.0; v[0].z = 10.0f; v[0].nx = 0.0f; v[0].ny = 1.0f; v[0].nz = 0.0f; v[0].tu =
0.0f; v[0].tv = 0.0f; v[1].x = 0.0f; v[1].y = 0.0f; v[1].z = 10.0f; v[1].nx =
0.0f; v[1].ny = 1.0f; v[1].nz = 0.0f; v[1].tu = 0.0f; v[1].tv = 0.0f; v[2].x =
10.0f; v[2].y = 10.0f; v[2].z = 10.0f; v[2].nx = 0.0f; v[2].ny = 1.0f; v[2].nz
= 0.0f; v[2].tu = 0.0f; v[2].tv = 0.0f; v[3].x = 0.0f; v[3].y = 10.0f; v[3].z =
10.0f; v[3].nx = 0.0f; v[3].ny = 1.0f; v[3].nz = 0.0f; v[3].tu = 0.0f; v[3].tv
= 0.0f; pBigSquareVB->Unlock(); The vertex buffer has been initialized and is
ready to render. The following code example shows how to use the legacy FVF to
draw a square. g_d3dDevice->SetVertexShader( VertexFVF );
g_d3dDevice->SetStreamSource( 0, pBigSquareVB, 4*sizeof(Vertex) );
g_d3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0 ,2); Passing an FVF to the
IDirect3DDevice8::SetVertexShader method tells Direct3D that a legacy FVF is
being used and that stream 0 is the only valid stream. [Visual Basic] The first
step is to define the custom vertex type and FVF as shown in the code example
below. Private Type Vertex x As Single y As Single z As Single nx As Single ny
As Single nz As Single tu As Single tv As Single End Type Const VertexFVF =
(D3DFVF_XYZ Or D3DFVF_NORMAL Or D3DFVF_TEX1) The next step is to create a
vertex buffer with enough room for four vertices by using the
Direct3DDevice8.CreateVertexBuffer method as shown in the code example below.
Set BigSquareVB = m_D3DDevice.CreateVertexBuffer( _ 4*len(Vertex), VertexFVF, _
D3DUSAGE_WRITEONLY, _ D3DPOOL_DEFAULT) The next step is to manipulate the
values for each vertex as shown in the code example below. Dim v(4) As Vertex
Call BigSquareVB.Lock(0, 0, v(), 0) v(0).x = 0.0: v(0).y = 10.0: v(0).z = 10.0
v(0).nx = 0.0: v(0).ny = 1.0: v(0).nz = 0.0 v(0).tu = 0.0: v(0).tv = 0.0 v(1).x
= 0.0: v(1).y = 0.0: v(1).z = 10.0 v(1).nx = 0.0: v(1).ny = 1.0: v(1).nz = 0.0
v(1).tu = 0.0: v(1).tv = 0.0 v(2).x = 10.0: v(2).y = 10.0: v(2).z = 10.0
v(2).nx = 0.0: v(2).ny = 1.0: v(2).nz = 0.0 v(2).tu = 0.0: v(2).tv = 0.0 v(3).x
= 0.0: v(3).y = 10.0: v(3).z = 10.0 v(3).nx = 0.0: v(3).ny = 1.0: v(3).nz = 0.0
v(3).tu = 0.0: v(3).tv = 0.0 BigSquareVB.Unlock The vertex buffer has been
initialized and is ready to render. The following code example shows how to use
the legacy FVF to draw a square. Call m_D3DDevice.SetVertexShader(VertexFVF)
Call m_D3DDevice.SetStreamSource(0, BigSquareVB, 4*len(Vertex)) Call
m_D3DDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0 ,2) Passing an FVF to the
Direct3DDevice8.SetVertexShader method tells Direct3D that a legacy FVF is
being used and that stream 0 is the only valid stream. LVertex Legacy Type This
topic shows the steps necessary to initialize and use vertices that have a
position, diffuse color, specular color, and texture coordinates. [C++] The
first step is to define the custom vertex type and FVF as shown in the code
example below. struct LVertex { FLOAT x, y, z; D3DCOLOR specular, diffuse;
FLOAT tu, tv; }; const DWORD VertexFVF = (D3DFVF_XYZ | D3DFVF_DIFFUSE |
D3DFVF_SPECULAR | D3DFVF_TEX1 ); The next step is to create a vertex buffer
with enough room for four vertices by using the
IDirect3DDevice8::CreateVertexBuffer method as shown in the code example below.
g_d3dDevice->CreateVertexBuffer( 4*sizeof(LVertex), VertexFVF,
D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT, &pBigSquareVB); The next step is to
manipulate the values for each vertex as shown in the code example below.
LVertex * v; pBigSquareVB->Lock( 0, 0, (BYTE**)&v, 0 ); v[0].x = 0.0f; v[0].y =
10.0; v[0].z = 10.0f; v[0].diffuse = 0xffff0000; v[0].specular = 0xff00ff00;
v[0].tu = 0.0f; v[0].tv = 0.0f; v[1].x = 0.0f; v[1].y = 0.0f; v[1].z = 10.0f;
v[1].diffuse = 0xff00ff00; v[1].specular = 0xff00ffff; v[1].tu = 0.0f; v[1].tv
= 0.0f; v[2].x = 10.0f; v[2].y = 10.0f; v[2].z = 10.0f; v[2].diffuse =
0xffff00ff; v[2].specular = 0xff000000; v[2].tu = 0.0f; v[2].tv = 0.0f; v[3].x
= 0.0f; v[3].y = 10.0f; v[3].z = 10.0f; v[3].diffuse = 0xffffff00;
v[3].specular = 0xffff0000; v[3].tu = 0.0f; v[3].tv = 0.0f;
pBigSquareVB->Unlock(); The vertex buffer has been initialized and is ready to
render. The following code example shows how to use the legacy FVF to draw a
square. g_d3dDevice->SetVertexShader( VertexFVF );
g_d3dDevice->SetStreamSource( 0, pBigSquareVB, 4*sizeof(LVertex) );
g_d3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0 ,2); Passing an FVF to the
IDirect3DDevice8::SetVertexShader method tells Direct3D that a legacy FVF is
being used and that stream 0 is the only valid stream. [Visual Basic] The first
step is to define the custom vertex type and FVF as shown in the code example
below. Private Type LVertex x As Single y As Single z As Single diffuse As Long
specular As Long tu As Single tv As Single End Type Const VertexFVF =
(D3DFVF_XYZ Or D3DFVF_DIFFUSE Or _ D3DFVF_SPECULAR Or D3DFVF_TEX1) The next
step is to create a vertex with enough room for four vertices buffer by using
the Direct3DDevice8.CreateVertexBuffer method as shown in the code example
below. Set BigSquareVB = m_D3DDevice.CreateVertexBuffer( _ 4*len(LVertex),
VertexFVF, _ D3DUSAGE_WRITEONLY, _ D3DPOOL_DEFAULT) The next step is to
manipulate the values for each vertex as shown in the code example below. Dim
v(4) As LVertex Call BigSquareVB.Lock(0, 0, v(), 0) v(0).x = 0.0: v(0).y =
10.0: v(0).z = 10.0 v(0).diffuse = &HFFFF0000; v(0).specular = &HFF00FF00;
v(0).tu = 0.0: v(0).tv = 0.0 v(1).x = 0.0: v(1).y = 0.0: v(1).z = 10.0
v(1).diffuse = &HFF00FF00; v(1).specular = &HFF00FFFF; v(1).tu = 0.0: v(1).tv =
0.0 v(2).x = 10.0: v(2).y = 10.0: v(2).z = 10.0 v(2).diffuse = &HFFFF00FF;
v(2).specular = &HFF000000; v(2).tu = 0.0: v(2).tv = 0.0 v(3).x = 0.0: v(3).y =
10.0: v(3).z = 10.0 v(3).diffuse = &HFFFFFF00; v(3).specular = &HFFFF0000;
v(3).tu = 0.0: v(3).tv = 0.0 BigSquareVB.Unlock The vertex buffer has been
initialized and is ready to render. The following code example shows how to use
the legacy FVF to draw a square. Call m_D3DDevice.SetVertexShader(VertexFVF)
Call m_D3DDevice.SetStreamSource(0, BigSquareVB, 4*len(LVertex)) Call
m_D3DDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0 ,2) Passing an FVF to the
Direct3DDevice8.SetVertexShader method tells Direct3D that a legacy FVF is
being used and that stream 0 is the only valid stream. TLVertex Legacy Type The
topic shows the steps necessary to initialize and use vertices that have a
transformed position, diffuse color, specular color, and texture coordinates.
[C++] The first step is to define the custom vertex type and FVF as shown in
the code example below. struct TLVertex { FLOAT x, y, z, rhw; D3DCOLOR
specular, diffuse; FLOAT tu, tv; }; const DWORD VertexFVF = (D3DFVF_XYZRHW |
D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1 ); The next step is to create a
vertex buffer with enough room for four vertices by using the
IDirect3DDevice8::CreateVertexBuffer method as shown in the code example below.
g_d3dDevice->CreateVertexBuffer( 4*sizeof(TLVertex), VertexFVF,
D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT, &pBigSquareVB); The next step is to
manipulate the values for each vertex as shown in the code example below.
TLVertex * v; pBigSquareVB->Lock( 0, 0, (BYTE**)&v, 0 ); v[0].x = 0.0f; v[0].y
= 10.0; v[0].z = 10.0f; v[0].rhw = 1.0f; v[0].diffuse = 0xffff0000;
v[0].specular = 0xff00ff00; v[0].tu = 0.0f; v[0].tv = 0.0f; v[1].x = 0.0f;
v[1].y = 0.0f; v[1].z = 10.0f; v[1].rhw = 1.0f; v[1].diffuse = 0xff00ff00;
v[1].specular = 0xff00ffff; v[1].tu = 0.0f; v[1].tv = 0.0f; v[2].x = 10.0f;
v[2].y = 10.0f; v[2].z = 10.0f; v[2].rhw = 1.0f; v[2].diffuse = 0xffff00ff;
v[2].specular = 0xff000000; v[2].tu = 0.0f; v[2].tv = 0.0f; v[3].x = 0.0f;
v[3].y = 10.0f; v[3].z = 10.0f; v[3].rhw = 1.0f; v[3].diffuse = 0xffffff00;
v[3].specular = 0xffff0000; v[3].tu = 0.0f; v[3].tv = 0.0f;
pBigSquareVB->Unlock(); The vertex buffer has been initialized and is ready to
render. The following code example shows how to use the legacy FVF to draw a
square. g_d3dDevice->SetVertexShader( VertexFVF );
g_d3dDevice->SetStreamSource( 0, pBigSquareVB, 4*sizeof(TLVertex) );
g_d3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0 ,2); Passing an FVF to the
IDirect3DDevice8::SetVertexShader method tells Direct3D that a legacy FVF is
being used and that stream 0 is the only valid stream. [Visual Basic] The first
step is to define the custom vertex type and FVF as shown in the code example
below. Private Type TLVertex x As Single y As Single z As Single rhw As Single
diffuse As Long specular As Long tu As Single tv As Single End Type Const
VertexFVF = (D3DFVF_XYZRHW Or D3DFVF_DIFFUSE Or _ D3DFVF_SPECULAR Or
D3DFVF_TEX1) The next step is to create a vertex buffer with enough room for
four vertices by using the Direct3DDevice8.CreateVertexBuffer method as shown
in the code example below. Set BigSquareVB = m_D3DDevice.CreateVertexBuffer( _
4*len(TLVertex), VertexFVF, _ D3DUSAGE_WRITEONLY, D3DPOOL_DEFAULT) The next
step is to manipulate the values for each vertex as shown in the code example
below. Dim v(4) As TLVertex Call BigSquareVB.Lock(0, 0, v(), 0) v(0).x = 0.0:
v(0).y = 10.0: v(0).z = 10.0: v(0).rhw = 1.0 v(0).diffuse = &HFFFF0000;
v(0).specular = &HFF00FF00; v(0).tu = 0.0: v(0).tv = 0.0 v(1).x = 0.0: v(1).y =
0.0: v(1).z = 10.0: v(1).rhw = 1.0 v(1).diffuse = &HFF00FF00; v(1).specular =
&HFF00FFFF; v(1).tu = 0.0: v(1).tv = 0.0 v(2).x = 10.0: v(2).y = 10.0: v(2).z =
10.0: v(2).rhw = 1.0 v(2).diffuse = &HFFFF00FF; v(2).specular = &HFF000000;
v(2).tu = 0.0: v(2).tv = 0.0 v(3).x = 0.0: v(3).y = 10.0: v(3).z = 10.0:
v(3).rhw = 1.0 v(3).diffuse = &HFFFFFF00; v(3).specular = &HFFFF0000; v(3).tu =
0.0: v(3).tv = 0.0 BigSquareVB.Unlock The vertex buffer has been initialized
and is ready to render. The following code example shows how to use the legacy
FVF to draw a square. Call m_D3DDevice.SetVertexShader(VertexFVF) Call
m_D3DDevice.SetStreamSource(0, BigSquareVB, 4*len(TLVertex)) Call
m_D3DDevice.DrawPrimitive(D3DPT_TRIANGLESTRIP, 0 ,2) Passing an FVF to the
Direct3DDevice8.SetVertexShader method tells Direct3D that a legacy FVF is
being used and that stream 0 is the only valid stream. Programmable Stream
Model This following sections cover shaders that can be used for the
programmable stream model. * ColorVertex Shader * SingleTexture Shader *
MultiTexture Shader ColorVertex Shader This topic shows the steps necessary to
initialize and use a simple vertex shader that uses a position and a diffuse
color. [C++] The first step is to declare the structures that hold the position
and color as shown in the code example below. struct XYZBuff { FLOAT x, y, z;
D3DCOLOR color; }; struct ColBuf { D3DCOLOR color; }; #define XYZBUFF
(D3DFVF_XYZ) #define COLBUFF (D3DFVF_DIFFUSE) The next step is to create a
Vertex Shader Declaration as shown in the code below. DWORD decl[] = {
D3DVSD_STREAM(0), D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),
D3DVSD_STREAM(1), D3DVSD_REG( D3DVSDE_DIFFUSE, D3DVSDT_D3DCOLOR), D3DVSD_END()
}; The next step is to call the IDirect3DDevice8::CreateVertexShader method to
create the vertex shader. g_d3dDevice->CreateVertexShader( decl, NULL,
&vShader, 0); Passing NULL to the second parameter of CreateVertexShader tells
Direct3D that this vertex shader will use a fixed function pipeline. After
creating the vertex buffer and vertex shader, they are ready to use. The code
example below shows how to set the vertex shader, set the stream source, and
then draw a triangle list that uses the new vertex shader.
g_d3dDevice->SetVertexShader( &vShader ); g_d3dDevice->SetStreamSource( 0,
xyzbuf, 4 * sizeof(FLOAT)); g_d3dDevice->SetStreamSource( 1, colbuf, 2 *
sizeof(FLOAT)); g_d3dDevice->SetIndices( pIB, 0 );
g_d3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, max - min + 1, 0,
count / 3 ); [Visual Basic] The first step is to declare the structures that
hold the position and color as shown in the code example below. Private Type
XYZBuff x As Single y As Single z As Single End Type Private Type ColBuf color
As Long End Type Const XYZBUFF_FVF = (D3DFVF_XYZ) Const COLBUFF_FVF =
(D3DFVF_DIFFUSE) The next step is to create a Vertex Shader Declaration as
shown in the code below. Dim decl(5) As Long decl(0) = D3DVSD_STREAM(0) decl(1)
= D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3) decl(2) = D3DVSD_STREAM(1)
decl(3) = D3DVSD_REG( D3DVSDE_DIFFUSE, D3DVSDT_UBYTE) decl(4) = D3DVSD_END()
The next step is to call the Direct3DDevice8.CreateVertexShader method to
create the vertex shader. Call m_D3DDevice.CreateVertexShader( decl, ByVal 0,
vShader, 0) Passing ByVal 0 to the second parameter of CreateVertexShader tells
Direct3D that this vertex shader will use a fixed function pipeline. After
creating the vertex buffer and vertex shader, they are ready to use. The code
example below shows how to set the vertex shader, set the stream source, and
then draw a triangle list that uses the new vertex shader. Call
m_D3DDevice.SetVertexShader( vShader ) Call m_D3DDevice.SetStreamSource( 0,
xyzbuf, 4 * len(xyzbuf)) Call m_D3DDevice.SetStreamSource( 1, colbuf, 2 *
len(colbuf)) Call m_D3DDevice.SetIndices( IB, 0 ) Call
m_D3DDevice.DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, max - min + 1, 0,
count / 3 ) SingleTexture Shader This topic shows the steps necessary to
initialize and use a simple vertex shader that uses a position and texture
coordinates. [C++] The first step is to declare the structures that hold the
position and texture coordinates as shown in the code example below. struct
XYZBuff { D3DVALUE x, y, z; }; struct TEX0Buff { D3DVALUE tu, tv; }; #define
XYZBUFF (D3DFVF_XYZ) #define TEX0BUFF (D3DFVF_TEX1) The next step is to create
a Vertex Shader Declaration as shown in the code below. DWORD decl[] = {
D3DVSD_STREAM(0), D3DVSD_REG( D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),
D3DVSD_STREAM(1), D3DVSD_REG( D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2 ), D3DVSD_END()
}; The next step is to call the IDirect3DDevice8::CreateVertexShader method to
create the vertex shader. g_d3dDevice->CreateVertexShader( decl, NULL,
&vShader, 0); Passing NULL to the second parameter of CreateVertexShader tells
Direct3D that this vertex shader will use a fixed function pipeline. After
creating the vertex buffer and vertex shader, they are ready to use. The code
example below shows how to set the vertex shader, set the stream source, and
then draw a triangle list that uses the new vertex shader.
g_d3dDevice->SetVertexShader( &vShader ); g_d3dDevice->SetStreamSource( 0,
xyzbuf, 4 * sizeof(FLOAT)); g_d3dDevice->SetStreamSource( 1, tex0buf, 2 *
sizeof(FLOAT)); g_d3dDevice->SetIndices( pIB, 0 );
g_d3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, max - min + 1, 0,
count / 3 ); [Visual Basic] The first step is to declare the structures that
hold the position and color as shown in the code example below. Private Type
XYZBuff x As Single y As Single z As Single End Type Private Type Tex0Buf tu As
Single tv As Single End Type Const XYZBUFF_FVF = (D3DFVF_XYZ) Const
TEX0BUFF_FVF = (D3DFVF_TEX1) The next step is to create a Vertex Shader
Declaration as shown in the code below. Dim decl(5) As Long decl(0) =
D3DVSD_STREAM(0) decl(1) = D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3) decl(2)
= D3DVSD_STREAM(1) decl(3) = D3DVSD_REG(D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2)
decl(4) = D3DVSD_END() The next step is to call the
Direct3DDevice8.CreateVertexShader method to create the vertex shader. Call
m_D3DDevice.CreateVertexShader( decl, ByVal 0, vShader, 0) Passing ByVal 0 to
the second parameter of CreateVertexShader tells Direct3D that this vertex
shader will use a fixed function pipeline. After creating the vertex buffer and
vertex shader, they are ready to use. The code example below shows how to set
the vertex shader, set the stream source, and then draw a triangle list that
uses the new vertex shader. Call m_D3DDevice.SetVertexShader( vShader ) Call
m_D3DDevice.SetStreamSource( 0, xyzbuf, 4 * len(xyzbuf)) Call
m_D3DDevice.SetStreamSource( 1, tex0buf, 2 * len(colbuf)) Call
m_D3DDevice.SetIndices( IB, 0 ) Call m_D3DDevice.DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, 0, max - min + 1, 0, count / 3 ) MultiTexture Shader This
topic shows the steps necessary to initialize and use a simple vertex shader
that uses a position and multiple texture coordinates for multiple textures.
[C++] The first step is to declare the structures that holds the position and
color as shown in the code example below. struct XYZBuff { D3DVALUE x, y, z; };
struct Tex0Buff { D3DVALUE tu, tv; }; struct Tex1Buff { D3DVALUE tu2, tv2; };
#define XYZBUFF (D3DFVF_XYZ) #define TEX0BUFF (D3DFVF_TEX1) #define TEX1BUFF
(D3DFVF_TEX1) The next step is to create a Vertex Shader Declaration as shown
in the code below. DWORD decl[] = { D3DVSD_STREAM(0), D3DVSD_REG(
D3DVSDE_POSITION, D3DVSDT_FLOAT3 ), D3DVSD_STREAM(1), D3DVSD_REG(
D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2), D3DVSD_STREAM(2), D3DVSD_REG(
D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2), D3DVSD_END() }; The next step is to call
the IDirect3DDevice8::CreateVertexShader method to create the vertex shader.
g_d3dDevice->CreateVertexShader( decl, NULL, &vShader, 0); Passing NULL to the
second parameter of CreateVertexShader tells Direct3D that this vertex shader
will use a fixed function pipeline. After creating the vertex buffer and vertex
shader, they are ready to use. The code example below shows how to set the
vertex shader, set the stream source, and then draw a triangle list that uses
the new vertex shader. g_d3dDevice->SetVertexShader( &vShader ); //JM I think
it should be 3* sizeof()below … g_d3dDevice->SetStreamSource( 0, xyzbuf, 4 *
sizeof(FLOAT)); g_d3dDevice->SetStreamSource( 1, tex0buf, 2 * sizeof(FLOAT));
g_d3dDevice->SetStreamSource( 2, tex1buf, 2 * sizeof(FLOAT));
g_d3dDevice->SetIndices( pIB, 0 ); g_d3dDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, 0, max - min + 1, 0, count / 3 ); [Visual Basic] The first
step is to declare the structures that holds the position and color as shown in
the code example below. Private Type XYZBUFF x As Single y As Single z As
Single End Type Private Type TEX0BUFF tu As Single tv As Single End Type
Private Type TEX1BUFF tu2 As Single tv2 As Single End Type Const XYZBUFF_FVF =
(D3DFVF_XYZ) Const TEX0BUFF_FVF = (D3DFVF_TEX1) Const TEX1BUFF_FVF =
(D3DFVF_TEX1) The next step is to create a Vertex Shader Declaration as shown
in the code below. Dim decl(7) As Long decl(0) = D3DVSD_STREAM(0) decl(1) =
D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3) decl(2) = D3DVSD_STREAM(1) decl(3)
= D3DVSD_REG( D3DVSDE_TEXCOORD0, D3DVSDT_FLOAT2) decl(4) = D3DVSD_STREAM(2)
decl(5) = D3DVSD_REG( D3DVSDE_TEXCOORD1, D3DVSDT_FLOAT2) decl(6) = D3DVSD_END()
The next step is to call the Direct3DDevice8.CreateVertexShader method to
create the vertex shader. Call m_D3DDevice.CreateVertexShader( decl, ByVal 0,
vShader, 0) Passing ByVal 0 to the second parameter of CreateVertexShader tells
Direct3D that this vertex shader will use a fixed function pipeline. After
creating the vertex buffer and vertex shader, they are ready to use. The code
example below shows how to set the vertex shader, set the stream source, and
then draw a triangle list that uses the new vertex shader. Call
m_D3DDevice.SetVertexShader( vShader ) Call m_D3DDevice.SetStreamSource( 0,
xyzbuf, 4 * len(xyzbuf)) Call m_D3DDevice.SetStreamSource( 1, tex0buf, 2 *
len(colbuf)) Call m_D3DDevice.SetStreamSource( 2, tex0buf, 2 * len(colbuf))
Call m_D3DDevice.SetIndices( IB, 0 ) Call m_D3DDevice.DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, 0, max - min + 1, 0, count / 3 ) Using DirectX Graphics
This section is a guide to using the Microsoft® Direct3D® and Direct3DX APIs in
application development. Information is presented in the following topics. *
Direct3D Object * Direct3D Device * Direct3D Resources * Surfaces * Lights *
Materials * Vertex Formats * Textures * Depth Buffers * Stencil Buffers *
Vertex Buffers * Index Buffers * Techniques and Special Effects For a more
general overview, see Getting Started with DirectX Graphics. For an
understanding of the general mechanisms of data flow and organization, see
Understanding DirectX Graphics. For information on advanced features such as
programmable shaders, see Advanced Topics in DirectX Graphics. Direct3D Object
This section contains information about the Microsoft® Direct3D® object. * What
is a Direct3D Object? * Accessing Direct3D What is a Direct3D Object?
Microsoft® Direct3D® is implemented through COM objects and interfaces.
Applications written in C++ access these interfaces and objects directly,
whereas Microsoft Visual Basic® applications interact with a layer of
code—visible as the Microsoft DirectX® for Visual Basic Classes—that marshals
data from a Visual Basic application to the DirectX run time. The Direct3D
object is the first object that your application creates and the last object
that your application releases. Functions for enumerating and retrieving
capabilities of a Direct3D device are accessible through the Direct3D object.
This enables applications to select devices without creating them. Accessing
Direct3D [C++] When a Microsoft® Direct3D® application written in C++ starts,
it must obtain a pointer to an IDirect3D8 interface to access Direct3D
functionality. The following code example shows how to use the Direct3DCreate8
function to retrieve a pointer to the Direct3D interface. LPDIRECT3D8 g_pD3D =
NULL; if( NULL == (g_pD3D = Direct3DCreate8(D3D_SDK_VERSION))) return E_FAIL;
To navigate from the Direct3DDevice object to the Direct3D object that created
the device, use the IDirect3DDevice8::GetDirect3D method. [Visual Basic] When a
Microsoft® Direct3D® application written in Microsoft Visual Basic® starts, it
must obtain a reference to the Direct3D8 class to access Direct3D
functionality. The following code example shows how to use the
DirectX8.Direct3DCreate method to retrieve a reference to the Direct3D class.
Dim g_DX As New DirectX8 Dim g_D3D As Direct3D8 Set g_D3D =
g_DX.Direct3DCreate() If g_D3D Is Nothing Then Exit Function To navigate from
the Direct3DDevice object to the Direct3D object that created the device, use
the Direct3DDevice8.GetDirect3D method. Direct3D Device This section provides
an overview of Microsoft® Direct3D® devices. The overview is divided into the
following topics. * What is a Direct3D Device? * Device Types *
Device-Supported Primitive Types * Using Devices * Device States * Lost Devices
What is a Direct3D Device? A Microsoft® Direct3D® device is the rendering
component of Direct3D. It encapsulates and stores the rendering state. In
addition, a Direct3D device performs transformations and lighting operations
and rasterizes an image to a surface. Architecturally, Direct3D devices contain
a transformation module, a lighting module, and a rasterizing module, as the
following illustration shows. Direct3D enables applications that use custom
transformation and lighting models to bypass the Direct3D device's
transformation and lighting modules. For details, see Vertex Shaders. Device
Types This section introduces Microsoft® Direct3D® devices and presents
information for each type of device. The following topics are discussed. *
About Device Types * HAL Device * Reference Device * Pluggable Software Device
* Device Behaviors About Device Types Microsoft® Direct3D® currently supports
three main types of Direct3D devices: a hardware abstraction layer (HAL) device
with hardware-accelerated rasterization and shading with both hardware and
software vertex processing; a reference device; and a pluggable software device
(providing software rasterization). You can think of these three devices as
three separate drivers. Software and reference devices are represented by
software drivers, and the HAL device is represented by a hardware driver. The
most common way to take advantage of these devices is to use the HAL device for
shipping applications, and the reference device for feature testing. These are
provided by third parties to emulate particular devices—for example,
developmental hardware that has not yet been released. The Direct3D device that
an application creates must correspond to the capabilities of the hardware on
which the application is running. Direct3D provides rendering capabilities,
either by accessing 3-D hardware that is installed in the computer or by
emulating the capabilities of 3-D hardware in software. Therefore, Direct3D
provides devices for both hardware access and software emulation.
Hardware-accelerated devices give much better performance than software
devices. The HAL device type is available on all Direct3D supported graphic
adapters. In most cases, applications target computers that have hardware
acceleration and rely on software emulation to accommodate lower-end computers.
With the exception of the reference device, software devices do not always
support the same features as a hardware device. Applications should always
query for device capabilities to determine which features are supported.
Because the behavior of the software and reference devices provided with
Microsoft DirectX® 8.0 is identical to that of the HAL device, application code
authored to work with the HAL device will work with the software or reference
devices without modifications. Note that while the provided software or
reference device behavior is identical to that of the HAL device, the device
capabilities do vary, and a particular software device may implement a much
smaller set of capabilities. HAL Device The primary device type is the hardware
abstraction layer (HAL) device, which supports hardware accelerated
rasterization and both hardware and software vertex processing. If the computer
on which your application is running is equipped with a display adapter that
supports Microsoft® Direct3D®, your application should use it for 3-D
operations. Direct3D HAL devices implement all or part of the transformation,
lighting, and rasterizing modules in hardware. Applications do not access 3-D
cards directly. They call Direct3D functions and methods. Direct3D accesses the
hardware through the HAL. If the computer that your application is running on
supports the HAL, it will gain the best performance by using a HAL device.
[C++] To create a HAL device from C++, call the IDirect3D8::CreateDevice
method, and pass the D3DDEVTYPE_HAL constant as the device type. For details,
see Creating a Device. [Visual Basic] To create a HAL device from Microsoft
Visual Basic®, call the Direct3D8.CreateDevice method, and pass D3DDEVTYPE_HAL
constant as the device type. For details, see Creating a Device. Note Hardware
devices cannot render to 8-bit render-target surfaces. Reference Device
Microsoft® Direct3D® supports an additional device type called a reference
device or reference rasterizer. Unlike a software device, the reference
rasterizer supports every Direct3D feature. Because these features are
implemented for accuracy, rather than speed, and are implemented in software,
the results are not very fast. The reference rasterizer does make use of
special CPU instructions whenever it can, but it is not intended for retail
applications. Use the reference rasterizer only for feature testing or
demonstration purposes. [C++] To create a reference device from C++, call the
IDirect3D8::CreateDevice method, and pass the D3DDEVTYPE_REF constant as the
device type. For details, see Creating a Device. [Visual Basic] To create a
reference device from Microsoft Visual Basic®, call the Direct3D8.CreateDevice
method, and pass the D3DDEVTYPE_HAL constant as the device type. For details,
see Creating a Device. Pluggable Software Device If the user's computer
provides no special hardware acceleration for 3-D operations, your application
might emulate 3-D hardware in software. Software rasterization devices emulate
the functions of color 3-D hardware in software. Because a software device is
emulated in software, it runs more slowly than a hardware abstraction layer
(HAL) device. However, software devices take advantage of any special
instructions supported by the user's CPU to increase performance. Instruction
sets include the AMD 3D-Now! instruction set on some AMD processors and the MMX
instruction set supported by many Intel processors. Microsoft® Direct3D uses
the 3D-Now! instruction set to accelerate transformation and lighting
operations and the MMX instruction set to accelerate rasterization. Software
rasterization for Direct3D® is provided by pluggable software devices, which
enable applications to access a variety of software rasterizers through the
Direct3D interfaces. Software devices are loaded by the application and
registered with the Direct3D object, at which point you can create a
Direct3DDevice object that will perform rendering with the software device.
Direct3D software devices communicate with Direct3D through an interface
similar to the hardware device driver interface (DDI). The Direct3D DDK
provides the documentation and headers for developing pluggable software
devices. Device Behaviors [C++] Microsoft® Direct3D® enables you to specify the
behavior of a device, as well the device's type. The IDirect3D8::CreateDevice
method enables a combination of one or more of the behavior flags to control
the global behaviors of the Direct3D device. These behaviors specify what is
and is not maintained in the run-time portion of Direct3D, and the device types
specify which driver to use. Although some combinations of device behaviors are
not valid, it is possible to use all device behaviors with all device types.
For example, it is valid to specify D3DDEVTYPE_SW on a device created with
D3DCREATE_PUREDEVICE. [Visual Basic] Microsoft® Direct3D® enables you to
specify the behavior and the type of a device. The Direct3D8.CreateDevice
method enables a combination of one or more of the behavior flags to control
the global behaviors of the Direct3D device. These behaviors specify what is
and is not maintained in the run-time portion of Direct3D, and the device types
specify which driver to use. Although some combinations of device behaviors are
not valid, it is possible to use all device behaviors with all device types.
For example, it is valid to specify the D3DDEVTYPE_SW member of the
CONST_D3DDEVTYPE enumeration on a device created with the D3DCREATE_PUREDEVICE
member of the CONST_D3DCREATEFLAGS enumeration. Device-Supported Primitive
Types Microsoft® Direct3D® devices can create and manipulate the following
types of primitives. * Point Lists * Line Lists * Line Strips * Triangle Lists
* Triangle Strips * Triangle Fans [C++] You can render primitive types from a
C++ application with any of the rendering methods of the IDirect3DDevice8
interface. For more information, see Rendering. [Visual Basic] You can render
primitive types from a Microsoft Visual Basic® application with any of the
rendering methods of the Direct3DDevice8 class. For more information, see
Rendering. Note that you cannot render point lists with the indexed-primitive
rendering methods. Point Lists A point list is a collection of vertices that
are rendered as isolated points. Your application can use them in 3-D scenes
for star fields, or dotted lines on the surface of a polygon. The following
illustration depicts a rendered point list. Your application can apply
materials and textures to a point list. The colors in the material or texture
appear only at the points drawn, and not anywhere between the points. [C++] The
following code shows how to create vertices for this point list. struct
CUSTOMVERTEX { float x,y,z; }; CUSTOMVERTEX Vertices[] = { {-5.0, -5.0, 0.0}, {
0.0, 5.0, 0.0}, { 5.0, -5.0, 0.0}, {10.0, 5.0, 0.0}, {15.0, -5.0, 0.0}, {20.0,
5.0, 0.0} }; The code example below shows how to use
IDirect3DDevice8::DrawPrimitive to render this point list. // // It is assumed
that d3dDevice is a valid // pointer to a IDirect3DDevice8 interface. //
d3dDevice->DrawPrimitive( D3DPT_POINTLIST, 0, 6 ); [Visual Basic] The following
code shows how to create vertices for this point list. Private Type
CUSTOMVERTEX x As Single y As Single z As Single End Type Dim Vertices(5) As
CUSTOMVERTEX With Vertices(0): .x = -5.0: .y = -5.0: .z = 0.0: End With With
Vertices(1): .x = 0.0: .y = 5.0: .z = 0.0: End With With Vertices(2): .x = 5.0:
.y = -5.0: .z = 0.0: End With With Vertices(3): .x = 10.0: .y = 5.0: .z = 0.0:
End With With Vertices(4): .x = 15.0: .y = -5.0: .z = 0.0: End With With
Vertices(5): .x = 20.0: .y = 5.0: .z = 0.0: End With Line Lists A line list is
a list of isolated, straight line segments. Line lists are useful for such
tasks as adding sleet or heavy rain to a 3-D scene. Applications create a line
list by filling an array of vertices, and the number of vertices in a line list
must be an even number greater than or equal to two. The following illustration
shows a rendered line list. You can apply materials and textures to a line
list. The colors in the material or texture appear only along the lines drawn,
not at any point in between the lines. [C++] The following code shows how to
create vertices for this line list. struct CUSTOMVERTEX { float x,y,z; };
CUSTOMVERTEX Vertices[] = { {-5.0, -5.0, 0.0}, { 0.0, 5.0, 0.0}, { 5.0, -5.0,
0.0}, {10.0, 5.0, 0.0}, {15.0, -5.0, 0.0}, {20.0, 5.0, 0.0} }; The code example
below shows how to use IDirect3DDevice8::DrawPrimitive to render this line
list. // // It is assumed that d3dDevice is a valid // pointer to a
IDirect3DDevice8 interface. // d3dDevice->DrawPrimitive( D3DPT_LINELIST, 0, 3
); [Visual Basic] The following code shows how to create vertices for this line
list. Private Type CUSTOMVERTEX x As Single y As Single z As Single End Type
Dim Vertices(5) As CUSTOMVERTEX With Vertices(0): .x = -5.0: .y = -5.0: .z =
0.0: End With With Vertices(1): .x = 0.0: .y = 5.0: .z = 0.0: End With With
Vertices(2): .x = 5.0: .y = -5.0: .z = 0.0: End With With Vertices(3): .x =
10.0: .y = 5.0: .z = 0.0: End With With Vertices(4): .x = 15.0: .y = -5.0: .z =
0.0: End With With Vertices(5): .x = 20.0: .y = 5.0: .z = 0.0: End With Line
Strips A line strip is a primitive that is composed of connected line segments.
Your application can use line strips for creating polygons that are not closed.
A closed polygon is a polygon whose last vertex is connected to its first
vertex by a line segment. If your application makes polygons based on line
strips, the vertices are not guaranteed to be coplanar. The following
illustration depicts a rendered line strip. [C++] The following code shows how
to create vertices for this line strip. struct CUSTOMVERTEX { float x,y,z; };
CUSTOMVERTEX Vertices[] = { {-5.0, -5.0, 0.0}, { 0.0, 5.0, 0.0}, { 5.0, -5.0,
0.0}, {10.0, 5.0, 0.0}, {15.0, -5.0, 0.0}, {20.0, 5.0, 0.0} }; The code example
below shows how to use IDirect3DDevice8::DrawPrimitive to render this line
strip. // // It is assumed that d3dDevice is a valid // pointer to a
IDirect3DDevice8 interface. // d3dDevice->DrawPrimitive( D3DPT_LINESTRIP, 0, 5
); [Visual Basic] The following code shows how to create vertices for this line
strip. Private Type CUSTOMVERTEX x As Single y As Single z As Single End Type
Dim Vertices(5) As CUSTOMVERTEX With Vertices(0): .x = -5.0: .y = -5.0: .z =
0.0: End With With Vertices(1): .x = 0.0: .y = 5.0: .z = 0.0: End With With
Vertices(2): .x = 5.0: .y = -5.0: .z = 0.0: End With With Vertices(3): .x =
10.0: .y = 5.0: .z = 0.0: End With With Vertices(4): .x = 15.0: .y = -5.0: .z =
0.0: End With With Vertices(5): .x = 20.0: .y = 5.0: .z = 0.0: End With
Triangle Lists A triangle list is a list of isolated triangles. They might or
might not be near each other. A triangle list must have at least three
vertices. The total number of vertices must be divisible by three. Use triangle
lists to create an object that is composed of disjoint pieces. For instance,
one way to create a force-field wall in a 3-D game is to specify a large list
of small, unconnected triangles. Then apply a material and texture that appears
to emit light to the triangle list. Each triangle in the wall appears to glow.
The scene behind the wall becomes partially visible through the gaps between
the triangles, as a player might expect when looking at a force field. Triangle
lists are also useful for creating primitives that have sharp edges and are
shaded with Gouraud shading. See Face and Vertex Normal Vectors. The following
illustration depicts a rendered triangle list. [C++] The following code shows
how to create vertices for this triangle list. struct CUSTOMVERTEX { float
x,y,z; }; CUSTOMVERTEX Vertices[] = { {-5.0, -5.0, 0.0}, { 0.0, 5.0, 0.0}, {
5.0, -5.0, 0.0}, {10.0, 5.0, 0.0}, {15.0, -5.0, 0.0}, {20.0, 5.0, 0.0} }; The
code example below shows how to use IDirect3DDevice8::DrawPrimitive to render
this triangle list. // // It is assumed that d3dDevice is a valid // pointer to
a IDirect3DDevice8 interface. // d3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST,
0, 2 ); [Visual Basic] The following code shows how to create vertices for this
triangle list. Private Type CUSTOMVERTEX x As Single y As Single z As Single
End Type Dim Vertices(5) As CUSTOMVERTEX With Vertices(0): .x = -5.0: .y =
-5.0: .z = 0.0: End With With Vertices(1): .x = 0.0: .y = 5.0: .z = 0.0: End
With With Vertices(2): .x = 5.0: .y = -5.0: .z = 0.0: End With With
Vertices(3): .x = 10.0: .y = 5.0: .z = 0.0: End With With Vertices(4): .x =
15.0: .y = -5.0: .z = 0.0: End With With Vertices(5): .x = 20.0: .y = 5.0: .z =
0.0: End With Triangle Strips A triangle strip is a series of connected
triangles. Because the triangles are connected, the application does not need
to repeatedly specify all three vertices for each triangle. For example, you
need only seven vertices to define the following triangle strip. The system
uses vertices v1, v2, and v3 to draw the first triangle, v2, v4, and v3 to draw
the second triangle, v3, v4, and v5 to draw the third, v4, v6, and v5 to draw
the fourth, and so on. Notice that the vertices of the second and fourth
triangles are out of order; this is required to make sure that all the
triangles are drawn in a clockwise orientation. Most objects in 3-D scenes are
composed of triangle strips. This is because triangle strips can be used to
specify complex objects in a way that makes efficient use of memory and
processing time. The following illustration depicts a rendered triangle strip.
[C++] The following code shows how to create vertices for this triangle strip.
struct CUSTOMVERTEX { float x,y,z; }; CUSTOMVERTEX Vertices[] = { {-5.0, -5.0,
0.0}, { 0.0, 5.0, 0.0}, { 5.0, -5.0, 0.0}, {10.0, 5.0, 0.0}, {15.0, -5.0, 0.0},
{20.0, 5.0, 0.0} }; The code example below shows how to use
IDirect3DDevice8::DrawPrimitive to render this triangle strip. // // It is
assumed that d3dDevice is a valid // pointer to a IDirect3DDevice8 interface.
// d3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 5 ); [Visual Basic] The
following code shows how to create vertices for this triangle strip. Private
Type CUSTOMVERTEX x As Single y As Single z As Single End Type Dim Vertices(5)
As CUSTOMVERTEX With Vertices(0): .x = -5.0: .y = -5.0: .z = 0.0: End With With
Vertices(1): .x = 0.0: .y = 5.0: .z = 0.0: End With With Vertices(2): .x = 5.0:
.y = -5.0: .z = 0.0: End With With Vertices(3): .x = 10.0: .y = 5.0: .z = 0.0:
End With With Vertices(4): .x = 15.0: .y = -5.0: .z = 0.0: End With With
Vertices(5): .x = 20.0: .y = 5.0: .z = 0.0: End With Triangle Fans A triangle
fan is similar to a triangle strip, except that all the triangles share one
vertex, as shown in the following illustration. The system uses vertices v2,
v3, and v1 to draw the first triangle, v3, v4, and v1 to draw the second
triangle, v4, v5, and v1 to draw the third triangle, and so on. When flat
shading is enabled, the system shades the triangle with the color from its
first vertex. This illustration depicts a rendered triangle fan. [C++] The
following code shows how to create vertices for this triangle fan. struct
CUSTOMVERTEX { float x,y,z; }; CUSTOMVERTEX Vertices[] = { { 0.0, 0.0, 0.0},
{-5.0, -5.0, 0.0}, {-3.0, 7.0, 0.0}, { 0.0, 10.0, 0.0}, { 3.0, 7.0, 0.0}, {
5.0, 5.0, 0.0}, }; The code example below shows how to use
IDirect3DDevice8::DrawPrimitive to render this triangle fan. // // It is
assumed that d3dDevice is a valid // pointer to a IDirect3DDevice8 interface.
// d3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 4 ); [Visual Basic] The
following code shows how to create vertices for this triangle fan. Private Type
CUSTOMVERTEX x As Single y As Single z As Single End Type Dim Vertices(5) As
CUSTOMVERTEX With Vertices(0): .x = 0.0: .y = 0.0: .z = 0.0: End With With
Vertices(1): .x = -5.0: .y = -5.0: .z = 0.0: End With With Vertices(2): .x =
-3.0: .y = 7.0: .z = 0.0: End With With Vertices(3): .x = 0.0: .y = 10.0: .z =
0.0: End With With Vertices(4): .x = 3.0: .y = 7.0: .z = 0.0: End With With
Vertices(5): .x = 5.0: .y = 5.0: .z = 0.0: End With Using Devices This section
provides information about using Microsoft® Direct3D® devices in an
application. Information is divided into the following topics. * Determining
Hardware Support * Selecting a Device * Creating a Device * Setting
Transformations * Processing Vertex Data * Working with Mouse Cursors *
Rendering Determining Hardware Support Direct3D provides the following
functions to determine hardware support. [C++] IDirect3D8::CheckDeviceFormat
Used to verify whether a surface format can be used as a texture, whether a
surface format can be used as a texture and a render target, or whether a
surface format can be used as a depth-stencil buffer. In addition, this method
is used to verify depth buffer format support and depth-stencil buffer format
support. IDirect3D8::CheckDeviceType Used to verify a device's ability to
perform hardware acceleration, a device's ability to build a swap chain for
presentation, or a device's ability to render to the current display format.
IDirect3D8::CheckDepthStencilMatch Used to verify whether a depth-stencil
buffer format is compatible with a render- target format. Note that before
calling this method, the application should call CheckDeviceFormat on both the
depth-stencil and render target formats. [Visual Basic]
Direct3D8.CheckDeviceFormat Used to verify whether a surface format can be used
as a texture, whether a surface format can be used as a texture and a render
target, or whether a surface format can be used as a depth-stencil buffer. In
addition, this method is used to verify depth-buffer format support and
depth-stencil buffer format support. Direct3D8.CheckDeviceType Used to verify a
device's ability to perform hardware acceleration, a device's ability to build
a swap chain for presentation, or a device's ability to render to the current
display format. Direct3D8.CheckDepthStencilMatch Used to verify whether a
depth-stencil buffer format is compatible with a render- target format. Note
that before calling this method, the application should call CheckDeviceFormat
on both the depth-stencil and render-target formats. Selecting a Device
Applications can query hardware to detect the supported Microsoft® Direct3D®
device types. This section contains information on the primary tasks involved
in enumerating display adapters and selecting Direct3D devices. An application
must perform a series of tasks to select an appropriate Direct3D device. Note
that the following steps are intended for a full-screen application. In most
cases, a windowed application can skip most of these steps. [C++] 1. Initially,
the application must enumerate the display adapters on the system. An adapter
is a physical piece of hardware. Note that the graphics card might contain more
than a single adapter, as is the case with a dual-head display. Applications
that are not concerned with multimonitor support can disregard this step, and
pass D3DADAPTER_DEFAULT to the IDirect3D8::EnumAdapterModes method in step 2.
2. For each adapter, the application enumerates the supported display modes by
calling EnumAdapterModes. 3. If required, the application checks for the
presence of hardware acceleration in each enumerated display mode by calling
IDirect3D8::CheckDeviceType, as shown in the following code example. Note that
this is only one of the possible uses for CheckDeviceType; for details, see
Determining Hardware Support. D3DPRESENT_PARAMETERS Params; // Initialize
values for D3DPRESENT_PARAMETERS members. Params.BackBufferFormat =
D3DFMT_X1R5G5B5; if(FAILED(m_pD3D->CheckDeviceType(Device.m_uAdapter,
Device.m_DevType, Params.BackBufferFormat, Params.BackBufferFormat, FALSE)))
return E_FAIL; 4. The application checks for the desired level of functionality
for the device on this adapter by calling the IDirect3D8::GetDeviceCaps method.
This method filters out those devices that do not support the required
functionality. The device capability returned by GetDeviceCaps is guaranteed to
be constant for a device across all display modes verified by CheckDeviceType.
5. Devices can always render to surfaces of the format of an enumerated display
mode that is supported by the device. If the application is required to render
to a surface of a different format, it can call IDirect3D8::CheckDeviceFormat.
If the device can render to the format, then it is guaranteed that all
capabilities returned by GetDeviceCaps are applicable. 6. Lastly, the
application can determine if multisampling techniques, such as full- scene
antialiasing, are supported for a render format by using the
IDirect3D8::CheckDeviceMultiSampleType method. [Visual Basic] 1. Initially, the
application must enumerate the display adapters on the system. An adapter is a
physical piece of hardware. Note that the graphics card might contain more than
a single adapter, as is the case with a dual-head display. Applications that
are not concerned with multimonitor support can disregard this step, and pass
D3DADAPTER_DEFAULT to the Direct3D8.EnumAdapterModes method in step 2. 2. For
each adapter, the application enumerates the supported display modes by calling
EnumAdapterModes. 3. If required, the application checks for the presence of
hardware acceleration in each enumerated display mode by calling
Direct3D8.CheckDeviceType. Note that this is only one of the possible uses for
CheckDeviceType. For details see Determining Hardware Support. 4. The
application checks for the desired level of functionality for the device on
this adapter by calling the Direct3D8.GetDeviceCaps method. This method filters
out those devices that do not support the required functionality. The device
capability returned by GetDeviceCaps is guaranteed to be constant for a device
across all display modes verified by CheckDeviceType. 5. Devices can always
render to surfaces of the format of an enumerated display mode that is
supported by the device. If the application is required to render to a surface
of a different format, it can call Direct3D8.CheckDeviceFormat. If the device
can render to the format, then it is guaranteed that all capabilities returned
by GetDeviceCaps are applicable. 6. Lastly, the application can determine if
multisampling techniques, such as full- scene antialiasing, are supported for a
render format by using the Direct3D8.CheckDeviceMultiSampleType method. After
completing the above steps, the application should have a list of display modes
in which it can operate. The final step is to verify that enough
device-accessible memory is available to accommodate the required number of
buffers and antialiasing. This test is necessary because the memory consumption
for the mode and multisample combination is impossible to predict without
verifying it. Moreover, some display adapter architectures might not have a
constant amount of device- accessible memory. This means that an application
should be able to report out-of- video-memory failures when going into
full-screen mode. Typically, an application should remove full-screen mode from
the list of modes it offers to a user, or it should attempt to consume less
memory by reducing the number of back buffers or using a less expensive
multisampling technique. [C++] A windowed application performs a similar set of
tasks. 1. It determines the desktop rectangle covered by the client area of the
window. 2. It enumerates adapters, looking for the adapter whose monitor covers
the client area. If the client area is owned by more than one adapter, then the
application can choose to drive each adapter independently, or to drive a
single adapter and have Direct3D transfer pixels from one device to another at
presentation. The application can also disregard the above two steps and use
the D3DADAPTER_DEFAULT adapter. Note that this might result in slower operation
when the window is placed on a secondary monitor. 3. The application should
call CheckDeviceType to determine if the device can support rendering to a back
buffer of the specified format while in desktop mode.
IDirect3D8::GetAdapterDisplayMode can be used to determine the desktop display
format, as shown in the following code example. D3DPRESENT_PARAMETERS Params;
// Initialize values for D3DPRESENT_PARAMETERS members. // Use the current
display mode. D3DDISPLAYMODE mode;
if(FAILED(m_pD3D->GetAdapterDisplayMode(Device.m_uAdapter , &mode))) return
E_FAIL; Params.BackBufferFormat = mode.Format;
if(FAILED(m_pD3D->CheckDeviceType(Device.m_uAdapter, Device.m_DevType,
Params.BackBufferFormat, Params.BackBufferFormat, FALSE))) return E_FAIL;
[Visual Basic] A windowed application performs a similar set of tasks. 1. It
determines the desktop rectangle covered by the client area of the window. 2.
It enumerates adapters, looking for the adapter whose monitor covers the client
area. If the client area is owned by more than one adapter, then the
application can choose to drive each adapter independently, or to drive a
single adapter and have Direct3D transfer pixels from one device to another at
presentation. The application can also disregard steps one and two and use the
D3DADAPTER_DEFAULT adapter. Note that this might result in slower operation
when the window is placed on a secondary monitor. 3. The application should
call CheckDeviceType to determine if the device can support rendering to a back
buffer of the specified format while in desktop mode.
Direct3D8.GetAdapterDisplayMode can be used to determine the desktop display
format. Creating a Device [C++] Note All rendering devices created by a given
Microsoft® Direct3D® object share the same physical resources. Although your
application can create multiple rendering devices from a single Direct3D
object, because they share the same hardware, extreme performance penalties
will be incurred. To create a Direct3D device in a C++ application, your
application must first create a Direct3D object, as explained in Accessing
Direct3D. First, initialize values for the D3DPRESENT_PARAMETERS structure that
is used to create the Direct3D device. The following code example specifies a
windowed application where the back buffer is flipped to the front buffer on
VSYNC only. LPDIRECT3DDEVICE8 d3dDevice = NULL; D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect =
D3DSWAPEFFECT_COPY_VSYNC; Next, create the Direct3D device. The following
IDirect3D8::CreateDevice call specifies the default adapter, a hardware
abstraction layer (HAL) device, and software vertex processing. if( FAILED(
g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3dDevice ) ) ) return E_FAIL;
Note that a call to create, release, or reset the device should happen only on
the same thread as the window procedure of the focus window. After creating the
device, set its state. [Visual Basic] Note All rendering devices created by a
given Microsoft® Direct3D® object share the same physical resources. Although
your application can create multiple rendering devices from a single Direct3D
object, because they share the same hardware, extreme performance penalties
will be incurred. To create a Direct3D device in a Microsoft Visual Basic®
application, your application must first create a Direct3D object, as explained
in Accessing Direct3D. First, initialize values for the D3DPRESENT_PARAMETERS
type that is used to create the Direct3D device. The following code example
specifies a windowed application where the back buffer is flipped to the front
buffer on VSYNC only. Dim d3dDevice As Direct3DDevice8 Dim d3dpp As
D3DPRESENT_PARAMETERS d3dpp.Windowed = 1 d3dpp.SwapEffect =
D3DSWAPEFFECT_COPY_VSYNC Next, create the Direct3D device. The following
Direct3D8.CreateDevice call specifies the default adapter, a hardware
abstraction layer (HAL) device, and software vertex processing. Set d3dDevice =
g_D3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, _
D3DCREATE_SOFTWARE_VERTEXPROCESSING, d3dpp) If d3dDevice Is Nothing Then Exit
Function After creating the device, set its state. Setting Transformations
[C++] In C++, transformations are applied by using the
Direct3DDevice8.SetTransform method. For example, you can use code like the
following to set the view transformation. HRESULT hr; D3DMATRIX view; // Fill
in the view matrix. hr = pDev->SetTransform(D3DTS_VIEW, &view); if(FAILED(hr))
{ // Code to handle the error goes here. } There are several possible settings
for the first parameter in a call to SetTransform. The most common are
D3DTS_WORLD, D3DTS_VIEW, and D3DTS_PROJECTION. These transformation states are
defined by the D3DTRANSFORMSTATETYPE enumerated type. This enumeration also
contains the states D3DTS_TEXTURE1 through D3DTS_TEXTURE7, which you can use to
apply transformations to texture coordinates. [Visual Basic] In Microsoft®
Visual Basic®, transformations are applied by using the
Direct3DDevice8.SetTransform method. For example, you could use code like the
following to set the view transformation. On Local Error Resume Next Dim view
As D3DMATRIX ' Fill in the view matrix. Call d3dDevice.SetTransform(D3DTS_VIEW,
view) If Err.Number <> DD_OK Then ' Code to handle the error goes here. End If
There are several possible settings for the first parameter in a call to
SetTransform. The most common are D3DTS_WORLD, D3DTS_VIEW, and
D3DTS_PROJECTION. These transformation states are defined by the
CONST_D3DTRANSFORMSTATETYPE enumeration. This enumeration also contains the
states D3DTS_TEXTURE1 through D3DTS_TEXTURE7, which you can use to apply
transformations to texture coordinates. Processing Vertex Data [C++] The
IDirect3DDevice8 interface supports vertex processing in both software and
hardware. In general, the device capabilities for software and hardware vertex
processing are not identical. Hardware capabilities are variable, depending on
the display adapter and driver, while software capabilities are fixed. The
following flags control vertex processing behavior for the hardware abstraction
layer (HAL) and reference devices. * D3DCREATE_SOFTWARE_VERTEXPROCESSING *
D3DCREATE_HARDWARE_VERTEXPROCESSING * D3DCREATE_MIXED_VERTEXPROCESSING Specify
one of the vertex processing behavior flags when calling
IDirect3D8::CreateDevice. The mixed-mode flag enables the device to perform
both software and hardware vertex processing. Only one vertex processing flag
may be set for a device at any one time. Note that the
D3DCREATE_HARDWARE_VERTEXPROCESSING flag is required to be set when creating a
pure device (D3DCREATE_PUREDEVICE). To avoid dual vertex processing
capabilities on a single device, only the hardware vertex processing
capabilities can be queried at run time. Software vertex processing
capabilities are fixed and cannot be queried at run time. You can consult the
VertexProcessingCaps member of the D3DCAPS8 structure to determine the hardware
vertex processing capabilities of the device. For software vertex processing
the following capabilities are supported. * D3DVTXPCAPS_DIRECTIONALLIGHTS *
D3DVTXPCAPS_LOCALVIEWER * D3DVTXPCAPS_MATERIALSOURCE7 *
D3DVTXPCAPS_POSITIONALLIGHTS * D3DVTXPCAPS_TEXGEN * D3DVTXPCAPS_TWEENING In
addition, the following table lists the values that are set for members of the
D3DCAPS8 structure for a device in software vertex processing mode. Member
Software Vertex Processing Capabilities MaxActiveLights Unlimited
MaxUserClipPlanes 6 MaxVertexBlendMatrices 4 MaxStreams 16 MaxVertexIndex
0xFFFFFFFF [Visual Basic] The Direct3DDevice8 class supports vertex processing
in both software and hardware. In general, the device capabilities for software
and hardware vertex processing are not identical. Hardware capabilities are
variable, depending on the display adapter and driver, while software
capabilities are fixed. The following flags control vertex processing behavior
for the hardware abstraction layer (HAL) and reference devices. *
D3DCREATE_SOFTWARE_VERTEXPROCESSING * D3DCREATE_HARDWARE_VERTEXPROCESSING *
D3DCREATE_MIXED_MODE_VERTEXPROCESSING Specify one of the vertex processing
behavior flags when calling Direct3D8.CreateDevice. The mixed-mode flag enables
the device to perform both software and hardware vertex processing. Only one
vertex processing flag may be set for a device at any one time. Note that the
D3DCREATE_HARDWARE_VERTEXPROCESSING flag is required to be set when creating a
pure device (D3DCREATE_PUREDEVICE). To avoid dual vertex processing
capabilities on a single device, only the hardware vertex processing
capabilities can be queried at run time. Software vertex processing
capabilities are fixed and cannot be queried at run time. You can consult the
VertexProcessingCaps member of the D3DCAPS8 structure to determine the hardware
vertex processing capabilities of the device. For software vertex processing
the following capabilities are supported. * D3DVTXPCAPS_DIRECTIONALLIGHTS *
D3DVTXPCAPS_LOCALVIEWER * D3DVTXPCAPS_MATERIALSOURCE7 *
D3DVTXPCAPS_POSITIONALLIGHTS * D3DVTXPCAPS_TEXGEN * D3DVTXPCAPS_TWEENING In the
addition, the following table lists the values that are set for members of the
D3DCAPS8 structure for a device in software vertex processing mode. Member
Software Vertex Processing Capabilities MaxActiveLights Unlimited
MaxUserClipPlanes 6 MaxVertexBlendMatrices 4 MaxStreams 16 MaxVertexIndex
0xFFFFFFFF Software vertex processing provides a guaranteed set of vertex
processing capabilities, including an unbounded number of lights and full
support for programmable vertex shaders. You can toggle between software and
hardware vertex processing at any time when using the HAL Device, the only
device type that supports both hardware and software vertex processing. The
only requirement is that vertex buffers used for software vertex processing
must be allocated in system memory. Note The performance of hardware vertex
processing is comparable to that of software vertex processing. For this
reason, it's a good idea to provide, within a single device type, both
hardware- and software-emulation functionality for vertex processing. This is
not the case for rasterization, for which host processors are much slower than
specialized graphics hardware. Thus both hardware- and software-emulated
rasterization is not provided within a single device type. Software vertex
processing is the only instance of functionality duplicated between the run
time and the hardware (driver) within a single device. Thus all other device
capabilities represent potentially variable functionality provided by the
driver. Working with Mouse Cursors The mouse cursor methods enable the
application to specify a color cursor by providing a surface that contains an
image. The system will ensure that this cursor will be updated at half the
display rate or more if the application's frame rate is slow. However, the
cursor will never be updated more frequently than the display refresh rate.
[C++] The mouse cursor position is tied to the system cursor, appropriately
scaled for the current display mode spatial resolution, but it can be moved
explicitly by the application. This is analogous to the behavior of the
Microsoft® Win32? API– supported system mouse cursor. For more information on
how to use a mouse cursor in your Microsoft® Direct3D® application, see the
following reference topics. * IDirect3DDevice8::ShowCursor *
IDirect3DDevice8::SetCursorPosition * IDirect3DDevice8::SetCursorProperties
Direct3D ensures that the mouse is supported either by hardware implementations
or by the Direct3D run time that performs hardware-accelerated blitting
operations when calling IDirect3DDevice8::Present. [Visual Basic] The mouse
cursor position is tied to the system cursor (appropriately scaled for the
current display mode spatial resolution) but it can be moved explicitly by the
application. This is analogous to the behavior of the Microsoft® Win32? API
supported system mouse cursor. For more information on how to use a mouse
cursor in your Microsoft® Direct3D® application, see the following reference
topics. * Direct3DDevice8.ShowCursor * Direct3DDevice8.SetCursorPosition *
Direct3DDevice8.SetCursorProperties Direct3D ensures that the mouse will be
supported either by hardware implementations or by the Direct3D run time
performing hardware-accelerated blitting operations when calling
Direct3DDevice8.Present. Rendering Applications use the DrawPrimitive family of
methods to render a 3-D scene. The following topics discuss rendering with
DrawPrimitive. * Clearing Surfaces * Beginning and Ending a Scene * Presenting
a Scene * Rendering Primitives Clearing Surfaces Before rendering objects in a
scene, clear the viewport on the render-target surface or a subset of the
viewport. Clearing the viewport causes the system to set the desired portion of
the render-target surface and any attached depth or stencil buffers to a
desired state. This resets the areas of the surface that will be rendered
again, and it resets the corresponding areas of the depth and stencil buffers,
if any are in use. Clearing a render-target surface can set the desired region
to a default color or texture. For depth and stencil buffers, this can set a
depth or stencil value. [C++] Use the IDirect3DDevice8::Clear method to clear
the viewport. For more information about using this method, see Clearing a
Viewport. [Visual Basic] Use the Direct3DDevice8.Clear method to clear the
viewport. For more information about using this method, see Clearing a
Viewport. Optimization Note Applications that render scenes covering the entire
area of the render-target surface can improve performance by clearing the
attached depth and stencil buffer surfaces, if any, instead of the render
target. In this case, clearing the depth buffer causes Microsoft® Direct3D® to
rewrite the render target on the next rendered frame, making an explicit clear
operation on the render target redundant. However, if your application renders
only to a portion of the render- target surface, explicit clear operations are
required. Beginning and Ending a Scene [C++] Applications written in C++ notify
Microsoft® Direct3D® that scene rendering is about to begin by calling the
IDirect3DDevice8::BeginScene method. BeginScene causes the system to check its
internal data structures and the availability and validity of rendering
surfaces. It also sets an internal flag to signal that a scene is in progress.
After you begin a scene, you can call the various rendering methods to render
the primitives or individual vertices that make up the objects in the scene.
Attempts to call rendering methods when a scene is not in progress fail. For
more information, see Rendering Primitives. After you complete the scene, call
the IDirect3DDevice8::EndScene method. The EndScene method flushes cached data,
verifies the integrity of rendering surfaces, and clears an internal flag that
signals when a scene is in progress. All rendering methods must be bracketed by
calls to the BeginScene and EndScene methods. If surfaces are lost or internal
errors occur, the scene methods return error values. If BeginScene fails, the
scene does not begin, and subsequent calls to EndScene will fail. To summarize
these cases: * If BeginScene returns any error, you must not call EndScene
because the scene has not successfully begun. * If BeginScene succeeds, but you
get an error while rendering the scene, you must call EndScene. * If EndScene
fails, for any reason, you need not call it again. For example, some simple
scene code might look like the following example. HRESULT hr;
if(SUCCEEDED(pDevice->BeginScene())) { // Render primitives only if the scene
// starts successfully. // Close the scene. hr = pDevice->EndScene();
if(FAILED(hr)) return hr; } [Visual Basic] Microsoft® Visual Basic®
applications notify Microsoft Direct3D® that scene rendering is about to begin
by calling the Direct3DDevice8.BeginScene method. BeginScene causes the system
to check its internal data structures and the availability and validity of
rendering surfaces. It also sets an internal flag to signal that a scene is in
progress. After you begin a scene, you can call the various rendering methods
to render the primitives or individual vertices that make up the objects in the
scene. Attempts to call rendering methods when a scene is not in progress fail.
For more information, see Rendering Primitives. After you complete the scene,
call the Direct3DDevice8.EndScene method. The EndScene method flushes cached
data, verifies the integrity of rendering surfaces, and clears an internal flag
that signals when a scene is in progress. All rendering methods must be
bracketed by calls to the BeginScene and EndScene methods. If surfaces are lost
or internal errors occur, the scene methods fail and Err.Number is set to an
error code. If BeginScene fails, the scene does not begin, and subsequent calls
to EndScene will fail. When surfaces are lost during rendering, EndScene will
fail. To summarize these cases: * If BeginScene returns any error, you must not
call EndScene because the scene has not successfully begun. * If BeginScene
succeeds, but you get an error while rendering the scene, you must call
EndScene. * If EndScene fails, for any reason, you need not call it again. For
example, some simple scene code might look like the following example. On Local
Error Resume Next Call d3dDevice.BeginScene If Err.Number = DD_OK Then ' Render
primitives only if the scene ' starts successfully. ' Close the scene. Call
d3dDevice.EndScene If Err.Number <> DD_OK Then ' Code to handle error goes
here. End If End If You cannot embed scenes; that is, you must complete
rendering a scene before you can begin another one. Calling EndScene when
BeginScene has not been called returns an error value. Likewise, calling
BeginScene when a previous scene has not been completed with the EndScene
method results in an error. Do not attempt to call GDI functions on Direct3D
surfaces, such as the render target or textures, while a scene is being
rendered—is between BeginScene and EndScene calls. Attempts to do so can
prevent the results of the GDI operations from being visible. If your
application uses GDI functions, be sure that all GDI calls are made outside the
scene functions. Presenting a Scene This section introduces the presentation
application programming interfaces (APIs) and discusses the issues involved in
presenting a scene to the display. Information is divided into the following
topics. * Introduction to Presenting a Scene * Multiple Views in Windowed Mode
* Multiple-Monitor Operations * Manipulating the Depth Buffer * Accessing the
Color Front Buffer Introduction to Presenting a Scene [C++] The presentation
application programming interfaces (APIs) are a set of methods that control the
state of the device that affects what the user sees on the monitor. These
methods include setting display modes and once-per-frame methods that are used
to present images to the user. * IDirect3DDevice8::Present *
IDirect3DDevice8::Reset * IDirect3DDevice8::GetGammaRamp *
IDirect3DDevice8::SetGammaRamp * IDirect3DDevice8::GetRasterStatus Familiarity
with the following terms is necessary to understand the presentation APIs. *
Front Buffer. A rectangle of memory that is translated by the graphics adapter
and displayed on the monitor or other output device. * Back Buffer. A surface
whose contents can be promoted to the front buffer. * Swap Chain. A collection
of back buffers that can be serially presented to the front buffer. Typically,
a full-screen swap chain presents subsequent images with the flipping DDI, and
a windowed swap chain presents images with the blitting DDI. Because Microsoft®
Direct3D® for Microsoft DirectX® 8.0 has one swap chain as a property of the
device, there is always at least one swap chain per device. The
IDirect3DDevice8 interface has a set of methods that manipulate the implicit
swap chain and are a copy of the swap chain's own interface. Applications can
create additional swap chains; however, this is not necessary for the typical
single window or full-screen application. The front buffer is not directly
exposed in the Direct3D API for DirectX 8.0. As a result, applications cannot
lock or render to the front buffer. For details, see Accessing the Color Front
Buffer. Note DirectX 7.x provided a number of presentation APIs that were
called together. A good example of this is the
IDirectDraw7::SetCooperativeLevel, IDirectDraw7::SetDisplayMode, and
IDirectDraw7::CreateSurface sequence. Additionally, the
IDirectDrawSurface7::Flip and IDirectDrawSurface7::Blt methods signaled the
transport of rendered frames to the monitor. DirectX 8.0 collapses these groups
of APIs into two main methods, Reset and Present. Reset subsumes
SetCooperativeLevel, SetDisplayMode, CreateSurface, and some of the parameters
to Flip. Present subsumes Flip and the presentation uses of Blt. A call to
IDirect3D8::CreateDevice represents an implicit reset of the device. The
DirectX 8.0 API has no notion of a primary surface; you cannot create an object
that represents the primary surface. It is considered to be an internal
property of the device. Gamma ramps are associated with a swap chain and are
manipulated with the IDirect3DDevice8::GetGammaRamp and
IDirect3DDevice8::SetGammaRamp methods. [Visual Basic] The presentation
application programming interfaces (APIs) are a set of methods that control the
state of the device that affects what you see on the monitor. These methods
include setting display modes and once-per-frame methods that are used to
present images to the user. * Direct3DDevice8.Present * Direct3DDevice8.Reset *
Direct3DDevice8.GetGammaRamp * Direct3DDevice8.SetGammaRamp *
Direct3DDevice8.GetRasterStatus Familiarity with the following terms is
necessary to understand the presentation APIs. * Front Buffer. A rectangle of
memory that is translated by the graphics adapter and displayed on the monitor
or other output device. * Back Buffer. A surface whose contents can be promoted
to the front buffer. * Swap Chain. A collection of back buffers that can be
serially presented to the front buffer. Typically, a full-screen swap chain
presents subsequent images with the flipping DDI, and a windowed swap chain
presents images with the blitting DDI. Because Microsoft® Direct3D® Microsoft
for DirectX® 8.0 has one swap chain as a property of the device, there is
always at least one swap chain per device. The Direct3DDevice8 class has a set
of methods that manipulate the implicit swap chain and are a copy of the swap
chain's own interface. Applications can create additional swap chains; however,
this is not necessary for the typical single window or full- screen
application. The front buffer is not directly exposed in the Direct3D API for
DirectX 8.0. As a result, applications cannot lock or render to the front
buffer. For details, see Accessing the Color Front Buffer. Note DirectX 7.x
provided a number of presentation APIs that were called together. A good
example of this is the DirectDraw7.SetCooperativeLevel,
DirectDraw7.SetDisplayMode, and DirectDraw7.CreateSurface sequence.
Additionally, the DirectDrawSurface7.Flip and DirectDrawSurface7.Blt methods
signaled the transport of rendered frames to the monitor. DirectX 8.0 collapses
these groups of APIs into two main methods, Reset and Present. Reset subsumes
SetCooperativeLevel, SetDisplayMode, CreateSurface, and some of the parameters
to Flip. Present subsumes Flip and the presentation uses of Blt. A call to
Direct3D8.CreateDevice represents an implicit reset of the device. The DirectX
8.0 API has no notion of a primary surface; you cannot to create an object that
represents the primary surface. It is considered to be an internal property of
the device. Gamma ramps are associated with a swap chain and are manipulated
with the Direct3DDevice8.GetGammaRamp and Direct3DDevice8.SetGammaRamp methods.
Multiple Views in Windowed Mode [C++] In addition to the swap chain that is
owned and manipulated through the Direct3DDevice object, an application can use
the IDirect3DDevice8::CreateAdditionalSwapChain method to create additional
swap chains to present multiple views from the same device. Typically, the
application creates one swap chain per view, and it associates each swap chain
with a particular view. The application renders images in the back buffers of
each swap chain, and then uses the IDirect3DDevice8::Present method to present
them individually. Note that only one swap chain at a time can be full-screen
on each adapter. [Visual Basic] In addition to the swap chain that is owned and
manipulated through the Direct3DDevice object, an application can use the
Direct3DDevice8.CreateAdditionalSwapChain method to create additional swap
chains to present multiple views from the same device. Typically, the
application creates one swap chain per view, and it associates each swap chain
with a particular view. The application renders images in the back buffers of
each swap chain, and then uses the Direct3DDevice8.Present method to present
them individually. Note that only one swap chain at a time can be full-screen
on each adapter. Multiple-Monitor Operations [C++] When a device is
successfully reset (IDirect3DDevice8::Reset) or created
(IDirect3D8::CreateDevice) in full-screen operations, the Microsoft® Direct3D®
object that created the device is marked as owning all adapters on that system.
This state is known as exclusive mode, and the Direct3D object owns exclusive
mode. Exclusive mode means that devices created by any other Direct3D object
can neither assume full-screen operations nor allocate video memory. In
addition, when a Direct3D object assumes exclusive mode, all devices other than
the one that went full-screen are placed in lost state. For details, see Lost
Devices. [Visual Basic] When a device is successfully reset
(Direct3DDevice8.Reset) or created (Direct3D8.CreateDevice) in full-screen
operations, the Microsoft® Direct3D® object that created the device is marked
as owning all adapters on that system. This state is known as exclusive mode,
and the Direct3D object owns exclusive mode. Exclusive mode means that devices
created by any other Direct3D object can neither assume full-screen operations
nor allocate video memory. In addition, when a Direct3D object assumes
exclusive mode, all devices other than the one that went full-screen are placed
in lost state. For details, see Lost Devices. Along with exclusive mode, the
Direct3D object is informed of the focus window that the device will use.
Exclusive mode is released when the final full-screen device owned by that
Direct3D object is either reset to windowed mode or destroyed. Devices can be
divided into two categories when a Direct3D object owns exclusive mode. The
first category of devices have the following characteristics. * They are
created by the same Direct3D object that created the device that is
full-screen. * They have the same focus window as the device that is
full-screen. * They represent a different adapter from any full-screen device.
Devices in this category have no restrictions concerning their ability to be
reset or created, and they are not placed in lost state. Devices in this
category can even be put into full-screen mode. Devices that do not fall in the
first category—devices created by another Direct3D object, created with a
different focus window, and created for an adapter with a device that is
already full-screen—cannot be reset and remain in lost state until the
exclusive mode is lost. As a result, a multiple-monitor application can place
several devices in full-screen mode, but only if all these devices are for
different adapters, were created by the same Direct3D object, and share the
same focus window. Manipulating the Depth Buffer [C++] Depth buffers are
associated with the device. Applications are required to move the depth buffers
when they set render targets. The IDirect3DDevice8::GetDepthStencilSurface and
IDirect3DDevice8::SetRenderTarget methods are used to manipulate depth buffers.
[Visual Basic] Depth buffers are associated with the device. Applications are
required to move the depth buffers when they set render targets. The
Direct3DDevice8.GetDepthStencilSurface and Direct3DDevice8.SetRenderTarget
methods are used to manipulate depth buffers. Accessing the Color Front Buffer
[C++] Accessing the front buffer is allowed through the
IDirect3DDevice8::GetFrontBuffer method. Although this method is provided, it
is intended explicitly for testing requirements. Thus, its functionality is not
guaranteed. [Visual Basic] Accessing the front buffer is allowed through the
Direct3DDevice8.GetFrontBuffer method. Although this method is provided, it is
intended explicitly for testing requirements. Thus, its functionality is not
guaranteed. Rendering Primitives The following topics introduce the
DrawPrimitive rendering methods and provide information about using them in
your application. * Vertex Data Streams * Setting the Stream Source * Rendering
from Vertex and Index Buffers * Rendering from User Memory Pointers Vertex Data
Streams The rendering interfaces for Microsoft® Direct3D® consist of methods
that render primitives from vertex data stored in one or more data buffers.
Vertex data consists of vertex elements combined to form vertex components.
Vertex elements, the smallest unit of a vertex, represent entities such as
position, normal, or color. Vertex components are one or more vertex elements
stored contiguously (interleaved per vertex) in a single memory buffer. A
complete vertex consists of one or more components, where each component is in
a separate memory buffer. To render a primitive, multiple vertex components are
read and assembled so that complete vertices are available for vertex
processing. The illustration below shows the process of rendering primitives
using vertex components. Rendering primitives consists of two steps. First, set
up one or more vertex component streams; second, invoke a DrawPrimitive method
to render from those streams. Identification of vertex elements within these
component streams is specified by the vertex shader. For details, see Vertex
Shaders. The DrawPrimitive methods specify an offset in the vertex data streams
so that an arbitrary contiguous subset of the primitives within one set of
vertex data can be rendered with each draw invocation. This enables you to
change the device rendering state between groups of primitives that are
rendered from the same vertex buffers. Both indexed and nonindexed drawing
methods are supported. For more information, see Rendering from Vertex and
Index Buffers. A secondary set of rendering interfaces supports passing vertex
and index data directly from user memory pointers. For more information, see
Rendering from User Memory Pointers. Setting the Stream Source [C++] The
IDirect3DDevice8::SetStreamSource method binds a vertex buffer to a device data
stream, creating an association between the vertex data and one of several data
stream ports that feed the primitive processing functions. The actual
references to the stream data do not occur until a drawing method, such as
IDirect3DDevice8::DrawPrimitive, is called. A stream is defined as a uniform
array of component data, where each component consists of one or more elements
representing a single entity such as position, normal, color, and so on. The
Stride parameter specifies the size of the component, in bytes. [Visual Basic]
The Direct3DDevice8.SetStreamSource method binds a vertex buffer to a device
data stream, creating an association between the vertex data and one of several
data stream ports that feed the primitive processing functions. The actual
references to the stream data do not occur until a drawing method, such as
Direct3DDevice8.DrawPrimitive, is called. A stream is defined as a uniform
array of component data, where each component consists of one or more elements
representing a single entity such as position, normal, color, and so on. The
Stride parameter specifies the size of the component, in bytes. Rendering from
Vertex and Index Buffers [C++] Both indexed and nonindexed drawing methods are
supported by Microsoft® Direct3D®. The indexed methods use a single set of
indices for all vertex components. Vertex data is presented to the Direct3D
application programming interface (API) in vertex buffers, and index data for
the indexed drawing methods is presented in index buffers. For more
information, see the following reference topics. *
IDirect3DDevice8::DrawPrimitive * IDirect3DDevice8::DrawIndexedPrimitive These
methods draw primitives from the current set of data input streams. For details
on setting the current index array to an index buffer, see the
IDirect3DDevice8::SetIndices method. [Visual Basic] Both indexed and nonindexed
drawing methods are supported by Microsoft® Direct3D®. The indexed methods use
a single set of indices for all vertex components. Vertex data is presented to
the Direct3D application programming interface (API) in vertex buffers, and
index data for the indexed drawing methods is presented in index buffers. For
more information, see the following reference topics. *
Direct3DDevice8.DrawPrimitive * Direct3DDevice8.DrawIndexedPrimitive These
methods draw primitives from the current set of data input streams. For details
on setting the current index array to an index buffer, see the
Direct3DDevice8.SetIndices method. Rendering from User Memory Pointers [C++] A
secondary set of rendering interfaces supports passing vertex and index data
directly from user memory pointers. These interfaces support a single stream of
vertex data only. For more information, see the following reference topics. *
IDirect3DDevice8::DrawPrimitiveUP * IDirect3DDevice8::DrawIndexedPrimitiveUP
These methods render with data specified by user memory pointers, instead of
vertex and index buffers. [Visual Basic] A secondary set of rendering
interfaces supports passing vertex and index data directly from user memory
pointers. These interfaces support a single stream of vertex data only. For
more information, see the following reference topics. *
Direct3DDevice8.DrawPrimitiveUP * Direct3DDevice8.DrawIndexedPrimitiveUP These
methods render with data specified by user memory pointers, instead of vertex
and index buffers. Device States A Microsoft® Direct3D® device is a state
computer; applications set up the state of the lighting, rendering, and
transformation modules and then pass data through them during rendering. This
section describes render states, provides details about each render state used
in Direct3D, and contains information about device state blocks, which
applications can use to manipulate groups of devices states in a single call.
The following topics are discussed. * Render States * Texture Stage States *
State Blocks Render States This section introduces the concept of render states
and discusses the various render states in detail. Information in this section
is organized into the following topics. * About Render States * Alpha Blending
State * Alpha Testing State * Ambient Lighting State * Antialiasing State *
Culling State * Depth Buffering State * Fog State * Lighting State * Outline
and Fill State * Per-Vertex Color State * Primitive Clipping State * Shading
State * Stencil Buffer State * Texture Wrapping State About Render States
Device render states control the behavior of the Microsoft® Direct3D® device's
rasterization module. They do this by altering the attributes of the rendering
state, what type of shading is used, fog attributes, and other rasterizer
operations. [C++] Applications written in C++ control the characteristics of
the rendering state by invoking the IDirect3DDevice8::SetRenderState method.
The D3DRENDERSTATETYPE enumerated type specifies all possible rendering states.
Your application passes a value from the D3DRENDERSTATETYPE enumeration as the
first parameter to the SetRenderState method. Fixed function vertex processing
is controlled by the SetRenderState method and the following device render
states. Most of these controls do not have any effect when using programmed
vertex shaders. * D3DRS_SPECULARENABLE * D3DRS_FOGSTART * D3DRS_FOGEND *
D3DRS_FOGDENSITY * D3DRS_RANGEFOGENABLE * D3DRS_LIGHTING * D3DRS_AMBIENT *
D3DRS_FOGVERTEXMODE * D3DRS_COLORVERTEX * D3DRS_LOCALVIEWER *
D3DRS_NORMALIZENORMALS * D3DRS_DIFFUSEMATERIALSOURCE *
D3DRS_SPECULARMATERIALSOURCE * D3DRS_AMBIENTMATERIALSOURCE *
D3DRS_EMISSIVEMATERIALSOURCE * D3DRS_VERTEXBLEND In addition, the
fixed-function vertex processing pipeline uses the following methods to set
transforms, materials, and lights. * IDirect3DDevice8::SetTransform *
IDirect3DDevice8::SetMaterial * IDirect3DDevice8::SetLight *
IDirect3DDevice8::LightEnable Note D3DRS_SPECULARENABLE controls the addition
of specular color in the pixel pipeline. D3DRS_FOGSTART, D3DRS_FOGEND, and
D3DRS_FOGDENSITY control the start, end, and density of pixel fog density
computation. [Visual Basic] Microsoft® Visual Basic® applications control the
characteristics of the rendering state by invoking the
Direct3DDevice8.SetRenderState method. The CONST_D3DRENDERSTATETYPE enumeration
specifies all possible rendering states. Your application passes a value from
the CONST_D3DRENDERSTATETYPE enumeration as the first parameter to the
SetRenderState method. Fixed function vertex processing is controlled by the
SetRenderState method and the following device render states. Most of these
controls do not have any effect when using programmed vertex shaders. *
D3DRS_SPECULARENABLE * D3DRS_FOGSTART * D3DRS_FOGEND * D3DRS_FOGDENSITY *
D3DRS_RANGEFOGENABLE * D3DRS_LIGHTING * D3DRS_AMBIENT * D3DRS_FOGVERTEXMODE *
D3DRS_COLORVERTEX * D3DRS_LOCALVIEWER * D3DRS_NORMALIZENORMALS *
D3DRS_DIFFUSEMATERIALSOURCE * D3DRS_SPECULARMATERIALSOURCE *
D3DRS_AMBIENTMATERIALSOURCE * D3DRS_EMISSIVEMATERIALSOURCE * D3DRS_VERTEXBLEND
In addition, the fixed-function vertex processing pipeline uses the following
methods to set transforms, materials, and lights. *
Direct3DDevice8.SetTransform * Direct3DDevice8.SetMaterial *
Direct3DDevice8.SetLight * Direct3DDevice8.LightEnable Note
D3DRS_SPECULARENABLE controls the addition of specular color in the pixel
pipeline. D3DRS_FOGSTART, D3DRS_FOGEND, and D3DRS_FOGDENSITY control the start,
end, and density of pixel fog density computation. Alpha Blending State The
alpha value of a color controls its transparency. Enabling alpha blending
allows colors, materials, and textures on a surface to be blended with
transparency onto another surface. For more information, see Alpha Texture
Blending and Multiple Texture Blending. [C++] Applications written in C++ use
the D3DRS_ALPHABLENDENABLE render state to enable alpha transparency blending.
The Microsoft® Direct3D® API allows many types of alpha blending. However, it
is important to note the user's 3-D hardware might not support all the blending
states allowed by Direct3D. The type of alpha blending that is done depends on
the D3DRS_SRCBLEND and D3DRS_DESTBLEND render states. Source and destination
blend states are used in pairs. The following code example demonstrates how the
source blend state is set to D3DBLEND_SRCCOLOR and the destination blend state
is set to D3DBLEND_INVSRCCOLOR. // This code example assumes that d3dDevice is
a // valid pointer to an IDirect3DDevice8 interface. // Set the source blend
state. d3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR); // Set the
destination blend state. d3dDevice->SetRenderState(D3DRS_DESTBLEND,
D3DBLEND_INVSRCCOLOR); As a result of the calls in the preceding code example,
Direct3D performs a linear blend between the source color—the color of the
primitive that is rendered at the current location—and the destination
color—the color at the current location in the frame buffer. This gives an
appearance similar to tinted glass. Some of the color of the destination object
seems to be transmitted through the source object. The rest of the color
appears to be absorbed. Altering the source and destination blend states can
give the appearance of emissive objects in a foggy or dusty atmosphere. For
instance, if your application models flames, force fields, plasma beams, or
similarly radiant objects in a foggy environment, set the source and
destination blend states to D3DBLEND_ONE. Another application of alpha blending
is to control the lighting in a 3-D scene, also called light mapping. Setting
the source blend state to D3DBLEND_ZERO and the destination blend state to
D3DBLEND_SRCALPHA darkens a scene according to the source alpha information.
The source primitive is used as a light map that scales the contents of the
frame buffer to darken it when appropriate. This produces monochrome light
mapping. You can achieve color light mapping by setting the source alpha
blending state to D3DBLEND_ZERO and the destination blend state to
D3DBLEND_SRCCOLOR. [Visual Basic] Microsoft® Visual Basic® applications use the
D3DRS_ALPHABLENDENABLE render state to enable alpha transparency blending. The
Microsoft® Direct3D® API allows many types of alpha blending. However, it is
important to note the user's 3-D hardware might not support all the blending
states allowed by Direct3D. The type of alpha blending that is done depends on
the D3DRS_SRCBLEND and D3DRS_DESTBLEND render states. Source and destination
blend states are used in pairs. The following code example demonstrates how the
source blend state is set to D3DBLEND_SRCCOLOR and the destination blend state
is set to D3DBLEND_INVSRCCOLOR. ' This code example assumes that d3dDevice
contains ' a reference to a Direct3DDevice8 object. ' Set the source blend
state. d3dDevice.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR ' Set the
destination blend state. d3dDevice.SetRenderState D3DRS_DESTBLEND,
D3DBLEND_INVSRCCOLOR As a result of the calls in the preceding code example,
Direct3D performs a linear blend between the source color—the color of the
primitive that is rendered at the current location—and the destination
color—the color at the current location in the frame buffer. This gives an
appearance similar to tinted glass. Some of the color of the destination object
seems to be transmitted through the source object. The rest of the color
appears to be absorbed. Altering the source and destination blend states can
give the appearance of emissive objects in a foggy or dusty atmosphere. For
instance, if your application models flames, force fields, plasma beams, or
similarly radiant objects in a foggy environment, set the source and
destination blend states to D3DBLEND_ONE. Another application of alpha blending
is to control the lighting in a 3-D scene, also called light mapping. Setting
the source blend state to D3DBLEND_ZERO and the destination blend state to
D3DBLEND_SRCALPHA darkens a scene according to the source alpha information.
The source primitive is used as a light map that scales the contents of the
frame buffer to darken it when appropriate. This produces monochrome light
mapping. You can achieve color light mapping by setting the source alpha
blending state to D3DBLEND_ZERO and the destination blend state to
D3DBLEND_SRCCOLOR. Alpha Testing State [C++] C++ applications can use alpha
testing to control when pixels are written to the render-target surface. By
using the D3DRS_ALPHATESTENABLE render state, your application sets the current
Microsoft® Direct3D® device so that it tests each pixel according to an alpha
test function. If the test succeeds, the pixel is written to the surface. If it
does not, Direct3D ignores the pixel. Select the alpha test function with the
D3DRS_ALPHAFUNC render state. Your application can set a reference alpha value
for all pixels to compare against by using the D3DRS_ALPHAREF render state. The
most common use for alpha testing is to improve performance when rasterizing
objects that are nearly transparent. If the color data being rasterized is more
opaque than the color at a given pixel (D3DPCMPCAPS_GREATEREQUAL), then the
pixel is written. Otherwise, the rasterizer ignores the pixel altogether,
saving the processing required to blend the two colors. The following code
example checks if a given comparison function is supported and, if so, it sets
the comparison function parameters required to improve performance during
rendering. // This code example assumes that pCaps is a // D3DCAPS8 structure
that was filled with a // previous call to IDirect3D8::GetDeviceCaps. if
(pCaps.AlphaCmpCaps & D3DPCMPCAPS_GREATEREQUAL) {
dev->SetRenderState(D3DRS_ALPHAREF, (DWORD)0x00000001);
dev->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
dev->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); } // If the
comparison is not supported, render anyway. // The only drawback is no
performance gain. Not all hardware supports all alpha-testing features. You can
check the device capabilities by calling the IDirect3D8::GetDeviceCaps method.
After retrieving the device capabilities, check the AlphaCmpCaps member of the
associated D3DCAPS8 structure for the desired comparison function. If the
AlphaCmpCaps member contains only the D3DPCMPCAPS_ALWAYS capability or only the
D3DPCMPCAPS_NEVER capability, the driver does not support alpha tests. [Visual
Basic] Applications written in Microsoft® Visual Basic® use alpha testing to
control when pixels are written to the render-target surface. By using the
D3DRS_ALPHATESTENABLE render state, your application sets the current
Microsoft® Direct3D® device so that it tests each pixel according to an alpha
test function. If the test succeeds, the pixel is written to the surface. If it
does not, Direct3D ignores the pixel. Select the alpha test function with the
D3DRS_ALPHAFUNC render state. Your application can set a reference alpha value
for all pixels to compare against by using the D3DRS_ALPHAREF render state. The
most common use for alpha testing is to improve performance when rasterizing
objects that are nearly transparent. If the color data being rasterized is more
opaque than the color at a given pixel (D3DPCMPCAPS_GREATEREQUAL), then the
pixel is written. Otherwise, the rasterizer ignores the pixel altogether,
saving the processing required to blend the two colors. The following code
example checks if a given comparison function is supported and, if so, it sets
the comparison function parameters required to improve performance during
rendering. ' This example assumes that Caps is a ' D3DCAPS8 type that was
filled with a ' previous call to Direct3D8.GetDeviceCaps. If (Caps.AlphaCmpCaps
And D3DPCMPCAPS_GREATEREQUAL) Then Call dev.SetRenderState(D3DRS_ALPHAREF, &H1)
Call dev.SetRenderState(D3DRS_ALPHATESTENABLE, True) Call
dev.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL) End If ' If the
comparison is not supported, render anyway. ' The only drawback is no
performance gain. Not all hardware supports all alpha-testing features. You can
check the device capabilities by calling the Direct3D8.GetDeviceCaps method.
After retrieving the device capabilities, check the AlphaCmpCaps member of the
associated D3DCAPS8 type for the desired comparison function. If the
AlphaCmpCaps member contains only the D3DPCMPCAPS_ALWAYS capability or only the
D3DPCMPCAPS_NEVER capability, the driver does not support alpha tests. Ambient
Lighting State Ambient light is surrounding light that radiates from all
directions. For specific information on how Microsoft® Direct3D® uses ambient
light, see Direct Light vs. Ambient Light, and Mathematics of Direct3D
Lighting. [C++] A C++ application sets the color of ambient lighting by
invoking the IDirect3DDevice8::SetRenderState method and passing the enumerated
value D3DRS_AMBIENT as the first parameter. The second parameter is a color
value. The default value is zero. // This code example assumes that d3dDevice
is a // valid pointer to an IDirect3DDevice8 interface. // Set the ambient
light. d3dDevice->SetRenderState(D3DRS_AMBIENT, 0x00202020); [Visual Basic] A
Microsoft Visual Basic® application sets the color of ambient lighting by
invoking the Direct3DDevice8.SetRenderState method and passing the enumerated
value D3DRS_AMBIENT as the first parameter. The second parameter is a color
value. The default value is zero. ' This code example assumes that D3DDevice
contains a valid ' reference to a Direct3DDevice8 object. ' Set the ambient
light. Call D3DDevice.SetRenderState(D3DRS_AMBIENT, &H202020) Antialiasing
State Antialiasing is a method of making lines and edges appear smoother on the
screen. Microsoft® Direct3D® supports two antialiasing methods: edge
antialiasing and full- scene antialiasing. For details about these techniques,
see Antialiasing. [C++] By default, Direct3D does not perform antialiasing. To
enable edge-antialiasing, which requires a second rendering pass, set the
D3DRS_EDGEANTIALIAS render state to TRUE. To disable it, set
D3DRS_EDGEANTIALIAS to FALSE. To enable full-scene antialiasing, set the
D3DRS_MULTISAMPLEANTIALIAS render state to TRUE. To disable it, set
D3DRS_MULTISAMPLEANTIALIAS to FALSE. [Visual Basic] By default, Direct3D does
not perform antialiasing. To enable edge-antialiasing, which requires a second
rendering pass, set the D3DRS_EDGEANTIALIAS render state to True. To disable
it, set D3DRS_EDGEANTIALIAS to False. To enable full-scene antialiasing, set
the D3DRS_MULTISAMPLEANTIALIAS to True. To disable it, set
D3DRS_MULTISAMPLEANTIALIAS to False. Culling State As Microsoft® Direct3D®
renders primitives, it culls primitives that are facing away from the user.
[C++] C++ applications set the culling mode by using the D3DRS_CULLMODE render
state, which can be set to a member of the D3DCULL enumerated type. By default,
Direct3D culls back faces with counterclockwise vertices. The following code
sample illustrates the process of setting the culling mode to cull back faces
with clockwise vertices. // This code example assumes that d3dDevice is a valid
// pointer to an IDirect3DDevice8 interface. // Set the culling state.
d3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); [Visual Basic] Microsoft
Visual Basic® applications set the culling mode by using the D3DRS_CULLMODE
render state, which can be set to a member of the CONST_D3DCULL enumeration. By
default, Direct3D culls back faces with counterclockwise vertices. The
following code sample illustrates the process of setting the culling mode to
cull back faces with clockwise vertices. ' This code example assumes that
d3dDevice contains a valid ' reference to a Direct3DDevice8 object. ' Set the
culling state. Call d3dDevice.SetRenderState(D3DRENDERSTATE_CULLMODE,
D3DCULL_CW) Depth Buffering State Depth buffering is a method of removing
hidden lines and surfaces. By default, Microsoft® Direct3D® does not use depth
buffering. For a conceptual overview of depth buffers, see What Are Depth
Buffers?. [C++] C++ applications update the depth-buffering state with the
D3DRS_ZENABLE render state, using a member of the D3DZBUFFERTYPE enumeration to
specify the new state value. If your application needs to prevent Direct3D from
writing to the depth buffer, it can use the D3DRS_ZWRITEENABLE enumerated
value, specifying D3DZB_FALSE as the second parameter for the call to
IDirect3DDevice8::SetRenderState. The following code example shows how the
depth-buffer state is set to enable z- buffering. // This code example assumes
that d3dDevice is a // valid pointer to an IDirect3DDevice8 interface. //
Enable z-buffering. d3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); Your
application can also use the D3DRS_ZFUNC render state to control the comparison
function that Direct3D uses when performing depth buffering. Z-biasing is a
method of displaying one surface in front of another, even if their depth
values are the same. You can use this technique for a variety of effects. A
common example is rendering shadows on walls. Both the shadow and the wall have
the same depth value. However, you want your application to show the shadow on
the wall. Giving a z-bias to the shadow makes Direct3D display them properly
(see D3DRS_ZBIAS). [Visual Basic] Microsoft Visual Basic® applications update
the depth-buffering state with the D3DRS_ZENABLE render state, using a member
of the CONST_D3DZBUFFERTYPE enumeration to specify the new state value. If your
application needs to prevent Direct3D from writing to the depth buffer, it can
use the D3DRS_ZWRITEENABLE render state, specifying D3DZB_FALSE as the second
parameter for the call to Direct3DDevice8.SetRenderState. The following Visual
Basic code example shows how the depth-buffer state is set to enable
z-buffering. ' This code example assumes that d3dDevice contains a valid '
reference to a Direct3DDevice8 object. ' Enable z-buffering. Call
d3dDevice.SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE) Your application can also
use the D3DRS_ZFUNC render state to control the comparison function that
Direct3D uses when performing depth buffering. Z-biasing is a method of
displaying one surface in front of another, even if their depth values are the
same. You can use this technique for a variety of effects. A common example is
rendering shadows on walls. Both the shadow and the wall have the same depth
value. However, you want your application to show the shadow on the wall.
Giving a z-bias to the shadow makes Direct3D display them properly (see
D3DRS_ZBIAS). Fog State Fog effects can give a 3-D scene greater realism. You
can use fog effects for more than simulating fog. They can also decrease the
clarity of a scene with distance. This mirrors what happens in the real world;
as objects become more distant from the user, their detail is less distinct.
For more information about using fog in your application, see Fog. [C++] A C++
application controls fog through device rendering states. The
D3DRENDERSTATETYPE enumerated type includes states to control whether pixel
(table) or vertex fog is used, what color it is, the fog formula the system
applies, and the parameters of the formula. You enable fog by setting the
D3DRS_FOGENABLE render state to TRUE. The fog color can be set to any color
value by using the D3DRS_FOGCOLOR render state; the alpha component of the fog
color is ignored, . The D3DRS_FOGTABLEMODE and D3DRS_FOGVERTEXMODE render
states control the fog formula applied for fog calculations, and they
indirectly control which type of fog is applied. Both render states can be set
to a member of the D3DFOGMODE enumerated type. Setting either render state to
D3DFOG_NONE disables pixel or vertex fog, respectively. If both render states
are set to valid modes, the system applies only pixel fog effects. The
D3DRS_FOGSTART and D3DRS_FOGEND render states control fog formula parameters
for the D3DFOG_LINEAR mode. The D3DRS_FOGDENSITY render state controls fog
density in the exponential fog modes. [Visual Basic] A Microsoft® Visual Basic®
application controls fog through device rendering states. The
CONST_D3DRENDERSTATETYPE enumeration includes states to control whether pixel
(table) or vertex fog is used, what color it is, the fog formula the system
applies, and the parameters of the formula. You enable fog by setting the
D3DRS_FOGENABLE render state to True. The fog color can be set to any color
value by using the D3DRS_FOGCOLOR render state; the alpha component of the fog
color is ignored. The D3DRS_FOGTABLEMODE and D3DRS_FOGVERTEXMODE render states
control the fog formula applied for fog calculations, and they indirectly
control which type of fog is applied. Both render states can be set to a member
of the CONST_D3DFOGMODE enumeration. Setting either render state to D3DFOG_NONE
disables pixel or vertex fog, respectively. If both render states are set to
valid modes, the system applies only pixel fog effects. The D3DRS_FOGSTART and
D3DRS_FOGEND render states control fog formula parameters for the D3DFOG_LINEAR
mode. The D3DRS_FOGDENSITY render state controls fog density in the exponential
fog modes. For more information, see Fog Parameters. Lighting State
Applications that use the Microsoft® Direct3D® geometry pipeline can enable or
disable lighting calculations. Only vertices that contain a vertex normal are
properly lit; vertices with no normal will use a dot product of zero in all
lighting computations. Therefore, a vertex that does not use a normal receives
no light. For more information, see Mathematics of Direct3D Lighting. [C++]
Applications enable Direct3D lighting by setting the D3DRS_LIGHTING render
state to TRUE, which is the default setting, and they disable Direct3D lighting
by setting the render state to FALSE. The lighting render state is entirely
independent of lighting computations that can be performed on vertices within a
vertex buffer. The IDirect3DDevice8::ProcessVertices method accepts its own
flags to control lighting calculations during vertex processing. [Visual Basic]
Applications enable Direct3D lighting by setting the D3DRS_LIGHTING render
state to True, which is the default setting, and they disable Direct3D lighting
by setting the render state to False. The lighting render state is entirely
independent of lighting computations that can be performed on vertices within a
vertex buffer. The Direct3DDevice8.ProcessVertices method accepts its own flags
to control lighting calculations during vertex processing. Outline and Fill
State [C++] Primitives that have no textures are rendered with the color
specified by their material, or with the colors specified for the vertices, if
any. You can select the method to fill them by specifying a value defined by
the D3DFILLMODE enumerated type for the D3DRS_FILLMODE render state. To enable
dithering, your application must pass the D3DRS_DITHERENABLE enumerated value
as the first parameter to IDirect3DDevice8::SetRenderState. It must set the
second parameter to TRUE to enable dithering, and FALSE to disable it. At
times, drawing the last pixel in a line can cause unsightly overlap with
surrounding primitives. You can control this using the D3DRS_LASTPIXEL
enumerated value. However, do not alter this setting without some forethought.
Under some conditions, suppressing the rendering of the last pixel can cause
unsightly gaps between primitives. By default, Microsoft® Direct3D® devices use
a solid outline for primitives. The outline pattern can be changed using the
D3DLINEPATTERN structure. For details, see the D3DRS_LINEPATTERN render state.
[Visual Basic] Primitives that have no textures are rendered with the color
specified by their material, or with the colors specified for the vertices, if
any. You can select the method to fill them by specifying a value defined by
the CONST_D3DFILLMODE enumeration for the D3DRS_FILLMODE render state. To
enable dithering, your application must pass the D3DRS_DITHERENABLE enumerated
value as the first parameter to Direct3DDevice8.SetRenderState. It must set the
second parameter to True to enable dithering, and False to disable it. At
times, drawing the last pixel in a line can cause unsightly overlap with
surrounding primitives. You can control this using the D3DRS_LASTPIXEL
enumerated value. However, do not alter this setting without some forethought.
Under some conditions, suppressing the rendering of the last pixel can cause
unsightly gaps between primitives. By default, Microsoft® Direct3D® devices use
a solid outline for primitives. The outline pattern can be changed using the
D3DLINEPATTERN type. For details, see the D3DRS_LINEPATTERN render state.
Per-Vertex Color State [C++] When using flexible vertex format (FVF) codes,
vertices can contain both vertex color and vertex normal information. By
default, Microsoft® Direct3D® uses this information when it calculates
lighting. To disable use of vertex color lighting information, invoke the
IDirect3DDevice8::SetRenderState method and pass D3DRS_COLORVERTEX as the first
parameter. Set the second parameter to FALSE to disable vertex color lighting,
or TRUE to enable it. If per-vertex color is enabled, applications can
configure the source from which the system retrieves color information for a
vertex. The D3DRS_AMBIENTMATERIALSOURCE, D3DRS_DIFFUSEMATERIALSOURCE,
D3DRS_EMISSIVEMATERIALSOURCE, and D3DRS_SPECULARMATERIALSOURCE render states
control the ambient, diffuse, emissive, and specular color component sources,
respectively. Each state can be set to members of the D3DMATERIALCOLORSOURCE
enumerated type, which defines constants that instruct the system to use the
current material, diffuse color, or specular color as the source for the
specified color component. [Visual Basic] The following vertex types cannot
contain both color and normal information. * D3DLVERTEX * D3DLVERTEX2 *
D3DTLVERTEX * D3DTLVERTEX2 * D3DVERTEX * D3DVERTEX2 Because the default shading
mode is Gouraud shading, which depends on both vertex color and normal
information, Microsoft® Direct3D® does not use vertex color in lighting
calculations involving the predefined vertex types. However, when you use
flexible vertex format (FVF) codes, vertices can contain both vertex color and
vertex normal information. By default, Direct3D uses this information when it
calculates lighting. To disable use of vertex color lighting information,
invoke the Direct3DDevice8.SetRenderState method and pass D3DRS_COLORVERTEX as
the first parameter. Set the second parameter to False to disable vertex color
lighting, or True to enable it. If per-vertex color is enabled, applications
can configure the source from which the system retrieves color information for
a vertex. The D3DRS_AMBIENTMATERIALSOURCE, D3DRS_DIFFUSEMATERIALSOURCE,
D3DRS_EMISSIVEMATERIALSOURCE, and D3DRS_SPECULARMATERIALSOURCE render states
control the ambient, diffuse, emissive, and specular color component sources,
respectively. Each state can be set to members of the
CONST_D3DMATERIALCOLORSOURCE enumeration, which defines constants that instruct
the system to use the current material, diffuse color, or specular color as the
source for the specified color component. Primitive Clipping State [C++]
Microsoft® Direct3D® can clip primitives that render partially outside the
viewport. When using C++, Direct3D clipping is controlled by the D3DRS_CLIPPING
render state. Set this render state to TRUE (the default value) to enable
primitive clipping. Set it to FALSE to disable Direct3D clipping services. The
primitive clipping render state is entirely independent of clipping operations
that can be performed on vertices within a vertex buffer. The
IDirect3DDevice8::ProcessVertices method accepts its own flags to control
primitive clipping during vertex processing. [Visual Basic] Microsoft®
Direct3D® can clip primitives that render partially outside the viewport. When
using Microsoft Visual Basic®, Direct3D clipping is controlled by the
D3DRS_CLIPPING render state. Set this render state to True (the default value)
to enable primitive clipping. Set it to False to disable Direct3D clipping
services. The primitive clipping render state is entirely independent of
clipping operations that can be performed on vertices within a vertex buffer.
The Direct3DDevice8.ProcessVertices method accepts its own flags to control
primitive clipping during vertex processing. Shading State [C++] Microsoft®
Direct3D® supports both flat and Gouraud shading. The default is Gouraud
shading. To control the current shading mode, your C++ application specifies a
member of the D3DSHADEMODE enumerated type for the D3DRS_SHADEMODE render
state. The following C++ code example demonstrates the process of setting the
shading state to flat shading mode. // This code example assumes that d3dDevice
is a // valid pointer to a IDirect3DDevice8 interface. // Set the shading
state. d3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); [Visual
Basic] Microsoft® Direct3D® supports both flat and Gouraud shading. The default
is Gouraud shading. To control the current shading mode, your Microsoft Visual
Basic® application specifies a member of the CONST_D3DSHADEMODE enumeration for
the D3DRS_SHADEMODE render state. The following Visual Basic code example
demonstrates the process of setting the shading state to flat shading mode. '
This example assumes that d3dDevice is a valid ' reference to a Direct3DDevice8
object. ' Set the shading state. Call d3dDevice.SetRenderState(D3DRS_SHADEMODE,
D3DSHADE_FLAT) Stencil Buffer State Applications use the stencil buffer to
determine whether a pixel is written to the rendering target surface. For
details, see Stencil Buffers. [C++] Applications written in C++ enable or
disable stenciling by calling the IDirect3DDevice8::SetRenderState method. Pass
D3DRS_STENCILENABLE as the value of the first parameter. Set the value of the
second parameter to TRUE or FALSE to enable or disable stenciling,
respectively. Set the comparison function that Microsoft® Direct3D® uses to
perform the stencil test by calling SetRenderState. Set the value of the first
parameter to D3DRS_STENCILFUNC. Pass a member of the D3DCMPFUNC enumerated type
as the value of the second parameter. The stencil reference value is the value
in the stencil buffer that the stencil function uses for its test. By default,
the stencil reference value is zero. Your application can set the value by
calling SetRenderState. Pass D3DRS_STENCILREF as the value of the first
parameter. Set the value of the second parameter to the new reference value.
Before the Direct3D module performs the stencil test for any pixel, it performs
a bitwise AND operation of the stencil reference value and a stencil mask
value. The result is compared against the contents of the stencil buffer using
the stencil comparison function. Your application can set the stencil mask by
calling SetRenderState. Pass D3DRS_STENCILMASK as the value of the first
parameter. Set the value of the second parameter to the new stencil mask. To
set the action that Direct3D takes when the stencil test fails, call
SetRenderState and pass D3DRS_STENCILFAIL as the first parameter. The second
parameter must be a member of the D3DSTENCILOP enumerated type. Your
application can also control how Direct3D responds when the stencil test passes
but the z-buffer test fails. Call SetRenderState and pass D3DRS_STENCILZFAIL as
the first parameter and use a member of the D3DSTENCILOP enumerated type for
the second parameter. In addition, your application can control what Direct3D
does when both the stencil test and the z-buffer test pass. Call SetRenderState
and pass D3DRS_STENCILPASS as the first parameter. Again, the second parameter
must be a member of the D3DSTENCILOP enumerated type. [Visual Basic]
Applications written in Microsoft® Visual Basic® enable or disable stenciling
by calling the Direct3DDevice8.SetRenderState method. Pass D3DRS_STENCILENABLE
as the value of the first parameter. Set the value of the second parameter to
True or False to enable or disable stenciling, respectively. Set the comparison
function that Microsoft® Direct3D® uses to perform the stencil test by calling
SetRenderState. Set the value of the first parameter to D3DRS_STENCILFUNC. Pass
a member of the CONST_D3DCMPFUNC enumeration as the value of the second
parameter. The stencil reference value is the value in the stencil buffer that
the stencil function uses for its test. By default, the stencil reference value
is zero. Your application can set the value by calling SetRenderState. Pass
D3DRS_STENCILREF as the value of the first parameter. Set the value of the
second parameter to the new reference value. Before Direct3D module performs
the stencil test for a pixel, it performs a bitwise And operation of the
stencil reference value and a stencil mask value. The result is compared
against the contents of the stencil buffer using the stencil comparison
function. Your application can set the stencil mask by calling SetRenderState.
Pass D3DRS_STENCILMASK as the value of the first parameter. Set the value of
the second parameter to the new stencil mask. To set the action that Direct3D
takes when the stencil test fails, call SetRenderState and pass
D3DRS_STENCILFAIL as the first parameter. The second parameter must be a member
of the CONST_D3DSTENCILOP enumeration. Your application can also control how
Direct3D responds when the stencil test passes but the z-buffer test fails.
Call SetRenderState and pass D3DRS_STENCILZFAIL as the first parameter and use
a member of the CONST_D3DSTENCILOP enumeration for the second parameter. In
addition, your application can control what Direct3D does when both the stencil
test and the z-buffer test pass. Call SetRenderState and pass D3DRS_STENCILPASS
as the first parameter. Again, the second parameter must be a member of the
CONST_D3DSTENCILOP enumeration. Texture Wrapping State [C++] The D3DRS_WRAP0
through D3DRS_WRAP7 render states enable and disable u- and v-wrapping for
various textures in the device's multitexture cascade. You can set these render
states to a combination of the D3DWRAPCOORD_0, D3DWRAPCOORD_1, D3DWRAPCOORD_2,
and D3DWRAPCOORD_3 flags to enable wrapping in first, second, third, and fourth
directions of the texture. Use a value of zero to disable wrapping altogether.
Texture wrapping is disabled in all directions for all texture stages by
default. [Visual Basic] The D3DRS_WRAP0 through D3DRS_WRAP7 render states
control texture wrapping for various textures in the device's multitexture
cascade. You can set these render states to a combination of the
D3DWRAPCOORD_0, D3DWRAPCOORD_1, D3DWRAPCOORD_2, and D3DWRAPCOORD_3 values from
the CONST_D3DWRAPFLAGS enumeration to enable wrapping in first, second, third,
and fourth directions of the texture. Use a value of zero to disable wrapping
altogether. Texture wrapping is disabled in all directions for all texture
stages by default. For a conceptual overview, see Texture Wrapping. Texture
Stage States This section introduces the concept of texture stage states and
discusses the various texture stage states in detail. Information in this
section is organized into the following topics. * About Texture Stage States *
Texture Addressing State * Texture Border State * Texture Filtering State *
Texture Blending State About Texture Stage States Texture stage states control
the style of texturing and how texture filtering is done. C++] Applications
written in C++ control the characteristics of the texture-related render states
by invoking the IDirect3DDevice8::SetTextureStageState method. The
D3DTEXTURESTAGESTATETYPE enumerated type specifies all the possible
texture-related rendering states. Your application passes a value from the
D3DTEXTURESTAGESTATETYPE enumeration as the first parameter to the
SetTextureStageState method. Applications set the texture for a stage by
calling the IDirect3DDevice8::SetTexture method. [Visual Basic] Microsoft®
Visual Basic® applications control the characteristics of the texture- related
rendering states by invoking the Direct3DDevice8.SetTextureStageState method.
The CONST_D3DTEXTURESTAGESTATETYPE enumeration specifies all possible
texture-related rendering states. Your application passes a value from the
CONST_D3DRENDERSTATETYPE enumeration as the first parameter to the
SetTextureStageState method. Applications set the texture for a stage by
calling the Direct3DDevice8.SetTexture method. Texture Addressing State [C++]
C++ applications use the D3DTSS_ADDRESSU, D3DTSS_ADDRESSV, and D3DTSS_ADDRESSW
texture stage states to set the texture addressing. [Visual Basic] Microsoft®
Visual Basic® applications use the D3DTSS_ADDRESSU, D3DTSS_ADDRESSV, and
D3DTSS_ADDRESSW texture stage states to set texture addressing. Texture Border
State [C++] C++ applications use the D3DTSS_BORDERCOLOR texture stage state to
set border color texture addressing. [Visual Basic] Microsoft® Visual Basic®
applications use the D3DTSS_BORDERCOLOR texture stage state to set border color
texture addressing. For more information, see Border Color Texture Address
Mode. Texture Filtering State [C++] C++ applications use the D3DTSS_MAGFILTER,
D3DTSS_MINFILTER, and D3DTSS_MIPFILTER, and texture-stage states to control
texture filtering. [Visual Basic] Microsoft® Visual Basic® applications use the
D3DTSS_MAGFILTER, D3DTSS_MINFILTER, and D3DTSS_MIPFILTER, and texture-stage
states to control texture filtering. Texture Blending State [C++] C++
applications use the texture blending states defined by the D3DTSS_COLOROP and
D3DTSS_ALPHAOP texture stage states to control texture blending. [Visual Basic]
Microsoft® Visual Basic® applications use the texture blending states defined
by the D3DTSS_COLOROP and D3DTSS_ALPHAOP texture stage states to control
texture blending. For more information, see Multiple Texture Blending. State
Blocks The following topics in this section describe the key concepts of device
state blocks and provide information about how applications use state blocks. *
About State Blocks * Recording State Blocks * Capturing State Blocks * Applying
State Blocks * Creating Predefined State Blocks * Deleting State Blocks About
State Blocks A state block in Microsoft® Direct3D® is a group of device
states—render states, lighting and material parameters, transformation states,
texture stage states, and current texture information. The state block is a
snapshot of the device's current state, or it is explicitly recorded. The
snapshot can be applied to a device in a single call. Device-state blocks can
be optimized by the rendering device to accelerate the common sequences of
state changes that your application requires, or they can simply make applying
device states easier. [C++] In C++, you receive a state-block handle when you
finish recording a state block by calling the IDirect3DDevice8::EndStateBlock
method, and when you capture a predefined set of device state data by calling
the IDirect3DDevice8::CreateStateBlock method. [Visual Basic] In Microsoft
Visual Basic®, you receive a state-block handle when you finish recording a
state block by calling the Direct3DDevice8.EndStateBlock method, and when you
capture a predefined set of device state data by calling the
Direct3DDevice8.CreateStateBlock method. Recording State Blocks [C++] The
IDirect3DDevice8 interface provides the IDirect3DDevice8::BeginStateBlock
method to record device states in a state block as your application calls for
them. The BeginStateBlock method causes the system to start recording device
state changes in a state block, rather than applying them to the device. After
you call BeginStateBlock, calls to any of the following methods are recorded in
a device state block. * IDirect3DDevice8::LightEnable *
IDirect3DDevice8::SetClipPlane * IDirect3DDevice8::SetLight *
IDirect3DDevice8::SetMaterial * IDirect3DDevice8::SetRenderState *
IDirect3DDevice8::SetTexture * IDirect3DDevice8::SetTextureStageState *
IDirect3DDevice8::SetTransform * IDirect3DDevice8::SetViewport When you're done
recording the state block, notify the system to stop recording by calling the
IDirect3DDevice8::EndStateBlock method. The EndStateBlock method places the
handle of the state block in the variable whose address you pass in the pToken
parameter. Your application uses this handle to apply the state block to the
device as needed, to capture new state data into the block, and to delete the
state block when it is no longer required. [Visual Basic] The Direct3DDevice8
object offers the Direct3DDevice8.BeginStateBlock method to record device
states in a state block as your application calls for them. The BeginStateBlock
method causes the system to start recording device state changes in a state
block, rather than applying them to the device. After you call BeginStateBlock,
calls to any of the following methods are recorded in a device state block. *
Direct3DDevice8.LightEnable * Direct3DDevice8.SetClipPlane *
Direct3DDevice8.SetLight * Direct3DDevice8.SetMaterial *
Direct3DDevice8.SetRenderState * Direct3DDevice8.SetTexture *
Direct3DDevice8.SetTextureStageState * Direct3DDevice8.SetTransform *
Direct3DDevice8.SetViewport When you are done recording the state block, notify
the system to stop recording by calling the Direct3DDevice8.EndStateBlock
method. The EndStateBlock method places the handle of the state block in the
method's return value. Your application uses this handle to apply the state
block to the device as needed, to capture new state data into the block, and to
delete the state block when it is no longer required. Performance Note For best
results, group all state changes tightly between a BeginStateBlock and
EndStateBlock pair. It is important to check the error code from the
EndStateBlock method. If the method fails, it is likely because the display
mode has changed. Design your application to recover from this type of failure
by recreating its surfaces and recording the state block again. Capturing State
Blocks [C++] The IDirect3DDevice8::CaptureStateBlock method updates the values
within an existing state block to reflect the current state of the device. The
method accepts a single parameter, Token, that identifies the state block that
will receive the current state of the device if the call succeeds. The
CaptureStateBlock method is especially useful to update a state block that your
application has already recorded to include slightly different state settings.
To do so, apply the existing state block, change the necessary settings, then
capture the state of the system back to the state block, as shown in the
following code example. // The token variable contains a handle to a
device-state block for // a previously recorded set of device states. // Set
the current state block. d3dDevice->ApplyStateBlock(token); // Change device
states as needed. . . . // Capture the modified device state data back to the
existing block. d3dDevice->CaptureStateBlock(token); The CaptureStateBlock
method doesn't capture the entire state of the device; it only updates the
values for the states already in the state block. For example, imagine a state
block that contains the two operations shown in the following code example.
d3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
d3dDevice->SetTexture(0, pTexture); If your application changed either of these
settings since the state block was originally recorded, the CaptureStateBlock
method will update the states within the block—and only those states—to their
new values. [Visual Basic] The Direct3DDevice8.CaptureStateBlock method updates
the values in an existing state block to reflect the current state of the
device. The method accepts a single parameter, Token, that identifies the state
block that will receive the current state of the device if the call succeeds.
The CaptureStateBlock method is especially useful to update a state block that
your application has already recorded to include slightly different state
settings. To do so, apply the existing state block, change the necessary
settings, then capture the state of the system back to the state block, as
shown in the following code example. ' The Token variable contains a handle to
a device state block for ' a previously recorded set of device states. ' Set
the current state block. Call d3dDevice.ApplyStateBlock(Token) ' Change device
states as needed. . . . ' Capture the modified device state data back to the
existing block. Call d3dDevice.CaptureStateBlock(Token) The CaptureStateBlock
method doesn't capture the entire state of the device; it only updates the
values for the states already in the state block. For example, imagine a state
block that contains the two operations shown in the following code example.
Call d3dDevice.SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD) Call
d3dDevice.SetTexture(0, Texture) If your application changed either of these
settings since the state block was originally recorded, the CaptureStateBlock
method will update the states within the block—and only those states—to their
new values. Applying State Blocks [C++] The IDirect3DDevice8::ApplyStateBlock
method applies an existing state block to the device. The ApplyStateBlock
method accepts a single parameter, Token, that identifies the state block to
apply. Note You cannot apply a state block while recording another state
block—that is, between calls to IDirect3DDevice8::BeginStateBlock and
IDirect3DDevice8::EndStateBlock. Attempts to do so will fail. [Visual Basic]
The Direct3DDevice8.ApplyStateBlock method applies an existing state block to
the device. The ApplyStateBlock method accepts a single parameter, Token, that
identifies the state block to apply. Note You cannot apply a state block while
recording another state block—that is, between calls to
Direct3DDevice8.BeginStateBlock and Direct3DDevice8.EndStateBlock. Attempts to
do so will fail. Creating Predefined State Blocks [C++] The
IDirect3DDevice8::CreateStateBlock method creates a new state block that
contains the entire set of device states or only those device states related to
vertex or pixel processing. The CreateStateBlock method accepts two parameters.
The first parameter identifies the type of state information to capture in the
new state block, and the second parameter is the address of a variable that
will receive a valid state- block handle if the call succeeds. Valid values for
the first parameter are defined by the D3DSTATEBLOCKTYPE enumerated type, which
includes members that you can use to capture the entire set of device states
(D3DSBT_ALL), or only those states that pertain to vertex or pixel processing
(D3DSBT_VERTEXSTATE or D3DSBT_PIXELSTATE). The following list summarizes the
states that the system captures when you pass the D3DSBT_VERTEXSTATE or
D3DSBT_PIXELSTATE values. * Vertex-related states (D3DSBT_VERTEXSTATE) * State
(enabled or disabled) of all lights * Transformation matrices * User-defined
clipping planes These values are set for the following render states.
D3DRS_AMBIENT D3DRS_AMBIENTMATERIALSOURCE D3DRS_CLIPPING D3DRS_CLIPPLANEENABLE
D3DRS_COLORVERTEX D3DRS_CULLMODE D3DRS_DIFFUSEMATERIALSOURCE
D3DRS_EMISSIVEMATERIALSOURCE D3DRS_FOGCOLOR D3DRS_FOGDENSITY D3DRS_FOGENABLE
D3DRS_FOGEND D3DRS_FOGSTART D3DRS_FOGTABLEMODE D3DRS_FOGVERTEXMODE
D3DRS_INDEXEDVERTEXBLENDENABLE D3DRS_LIGHTING D3DRS_LOCALVIEWER
D3DRS_NORMALIZENORMALS D3DRS_POINTSCALE_A D3DRS_POINTSCALE_B D3DRS_POINTSCALE_C
D3DRS_POINTSIZE D3DRS_POINTSIZE_MAX D3DRS_POINTSIZE_MIN D3DRS_POINTSCALEENABLE
D3DRS_POINTSPRITEENABLE D3DRS_PATCHEDGESTYLE D3DRS_PATCHSEGMENTS
D3DRS_RANGEFOGENABLE D3DRS_SHADEMODE D3DRS_SOFTWAREVERTEXPROCESSING
D3DRS_SPECULARENABLE D3DRS_SPECULARMATERIALSOURCE D3DRS_TWEENFACTOR
D3DRS_VERTEXBLEND These values are set for the following texture-stage states.
D3DTSS_TEXCOORDINDEX D3DTSS_TEXTURETRANSFORMFLAGS * Pixel-related states
(D3DSBT_PIXELSTATE) These values are set for the following render states.
D3DRS_ALPHABLENDENABLE D3DRS_ALPHAFUNC D3DRS_ALPHAREF D3DRS_ALPHATESTENABLE
D3DRS_COLORWRITEENABLE D3DRS_DESTBLEND D3DRS_DITHERENABLE D3DRS_EDGEANTIALIAS
D3DRS_FILLMODE D3DRS_FOGDENSITY D3DRS_FOGEND D3DRS_FOGSTART D3DRS_LASTPIXEL
D3DRS_LINEPATTERN D3DRS_MULTISAMPLEANTIALIAS D3DRS_MULTISAMPLEMASK
D3DRS_SHADEMODE D3DRS_SRCBLEND D3DRS_STENCILENABLE D3DRS_STENCILFAIL
D3DRS_STENCILFUNC D3DRS_STENCILMASK D3DRS_STENCILPASS D3DRS_STENCILREF
D3DRS_STENCILWRITEMASK D3DRS_STENCILZFAIL D3DRS_TEXTUREFACTOR D3DRS_WRAP0
through D3DRS_WRAP7 D3DRS_ZBIAS D3DRS_ZENABLE D3DRS_ZFUNC D3DRS_ZWRITEENABLE
These values are set for the following texture-stage states. D3DTSS_ADDRESSU
D3DTSS_ADDRESSV D3DTSS_ADDRESSW D3DTSS_ALPHAARG1 D3DTSS_ALPHAARG2
D3DTSS_ALPHAOP D3DTSS_BORDERCOLOR D3DTSS_BUMPENVLOFFSET D3DTSS_BUMPENVLSCALE
D3DTSS_BUMPENVMAT00 D3DTSS_BUMPENVMAT01 D3DTSS_BUMPENVMAT10 D3DTSS_BUMPENVMAT11
D3DTSS_COLORARG1 D3DTSS_COLORARG2 D3DTSS_COLOROP D3DTSS_MAGFILTER
D3DTSS_MAXANISOTROPY D3DTSS_MAXMIPLEVEL D3DTSS_MINFILTER D3DTSS_MIPFILTER
D3DTSS_MIPMAPLODBIAS D3DTSS_TEXCOORDINDEX D3DTSS_TEXTURETRANSFORMFLAGS [Visual
Basic] The Direct3DDevice8.CreateStateBlock method creates a new state block
that contains the entire set of device states or only those device states
related to vertex or pixel processing. The CreateStateBlock method accepts two
parameters. The first parameter identifies the type of state information to
capture in the new state block, and the second parameter is the address of a
variable that will receive a valid state- block handle if the call succeeds.
Valid values for the first parameter are defined by the CONST_D3DSTATEBLOCKTYPE
enumeration, which includes members that you can use to capture the entire set
of device states (D3DSBT_ALL), or only those states that pertain to vertex or
pixel processing (D3DSBT_VERTEXSTATE or D3DSBT_PIXELSTATE). The following list
summarizes the states that the system captures when you pass the
D3DSBT_VERTEXSTATE or D3DSBT_PIXELSTATE values. * Vertex-related states
(D3DSBT_VERTEXSTATE) * State (enabled or disabled) of all lights *
Transformation matrices * User-defined clipping planes These values are set for
the following render states. D3DRS_AMBIENT D3DRS_AMBIENTMATERIALSOURCE
D3DRS_CLIPPING D3DRS_CLIPPLANEENABLE D3DRS_COLORVERTEX D3DRS_CULLMODE
D3DRS_DIFFUSEMATERIALSOURCE D3DRS_EMISSIVEMATERIALSOURCE D3DRS_FOGCOLOR
D3DRS_FOGDENSITY D3DRS_FOGENABLE D3DRS_FOGEND D3DRS_FOGSTART D3DRS_FOGTABLEMODE
D3DRS_FOGVERTEXMODE D3DRS_INDEXVERTEXBLENDENABLE D3DRS_LIGHTING
D3DRS_LOCALVIEWER D3DRS_NORMALIZENORMALS D3DRS_POINTSCALE_A D3DRS_POINTSCALE_B
D3DRS_POINTSCALE_C D3DRS_POINTSIZE D3DRS_POINTSIZE_MAX D3DRS_POINTSIZE_MIN
D3DRS_POINTSCALEENABLE D3DRS_POINTSPRITEENABLE D3DRS_PATCHSEGMENTS
D3DRS_RANGEFOGENABLE D3DRS_SHADEMODE D3DRS_SOFTWAREVERTEXPROCESSING
D3DRS_SPECULARENABLE D3DRS_SPECULARMATERIALSOURCE D3DRS_TWEENFACTOR
D3DRS_VERTEXBLEND These values are set for the following texture-stage states.
D3DTSS_TEXCOORDINDEX D3DTSS_TEXTURETRANSFORMFLAGS * Pixel-related States
(D3DSBT_PIXELSTATE) These values are set for the following render states.
D3DRS_ALPHABLENDENABLE D3DRS_ALPHAFUNC D3DRS_ALPHAREF D3DRS_ALPHATESTENABLE
D3DRS_COLORWRITEENABLE D3DRS_DESTBLEND D3DRS_DITHERENABLE D3DRS_EDGEANTIALIAS
D3DRS_FILLMODE D3DRS_FOGDENSITY D3DRS_FOGEND D3DRS_FOGSTART D3DRS_LASTPIXEL
D3DRS_LINEPATTERN D3DRS_MULTISAMPLEANTIALIAS D3DRS_MULTISAMPLEMASK
D3DRS_SHADEMODE D3DRS_SRCBLEND D3DRS_STENCILENABLE D3DRS_STENCILFAIL
D3DRS_STENCILFUNC D3DRS_STENCILMASK D3DRS_STENCILPASS D3DRS_STENCILREF
D3DRS_STENCILWRITEMASK D3DRS_STENCILZFAIL D3DRS_TEXTUREFACTOR D3DRS_WRAP0
through D3DRS_WRAP7 D3DRS_ZBIAS D3DRS_ZENABLE D3DRS_ZFUNC D3DRS_ZWRITEENABLE
These values are set for the following texture-stage states. D3DTSS_ADDRESSU
D3DTSS_ADDRESSV D3DTSS_ADDRESSW D3DTSS_ALPHAARG1 D3DTSS_ALPHAARG2
D3DTSS_ALPHAOP D3DTSS_BORDERCOLOR D3DTSS_BUMPENVLOFFSET D3DTSS_BUMPENVLSCALE
D3DTSS_BUMPENVMAT00 D3DTSS_BUMPENVMAT01 D3DTSS_BUMPENVMAT10 D3DTSS_BUMPENVMAT11
D3DTSS_COLORARG1 D3DTSS_COLORARG2 D3DTSS_COLOROP D3DTSS_MAGFILTER
D3DTSS_MAXANISOTROPY D3DTSS_MAXMIPLEVEL D3DTSS_MINFILTER D3DTSS_MIPFILTER
D3DTSS_MIPMAPLODBIAS D3DTSS_TEXCOORDINDEX D3DTSS_TEXTURETRANSFORMFLAGS Note It
is important to check the error code from the CreateStateBlock method. If the
method fails, it is likely because the display mode has changed. Your
application should recover from this type of failure by recreating its
surfaces, and then recreating the state block. Deleting State Blocks [C++] The
IDirect3DDevice8::DeleteStateBlock deletes a state block, deallocating the
memory used to contain it. The DeleteStateBlock method accepts the handle to
the state block to delete at its only parameter. After deleting a state block,
any handles to it are invalid, and can no longer be used. [Visual Basic] The
Direct3DDevice8.DeleteStateBlock deletes a state block, deallocating the memory
used to contain it. The DeleteStateBlock method accepts the handle to the state
block to delete at its only parameter. After deleting a state block, any
handles to it are invalid, and can no longer be used. Lost Devices This section
provides information about lost devices in Microsoft® Direct3D®. Information is
divided into the following topics. * What is a Lost Device? * Responding to a
Lost Device * Lost Devices and Locking Operations * Lost Devices and Resources
* Lost Devices and Retrieved Data What is a Lost Device? [C++] A Microsoft®
Direct3D® device can be in either an operational state or a lost state. The
operational state is the normal state of the device; the device executes and
presents all rendering as expected. The device makes a transition to the lost
state when an event—such as the loss of keyboard focus in a full-screen
application— causes rendering to become impossible. The lost state is
characterized by the silent failure of all rendering operations, which means
that the rendering methods can return success codes even though the rendering
operations fail. In this situation, the error code D3DERR_DEVICELOST is
returned by IDirect3DDevice8::Present. By design, the full set of scenarios
that can cause a device to become lost is not specified. Some typical examples
include loss of focus, such as when the user presses ALT+TAB or when a system
dialog is initialized. Devices can also be lost due to a power management
event, or when another application assumes full-screen operation. In addition,
any failure from IDirect3DDevice8::Reset puts the device into a lost state.
[Visual Basic] A Microsoft® Direct3D® device can be in either an operational
state or a lost state. The operational state is the normal state of the device;
the device executes and presents all rendering as expected. The device makes a
transition to the lost state when an event—such as the loss of keyboard focus
in a full-screen application— causes rendering to become impossible. The lost
state is characterized by the silent failure of all rendering operations, which
means that the rendering methods can return success codes even though the
rendering operations fail. In this situation, the error code D3DERR_DEVICELOST
is returned by Direct3DDevice8.Present. By design, the full set of scenarios
that can cause a device to become lost is not specified. Some typical examples
include loss of focus, such as when the user presses ALT+TAB or when a system
dialog is initialized. Devices can also be lost due to a power management
event, or when another application assumes full-screen operation. In addition,
any failure from Direct3DDevice8.Reset puts the device into a lost state.
Responding to a Lost Device [C++] If a device is lost, the application queries
the device to see if it can be restored to the operational state. If not, the
application waits until the device can be restored. If the device can be
restored, the application prepares the device by destroying all video-memory
resources and any swap chains. Then, the application calls the
IDirect3DDevice8::Reset method. Reset is the only method that has an effect
when a device is lost, and is the only method by which an application can
change the device from a lost to an operational state. Reset will fail unless
the application releases all resources that are allocated in D3DPOOL_DEFAULT,
including those created by the IDirect3DDevice8::CreateRenderTarget and
IDirect3DDevice8::CreateDepthStencilSurface methods. For the most part, the
high-frequency calls of Microsoft® Direct3D® do not return any information
about whether the device has been lost. The application can continue to call
rendering methods, such as IDirect3DDevice8::DrawPrimitive, without receiving
notification of a lost device. Internally, these operations are discarded until
the device is reset to the operational state. The application can determine
what to do on encountering a lost device by querying the return value of the
IDirect3DDevice8::TestCooperativeLevel method. * If the method returns D3D_OK,
the device is operational. * If the device is lost but cannot be restored at
the current time, the return value is D3DERR_DEVICELOST. This is the case when
the user presses ALT+TAB, causing a full-screen device to lose focus.
Applications should respond by pausing until the device can be reset. A
D3DERR_DEVICENOTRESET return code from TestCooperativeLevel indicates this
situation. * If the device is lost and can be restored, the return code from
TestCooperativeLevel is D3DERR_DEVICENOTRESET. Note that the return code from
the IDirect3DDevice8::Present method is still D3DERR_DEVICELOST. In all cases,
destroying video-memory resources is a prerequisite to calling Reset, even if
the device has not been lost. [Visual Basic] If a device is lost, the
application queries the device to see if it can be restored to the operational
state. If not, the application waits until the device can be restored. If the
device can be restored, the application prepares the device by destroying all
video-memory resources and any swap chains. Then, the application calls
Direct3DDevice8.Reset. Reset is the only method that has an effect when the
device is lost, and is the only method by which an application can change the
device from a lost to an operational state. Reset will fail unless the
application releases all resources that are allocated in D3DPOOL_DEFAULT,
including those created by the Direct3DDevice8.CreateRenderTarget and
Direct3DDevice8.CreateDepthStencilSurface methods. For the most part, the
high-frequency calls of Microsoft® Direct3D® do not return information about
whether the device has been lost. The application can continue to call
rendering methods, such as Direct3DDevice8.DrawPrimitive, without receiving
notification of a lost device. Internally, these operations are discarded until
the device is reset to the operational state. The application can determine
what to do on encountering a lost device by querying the return value of the
Direct3DDevice8.TestCooperativeLevel method. * If the method returns D3D_OK,
the device is operational. * If the device is lost but cannot be restored at
the current time, the return value is D3DERR_DEVICELOST. This is the case when
the user presses ALT+TAB, causing a full-screen device to lose focus.
Applications should respond by pausing until the device can be reset. A
D3DERR_DEVICENOTRESET return code from TestCooperativeLevel indicates this
situation. * If the device is lost and can be restored, the return code from
TestCooperativeLevel is D3DERR_DEVICENOTRESET. Note that the return code from
the Direct3DDevice8.Present method is still D3DERR_DEVICELOST. In all cases,
destroying video-memory resources is a prerequisite to calling Reset, even if
the device has not been lost. Lost Devices and Locking Operations Internally,
Microsoft® Direct3D® does enough work to ensure that a lock operation will
succeed after a device is lost. However, it is not guaranteed that the video-
memory resource's data will be accurate during the lock operation. It is
guaranteed that no error code will be returned. This allows applications to be
written without concern for device loss during a lock operation. For more
information, see Lost Devices and Retrieved Data. Lost Devices and Resources
[C++] Resources can consume video memory. Because a lost device is disconnected
from the video memory owned by the adapter, it is not possible to guarantee
allocation of video memory when the device is lost. As a result, all resource
creation methods are implemented to succeed by returning D3D_OK, but do in fact
allocate only dummy system memory. Because any video-memory resource must be
destroyed before the device is resized, there is no issue of over-allocating
video memory. These dummy surfaces allow lock and copy operations to appear to
function normally until the application calls IDirect3DDevice8::Present and
discovers that the device has been lost. All video memory must be released
before a device can be reset from a lost state to an operational state. This
means that the application should release any swap chains created with
IDirect3DDevice8::CreateAdditionalSwapChain and any resources placed in the
D3DPOOL_DEFAULT memory class. The application need not release resources in the
D3DPOOL_MANAGED or D3DPOOL_SYSTEMMEM memory classes. Other state data is
automatically destroyed by the transition to an operational state. [Visual
Basic] Resources can consume video memory. Because a lost device is
disconnected from the video memory owned by the adapter, it is not possible to
guarantee allocation of video memory when the device is lost. As a result, all
resource creation methods are implemented to succeed by returning D3D_OK, but
do in fact allocate only dummy system memory. Because any video-memory resource
must be destroyed before the device is resized, there is no issue of
over-allocating video memory. These dummy surfaces allow lock and copy
operations to appear to function normally until the application calls
Direct3DDevice8.Present and discovers that the device has been lost. All video
memory must be released before a device can be reset from a lost state to an
operational state. This means that the application should release any swap
chains created with Direct3DDevice8.CreateAdditionalSwapChain and any resources
placed in the D3DPOOL_DEFAULT memory class. The application need not release
resources in the D3DPOOL_MANAGED or D3DPOOL_SYSTEMMEM memory classes. Other
state data is automatically destroyed by the transition to an operational
state. You are encouraged to develop applications with a single code path to
respond to device loss. This code path is likely to be similar, if not
identical, to the code path taken to initialize the device at startup. Lost
Devices and Retrieved Data Microsoft® Direct3D® allows applications to copy
generated or previously written images from video-memory resources to
nonvolatile system-memory resources. Because the source images of such
transfers might be lost at any time, Direct3D allows such copy operations to
fail when the device is lost. [C++] The copy operations,
IDirect3DDevice8::UpdateTexture and IDirect3DDevice8::CopyRects, can return
D3DERR_DEVICELOST when the source object is in volatile memory
(D3DPOOL_DEFAULT) and the destination object is in nonvolatile memory
(D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED). Another copy operation,
IDirect3DDevice8::GetFrontBuffer, can fail due to retrieving data from the
primary surface. Note that these cases are the only instance of
D3DERR_DEVICELOST outside of the IDirect3DDevice8::Present,
IDirect3DDevice8::TestCooperativeLevel, and IDirect3DDevice8::Reset methods.
[Visual Basic] The copy operations, Direct3DDevice8.UpdateTexture and
Direct3DDevice8.CopyRects, can return D3DERR_DEVICELOST when the source object
is in volatile memory (D3DPOOL_DEFAULT) and the destination object is in
nonvolatile memory (D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED). Another copy
operation, Direct3DDevice8.GetFrontBuffer, can fail due to retrieving data from
the primary surface. Note that these cases are the only instance of
D3DERR_DEVICELOST outside of the Direct3DDevice8.Present,
Direct3DDevice8.TestCooperativeLevel, and Direct3DDevice8.Reset methods.
Direct3D Resources This section discusses resources and gives a general
overview on how they are used in your application. Information is divided into
the following topics. * What Are Resources? * Resource Properties * Resource
Relationships * Using Resources What Are Resources? Resources are the textures
and buffers that are used to render a scene. Applications need to create, load,
copy, and use resources. This section gives a brief introduction to resources
and the steps and methods used by applications when working with resources. For
more information on specific resource types, see Textures, Vertex Buffers, and
Index Buffers. [C++] All resources, including the geometry resources
IDirect3DIndexBuffer8 and IDirect3DVertexBuffer8, inherit from the
IDirect3DResource8 interface. The texture resources, IDirect3DCubeTexture8,
IDirect3DTexture8, and IDirect3DVolumeTexture8, also inherit from the
IDirect3DBaseTexture8 interface. [Visual Basic] All resources, including the
geometry resources Direct3DIndexBuffer8 and Direct3DVertexBuffer8, implement
the methods of the Direct3DResource8 class. The texture resources,
Direct3DCubeTexture8, Direct3DTexture8, and Direct3DVolumeTexture8, also
implement the methods of the Direct3DBaseTexture8 class. Resource Properties
All resources share the following properties. * Usage. The way a resource is
used—for example, as a texture or a render target. * Format. The format of the
data—for example, the pixel format of a 2-D surface. * Pool. The type of memory
where the resource is allocated. * Type. The type of resource—for example, a
vertex buffer or render target. Resource uses are enforced. An application that
will use a resource in a certain operation must specify that operation at
resource creation time. The following usages are defined for resources. *
D3DUSAGE_DEPTHSTENCIL * D3DUSAGE_DONOTCLIP * D3DUSAGE_DYNAMIC *
D3DUSAGE_RTPATCHES * D3DUSAGE_NPATCHES * D3DUSAGE_POINTS *
D3DUSAGE_RENDERTARGET * D3DUSAGE_SOFTWAREPROCESSING * D3DUSAGE_WRITEONLY The
D3DUSAGE_RTPATCHES, D3DUSAGE_NPATCHES, and D3DUSAGE_POINTS flags indicate to
the driver that the data in these buffers is likely to be used for triangular
or grid patches, N patches, or point sprites, respectively. These flags are
provided in case the hardware cannot perform these operations without host
processing. Therefore, the driver will want to allocate these surfaces in
system memory so that the CPU can access them. If the driver can perform these
operations entirely in hardware, then it can allocate these surfaces in video
or /AGP memory to avoid a host copy and improve performance at least twofold.
Note that the information provided by these flags is not absolutely required. A
driver can detect that such operations are being performed on the data, and it
will move the buffer back to system memory for subsequent frames. For details
on the usage flags and how they relate to specific resources, see the reference
pages on the individual resource creation methods. [C++] For information on the
surface format of resources, see the D3DFORMAT enumerated type. The class of
memory that holds a resource's buffers is called a pool. Pool values are
defined by the D3DPOOL enumerated type. A pool cannot be mixed for different
objects contained in a single resource—that is, mip levels in a mipmap—and once
a pool is chosen for a resource, the pool cannot be changed. The resources
types are set implicitly at run time when the application calls a resource
creation method such as IDirect3DDevice8::CreateCubeTexture. Resource types are
defined by the D3DRESOURCETYPE enumerated type. Applications can query these
types at run time; however, it is expected that most scenarios will not require
run-time type checking. [Visual Basic] For information on the surface format of
resources, see the CONST_D3DFORMAT enumeration. The class of memory that holds
a resource's buffers is called a pool. Pool values are defined by the
CONST_D3DPOOL enumeration. A pool cannot be mixed for different objects
contained in a single resource—that is, mip levels in a mipmap— and once a pool
is chosen for a resource, the pool cannot be changed. The resources types are
set implicitly at run time when the application calls a resource creation
method such as Direct3DDevice8.CreateCubeTexture. Resource types are defined by
the CONST_D3DRESOURCETYPE enumeration. Applications can query these types at
run time; however, it is expected that most scenarios will not require run-time
type checking. Resource Relationships The following diagram illustrates the
operations that are syntactically possible on specific resources and their
contents. For more information on how to use resources, see Manipulating
Resources. Arrows running from left to right indicate that the target types are
created by the given methods, while arrows running from right to left indicate
that those resource types can be passed as arguments to the given methods.
Using Resources The following topics discuss common tasks that applications
perform when working with resources. * Managing Resources * Application-Managed
Resources and Allocation Strategies * Manipulating Resources * Locking
Resources Managing Resources [C++] Resource management is the process where
resources are promoted from system- memory storage to device-accessible storage
and discarded from device-accessible storage. The Microsoft® Direct3D® run time
has its own management algorithm based on a least-recently-used priority
technique. Direct3D switches to a most- recently-used priority technique when
it detects that more resources than can coexist in device-accessible memory are
used in a single frame—between IDirect3DDevice8::BeginScene and
IDirect3DDevice8::EndScene calls. Use the D3DPOOL_MANAGED flag at creation time
to specify a managed resource. Managed resources persist through transitions
between the lost and operational states of the device. The device can be
restored with a call to IDirect3DDevice8::Reset, and such resources continue to
function normally without being reloaded with artwork. However, if the device
must be destroyed and recreated, all resources created using D3DPOOL_MANAGED
must be recreated. Use the D3DPOOL_DEFAULT flag at creation time to specify
that a resource be placed in the default pool. Resources in the default pool do
not persist through transitions between the lost and operational states of the
device. These resources must be released before calling Reset and must then be
recreated. [Visual Basic] Resource management is the process where resources
are promoted from system- memory storage to device-accessible storage and
discarded from device-accessible storage. The Microsoft® Direct3D® run time has
its own management algorithm based on a least-recently-used priority technique.
Direct3D switches to a most- recently-used priority technique when it detects
that more resources than can coexist in device-accessible memory are used
within a single frame—between Direct3DDevice8.BeginScene and
Direct3DDevice8.EndScene calls. Use the D3DPOOL_MANAGED flag at creation time
to specify a managed resource. Managed resources persist through transitions
between the lost and operational states of the device. The device can be
restored with a call to Direct3DDevice8.Reset, and such resources continue to
function normally without being reloaded with artwork. However, if the device
must be destroyed and recreated, all resources created using D3DPOOL_MANAGED
must be recreated. Use the D3DPOOL_DEFAULT flag at creation time to specify
that a resource be placed in the default pool. Resources in the default pool do
not persist through transitions between the lost and operational states of the
device. These resources must be released before calling Reset and must then be
recreated. For more information on the lost state of a device, see Lost
Devices. Note that resource management is not supported for all types and
usages. For example, objects created with the D3DUSAGE_RENDERTARGET flag are
not supported. In addition, resource management is not recommended for objects
whose contents are changing with high frequency. For example, a managed vertex
buffer that changes every frame can significantly degrade performance for some
hardware. However, this is not a problem for texture resources.
Application-Managed Resources and Allocation Strategies Managed vertex-buffer
or index-buffer resources cannot be declared dynamic by specifying
D3DUSAGE_DYNAMIC at creation time. This would require an additional copy for
every modification to the vertex buffer contents. Dynamic vertex buffers are
intended for rendering dynamic geometry as well as data pulled in from BSP
trees or other visibility data structures. This can be accomplished by pre-
allocating buffers of the desired format. These resources are then parceled out
to support application needs by a resource manager within the application.
Because there are only a few different vertex strides that an application will
use simultaneously, and a different vertex buffer is required only for each
unique stride, the total number of dynamic vertex buffers is small. When
managing dynamic resources in this way, it is important to ensure that
high-frequency demands on the resources do not significantly decrease the
application's performance. When simultaneously using both D3D-managed and
application-managed resources, all application managed resources should be
allocated in D3DPOOL_DEFAULT memory prior to creating any managed resources.
Allocating resources in D3DPOOL_DEFAULT memory after allocating resources in
D3DPOOL_MANAGED memory will give the D3D memory manager an inaccurate account
of available memory. Manipulating Resources [C++] Your application manipulates
resources in order to render a scene. First, the application creates texture
resources by using the following methods. * IDirect3DDevice8::CreateCubeTexture
* IDirect3DDevice8::CreateTexture * IDirect3DDevice8::CreateVolumeTexture The
texture objects returned by the texture creation methods are containers for
surfaces or volumes; these containers are generically known as buffers. The
buffers owned by the resource inherit the usages, format, and pool of the
resource but have their own type. For more information, see Resource
Properties. The application gains access to the contained surfaces, for the
purpose of loading artwork, by calling the following methods. For details, see
Locking Resources. * IDirect3DCubeTexture8::LockRect *
IDirect3DTexture8::LockRect * IDirect3DVolumeTexture8::LockBox The lock methods
take arguments denoting the contained surface—for example, the mipmap sub-level
or cube face of the texture—and return pointers to the pixels. The typical
application never uses a surface object directly. In addition, the application
creates geometry-oriented resources by using the following methods. *
IDirect3DDevice8::CreateIndexBuffer * IDirect3DDevice8::CreateVertexBuffer Your
application locks and fills the buffer resources by calling the following
methods. * IDirect3DIndexBuffer8::Lock * IDirect3DVertexBuffer8::Lock If your
application is allowing the Microsoft® Direct3D® run time to manage these
resources, then the resource creation process ends here. Otherwise, the
application manages the promotion of system memory resources to
device-accessible resources, where the hardware accelerator can use them, by
calling the IDirect3DDevice8::UpdateTexture method. To present images rendered
from resources, the application also needs color and depth-stencil buffers. For
typical applications, the color buffer is owned by the device's swap chain,
which is a collection of back buffer surfaces, and is implicitly created with
the device. Depth-stencil surfaces can be implicitly created, or explicitly
created by using the IDirect3DDevice8::CreateDepthStencilSurface method. The
application associates a device and its depth and color buffer with a call to
IDirect3DDevice8::SetRenderTarget. For details on presenting the final image,
see Presenting a Scene. [Visual Basic] Your application manipulates resources
in order to render a scene. First, the application creates texture resources by
using the following methods. * Direct3DDevice8.CreateCubeTexture *
Direct3DDevice8.CreateTexture * Direct3DDevice8.CreateVolumeTexture The texture
objects returned by the texture creation methods are containers for surfaces or
volumes; these containers are generically known as buffers. The buffers owned
by the resource inherit the usages, format, and pool of the resource but have
their own type. For more information, see Resource Properties. The application
gains access to the contained surfaces, for the purpose of loading artwork, by
calling the following methods. For details, see Locking Resources. *
Direct3DCubeTexture8.LockRect * Direct3DTexture8.LockRect *
Direct3DVolumeTexture8.LockBox The lock methods take arguments denoting the
contained surface—for example, the mipmap sub-level or cube face of the
texture—and return pointers to the pixels. The typical application never uses a
surface object directly. In addition, the application creates geometry-oriented
resources by using the following methods. * Direct3DDevice8.CreateIndexBuffer *
Direct3DDevice8.CreateVertexBuffer Your application locks and fills the buffer
resources by calling the following functions. * D3DIndexBuffer8SetData *
D3DVertexBuffer8SetData If your application is allowing the Microsoft®
Direct3D® run time to manage these resources, then the resource creation
process ends here. Otherwise, the application manages the promotion of system
memory resources to device-accessible resources, where the hardware accelerator
can use them, by calling Direct3DDevice8.UpdateTexture. To present images
rendered from resources, the application also needs color and depth-stencil
buffers. For typical applications, the color buffer is owned by the device's
swap chain, which is a collection of back buffer surfaces, and is implicitly
created with the device. Depth-stencil surfaces can be implicitly created, or
explicitly created by using the Direct3DDevice8.CreateDepthStencilSurface
method. The application associates a device and its depth and color buffer with
a call to Direct3DDevice8.SetRenderTarget. For details on presenting the final
image, see Presenting a Scene. Locking Resources Locking a resource means
granting CPU access to its storage. The following locking methods are defined
for resources. * D3DLOCK_DISCARD * D3DLOCK_READONLY * D3DLOCK_NOOVERWRITE *
D3DLOCK_NOSYSLOCK * D3DLOCK_NO_DIRTY_UPDATE For details on locking flags and
how they relate to specific resources, see the reference pages on the
individual resource locking methods. Application developers should note that
the D3DLOCK_DISCARD, D3DLOCK_READONLY, and D3DLOCK_NOOVERWRITE flags are only
hints. The run time does not check that applications are following the
functionality specified by these flags. An application that specifies
D3DLOCK_READONLY but then writes to the resource should expect undefined
results. An application that specifies D3DUSAGE_WRITEONLY but then reads from
the resource should expect a significant performance penalty. In general,
working against locking flags, including the locking usage flags, is not
guaranteed to work in the future and may incur a significant performance
penalty both now and in the future. A lock operation is followed by an unlock
operation. For example, after locking a texture, the application subsequently
relinquishes direct access to locked textures by unlocking them. In addition to
granting processor access, any other operations involving that resource are
serialized for the duration of a lock. Only a single lock for a resource is
allowed, even for non-overlapping regions, and no accelerator operations on a
surface can be ongoing while a lock operation is outstanding on that surface.
Each resource interface has methods for locking the contained buffers. Each
texture resource can also lock a sub-portion of that resource. Two-dimensional
resources (surfaces) allow the locking of sub-rectangles, and volume resources
allow the locking of sub-volumes or boxes. Each lock method returns a structure
that contains a pointer to the storage backing the resource and values
representing the distances between rows or planes of data, depending on the
resource type. For details, see the method lists for the resource interfaces.
The returned pointer always points to the top- left byte in the locked
sub-regions. When working with index and vertex buffers, you can make multiple
lock calls; however, you must ensure that the number of lock calls matches the
number of unlock calls. The DXT set of compressed texture formats, which store
pixels in encoded 4?4 blocks, can only be locked on 4?4 boundaries. Surfaces
This section contains information about Microsoft® Direct3D® surfaces. The
following topics are discussed. * Basic Concepts of Surfaces * Gamma Controls *
Accessing Surface Memory Directly * Private Surface Data Basic Concepts of
Surfaces This section contains information about the basic concepts associated
with Microsoft® Direct3D® surfaces. The following topics are discussed. *
Surface Interfaces * Width vs. Pitch * Surface Formats * Flipping Surfaces *
Copying to Surfaces Surface Interfaces [C++] A surface represents a linear area
of display memory. A surface usually resides in the display memory of the
display card, although surfaces can exist in system memory. Surface objects are
contained within the IDirect3DSurface8 interface. An IDirect3DSurface8
interface is obtained by calling one of the following methods. *
IDirect3DCubeTexture8::GetCubeMapSurface *
IDirect3DDevice8::CreateDepthStencilSurface *
IDirect3DDevice8::CreateImageSurface * IDirect3DDevice8::CreateRenderTarget *
IDirect3DDevice8::GetBackBuffer * IDirect3DDevice8::GetDepthStencilSurface *
IDirect3DDevice8::GetFrontBuffer * IDirect3DDevice8::GetRenderTarget *
IDirect3DSwapChain8::GetBackBuffer * IDirect3DTexture8::GetSurfaceLevel The
IDirect3DSurface8 interface enables you to indirectly access memory through the
IDirect3DDevice8::CopyRects method. This method allows you to copy a
rectangular region of pixels from one IDirect3DSurface8 interface to another
IDirect3DSurface8 interface. The surface interface also has methods to directly
access display memory. For example, you can use the IDirect3DSurface8::LockRect
method to lock a rectangular region of display memory. It is important to call
IDirect3DSurface8::UnlockRect after you are done working with the locked
rectangular region on the surface. [Visual Basic] A surface represents a linear
area of display memory. A surface usually resides in the display memory of the
display card, although surfaces can exist in system memory. Surface objects are
contained in the Direct3DSurface8 object. A Direct3DSurface8 class is obtained
by calling one of the following methods. *
Direct3DCubeTexture8.GetCubeMapSurface *
Direct3DDevice8.CreateDepthStencilSurface * Direct3DDevice8.CreateImageSurface
* Direct3DDevice8.CreateRenderTarget * Direct3DDevice8.GetBackBuffer *
Direct3DDevice8.GetDepthStencilSurface * Direct3DDevice8.GetFrontBuffer *
Direct3DDevice8.GetRenderTarget * Direct3DSwapChain8.GetBackBuffer *
Direct3DTexture8.GetSurfaceLevel The Direct3DSurface8 object enables you to
indirectly access memory through the Direct3DDevice8.CopyRects method. This
method allows you to copy a rectangular region of pixels from one
Direct3DSurface8 object to another specified rectangular region on another
Direct3DSurface8 object. The surface object also has methods to directly access
display memory. For example, you can use the Direct3DSurface8.LockRect method
to lock a rectangular region of display memory. It is important to call
Direct3DSurface8.UnlockRect after you are done working with the locked
rectangular region on the surface. Width vs. Pitch Although the terms width and
pitch are often used informally, they have very important, and distinctly
different, meanings. As a result, you should understand the meanings for each,
and how to interpret the values that Microsoft® Direct3D® uses to describe
them. [C++] Direct3D uses the D3DSURFACE_DESC structure to carry information
describing a surface. Among other things, this structure is defined to contain
information about a surface's dimensions, as well as how those dimensions are
represented in memory. The structure uses the Height and Width members to
describe the logical dimensions of the surface. Both members are measured in
pixels. Therefore, the Height and Width values for a 640?480 surface are the
same whether it is an 8-bit surface or a 24-bit RGB surface. When you lock a
surface using the IDirect3DSurface8::LockRect method, the method fills in a
D3DLOCKED_RECT structure that contains the pitch of the surface and a pointer
to the locked bits. The value in the Pitch member describes the surface's
memory pitch, also called stride. Pitch is the distance, in bytes, between two
memory addresses that represent the beginning of one bitmap line and the
beginning of the next bitmap line. Because pitch is measured in bytes rather
than pixels, a 640?480?8 surface has a very different pitch value than a
surface with the same dimensions but a different pixel format. Additionally,
the pitch value sometimes reflects bytes that Direct3D has reserved as a cache,
so it is not safe to assume that pitch is simply the width multiplied by the
number of bytes per pixel. Rather, visualize the difference between width and
pitch as shown in the following illustration. [Visual Basic] Direct3D uses the
D3DSURFACE_DESC type to carry information describing a surface. Among other
things, this structure is defined to contain information about a surface's
dimensions, as well as how those dimensions are represented in memory. The
structure uses the Height and Width members to describe the logical dimensions
of the surface. Both members are measured in pixels. Therefore, the Height and
Width values for a 640?480 surface are the same, whether it is an 8-bit surface
or a 24-bit RGB surface. When you lock a surface using the
Direct3DSurface8.LockRect method, the method fills in a D3DLOCKED_RECT
structure that contains the pitch of the surface and a pointer to the locked
bits. The value in the Pitch member describes the surface's memory pitch, also
called stride. Pitch is the distance, in bytes, between two memory addresses
that represent the beginning of one bitmap line and the beginning of the next
bitmap line. Because pitch is measured in bytes rather than pixels, a 640?480?8
surface has a very different pitch value than a surface with the same
dimensions but a different pixel format. Additionally, the pitch value
sometimes reflects bytes that Direct3D has reserved as a cache, so it is not
safe to assume that pitch is simply the width multiplied by the number of bytes
per pixel. Rather, visualize the difference between width and pitch as shown in
the following illustration. In this figure, the front buffer and back buffer
are both 640?480?8, and the cache is 384?480?8. [C++] Pitch values are only
useful when you are directly accessing surface memory. For example, after
calling the LockRect method, the pBits member of the associated D3DLOCKED_RECT
structure contains the address of the top-left pixel of the locked area of the
surface, and the Pitch member is the surface pitch. You access pixels
horizontally by incrementing or decrementing the surface pointer by the number
of bytes per pixel, and you move up or down by adding the pitch value to, or
subtracting it from, the current surface pointer. [Visual Basic] Pitch values
are only useful when you are directly accessing surface memory. For example,
after calling the LockRect method, the pBits member of the associated
D3DLOCKED_RECT structure contains the address of the top-left pixel of the
locked area of the surface, and the Pitch member is the surface pitch. You
access pixels horizontally by incrementing or decrementing the surface pointer
by the number of bytes per pixel, and you move up or down by adding the pitch
value to, or subtracting it from, the current surface pointer. When accessing
surfaces directly, take care to stay within the memory allocated for the
dimensions of the surface and stay out of any memory reserved for cache.
Additionally, when you lock only a portion of a surface, you must stay within
the rectangle you specify when locking the surface. Failing to follow these
guidelines will have unpredictable results. When rendering directly into
surface memory, always use the pitch returned by the LockRect method. Do not
assume a pitch based solely on the display mode. If your application works on
some display adapters but looks garbled on others, this may be the cause of the
problem. For more information, see Accessing Surface Memory Directly. Surface
Formats [C++] Surface formats dictate how data for each pixel in surface memory
is interpreted. Microsoft® Direct3D® uses the D3DFORMAT member of the
D3DSURFACE_DESC structure to describe the surface format. You can retrieve the
format of an existing surface by calling the IDirect3DSurface8::GetDesc method.
[Visual Basic] Surface formats dictate how data for each pixel in surface
memory is interpreted. Microsoft® Direct3D® uses the CONST_D3DFORMAT member of
the D3DSURFACE_DESC structure to describe a surface format. You can retrieve
the format of an existing surface by calling the Direct3DSurface8.GetDesc
method. Flipping Surfaces A Microsoft® Direct3D® application typically displays
an animated sequence by generating the frames of the animation in back buffers
and presenting them in sequence. Back buffers are organized into swap chains. A
swap chain is a series of buffers that "flip" to the screen one after another.
This can be used to render one scene in memory and then flip the scene to the
screen when rendering is complete. This avoids the phenomenon known as tearing
and allows for smoother animation. [C++] Each device created in Direct3D has at
least one swap chain. When you initialize the first Direct3D device, you set
the BackBufferCount member of the D3DPRESENT_PARAMETERS structure, which tells
Direct3D the number of back buffers that will be in the swap chain. The call to
IDirect3D8::CreateDevice then creates the Direct3D device and corresponding
swap chain. When you use the IDirect3DDevice8::Present method to request a
surface flip operation, the pointers to surface memory for the front buffer and
back buffers are swapped. Flipping is performed by switching pointers that the
display device uses for referencing memory, not by copying surface memory. When
a flipping chain contains a front buffer and more than one back buffer, the
pointers are switched in a circular pattern, as shown in the following
illustration. [Visual Basic] Each device created in Direct3D has at least one
swap chain. When you initialize the first Direct3D device, you set the
BackBufferCount member of the D3DPRESENT_PARAMETERS structure, which tells
Direct3D the number of back buffers that will be in the swap chain. The call to
Direct3D8.CreateDevice then creates the Direct3D device and corresponding swap
chain. When you use the Direct3DDevice8.Present method to request a surface
flip operation, the pointers to surface memory for the front buffer and back
buffers are swapped. Flipping is performed by switching pointers that the
display device uses for referencing memory, not by copying surface memory. When
a flipping chain contains a front buffer and more than one back buffer, the
pointers are switched in a circular pattern, as shown in the following
illustration. [C++] You can create addition swap chains for a device by calling
IDirect3DDevice8::CreateAdditionalSwapChain. An application can create one swap
chain per view and associate each swap chain with a particular window. The
application renders images in the back buffers of each swap chain, and then
presents them individually. The two parameters that CreateAdditionalSwapChain
takes are a pointer to a D3DPRESENT_PARAMETERS structure and the address of a
pointer to an IDirect3DSwapChain8 interface. You can then use
IDirect3DSwapChain8::Present to display the contents of the next back buffer to
the front buffer. Note that a device can only have one full-screen swap chain.
You can gain access to a specific back buffer by calling the
IDirect3DDevice8::GetBackBuffer or IDirect3DSwapChain8::GetBackBuffer methods,
which return a pointer to a IDirect3DSurface8 interface that represents the
returned back buffer surface. Note that calling this method increases the
internal reference count on the IDirect3DDevice8 interface so be sure to call
IUnknown::Release when you are done using this surface or you will have a
memory leak. Remember, Direct3D flips surfaces by swapping surface memory
pointers within the swap chain, not by swapping the surfaces themselves. This
means that you will always render to the back buffer that will be displayed
next. [Visual Basic] You can create addition swap chains for a device by
calling Direct3DDevice8.CreateAdditionalSwapChain. An application can create
one swap chain per view and associate each swap chain with a particular window.
The application renders images in the back buffers of each swap chain, and then
presents them individually. CreateAdditionalSwapChain takes a
D3DPRESENT_PARAMETERS type and returns a Direct3DSwapChain8 object. You can
then use Direct3DSwapChain8.Present to display the contents of the next back
buffer to the front buffer. Note that a device can only have one full-screen
swap chain. You can gain access to a specific back buffer by calling the
Direct3DDevice8.GetBackBuffer or Direct3DSwapChain8.GetBackBuffer methods,
which return a Direct3DSurface8 object that represents the returned back buffer
surface. Remember, Direct3D flips surfaces by swapping surface memory pointers
within the swap chain, not by swapping the surfaces themselves. This means that
you will always render to the back buffer that is will be displayed next. It is
important to note the distinction between a "flipping operation", as performed
by a display adapter driver, and a "Present" operation applied to a swap chain
created with D3DSWAPEFFECT_FLIP. The term "flip" conventionally denotes an
operation that alters the range of video memory addresses that a display
adapter uses to generate its output signal, thus causing the contents of a
previously hidden back buffer to be displayed. In DirectX 8, the term is often
used more generally to describe the presentation of a back buffer in any swap
chain created with the D3DSWAPEFFECT_FLIP swap effect. While such "Present"
operations are almost invariably implemented by flip operations when the swap
chain is a full-screen one, they are necessarily implemented by copy operations
when the swap chain is windowed. Furthermore, a display adapter driver may use
flipping to implement Present operations against full-screen swap chains based
on the D3DSWAPEFFECT_DISCARD, D3DSWAPEFFECT_COPY and D3DSWAPEFFECT_COPY_VSYNC
swap effects. The discussion above applies to the commonly used case of a
full-screen swap chain created with D3DSWAPEFFECT_FLIP. [C++] For a more
general discussion of the different swap effects for both windowed and
full-screen swap chains, see D3DSWAPEFFECT. [Visual Basic] For a more general
discussion of the different swap effects for both windowed and full-screen swap
chains, see CONST_3DSWAPEFFECT. Copying To Surfaces [C++] When using the
IDirect3DDevice8::CopyRects method, you pass an array of rectangles on the
source surface or NULL to specify the entire surface. You also pass an array of
points on the destination surface to which the top-left position of each
rectangle on the source image is copied. This method does not support clipping.
The operation will fail unless all the source rectangles and their
corresponding destination rectangles are completely contained within the source
and destination surfaces respectively. This method does not support alpha
blending, color keys, or format conversion. Note that the destination and
source surfaces must be distinct. CopyRects Example The following example
copies two rectangles from the source surface to a destination surface. The
first rectangle is copied from (0, 0, 50, 50) on the source surface to the same
location on the destination surface, and the second rectangle is copied from
(50, 50, 100, 100) on the source surface to (150 ,150, 200, 200) on the
destination surface. //The following assumptions are made: //-d3dDevice is a
valid Direct3DDevice8 object. //-pSource and pDest are valid IDirect3DSurface8
pointers. RECT rcSource[] = { 0, 0, 50, 50, 50, 50, 100, 100 }; POINT ptDest[]
= { 0, 0, 150, 150 }; d3dDevice->CopyRect( pSource, rcSource, 2, pDest,
ptDest); The following methods are also available in C++/C for copying images
to a Microsoft® Direct3D® surface. * D3DXLoadSurfaceFromFileA *
D3DXLoadSurfaceFromFileInMemory * D3DXLoadSurfaceFromFileW *
D3DXLoadSurfaceFromMemory * D3DXLoadSurfaceFromResourceA *
D3DXLoadSurfaceFromResourceW * D3DXLoadSurfaceFromSurface *
IDirect3DDevice8::CopyRects [Visual Basic] When using the
Direct3DDevice8.CopyRects method, you pass the first element of an array of
rectangles on the source surface or Nothing to specify the entire surface. You
also pass an array of points on the destination surface to which the top-left-
position of each rectangle on the source image is copied. You can pass ByVal 0
to copy the rectangles with the same top-left position as the source. This
method does not support clipping. The operation will fail unless all the source
rectangles and their corresponding destination rectangles are completely
contained within the source and destination surfaces respectively. This method
does not support alpha blending, color keys, or format conversion. Note that
the source and destination surfaces must be distinct. CopyRects Example The
following example copies two rectangles from the source surface to a
destination surface. The first rectangle is copied from (0, 0, 50, 50) on the
source surface to the same location on the destination surface and the second
rectangle is copied from (50, 50, 100, 100) on the source surface to (150 ,150,
200, 200) on the destination surface. 'The following assumptions are made:
'-d3dDevice is a valid IDirect3DDevice8 object. '-Source and Dest are valid
Direct3DSurface8 objects. Dim rcSource(1) As RECT Dim ptDest(1) As Point
rcSource(0).left = 0 rcSource(0).top = 0 rcSource(0).right= 0
rcSource(0).bottom = 0 rcSource(1).left = 50 rcSource(1).top = 50
rcSource(1).right = 100 rcSource(1).bottom = 100 ptDest(0).x = 0 ptDest(0).y =
0 ptDest(1).x = 150 ptDest(1).y = 150 d3dDevice.CopyRects Source, rcSource, 2,
Dest, ptDest The following methods are also available in Microsoft® Visual
Basic® for copying images to a Microsoft Direct3D® surface. *
D3DX8.LoadSurfaceFromFile * D3DX8.LoadSurfaceFromFileInMemory *
D3DX8.LoadSurfaceFromMemory * D3DX8.LoadSurfaceFromResource *
D3DX8.LoadSurfaceFromSurface * Direct3DDevice8.CopyRects Gamma Controls This
section contains information about gamma controls used with Microsoft®
Direct3D®. Information is organized into the following topics. * What Are Gamma
Controls? * Using Gamma Controls What Are Gamma Controls? Gamma controls allow
you to change how the system displays the contents of the surface, without
affecting the contents of the surface itself. Think of these controls as very
simple filters that Microsoft® Direct3D® applies to data as it leaves a surface
and before it is rendered on the screen. Gamma controls are simply a property
of a swap chain. Gamma controls make it possible to dynamically change how a
surface's red, green, and blue levels map to the actual levels that the system
displays. By setting gamma levels, you can cause the user's screen to flash
colors—red when the user's character is shot, green when the character picks up
a new item, and so on—without copying new images to the frame buffer to achieve
the effect. Or, you might adjust color levels to apply a color bias to the
images in the back buffer. There is always at least one swap chain (the
implicit swap chain) for each device because Microsoft® Direct3D® for Microsoft
DirectX® 8.0 has one swap chain as a property of the device. Because the gamma
ramp is a property of the swap chain, the gamma ramp can be applied when the
swap chain is windowed. The gamma ramp takes effect immediately. There is no
waiting for a VSYNC operation. For details on how to use gamma controls, see
Using Gamma Controls. Using Gamma Controls [C++] The
IDirect3DDevice8::SetGammaRamp and IDirect3DDevice8::GetGammaRamp methods allow
you to manipulate ramp levels that affect the red, green, and blue color
components of pixels from the surface before they are sent to the
digital-to-analog converter (DAC) for display. [Visual Basic] The
Direct3DDevice8.SetGammaRamp and Direct3DDevice8.GetGammaRamp methods allow you
to manipulate ramp levels that affect the red, green, and blue color components
of pixels from the surface before they are sent to the digital-to- analog
converter (DAC) for display. In the following topics describe the general
concept of ramp levels and provide information about working with those levels.
* About Gamma Ramp Levels * Detecting Gamma Ramp Support * Setting and
Retrieving Gamma Ramp Levels About Gamma Ramp Levels In Microsoft® Direct3D®,
the term gamma ramp describes a set of values that map the level of a
particular color component—red, green, blue—for all pixels in the frame buffer
to new levels that are received by the digital-to-analog converter (DAC) for
display. The remapping is performed by way of three look-up tables, one for
each color component. Here's how it works: Direct3D takes a pixel from the
frame buffer and evaluates its individual red, green, and blue color
components. Each component is represented by a value from 0 to 65535. Direct3D
takes the original value and uses it to index a 256- element array (the ramp),
where each element contains a value that replaces the original one. Direct3D
performs this look-up and replace process for each color component of each
pixel in the frame buffer, thereby changing the final colors for all the
on-screen pixels. It's handy to visualize the ramp values by graphing them. The
left graph of the two following graphs shows a ramp that doesn't modify colors
at all. The right graph shows a ramp that imposes a negative bias to the color
component to which it is applied. The array elements for the graph on the left
contain values identical to their index—0 in the element at index 0, and 65535
at index 255. This type of ramp is the default, as it doesn't change the input
values before they're displayed. The right graph provides more variation; its
ramp contains values that range from 0 in the first element to 32768 in the
last element, with values ranging uniformly in between. The effect is that the
color component that uses this ramp appears muted on the display. You are not
limited to using linear graphs; if your application can assign arbitrary
mapping if needed. You can even set the entries to all zeroes to remove a color
component completely from the display. Detecting Gamma Ramp Support If the
device does not support gamma ramps in the swap chain's current presentation
mode (full-screen or windowed), no error value is returned. Applications can
check the D3DCAPS2_FULLSCREENGAMMA and D3DCAPS2_CANCALIBRATEGAMMA capability
bits in the Caps2 member of the D3DCAPS8 type to determine the capabilities of
the device and whether a calibrator is installed. Setting and Retrieving Gamma
Ramp Levels [C++] Gamma ramp levels are effectively look-up tables that
Microsoft® Direct3D® uses to map the frame buffer color components to new
levels that will be displayed. For more information, see About Gamma Ramp
Levels. You can set and retrieve ramp levels for the primary surface by calling
the IDirect3DDevice8::SetGammaRamp and IDirect3DDevice8::GetGammaRamp methods.
SetGammaRamp accepts two parameters and GetGammaRamp accepts one parameter. For
SetGammaRamp, the first parameter is either D3DSGR_CALIBRATE or
D3DSGR_NO_CALIBRATION. The second parameter, pRamp, is a pointer to a
D3DGAMMARAMP structure. The D3DGAMMARAMP structure contains three 256-element
arrays of WORDs, one array each to contain the red, green, and blue gamma
ramps. GetGammaRamp has one parameter that takes a pointer to a D3DGAMMARAMP
type that will be filled with the current gamma ramp. You can include the
DDSGR_CALIBRATE value for the first parameter of SetGammaRamp to invoke the
calibrator when setting new gamma levels. Calibrating gamma ramps incurs some
processing overhead, and should not be used frequently. Setting a calibrated
gamma ramp provides a consistent and absolute gamma value for the user,
regardless of the display adapter and monitor. Not all systems support gamma
calibration. To determine if gamma calibration is supported, call
IDirect3DDevice8::GetDeviceCaps, and examine the Caps2 member of the associated
D3DCAPS8 structure after the method returns. If the D3DCAPS2_CANCALIBRATEGAMMA
capability flag is present, then gamma calibration is supported. When setting
new ramp levels, keep in mind that that the levels you set in the arrays are
only used when your application is in full-screen, exclusive mode. Whenever
your application changes to normal mode, the ramp levels are set aside, taking
effect again when the application reinstates full-screen mode. [Visual Basic]
Gamma ramp levels are effectively look-up tables that Microsoft® Direct3D® uses
to map the frame buffer color components to new levels that will be displayed.
For more information, see About Gamma Ramp Levels. You set and retrieve ramp
levels for the primary surface by calling the Direct3DDevice8.SetGammaRamp and
Direct3DDevice8.GetGammaRamp methods. SetGammaRamp accepts two parameters and
GetGammaRamp accepts one parameter. For SetGammaRamp, the first parameter is
either D3DSGR_CALIBRATE or D3DSGR_NO_CALIBRATION. The second parameter, pRamp,
takes a D3DGAMMARAMP type. The D3DGAMMARAMP type contains three 256-element
arrays of DWORDs, one array each to contain the red, green, and blue gamma
ramps. GetGammaRamp has one parameter that takes a D3DGAMMARAMP type that will
be filled with the current gamma ramp. You can include the D3DSGR_CALIBRATE
value for the first parameter of SetGammaRamp to invoke the calibrator when
setting new gamma levels. Calibrating gamma ramps incurs some processing
overhead, and should not be used frequently. Setting a calibrated gamma ramp
provides a consistent and absolute gamma value for the user, regardless of the
display adapter and monitor. Not all systems support gamma calibration. To
determine if gamma calibration is supported, call
Direct3DDevice8.GetDeviceCaps, and examine the Caps2 member of the associated
D3DCAPS8 structure after the method returns. If the D3DCAPS2_CANCALIBRATEGAMMA
capability flag is present, then gamma calibration is supported. When setting
new ramp levels, keep in mind that that the levels you set in the arrays are
only used when your application is in full-screen, exclusive mode. Whenever
your application changes to normal mode, the ramp levels are set aside, taking
effect again when the application reinstates full-screen mode. Accessing
Surface Memory Directly [C++] You can directly access the surface memory by
using the IDirect3DSurface8::LockRect method. When you call this method, the
pRect parameter is a pointer to a RECT structure that describes the rectangle
on the surface to access directly. To request that the entire surface be
locked, set pRect to NULL. Also, you can specify a RECT that covers only a
portion of the surface. Providing that no two rectangles overlap, two threads
or processes can simultaneously lock multiple rectangles in a surface. Note
that a multisample back buffer cannot be locked. The LockRect method fills a
D3DLOCKED_RECT structure with all the information to properly access the
surface memory. The structure includes information about the pitch and has a
pointer to the locked bits. When you finish accessing the surface memory, call
the IDirect3DSurface8::UnlockRect method to unlock it. While you have a surface
locked, you can directly manipulate the contents. The following list describes
some tips for avoiding common problems with directly rendering surface memory.
* Never assume a constant display pitch. Always examine the pitch information
returned by the LockRect method. This pitch can vary for a number of reasons,
including the location of the surface memory, the display card type, or even
the version of the Microsoft® Direct3D® driver. For more information, see Width
vs. Pitch. * Make certain you copy to unlocked surfaces. Direct3D copy methods
will fail if called on a locked surface. * Limit your application's activity
while a surface is locked. * Always copy data aligned to display memory.
Microsoft® Windows® 95 and Windows 98 use a page fault handler, Vflatd.386, to
implement a virtual flat-frame buffer for display cards with bank-switched
memory. The handler allows these display devices to present a linear frame
buffer to Direct3D. Copying data unaligned to display memory can cause the
system to suspend operations if the copy spans memory banks. * A surface may
not be locked if it belongs to a resource assigned to the D3DPOOL_DEFAULT
memory pool. Back buffer surfaces, which may be accessed using the
IDirect3DDevice8::GetBackBuffer and IDirect3DSwapChain8::GetBackBuffer methods,
may be locked only if the swap chain was created with the Flags member of the
D3DPRESENT_PARAMETERS structure set to include
D3DPRESENTFLAG_LOCKABLE_BACKBUFFER. [Visual Basic] You can directly access the
surface memory by using the Direct3DSurface8.LockRect method. When you call
this method, the RECT parameter is a RECT type that describes the rectangle on
the surface to access directly. To request that the entire surface be locked,
set RECT to Nothing. Also, you can specify a RECT that covers only a portion of
the surface. Providing that no two rectangles overlap, two threads or processes
can simultaneously lock multiple rectangles in a surface. Note that a
multisample back buffer cannot be locked. The LockRect method fills a
D3DLOCKED_RECT type with all the information to properly access the surface
memory. The structure includes information about the pitch and has the locked
bits. When you finish accessing the surface memory, call the
Direct3DSurface8.UnlockRect method to unlock it. While you have a surface
locked, you can directly manipulate the contents. The following list describes
some tips for avoiding common problems with directly rendering surface memory.
* Never assume a constant display pitch. Always examine the pitch information
returned by the LockRect method. This pitch can vary for a number of reasons,
including the location of the surface memory, the display card type, or even
the version of the Microsoft® Direct3D® driver. For more information, see Width
vs. Pitch. * Make certain you copy to unlocked surfaces. Direct3D copy methods
will fail if called on a locked surface. * Limit your application's activity
while a surface is locked. * Always copy data aligned to display memory.
Microsoft® Windows® 95 and Windows 98 use a page fault handler, Vflatd.386, to
implement a virtual flat-frame buffer for display cards with bank-switched
memory. The handler allows these display devices to present a linear frame
buffer to Direct3D. Copying data unaligned to display memory can cause the
system to suspend operations if the copy spans memory banks. * A surface may
not be locked if it belongs to a resource assigned to the D3DPOOL_DEFAULT
memory pool. Back buffer surfaces, which may be accessed using the
Direct3DDevice8.GetBackBuffer and Direct3DSwapChain8.GetBackBuffer methods, may
be locked only if the swap chain was created with the Flags member of the
D3DPRESENT_PARAMETERS structure set to include
D3DPRESENTFLAG_LOCKABLE_BACKBUFFER. Private Surface Data [C++] You can store
any kind of application-specific data with a surface. For example, a surface
representing a map in a game might contain information about terrain. A surface
can have more than one private data buffer. Each buffer is identified by a GUID
that you supply when attaching the data to the surface. To store private
surface data, use the IDirect3DSurface8::SetPrivateData method, passing a
pointer to the source buffer, the size of the data, and an application-defined
GUID for the data. Optionally, the source data can exist in the form of a COM
object; in this case, you pass a pointer to the object's IUnknown interface
pointer and you set the D3DSPD_IUNKNOWNPOINTER flag. SetPrivateData allocates
an internal buffer for the data and copies it. You can then safely free the
source buffer or object. The internal buffer or interface reference is released
when IDirect3DSurface8::FreePrivateData is called. This happens automatically
when the surface is freed. To retrieve private data for a surface, you must
allocate a buffer of the correct size and then call the
IDirect3DSurface8::GetPrivateData method, passing the GUID that was assigned to
the data by SetPrivateData. You are responsible for freeing any dynamic memory
you use for this buffer. If the data is a COM object, this method retrieves the
IUnknown pointer. If you don't know how big a buffer to allocate, first call
GetPrivateData with zero in SizeOfData. If the method fails with
D3DERR_MOREDATA, it returns the necessary number of bytes for the buffer in
SizeOfData. [Visual Basic] You can store any kind of application-specific data
with a surface. For example, a surface representing a map in a game might
contain information about terrain. A surface can have more than one private
data buffer. Each buffer is identified by a GUID that you supply when attaching
the data to the surface. To store private surface data, use the
Direct3DSurface8.SetPrivateData method, passing a buffer that contains data to
associate with the surface, the size of the data buffer, and an
application-defined DXGUID for the data. SetPrivateData allocates an internal
buffer for the data and copies it. You can then safely free the source buffer
or object. The internal buffer or interface reference is released when
Direct3DSurface8.FreePrivateData is called. This happens automatically when the
surface is freed. To retrieve private data for a surface, you must allocate a
buffer of the correct size and then call the Direct3DSurface8.GetPrivateData
method, passing the DXGUID that was assigned to the data by SetPrivateData. You
are responsible for freeing any dynamic memory you use for this buffer. If you
don't know how big a buffer to allocate, first call GetPrivateData with zero in
SizeOfData. If the method fails with D3DERR_MOREDATA, it returns the necessary
number of bytes for the buffer in SizeOfData. Lights Lights are used to
illuminate objects in a scene. This section describes lights and how they are
used in Microsoft® Direct3D® applications. The following topics are discussed.
* Introduction to Lighting and Materials * Direct3D Light Model vs. Nature *
Color Values for Lights and Materials * Direct Light vs. Ambient Light * Light
Objects * Light Properties * Using Lights Introduction to Lighting and
Materials When lighting is enabled, as Microsoft® Direct3D® rasterizes a scene
in the final stage of rendering, it determines the color of each rendered pixel
based on a combination of the current material color and the texels in an
associated texture map; the diffuse and specular colors at the vertex, if
specified; and the color and intensity of light produced by light sources in
the scene or the scene's ambient light level. When you use Direct3D lighting
and materials, you allow Direct3D to handle the details of illumination for
you. Advanced users can perform lighting on their own, if desired. How you work
with lighting and materials makes a big difference in the appearance of the
rendered scene. Materials define how light reflects off a surface. Direct light
and ambient light levels define the light that is reflected. You must use
materials to render a scene if lighting is enabled. Lights are not required to
render a scene, but details in a scene rendered without light are not visible.
At best, rendering an unlit scene results in a silhouette of the objects in the
scene. This is not enough detail for most purposes. Direct3D Light Model vs.
Nature In nature, when light is emitted from a source, it is reflect off of
hundreds, if not thousands or millions, of objects before reaching the user's
eye. Each time it is reflected, some light is absorbed by a surface, some is
scattered in random directions, and the rest goes on to another surface or to
the user's eye. This process continues until the light is reduced to nothing or
a user perceives the light. Obviously, the calculations required to perfectly
simulate the natural behavior of light are too time-consuming to use for
real-time 3-D graphics. Therefore, with speed in mind, the Microsoft® Direct3D®
light model approximates the way light works in the natural world. Direct3D
describes light in terms of red, green, and blue components that combine to
create a final color. For more information, see Color Values for Lights and
Materials. In Direct3D, when light reflects off a surface, the light color
interacts mathematically with the surface itself to create the color eventually
displayed on the screen. For specific information about the algorithms Direct3D
uses, see Mathematics of Direct3D Lighting. The Direct3D light model
generalizes light into two types: ambient light and direct light. Each has
different attributes, and each interacts with the material of a surface in
different ways. Ambient light is light that has been scattered so much that its
direction and source are indeterminate: it maintains a low-level of intensity
everywhere. The indirect lighting used by photographers is a good example of
ambient light. Ambient light in Direct3D, as in nature, has no real direction
or source, only a color and intensity. In fact, the ambient light level is
completely independent of any objects in a scene that generate light. Ambient
light does not contribute to specular reflection. Direct light is the light
generated by a source within a scene; it always has color and intensity, and it
travels in a specified direction. Direct light interacts with the material of a
surface to create specular highlights, and its direction is used as a factor in
shading algorithms, including Gouraud shading. When direct light is reflected,
it does not contribute to the ambient light level in a scene. The sources in a
scene that generate direct light have different characteristics that affect how
they illuminate a scene. For more information, see Lights. Additionally, a
polygon's material has properties that affect how that polygon reflects the
light it receives. You set a single reflectance trait that describes how the
material reflects ambient light, and you set individual traits to determine the
material's specular and diffuse reflectance. For more information, see
Materials. Color Values for Lights and Materials [C++] Microsoft® Direct3D®
describes color in terms of four components—red, green, blue, and alpha—that
combine to make a final color. The D3DCOLORVALUE C++ structure is defined to
contain values for each component. Each member is a floating- point value that
typically ranges from 0.0 to 1.0, inclusive. Although both lights and materials
use the same structure to describe color, the values in the structure are used
a little differently by each. [Visual Basic] Microsoft® Direct3D® describes
color in terms of four components—red, green, blue, and alpha—that combine to
make a final color. The D3DCOLORVALUE type is defined to contain values for
each component. Each member is a floating-point value that typically ranges
from 0.0 to 1.0, inclusive. Although both lights and materials use the same
structure to describe color, the values in the structure are used a little
differently by each. Color values for light sources represent the amount of a
particular light component it emits. Because lights don't use an alpha
component, only the red, green, and blue components of the color are relevant.
You can visualize the three components as the red, green, and blue lenses on a
projection television. Each lens might be off (a 0.0 value in the appropriate
member), it might be as bright as possible (a 1.0 value), or it might be some
level in between. The colors coming through the lenses combine to make the
light's final color. A combination like R: 1.0, G: 1.0, B: 1.0 creates a white
light, where R: 0.0, G: 0.0, B: 0.0 doesn't emit light at all. You can make a
light that emits only one component, resulting in a pure red, green, or blue
light, or, the light could use combinations to emit colors like yellow or
purple. You can even set negative color component values to create a "dark
light" that actually removes light from a scene. Or, you might set the
components to some value larger than 1.0 to create an extremely bright light.
With materials, on the other hand, color values represent how much of a light
component is reflected by a surface that is rendered with that material. A
material whose color components are R: 1.0, G: 1.0, B: 1.0, A: 1.0 reflects all
the light that comes its way. Likewise, a material with R: 0.0, G: 1.0, B: 0.0,
A: 1.0 reflects all the green light that is directed at it. Materials have
multiple reflectance values to create various types of effects; for more
information, see Material Properties. Color values for ambient light are
different from those used for direct light sources and materials. For more
information, see Direct Light vs. Ambient Light. Direct Light vs. Ambient Light
Although both direct and ambient light illuminate objects in a scene, they are
independent of one another, they have very different effects, and they require
that you work with them in completely different ways. [C++] Direct light is
just that: direct. Direct light always has direction and color, and it is a
factor for shading algorithms, such as Gouraud shading. Different types of
lights emit direct light in different ways, creating special attenuation
effects. You create a set of light parameters for direct light by calling the
IDirect3DDevice8::SetLight method. For more information, see Lights. Ambient
light is effectively everywhere in a scene. You can think of it as a general
level of light that fills an entire scene, regardless of the objects and their
locations in that scene. Ambient light, being everywhere, has no position or
direction, only color and intensity. Set the ambient light level with a call to
the IDirect3DDevice8::SetRenderState method, specifying D3DRS_AMBIENT as the
State parameter, and the desired RGBA color as the Value parameter. Ambient
light color takes the form of an RGBA value, where each component is an integer
value from 0 to 255. This is unlike most color values in Microsoft® Direct3D®.
For more information, see Color Values for Lights and Materials. You can use
the D3DCOLOR_RGBA macro to generate RGBA values. The red, green, and blue
components combine to make the final color of the ambient light. The alpha
component controls the transparency of the color. When using hardware
acceleration or RGB emulation, the alpha component is ignored. [Visual Basic]
Direct light is just that: direct. Direct light always has direction and color,
and it is a factor for shading algorithms, such as Gouraud shading. Different
types of lights emit direct light in different ways, creating special
attenuation effects. You create a set of light parameters for direct light by
calling the Direct3DDevice8.SetLight method. For more information, see Lights.
Ambient light is effectively everywhere in a scene. You can think of it as a
general level of light that fills an entire scene, regardless of the objects
and their locations in that scene. Ambient light, being everywhere, has no
position or direction, only color and intensity. Set the ambient light level
with a call to the Direct3DDevice8.SetRenderState method, specifying
D3DRS_AMBIENT as the State parameter, and the desired RGBA color as the Value
parameter. Light Objects Microsoft® Direct3D® employs three types of lights:
point lights, spotlights, and directional lights. You choose the type of light
you want when you create a set of light properties. The illumination properties
and the resulting computational overhead varies with each type of light source.
The following types of light sources, supported by the Direct3D lighting
module, are discussed. * Point Lights * Spotlights * Directional Lights Do not
confuse light sources in a scene with the concept of an ambient light level.
For more information, see Direct Light vs. Ambient Light, Light Properties and
Using Lights. Point Lights Point lights have color and position within a scene,
but no single direction. They give off light equally in all directions, as
shown in the following illustration. A light bulb is a good example of a point
light. Point lights are affected by attenuation and range, and illuminate a
mesh on a vertex-by-vertex basis. During lighting, Microsoft® Direct3D® uses
the point light's position in world space and the coordinates of the vertex
being lit to derive a vector for the direction of the light, and the distance
that the light has traveled. Both are used, along with the vertex normal, to
calculate the contribution of the light to the illumination of the surface.
Spotlights Spotlights have color, position, and direction in which they emit
light. Light emitted from a spotlight is made up of a bright inner cone and a
larger outer cone, with the light intensity diminishing between the two, as
shown in the following illustration. Spotlights are affected by falloff,
attenuation, and range. These factors, as well as the distance light travels to
each vertex, are figured in when computing lighting effects for objects in a
scene. Computing these effects for each vertex makes spotlights the most
computationally expensive of all lights in Microsoft Direct3D®. Directional
Lights Directional lights have only color and direction, not position. They
emit parallel light. This means that all light generated by directional lights
travels through a scene in the same direction. Imagine a directional light as a
light source at near infinite distance, such as the sun. Directional lights are
not affected by attenuation or range, so the direction and color you specify
are the only factors considered when Microsoft® Direct3D® calculates vertex
colors. Because of the small number of illumination factors, these are the
least computationally intensive lights to use. Light Properties [C++] Light
properties describe a light source's type and color. Depending on the type of
light being used, a light can have properties for attenuation and range, or for
spotlight effects. But, not all types of lights use all properties. Microsoft®
Direct3D® uses the D3DLIGHT8 structure to carry information about light
properties for all types of light sources. This section contains information
for all light properties. Information is divided into the following groups.
[Visual Basic] Light properties describe a light source's type and color.
Depending on the type of light being used, a light can have properties for
attenuation and range, or for spotlight effects. But, not all types of lights
use all properties. Microsoft® Direct3D® uses the D3DLIGHT8 type for Microsoft
Visual Basic® to carry information about light properties for all types of
light sources. This section contains information for all light properties.
Information is divided into the following groups. * Light Type * Light Color *
Color Vertices * Light Position, Range, and Attenuation * Light Direction *
Spotlight Properties Light properties affect how a light source illuminates
objects in a scene. For more information, see Using Lights, Setting Light
Properties, and Mathematics of Direct3D Lighting. Light Type [C++] The light
type property defines which type of light source you're using. The light type
is set by using a value from the D3DLIGHTTYPE C++ enumeration in the Type
member of the light's D3DLIGHT8 structure. There are three types of lights in
Microsoft® Direct3D®—point lights, spotlights, and directional lights. Each
type illuminates objects in a scene differently, with varying levels of
computational overhead. For general information about how each type of light
works, see Light Objects. [Visual Basic] The light type property defines which
type of light source you're using. The light type is set by using a value from
the CONST_D3DLIGHTTYPE Microsoft Visual Basic® enumeration in the Type member
of the light's D3DLIGHT8 type. There are three types of lights in Microsoft®
Direct3D®—point lights, spotlights, and directional lights. Each type
illuminates objects in a scene differently, with varying levels of
computational overhead. For general information about how each type of light
works, see Light Objects. Light Color Lights in Microsoft® Direct3D® emit three
colors that are used independently in the system's lighting computations: a
diffuse color, an ambient color, and a specular color. Each is incorporated by
the Direct3D lighting module, interacting with a counterpart from the current
material, to produce a final color used in rendering. The diffuse color
interacts with the diffuse reflectance property of the current material, the
specular color with the material's specular reflectance property, and so on.
For specifics about how Direct3D applies these colors, see Mathematics of
Direct3D Lighting. [C++] In a C++ application, the D3DLIGHT8 structure includes
three members for these colors—Diffuse, Ambient, and Specular—each one is a
D3DCOLORVALUE structure that defines the color being emitted. [Visual Basic]
The D3DLIGHT8 Microsoft Visual Basic® type includes three members for these
colors—Diffuse, Ambient, and Specular—each one is a D3DCOLORVALUE type that
defines the color being emitted. The type of color that applies most heavily to
the system's computations is the diffuse color. The most common diffuse color
is white (R:1.0 G:1.0 B:1.0), but you can create colors as needed to achieve
desired effects. For example, you could use red light for a fireplace, or you
could use green light for a traffic signal set to "Go." Generally, you set the
light color components to values between 0.0 and 1.0, inclusive, but this isn't
a requirement. For example, you might set all the components to 2.0, creating a
light that is "brighter than white." This type of setting can be especially
useful when you use attenuation settings other than constant. Note that
although Direct3D uses RGBA values for lights, the alpha color component is not
used. For more information, see Color Values for Lights and Materials. Color
Vertices [C++] Usually material colors are used for lighting. However, you can
specify that material colors—emissive, ambient, diffuse, and specular—are to be
overridden by diffuse or specular vertex colors. This is done by calling
IDirect3DDevice8::SetRenderState and setting the device state variables listed
in the following table. [Visual Basic] Usually material colors are used for
lighting. However, you can specify that material colors—emissive, ambient,
diffuse, and specular—are to be overridden by diffuse or specular vertex
colors. This is done by calling Direct3DDevice8.SetRenderState and setting the
device state variables listed in the following table. Device state variable
Meaning Type Default D3DRS_AMBIENTMATERIALSOURCE Defines where to get ambient
material color. D3DMATERIALCOLORSOURCE D3DMCS_MATERIAL
D3DRS_DIFFUSEMATERIALSOURCE Defines where to get diffuse material color.
D3DMATERIALCOLORSOURCE D3DMCS_COLOR1 D3DRS_SPECULARMATERIALSOURCE Defines where
to get specular material color. D3DMATERIALCOLORSOURCE D3DMCS_COLOR2
D3DRS_EMISSIVEMATERIALSOURCE Defines where to get emissive material color.
D3DMATERIALCOLORSOURCE D3DMCS_MATERIAL D3DRS_COLORVERTEX Disables or enables
use of vertex colors. BOOL TRUE The alpha/transparency value always comes only
from the diffuse color's alpha channel. The fog value always comes only from
the specular color's alpha channel. D3DMATERIALCOLORSOURCE can have the
following values. * D3DMCS_MATERIAL - Material color is used as source. *
D3DMCS_COLOR1 - Diffuse vertex color is used as source. * D3DMCS_COLOR2 -
Specular vertex color is used as source. Light Position, Range, and Attenuation
[C++] The position, range, and attenuation properties define a light's location
in world space, and how the light it emits behaves over distance. As with all
light properties you use in C++, these are contained in a light's D3DLIGHT8
structure. Position Light position is described using a D3DVECTOR structure in
the Position member of the D3DLIGHT8 structure. The x-, y-, and z-coordinates
are assumed to be in world space. Directional lights are the only type of light
that don't use the position property. Range A light's range property determines
the distance, in world space, at which meshes in a scene no longer receive
light emitted by that object. The Range member contains a floating-point value
that represents the light's maximum range, in world space. Directional lights
don't use the range property. Attenuation Attenuation controls how a light's
intensity decreases toward the maximum distance specified by the range
property. Three D3DLIGHT8 structure members represent light attenuation:
Attenuation0, Attenuation1, and Attenuation2. These members contain
floating-point values ranging from 0.0 through infinity, controlling a light's
attenuation. Some applications set the Attenuation1 member to 1.0 and the
others to 0.0, resulting in light intensity that changes as 1 / D, where D is
the distance from the light source to the vertex. The maximum light intensity
is at the source, decreasing to 1 / (Light Range) at the light's range.
Typically, an application sets Attenuation0 to 0.0, Attenuation1 to a constant
value, and Attenuation2 to 0.0. You can combine attenuation values to get more
complex attenuation effects. Or, you might set them to values outside the
normal range to create even stranger attenuation effects; negative attenuation
values make a light that gets brighter over distance. For more information
about the mathematical model that Microsoft® Direct3D® uses to calculate
attenuation, see Light Attenuation Over Distance. Like the range property,
directional lights don't use the attenuation property. [Visual Basic] The
D3DLIGHT8 type includes members that your Microsoft® Visual Basic® application
uses to define a light's position, range, and attenuation properties. These
describe a light's location in world space, and how the light it emits behaves
over distance. Position Light position is described using a D3DVECTOR type in
the Position member of the D3DLIGHT8 type. The x-, y-, and z-coordinates are
assumed to be in world space. Directional lights are the only type of light
that don't use the position property. Range A light's range property determines
the distance, in world space, at which meshes in a scene no longer receive
light emitted by that object. The Range member contains a floating-point value
that represents the light's maximum range, in world space. Directional lights
don't use the range property. Attenuation Attenuation controls how a light's
intensity decreases toward the maximum distance specified by the range
property. Three D3DLIGHT8 members represent light attenuation: Attenuation0,
Attenuation1, and Attenuation2. These members contain floating-point values
ranging from 0.0 through infinity, controlling a light's attenuation. Some
applications set the Attenuation1 member to 1.0 and the others to 0.0,
resulting in light intensity that changes as 1 / D, where D is the distance
from the light source to the vertex. The maximum light intensity is at the
source, decreasing to 1 / (Light Range) at the light's range. Typically, an
application sets Attenuation0 to 0.0, Attenuation1 to a constant value, and
Attenuation2 to 0.0. You can combine attenuation values to get more complex
attenuation effects. Or, you might set them to values outside the normal range
to create even stranger attenuation effects; negative attenuation values make a
light that gets brighter over distance. For more information about the
mathematical model that Microsoft® Direct3D® uses to calculate attenuation, see
Light Attenuation Over Distance. Like the range property, directional lights
don't use the attenuation property. Light Direction A light's direction
property determines the direction that the light emitted by the object travels,
in world space. Direction is used only by directional lights and spotlights,
and is described with a vector. [C++] C++ applications set the light direction
in the Direction member of the light's D3DLIGHT8 structure. The Direction
member is of type D3DVECTOR. Direction vectors are described as distances from
a logical origin, regardless of the light's position in a scene. Therefore, a
spotlight that points straight into a scene—along the positive z-axis—has a
direction vector of <0,0,1> no matter where its position is defined to be.
Similarly, you can simulate sunlight shining directly on a scene by using a
directional light whose direction is <0,-1,0>. Obviously, you don't have to
create lights that shine along the coordinate axes; you can mix and match
values to create lights that shine at more interesting angles. [Visual Basic]
Microsoft® Visual Basic® applications set the light direction in the Direction
member of the light's D3DLIGHT8 type. The Direction member is of type
D3DVECTOR. Direction vectors are described as distances from a logical origin,
regardless of the light's position within a scene. Therefore, a spotlight that
points straight into a scene—along the positive z-axis—has a direction vector
of <0,0,1> no matter where its position is defined to be. Similarly, you can
simulate sunlight shining directly on a scene by using a directional light
whose direction is <0,-1,0>. Obviously, you don't have to create lights that
shine along the coordinate axes; you can mix and match values to create lights
that shine at more interesting angles. Note Although you don't need to
normalize a light's direction vector, always be sure that it has magnitude. In
other words, don't use a <0,0,0> direction vector. Spotlight Properties [C++]
The D3DLIGHT8 C++ structure contains three members that are used only by
spotlights. These members—Falloff, Theta, and Phi—control how large or small a
spotlight object's inner and outer cones are, and how light decreases between
them. For general information about these characteristics, see Spotlights. The
Theta value is the radian angle of the spotlight's inner cone, and the Phi
value is the angle for the outer cone of light. The Falloff value controls how
light intensity decreases between the outer edge of the inner cone and the
inner edge of the outer cone. Most applications set Falloff to 1.0 to create
falloff that occurs evenly between the two cones, but you can set other values
as needed. For more information about the mathematical model used by Microsoft®
Direct3D® for calculating falloff, see Spotlight Falloff Model. The following
illustration shows the relationship between the values for these members and
how they can affect a spotlight's inner and outer cones of light. [Visual
Basic] The D3DLIGHT8 Microsoft® Visual Basic® type contains three members that
are used only by spotlights. These members—Falloff, Theta, and Phi—control how
large or small a spotlight object's inner and outer cones are, and how light
decreases between them. For general information about these characteristics,
see Spotlights. The Theta value is the radian angle of the spotlight's inner
cone, and the Phi value is the angle for the outer cone of light. The Falloff
value controls how light intensity decreases between the outer edge of the
inner cone and the inner edge of the outer cone. Most applications set Falloff
to 1.0 to create falloff that occurs evenly between the two cones, but you can
set other values as needed. For more information about the mathematical model
used by Microsoft® Direct3D® for calculating falloff, see Spotlight Falloff
Model. The following illustration shows the relationship between the values for
these members and how they can affect a spotlight's inner and outer cones of
light. Using Lights This section provides information about using lights in a
Microsoft® Direct3D® application. Information is divided into the following
topics. * Setting Light Properties * Enabling and Disabling Lights * Retrieving
Light Properties Setting Light Properties [C++] You set lighting properties in
a C++ application by preparing a D3DLIGHT8 structure and then calling the
IDirect3DDevice8::SetLight method. The SetLight method accepts the index at
which the device should place the set of light properties to its internal list
of light properties, and the address of a prepared D3DLIGHT8 structure that
defines those properties. You can call SetLight with new information as needed
to update the light's illumination properties. The system allocates memory to
accommodate a set of lighting properties each time you call the SetLight method
with an index that has never been assigned properties. Applications can set a
number of lights, with only a subset of the assigned lights enabled at a time.
Check the MaxActiveLights member of the D3DCAPS8 structure when you retrieve
device capabilities to determine the maximum number of active lights supported
by that device. If you no longer need a light, you can disable it or overwrite
it with a new set of light properties. The following C++ code example prepares
and sets properties for a white point-light whose emitted light will not
attenuate over distance. /* * For the purposes of this example, the d3dDevice
variable * is a valid pointer to an IDirect3DDevice8 interface. */ D3DLIGHT8
d3dLight; HRESULT hr; // Initialize the structure. ZeroMemory(&d3dLight,
sizeof(D3DLIGHT8)); // Set up a white point light. d3dLight.Type =
D3DLIGHT_POINT; d3dLight.Diffuse.r = 1.0f; d3dLight.Diffuse.g = 1.0f;
d3dLight.Diffuse.b = 1.0f; d3dLight.Ambient.r = 1.0f; d3dLight.Ambient.g =
1.0f; d3dLight.Ambient.b = 1.0f; d3dLight.Specular.r = 1.0f;
d3dLight.Specular.g = 1.0f; d3dLight.Specular.b = 1.0f; // Position it high in
the scene and behind the user. // Remember, these coordinates are in world
space, so // the user could be anywhere in world space, too. // For the
purposes of this example, assume the user // is at the origin of world space.
d3dLight.Position.x = 0.0f; d3dLight.Position.y = 1000.0f; d3dLight.Position.z
= -100.0f; // Don't attenuate. d3dLight.Attenuation0 = 1.0f; d3dLight.dvRange =
1000.0f; // Set the property information for the first light. hr =
d3dDevice->SetLight(0, &d3dLight); if (FAILED(hr)) { // Code to handle the
error goes here. } You can update a set of light properties with another call
to SetLight at any time. Just specify the index of the set of light properties
to update and the address of the D3DLIGHT8 structure that contains the new
properties. Note Assigning a set of light properties to the device does not
enable the light source whose properties are being added. Enable a light source
by calling the IDirect3DDevice8::LightEnable method for the device. [Visual
Basic] Your Microsoft Visual Basic® application sets lighting properties by
preparing a D3DLIGHT8 type and then calling the Direct3DDevice8.SetLight
method. The SetLight method accepts the index at which the device should place
the set of light properties to its internal list of light properties, and the
address of a prepared D3DLIGHT8 type that defines those properties. You can
call SetLight with new information as needed to update the light's illumination
properties. The system allocates memory to accommodate a set of lighting
properties each time you call the SetLight method with an index that has never
had properties assigned. Applications can set a number of lights, with only a
subset of the assigned lights enabled at a time. Check the MaxActiveLights
member of the D3DCAPS8 type when you retrieve device capabilities to determine
the maximum number of active lights supported by that device. If you no longer
need a light, you can disable it or overwrite it with a new set of light
properties. The following code example prepares and sets properties for a white
point-light whose emitted light will not attenuate over distance. ' ' For this
example, the d3dDevice variable contains a valid reference ' to a
Direct3DDevice8 object. ' Dim LightDesc As D3DLIGHT8 Dim c As D3DCOLORVALUE Dim
vPos As D3DVECTOR ' Use the same color settings for all emitted light color.
With c .r = 1#: .g = 1#: .b = 1# .a = 1# ' The alpha component isn't used for
lights. End With With vPos .x = 0: .y = 1000: .z = -100 End With With LightDesc
.Type = D3DLIGHT_POINT .Position = vPos .Ambient = c: .diffuse = c: .specular =
c .Attenuation0 = 1# ' Don't attenuate the light End With d3dDevice.SetLight 0,
LightDesc You can update a set of light properties with another call to
SetLight at any time. Specify the index of the set of light properties to
update and the D3DLIGHT8 type that contains the new properties. Note Assigning
a set of light properties to the device does not enable the light source whose
properties are being added. Enable a light source by calling the
Direct3DDevice8.LightEnable method for the device. Enabling and Disabling
Lights [C++] Once you assign a set of light properties for a light source in a
scene, the light source can be activated by calling the
IDirect3DDevice8::LightEnable method for the device. New light sources are
disabled by default. The LightEnable method accepts two parameters. Set the
first parameter to the zero-based index of the light source to be affected by
the method, and set the second parameter to TRUE to enable the light or FALSE
to disable it. The following code example illustrates the use of this method by
enabling the first light source in the device's list of light source
properties. /* * For the purposes of this example, the d3dDevice variable * is
a valid pointer to an IDirect3DDevice8 interface. */ HRESULT hr; hr =
pd3dDevice->LightEnable(0, TRUE); if (FAILED(hr)) { // Code to handle the error
goes here. } [Visual Basic] Once you assign a set of light properties for a
light source in a scene, the light source can be activated by calling the
Direct3DDevice8.LightEnable method for the device. New light sources are
disabled by default. The LightEnable method accepts two parameters. Set the
first parameter to the zero-based index of the light source to be affected by
the method, and set the second parameter to True to enable the light or False
to disable it. The following code example illustrates the use of this method by
enabling the first light source in the device's list of light source
properties. ' ' For the purposes of this example, the d3dDevice variable
contains ' a valid reference to Direct3DDevice8 object. ' On Local Error Resume
Next Call d3dDevice.LightEnable(0, True) If Err.Number <> D3D_OK Then 'Code to
handle the error goes here. End If [C++] If you enable or disable a light that
has no properties that are set with IDirect3DDevice8::SetLight, the LightEnable
method creates a light source with the properties listed in following table and
enables or disables it. [Visual Basic] If you enable or disable a light that
has no properties that are set with Direct3Ddevice8.SetLight, the LightEnable
method creates a light source with the properties listed in following table and
enables or disables it. Member Default Type D3DLIGHT_DIRECTIONAL Diffuse (R:1,
G:1, B:1, A:0) Specular (R:0, G:0, B:0, A:0) Ambient (R:0, G:0, B:0, A:0)
Position (0, 0, 0) Direction (0, 0, 1) Range 0 Falloff 0 Attenuation0 0
Attenuation1 0 Attenuation2 0 Theta 0 Phi 0 Retrieving Light Properties [C++]
You can retrieve all the properties for an existing light source from C++ by
calling the IDirect3DDevice8::GetLight method for the device. When calling the
GetLight method, pass in the first parameter the zero-based index of the light
source for which the properties will be retrieved, and supply the address of a
D3DLIGHT8 structure in the second parameter. The device fills the D3DLIGHT8
structure to describe the lighting properties it uses for the light source at
that index. The following code example illustrates this process. /* * For the
purposes of this example, the pd3dDevice variable * is a valid pointer to an
IDirect3DDevice8 interface. */ HRESULT hr; D3DLIGHT8 light; // Get the property
information for the first light. hr = pd3dDevice->GetLight(0, &light); if
(FAILED(hr)) { // Code to handle the error goes here. } If you supply an index
outside the range of the light sources assigned in the device, the GetLight
method fails, returning D3DERR_INVALIDCALL. [Visual Basic] A Microsoft® Visual
Basic® application retrieves the properties for an existing light source by
calling the Direct3DDevice8.GetLight method for the device. When calling the
GetLight method, pass in the first parameter the zero-based index of the light
source for which the properties will be retrieved, and a variable of type
D3DLIGHT8 as the second parameter. The device fills the D3DLIGHT8 type to
describe the lighting properties it uses for the light source at that index.
The following code example illustrates this process. ' ' For the purposes of
this example, the d3dDevice variable contains ' a valid reference to a
Direct3DDevice8 object. ' Dim lightDesc As D3DLIGHT8 ' Get the property
information for the first light. Call d3dDevice.GetLight(0, lightDesc) If
Err.Number <> D3D_OK Then ' Code to handle the error goes here. End If If you
supply an index outside the range of the light sources assigned in the device,
the GetLight method fails, and the value of Err.Number is D3DERR_INVALIDCALL.
Materials This section describes materials and how they are used in Microsoft®
Direct3D® applications. The following topics are discussed. * What Are
Materials? * Material Properties * Using Materials Default Material Properties
Note If your application does not specify material properties for rendering,
the system uses a default material. The default material reflects all diffuse
light—white, for example—with no ambient or specular reflection, and no
emissive color. What Are Materials? Materials describe how polygons reflect
light or appear to emit light in a 3-D scene. Essentially, a material is a set
of properties that tell Microsoft® Direct3D® the following things about the
polygons it is rendering. * How they reflect ambient and diffuse light * What
their specular highlights look like * Whether the polygons appear to emit light
[C++] Direct3D applications written in C++ use the D3DMATERIAL8 structure to
describe material properties. For more information, see Material Properties.
[Visual Basic] Direct3D applications written in Microsoft® Visual Basic® use
the D3DMATERIAL8 type to describe material properties. For more information,
see Material Properties. Material Properties [C++] Material properties detail a
material's diffuse reflection, ambient reflection, light emission, and specular
highlight characteristics. Microsoft® Direct3D® uses the D3DMATERIAL8 structure
to carry all material property information. Material properties affect the
colors that Direct3D uses to rasterize polygons that use the material. With the
exception of the specular property, each property is described as an RGBA color
that represents how much of the red, green, and blue parts of a given type of
light it reflects, and an alpha blending factor—the alpha component of the RGBA
color. The material's specular property is described in two parts: color and
power. For more information, see Color Values for Lights and Materials. Diffuse
and Ambient Reflection The Diffuse and Ambient members of the D3DMATERIAL8
structure describe how a material reflects the ambient and diffuse light in a
scene. Because most scenes contain much more diffuse light than ambient light,
diffuse reflection plays the largest part in determining color. Additionally,
because diffuse light is directional, the angle of incidence for diffuse light
affects the overall intensity of the reflection. Diffuse reflection is greatest
when the light strikes a vertex parallel to the vertex normal. As the angle
increases, the effect of diffuse reflection diminishes. The amount of light
reflected is the cosine of the angle between the incoming light and the vertex
normal, as shown here. Ambient reflection, like ambient light, is
nondirectional. Ambient reflection has a lesser impact on the apparent color of
a rendered object, but it does affect the overall color and is most noticeable
when little or no diffuse light reflects off the material. A material's ambient
reflection is affected by the ambient light set for a scene by calling the
IDirect3DDevice8::SetRenderState method with the D3DRS_AMBIENT flag. Diffuse
and ambient reflection work together to determine the perceived color of an
object, and are usually identical values. For example, to render a blue
crystalline object, you create a material that reflects only the blue component
of diffuse and ambient light. When placed in a room with a white light, the
crystal appears to be blue. However, in a room that has only red light, the
same crystal would appear to be black, because its material doesn't reflect red
light. Emission Materials can be used to make a rendered object appear to be
self-luminous. The Emissive member of the D3DMATERIAL8 structure is used to
describe the color and transparency of the emitted light. Emission affects an
object's color and can, for example, make a dark material brighter and take on
part of the emitted color. You can use a material's emissive property to add
the illusion that an object is emitting light, without incurring the
computational overhead of adding a light to the scene. In the case of the blue
crystal, the emissive property is useful if you want to make the crystal appear
to light up, but not cast light on other objects in the scene. Remember,
materials with emissive properties don't emit light that can be reflected by
other objects in a scene. To achieve this reflected light, you need to place an
additional light within the scene. Specular Reflection Specular reflection
creates highlights on objects, making them appear shiny. The D3DMATERIAL8
structure contains two members that describe the specular highlight color as
well as the material's overall shininess. You establish the color of the
specular highlights by setting the Specular member to the desired RGBA color—
the most common colors are white or light gray. The values you set in the Power
member control how sharp the specular effects are. Specular highlights can
create dramatic effects. Drawing again on the blue crystal analogy: a larger
Power value creates sharper specular highlights, making the crystal appear to
be quite shiny. Smaller values increase the area of the effect, creating a dull
reflection that make the crystal look frosty. To make an object truly matte,
set the Power member to zero and the color in Specular to black. Experiment
with different levels of reflection to produce a realistic appearance for your
needs. The following illustration shows two identical models. The one on the
left uses a specular reflection power of 10; the model on the right has no
specular reflection. [Visual Basic] Material properties detail a material's
diffuse reflection, ambient reflection, light emission, and specular highlight
characteristics. Microsoft® Direct3D® uses the D3DMATERIAL8 type to carry all
material property information. Material properties affect the colors Direct3D
uses to rasterize polygons that use the material. With the exception of the
specular property, each property is described as an RGBA color that represents
how much of the red, green, and blue parts of a given type of light it
reflects, and an alpha blending factor—the alpha component of the RGBA color.
The material's specular property is described in two parts: color and power.
For more information, see Color Values for Lights and Materials. Diffuse and
Ambient Reflection The diffuse and ambient members of the D3DMATERIAL8 type
describe how a material reflects the ambient and diffuse light in a scene.
Because most scenes contain much more diffuse light than ambient light, diffuse
reflection plays the largest part in determining color. Additionally, because
diffuse light is directional, the angle of incidence for diffuse light affects
the overall intensity of the reflection. Diffuse reflection is greatest when
the light strikes a vertex parallel to the vertex normal. As the angle
increases, the effect of diffuse reflection diminishes. The amount of light
reflected is the cosine of the angle between the incoming light and the vertex
normal, as shown here. Ambient reflection, like ambient light, is
nondirectional. Ambient reflection has a lesser impact on the apparent color of
a rendered object, but it does affect the overall color and is most noticeable
when little or no diffuse light reflects off the material. A material's ambient
reflection is affected by the ambient light set for a scene by calling the
Direct3DDevice8.SetRenderState method with the D3DRS_AMBIENT flag. Diffuse and
ambient reflection work together to determine the perceived color of an object,
and are usually identical values. For example, to render a blue crystalline
object, create a material that reflects only the blue component of diffuse and
ambient light. When placed in a room with a white light, the crystal appears to
be blue. However, in a room that has only red light, the same crystal appears
to be black, because its material doesn't reflect red light. Emission Materials
can be used to make a rendered object appear self-luminous. The emissive member
of the D3DMATERIAL8 type is used to describe the color and transparency of the
emitted light. Emission affects an object's color and can, for example, make a
dark material brighter and take on part of the emitted color. You can use a
material's emissive property to add the illusion that an object is emitting
light, without incurring the computational overhead of adding a light to the
scene. In the case of the blue crystal, the emissive property is useful to make
the crystal appear to light up but not cast light on other objects in the
scene. Remember, materials with emissive properties don't emit light that can
be reflected by other objects in a scene. To achieve this reflected light, you
must place an additional light within the scene. Specular Reflection Specular
reflection creates highlights on objects, making them appear shiny. The
D3DMATERIAL8 type contains two members that describe the specular highlight
color as well as the material's overall shininess. You establish the color of
the specular highlights by setting the specular member to the desired RGBA
color—the most common colors are white or light gray. The values you set in the
power member control how sharp the specular effects are. Specular highlights
can create dramatic effects. Drawing again on the blue crystal analogy: a
larger power value creates sharper specular highlights, making the crystal
appear quite shiny. Smaller values increase the area of the effect, creating a
dull reflection that make the crystal look frosty. To make an object truly
matte, set the power member to zero and the color in specular to black.
Experiment with different levels of reflection to produce a realistic
appearance for your needs. The following illustration shows two identical
models. The one on the left uses a specular reflection power of 10; the model
on the right has no specular reflection. Using Materials This section contains
information about using materials in a Microsoft® Direct3D® application.
Information is divided into the following topics. * Setting Material Properties
* Retrieving Material Properties Setting Material Properties Microsoft®
Direct3D® rendering devices can render with one set of material properties at a
time. [C++] In a C++ application, you set the material properties that the
system uses by preparing a D3DMATERIAL8 structure, and then calling the
IDirect3DDevice8::SetMaterial method. To prepare the D3DMATERIAL8 structure for
use, set the property information in the structure to create the desired effect
during rendering. The following code example sets up the D3DMATERIAL8 structure
for a purple material with sharp white specular highlights. D3DMATERIAL8 mat;
// Set the RGBA for diffuse reflection. mat.Diffuse.r = 0.5f; mat.Diffuse.g =
0.0f; mat.Diffuse.b = 0.5f; mat.Diffuse.a = 1.0f; // Set the RGBA for ambient
reflection. mat.Ambient.r = 0.5f; mat.Ambient.g = 0.0f; mat.Ambient.b = 0.5f;
mat.Ambient.a = 1.0f; // Set the color and sharpness of specular highlights.
mat.Specular.r = 1.0f; mat.Specular.g = 1.0f; mat.Specular.b = 1.0f;
mat.Specular.a = 1.0f; mat.Power = 50.0f; After preparing the D3DMATERIAL8
structure, you apply the properties by calling the
IDirect3DDevice8::SetMaterial method of the rendering device. This method
accepts the address of a prepared D3DMATERIAL8 structure as its only parameter.
You can call SetMaterial with new information as needed to update the material
properties for the device. The following code example shows how this might look
in code. // This code example uses the material properties defined for // the
mat variable earlier in this topic. The pd3dDev is assumed // to be a valid
pointer to an IDirect3DDevice8 interface. HRESULT hr; hr =
pd3dDev->SetMaterial(&mat); if(FAILED(hr)) { // Code to handle the error goes
here. } [Visual Basic] In a Microsoft® Visual Basic® application, set the
material properties that the system uses by preparing a D3DMATERIAL8 type, then
calling the Direct3DDevice8.SetMaterial method. To prepare the D3DMATERIAL8
type for use, set the property information in the structure to create the
desired effect during rendering. The following code example sets up the
D3DMATERIAL8 type for a purple material with sharp white specular highlights.
Dim mat As D3DMATERIAL8 ' Set the RGBA for diffuse reflection. mat.diffuse.r =
0.5 mat.diffuse.g = 0# mat.diffuse.b = 0.5 mat.diffuse.a = 1# ' Set the RGBA
for ambient reflection. mat.ambient.r = 0.5 mat.ambient.g = 0# mat.ambient.b =
0.5 mat.ambient.a = 1# ' Set the color and sharpness of specular highlights.
mat.specular.r = 1# mat.specular.g = 1# mat.specular.b = 1# mat.specular.a = 1#
mat.power = 50# After preparing the D3DMATERIAL8 type, apply the properties by
calling the Direct3DDevice8.SetMaterial method of the rendering device. This
method accepts the address of a prepared D3DMATERIAL8 type as its only
parameter. You can call SetMaterial with new information as needed to update
the material properties for the device. The following code example shows how
this might look in code. ' This code example uses the material properties
defined for ' the mat variable earlier in this topic. The d3dDevice is '
assumed to contain a valid reference to a Direct3DDevice8 ' object. On Local
Error Resume Next Call d3dDevice.SetMaterial(mat) If Err.Number <> D3D_OK Then
' Code to handle the error goes here. End If When you create a Direct3D device,
the current material is automatically set to the default shown in the following
table. Member Value Diffuse (R:1, G:1, B:1, A:0) Specular (R:0, G:0, B:0, A:0)
Ambient (R:0, G:0, B:0, A:0) Emissive (R:0, G:0, B:0, A:0) Power (0.0)
Retrieving Material Properties [C++] You retrieve the material properties that
the rendering device is currently using by calling the
IDirect3DDevice8::GetMaterial method for the device. Unlike the
IDirect3DDevice8::SetMaterial method, GetMaterial doesn't require preparation.
The GetMaterial method accepts the address of a D3DMATERIAL8 structure, and
fills the provided structure with information describing the current material
properties before returning. // For this example, the pd3dDev variable is
assumed to // be a valid pointer to an IDirect3DDevice8 interface. HRESULT hr;
D3DMATERIAL8 mat; hr = pd3dDev->GetMaterial(&mat); if(FAILED(hr)) { // Code to
handle the error goes here. } [Visual Basic] You retrieve the material
properties that the rendering device is currently using by calling the
Direct3DDevice8.GetMaterial method for the device. Unlike the
Direct3DDevice8.SetMaterial method, GetMaterial doesn't require preparation.
The GetMaterial method accepts a variable of type D3DMATERIAL8, and fills it
with information describing the current material properties before returning. '
For this example, the d3dDevice variable is assumed to ' contain a valid
reference to a Direct3DDevice8 object. On Local Error Resume Next Dim mat As
D3DMATERIAL8 Call d3dDevice.GetMaterial(mat) If Err.Number <> D3D_OK Then '
Code to handle the error goes here. End If Vertex Formats This section
describes the concepts you need to understand to specify vertices in Microsoft®
Direct3D®, and provides information about the various formats your application
can use to declare vertices. The following topics are discussed. * About Vertex
Formats * Untransformed and Unlit Vertices * Untransformed and Lit Vertices *
Transformed and Lit Vertices * Transformed and Lit Vertex Functionality *
Flexible Vertex Formats and Vertex Shaders About Vertex Formats A flexible
vertex format (FVF) code describes the contents of vertices stored interleaved
in a single data stream. It generally specifies data to be processed by the
fixed function vertex processing pipeline. [C++] Microsoft® Direct3D®
applications can define model vertices in several different ways. Support for
flexible vertex definitions, also known as flexible vertex formats or flexible
vertex format codes, makes it possible for your application to use only the
vertex components it needs, eliminating those components that aren't used. By
using only the needed vertex components, your application can conserve memory
and minimize the processing bandwidth required to render models. You describe
how your vertices are formatted by using a combination of Flexible Vertex
Format Flags. [Visual Basic] Microsoft® Direct3D® applications can define model
vertices in several different ways. Support for flexible vertex definitions,
also known as flexible vertex formats or flexible vertex format codes, makes it
possible for your application to use only the vertex components it needs,
eliminating those components that aren't used. By using only the needed vertex
components, your application can conserve memory and minimize the processing
bandwidth required to render models. You describe how your vertices are
formatted by using a combination of Flexible Vertex Format Flags. The FVF
specification includes formats for point size, specified by D3DFVF_PSIZE. This
size is expressed in camera space units for non-TL vertices, and in
device-space units for TL vertices. [C++] The rendering methods of the
IDirect3DDevice8 interface provides C++ applications with methods that accept a
combination of these flags, and uses them to determine how to render
primitives. Basically, these flags tell the system which vertex
components—position, vertex blending weights, normal, colors, the number and
format of texture coordinates—your application uses and, indirectly, which
parts of the rendering pipeline you want Direct3D to apply to them. In
addition, the presence or absence of a particular vertex format flag
communicates to the system which vertex component fields are present in memory
and which you've omitted. To determine device limitations, you can query a
device for the D3DFVFCAPS_DONOTSTRIPELEMENTS and D3DFVFCAPS_TEXCOORDCOUNTMASK
flexible vertex format flags. For more information, see the FVFCaps member of
the D3DCAPS8 structure. One significant requirement that the system places on
how you format your vertices is on the order in which the data appears. The
following illustration depicts the required order for all possible vertex
components in memory, and their associated data types. Note Texture coordinates
can be declared in different formats, allowing textures to be addressed using
as few as one coordinate or as many as four texture coordinates (for 2-D
projected texture coordinates). For more information, see Texture Coordinate
Formats. Use the D3DFVF_TEXCOORDSIZEn set of macros to create bit patterns that
identify the texture coordinate formats that your vertex format uses. No
application will use every component—the reciprocal homogeneous W (RHW) and
vertex normal fields are mutually exclusive. Nor will most applications try to
use all eight sets of texture coordinates, but Direct3D has this capacity.
There are several restrictions on which flags you can use with other flags. For
example, you cannot use the D3DFVF_XYZ and D3DFVF_XYZRHW flags together, as
this would indicate that your application is describing a vertex's position
with both untransformed and transformed vertices. To use indexed vertex
blending, the D3DFVF_LASTBETA_UBYTE4 flag should appear at the end of the FVF.
The presence of this flag indicates that the fifth blending weight will be
treated as a DWORD instead of float. For more information, see Indexed Vertex
Blending. The following code samples shows the difference between an FVF code
that uses the D3DFVF_LASTBETA_UBYTE4 flag and one that doesn't. The FVF defined
below does not use the D3DFVF_LASTBETA_UBYTE4 flag. The flag D3DFVF_XYZ3 is
present when four blending indices are used because you always use (1 - the sum
of the first three) for the fourth. #define D3DFVF_BLENDVERTEX
(D3DFVF_XYZB3|D3DFVF_NORMAL|D3DFVF_TEX1) struct BLENDVERTEX { D3DXVECTOR3 v; //
Referenced as v0 in the vertex shader FLOAT blend1; // Referenced as v1.x in
the vertex shader FLOAT blend2; // Referenced as v1.y in the vertex shader
FLOAT blend3; // Referenced as v1.z in the vertex shader // v1.w = 1.0 - (v1.x
+ v1.y + v1.z) D3DXVECTOR3 n; // Referenced as v3 in the vertex shader FLOAT
tu, tv; // Referenced as v7 in the vertex shader }; The FVF defined below uses
the D3DFVF_LAST_UBYTE4 flag. #define D3DFVF_BLENDVERTEX (D3DFVF_XYZB4 |
D3DFVF_LASTBETA_UBYTE4 |D3DFVF_NORMAL|D3DFVF_TEX1) struct BLENDVERTEX {
D3DXVECTOR3 v; // Referenced as v0 in the vertex shader FLOAT blend1; //
Referenced as v1.x in the vertex shader FLOAT blend2; // Referenced as v1.y in
the vertex shader FLOAT blend3; // Referenced as v1.z in the vertex shader //
v1.w = 1.0 - (v1.x + v1.y + v1.z) DWORD indices; // Referenced as v2.xyzw in
the vertex shader D3DXVECTOR3 n; // Referenced as v3 in the vertex shader FLOAT
tu, tv; // Referenced as v7 in the vertex shader }; For more information, see
Flexible Vertex Format Flags. [Visual Basic] The Direct3DDevice8 Microsoft®
Visual Basic® class includes methods that accept a combination of these flags,
and uses them to determine how to render primitives. Basically, these flags
tell the system which vertex components—position, vertex blending weights,
normal, colors, the number and format of texture coordinates— your application
uses and, indirectly, which parts of the rendering pipeline you want Direct3D
to apply to them. In addition, the presence or absence of a particular vertex
format flag communicates to the system which vertex component fields are
present in memory and which you've omitted. To determine device limitations,
you can query a device for the D3DFVFCAPS_DONOTSTRIPELEMENTS and
D3DFVFCAPS_TEXCOORDCOUNTMASK flexible vertex format flags. For more
information, see the FVFCaps member of the D3DCAPS8 type. One significant
requirement that the system places on how you format your vertices is on the
order in which the data appears. The following illustration depicts the
required order for all possible vertex components in memory, and their
associated data types. Texture coordinates can be declared in different
formats, allowing textures to be addressed using as few as one coordinate, or
as many as four texture coordinates for 2-D projected texture coordinates. Use
the D3DFVF_TEXCOORDSIZEn set of helper functions from Math.bas to create bit
patterns that identify the texture coordinate formats that your vertex format
uses. The Math.bas Visual Basic code module is included with this SDK. No real
application will use every single component—the reciprocal homogeneous W (RHW)
and vertex normal fields are mutually exclusive. Nor will most applications try
to use all eight sets of texture coordinates, but the flexibility is there.
There are several restrictions on which flags you can use with other flags.
These are mostly common sense. For example, you cannot use the D3DFVF_XYZ and
D3DFVF_XYZRHW flags together, as this would indicate that your application is
describing a vertex's position with both untransformed and transformed
vertices. For more information, take a look at the description for each of the
Flexible Vertex Format Flags. To use indexed vertex blending, the
D3DFVF_LASTBETA_UBYTE4 flag should appear at the end of the FVF. The presence
of this flag indicates that the fifth blending weight will be treated as a
DWORD instead of float. For more information, see Indexed Vertex Blending. The
following code samples shows the difference between an FVF code that uses the
D3DFVF_LASTBETA_UBYTE4 flag and one that doesn't. The FVF defined below does
not use the D3DFVF_LASTBETA_UBYTE4 flag. The flag D3DFVF_XYZ3 is present when
four blending indices are used because you always use (1 - the sum of the first
three) for the fourth. Const D3DFVF_BLENDVERTEX = (D3DFVF_XYZB3 Or
D3DFVF_NORMAL Or D3DFVF_TEX1) Private Type BLENDVERTEX v As D3DXVECTOR '
Referenced as v0 in the vertex shader blend1 As Single ' Referenced as v1.x in
the vertex shader blend2 As Single ' Referenced as v1.y in the vertex shader
blend3 As Single ' Referenced as v1.z in the vertex shader ' v1.w = 1.0 - (v1.x
+ v1.y + v1.z) n As D3DXVECTOR ' Referenced as v3 in the vertex shader tu as
Single ' tu and tv referenced as v7 in the vertex shader tv As Single ' End
Type The FVF defined below uses the D3DFVF_LAST_UBYTE4 flag. Const
D3DFVF_BLENDVERTEX = (D3DFVF_XYZB4 Or D3DFVF_LASTBETA_UBYTE4 Or _ D3DFVF_NORMAL
Or D3DFVF_TEX1) Private Type BLENDVERTEX v As D3DXVECTOR 'Referenced as v0 in
the vertex shader blend1 As Single ' Referenced as v1.x in the vertex shader
blend2 As Single ' Referenced as v1.y in the vertex shader blend3 As Single '
Referenced as v1.z in the vertex shader ' v1.w = 1.0 - (v1.x + v1.y + v1.z)
indices As Long ' Referenced as v2.xyzw in the vertex shader n As D3DXVECTOR '
Referenced as v3 in the vertex shader tu As Single ' tu and tv referenced as v7
in the vertex shader tv As Single End Type For more information, see Flexible
Vertex Format Flags. Untransformed and Unlit Vertices [C++] The presence of the
D3DFVF_XYZ, or any D3DFVF_XYZBn flag, and D3DFVF_NORMAL flags in the vertex
description that you pass to rendering methods identifies the untransformed and
unlit vertex type. By using untransformed and unlit vertices, your application
effectively requests that Microsoft® Direct3D® perform all transformation and
lighting operations using its internal algorithms. You can disable the Direct3D
lighting engine for the primitives being rendered by setting the D3DRS_LIGHTING
render state to FALSE. [Visual Basic] The presence of the D3DFVF_XYZ, or any
D3DFVF_XYZBn flag, and D3DFVF_NORMAL flags in the vertex description that you
pass to rendering methods identifies the untransformed and unlit vertex type.
By using untransformed and unlit vertices, your application effectively
requests that Microsoft® Direct3D perform all transformation and lighting
operations using its internal algorithms. You can disable the Direct3D lighting
engine for the primitives being rendered by setting the D3DRS_LIGHTING render
state to False. Many applications use this vertex type, as it frees them from
implementing their own transformation and lighting engines. However, because
the system is making calculations for you, it requires that you provide a
certain amount of information with each vertex. * You are required to specify
vertices in untransformed model coordinates. The system then applies world,
view, and projection transformations to the model coordinates to position them
in your scene and determine their final locations on the screen. * You can
include a vertex normal for more realistic lighting effects. Vertices lit by
the system that don't include a vertex normal will use a dot product of 0 in
all lighting calculations. These vertices are assumed to receive no incident
light. The system uses the vertex normal, along with the current material, in
its lighting calculations. For details, see Face and Vertex Normal Vectors,
Lights, Materials, and Mathematics of Direct3D Lighting. [C++] Other than these
requirements, you have the flexibility to use or disregard the other vertex
components. For example, you can include a diffuse or specular color with your
untransformed vertices. This was not possible before Microsoft DirectX® 6.0.
Including individual colors for each vertex makes it possible to achieve
shading effects that are more subtle and flexible than lighting calculations
that use only the material color. Keep in mind that you must enable per-vertex
color through the D3DRS_COLORVERTEX render state. Untransformed, unlit vertices
can also include up to eight sets of texture coordinates. When you define your
own vertex format, remember which vertex components your application needs, and
make sure they appear in the required order by declaring a properly ordered
structure. The following code example declares a valid vertex format structure
that includes a position, a vertex normal, a diffuse color, and two sets of
texture coordinates. // // The vertex format description for this vertex would
be: // (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2) // typedef
struct _UNLITVERTEX { float x, y, z; // position float nx, ny, nz; // normal
DWORD Diffuse; // diffuse color float tu1, tv1; // texture coordinates float
tu2, tv2; tv2; } UNLITVERTEX, *LPUNLITVERTEX; The vertex description for the
preceding structure is a combination of the D3DFVF_XYZ, D3DFVF_NORMAL,
D3DFVF_DIFFUSE, and D3DFVF_TEX2 flexible vertex format flags. For more
information, see About Vertex Formats. [Visual Basic] Other than these
requirements, you have the flexibility to use or disregard the other vertex
components. For example, you can include a diffuse or specular color with your
untransformed vertices. This was not possible before Microsoft DirectX® 6.0.
Including individual colors for each vertex makes it possible to achieve
shading effects that are more subtle and flexible than lighting calculations
that use only the material color. Keep in mind that you must enable per-vertex
color through the D3DRS_COLORVERTEX render state. Untransformed, unlit vertices
can also include up to eight sets of texture coordinates. Microsoft Visual
Basic® applications can use either the D3DVERTEX or D3DVERTEX2 type for
vertices. If these types do not suit your application's needs, feel free to
define your own. Remember which vertex components your application needs, and
make sure they appear in the required order by declaring a properly ordered
structure. The following code example declares a valid vertex format structure
that includes a position, a vertex normal, a diffuse color, and two sets of
texture coordinates. ' ' The vertex format description for this vertex would
be: ' (D3DFVF_XYZ Or D3DFVF_NORMAL Or D3DFVF_DIFFUSE Or D3DFVF_TEX2) ' Type
UNLITVERTEX x As Single ' Position y As Single z As Single nx As Single '
Normal ny As Single nz As Single Diffuse As Long ' diffuse color tu1 As Single
' texture coordinates tv1 As Single tu2 As Single ' texture coordinates tv2 As
Single End Type The vertex description for the preceding structure would be a
combination of the D3DFVF_XYZ, D3DFVF_NORMAL, D3DFVF_DIFFUSE, and D3DFVF_TEX2
flexible vertex format flags. For more information, see About Vertex Formats.
Untransformed and Lit Vertices [C++] If you include the D3DFVF_XYZ flag, but
not the D3DFVF_NORMAL flag, in the vertex format description you use with the
Microsoft® Direct3D® rendering methods, you are identifying your vertices as
untransformed but already lit. For information about other dependencies and
exclusions, see the description for the Flexible Vertex Format Flags. [Visual
Basic] If you include the D3DFVF_XYZ flag, but not the D3DFVF_NORMAL flag, in
the vertex format description you use with the Microsoft® Direct3D® rendering
methods, you are identifying your vertices as untransformed but already lit.
For information about other dependencies and exclusions, see the description
for the Flexible Vertex Format Flags. By using untransformed and lit vertices,
your application requests that Direct3D not perform any lighting calculations
on your vertices, but it should still transform them using the previously set
world, view, and projection matrices. Because the system isn't doing lighting
calculations, it doesn't need a vertex normal. The system uses the diffuse and
specular components at each vertex for shading. These colors might be
arbitrary, or they might be computed using your own lighting formulas. If you
don't include a diffuse or specular component, the system uses the default
colors. The default value for the diffuse color is 0xFFFFFFFF, and the default
value for the specular color is 0x0. Like the other vertex types, except for
including a position and some amount of color information, you are free to
include or disregard the texture coordinate sets in the unlit vertex format.
[C++] When you define your own vertex format, remember which vertex components
your application needs, and make sure they appear in the required order by
declaring a properly ordered structure. The following code example declares a
valid untransformed and lit vertex, with diffuse and specular vertex colors,
and three sets of texture coordinates. // // The vertex format description for
this vertex would be: // (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_SPECULAR |
D3DFVF_TEX3) // typedef struct _LITVERTEX { float x, y, z; // position DWORD
Diffuse; // diffuse color DWORD Specular; // specular color float tu1, tv1; //
texture coordinates float tu2, tv2; float tu3, tv3; } LITVERTEX, *LPLITVERTEX;
The vertex description for the preceding structure is a combination of the
D3DFVF_XYZ, D3DFVF_DIFFUSE, D3DFVF_SPECULAR, and D3DFVF_TEX3 flexible vertex
format flags. For more information, see About Vertex Formats. [Visual Basic]
Applications written in Microsoft Visual Basic® can define their own vertex
formats, or use either the D3DLVERTEX or D3DLVERTEX2 type for lit vertices. If
these types do not include all the fields that your application needs, you can
define another type. Make sure that your vertex components appear in the
required order, declaring a new type accordingly. The following code example
declares a valid untransformed and lit vertex, with diffuse and specular vertex
colors, and three sets of texture coordinates. ' ' The vertex format
description for this vertex ' would be: (D3DFVF_XYZ Or D3DFVF_DIFFUSE Or '
D3DFVF_SPECULAR Or D3DFVF_TEX3) ' Type LITVERTEX x As Single ' position y As
Single z As Single Diffuse As Long ' diffuse color Specular As Long ' specular
color tu1 As Single ' texture coordinates tv1 As Single tu2 As Single tv2 As
Single tu3 As Single tv3 As Single End Type The vertex description for the
preceding type is a combination of the D3DFVF_XYZ, D3DFVF_DIFFUSE,
D3DFVF_SPECULAR, and D3DFVF_TEX3 flexible vertex format flags. For more
information, see About Vertex Formats. Transformed and Lit Vertices [C++] If
you include the D3DFVF_XYZRHW flag in your vertex format description, you are
telling the system that your application is using transformed and lit vertices.
This means that Microsoft® Direct3D® doesn't transform your vertices with the
world, view, or projection matrices, nor does it perform any lighting
calculations. It assumes that your application has taken care of these steps.
This fact makes transformed and lit vertices common when porting existing 3-D
applications to Direct3D. In short, Direct3D does not modify transformed and
lit vertices at all. It passes them directly to the driver to be rasterized.
The vertex format flags associated with untransformed vertices and lighting
(D3DFVF_XYZ and D3DFVF_NORMAL) are not allowed if D3DFVF_XYZRHW is present. For
more about flag dependencies and exclusions, see the description for each of
the Flexible Vertex Format Flags. [Visual Basic] If you include the
D3DFVF_XYZRHW flag in your vertex format description, you are telling the
system that your application is using transformed and lit vertices. This means
that Microsoft® Direct3D® doesn't transform your vertices with the world, view,
or projection matrices, nor does it perform any lighting calculations. It
assumes that your application has taken care of these steps. This fact makes
transformed and lit vertices common when porting existing 3-D applications to
Direct3D. In short, Direct3D does not modify transformed and lit vertices at
all. It passes them directly to the driver to be rasterized. The vertex format
flags associated with untransformed vertices and lighting (D3DFVF_XYZ and
D3DFVF_NORMAL) are not allowed if D3DFVF_XYZRHW is present. For more about flag
dependencies and exclusions, see the description for each of the Flexible
Vertex Format Flags. The system requires that the vertex position you specify
be already transformed. The x and y values must be in screen coordinates, and z
must be the depth value of the pixel to be used in the z-buffer. Z values can
range from 0.0 to 1.0, where 0.0 is the closest possible position to the user,
and 1.0 is the farthest position still visible within the viewing area.
Immediately following the position, transformed and lit vertices must include a
reciprocal of homogeneous W (RHW) value. RHW is the reciprocal of the W
coordinate from the homogeneous point (x,y,z,w) at which the vertex exists in
projection space. This value often works out to be the distance from the
eyepoint to the vertex, taken along the z-axis. Other than the position and RHW
requirements, this vertex format is similar to an untransformed and lit vertex.
To recap: * The system doesn't do any lighting calculations with this format,
so it doesn't need a vertex normal. * You can specify a diffuse or specular
color. If you don't, the system uses 0x0 for specular color and 0xFFFFFFFF for
diffuse color. * You can use up to eight sets of texture coordinates, or none
at all. [C++] When you define your own vertex format, remember which vertex
components your application needs, and make sure they appear in the required
order by declaring a properly ordered structure. The following code example
declares a valid transformed and lit vertex, with diffuse and specular vertex
colors, and one set of texture coordinates. // // The vertex format description
for this vertex would be // (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_SPECULAR |
D3DFVF_TEX1) // typedef struct _TRANSLITVERTEX { float x, y; // screen position
float z; // Z-buffer depth float rhw; // reciprocal homogeneous W DWORD
Diffuse; // diffuse color DWORD Specular; // specular color float tu1, tv1; //
texture coordinates } TRANSLITVERTEX, *LPTRANSLITVERTEX; The vertex description
for the preceding structure would be a combination of the D3DFVF_XYZRHW,
D3DFVF_DIFFUSE, D3DFVF_SPECULAR, and D3DFVF_TEX1 flexible vertex format flags.
For more information, see About Vertex Formats. [Visual Basic] Microsoft Visual
Basic® applications can use either the D3DTLVERTEX or D3DTLVERTEX2 type for
transformed and lit vertices. If these types do not include all the fields your
application needs, you can define another type. Make sure that your vertex
components appear in the required order, declaring a new type accordingly. The
following code example declares a valid transformed and lit vertex, with
diffuse and specular vertex colors, and one set of texture coordinates. ' ' The
vertex format description for this vertex would be ' (D3DFVF_XYZRHW Or
D3DFVF_DIFFUSE Or D3DFVF_SPECULAR Or D3DFVF_TEX1) ' Type TRANSLITVERTEX x As
Single ' screen position y As Single z As Single ' Z-buffer depth rhw As Single
' reciprocal homogeneous W Diffuse As Long ' diffuse color Specular As Long '
specular color tu1 As Single ' texture coordinates tv1 As Single End Type The
vertex description for the preceding type is a combination of the
D3DFVF_XYZRHW, D3DFVF_DIFFUSE, D3DFVF_SPECULAR, and D3DFVF_TEX1 flexible vertex
format flags. For more information, see About Vertex Formats and Transformed
and Lit Vertex Functionality. Transformed and Lit Vertex Functionality Vertex
data specified with a flexible vertex format (FVF) code has the property of
being either transformed or nontransformed. The terminology used for
FVF-specified transformed vertices is TL (transformed and lit) vertices.
Microsoft® Direct3D® for Microsoft DirectX® 8.0 continues to support TL vertex
data, as in previous releases. However, TL vertices are subject to some
conditions that are not applicable to nontransformed vertices. TL vertex data
is possible only for vertices specified by an FVF code, and it is not valid as
input for a programmable vertex shader. Programmable vertex shaders have the
flexibility to take various forms of transformed vertex data, but this is
different from FVF-TL vertex data because the interpretation is part of the
shader, not a property of the vertex data. Because it is defined by an FVF
code, TL vertex data is also inherently single stream. TL vertex data is not
guaranteed to be clipped by Direct3D, thus it is required that TL vertex
primitives be clipped prior to sending them to Direct3D for rendering. The x
and y values are required to be clipped to the viewport, or, if available, the
device guardband. The z values for TL vertices are required to be between 0.
and 1, inclusive. It is also required that the RHW values be within the range
[0 < 1/D3DCAPS8.MaxVertexW]. The RHW requirement is to guarantee that the w
values are within the supported range of the hardware rasterization device.
Note that the w, and RHW, range of vertices resulting from a perspective
projection transformation can be modified by applying a scale to all values in
the projection matrix. Note If D3DPMISCCAPS_CLIPTLVERTS is set, then the device
clips post- transformed vertex data to the z and (x, y) viewport limits.
Clipping to user- defined clip planes is not supported for post-transformed
vertex data. If the D3DPMISCCAPS_CLIPTLVERTS capability is not set, then the
application is required to clip these primitives to the z limit and at least to
the guardband extent in x and y. On the other hand, clipping for
pre-transformed vertices is fully supported in both drawing and vertex
processing calls to a destination vertex buffer followed by another drawing
call. This includes user-defined clip planes as well as the z and (x, y)
viewport limits. TL vertex data is always passed directly to the driver for
rendering. When using vertex buffers with TL vertex data, there can be
significant performance advantages to having the driver allocate these vertex
buffers in AGP or video memory. Note that the allocation of a TL vertex buffer
may be driver-allocated even when non-TL vertex data —either FVF or non-FVF—is
not allowed to be driver-allocated, as would be the case when running on a
hardware device that does not support transformation and lighting. For more
information, see Transformed and Lit Vertices. Flexible Vertex Formats and
Vertex Shaders Microsoft® Direct3D® for Microsoft DirectX® 8.0 has a simplified
programming model for using the fixed function vertex processing pipeline with
a single input stream, providing functionality very similar to that of previous
DirectX releases. In this case, the vertex shader consists of a flexible vertex
format (FVF) code that is passed in place of a vertex shader handle when
setting the current vertex shader. The handle space for vertex shaders is
managed by the run-time library so that handles that are valid FVF codes are
reserved for this usage. Setting an FVF code as the current vertex shader
causes the vertex processing to load from stream zero only, and to interpret
the vertex elements as defined in the FVF code. [C++] The following code
example illustrates how to use an FVF code as a vertex shader in your C++
application. First, define a structure for your custom vertex type and
initialize the vertices. In this case, three vertices are initialized for
rendering a triangle. // This code example assumes that d3dDevice is a // valid
pointer to an IDirect3DDevice8 interface. struct CUSTOMVERTEX { FLOAT x, y, z,
rhw; // The transformed position for the vertex DWORD color; // The vertex
color }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
CUSTOMVERTEX g_Vertices[] = { { 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x,
y, z, rhw, color { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, }, { 50.0f, 250.0f,
0.5f, 1.0f, 0xff00ffff, }, }; Then, render the primitive using stream zero.
d3dDevice->SetStreamSource( 0, g_pVB, sizeof(CUSTOMVERTEX) );
d3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX ); d3dDevice->DrawPrimitive(
D3DPT_TRIANGLELIST, 0, 1 ); For more information, see Vertex Shaders. [Visual
Basic] The following code example demonstrates how to use an FVF code as a
vertex shader in your Microsoft Visual Basic® application. First, define a
structure for your custom vertex type and initialize the vertices. In this
case, three vertices are initialized for rendering a triangle. ' This code
example assumes that d3dDeviceis a valid reference ' to a Direct3DDevice8
object. Private Type CUSTOMVERTEX x As Single 'x in screen space y As Single 'y
in screen space z As Single 'Normalized z rhw As Single 'Normalized z rhw color
As Long 'Vertex color End Type Const D3DFVF_CUSTOMVERTEX = (D3DFVF_XYZRHW Or
D3DFVF_DIFFUSE) Dim Vertices(2) As CUSTOMVERTEX Dim VertexSizeInBytes As Long
VertexSizeInBytes = Len(Vertices(0)) With Vertices(0): .x = 150: .y = 50: .z =
0.5: .rhw = 1: .color = &HFFFF0000: End With With Vertices(1): .x = 250: .y =
250: .z = 0.5: .rhw = 1: .color = &HFF00FF00: End With With Vertices(2): .x =
50: .y = 250: .z = 0.5: .rhw = 1: .color = &HFF00FFFF: End With Then, render
the primitive using stream zero. sizeOfVertex = Len(v)
d3dDevice.SetStreamSource 0, g_VB, sizeOfVertex d3dDevice.SetVertexShader
D3DFVF_CUSTOMVERTEX d3dDevice.DrawPrimitive D3DPT_TRIANGLELIST, 0, 1 For more
information, see Vertex Shaders. Textures Textures are a powerful tool in
creating realism in computer-generated 3-D images. Microsoft® Direct3D®
supports an extensive texturing feature set, providing developers with easy
access to advanced texturing techniques. This section discusses the purposes
and uses of textures in Direct3D. The information is presented in the following
topics. * Basic Texturing Concepts * Texture Coordinates * Texture Resources *
Texture Filtering * Texture Wrapping * Texture Blending * Compressed Texture
Resources * Volume Texture Resources * Automatic Texture Management * Hardware
Considerations for Texturing Basic Texturing Concepts This section presents the
most fundamental concepts required for an understanding of texturing in
Microsoft® Direct3D®. The information in this section is presented in the
following topics. * What Is a Texture? * Texture Addressing Modes * Texture
Dirty Regions * Texture Palettes What Is a Texture? Early computer-generated
3-D images, although generally advanced for their time, tended to have a shiny
plastic look. They lacked the types of markings—such as scuffs, cracks,
fingerprints, and smudges—that give 3-D objects realistic visual complexity. In
recent years, textures have gained popularity among developers as a tool for
enhancing the realism of computer-generated 3-D images. In its everyday use,
the word texture refers to an object's smoothness or roughness. In computer
graphics, however, a texture is a bitmap of pixel colors that give an object
the appearance of texture. Because Microsoft® Direct3D® textures are bitmaps,
any bitmap can be applied to a Direct3D primitive. For instance, applications
can create and manipulate objects that appear to have a wood grain pattern in
them. Grass, dirt, and rocks can be applied to a set of 3-D primitives that
form a hill. The result is a realistic-looking hillside. You can also use
texturing to create effects such as signs along a roadside, rock strata in a
cliff, or the appearance of marble on a floor. In addition, Direct3D supports
more advanced texturing techniques such as texture blending—with or without
transparency—and light mapping. For more information, see Texture Blending and
Light Mapping with Textures. If your application creates a hardware abstraction
layer (HAL) device or a software device (see Device Types), it can use 8-, 16-,
24-, or 32-bit textures. Texture Addressing Modes This section describes the
purpose and use of Microsoft® Direct3D® texture addressing modes. It is
organized into the following topics. * What Are Texture Addressing Modes? *
Wrap Texture Address Mode * Mirror Texture Address Mode * Clamp Texture Address
Mode * Border Color Texture Address Mode * Setting and Retrieving Texture
Addressing Modes * Texture Addressing Modes and Texture Wrapping * Device
Limitations for Texture Addressing What Are Texture Addressing Modes? Your
Microsoft® Direct3D® application can assign texture coordinates to any vertex
of any primitive. For details, see Texture Coordinates. Typically, the u- and
v-texture coordinates that you assign to a vertex are in the range of 0.0 to
1.0 inclusive. However, by assigning texture coordinates outside that range,
you can create certain special texturing effects. You control what Direct3D
does with texture coordinates that are outside the [0.0, 1.0] range by setting
the texture addressing mode. For instance, you can have your application set
the texture addressing mode so that a texture is tiled across a primitive. The
following topics contain additional details. * Wrap Texture Address Mode *
Mirror Texture Address Mode * Clamp Texture Address Mode * Border Color Texture
Address Mode Wrap Texture Address Mode [C++] The wrap texture address mode,
identified by the D3DTADDRESS_WRAP member of the D3DTEXTUREADDRESS enumerated
type, makes Microsoft® Direct3D® repeat the texture on every integer junction.
Suppose, for example, your application creates a square primitive and specifies
texture coordinates of (0.0,0.0), (0.0,3.0), (3.0,3.0), and (3.0,0.0). Setting
the texture addressing mode to D3DTADDRESS_WRAP results in the texture being
applied three times in both the u-and v-directions. [Visual Basic] The wrap
texture address mode, identified by the D3DTADDRESS_WRAP member of the
CONST_D3DTEXTUREADDRESS enumeration, makes Microsoft® Direct3D® repeat the
texture on every integer junction. Suppose, for example, your application
creates a square primitive and specifies texture coordinates of (0.0,0.0),
(0.0,3.0), (3.0,3.0), and (3.0,0.0). Setting the texture addressing mode to
D3DTADDRESS_WRAP results in the texture being applied three times in both the
u- and v-directions. This is illustrated in the following figure. The effects
of this texture address mode are similar to, but distinct from, those of the
mirror mode. For more information, see Mirror Texture Address Mode. Mirror
Texture Address Mode [C++] The mirror texture address mode, identified by the
D3DTADDRESS_MIRROR member of the D3DTEXTUREADDRESS enumerated type, causes
Microsoft® Direct3D® to mirror the texture at every integer boundary. Suppose,
for example, your application creates a square primitive and specifies texture
coordinates of (0.0,0.0), (0.0,3.0), (3.0,3.0), and (3.0,0.0). Setting the
texture addressing mode to D3DTADDRESS_MIRROR results in the texture being
applied three times in both the u- and v-directions. Every other row and column
that it is applied to is a mirror image of the preceding row or column. [Visual
Basic] The mirror texture address mode, identified by the D3DTADDRESS_MIRROR
member of the CONST_D3DTEXTUREADDRESS enumeration, causes Microsoft® Direct3D®
to mirror the texture at every integer boundary. Suppose, for example, your
application creates a square primitive and specifies texture coordinates of
(0.0,0.0), (0.0,3.0), (3.0,3.0), and (3.0,0.0). Setting the texture addressing
mode to D3DTADDRESS_MIRROR results in the texture being applied three times in
both the u- and v-directions. Every other row and column that it is applied to
is a mirror image of the preceding row or column. This is illustrated in the
following figure. The effects of this texture address mode are similar to, but
distinct from, those of the wrap mode. For more information, see Wrap Texture
Address Mode. Clamp Texture Address Mode [C++] The clamp texture address mode,
identified by the D3DTADDRESS_CLAMP member of the D3DTEXTUREADDRESS enumerated
type, causes Microsoft® Direct3D® to clamp your texture coordinates to the
[0.0, 1.0] range. That is, it applies the texture once, then smears the color
of edge pixels. For example, suppose that your application creates a square
primitive and assigns texture coordinates of (0.0,0.0), (0.0,3.0), (3.0,3.0),
and (3.0,0.0) to the primitive's vertices. Setting the texture addressing mode
to D3DTADDRESS_CLAMP results in the texture being applied once. The pixel
colors at the top of the columns and the end of the rows are extended to the
top and right of the primitive respectively. [Visual Basic] The clamp texture
address mode, identified by the D3DTADDRESS_CLAMP member of the
CONST_D3DTEXTUREADDRESS enumeration, causes Microsoft® Direct3D® to clamp your
texture coordinates to the [0.0, 1.0] range. That is, it applies the texture
once, then smears the color of edge pixels. For instance, suppose that your
application creates a square primitive and assigns texture coordinates of
(0.0,0.0), (0.0,3.0), (3.0,3.0), and (3.0,0.0) to the primitive's vertices.
Setting the texture addressing mode to D3DTADDRESS_CLAMP results in the texture
being applied once. The pixel colors at the top of the columns and the end of
the rows are extended to the top and right of the primitive respectively. This
is illustrated in the following figure. Border Color Texture Address Mode [C++]
The border color texture address mode, identified by the D3DTADDRESS_BORDER
member of the D3DTEXTUREADDRESS enumerated type, causes Microsoft® Direct3D® to
use an arbitrary color, known as the border color, for any texture coordinates
outside the range of 0.0 through 1.0, inclusive. [Visual Basic] The border
color texture address mode, identified by the D3DTADDRESS_BORDER member of the
CONST_D3DTEXTUREADDRESS enumeration, causes Microsoft® Direct3D® to use an
arbitrary color, known as the border color, for any texture coordinates outside
the range of 0.0 through 1.0, inclusive. This is shown in the following figure
in which the application specifies that the texture be applied to the primitive
using a red border. [C++] Applications set the border color by calling
IDirect3DDevice8::SetTextureStageState. Set the first parameter for the call to
the desired texture stage identifier, the second parameter to the
D3DTSS_BORDERCOLOR stage state value, and the third parameter to the new RGBA
border color. [Visual Basic] Microsoft Visual Basic® applications set the
border color by calling Direct3DDevice8.SetTextureStageState. Set the first
parameter for the call to the desired texture stage identifier, the second
parameter to the D3DTSS_BORDERCOLOR stage state value, and the third parameter
to the new RGBA border color. Setting and Retrieving Texture Addressing Modes
[C++] You can set texture addressing modes for individual texture stages by
calling the IDirect3DDevice8::SetTextureStageState method. Specify the desired
texture stage identifier in the first parameter. Set the second parameter to
D3DTSS_ADDRESSU, D3DTSS_ADDRESSV, or D3DTSS_ADDRESSW values to update the u-,
v-, or v- addressing modes individually. The third parameter you pass to
SetTextureStageState determines which mode is being set. This can be any member
of the D3DTEXTUREADDRESS enumerated type. To retrieve the current texture
address mode for a texture stage, call IDirect3DDevice8::GetTextureStageState,
using the D3DTSS_ADDRESSU, D3DTSS_ADDRESSV, or D3DTSS_ADDRESSW members of the
D3DTEXTURESTAGESTATETYPE enumeration to identify the address mode about which
you want information. [Visual Basic] You can set texture addressing modes for
individual texture stages by calling the Direct3DDevice8.SetTextureStageState
method. Specify the desired texture stage identifier in the first parameter.
Set the second parameter to D3DTSS_ADDRESSU, D3DTSS_ADDRESSV, or
D3DTSS_ADDRESSW values to update the u-, v-, or w- addressing modes
individually. The third parameter you pass to SetTextureStageState determines
which mode is being set. This can be any member of the CONST_D3DTEXTUREADDRESS
enumeration. To retrieve the current texture address mode for a given texture
stage, call Direct3DDevice8.GetTextureStageState, using the D3DTSS_ADDRESSU,
D3DTSS_ADDRESSV, or D3DTSS_ADDRESSW members of the
CONST_D3DTEXTURESTAGESTATETYPE enumeration to the address mode about which you
want information. Texture Addressing Modes and Texture Wrapping Direct3D
enables applications to perform texture wrapping. It is important to note that
setting the texture addressing mode to D3DTADDRESS_WRAP is not the same as
performing texture wrapping. Setting the texture addressing mode to
D3DTADDRESS_WRAP results in multiple copies of the source texture being applied
to the current primitive, and enabling texture wrapping changes how the system
rasterizes textured polygons. For details, see Texture Wrapping. Enabling
texture wrapping effectively makes texture coordinates outside the [0.0, 1.0]
range invalid, and the behavior for rasterizing such delinquent texture
coordinates is undefined in this case. When texture wrapping is enabled,
texture addressing modes are not used. Take care that your application does not
specify texture coordinates lower than 0.0 or higher than 1.0 when texture
wrapping is enabled. Device Limitations for Texture Addressing [C++] Although
the system generally allows texture coordinates outside the range of 0.0 and
1.0, inclusive, hardware limitations often affect how far outside that range
texture coordinates can be. A rendering device communicates this limit in the
MaxTextureRepeat member of the D3DCAPS8 structure when you retrieve device
capabilities. The value in this member describes the full range of texture
coordinates allowed by the device. For instance, if this value is 128, then the
input texture coordinates must be kept in the range -128.0 to +128.0. Passing
vertices with texture coordinates outside this range is invalid. The same
restriction applies to the texture coordinates generated as a result of
automatic texture coordinate generation and texture coordinate transformations.
The interpretation of MaxTextureRepeat is also affected by the
D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE capability bit. When this bit is set,
the value in the MaxTextureRepeat member of D3DCAPS8 is used precisely as
described. However, when D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE is not set,
texture repeating limitations depend on the size of the texture indexed by the
texture coordinates. In this case, MaxTextureRepeat must be scaled by the
current texture size at the largest level of detail to compute the valid
texture coordinate range. For example, given a texture dimension of 32 and
MaxTextureRepeat value of 512, the actual valid texture coordinate range is
512/32 = 16, so the texture coordinates for this device must be within the
range of -16.0 to +16.0. [Visual Basic] Although the system generally allows
texture coordinates outside the range of 0.0 and 1.0, inclusive, hardware
limitations often affect how far outside that range texture coordinates can be.
A rendering device communicates this limit in the MaxTextureRepeat member of
the D3DCAPS8 type when you retrieve device capabilities. The value in this
member describes the full range of texture coordinates allowed by the device.
For instance, if this value is 128, then the input texture coordinates must be
kept in the range -128.0 to +128.0. Passing vertices with texture coordinates
outside of this range is invalid. The same restriction applies to the texture
coordinates generated as a result of automatic texture coordinate generation
and texture coordinate transformations. The interpretation of MaxTextureRepeat
is also affected by the D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE capability
bit. When this bit is set, the value in the MaxTextureRepeat member of D3DCAPS8
is used precisely as described. However, when
D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE is not set, texture repeating
limitations depend on the size of the texture indexed by the texture
coordinates. In this case, MaxTextureRepeat must be scaled by the current
texture size at the largest level of detail to compute the valid texture
coordinate range. For example, given a texture dimension of 32 and
MaxTextureRepeat value of 512, the actual valid texture coordinate range is
512/32 = 16, so the texture coordinates for this device must be within the
range of -16.0 to +16.0. Texture Dirty Regions [C++] Applications can optimize
what subset of a texture is copied by specifying dirty regions on textures.
Only those regions marked as dirty are copied by a call to
IDirect3DDevice8::UpdateTexture. However, the dirty regions may be expanded to
optimize alignment. When a texture is created, the entire texture is considered
dirty. Only the following four operations affect the dirty state of a texture.
* Adding a dirty region to a texture * Locking some buffer in the texture. This
operation adds the locked region as a dirty region. The application can turn
off this automatic dirty region update if it has better knowledge of the actual
dirty regions. * Using the texture as a destination in
IDirect3DDevice8::CopyRects marks the entire texture as dirty. * Using the
texture as a source in UpdateTexture clears all the dirty regions on the source
texture. [Visual Basic] Applications can optimize what subset of a texture is
copied by specifying dirty regions on textures. Only those regions marked as
dirty are copies by a call to Direct3DDevice8.UpdateTexture. However, the dirty
regions may be expanded to optimize alignment. When a texture is created, the
entire texture is considered dirty. Only the following four operations affect
the dirty state of a texture. * Adding a dirty region to a texture * Locking
some buffer in the texture. This operation adds the locked region as a dirty
region. The application can turn off this automatic dirty region update if it
has better knowledge of the actual dirty regions. * Using the texture as a
destination in Direct3DDevice8.CopyRects marks the entire texture as dirty. *
Using the texture as a source in UpdateTexture clears all the dirty regions on
the source texture. Dirty regions are set on the top level of a mipmapped
texture, and UpdateTexture can expand the dirty region down the mip chain in
order to minimize the number of bytes copied for each sublevel. Note that the
sublevel dirty region coordinates are rounded outward, that is, their
fractional parts are rounded toward the nearest edge of the texture. [C++]
Because each type of texture has different types of dirty regions, there are
methods on each texture type. 2-D textures use dirty rectangle, and volume
textures use boxes. * IDirect3DCubeTexture8::AddDirtyRect *
IDirect3DTexture8::AddDirtyRect * IDirect3DVolumeTexture8::AddDirtyBox Passing
NULL for the pDirtyRect or pDirtyBox parameters for the above methods expands
the dirty region to cover the entire texture. [Visual Basic] Because each type
of texture has different types of dirty regions, there are methods on each
texture type. 2-D textures use dirty rectangle, and volume textures use boxes.
* Direct3DCubeTexture8.AddDirtyRect * Direct3DTexture8.AddDirtyRect *
Direct3DVolumeTexture8.AddDirtyBox Passing ByVal 0 for the DirtyRect or
DirtyBox parameters for the above methods expands the dirty region to cover the
entire texture. Each lock method can take D3DLOCK_NO_DIRTY_UPDATE, which
prevents any changes to the dirty state of the texture. For more information,
see Locking Resources. Applications should use D3DLOCK_NO_DIRTY_UPDATE when
further information about the true set of regions changed during a lock
operation is available. You should note that a lock or copy to only a
sublevel—that is, without locking or copying to the top level—of texture does
not update the dirty regions for that texture. Applications assume the same
responsibility for updating dirty regions when they lock lower levels without
locking the topmost level. Texture Palettes [C++] Microsoft® Direct3D® for
Microsoft DirectX® 8.0 supports paletted textures through a set of 256 entry
palettes associated with the IDirect3DDevice8 object. A palette is made current
by calling the IDirect3DDevice8::SetCurrentTexturePalette method. The current
palette is used for translating all paletted textures for all active texture
stages. IDirect3DDevice8::SetPaletteEntries updates all of a palette's 256
entries. Each entry is a PALETTEENTRY structure of the format D3DFMT_A8R8G8B8.
All entries default to 0xFFFFFFFF. Note that as of DirectX 8.0, the peFlags
member of the PALLETTEENTRY structure does not work as documented in the
Microsoft Platform Software Development Kit (SDK). The peFlags member is now
the alpha channel for 8-bit palettized formats. The IDirect3DDevice8 palettes
contain an alpha channel. This alpha channel can be used when the
D3DPTEXTURECAPS_ALPHAPALETTE device capability flag is set, indicating that the
device supports alpha from the palette. The palette alpha channel is used when
the texture format does not have an alpha channel. If the device does not
support alpha from the palette and the texture format does not have an alpha
channel, then a value of 0xFF is used for alpha. [Visual Basic] Microsoft®
Direct3D® for Microsoft DirectX® 8.0 supports paletted textures through a set
of 256 entry palettes associated with the Direct3DDevice8 object. A palette is
made current by calling the Direct3DDevice8.SetCurrentTexturePalette method.
The current palette is used for translating all paletted textures for all
active texture stages. Direct3DDevice8.SetPaletteEntries updates all of a
palette's 256 entries. Each entry is a PALETTEENTRY type of the format
D3DFMT_A8R8G8B8. All entries default to 0xFFFFFFFF. Note that as of DirectX 8,
the peFlags member of the PALLETTEENTRY structure does not work as documented
in the Microsoft Platform Software Development Kit (SDK). The peFlags member is
now the alpha channel for 8-bit palettized formats. The Direct3DDevice8
palettes contain an alpha channel. This alpha channel can be used when the
D3DPTEXTURECAPS_ALPHAPALETTE device capability flag is set, indicating that the
device supports alpha from the palette. The palette alpha channel is used when
the texture format does not have an alpha channel. If the device does not
support alpha from the palette and the texture format does not have an alpha
channel, then a value of 0xFF is used for alpha. There is a maximum of 16,384
palettes. Because memory resources associated with the set of palettes are
proportional to the maximum palette number that an application references, use
contiguous palette numbers starting at zero. Texture Coordinates The following
topics introduce the concept of texture coordinates, their formats, and the
Microsoft® Direct3D® services used to manipulate them. * Understanding Texture
Coordinates * Directly Mapping Texels to Pixels * Texture Coordinate Formats *
Texture Coordinate Processing Understanding Texture Coordinates Most textures,
like bitmaps, are a two-dimensional array of color values. Cubic- environment
map textures are an exception. For details, see Cubic Environment Mapping. The
individual color values are called a texture element, or texel. Each texel has
a unique address in the texture. The address can be thought of as a column and
row number, which are labeled u and v respectively. Texture coordinates are in
texture space. That is, they are relative to the location (0,0) in the texture.
When a texture is applied to a primitive in 3-D space, its texel addresses must
be mapped into object coordinates. They must then be translated into screen
coordinates, or pixel locations. Microsoft® Direct3D® maps texels in texture
space directly to pixels in screen space, skipping the intermediate step for
greater efficiency. This mapping process is actually an inverse mapping. That
is, for each pixel in screen space, the corresponding texel position in texture
space is calculated. The texture color at or around that point is sampled. The
sampling process is called texture filtering. For more information, see Texture
Filtering. Each texel in a texture can be specified by its texel coordinate.
However, in order to map texels onto primitives, Direct3D requires a uniform
address range for all texels in all textures. Therefore, it uses a generic
addressing scheme in which all texel addresses are in the range of 0.0 to 1.0
inclusive. Direct3D applications specify texture coordinates in terms of u,v
values, much like 2-D Cartesian coordinates are specified in terms of x,y
coordinates. Technically, the system can actually process texture coordinates
outside the range of 0.0 and 1.0, and does so by using the parameters you set
for texture addressing. For more information, see Texture Addressing Modes. A
result of this is that identical texture addresses can map to different texel
coordinates in different textures. In the following illustration, the texture
address being used is (0.5,1.0). However, because the textures are different
sizes, the texture address maps to different texels. Texture 1, on the left, is
5x5. The texture address (0.5,1.0) maps to texel (2,4). Texture 2, on the
right, is 7x7. The texture address (0.5,1.0) maps to texel (3,6). A simplified
version of the texel mapping process is shown in the following diagram.
Admittedly, this example is extremely simple. For more detailed information,
see Directly Mapping Texels to Pixels. For this example, a pixel, shown at the
left of the illustration, is idealized into a square of color. The addresses of
the four corners of the pixel are mapped onto the 3- D primitive in object
space. The shape of the pixel is often distorted because of the shape of the
primitive in 3-D space and because of the viewing angle. The corners of the
surface area on the primitive that correspond the corners of the pixel are then
mapped into texture space. The mapping process distorts the pixel's shape
again, which is common. The final color value of the pixel is computed from the
texels in the region to which the pixel maps. You determine the method that
Direct3D uses to arrive at the pixel color when you set the texture filtering
method. For more information, see Texture Filtering. Your application can
assign texture coordinates directly to vertices. This capability gives you
control over which portion of a texture is mapped onto a primitive. For
instance, suppose you create a rectangular primitive that is exactly the same
size as the texture in the following illustration. In this example, you want
your application to map the whole texture onto the whole wall. The texture
coordinates your application assigns to the vertices of the primitive are
(0.0,0.0), (1.0,0.0), (1.0,1.0), and (0.0,1.0). If you decide to decrease the
height of the wall by one-half, you can distort the texture to fit onto the
smaller wall, or you can assign texture coordinates that cause Direct3D to use
the bottom half of the texture. If you decide to distort or scale the texture
to fit the smaller wall, the texture filtering method that you use will
influence the quality of the image. For more information, see Texture
Filtering. If, instead, you decide to assign texture coordinates to make
Direct3D use the bottom half of the texture for the smaller wall, the texture
coordinates your application assigns to the vertices of the primitive in this
example are (0.0,0.0), (1.0,0.0), (1.0,0.5), and (0.0,0.5). Direct3D applies
the bottom half of the texture to the wall. It is possible for texture
coordinates of a vertex to be greater than 1.0. When you assign texture
coordinates to a vertex that are not in the range of 0.0 to 1.0 inclusive, you
should also set the texture addressing mode. For further information, see
Texture Addressing Modes. Directly Mapping Texels to Pixels Applications often
need to apply textures to geometry in a scene so that texels map directly to
on-screen pixels. For example, take an application that needs to display text
within a texture on an object within a scene. In order to clearly display
textual information in a texture, the application needs some way to ensure that
the textured geometry receives texels undisrupted by texture filtering. Failing
this, the resulting image is often blurred, or in the case of point-sampled
texture filtering, can cause rough edges. Because the Microsoft® Direct3D®
pixel and texture sampling rules are carefully defined to unify pixel and
texture sampling while supporting image and texture filtering, getting the
texels in a texture to map directly to on-screen pixels can be a significant
and often frustrating challenge. Overcoming this challenge requires a clear
understanding of how Direct3D maps the floating-point texture coordinates for a
vertex to the integer pixel coordinates used by the rasterizer. Direct3D
performs the following computations to map floating point texture coordinates
to texel addresses. In these formulas, Tx and Ty are the horizontal and
vertical output texel coordinates, and u and v are the horizontal and vertical
texture coordinates supplied for the vertex. The Mx and My elements represent
the number of horizontal or vertical texels at the current mipmap level. The
remainder of this discussion targets horizontal mapping of texels to pixels;
keep in mind that mapping in the vertical is identical to the horizontal case.
Placing the texture coordinate limits 0.0 and 1.0 into these formulas maps a
texture coordinate of 0.0 halfway between the first and last texels of a
repeated texture map. The coordinate 1.0 is mapped halfway between the last
texel of the current iteration of the texture map and the next iteration. For a
repeated texture that's four texels wide, at mipmap level 0, the following
illustration shows where the system maps the coordinates 0.0 and 1.0. Given an
understanding of this mapping, you can apply a simple bias to your screen-
space geometry coordinates to force the system to map each texel to a
corresponding pixel. For example, to draw a four-sided polygon that maps each
texel from the preceding texture to one, and only one, pixel on the screen, you
must force geometry coordinates to overlap the pixels, effectively placing the
center of each texel at the center of each pixel. The result is the 1-to-1
mapping often sought-after by applications. To map the texture with a 4-texel
width to the pixel coordinates 0 through 3, draw a four-sided polygon, from two
triangles, that has screen-space coordinates of ?0.5 to 3.5 and texture
coordinates of 0.0 to 1.0. For example, take the pixel at screen coordinate
0.0. Because 0.0 is one-half pixel away from the first vertex, at -0.5, and the
total width is 4.0, the iterated texture coordinate is 0.125. Scaling this by
the texture size, which is 4, results in the coordinate 0.5. Subtracting this
0.5 bias produces a texture address of 0.0, which fully maps to the first texel
in the map. To summarize, texture coordinates overlap the texture map evenly on
both sides. The following illustration shows the mapping of a texture that is
four texels wide. The system normalizes pixel coordinates in the same way it
normalizes texel coordinates. Therefore, if the vertices overlap the pixels
into which to render, and if the vertices use texture coordinates of 0.0 and
1.0, the pixels and texels line up. If both are of similar size and properly
aligned, they match exactly, texel to pixel, as shown in the following figure.
Texture Coordinate Formats Texture coordinates in Microsoft® Direct3D® can
include one, two, three, or four floating point elements to address textures
with varying levels of dimension. A 1-D texture—a texture surface with
dimensions of 1-by-n texels—is addressed by one texture coordinate. The most
common case, 2-D textures, are addressed with two texture coordinates commonly
called u and v. Direct3D supports a single type of 3-D texture, called a
cubic-environment map. Cubic environment maps aren't truly 3-D, but they are
addressed with a 3-element vector. For details, see Cubic Environment Mapping.
[C++] As described in About Vertex Formats, applications encode texture
coordinates in the vertex format. The vertex format can include multiple sets
of texture coordinates. Use the D3DFVF_TEX0 through D3DFVF_TEX8 flexible vertex
format flags to describe a vertex format that includes no texture coordinates,
or as many as eight sets. Each texture coordinate set can have between one and
four elements. The D3DFVF_TEXTUREFORMAT1 through D3DFVF_TEXTUREFORMAT4 flags
describe the number of elements in a texture coordinate in a set, but these
flags aren't used by themselves. Rather, the D3DFVF_TEXCOORDSIZEn set of macros
use these flags to create bit patterns that describe the number of elements
used by a particular set of texture coordinates in the vertex format. These
macros accept a single parameter that identifies the index of the coordinate
set whose number of elements is being defined. The following example
illustrates how these macros are used. // This vertex format contains two sets
of texture coordinates. // The first set (index 0) has 2 elements, and the
second set // has 1 element. The description for this vertex format would be:
// dwFVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2 | //
D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE1(1); // typedef struct CVF {
D3DVECTOR position; D3DVECTOR normal; D3DCOLOR diffuse; float u, v; // 1st set,
2-D float t; // 2nd set, 1-D } CustomVertexFormat; [Visual Basic] As described
in About Vertex Formats, applications encode texture coordinates in the vertex
format. The vertex format can include multiple sets of texture coordinates. Use
the D3DFVF_TEX0 through D3DFVF_TEX8 flexible vertex format flags to describe a
vertex format that includes no texture coordinates, or as many as eight sets.
Each texture coordinate set can have between one and four elements. Use the
D3DFVF_TEXCOORDSIZEn set of helper functions in the Math.bas source file that
ships with this SDK to generate bit patterns that describe the number of
elements used by a set of texture coordinates in the vertex format. These
macros accept a single parameter that identifies the index of the coordinate
set whose number of elements is being defined. The following example
illustrates how these macros are used. Private Sub Form_Load() ' This vertex
format contains two sets of texture coordinates. ' The first set (index 0) has
2 elements, and the second set ' has 1 element. ' ' The description for this
vertex format would be: ' lFVF = D3DFVF_XYZ Or D3DFVF_NORMAL Or D3DFVF_DIFFUSE
Or D3DFVF_TEX2 Or _ ' D3DFVF_TEXCOORDSIZE2(0) Or D3DFVF_TEXCOORDSIZE1(1) ' Type
CustomVertexFormat position As D3DVECTOR normal As D3DVECTOR diffuse As
D3DVECTOR ' 1st set, 2-D u As Single v As Single ' 2nd set, 1-D t As Single End
Type Note With the exception of cubic-environment maps, rasterizers cannot
address textures by using any more than two elements. Applications can supply
up to three elements for a texture coordinate, but only if the texture is a
cube map, or the D3DTTFF_PROJECTED texture transform flag is used. The
D3DTTFF_PROJECTED flag causes the rasterizer to divide the first two elements
by the third (or nth) element. For more information, see Texture Coordinate
Transformations. Texture Coordinate Processing This section describes
Microsoft® Direct3D® support for processing texture coordinates. Information is
organized into the following topics. * Texture Coordinate Processing Path *
Automatically Generated Texture Coordinates * Texture Coordinate
Transformations * Using Texture Coordinate Processing Texture Coordinate
Processing Path The following figure shows the path taken by the texture
coordinates from their source, through processing, and to the rasterizer. [C++]
There are two sources from which the system can draw texture coordinates. For a
given texture stage, you can use texture coordinates included in the vertex
format (D3DFVF_TEX1 through D3DFVF_TEX8), or you can use texture coordinates
automatically generated by Microsoft® Direct3D®. For details about the latter
case, see Automatically Generated Texture Coordinates. If the
D3DTSS_TEXTURETRANSFORMFLAGS texture stage state for the current texture stage
is set to D3DTTFF_DISABLE (the default setting), input coordinates are not
transformed. If D3DTSS_TEXTURETRANSFORMFLAGS is set to any other value, the
transformation matrix for that stage is applied to the input coordinates. The
D3DTEXTURETRANSFORMFLAGS enumerated type defines valid values for the
D3DTSS_TEXTURETRANSFORMFLAGS texture-stage state. With the exception of the
D3DTTFF_DISABLE flag, which bypasses texture coordinate transformation, the
values defined in this enumeration configure the number of output coordinates
that the system passes to the rasterizer. The D3DTTFF_COUNT1 through
D3DTTFF_COUNT4 flags instruct the system to pass one, two, three, or four
elements from the output coordinates to the rasterizer. Currently 1-D texture
coordinates aren't supported. The D3DTTFF_PROJECTED flag is special: it tells
the system that the texture coordinates are for a projected texture. Combine
the D3DTTFF_PROJECTED flag with another member of D3DTEXTURETRANSFORMFLAGS to
instruct the rasterizer to divide all the elements by the last element before
rasterization takes place. For example, when explicitly using three-element
texture coordinates, or when transformation results in a three-element texture
coordinate, you can combine the D3DTTFF_COUNT3 and D3DTTFF_PROJECTED flags to
cause the rasterizer to divide the first two elements by the last, producing
2-D texture coordinates required to address a 2-D texture. [Visual Basic] There
are two sources from which the system can draw texture coordinates. For a given
texture stage, you can use texture coordinates included in the vertex format
(D3DFVF_TEX1 through D3DFVF_TEX8), or you can use texture coordinates
automatically generated by Microsoft® Direct3D®. For details about the latter
case, see Automatically Generated Texture Coordinates. If the
D3DTSS_TEXTURETRANSFORMFLAGS texture stage state for the current texture stage
is set to D3DTTFF_DISABLE (the default setting), input coordinates are not
transformed. If D3DTSS_TEXTURETRANSFORMFLAGS is set to any other value, the
transformation matrix for that stage is applied to the input coordinates. The
CONST_D3DTEXTURETRANSFORMFLAGS enumeration defines valid values for the
D3DTSS_TEXTURETRANSFORMFLAGS texture-stage state. With the exception of the
D3DTTFF_DISABLE flag, which bypasses texture coordinate transformation, the
values defined in this enumeration configure the number of output coordinates
that the system passes to the rasterizer. The D3DTTFF_COUNT1 through
D3DTTFF_COUNT4 flags instruct the system to pass one, two, three, or four
elements from the output coordinates to the rasterizer. The D3DTTFF_PROJECTED
flag is special: it tells the system that the texture coordinates are for a
projected texture. Combine the D3DTTFF_PROJECTED flag with another member of
CONST_D3DTEXTURETRANSFORMFLAGS to instruct the rasterizer to divide all the
elements by the last element before rasterization takes place. For instance,
when explicitly using three-element texture coordinates, or when transformation
results in a three-element texture coordinate, you can combine the
D3DTTFF_COUNT3 and D3DTTFF_PROJECTED flags to cause the rasterizer to divide
the first two elements by the last, producing 2-D texture coordinates required
to address a 2-D texture. Note With the exception of cubic-environment maps,
rasterizers cannot address textures by using texture coordinates with more than
two elements. If you specify more elements than can be used to address the
current texture for that stage, the extraneous elements are ignored. This also
applies when using 2-D texture coordinates for a 1-D texture. Automatically
Generated Texture Coordinates Microsoft® Direct3D® can automatically generate
the texture coordinates for a vertex. This section describes the services
offered by the system and includes details on how the services are used. The
following topics are discussed. * About Automatically Generated Texture
Coordinates * Configuring Automatically Generated Texture Coordinates About
Automatically Generated Texture Coordinates The system can use the transformed
camera-space position or the normal from a vertex as texture coordinates, or it
can compute the three element vectors used to address a cubic environment map.
Like texture coordinates that you explicitly specify in a vertex, you can use
automatically generated texture coordinates as input for texture coordinate
transformations. Automatically generated texture coordinates can significantly
reduce the bandwidth required for geometry data by eliminating the need for
explicit texture coordinates in the vertex format. In many cases, the texture
coordinates that the system generates can be used with transformations to
produce special effects. Of course, this is a special-purpose feature, and you
will use explicit texture coordinates for many occasions. Configuring
Automatically Generated Texture Coordinates [C++] In C++, the
D3DTSS_TEXCOORDINDEX texture-stage state (from the D3DTEXTURESTAGESTATETYPE
enumerated type) controls how the system generates texture coordinates. [Visual
Basic] In Microsoft® Visual Basic®, the D3DTSS_TEXCOORDINDEX texture-stage
state (from the CONST_D3DTEXTURESTAGESTATETYPE enumeration) controls how the
system generates texture coordinates. Normally, this state instructs the system
to use a particular set of texture coordinates encoded in the vertex format.
When you include the D3DTSS_TCI_CAMERASPACENORMAL,
D3DTSS_TCI_CAMERASPACEPOSITION, or D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR flags
in the value that you assign to this state, the system behavior is quite
different. If any of these flags are present, the texture stage ignores the
texture coordinates within the vertex format in favor of coordinates that the
system generates. The meanings for each flag are shown in the following list.
D3DTSS_TCI_CAMERASPACENORMAL Use the vertex normal, transformed to camera
space, as input texture coordinates. D3DTSS_TCI_CAMERASPACEPOSITION Use the
vertex position, transformed to camera space, as input texture coordinates.
D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR Use the reflection vector, transformed
to camera space, as input texture coordinates. The reflection vector is
computed from the input vertex position and normal vector. The preceding flags
are mutually exclusive. If you include one flag, you can still specify an index
value, which the system uses to determine the texture wrapping mode. [C++] The
following code example shows how these flags are used in C++. /* * For this
example, the d3dDevice variable is a valid * pointer to an IDirect3DDevice8
interface. * * Use the vertex position (camera-space) as the input * texture
coordinates for this texture stage, and the * wrap mode set in the
D3DRENDERSTATE_WRAP1 render state. */ d3dDevice->SetTextureStageState( 0,
D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION | 1 ); [Visual Basic] The
following code example shows how these flags are used in Visual Basic. ' ' For
this example, the D3DDevice variable is a valid ' reference to a
Direct3DDevice8 object. ' ' Use the vertex position (camera-space) as the input
' texture coordinates for this texture stage, and the ' wrap mode set in the
D3DRENDERSTATE_WRAP1 render state. ' Call D3DDevice.SetTextureStageState( 0,
D3DTSS_TEXCOORDINDEX, _ D3DTSS_TCI_CAMERASPACEPOSITION Or 1 ) Note
Automatically generated texture coordinates are most useful as input values for
a texture coordinate transformation, or to eliminate the need for your
application to compute three-element vectors for cubic-environment maps. See
Also Texture Coordinate Transformations, Cubic Environment Mapping Texture
Coordinate Transformations The following topics provide information about
working with the texture coordinate transformation features offered by
Microsoft® Direct3D® Immediate Mode. * About Texture Coordinate Transformations
* Setting and Retrieving Texture Coordinate Transformations * Enabling Texture
Coordinate Transformations About Texture Coordinate Transformations Microsoft®
Direct3D® devices can transform the texture coordinates for vertices by
applying a 4?4 matrix. The system applies transformations to texture
coordinates in the same manner as geometry, and any transformations that can be
communicated in a 4?4 matrix—scales, rotations, translations, projections,
shears, or any combination of these—can be applied. Note Direct3D does not
modify transformed and lit vertices. As a result, an application using
transformed and lit vertices cannot use Direct3D to transform the texture
coordinates of the vertices. Devices that support hardware-accelerated
transformation and lighting operations (TnLHAL Device) also accelerate the
transformation of texture coordinates. When hardware acceleration of
transformations isn't available, platform-specific optimizations in the
Direct3D geometry pipeline apply to texture coordinate transformations. Texture
coordinate transformations are useful for producing special effects while
avoiding the need to directly modify the texture coordinates of your geometry.
You could use simple translation or rotation matrices to animate textures on an
object, or you can transform texture coordinates that are automatically
generated by Direct3D to simplify and perhaps accelerate advanced effects such
as projected textures and dynamic light-mapping. Additionally, you might use
texture coordinate transforms to reuse a single set of texture coordinates for
multiple purposes, in multiple texture stages. For more information, see Using
Texture Coordinate Processing. Setting and Retrieving Texture Coordinate
Transformations [C++] Like the matrices that your application uses for
geometry, you set and retrieve texture coordinate transformations by calling
the IDirect3DDevice8::SetTransform and IDirect3DDevice8::GetTransform methods.
These methods accept the D3DTS_TEXTURE0 through D3DTS_TEXTURE7 members of the
D3DTRANSFORMSTATETYPE enumerated type to identify the transformation matrices
for texture stages 0 through 7, respectively. The following code sets a matrix
to apply to the texture coordinates for texture stage 0. // For this example,
the d3dDevice variable contains a // valid pointer to an IDirect3DDevice8
interface. // D3DMATRIX matTrans = D3DXMatrixIdentity( NULL ); // Set-up the
matrix for the desired transformation. d3dDevice->SetTransform( D3DTS_TEXTURE0,
&matTrans ); [Visual Basic] Like the matrices that your application uses for
geometry, you set and retrieve texture coordinate transformations by calling
the Direct3DDevice8.SetTransform and Direct3DDevice8.GetTransform methods.
These methods accept the D3DTS_TEXTURE0 through D3DTS_TEXTURE7 members of the
CONST_D3DTRANSFORMSTATETYPE enumeration to identify the transformation matrices
for texture stages 0 through 7, respectively. The following code sets a matrix
to apply to the texture coordinates for texture stage 0. ' For this example,
the D3DDevice variable contains a ' valid reference to a Direct3DDevice8
object, and ' dx contains a valid reference to a DirectX8 object. Dim matTrans
As D3DMATRIX Call D3DXMatrixIdentity( matTrans ) ' Set-up the matrix for the
desired transformation. D3dDevice.SetTransform( D3DTS_TEXTURE0, matTrans )
Enabling Texture Coordinate Transformations [C++] The
D3DTSS_TEXTURETRANSFORMFLAGS texture stage state controls the application of
texture coordinate transformations. Values for this texture stage state are
defined by the D3DTEXTURETRANSFORMFLAGS enumerated type. Texture coordinate
transformations are disabled when D3DTSS_TEXTURETRANSFORMFLAGS is set to
D3DTTFF_DISABLE (the default value). Assuming that texture coordinate
transformations were enabled for stage 0, the following code disables them. //
For this example, the d3dDevice variable contains a // valid pointer to an
IDirect3DDevice8 interface. D3dDevice->SetTextureStageState( 0,
D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); The other values defined in
D3DTEXTURETRANSFORMFLAGS are used to enable texture coordinate transformations,
and to control how many resulting texture coordinate elements are passed to the
rasterizer. For example, take the following code. // For this example, the
d3dDevice variable contains a // valid pointer to an IDirect3DDevice8
interface. D3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS,
D3DTTFF_COUNT2 ); The D3DTTFF_COUNT2 value instructs the system to apply the
transformation matrix set for texture stage 0, and then pass the first two
elements of the modified texture coordinates to the rasterizer. The
D3DTTFF_PROJECTED texture transformation flag indicates coordinates for a
projected texture. When this flag is specified, the rasterizer divides the
elements passed-in by the last element. Take the following code, for example.
// For this example, the d3dDevice variable contains a // valid pointer to an
IDirect3DDevice8 interface. d3dDevice->SetTextureStageState( 0,
D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3 | D3DTTFF_PROJECTED ); This
example informs the system to pass three texture coordinate elements to the
rasterizer. The rasterizer divides the first two elements by the third,
producing the 2- D texture coordinates needed to address the texture. [Visual
Basic] The D3DTSS_TEXTURETRANSFORMFLAGS texture stage state controls the
application of texture coordinate transformations. Values for this texture
stage state are defined by the CONST_D3DTEXTURETRANSFORMFLAGS enumeration.
Texture coordinate transformations are disabled when
D3DTSS_TEXTURETRANSFORMFLAGS is set to D3DTTFF_DISABLE (the default value).
Assuming that texture coordinate transformations were enabled for stage 0, the
following code example disables them. ' For this example, the D3DDevice
variable contains a ' valid reference to a Direct3DDevice8 object. Call
D3DDevice.SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, _
D3DTTFF_DISABLE) The other values defined in CONST_D3DTEXTURETRANSFORMFLAGS are
used to enable texture coordinate transformations, and to control how many
resulting texture coordinate elements are passed to the rasterizer. For
example, take the following code. ' For this example, the D3DDevice variable
contains a ' valid reference to a Direct3DDevice8 object. Call
D3DDevice.SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, _
D3DTTFF_COUNT2) The D3DTTFF_COUNT2 value instructs the system to apply the
transformation matrix set for texture stage 0, and then pass the first two
elements of the modified texture coordinates to the rasterizer. The
D3DTTFF_PROJECTED texture transformation flag indicates coordinates for a
projected texture. When this flag is specified, the rasterizer divides the
elements passed-in by the last element. Take the following code, for example. '
For this example, the D3DDevice variable contains a ' valid pointer to an
IDirect3DDevice8 interface. Call D3DDevice.SetTextureStageState(0,
D3DTSS_TEXTURETRANSFORMFLAGS, _ D3DTTFF_COUNT3 | D3DTTFF_PROJECTED) This
example informs the system to pass three texture coordinate elements to the
rasterizer. The rasterizer divides the first two elements by the third,
producing the 2- D texture coordinates needed to address the texture. Using
Texture Coordinate Processing [C++] The following list contains examples of
ways you might use texture coordinate processing to achieve special texturing
effects. Animating textures (by translation or rotation) on a model * Define
2-D texture coordinates in your vertex format. // Use a single texture, with
2-D texture coordinates. This // bit-pattern should be expanded to include
position, normal, // and color information as needed. DWORD dwFVFTex =
D3FVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0); * Configure the rasterizer to use 2-D
texture coordinates. SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS,
D3DTTFF_COUNT2); * Define and set an appropriate texture coordinate
transformation matrix. // M is a D3DMATRIX being set to translate texture //
coordinates in the U and V directions. // 1 0 0 0 // 0 1 0 0 // du dv 1 0 (du
and dv change each frame) // 0 0 0 1 D3DMATRIX M = D3DXMatrixIdentity(); //
declared in d3dutil.h M._31 = du; M._32 = dv; Creating texture coordinates as a
linear function of a model's camera-space position * Use the
D3DTSS_TCI_CAMERASPACEPOSITION flag to instruct the system to pass the vertex
position, in camera space, as input to a texture transformation. // The input
vertices have no texture coordinates, saving // bandwidth. Three texture
coordinates are generated by // using vertex position in camera space (x, y,
z). SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,
D3DTSS_TCI_CAMERASPACEPOSITION); * Instruct the rasterizer to expect 2-D
texture coordinates. // Two output coordinates are used.
SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2); * Define
and set a matrix that applies a linear function. // Generate texture
coordinates as linear functions // so that: // u = Ux*x + Uy*x + Uz*x + Uw // v
= Vx*x + Vy*x + Vz*x + Vw // The matrix M for this case is: // Ux Vx 0 0 // Uy
Vy 0 0 // Uz Vz 0 0 // Uw Vw 0 0 SetTransform(D3DTS_TEXTURE0, &M); Performing
environment mapping with a cubic environment map * Use the
D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR flag to instruct the system to
automatically generate texture coordinates as reflection vectors for cubic
mapping. SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,
D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR); * Instruct the rasterizer to expect
texture coordinates with three elements. SetTextureStageState(0,
D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3); Performing projective texturing
* Use the D3DTSS_TCI_CAMERASPACEPOSITION flag to instruct the system to pass
the vertex position as input to a texture transformation matrix.
SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION);
* Create and apply the texture projection matrix. This is beyond the scope of
this documentation, and is the topic of several industry articles. * Instruct
the rasterizer to expect three-element projected texture coordinates. // Two
output coordinates are used. SetTextureStageState(0,
D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTF_PROJECTED | D3DTTFF_COUNT3); [Visual
Basic] The following list contains examples of ways you might use texture
coordinate processing to achieve special texturing effects. Animating textures
(by translation or rotation) on a model * Define 2-D texture coordinates in
your vertex format. ' Use a single texture, with 2-D texture coordinates. This
' bit-pattern should be expanded to include position, normal, ' and color
information as needed. lFVFTex = (D3FVF_TEX1 Or D3DFVF_TEXCOORDSIZE2(0)) *
Configure the rasterizer to use 2-D texture coordinates.
SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2) * Define
and set an appropriate texture coordinate transformation matrix. ' M is a
D3DMATRIX being set to translate texture ' coordinates in the U and V
directions. ' 1 0 0 0 ' 0 1 0 0 ' du dv 0 0 (du and dv change each frame) ' 0 0
0 0 dx.IdentityMatrix(M) M.rc31 = du M.ec32 = dv Creating texture coordinates
as a linear function of a model's camera-space position * Use the
D3DTSS_TCI_CAMERASPACEPOSITION flag to instruct the system to pass the vertex
position, in camera space, as input to a texture transformation. ' The input
vertices have NO texture coordinates, saving ' bandwidth. Three texture
coordinates are generated by ' using vertex position in camera space (x, y, z).
SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION) *
Instruct the rasterizer to expect 2-D texture coordinates. ' Two output
coordinates are used. SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS,
D3DTTFF_COUNT2) * Define and set a matrix that applies a linear function. '
Generate texture coordinates as linear functions ' so that: ' u = Ux*x + Uy*x +
Uz*x + Uw ' v = Vx*x + Vy*x + Vz*x + Vw ' The matrix M for this case is: ' Ux
Vx 0 0 ' Uy Vy 0 0 ' Uz Vz 0 0 ' Uw Vw 0 0 SetTransform(D3DTS_TEXTURE0, M)
Performing environment mapping with a cubic environment map * Use the
D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR flag to instruct the system to
automatically generate texture coordinates as reflection vectors for cubic
mapping. SetTextureStageState(0, D3DTSS_TEXCOORDINDEX,
D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR) * Instruct the rasterizer to expect
texture coordinates with three elements. SetTextureStageState(0,
D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT3) Performing projective texturing *
Use the D3DTSS_TCI_CAMERASPACEPOSITION flag to instruct the system to pass the
vertex position as input to a texture transformation matrix:
SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_CAMERASPACEPOSITION) *
Create and apply the texture projection matrix. This is beyond the scope of
this documentation, and is the topic of several industry articles. * Instruct
the rasterizer to expect three-element projected texture coordinates. ' Two
output coordinates are used. SetTextureStageState(0,
D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTF_PROJECTED | D3DTTFF_COUNT3) Texture
Resources This section presents information on creating and rendering with
texture interface pointers. The information is organized in the following
topics. * Obtaining a Texture Surface Object * Rendering with Texture Resources
Obtaining a Texture Surface Object [C++] Texture resources are implemented in
the IDirect3DTexture8 interface. To obtain a pointer to a texture interface,
call the IDirect3DDevice8::CreateTexture method or any of the following D3DX
functions. * D3DXCreateTexture * D3DXCreateTextureFromFileA *
D3DXCreateTextureFromFileExA * D3DXCreateTextureFromFileExW *
D3DXCreateTextureFromFileInMemory * D3DXCreateTextureFromFileInMemoryEx *
D3DXCreateTextureFromFileW * D3DXCreateTextureFromResourceA *
D3DXCreateTextureFromResourceExA * D3DXCreateTextureFromResourceExW *
D3DXCreateTextureFromResourceW The following code example uses
D3DXCreateTextureFromFileA to load a texture from Tiger.bmp. // The following
code example assumes that d3dDevice // is a valid pointer to an
IDirect3DDevice8 interface. LPDIRECT3DTEXTURE8 pTexture;
D3DXCreateTextureFromFile( d3dDevice, "tiger.bmp", &pTexture); The first
parameter that D3DXCreateTextureFromFile accepts is a pointer to a
IDirect3DDevice8 interface. The second parameter tells Microsoft® Direct3D® the
name of the file from which to load the texture. The third parameter takes the
address of a pointer to a IDirect3DTexture8 interface, representing the created
texture object. [Visual Basic] Texture resources are implemented in the
Direct3DTexture8 class. To obtain a texture object, call the
Direct3DDevice8.CreateTexture method or any of the following D3DX functions. *
D3DX8.CreateTexture * D3DX8.CreateTextureFromFile *
D3DX8.CreateTextureFromFileEx * D3DX8.CreateTextureFromFileInMemory *
D3DX8.CreateTextureFromFileInMemoryEx * D3DX8.CreateTextureFromResource *
D3DX8.CreateTextureFromResourceEx The following code example uses
D3DX.CreateTextureFromFile to load a texture from Tiger.bmp. ' ' The following
code example assumes that d3dDevice ' is a valid Direct3DDevice8 object and
that g_D3DX is a valid ' D3DX8 object. ' Dim Texture As Direct3DTexture8 Set
Texture = g_D3DX.CreateTextureFromFile( d3dDevice, App.Path + "\tiger.bmp" )
The first parameter that CreateTextureFromFile accepts is a Direct3DDevice8
object. The second parameter tells Microsoft® Direct3D® the name of the file
from which to load the texture. This method returns a texture object, which is
assigned to Texture. Rendering with Texture Resources Microsoft® Direct3D®
supports multiple texture blending through the concept of texture stages. Each
te