title: Fast line drawing in OpenGL
body: <p>I am working on a project that requires drawing a lot of data as it is acquired by an ADC...something like 50,000 lines per frame on a monitor 1600 pixels wide.  It runs great on a system with a 2007-ish Quadro FX 570, but basically can't keep up with the data on machines with Intel HD 4000 class chips.  The data load is 32 channels of 200 Hz data received in batches of 5 samples per channel 40 times per second.  So, in other words, the card only needs to achieve 40 frames per second or better.</p>
  
  <p>I am using a single VBO for all 32 channels with space for 10,000 vertices each.  The VBO is essentially treated like a series of ring buffers for each channel.  When the data comes in, I decimate it based on the time scale being used.  So, basically, it tracks the min/max for each channel.  When enough data has been received for a single pixel column, it sets the next two vertices in the VBO for each channel and renders a new frame.</p>
  
  <p>I use glMapBuffer() to access the data once, update all of the channels, use glUnmapBuffer, and then render as necessary.</p>
  
  <p>I manually calculate the transform matrix ahead of time (using an orthographic transform calculated in a non-generic way to reduce multiplications), and the vertex shader looks like:</p>
  
  <pre><code>#version 120
  
  varying vec4 _outColor;
  
  uniform vec4 _lBound=vec4(-1.0);
  uniform vec4 _uBound=vec4(1.0);
  uniform mat4 _xform=mat4(1.0);
  
  attribute vec2 _inPos;
  attribute vec4 _inColor;
  
  void main()
  {
      gl_Position=clamp(_xform*vec4(_inPos, 0.0, 1.0), _lBound, _uBound);
      _outColor=_inColor;
  }
  </code></pre>
  
  <p>The <code>_lBound</code>, <code>_uBound</code>, and <code>_xform</code> uniforms are updated once per channel.  So, 32 times per frame.  The clamp is used to limit certain channels to a range of y-coordinates on the screen.</p>
  
  <p>The fragment shader is simply:</p>
  
  <pre><code>#version 120
  
  varying vec4 _outColor;
  
  void main()
  {
      gl_FragColor=_outColor;
  }
  </code></pre>
  
  <p>There is other stuff being render to the screen; channel labels, for example, using quads and a texture atlas; but profiling in gDEBugger seems to indicate that the line rendering takes the overwhelming majority of time per frame.</p>
  
  <p>Still, 50,000 lines does not seem like a horrendously large number to me.</p>
  
  <p>So, after all of that, the question is: are there any tricks to speeding up line drawing?  I tried rendering them to the stencil buffer and then clipping a single quad, but that was slower.  I thought about drawing the lines to a texture, the drawing a quad with the texture.  But, that does not seem scalable or even faster due to uploading large textures constantly.  I saw a technique that stores the y values in a single row texture, but that seems more like memory optimization rather than speed optimization.</p>