[MDX][VB .NET 2003] - Faster way to draw triangles

Started by
1 comment, last by MisterHeadache 18 years, 2 months ago
I'm working on a large project, a map file editor for first person shooters. I've gotten my core rendering code to run great, so now I'm after speed optimizations. Here is a sample of how I'm rendering the map brushes:

If Me.m_bDrawWorld Then
            For i = 0 To Me.m_map.m_WorldSpawn.BrushCount - 1
                Dim b As CBrush = Me.m_map.m_WorldSpawn.f_GetBrushByIndex(i)
                distance = Math.Abs(Vector3.Length(Vector3.Subtract(b.m_Origin, Me.m_Position)))
                If Me.f_SphereInFrustum(b.m_Origin, b.p_BoundingRadius) And b.p_BoundingRadius > distance * C_SMALLOBJECT Then
                    Dim face As CFace
                    Select Case renderMode
                        Case ERenderMode.Textured
                            For Each face In b.m_Faces
                                device.SetTexture(0, Me.m_TextureManager.f_GetTexture(face.p_TextureName))
                                If face.p_Selected Then
                                    device.VertexFormat = CustomVertex.PositionColoredTextured.Format
                                    device.DrawUserPrimitives(pType, face.m_Vertices.Length - iCount, face.m_SelectedTextureVertices)
                                ElseIf face.p_PreSelected Then
                                    Dim v() As CustomVertex.PositionColoredTextured
                                    device.VertexFormat = CustomVertex.PositionColoredTextured.Format
                                    face.s_GetPreSelectedVertices(v)
                                    device.DrawUserPrimitives(pType, face.m_Vertices.Length - iCount, v)
                                Else
                                    device.VertexFormat = CustomVertex.PositionTextured.Format
                                    device.DrawUserPrimitives(pType, face.m_Vertices.Length - iCount, face.m_TextureVertices)
                                End If
                            Next
                        Case Else
                            For Each face In b.m_Faces
                                device.VertexFormat = CustomVertex.PositionNormalColored.Format
                                device.DrawUserPrimitives(pType, face.m_Vertices.Length - iCount, face.m_Vertices)
                            Next
                    End Select

                End If
            Next
        End If

As you can see, I'm using basic view frustum culling along with a filter to discard distant objects before rendering. However, I'm calling the "DrawUserPrimitives()" method with each repaint of my panel, probably not the best way to do this. So, I was considering rewriting to use a vertex buffer, but my big question is this: when the user moves the camera, objects come into the view frustum and leave the view frustum, so do I rebuild the vertex buffer each movement? If so, that doesn't sound like it would offer any speed improvements. Or...should I put ALL of my vertices into the buffer and reference by index only those objects that are visible within the current view frustum, thus only asking DirectX to render the ones that are within the frustum? EDIT: 'source' tags are better than 'code' tags in this instance. 'code' tags are preferred for short 3-4 line fragments. Thanks! [Edited by - jollyjeffers on January 27, 2006 5:25:00 AM]
Advertisement
It will be significantly faster to put the vertices in a buffer and render the buffer (or portions thereof). If all you're using is static objects (non-moving), you won't need to update the vertex buffer. If you're using dynamic objects, you can create a dynamic vertex buffer which can have individual portions easily written over. To update the vertices's position due to movement, all you need to do is change the world transformation on the device (regardless of how you build the vertex buffer).

Drawing every object individually without a vertex buffer is going to cost a lot of overhead. One of the biggest slowdown times for the renderer is loading the vertex buffer (whether you create it manually or create it through DirectX drawing functions) into the video card; the preferred way is to load one buffer with as many different objects as possible, then just specify which vertices to render. What you're doing is loading a new buffer every time.

Not only that, but you're rendering every face of each object.... That means for EVERY triangle, a new vertex buffer is being loaded, causing some severe slowdowns. DirectX may be optimizing it a bit under the hood, but it's still going to be far less efficient than just building one vertex buffer and rendering it in parts (it stays in the video card's cache and therefore is not reloaded on every draw command).
Quote:Original post by MisterHeadache
Or...should I put ALL of my vertices into the buffer and reference by index only those objects that are visible within the current view frustum, thus only asking DirectX to render the ones that are within the frustum?


WOW, what a speed difference!

Quoting my idea - I recoded the section for the world brushes just this way and the render time dropped by about 2.5X! Vertex buffers are the boss, man!!!

This topic is closed to new replies.

Advertisement