WPF Control has slow performance on high polycount

Jul 1, 2013 at 10:33 PM
Edited Jul 1, 2013 at 10:35 PM
I'm currently working on a project with a team of people in which we have to load a few 3D models from various file formats (.obj, .fbx, etc.) and display them in a Autodesk style 3D application. After getting the basics of OpenGL and SharpGL, we managed to load and display the models without texturing and lighting; however, the frame rate stays consistently below 10. Our models have an average polycount of about 20000 triangles. One model brings SharpGL to its knees. Here's a view of our OpenGL draw method (a lot of the code is commented out from testing):
            OpenGL gl = args.OpenGL;
            //  gl.LoadIdentity();
            // OpenFileDialog openDialog = new OpenFileDialog();
            // openDialog.Filter = SerializationEngine.Instance.Filter;

            //  Clear and load the identity.
            //For color differentiation
            gl.ClearColor(Colors.CornflowerBlue.ScR, Colors.CornflowerBlue.ScG, Colors.CornflowerBlue.ScB, Colors.CornflowerBlue.ScA);
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
            gl.LoadIdentity();
            //PerspectiveCamera camera = new PerspectiveCamera();
            //camera.AspectRatio = 4.0 / 3.0;
            //camera.Near = 1;
            //camera.Far = 10000;
            //camera.Position = camPosition;
            //camera.Project(gl);

            //  View from a bit away the y axis and a few units above the ground.
            //gl.LookAt(15f, -10f, 10f, 0f, 0f, 0f, 0f, 1f, 5f);
            gl.Enable(OpenGL.GL_CULL_FACE);
            if (camera != null)
            {
                if (camera is LookAtCamera)
                {
                    (camera as LookAtCamera).Target = camTarget;
                    (camera as LookAtCamera).UpVector = new Vertex(0, 0, 1);
                }
                camera.Position = camPosition;
                camera.AspectRatio = 4.0 / 3.0;
                camera.Project(gl);
            }
            //gl.LookAt(camPosition.X, camPosition.Y, camPosition.Z, camTarget.X, camTarget.Y, camTarget.Z, 0, 0, 1);

            //  Rotate the objects every cycle.
            //gl.Rotate(fRotate, 0.0f, 0.5f, 3.0f);

            //  Move the objects down a bit so that they fit in the screen better.
            //gl.Translate(0, 0, -1);

            //  Draw every polygon in the collection.
            displayGrid.Render(gl, RenderMode.Design);

            foreach (Model model in SceneManager.Models)
            {
                model.PushObjectSpace(gl);
                if (model.Compare(SelectedSceneElement as Polygon) == 0)
                {
                    model.BoundingVolume.Render(gl, RenderMode.Render);
                }
                model.Render(gl, SharpGL.SceneGraph.Core.RenderMode.Render);
                //displayGrid.Render(gl, RenderMode.Render);
                model.PopObjectSpace(gl);
            }
We're created our own Model class which inherits from Polygon. While experimenting with OpenTK, we managed to get a consistent 30+ FPS with basically the same code even while using immediate mode and no shaders. Here's a snippet of our render method:
 Face[] faceArray = this.Faces.ToArray();

            gl.Begin(BeginMode.Triangles);

            foreach (Face face in faceArray)
            {
                face.Material.Push(gl);
                Index[] indexArray = face.Indices.ToArray();
                foreach (Index index in indexArray)
                {
                    try
                    {
                        UV uv = UVs[index.UV];

                        //gl.Color(ModelColor);
                        gl.Vertex(Vertices[index.Vertex]);
                        gl.TexCoord(uv.U, 1 - uv.V);
                        gl.Normal(Normals[index.Normal]);
                    }
                    catch
                    {
                        continue;
                    }
                }
                face.Material.Pop(gl);
            }
            gl.End();
We're running on Intel Core i5 3570 (no dedicated graphics on some, nvidia 9800GT on others), so I don't think its a hardware issue. We compiled in Release mode and ran it outside of VS2012 with no change. FBO render context is applied to the control, so there are no issues there. As I said before, we ran this in OpenTK without any issues; since SharpGL provides a nice object-oriented style framework for meshes, textures, and raytracing, we decided to use it. Any help would be greatly appreciated!
Jul 12, 2013 at 10:38 AM
Edited Jul 12, 2013 at 10:51 AM
I had the same trouble. Each 16 miliseconds (60 fps) you are sending 20k verticies from RAM to GPU through the PCI Expess bus. Use VAO and VBO buffers to store your model data, such vertecies positions,normals,uvs into GPU memory. And couple of shaders (vertex and fragment shaders) will help you to increase performance. I made project that can load models with over 500k triangles and shade them with phong shading and got 60 fps.
Aug 13, 2013 at 12:03 PM
In my simple applications, even FBO is still very slow with modest hardware. Using NativeWindow might help, see - https://sharpgl.codeplex.com/discussions/439223