Direct3D IM

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

 

X-Zone's DirectX FAQ
Direct3D Immediate Mode

Direct3D Immediate Mode

Why do my pre-lit vertices appear black under DirectX 7?

Why are my Indexed Primitive calls so slow?

My existing application successfully renders with the DrawPrimitive method, but when I started using the Direct3DDevice3 Interface, the primitives are not rendered properly.  Why?

Why are some or all of my triangles are not visible when I render them?

My world matrix scales an item, and the normals are scaled as well.  How can I prevent this from affecting my lighting?

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

Q. Why are some or all of my triangles are not visible when I render them?

A common reason for this is that the winding order of the triangles is incorrect.  By default, any triangle that would be drawn counterclockwise, after transformation to the camera view, is ignored.  This increases the performance of the rasterizer and prevents artifacts from backfaces by eliminating any triangles that are facing away from the viewer.

If this is the problem, you will have to swap two of the to reverse the winding order.  For a quick test to see if this is the problem, try turning off culling prior to rendering:

lpDevice->SetRenderState(D3DRENDERSTATE_CULLMODE,D3DCULL_NONE);

Back to the Top    Back to Main Index

Q.  Why do my pre-lit vertices appear black under DirectX 7?

When the lighting engine is enabled, which is the default, the color values of processed vertices will be set according to the normal provided for each vertex.  In the case of a D3DLVERTEX, there is no normal provided, since you have already calculated your own lighting values.  However, DirectX will try to light them anyway, and in the absence of a normal vector will set the color to black.

To prevent this, you must explicitly turn off lighting prior to rendering pre-lit primitives.  Unlike previous versions of DirectX, where a flag could be provided during rendering, there is now a render state which enables or disables lighting operations:

lpDevice->SetRenderState(D3DRENDERSTATE_LIGHTING,FALSE);

Back to the Top    Back to Main Index

Q. Why are my Indexed Primitive calls so slow?

Note: The following information is based on D3DIM 7.  Under DirectX 8, the DrawIndexedPrimitive command allows you to specify a starting vertex and number of vertices use.  By restricting this to the range used in a rendering call, only those vertices get processed.

In most postings I see of this nature, there is a common thread : A) There are a large number of vertexes overall, but B) each call to DrawIndexedPrimitive() is only  drawing a few polygons.

The reason that these operations appear to have huge performance penalties is because each call to DrawIndexedPrimitive() will transform all of the vertices in the list, regardless of which are actually utilized.  For example, take a moment to consider the following code :

for (int i=0;i<1000;i+=4)
        lpDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_VERTEX,
                                       verts,1600,index+i,4,0)

That code will render a total of  500 polygons, which is quite reasonable... However, in doing so, it will transform all 1600 vertexes in the "verts" array 250 times - that means 400,000 transformations per frame!  To be able to sustain 30 FPS at that kind of load would mean the CPU has to transform 12 Million transformations each second.

To avoid this, only pass the vertexes you will be using, and batch your primitives together if possible - approximately 100 triangles per call is optimal.  The benefit of batching is significant, and is worth breaking your object into a single triangle list if it consists of many small triangle strips.

Back to the Top    Back to Main Index

Q. My existing application successfully renders with the DrawPrimitive method, but when I started using the Direct3DDevice3 Interface, the primitives are not rendered properly.  Why?

The vertex description parameter of the DrawPrimitive functions has changed with the introduction of the flexible vertex format in DirectX 6.0 and above.  For example, if you previously specified a vertex type flag of D3DVT_LVERTEX, you will now need to use a value of D3DFVF_LVERTEX instead.  For a complete listing of the flexible vertex format flags, refer to the DirectX documentation for the DrawPrimitive method.

Back to the Top    Back to Main Index

Q. My world matrix scales an item, and the normals are scaled as well.  How can I prevent this from affecting my lighting?

This can be achieved in one of two ways:

1. Scale the length of your normals by the reciprocal of the scaling factor.  For example, if an object is scaled to 5 times it's size, then multiply the normals by 1/5, or 0.2.

2. Set the D3DRENDERSTATE_NORMALIZENORMALS to TRUE.  This will cause normals to be normalized (set to a length of 1.0) after transformation into camera space.  Note that this can be computationally expensive.

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.