Optimizing Your Geometry Handling

[Previous] [Next]

In this section, I'll cover some key issues you need to consider when you're designing the geometry and rendering features of your 3D world.

ComputeSphereVisibility

You should use IDirect3DDevice7::ComputeSphereVisibility to check the visibility of objects. This method calculates the visibility (complete, partial, or none) of an array of spheres within the current viewport of a device. If an object is not visible, there's no need to waste time submitting it to Direct3D for rendering. Direct3D computes sphere visibility by back-transforming the viewing frustum to the model space. This technique is performed using the inverse of the combined world, view, or projection matrices. If the combined matrix can't be inverted (if the determinant is 0), the method will fail, returning D3DERR_INVALIDMATRIX.

Vertex Buffers

By using DrawPrimitiveVB and DrawIndexedPrimitiveVB rather than their non-vertex buffer counterparts, you can minimize data copying and speed up rendering, especially when multitexturing or using a Direct3D device that supports transformation and lighting in hardware. You should also use vertex indexing, triangle strips, and triangle fans where appropriate to share vertices and therefore save time in the T&L pipeline.

Batching DrawPrimitive Calls

To reduce CPU overhead, use efficient batching by reducing the number of primitive-drawing calls you make. Calling DrawPrimitive once for each triangle in your scene is the worst thing you can do for performance! You can improve performance by sending all the triangles with the same attributes (texture and render state) in one call. If the lists are too large, however, you won't always see improvements in speed by sending lists of triangles together.

You should usually break your rendering jobs into chunks of about 100 triangles at a time because you need to consider the bus, processor, and multiple pipelines. For example, if the 3D pipelines are forced to wait idly while the processor transforms thousands of vertices and then transfers them over, when the 3D processor acts on the data, the CPU will be finished and will be idle while the accelerator works.

Floating-Point Precision and Multithread SetCooperativeLevel Flags

In DirectX 7, using the floating-point unit (FPU) control and multithread SetCooperativeLevel flags will reduce internal overhead. If your program never changes the floating-point precision level, set the DDSCL_FPUSETUP flag when calling SetCooperativeLevel so that Direct3D doesn't have to check the precision level every time it uses the FPU. If your program uses multiple threads, set the DDSCL_MULTITHREADED flag. If you have a single-threaded program, don't set this flag, and Direct3D will reduce its thread-synchronization overhead.

Guard-Band Clipping

Guard-band clipping helps increase performance by offloading clipping from software. When your code checks the boundaries to clip primitives to, it doesn't need to send primitives that are outside the viewport for rendering. The D3DDEVICEDESC7 structure queries the current device with methods such as IDirect3DDevice7::GetCaps. The members applicable to guard-band clipping are dvGuardBandLeft, dvGuardBandTop, dvGuardBandRight, and dvGuardBandBottom. These members define the screen-space coordinates of the guard-band clipping region. Direct3D will automatically clip any coordinates inside this rectangle but outside the viewport rectangle.

Texture-Type Hints

DirectX 7 offers the STATIC, DYNAMIC, and OPAQUE texture-type hints. Using these texture-type hints when creating textures will allow the renderer to make the most efficient possible use of textures.



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

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