My program is a 3D Spectrum processor which will show signal strength(y) vs frequency(x) vs time (z). It essentially plots a 3d height map, the height of the vertices corresponding to signal strength. The basic program flow is to create a height map with fixed x and z coordinates, and calculate the indices. After this, new Y coordinates are obtained and the whole 3D surface updated using a GL.BufferSubData call. Basically new spectral data comes in, it is placed in front of all the other, and the rest is moved towards the back with a circular buffer. The data processing for the new data is fairly quick, taking about 20ms.
Now the amount of data is fairly large. I plot 2048 points and I have 50 - 100 rows of this. So about 100,000 to 200,000 vertices. These are all plotted with a single GL.DrawElements with a VBO for the vertices and a VBO for the indices.
Now, I have a test program which generates the vertices and signals to the openGL program if data is available. If it does it transfers the data into the vertex array. If no more sdata is available it just draws.
The drawing seems to be very slow but I am not sure I am asking for too much. We need to draw about 300,000 triangles, and shade them with a 2D shader which basically only uses the height of the vertices to pick a color.
So I am seeing on a quad core Core i7 at 2.3 GHz with a nVidia 540m graphics card about 150 ms per frame. This is quite slow. The speed improves considerable if I make the window small and gets worse if it is full screen.
Am I expecting too much here? Or do I have an issue in my code?
Here is the problem statement. Why is the program so slow?
I am using c# with the opengl4Csharp libraries.
Here is the code: The GLUT idle callback has this:
Gl.Viewport(0, 0, width, height);
Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
// use our vertex shader program
Gl.UseProgram(plottingProgram);
Gl.BindTexture(myTexture); //this is the 2D texture
Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, TextureParameter.ClampToEdge);
Gl.TexParameteri(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, TextureParameter.ClampToEdge);
plottingProgram["model_matrix"].SetValue(Matrix4.CreateRotationY(yangle) * Matrix4.CreateRotationX(xangle));
if (dataAvailable)
{
CircularBuffer.UpdateVertexArray(); //this updates the y vertex values
spectrumVBO.BufferSubData(vertexBuffer); //vertexBuffer is an array with x,y,z data. x, is always the same
dataAvailable = false;
}
Gl.BindBufferToShaderAttribute(spectrumVBO, plottingProgram, "vertexPosition");
Gl.BindBuffer(spectrumIndicesVBO);
Gl.DrawElements(BeginMode.TriangleStrip, spectrumIndicesVBO.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);
And here are the shaders:
public static string VertexShader = @"
#version 130
in vec3 vertexPosition;
out vec2 textureCoordinate;
uniform mat4 projection_matrix;
uniform mat4 view_matrix;
uniform mat4 model_matrix;
void main(void)
{
textureCoordinate = vertexPosition.xy;
gl_Position = projection_matrix * view_matrix * model_matrix * vec4(vertexPosition, 1);
}
";
public static string FragmentShader = @"
#version 130
uniform sampler2D texture;
in vec2 textureCoordinate;
out vec4 fragment;
void main(void)
{
fragment = texture2D(texture,textureCoordinate);
}
";