mozzis's picture

TextPrinter seems slow

OpenTK: 0.9.9.1
Graphics Card: GForce 8400M GS
OS: Vista Business 64-bit
4.00 Gb RAM Core 2 Duo T7500 @ 2.2 GHz Experience Index 4.1
C# in Visual Studio 2008 Pro.

Thanks for the help with text positioning, I have that working now. I appreciate the simplicity of using TextPrinter.
I have noticed that my drawing is significantly slower when I draw the labels on graph tick marks. I am drawing 12 labels on each of 3 axes, typical label value is "1.40". The drawing is about half as fast with the labels as without. The label drawing code (for one axis) is below. Any suggestions?

		public void Draw(Color clr)
		{
			int nSize = _Values.Count;
			float fWidth = _Parent.ParentView.ClientSize.Width;
			float fHeight = _Parent.ParentView.ClientSize.Height;
			GL.PushMatrix();
			for (int nIx = 0; nIx < nSize; nIx++)
			{
				String lbl = _Values[nIx].ToString("F2");
				int nLen = lbl.Length;
				GL.LoadIdentity();
				Point3D point = _Pos[nIx] + _Parent.CenterOffset;
				GL.Translate(point.X, point.Y, point.Z);
				GL.Scale(2 / fWidth, 2 / fHeight, 1);
				tp.Print(lbl, _Font, clr);
			}
			GL.PopMatrix();
		}

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
the Fiddler's picture

TextPrinter does have an effect on performance, but I've generally found it adequate even on low-end hardware. Half as fast is a little nebulous: there's a difference between dropping from 600fps to 300fps and dropping from 30fps to 15fps (which is why it's generally better to measure frame time instead of frame rate) . Do you have any concrete frame times or rates with and without text printing?

Text printing is relatively fast (peak rate of ~1M glyphs/sec on a 8400M), but TextPrinter.Print() itself is a relatively slow call. It has to modify OpenGL state, construct objects on the stack and access Dictionaries before drawing the text. 36 Print calls is on the high side, but it should be manageable.

Another thing to keep in mind is that TextPrinter tries to create display lists for each string you pass. This is nice if your strings do not change every frame, but it also means you should specify TextPrinterOptions.NoCache if they do change every frame.

mozzis's picture

Sorry for the nebulosity before; I have quantified things and am puzzled by the results.

                                24 Vertices                            8M Vertices
No Labels                         0.0003                                   0.12
Labels                            0.05                                     0.55

So the time to draw the labels depends on the number of vertices in the model! This seems counterintuitive at best.

The difference in speed with the cube (24 verts) is enough to make the normal rotate and pan operations noticeably jerky with text on; with text off, it is very smooth.

How difficult would it be to provide an analog of VertexPointer where the caller provided an array of strings and an array of coordinates? That way, the setup/tear down time per string might be less.

the Fiddler's picture

Are those results in seconds? 0.12 seconds to render a 24-vertex model is way too high (less than 10fps?) This is probably an artifact of the timing code - hard to say what the exact cause is without the timing code or some profiling data (timing OpenGL/DirectX is notoriously hard to get right).

The array-of-strings/coordinates idea is excellent! Never thought of that before, but it is simple to implement and can potentially improve performance.

The only issue is that I simply don't have the resources to add new features to the TextPrinter anymore. I will still fix any bugs that arise, but the TextPrinter is in need of a dedicated developer who can adapt it and improve it further. (The code is pretty simple, actually, with the most complex parts trying to work around GDI+ bugs and performance issues.)

mozzis's picture

The results are in seconds. They are reported by the Stopwatch object, which also reports that it has < 70 ns resolution. I use the Stopwatch.Start at the start of my Paint routine and Stopwatch.Stop at the end and report the difference to the status bar. I know it would be better to average but I have an auto-rotate function and can see the values bounce around the reported ones.

I'd be willing to take a look at the TextPrinter code. I have more GDI experience than I do OpenGL but I can surely look at performance/convenience issues with occasional guidance.