Sign in to follow this  

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

This topic is 4342 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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!!!

Share this post


Link to post
Share on other sites

This topic is 4342 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this