我的程序是一个 3D 频谱处理器,它将显示信号强度 (y) 与频率 (x) 与时间 (z) 的关系。它基本上绘制了一个 3d 高度图,顶点的高度对应于信号强度。基本程序流程是创建具有固定 x 和 z 坐标的高度图,并计算索引。之后,获得新的 Y 坐标并使用 GL.BufferSubData 调用更新整个 3D 表面。基本上新的光谱数据进来了,它被放在所有其他的前面,其余的用一个循环缓冲区向后移动。新数据的数据处理相当快,大约需要 20 毫秒。
现在数据量相当大。我绘制了 2048 个点,我有 50 - 100 行。所以大约有 100,000 到 200,000 个顶点。这些都是用单个 GL.DrawElements 绘制的,其中一个 VBO 用于顶点,一个 VBO 用于索引。
现在,我有一个测试程序,如果数据可用,它会生成顶点和信号给 openGL 程序。如果是这样,它将数据传输到顶点数组中。如果没有更多的 sdata 可用,它只会绘制。
绘图似乎很慢,但我不确定我要求太多。我们需要绘制大约 300,000 个三角形,并使用 2D 着色器对它们进行着色,该着色器基本上只使用顶点的高度来选择颜色。
因此,我在 2.3 GHz 的四核 Core i7 和 nVidia 540m 显卡上看到每帧大约 150 毫秒。这很慢。如果我把窗口变小,速度会大大提高,如果是全屏,速度会变得更糟。
我对这里的期望是不是太高了?还是我的代码有问题?
这是问题陈述。为什么程序这么慢?
我将 c# 与 opengl4Csharp 库一起使用。
这是代码:GLUT空闲回调有这个:
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);
这里是着色器:
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);
}
";