DirectX 8 Graphics FAQ

Home | Up | Search | X-Zone News | Services | Book Support | Links | Feedback | Smalltalk MT | The Scrapyard | Technical Articles

 

X-Zone's DirectX FAQ
DirectX 8 Graphics

DirectX 8 Graphics

After installing the DX 8 SDK, I receive the error LNK1104: Cannot Open File "d3dim.lib" when attempting o compile my program.

I am using Direct3D to draw a tile map to the screen.  Why can't get the edges to match properly?

When I use the D3DX shape creation functions to generate a mesh, there are no texture coordinates in the vertices.  How can I set texture coordinates?

How can I render to multiple windows under DirectX 8 Graphics?

When loading a texture with the D3DX texture creation functions I specify a color key, but no transparency appears when I render the image.

I am rendering alpha blended polygons and setting the alpha of the diffuse vertex component to determine the opacity.  It works when there is no texture set, but as soon as I set a texture the alpha that I set is no longer applied.  Why?

Why does rendering of pre-transformed vertices appear to be slower in DX 8?

Why does rendering of an ID3DXMesh object slow down significantly after I define subsets?

Why doesn't Intellisense offer code completion options for DX 8 interfaces under VC++?

Will applications that I compile with the DirectX 8.1 SDK be compatible with systems  with the DirectX 8.0 runtimes?

I have heard that DirectX 8.1 no longer supports Windows 95.  Can I compile applications compatible with Windows 95 if I have the DirectX 8.1 SDK installed?

Why do my calls to IDirect3DDevice8::Getxxxx fail?

When I draw an image using ID3DXSprite::Draw() with 1:1 scaling, the sprite is different than the original image size.  Why?

Why does my programmable vertex shader fail during creation on some hardware?

Q. After installing the DX 8 SDK, I recieve the error LNK1104: Cannot Open File "d3dim.lib" when attempting o compile my program.

After installing the DirectX 8 SDK, you may recieve the following error when compiling existing source code written for previous versions of DirectX:

LINK : fatal error LNK1104: cannot open file "d3dim.lib"

This is because the library for Direct3D Immediate Mode (now called DirectGraphics) has been renamed as D3D8.LIB.  To correct this, link to D3D8.LIB instead of D3DIM.LIB.

Back to the Top    Back to Main Index

Q. I am using Direct3D to draw a tile map to the screen.  Why can't get the edges to match properly?

This is due to the algorithm used to determine what pixels to draw when rendering a triangle, which is determined by whether the center of each pixel is enclosed by the triangle.  The pixel centers lie on integer values, so if you are using integer coordinates to define a rectangle the sides will straddle pixels.

To account for this, expand your pre-transformed primitives by 0.5 pixels in each direction.  For an example of this, look at the source code in A Simple Blit Function for Direct3D.

Back to the Top    Back to Main Index

Q. When I use the D3DX shape creation functions to generate a mesh, there are no texture coordinates in the vertices.  How can I set texture coordinates?

To add texture coordinates, you will first have to use the D3DXCloneMeshFVF function to create a duplicate of the mesh with a new vertex format which contains elements for storing texture coordinates (tu,tv).  For an example of how to do this, take a look at the source code in Spherical Texture Mapping.

Back to the Top    Back to Main Index

Q. How can I render to multiple windows under DirectX 8 Graphics?

This can be accomplished by creating a swap chain for each window, using IDirect3DDevice8::CreateAdditionalSwapChain(), then setting the appropriate chain's frame buffer as the render target before rendering.

For more information, see Rendering to Multiple Windows.

Back to the Top    Back to Main Index

Q. When loading a texture with the D3DX texture creation functions I specify a color key, but no transparency appears when I render the image.

Color keying is not directly supported in DirectX 8, transparency instead being handled through alpha blending.  If you need to render color keyed images with transparency, the D3DX texture creation functions bridge the gap by automatically generating an alpha mask that culls out pixels of a specified color.

There are a couple of reasons that this may occur.  Probably the most common error is in specifying a key color with an alpha of zero.  Since bitmaps are assumed to be opaque, all pixel values read from the file will be assigned an alpha of 255.  Unless the key color has a matching alpha value, the color key test will fail.  You can prevent this by using a color function that allows you to specify alpha, or by OR'ing your color value with 0xff000000.

The other reason that color keying may fail is that the proper alpha blending states have not been set.  The following should be set prior to rendering to achieve transparency:

pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
pDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
pDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);

Back to the Top    Back to Main Index

Q. I am rendering with alpha blending and setting the alpha of the diffuse vertex component to determine the opacity.  It works when there is no texture set, but as soon as I set a texture the alpha that I set is no longer applied.  Why?

The problem originates in the texture blending stages, rather than in the subsequent alpha blending.  Alpha can come from several possible sources.  If this has not been specified, then the alpha will be taken from the texture, if one is selected.  If no texture is selected, then the default will use the alpha channel of the diffuse vertex component.

Explicitly specifying the diffuse vertex component as the source for alpha will insure that the alpha is drawn from the alpha value you set, whether a texture is selected or not:

pDevice->SetTextureStageState(D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
pDevice->SetTextureStageState(D3DTSS_ALPHAARG1,D3DTA_DIFFUSE);

If you later need to use the texture alpha as the source, set D3DTSS_ALPHAARG1 to D3DTA_TEXTURE.

Back to the Top    Back to Main Index

Q. Why does rendering of pre-transformed vertices appear to be slower in DX 8?

Unlike previous versions of Direct3D, DirectX Graphics 8 clips pre-transformed vertices by default.  To prevent this, set D3DRS_CLIPPING to FALSE before rendering pre-transformed vertex formats.

Back to the Top    Back to Main Index

Q. Why does rendering of an ID3DXMesh object slow down significantly after I define subsets?

You probably have not optimized the mesh after defining the face attributes. If you specify attributes and then call ID3DXMesh::DrawSubset(), this method must perform a search of the mesh for all faces containing the requested attributes.  In addition, the rendered faces are likely in a random access pattern, thus not utilizing vertex cache.  After defining the face attributes for your subsets, call the ID3DXMesh::Optimize or ID3DXMesh::OptimizeInPlace methods with the D3DXMESHOPT_ATTRSORT flag.  See Creating Subsets in ID3DXMesh for more information.

Back to the Top    Back to Main Index

Q. Why doesn't Intellisense offer code completion options for DX 8 interfaces under VC++?

The problem is that the IDE is drawing its information from the older headers that were installed with VC++.  It will also use information from the headers in your project files, though simply using #include does not cause them to be inventoried from the new headers.  You can enable Intellisense with the new interface by adding the header files containing the definitions to your project (e.g. D3DX8.H and D3D8.H for Direct3D).  Right click on your project in the FileView pane, select "Add Files to Project...", then select the necessary include files from the DXSDK\INCLUDE\ directory.

Back to the Top    Back to Main Index

Q. Will applications that I compile with the DirectX 8.1 SDK be compatible with systems  with the DirectX 8.0 runtimes?

By default, applications compiled under 8.1 will require the 8.1 runtimes to run, because some of the interfaces have changed and have different GUIDs.  However, you can specify a constant when creating the Direct3D object that will use the 8.0 interfaces.  Rather than creating an object as shown in the docs with

g_pD3D=Direct3DCreate8(D3D_SDK_VERSION);

instead use

g_pD3D=Direct3DCreate8(120);

The value 120 is equal to the D3D_SDK_VERSION that was specified in the DirectX 8.0 headers, which has been changed in the 8.1 SDK.  Specifying the original value will cause 8.0 version interfaces to be used by Direct3D, providing compatibility with 8.0.  Note that new features in 8.1, such as the latest pixel shader versions (1.2 - 1.4), will not be available.

Back to the Top    Back to Main Index

Q. I have heard that DirectX 8.1 no longer supports Windows 95.  Can I compile applications compatible with Windows 95 if I have the DirectX 8.1 SDK installed?

The DirectX 8.1 interfaces require Windows 98 or higher, and will thus not be available on Windows 95.  However, you can force applications compiled under the DirectX 8.1 SDK to use the 8.0 interfaces, allowing for Windows 95 compatibility.  For information on how to specify creation of 8.0 interface explicitly, go here.

Back to the Top    Back to Main Index

Q. Why do my calls to IDirect3DDevice8::Getxxxx fail?

This usually occurs when using a pure device, that is, a device created with the D3DCREATE_PUREDEVICE flag.  Such a device does not support any of the Get*() functions for any values that can be stored in state blocks.

Back to the Top    Back to Main Index

Q. When I draw an image using ID3DXSprite::Draw() with 1:1 scaling, the sprite is different than the original image size.  Why?

Since the image file is loaded into a texture, the bitmap is scaled to match the capabilities of the hardware. In general, this means that images that have dimensions that are not powers of 2 will be scaled up to the nearest power of 2.

When loading an image with D3DXCreateTextureFromFileEx(), you can pass a pointer to a D3DXIMAGE_INFO structure, which will be filled with information about the source image. You can then get the size of the texture using IDirect3DTexture::GetLevelDesc() and calculate the required scaling factor for 1:1 rendering:

LPDIRECT3DTEXTURE8 pText;
D3DXIMAGE_INFO info;
D3DXCreateTextureFromFileEx(....,&info,....,&pText);
D3DSURFACE_DESC desc;
pText->GetLevelDesc(0,&desc);
D3DXVECTOR2 vScaling;
vScaling.x=info.Width/desc.Width;
vScaling.y=info.Height/desc.Height;

Back to the Top    Back to Main Index

Q. Why does my programmable vertex shader fail during creation on some hardware?

This may be because the device created by your application is using hardware vertex processing, but the video hardware or driver does not support the programmable vertex shader execution in hardware, or does not implement the version of vertex shader code required by your shader.  To prevent this, you should check for vertex shader support when evaluating devices that use hardware vertex processing.  For example, if you are implementing a vertex shader that requires Version 1.0 support, you would add the following to the ConfirmDevice() code (assuming you are using the D3DApp framework):

if( (dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING ) ||
    (dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING ) )
{
    if( pCaps->VertexShaderVersion < D3DVS_VERSION(1,0) )
        return E_FAIL;
}

You do not need to perform this check on devices using software vertex processing, as shader support is guaranteed through emulation.

Back to the Top    Back to Main Index

This site, created by DirectX MVP Robert Dunlop and aided by the work of other volunteers, provides a free on-line resource for DirectX programmers.

Special thanks to WWW.MVPS.ORG, for providing a permanent home for this site.

Visitors Since 1/1/2000: Hit Counter
Last updated: 07/26/05.